Skip to content

Commit 20f84f8

Browse files
committed
feat: fault tolerant execution
1 parent de7278a commit 20f84f8

4 files changed

Lines changed: 658 additions & 2 deletions

File tree

rust/operator-binary/src/command.rs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,13 +15,15 @@ use crate::{
1515
STACKABLE_INTERNAL_TLS_DIR, STACKABLE_MOUNT_INTERNAL_TLS_DIR,
1616
STACKABLE_MOUNT_SERVER_TLS_DIR, STACKABLE_SERVER_TLS_DIR, STACKABLE_TLS_STORE_PASSWORD,
1717
SYSTEM_TRUST_STORE, SYSTEM_TRUST_STORE_PASSWORD, TrinoRole, v1alpha1,
18+
fault_tolerant_execution::ResolvedFaultTolerantExecutionConfig
1819
},
1920
};
2021

2122
pub fn container_prepare_args(
2223
trino: &v1alpha1::TrinoCluster,
2324
catalogs: &[CatalogConfig],
2425
merged_config: &v1alpha1::TrinoConfig,
26+
resolved_fte_config: &Option<ResolvedFaultTolerantExecutionConfig>,
2527
) -> Vec<String> {
2628
let mut args = vec![];
2729

@@ -78,12 +80,18 @@ pub fn container_prepare_args(
7880
args.extend_from_slice(&catalog.init_container_extra_start_commands);
7981
});
8082

83+
// Add the commands that are needed for fault tolerant execution (e.g., TLS certificates for S3)
84+
if let Some(resolved_fte) = resolved_fte_config {
85+
args.extend_from_slice(&resolved_fte.init_container_extra_start_commands);
86+
}
87+
8188
args
8289
}
8390

8491
pub fn container_trino_args(
8592
authentication_config: &TrinoAuthenticationConfig,
8693
catalogs: &[CatalogConfig],
94+
resolved_fte_config: &Option<ResolvedFaultTolerantExecutionConfig>,
8795
) -> Vec<String> {
8896
let mut args = vec![
8997
// copy config files to a writeable empty folder
@@ -110,6 +118,14 @@ pub fn container_trino_args(
110118
args.push(format!("export {env_name}=\"$(cat {file})\""));
111119
}
112120
});
121+
122+
// Add fault tolerant execution environment variables from files
123+
if let Some(resolved_fte) = resolved_fte_config {
124+
for (env_name, file) in &resolved_fte.load_env_from_files {
125+
args.push(format!("export {env_name}=\"$(cat {file})\""));
126+
}
127+
}
128+
113129
args.push("set -x".to_string());
114130

115131
// Start command

rust/operator-binary/src/controller.rs

