Repository navigation
feat: Make containerdebug configurable #967
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
4777107
f934169
8cde40c
97d492f
80780cf
aabdf6a
827bbab
e28c64f
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -87,6 +87,7 @@ pub fn container_prepare_args( | |
| pub fn container_trino_args( | ||
| authentication_config: &TrinoAuthenticationConfig, | ||
| catalogs: &BTreeMap<TrinoCatalogName, CatalogConfig>, | ||
| merged_config: &ValidatedTrinoConfig, | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We pass this only to use containerdebug. Passing just that field makes the dependency explicit and probably simplifies the tests. |
||
| ) -> Vec<String> { | ||
| let mut args = vec![ | ||
| // copy config files to a writable empty folder | ||
|
|
@@ -152,14 +153,18 @@ pub fn container_trino_args( | |
| {remove_vector_shutdown_file_command} | ||
| prepare_signal_handlers | ||
| mkdir --parents \"${file_log_directory}\" || true | ||
| containerdebug --output={STACKABLE_LOG_DIR}/containerdebug-state.json --loop & | ||
| {containerdebug_command} | ||
| bin/launcher run --etc-dir={RW_CONFIG_DIR_NAME} & | ||
| wait_for_termination $! | ||
| {create_vector_shutdown_file_command} | ||
| ", | ||
| remove_vector_shutdown_file_command = | ||
| remove_vector_shutdown_file_command(STACKABLE_LOG_DIR), | ||
| file_log_directory = FILE_LOG_DIRECTORY.as_ref(), | ||
| containerdebug_command = merged_config | ||
| .containerdebug | ||
| .background_command(STACKABLE_LOG_DIR) | ||
| .unwrap_or_default(), | ||
| create_vector_shutdown_file_command = | ||
| create_vector_shutdown_file_command(STACKABLE_LOG_DIR), | ||
| )); | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -402,7 +402,8 @@ pub fn build_rolegroup_statefulset( | |
| "-c".to_string(), | ||
| ]) | ||
| .args(vec![ | ||
| command::container_trino_args(trino_authentication_config, catalogs).join("\n"), | ||
| command::container_trino_args(trino_authentication_config, catalogs, merged_config) | ||
| .join("\n"), | ||
| ]) | ||
| .add_env_vars(env.merge(env_overrides.clone())) | ||
| .add_container_ports(container_ports(cluster)) | ||
|
|
@@ -835,8 +836,11 @@ fn add_derived_volumes_and_mounts( | |
|
|
||
| #[cfg(test)] | ||
| mod tests { | ||
| use rstest::rstest; | ||
| use stackable_operator::{ | ||
| crd::containerdebug::ValidatedContainerdebugConfig, | ||
| k8s_openapi::api::core::v1::{Container as K8sContainer, PodSpec, VolumeMount}, | ||
| shared::time::Duration, | ||
| v2::builder::pod::container::EnvVarName, | ||
| }; | ||
|
|
||
|
|
@@ -933,6 +937,47 @@ mod tests { | |
| assert_eq!(containerdebug[0].value.as_deref(), Some("/custom/log/dir")); | ||
| } | ||
|
|
||
| /// The trino container starts `containerdebug` from the role group's validated config. The | ||
| /// command itself is owned (and tested) by operator-rs, so only the wiring is checked here. | ||
| #[rstest] | ||
| #[case::enabled(ValidatedContainerdebugConfig::Enabled { | ||
| interval: Duration::from_minutes_unchecked(10) | ||
| })] | ||
| #[case::disabled(ValidatedContainerdebugConfig::Disabled)] | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We should mention in the docs that containerdebug can be turned off. |
||
| fn trino_container_starts_containerdebug_from_config( | ||
| #[case] containerdebug: ValidatedContainerdebugConfig, | ||
| ) { | ||
| let expected = containerdebug.background_command(STACKABLE_LOG_DIR); | ||
| let cluster = validated_cluster(); | ||
| let role_group_name = RoleGroupName::from_str("default").expect("valid role group name"); | ||
| let mut role_group_config = | ||
| cluster.coordinator_role_group_configs[&role_group_name].clone(); | ||
| role_group_config.config.containerdebug = containerdebug; | ||
|
|
||
| let stateful_set = build_rolegroup_statefulset( | ||
| &cluster, | ||
| &TrinoRole::Coordinator, | ||
| &role_group_name, | ||
| &role_group_config, | ||
| ) | ||
| .expect("the StatefulSet builds"); | ||
|
|
||
| let args = pod_spec(stateful_set) | ||
| .containers | ||
| .into_iter() | ||
| .find(|container| container.name == "trino") | ||
| .expect("the trino container exists") | ||
| .args | ||
| .expect("the trino container has args") | ||
| .join("\n"); | ||
| assert_eq!( | ||
| args.lines() | ||
| .find(|line| line.starts_with("containerdebug ")), | ||
| expected.as_deref(), | ||
| "args: {args}" | ||
| ); | ||
| } | ||
|
|
||
| /// The operator's own volume mounts are added with `expect`, which relies on every add whose | ||
| /// name derives from user input coming afterwards. A catalog volume that reuses an operator | ||
| /// volume name must therefore surface as an error, never as a panic. | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -10,6 +10,7 @@ use stackable_operator::{ | |
| cli::OperatorEnvironmentOptions, | ||
| commons::product_image_selection, | ||
| config::fragment, | ||
| crd::containerdebug, | ||
| kube::ResourceExt as _, | ||
| product_logging::spec::Logging, | ||
| v2::{ | ||
|
|
@@ -87,6 +88,12 @@ pub enum Error { | |
| role_group: RoleGroupName, | ||
| }, | ||
|
|
||
| #[snafu(display("invalid containerdebug configuration for role group {role_group}"))] | ||
| InvalidContainerdebugConfig { | ||
| source: containerdebug::Error, | ||
| role_group: RoleGroupName, | ||
| }, | ||
|
|
||
| #[snafu(display("failed to validate logging configuration"))] | ||
| ValidateLoggingConfig { | ||
| source: stackable_operator::v2::product_logging::framework::Error, | ||
|
|
@@ -375,8 +382,8 @@ where | |
| role_group: role_group_name.clone(), | ||
| })?; | ||
| role_groups.insert( | ||
| role_group_name, | ||
| into_role_group_config(merged, vector_aggregator_config_map_name)?, | ||
| role_group_name.clone(), | ||
| into_role_group_config(merged, &role_group_name, vector_aggregator_config_map_name)?, | ||
| ); | ||
| } | ||
|
|
||
|
|
@@ -387,16 +394,22 @@ where | |
| /// [`TrinoRoleGroupConfig`] consumed by the build steps. | ||
| fn into_role_group_config( | ||
| merged: RoleGroup<v1alpha1::TrinoConfig, JavaCommonConfig, v1alpha1::TrinoConfigOverrides>, | ||
| role_group_name: &RoleGroupName, | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We are passing the role_group_name just for the error, which does not indicate the role. It would be better to catch the error at the call site in validate_role_groups so that both role and role_group can be reported with the error. |
||
| vector_aggregator_config_map_name: &Option<ConfigMapName>, | ||
| ) -> Result<TrinoRoleGroupConfig> { | ||
| let replicas = merged.replicas; | ||
| let common = merged.config; | ||
|
|
||
| let containerdebug = common.config.containerdebug.validate().with_context(|_| { | ||
| InvalidContainerdebugConfigSnafu { | ||
| role_group: role_group_name.clone(), | ||
| } | ||
| })?; | ||
| let logging = validate_logging(&common.config.logging, vector_aggregator_config_map_name)?; | ||
|
|
||
| Ok(RoleGroupConfig { | ||
| replicas, | ||
| config: ValidatedTrinoConfig::from_merged(common.config, logging), | ||
| config: ValidatedTrinoConfig::from_merged(common.config, containerdebug, logging), | ||
| config_overrides: common.config_overrides, | ||
| env_overrides: common.env_overrides.into(), | ||
| cli_overrides: common.cli_overrides, | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -22,7 +22,11 @@ use stackable_operator::{ | |
| }, | ||
| config::{fragment::Fragment, merge::Merge}, | ||
| constant, | ||
| crd::{authentication::core, openlineage}, | ||
| crd::{ | ||
| authentication::core, | ||
| containerdebug::{default_containerdebug_config, v1alpha1::ContainerdebugConfig}, | ||
| openlineage, | ||
| }, | ||
| deep_merger::ObjectOverrides, | ||
| k8s_openapi::apimachinery::pkg::{api::resource::Quantity, apis::meta::v1::LabelSelector}, | ||
| kube::{CustomResource, ResourceExt}, | ||
|
|
@@ -215,7 +219,7 @@ pub mod versioned { | |
| pub event_listener_properties: KeyValueConfigOverrides, | ||
| } | ||
|
|
||
| #[derive(Clone, Debug, Default, Fragment, JsonSchema, PartialEq)] | ||
| #[derive(Clone, Debug, Fragment, JsonSchema, PartialEq)] | ||
| #[fragment_attrs( | ||
| derive( | ||
| Clone, | ||
|
|
@@ -233,6 +237,9 @@ pub mod versioned { | |
| #[fragment_attrs(serde(default))] | ||
| pub affinity: StackableAffinity, | ||
|
|
||
| #[fragment_attrs(serde(default))] | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If this attribute was dropped for some reason, no test would catch it. We also don't test that e.g. |
||
| pub containerdebug: ContainerdebugConfig, | ||
|
|
||
| /// Time period Pods have to gracefully shut down, e.g. `30m`, `1h` or `2d`. Consult the operator documentation for details. | ||
| #[fragment_attrs(serde(default))] | ||
| pub graceful_shutdown_timeout: Option<Duration>, | ||
|
|
@@ -542,6 +549,7 @@ impl v1alpha1::TrinoConfig { | |
| v1alpha1::TrinoConfigFragment { | ||
| logging: product_logging::spec::default_logging(), | ||
| affinity: get_affinity(cluster_name, role, trino_catalogs, opa_config), | ||
| containerdebug: default_containerdebug_config(), | ||
| resources: ResourcesFragment { | ||
| cpu: CpuLimitsFragment { | ||
| min: Some(Quantity(cpu_min.to_string())), | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Rather refer to the addition of the config.containerdebug field on roles and role groups.
Also, the default interval has (silently) changed from 1m to 30m so this should be mentioned.(ignore that bit: my op-rs branch was out of date)