Skip to content

Commit 523b904

Browse files
sbernauerxeniape
andauthored
fix: Fix upgrade path 3.3.x -> 4.0.x (#539)
* fix: Fix upgrade path 3.3.x -> 4.0.x * changelog * changelog * reword warning * reword warning * quote bash args * noop Co-authored-by: Xenia Fischer <xenia.fischer@stackable.tech> * Add udgrade test --------- Co-authored-by: Xenia Fischer <xenia.fischer@stackable.tech>
1 parent e4d9e7f commit 523b904

15 files changed

+248
-65
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,12 +21,14 @@ All notable changes to this project will be documented in this file.
2121

2222
- BREAKING: The fields `connection` and `host` on `S3Connection` as well as `bucketName` on `S3Bucket`are now mandatory ([#518]).
2323
- An invalid `HiveCluster` doesn't cause the operator to stop functioning ([#523]).
24+
- Fix upgrade path from HMS `3.3.x` to `4.0.x`. Previously the schemaTool would try to re-create the database tables and would therefore fail. Starting with version `4.0.0` the schemaTool has the flag `-initOrUpgradeSchema`, which we use to resolve that problem ([#539]).
2425

2526
[#505]: https://github.com/stackabletech/hive-operator/pull/505
2627
[#508]: https://github.com/stackabletech/hive-operator/pull/508
2728
[#518]: https://github.com/stackabletech/hive-operator/pull/518
2829
[#522]: https://github.com/stackabletech/hive-operator/pull/522
2930
[#523]: https://github.com/stackabletech/hive-operator/pull/523
31+
[#539]: https://github.com/stackabletech/hive-operator/pull/539
3032

3133
## [24.7.0] - 2024-07-24
3234

rust/crd/src/lib.rs

Lines changed: 8 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -332,7 +332,6 @@ impl MetaStoreConfig {
332332
pub const CONNECTION_PASSWORD: &'static str = "javax.jdo.option.ConnectionPassword";
333333
pub const METASTORE_METRICS_ENABLED: &'static str = "hive.metastore.metrics.enabled";
334334
pub const METASTORE_WAREHOUSE_DIR: &'static str = "hive.metastore.warehouse.dir";
335-
pub const DB_TYPE_CLI: &'static str = "dbType";
336335
// S3
337336
pub const S3_ENDPOINT: &'static str = "fs.s3a.endpoint";
338337
pub const S3_ACCESS_KEY: &'static str = "fs.s3a.access.key";
@@ -406,12 +405,6 @@ pub enum DbType {
406405
Mssql,
407406
}
408407

409-
impl Default for DbType {
410-
fn default() -> Self {
411-
Self::Derby
412-
}
413-
}
414-
415408
impl DbType {
416409
pub fn get_jdbc_driver_class(&self) -> &str {
417410
match self {
@@ -425,7 +418,7 @@ impl DbType {
425418
}
426419

427420
/// Database connection specification for the metadata database.
428-
#[derive(Clone, Debug, Default, Deserialize, Eq, Hash, JsonSchema, PartialEq, Serialize)]
421+
#[derive(Clone, Debug, Deserialize, Eq, Hash, JsonSchema, PartialEq, Serialize)]
429422
#[serde(rename_all = "camelCase")]
430423
pub struct DatabaseConnectionSpec {
431424
/// A connection string for the database. For example:
@@ -469,15 +462,10 @@ impl Configuration for MetaStoreConfigFragment {
469462

470463
fn compute_cli(
471464
&self,
472-
hive: &Self::Configurable,
465+
_hive: &Self::Configurable,
473466
_role_name: &str,
474467
) -> Result<BTreeMap<String, Option<String>>, product_config_utils::Error> {
475-
let mut result = BTreeMap::new();
476-
result.insert(
477-
MetaStoreConfig::DB_TYPE_CLI.to_string(),
478-
Some(hive.spec.cluster_config.database.db_type.to_string()),
479-
);
480-
Ok(result)
468+
Ok(BTreeMap::new())
481469
}
482470

483471
fn compute_files(
@@ -511,14 +499,7 @@ impl Configuration for MetaStoreConfigFragment {
511499
);
512500
result.insert(
513501
MetaStoreConfig::CONNECTION_DRIVER_NAME.to_string(),
514-
Some(
515-
hive.spec
516-
.cluster_config
517-
.database
518-
.db_type
519-
.get_jdbc_driver_class()
520-
.to_string(),
521-
),
502+
Some(hive.db_type().get_jdbc_driver_class().to_string()),
522503
);
523504

524505
result.insert(
@@ -657,6 +638,10 @@ impl HiveCluster {
657638
.map(|k| k.secret_class.clone())
658639
}
659640

641+
pub fn db_type(&self) -> &DbType {
642+
&self.spec.cluster_config.database.db_type
643+
}
644+
660645
/// Retrieve and merge resource configs for role and role groups
661646
pub fn merged_config(
662647
&self,

rust/operator-binary/src/controller.rs

Lines changed: 43 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ use std::{
33
borrow::Cow,
44
collections::{BTreeMap, HashMap},
55
hash::Hasher,
6-
str::FromStr,
76
sync::Arc,
87
};
98

@@ -16,10 +15,10 @@ use product_config::{
1615
};
1716
use snafu::{OptionExt, ResultExt, Snafu};
1817
use stackable_hive_crd::{
19-
Container, DbType, HiveCluster, HiveClusterStatus, HiveRole, MetaStoreConfig, APP_NAME,
20-
CORE_SITE_XML, DB_PASSWORD_ENV, DB_USERNAME_ENV, HADOOP_HEAPSIZE, HIVE_ENV_SH, HIVE_PORT,
21-
HIVE_PORT_NAME, HIVE_SITE_XML, JVM_HEAP_FACTOR, JVM_SECURITY_PROPERTIES_FILE, METRICS_PORT,
22-
METRICS_PORT_NAME, STACKABLE_CONFIG_DIR, STACKABLE_CONFIG_DIR_NAME, STACKABLE_CONFIG_MOUNT_DIR,
18+
Container, HiveCluster, HiveClusterStatus, HiveRole, MetaStoreConfig, APP_NAME, CORE_SITE_XML,
19+
DB_PASSWORD_ENV, DB_USERNAME_ENV, HADOOP_HEAPSIZE, HIVE_ENV_SH, HIVE_PORT, HIVE_PORT_NAME,
20+
HIVE_SITE_XML, JVM_HEAP_FACTOR, JVM_SECURITY_PROPERTIES_FILE, METRICS_PORT, METRICS_PORT_NAME,
21+
STACKABLE_CONFIG_DIR, STACKABLE_CONFIG_DIR_NAME, STACKABLE_CONFIG_MOUNT_DIR,
2322
STACKABLE_CONFIG_MOUNT_DIR_NAME, STACKABLE_LOG_CONFIG_MOUNT_DIR,
2423
STACKABLE_LOG_CONFIG_MOUNT_DIR_NAME, STACKABLE_LOG_DIR, STACKABLE_LOG_DIR_NAME,
2524
};
@@ -188,12 +187,6 @@ pub enum Error {
188187
source: stackable_operator::client::Error,
189188
},
190189

191-
#[snafu(display("failed to parse db type {db_type}"))]
192-
InvalidDbType {
193-
source: strum::ParseError,
194-
db_type: String,
195-
},
196-
197190
#[snafu(display("failed to configure S3 connection"))]
198191
ConfigureS3 { source: S3Error },
199192

@@ -828,36 +821,25 @@ fn build_metastore_rolegroup_statefulset(
828821
.rolegroup(rolegroup_ref)
829822
.context(InternalOperatorSnafu)?;
830823

831-
let mut db_type: Option<DbType> = None;
832824
let mut container_builder =
833825
ContainerBuilder::new(APP_NAME).context(FailedToCreateHiveContainerSnafu {
834826
name: APP_NAME.to_string(),
835827
})?;
836828

837829
for (property_name_kind, config) in metastore_config {
838-
match property_name_kind {
839-
PropertyNameKind::Env => {
840-
// overrides
841-
for (property_name, property_value) in config {
842-
if property_name.is_empty() {
843-
warn!("Received empty property_name for ENV... skipping");
844-
continue;
845-
}
846-
container_builder.add_env_var(property_name, property_value);
847-
}
848-
}
849-
PropertyNameKind::Cli => {
850-
for (property_name, property_value) in config {
851-
if property_name == MetaStoreConfig::DB_TYPE_CLI {
852-
db_type = Some(DbType::from_str(property_value).with_context(|_| {
853-
InvalidDbTypeSnafu {
854-
db_type: property_value.to_string(),
855-
}
856-
})?);
857-
}
830+
if property_name_kind == &PropertyNameKind::Env {
831+
// overrides
832+
for (property_name, property_value) in config {
833+
if property_name.is_empty() {
834+
warn!(
835+
property_name,
836+
property_value,
837+
"The env variable had an empty name, not adding it to the container"
838+
);
839+
continue;
858840
}
841+
container_builder.add_env_var(property_name, property_value);
859842
}
860-
_ => {}
861843
}
862844
}
863845

@@ -894,6 +876,26 @@ fn build_metastore_rolegroup_statefulset(
894876
}
895877
}
896878

879+
let db_type = hive.db_type();
880+
let start_command = if resolved_product_image.product_version.starts_with("3.") {
881+
// The schematool version in 3.1.x does *not* support the `-initOrUpgradeSchema` flag yet, so we can not use that.
882+
// As we *only* support HMS 3.1.x (or newer) since SDP release 23.11, we can safely assume we are always coming
883+
// from an existing 3.1.x installation. There is no need to upgrade the schema, we can just check if the schema
884+
// is already there and create it if it isn't.
885+
// The script `bin/start-metastore` is buggy (e.g. around version upgrades), but it's sufficient for that job :)
886+
//
887+
// TODO: Once we drop support for HMS 3.1.x we can remove this condition and very likely get rid of the
888+
// "bin/start-metastore" script.
889+
format!("bin/start-metastore --config {STACKABLE_CONFIG_DIR} --db-type {db_type} --hive-bin-dir bin &")
890+
} else {
891+
// schematool versions 4.0.x (and above) support the `-initOrUpgradeSchema`, which is exactly what we need :)
892+
// Some docs for the schemaTool can be found here: https://cwiki.apache.org/confluence/pages/viewpage.action?pageId=34835119
893+
formatdoc! {"
894+
bin/base --config \"{STACKABLE_CONFIG_DIR}\" --service schemaTool -dbType \"{db_type}\" -initOrUpgradeSchema
895+
bin/base --config \"{STACKABLE_CONFIG_DIR}\" --service metastore &
896+
"}
897+
};
898+
897899
let container_builder = container_builder
898900
.image_from_product_image(resolved_product_image)
899901
.command(vec![
@@ -905,23 +907,22 @@ fn build_metastore_rolegroup_statefulset(
905907
])
906908
.args(build_container_command_args(
907909
hive,
908-
formatdoc! {"
910+
formatdoc! {"
909911
{kerberos_container_start_commands}
910912
911913
{COMMON_BASH_TRAP_FUNCTIONS}
912914
{remove_vector_shutdown_file_command}
913915
prepare_signal_handlers
914-
bin/start-metastore --config {STACKABLE_CONFIG_DIR} --db-type {db_type} --hive-bin-dir bin &
916+
{start_command}
915917
wait_for_termination $!
916918
{create_vector_shutdown_file_command}
917919
",
918-
kerberos_container_start_commands = kerberos_container_start_commands(hive),
919-
remove_vector_shutdown_file_command =
920-
remove_vector_shutdown_file_command(STACKABLE_LOG_DIR),
921-
create_vector_shutdown_file_command =
922-
create_vector_shutdown_file_command(STACKABLE_LOG_DIR),
923-
db_type = &db_type.unwrap_or_default().to_string(),
924-
},
920+
kerberos_container_start_commands = kerberos_container_start_commands(hive),
921+
remove_vector_shutdown_file_command =
922+
remove_vector_shutdown_file_command(STACKABLE_LOG_DIR),
923+
create_vector_shutdown_file_command =
924+
create_vector_shutdown_file_command(STACKABLE_LOG_DIR),
925+
},
925926
s3_connection,
926927
))
927928
.add_volume_mount(STACKABLE_CONFIG_DIR_NAME, STACKABLE_CONFIG_DIR)
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
---
2+
apiVersion: v1
3+
kind: LimitRange
4+
metadata:
5+
name: limit-request-ratio
6+
spec:
7+
limits:
8+
- type: "Container"
9+
maxLimitRequestRatio:
10+
cpu: 5
11+
memory: 1
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
{% if test_scenario['values']['openshift'] == 'true' %}
2+
# see https://github.com/stackabletech/issues/issues/566
3+
---
4+
apiVersion: kuttl.dev/v1beta1
5+
kind: TestStep
6+
commands:
7+
- script: kubectl patch namespace $NAMESPACE -p '{"metadata":{"labels":{"pod-security.kubernetes.io/enforce":"privileged"}}}'
8+
timeout: 120
9+
{% endif %}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
---
2+
apiVersion: kuttl.dev/v1beta1
3+
kind: TestAssert
4+
{% if lookup('env', 'VECTOR_AGGREGATOR') %}
5+
---
6+
apiVersion: v1
7+
kind: ConfigMap
8+
metadata:
9+
name: vector-aggregator-discovery
10+
{% endif %}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
{% if lookup('env', 'VECTOR_AGGREGATOR') %}
2+
---
3+
apiVersion: v1
4+
kind: ConfigMap
5+
metadata:
6+
name: vector-aggregator-discovery
7+
data:
8+
ADDRESS: {{ lookup('env', 'VECTOR_AGGREGATOR') }}
9+
{% endif %}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
---
2+
apiVersion: kuttl.dev/v1beta1
3+
kind: TestAssert
4+
timeout: 600
5+
---
6+
apiVersion: v1
7+
kind: Service
8+
metadata:
9+
name: postgresql
10+
labels:
11+
app.kubernetes.io/name: postgresql
12+
---
13+
apiVersion: apps/v1
14+
kind: StatefulSet
15+
metadata:
16+
name: postgresql
17+
status:
18+
readyReplicas: 1
19+
replicas: 1
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
---
2+
apiVersion: kuttl.dev/v1beta1
3+
kind: TestStep
4+
commands:
5+
- script: >-
6+
helm install postgresql
7+
--version={{ test_scenario['values']['postgres'] }}
8+
--namespace $NAMESPACE
9+
-f helm-bitnami-postgresql-values.yaml
10+
--repo https://charts.bitnami.com/bitnami postgresql
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
---
2+
apiVersion: kuttl.dev/v1beta1
3+
kind: TestAssert
4+
timeout: 600
5+
---
6+
apiVersion: apps/v1
7+
kind: StatefulSet
8+
metadata:
9+
name: hive-metastore-default
10+
labels:
11+
{% if test_scenario['values']['hive-old'].find(",") > 0 %}
12+
# Yes, this *might* not work with custom images, I'm sorry!
13+
app.kubernetes.io/version: "{{ test_scenario['values']['hive-old'].split(',')[0] }}-stackable0.0.0-dev"
14+
{% else %}
15+
app.kubernetes.io/version: "{{ test_scenario['values']['hive-old'] }}-stackable0.0.0-dev"
16+
{% endif %}
17+
status:
18+
readyReplicas: 1
19+
replicas: 1

0 commit comments

Comments
 (0)