Lines changed: 65 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -78,14 +78,15 @@ use crate::{
7878
command, config,
7979
crd::{
8080
ACCESS_CONTROL_PROPERTIES, APP_NAME, CONFIG_DIR_NAME, CONFIG_PROPERTIES, Container,
81-
DISCOVERY_URI, ENV_INTERNAL_SECRET, HTTP_PORT, HTTP_PORT_NAME, HTTPS_PORT, HTTPS_PORT_NAME,
81+
DISCOVERY_URI, ENV_INTERNAL_SECRET, EXCHANGE_MANAGER_PROPERTIES, HTTP_PORT, HTTP_PORT_NAME, HTTPS_PORT, HTTPS_PORT_NAME,
8282
JVM_CONFIG, JVM_SECURITY_PROPERTIES, LOG_PROPERTIES, MAX_TRINO_LOG_FILES_SIZE,
8383
METRICS_PORT, METRICS_PORT_NAME, NODE_PROPERTIES, RW_CONFIG_DIR_NAME,
8484
STACKABLE_CLIENT_TLS_DIR, STACKABLE_INTERNAL_TLS_DIR, STACKABLE_MOUNT_INTERNAL_TLS_DIR,
8585
STACKABLE_MOUNT_SERVER_TLS_DIR, STACKABLE_SERVER_TLS_DIR, TrinoRole,
8686
authentication::resolve_authentication_classes,
8787
catalog,
8888
discovery::{TrinoDiscovery, TrinoDiscoveryProtocol, TrinoPodRef},
89+
fault_tolerant_execution::ResolvedFaultTolerantExecutionConfig,
8990
rolegroup_headless_service_name, v1alpha1,
9091
},
9192
listener::{
@@ -298,6 +299,11 @@ pub enum Error {
298299
source: crate::operations::graceful_shutdown::Error,
299300
},
300301

302+
#[snafu(display("failed to configure fault tolerant execution"))]
303+
FaultTolerantExecution {
304+
source: crate::crd::fault_tolerant_execution::Error,
305+
},
306+
301307
#[snafu(display("failed to get required Labels"))]
302308
GetRequiredLabels {
303309
source:
@@ -424,6 +430,20 @@ pub async fn reconcile_trino(
424430
catalogs.push(catalog_config);
425431
}
426432

433+
// Resolve fault tolerant execution configuration with S3 connections if needed
434+
let resolved_fte_config = match trino.spec.cluster_config.fault_tolerant_execution.as_ref() {
435+
Some(fte_config) => Some(
436+
ResolvedFaultTolerantExecutionConfig::from_config(
437+
fte_config,
438+
Some(client),
439+
&trino.namespace_r().context(ReadRoleSnafu)?,
440+
)
441+
.await
442+
.context(FaultTolerantExecutionSnafu)?
443+
),
444+
None => None,
445+
};
446+
427447
let validated_config = validated_product_config(
428448
trino,
429449
// The Trino version is a single number like 396.
@@ -526,6 +546,7 @@ pub async fn reconcile_trino(
526546
&trino_authentication_config,
527547
&trino_opa_config,
528548
&client.kubernetes_cluster_info,
549+
&resolved_fte_config,
529550
)?;
530551
let rg_catalog_configmap = build_rolegroup_catalog_config_map(
531552
trino,
@@ -543,6 +564,7 @@ pub async fn reconcile_trino(
543564
&trino_authentication_config,
544565
&catalogs,
545566
&rbac_sa.name_any(),
567+
&resolved_fte_config,
546568
)?;
547569

548570
cluster_resources
@@ -651,6 +673,7 @@ fn build_rolegroup_config_map(
651673
trino_authentication_config: &TrinoAuthenticationConfig,
652674
trino_opa_config: &Option<TrinoOpaConfig>,
653675
cluster_info: &KubernetesClusterInfo,
676+
resolved_fte_config: &Option<ResolvedFaultTolerantExecutionConfig>,
654677
) -> Result<ConfigMap> {
655678
let mut cm_conf_data = BTreeMap::new();
656679

@@ -712,6 +735,14 @@ fn build_rolegroup_config_map(
712735
dynamic_resolved_config
713736
.extend(graceful_shutdown_config_properties(trino, trino_role));
714737

738+
// Add fault tolerant execution properties from resolved configuration
739+
if let Some(resolved_fte) = resolved_fte_config {
740+
dynamic_resolved_config.extend(
741+
resolved_fte.config_properties.iter()
742+
.map(|(k, v)| (k.clone(), Some(v.clone())))
743+
);
744+
}
745+
715746
// Add static properties and overrides
716747
dynamic_resolved_config.extend(transformed_config);
717748

@@ -776,6 +807,20 @@ fn build_rolegroup_config_map(
776807

777808
cm_conf_data.insert(JVM_CONFIG.to_string(), jvm_config.to_string());
778809

810+
// Add exchange manager properties from resolved fault tolerant execution configuration
811+
if let Some(resolved_fte) = resolved_fte_config {
812+
if !resolved_fte.exchange_manager_properties.is_empty() {
813+
let exchange_props_with_options: BTreeMap<String, Option<String>> =
814+
resolved_fte.exchange_manager_properties.iter().map(|(k, v)| (k.clone(), Some(v.clone()))).collect();
815+
cm_conf_data.insert(
816+
EXCHANGE_MANAGER_PROPERTIES.to_string(),
817+
to_java_properties_string(
818+
exchange_props_with_options.iter()
819+
).with_context(|_| FailedToWriteJavaPropertiesSnafu)?,
820+
);
821+
}
822+
}
823+
779824
let jvm_sec_props: BTreeMap<String, Option<String>> = config
780825
.get(&PropertyNameKind::File(JVM_SECURITY_PROPERTIES.to_string()))
781826
.cloned()
@@ -884,6 +929,7 @@ fn build_rolegroup_statefulset(
884929
trino_authentication_config: &TrinoAuthenticationConfig,
885930
catalogs: &[CatalogConfig],
886931
sa_name: &str,
932+
resolved_fte_config: &Option<ResolvedFaultTolerantExecutionConfig>,
887933
) -> Result<StatefulSet> {
888934
let role = trino
889935
.role(trino_role)
@@ -974,6 +1020,7 @@ fn build_rolegroup_statefulset(
9741020
&mut cb_trino,
9751021
catalogs,
9761022
&requested_secret_lifetime,
1023+
resolved_fte_config,
9771024
)?;
9781025

9791026
let mut prepare_args = vec![];
@@ -992,6 +1039,7 @@ fn build_rolegroup_statefulset(
9921039
trino,
9931040
catalogs,
9941041
merged_config,
1042+
resolved_fte_config,
9951043
));
9961044

9971045
prepare_args
@@ -1056,7 +1104,7 @@ fn build_rolegroup_statefulset(
10561104
"-c".to_string(),
10571105
])
10581106
.args(vec![
1059-
command::container_trino_args(trino_authentication_config, catalogs).join("\n"),
1107+
command::container_trino_args(trino_authentication_config, catalogs, resolved_fte_config).join("\n"),
10601108
])
10611109
.add_env_vars(env)
10621110
.add_volume_mount("config", CONFIG_DIR_NAME)
@@ -1532,6 +1580,7 @@ fn tls_volume_mounts(
15321580
cb_trino: &mut ContainerBuilder,
15331581
catalogs: &[CatalogConfig],
15341582
requested_secret_lifetime: &Duration,
1583+
resolved_fte_config: &Option<ResolvedFaultTolerantExecutionConfig>,
15351584
) -> Result<()> {
15361585
if let Some(server_tls) = trino.get_server_tls() {
15371586
cb_prepare
@@ -1611,6 +1660,19 @@ fn tls_volume_mounts(
16111660
.context(AddVolumeSnafu)?;
16121661
}
16131662

1663+
// fault tolerant execution S3 credentials and other resources
1664+
if let Some(resolved_fte) = resolved_fte_config {
1665+
cb_prepare
1666+
.add_volume_mounts(resolved_fte.volume_mounts.clone())
1667+
.context(AddVolumeMountSnafu)?;
1668+
cb_trino
1669+
.add_volume_mounts(resolved_fte.volume_mounts.clone())
1670+
.context(AddVolumeMountSnafu)?;
1671+
pod_builder
1672+
.add_volumes(resolved_fte.volumes.clone())
1673+
.context(AddVolumeSnafu)?;
1674+
}
1675+
16141676
Ok(())
16151677
}
16161678

@@ -1780,6 +1842,7 @@ mod tests {
17801842
&trino_authentication_config,
17811843
&trino_opa_config,
17821844
&cluster_info,
1845+
&None,
17831846
)
17841847
.unwrap()
17851848
}

0 commit comments

Comments
 (0)