@@ -4,6 +4,8 @@ use snafu::{OptionExt, ResultExt, Snafu};
44use stackable_operator:: {
55 commons:: product_image_selection,
66 config:: fragment,
7+ crd:: git_sync,
8+ k8s_openapi:: api:: core:: v1:: { EnvVar , VolumeMount } ,
79 kube:: ResourceExt ,
810 product_logging:: spec:: Logging ,
911 role_utils:: { GenericRoleConfig , RoleGroup } ,
@@ -25,10 +27,10 @@ use strum::IntoEnumIterator;
2527use super :: {
2628 AirflowRoleGroupConfig , ValidatedAirflowConfig , ValidatedCluster , ValidatedClusterConfig ,
2729 ValidatedExecutorTemplate , ValidatedLogging , ValidatedRoleConfig ,
28- dereference:: DereferencedObjects ,
30+ build :: volumes :: LOG_VOLUME_NAME , dereference:: DereferencedObjects ,
2931} ;
3032use crate :: {
31- airflow_controller:: CONTAINER_IMAGE_BASE_NAME ,
33+ airflow_controller:: { CONTAINER_IMAGE_BASE_NAME , env_vars_from_overrides } ,
3234 crd:: {
3335 AirflowConfig , AirflowConfigFragment , AirflowConfigOverrides , AirflowExecutor , AirflowRole ,
3436 AirflowRoleType , Container , v1alpha2,
@@ -87,6 +89,9 @@ pub enum Error {
8789 "the Vector aggregator discovery ConfigMap name must be set when the Vector agent is enabled"
8890 ) ) ]
8991 MissingVectorAggregatorConfigMapName ,
92+
93+ #[ snafu( display( "invalid git-sync specification" ) ) ]
94+ InvalidGitSyncSpec { source : git_sync:: v1alpha2:: Error } ,
9095}
9196
9297pub fn validate_cluster (
@@ -155,6 +160,9 @@ pub fn validate_cluster(
155160 rolegroup,
156161 & default_config,
157162 & vector_aggregator_config_map_name,
163+ & resolved_product_image,
164+ & airflow. spec . cluster_config . dags_git_sync ,
165+ & airflow. spec . cluster_config . volume_mounts ,
158166 ) ?;
159167
160168 group_configs. insert ( role_group_name, config) ;
@@ -199,8 +207,22 @@ pub fn validate_cluster(
199207 & Container :: Base ,
200208 & vector_aggregator_config_map_name,
201209 ) ?;
210+ // Resolve the executor's git-sync resources up-front too, mirroring the role groups.
211+ let git_sync_resources = git_sync:: v1alpha2:: GitSyncResources :: new (
212+ & airflow. spec . cluster_config . dags_git_sync ,
213+ & resolved_product_image,
214+ & env_vars_from_overrides ( & common_configuration. env_overrides ) ,
215+ & airflow. spec . cluster_config . volume_mounts ,
216+ LOG_VOLUME_NAME . as_ref ( ) ,
217+ & logging. git_sync_container ,
218+ )
219+ . context ( InvalidGitSyncSpecSnafu ) ?;
202220 Some ( ValidatedExecutorTemplate {
203- config : ValidatedAirflowConfig :: from_merged_executor ( merged, logging) ,
221+ config : ValidatedAirflowConfig :: from_merged_executor (
222+ merged,
223+ logging,
224+ git_sync_resources,
225+ ) ,
204226 env_overrides : common_configuration. env_overrides . clone ( ) ,
205227 pod_overrides : common_configuration. pod_overrides . clone ( ) ,
206228 } )
@@ -218,7 +240,6 @@ pub fn validate_cluster(
218240 executor_template,
219241 authentication_config,
220242 authorization_config,
221- dags_git_sync : airflow. spec . cluster_config . dags_git_sync . clone ( ) ,
222243 credentials_secret_name : airflow. spec . cluster_config . credentials_secret_name . clone ( ) ,
223244 metadata_database : airflow. spec . cluster_config . metadata_database . clone ( ) ,
224245 celery_results_backend : airflow. spec . cluster_config . celery_results_backend . clone ( ) ,
@@ -249,12 +270,16 @@ pub fn validate_cluster(
249270///
250271/// Note the override `Merge` semantics: a role-group `null` inherits the role-level value rather
251272/// than unsetting it (config overrides), and env overrides layer role-group on top of role.
273+ #[ allow( clippy:: too_many_arguments) ]
252274fn validate_role_group (
253275 role : & AirflowRoleType ,
254276 role_group_name : & RoleGroupName ,
255277 rolegroup : & RoleGroup < AirflowConfigFragment , GenericCommonConfig , AirflowConfigOverrides > ,
256278 default_config : & AirflowConfigFragment ,
257279 vector_aggregator_config_map_name : & Option < ConfigMapName > ,
280+ image : & product_image_selection:: ResolvedProductImage ,
281+ dags_git_sync : & [ git_sync:: v1alpha2:: GitSync ] ,
282+ volume_mounts : & [ VolumeMount ] ,
258283) -> Result < AirflowRoleGroupConfig , Error > {
259284 let validated = with_validated_config :: <
260285 AirflowConfig ,
@@ -282,9 +307,21 @@ fn validate_role_group(
282307 vector_aggregator_config_map_name,
283308 ) ?;
284309
310+ // The git-sync resources depend on this role group's env-var overrides and (git-sync) logging
311+ // config, so they are resolved (and validated) here, up-front, rather than at build time.
312+ let git_sync_resources = git_sync:: v1alpha2:: GitSyncResources :: new (
313+ dags_git_sync,
314+ image,
315+ & Vec :: < EnvVar > :: from ( env_overrides. clone ( ) ) ,
316+ volume_mounts,
317+ LOG_VOLUME_NAME . as_ref ( ) ,
318+ & logging. git_sync_container ,
319+ )
320+ . context ( InvalidGitSyncSpecSnafu ) ?;
321+
285322 Ok ( RoleGroupConfig {
286323 replicas : validated. replicas ,
287- config : ValidatedAirflowConfig :: from_merged ( merged_config, logging) ,
324+ config : ValidatedAirflowConfig :: from_merged ( merged_config, logging, git_sync_resources ) ,
288325 config_overrides : validated. config . config_overrides ,
289326 env_overrides,
290327 cli_overrides : validated. config . cli_overrides ,
@@ -342,6 +379,20 @@ mod tests {
342379 use super :: validate_role_group;
343380 use crate :: crd:: { AirflowConfig , AirflowRole , v1alpha2} ;
344381
382+ /// A minimal resolved product image for tests that exercise `validate_role_group` (which needs
383+ /// one to resolve git-sync resources; the test role groups configure no git-sync, so the value
384+ /// is otherwise unused).
385+ fn test_resolved_product_image ( )
386+ -> stackable_operator:: commons:: product_image_selection:: ResolvedProductImage {
387+ stackable_operator:: commons:: product_image_selection:: ResolvedProductImage {
388+ product_version : "3.0.6" . to_string ( ) ,
389+ app_version_label_value : "3.0.6" . parse ( ) . expect ( "valid label value" ) ,
390+ image : "oci.example.org/sdp/airflow:3.0.6-stackable0.0.0-dev" . to_string ( ) ,
391+ image_pull_policy : "IfNotPresent" . to_string ( ) ,
392+ pull_secrets : None ,
393+ }
394+ }
395+
345396 fn test_cluster ( ) -> v1alpha2:: AirflowCluster {
346397 let cluster_yaml = r#"
347398 apiVersion: airflow.stackable.tech/v1alpha2
@@ -404,6 +455,9 @@ mod tests {
404455 rolegroup,
405456 & default_config,
406457 & None ,
458+ & test_resolved_product_image ( ) ,
459+ & [ ] ,
460+ & [ ] ,
407461 )
408462 . expect ( "validated role group" ) ;
409463 let config_overrides = validated. config_overrides ;
@@ -502,6 +556,9 @@ mod tests {
502556 rolegroup,
503557 & default_config,
504558 & None ,
559+ & test_resolved_product_image ( ) ,
560+ & [ ] ,
561+ & [ ] ,
505562 )
506563 . expect ( "validated role group" ) ;
507564
@@ -576,6 +633,9 @@ mod tests {
576633 rolegroup,
577634 & default_config,
578635 & None ,
636+ & test_resolved_product_image ( ) ,
637+ & [ ] ,
638+ & [ ] ,
579639 )
580640 . expect ( "validated role group" ) ;
581641
0 commit comments