@@ -649,8 +649,7 @@ func patchSidecarContainers(in []v1.Container, volumeMounts []v1.VolumeMount, su
649649 },
650650 },
651651 }
652- mergedEnv := append (env , container .Env ... )
653- container .Env = deduplicateEnvVars (mergedEnv , container .Name , logger )
652+ container .Env = appendEnvVars (env , container .Env ... )
654653 result = append (result , container )
655654 }
656655
@@ -769,6 +768,7 @@ func (c *Cluster) generateSpiloPodEnvVars(
769768 cloneDescription * acidv1.CloneDescription ,
770769 standbyDescription * acidv1.StandbyDescription ,
771770 customPodEnvVarsList []v1.EnvVar ) []v1.EnvVar {
771+
772772 envVars := []v1.EnvVar {
773773 {
774774 Name : "SCOPE" ,
@@ -843,6 +843,11 @@ func (c *Cluster) generateSpiloPodEnvVars(
843843 Value : c .OpConfig .PamRoleName ,
844844 },
845845 }
846+
847+ if c .OpConfig .EnableSpiloWalPathCompat {
848+ envVars = append (envVars , v1.EnvVar {Name : "ENABLE_WAL_PATH_COMPAT" , Value : "true" })
849+ }
850+
846851 if c .OpConfig .EnablePgVersionEnvVar {
847852 envVars = append (envVars , v1.EnvVar {Name : "PGVERSION" , Value : c .GetDesiredMajorVersion ()})
848853 }
@@ -874,73 +879,67 @@ func (c *Cluster) generateSpiloPodEnvVars(
874879 envVars = append (envVars , c .generateStandbyEnvironment (standbyDescription )... )
875880 }
876881
882+ if len (c .Spec .Env ) > 0 {
883+ envVars = appendEnvVars (envVars , c .Spec .Env ... )
884+ }
885+
877886 // add vars taken from pod_environment_configmap and pod_environment_secret first
878887 // (to allow them to override the globals set in the operator config)
879888 if len (customPodEnvVarsList ) > 0 {
880- envVars = append (envVars , customPodEnvVarsList ... )
889+ envVars = appendEnvVars (envVars , customPodEnvVarsList ... )
881890 }
882891
883892 if c .OpConfig .WALES3Bucket != "" {
884- envVars = append (envVars , v1.EnvVar {Name : "WAL_S3_BUCKET" , Value : c .OpConfig .WALES3Bucket })
885- envVars = append (envVars , v1.EnvVar {Name : "WAL_BUCKET_SCOPE_SUFFIX" , Value : getBucketScopeSuffix (string (uid ))})
886- envVars = append (envVars , v1.EnvVar {Name : "WAL_BUCKET_SCOPE_PREFIX" , Value : "" })
893+ envVars = appendEnvVars (envVars , v1.EnvVar {Name : "WAL_S3_BUCKET" , Value : c .OpConfig .WALES3Bucket })
894+ envVars = appendEnvVars (envVars , v1.EnvVar {Name : "WAL_BUCKET_SCOPE_SUFFIX" , Value : getBucketScopeSuffix (string (uid ))})
895+ envVars = appendEnvVars (envVars , v1.EnvVar {Name : "WAL_BUCKET_SCOPE_PREFIX" , Value : "" })
887896 }
888897
889898 if c .OpConfig .WALGSBucket != "" {
890- envVars = append (envVars , v1.EnvVar {Name : "WAL_GS_BUCKET" , Value : c .OpConfig .WALGSBucket })
891- envVars = append (envVars , v1.EnvVar {Name : "WAL_BUCKET_SCOPE_SUFFIX" , Value : getBucketScopeSuffix (string (uid ))})
892- envVars = append (envVars , v1.EnvVar {Name : "WAL_BUCKET_SCOPE_PREFIX" , Value : "" })
899+ envVars = appendEnvVars (envVars , v1.EnvVar {Name : "WAL_GS_BUCKET" , Value : c .OpConfig .WALGSBucket })
900+ envVars = appendEnvVars (envVars , v1.EnvVar {Name : "WAL_BUCKET_SCOPE_SUFFIX" , Value : getBucketScopeSuffix (string (uid ))})
901+ envVars = appendEnvVars (envVars , v1.EnvVar {Name : "WAL_BUCKET_SCOPE_PREFIX" , Value : "" })
893902 }
894903
895904 if c .OpConfig .WALAZStorageAccount != "" {
896- envVars = append (envVars , v1.EnvVar {Name : "AZURE_STORAGE_ACCOUNT" , Value : c .OpConfig .WALAZStorageAccount })
897- envVars = append (envVars , v1.EnvVar {Name : "WAL_BUCKET_SCOPE_SUFFIX" , Value : getBucketScopeSuffix (string (uid ))})
898- envVars = append (envVars , v1.EnvVar {Name : "WAL_BUCKET_SCOPE_PREFIX" , Value : "" })
905+ envVars = appendEnvVars (envVars , v1.EnvVar {Name : "AZURE_STORAGE_ACCOUNT" , Value : c .OpConfig .WALAZStorageAccount })
906+ envVars = appendEnvVars (envVars , v1.EnvVar {Name : "WAL_BUCKET_SCOPE_SUFFIX" , Value : getBucketScopeSuffix (string (uid ))})
907+ envVars = appendEnvVars (envVars , v1.EnvVar {Name : "WAL_BUCKET_SCOPE_PREFIX" , Value : "" })
899908 }
900909
901910 if c .OpConfig .GCPCredentials != "" {
902- envVars = append (envVars , v1.EnvVar {Name : "GOOGLE_APPLICATION_CREDENTIALS" , Value : c .OpConfig .GCPCredentials })
911+ envVars = appendEnvVars (envVars , v1.EnvVar {Name : "GOOGLE_APPLICATION_CREDENTIALS" , Value : c .OpConfig .GCPCredentials })
903912 }
904913
905914 if c .OpConfig .LogS3Bucket != "" {
906- envVars = append (envVars , v1.EnvVar {Name : "LOG_S3_BUCKET" , Value : c .OpConfig .LogS3Bucket })
907- envVars = append (envVars , v1.EnvVar {Name : "LOG_BUCKET_SCOPE_SUFFIX" , Value : getBucketScopeSuffix (string (uid ))})
908- envVars = append (envVars , v1.EnvVar {Name : "LOG_BUCKET_SCOPE_PREFIX" , Value : "" })
915+ envVars = appendEnvVars (envVars , v1.EnvVar {Name : "LOG_S3_BUCKET" , Value : c .OpConfig .LogS3Bucket })
916+ envVars = appendEnvVars (envVars , v1.EnvVar {Name : "LOG_BUCKET_SCOPE_SUFFIX" , Value : getBucketScopeSuffix (string (uid ))})
917+ envVars = appendEnvVars (envVars , v1.EnvVar {Name : "LOG_BUCKET_SCOPE_PREFIX" , Value : "" })
909918 }
910919
911920 return envVars
912921}
913922
914- // deduplicateEnvVars makes sure there are no duplicate in the target envVar array. While Kubernetes already
915- // deduplicates variables defined in a container, it leaves the last definition in the list and this behavior is not
916- // well-documented, which means that the behavior can be reversed at some point (it may also start producing an error).
917- // Therefore, the merge is done by the operator, the entries that are ahead in the passed list take priority over those
918- // that are behind, and only the name is considered in order to eliminate duplicates.
919- func deduplicateEnvVars (input []v1.EnvVar , containerName string , logger * logrus.Entry ) []v1.EnvVar {
920- result := make ([]v1.EnvVar , 0 )
921- names := make (map [string ]int )
922-
923- for i , va := range input {
924- if names [va .Name ] == 0 {
925- names [va .Name ]++
926- result = append (result , input [i ])
927- } else if names [va .Name ] == 1 {
928- names [va .Name ]++
929-
930- // Some variables (those to configure the WAL_ and LOG_ shipping) may be overwritten, only log as info
931- if strings .HasPrefix (va .Name , "WAL_" ) || strings .HasPrefix (va .Name , "LOG_" ) {
932- logger .Infof ("global variable %q has been overwritten by configmap/secret for container %q" ,
933- va .Name , containerName )
934- } else {
935- logger .Warningf ("variable %q is defined in %q more than once, the subsequent definitions are ignored" ,
936- va .Name , containerName )
937- }
923+ func appendEnvVars (envs []v1.EnvVar , appEnv ... v1.EnvVar ) []v1.EnvVar {
924+ jenvs := envs
925+ for _ , env := range appEnv {
926+ if ! isEnvVarPresent (jenvs , env .Name ) {
927+ jenvs = append (jenvs , env )
938928 }
939929 }
940- return result
930+ return jenvs
931+ }
932+
933+ func isEnvVarPresent (envs []v1.EnvVar , key string ) bool {
934+ for _ , env := range envs {
935+ if env .Name == key {
936+ return true
937+ }
938+ }
939+ return false
941940}
942941
943- // Return list of variables the pod recieved from the configured ConfigMap
942+ // Return list of variables the pod received from the configured ConfigMap
944943func (c * Cluster ) getPodEnvironmentConfigMapVariables () ([]v1.EnvVar , error ) {
945944 configMapPodEnvVarsList := make ([]v1.EnvVar , 0 )
946945
@@ -1105,16 +1104,6 @@ func (c *Cluster) generateStatefulSet(spec *acidv1.PostgresSpec) (*appsv1.Statef
11051104 initContainers = spec .InitContainers
11061105 }
11071106
1108- spiloCompathWalPathList := make ([]v1.EnvVar , 0 )
1109- if c .OpConfig .EnableSpiloWalPathCompat {
1110- spiloCompathWalPathList = append (spiloCompathWalPathList ,
1111- v1.EnvVar {
1112- Name : "ENABLE_WAL_PATH_COMPAT" ,
1113- Value : "true" ,
1114- },
1115- )
1116- }
1117-
11181107 // fetch env vars from custom ConfigMap
11191108 configMapEnvVarsList , err := c .getPodEnvironmentConfigMapVariables ()
11201109 if err != nil {
@@ -1128,8 +1117,7 @@ func (c *Cluster) generateStatefulSet(spec *acidv1.PostgresSpec) (*appsv1.Statef
11281117 }
11291118
11301119 // concat all custom pod env vars and sort them
1131- customPodEnvVarsList := append (spiloCompathWalPathList , configMapEnvVarsList ... )
1132- customPodEnvVarsList = append (customPodEnvVarsList , secretEnvVarsList ... )
1120+ customPodEnvVarsList := append (configMapEnvVarsList , secretEnvVarsList ... )
11331121 sort .Slice (customPodEnvVarsList ,
11341122 func (i , j int ) bool { return customPodEnvVarsList [i ].Name < customPodEnvVarsList [j ].Name })
11351123
@@ -1210,7 +1198,7 @@ func (c *Cluster) generateStatefulSet(spec *acidv1.PostgresSpec) (*appsv1.Statef
12101198 // use the same filenames as Secret resources by default
12111199 certFile := ensurePath (spec .TLS .CertificateFile , mountPath , "tls.crt" )
12121200 privateKeyFile := ensurePath (spec .TLS .PrivateKeyFile , mountPath , "tls.key" )
1213- spiloEnvVars = append (
1201+ spiloEnvVars = appendEnvVars (
12141202 spiloEnvVars ,
12151203 v1.EnvVar {Name : "SSL_CERTIFICATE_FILE" , Value : certFile },
12161204 v1.EnvVar {Name : "SSL_PRIVATE_KEY_FILE" , Value : privateKeyFile },
@@ -1224,7 +1212,7 @@ func (c *Cluster) generateStatefulSet(spec *acidv1.PostgresSpec) (*appsv1.Statef
12241212 }
12251213
12261214 caFile := ensurePath (spec .TLS .CAFile , mountPathCA , "" )
1227- spiloEnvVars = append (
1215+ spiloEnvVars = appendEnvVars (
12281216 spiloEnvVars ,
12291217 v1.EnvVar {Name : "SSL_CA_FILE" , Value : caFile },
12301218 )
@@ -1249,7 +1237,7 @@ func (c *Cluster) generateStatefulSet(spec *acidv1.PostgresSpec) (*appsv1.Statef
12491237 spiloContainer := generateContainer (constants .PostgresContainerName ,
12501238 & effectiveDockerImage ,
12511239 resourceRequirements ,
1252- deduplicateEnvVars ( spiloEnvVars , constants . PostgresContainerName , c . logger ) ,
1240+ spiloEnvVars ,
12531241 volumeMounts ,
12541242 c .OpConfig .Resources .SpiloPrivileged ,
12551243 c .OpConfig .Resources .SpiloAllowPrivilegeEscalation ,
0 commit comments