diff --git a/server/container_create.go b/server/container_create.go index a59bca63..0f581c00 100644 --- a/server/container_create.go +++ b/server/container_create.go @@ -1115,30 +1115,10 @@ func (s *Server) createSandboxContainer(ctx context.Context, containerID string, } specgen.SetProcessArgs(processArgs) - // Add environment variables from CRI and image config - envs := containerConfig.GetEnvs() - if envs != nil { - for _, item := range envs { - key := item.Key - value := item.Value - if key == "" { - continue - } - specgen.AddProcessEnv(key, value) - } - } - if containerImageConfig != nil { - for _, item := range containerImageConfig.Config.Env { - parts := strings.SplitN(item, "=", 2) - if len(parts) != 2 { - return nil, fmt.Errorf("invalid env from image: %s", item) - } - - if parts[0] == "" { - continue - } - specgen.AddProcessEnv(parts[0], parts[1]) - } + envs := mergeEnvs(containerImageConfig, containerConfig.GetEnvs()) + for _, e := range envs { + parts := strings.SplitN(e, "=", 2) + specgen.AddProcessEnv(parts[0], parts[1]) } // Set working directory diff --git a/server/utils.go b/server/utils.go index 2a15ab42..66c57757 100644 --- a/server/utils.go +++ b/server/utils.go @@ -10,8 +10,10 @@ import ( "github.com/cri-o/ocicni/pkg/ocicni" "github.com/kubernetes-incubator/cri-o/libkpod/sandbox" "github.com/kubernetes-incubator/cri-o/server/metrics" + "github.com/opencontainers/image-spec/specs-go/v1" "github.com/opencontainers/runtime-tools/validate" "github.com/syndtr/gocapability/capability" + pb "k8s.io/kubernetes/pkg/kubelet/apis/cri/v1alpha1/runtime" ) const ( @@ -210,3 +212,44 @@ func validateLabels(labels map[string]string) error { } return nil } + +func mergeEnvs(imageConfig *v1.Image, kubeEnvs []*pb.KeyValue) []string { + envs := []string{} + if kubeEnvs == nil && imageConfig != nil { + envs = imageConfig.Config.Env + } else { + for _, item := range kubeEnvs { + if item.GetKey() == "" { + continue + } + envs = append(envs, item.GetKey()+"="+item.GetValue()) + } + if imageConfig != nil { + for _, imageEnv := range imageConfig.Config.Env { + var found bool + parts := strings.SplitN(imageEnv, "=", 2) + if len(parts) != 2 { + continue + } + imageEnvKey := parts[0] + if imageEnvKey == "" { + continue + } + for _, kubeEnv := range envs { + kubeEnvKey := strings.SplitN(kubeEnv, "=", 2)[0] + if kubeEnvKey == "" { + continue + } + if imageEnvKey == kubeEnvKey { + found = true + break + } + } + if !found { + envs = append(envs, imageEnv) + } + } + } + } + return envs +} diff --git a/server/utils_test.go b/server/utils_test.go index b68f0f81..f943c2ea 100644 --- a/server/utils_test.go +++ b/server/utils_test.go @@ -4,6 +4,9 @@ import ( "io/ioutil" "os" "testing" + + "github.com/opencontainers/image-spec/specs-go/v1" + pb "k8s.io/kubernetes/pkg/kubelet/apis/cri/v1alpha1/runtime" ) const ( @@ -108,3 +111,33 @@ func TestSysctlsFromPodAnnotations(t *testing.T) { } } } + +func TestMergeEnvs(t *testing.T) { + configImage := &v1.Image{ + Config: v1.ImageConfig{ + Env: []string{"VAR1=1", "VAR2=2"}, + }, + } + + configKube := []*pb.KeyValue{ + { + Key: "VAR2", + Value: "3", + }, + { + Key: "VAR3", + Value: "3", + }, + } + + mergedEnvs := mergeEnvs(configImage, configKube) + + if len(mergedEnvs) != 3 { + t.Fatalf("Expected 3 env var, VAR1=1, VAR2=3 and VAR3=3, found %d", len(mergedEnvs)) + } + for _, env := range mergedEnvs { + if env != "VAR1=1" && env != "VAR2=3" && env != "VAR3=3" { + t.Fatalf("Expected VAR1=1 or VAR2=3 or VAR3=3, found %s", env) + } + } +}