diff --git a/kyaml/fn/runtime/container/container.go b/kyaml/fn/runtime/container/container.go index b37263f6c..4b82419d5 100644 --- a/kyaml/fn/runtime/container/container.go +++ b/kyaml/fn/runtime/container/container.go @@ -152,8 +152,6 @@ func (c *Filter) setupExec() { c.Exec.Args = args } -var tmpDirEnvKey string = "TMPDIR" - // getArgs returns the command + args to run to spawn the container func (c *Filter) getCommand() (string, []string) { // run the container using docker. this is simpler than using the docker @@ -175,7 +173,7 @@ func (c *Filter) getCommand() (string, []string) { args = append(args, "--mount", storageMount.String()) } - args = append(args, c.Env.GetDockerFlags()...) + args = append(args, runtimeutil.NewContainerEnvFromStringSlice(c.Env).GetDockerFlags()...) a := append(args, c.Image) return "docker", a } diff --git a/kyaml/fn/runtime/container/container_test.go b/kyaml/fn/runtime/container/container_test.go index 5921ee0f9..23d83c58d 100644 --- a/kyaml/fn/runtime/container/container_test.go +++ b/kyaml/fn/runtime/container/container_test.go @@ -6,7 +6,6 @@ package container import ( "bytes" "fmt" - "os" "testing" "github.com/stretchr/testify/assert" @@ -135,10 +134,11 @@ metadata: t.FailNow() } tt.instance.Exec.FunctionConfig = cfg - tt.instance.Env.AddKeyValue("KYAML_TEST", "FOO") + tt.instance.Env = append(tt.instance.Env, "KYAML_TEST=FOO") tt.instance.setupExec() - tt.expectedArgs = append(tt.expectedArgs, tt.instance.Env.GetDockerFlags()...) + tt.expectedArgs = append(tt.expectedArgs, + runtimeutil.NewContainerEnvFromStringSlice(tt.instance.Env).GetDockerFlags()...) tt.expectedArgs = append(tt.expectedArgs, tt.instance.Image) if !assert.Equal(t, "docker", tt.instance.Exec.Path) { @@ -238,15 +238,3 @@ func TestFilter_ExitCode(t *testing.T) { t.FailNow() } } - -func TestIgnoreEnv(t *testing.T) { - os.Setenv(tmpDirEnvKey, "") - - fltr := Filter{ContainerSpec: runtimeutil.ContainerSpec{Image: "example.com:version"}} - _, args := fltr.getCommand() - for _, arg := range args { - if arg == tmpDirEnvKey { - t.Fatalf("%s should not be exported to container", tmpDirEnvKey) - } - } -} diff --git a/kyaml/fn/runtime/runtimeutil/functiontypes.go b/kyaml/fn/runtime/runtimeutil/functiontypes.go index 95ccec112..36546bd74 100644 --- a/kyaml/fn/runtime/runtimeutil/functiontypes.go +++ b/kyaml/fn/runtime/runtimeutil/functiontypes.go @@ -102,6 +102,18 @@ func (ce *ContainerEnv) AddKey(key string) { } } +// Raw returns a slice of string which represents the envs. +// Example: [foo=bar, baz] +func (ce *ContainerEnv) Raw() []string { + var ret []string + for k, v := range ce.EnvVars { + ret = append(ret, k+"="+v) + } + + ret = append(ret, ce.VarsToExport...) + return ret +} + // NewContainerEnv returns a pointer to a new ContainerEnv func NewContainerEnv() *ContainerEnv { var ce ContainerEnv @@ -162,11 +174,8 @@ type ContainerSpec struct { // User is the username/uid that application runs as in continer User ContainerUser `json:"user,omitempty" yaml:"user,omitempty"` - // EnvRaw is a slice of env string. - EnvRaw []string `json:"envs,omitempty" yaml:"envs,omitempty"` - - // Env contains environment variables that will be exported to container - Env ContainerEnv `json:"-" yaml:"-"` + // Env is a slice of env string that will be exposed to container + Env []string `json:"envs,omitempty" yaml:"envs,omitempty"` } // ContainerNetwork @@ -230,7 +239,6 @@ func GetFunctionSpec(n *yaml.RNode) *FunctionSpec { if fn := getFunctionSpecFromAnnotation(n, meta); fn != nil { fn.Container.Network.Name = NetworkNameEmpty fn.StorageMounts = []StorageMount{} - fn.Container.Env = *NewContainerEnvFromStringSlice(fn.Container.EnvRaw) return fn } diff --git a/kyaml/fn/runtime/runtimeutil/runtimeutil_test.go b/kyaml/fn/runtime/runtimeutil/runtimeutil_test.go index 573ea1246..3083851b8 100644 --- a/kyaml/fn/runtime/runtimeutil/runtimeutil_test.go +++ b/kyaml/fn/runtime/runtimeutil/runtimeutil_test.go @@ -1514,6 +1514,6 @@ metadata: return } fn := GetFunctionSpec(cfg) - assert.Equal(t, tc.expected, fn.Container.Env) + assert.Equal(t, tc.expected, *NewContainerEnvFromStringSlice(fn.Container.Env)) } } diff --git a/kyaml/runfn/runfn.go b/kyaml/runfn/runfn.go index b3ce7281a..a2ab90dad 100644 --- a/kyaml/runfn/runfn.go +++ b/kyaml/runfn/runfn.go @@ -92,7 +92,7 @@ type RunFns struct { User runtimeutil.ContainerUser // Env contains environment variables that will be exported to container - Env runtimeutil.ContainerEnv + Env []string } // Execute runs the command @@ -274,16 +274,18 @@ func (r RunFns) getFunctionsFromFunctions() ([]kio.Filter, error) { // mergeContainerEnv will merge the envs specified by command line (imperative) and config // file (declarative). If they have same key, the imperative value will be respected. -func (r RunFns) mergeContainerEnv(envs runtimeutil.ContainerEnv) runtimeutil.ContainerEnv { - for key, value := range r.Env.EnvVars { - envs.AddKeyValue(key, value) +func (r RunFns) mergeContainerEnv(envs []string) []string { + imperative := runtimeutil.NewContainerEnvFromStringSlice(r.Env) + declarative := runtimeutil.NewContainerEnvFromStringSlice(envs) + for key, value := range imperative.EnvVars { + declarative.AddKeyValue(key, value) } - for _, key := range r.Env.VarsToExport { - envs.AddKey(key) + for _, key := range imperative.VarsToExport { + declarative.AddKey(key) } - return envs + return declarative.Raw() } func (r RunFns) getFunctionFilters(global bool, fns ...*yaml.RNode) ( diff --git a/kyaml/runfn/runfn_test.go b/kyaml/runfn/runfn_test.go index 8d10ffea3..dff30c4ef 100644 --- a/kyaml/runfn/runfn_test.go +++ b/kyaml/runfn/runfn_test.go @@ -991,43 +991,41 @@ func TestRunfns_mergeContainerEnv(t *testing.T) { testcases := []struct { name string instance RunFns - inputEnvs runtimeutil.ContainerEnv + inputEnvs []string expect runtimeutil.ContainerEnv }{ { - name: "all empty", - instance: RunFns{}, - inputEnvs: *runtimeutil.NewContainerEnv(), - expect: *runtimeutil.NewContainerEnv(), + name: "all empty", + instance: RunFns{}, + expect: *runtimeutil.NewContainerEnv(), }, { name: "empty command line envs", instance: RunFns{}, - inputEnvs: *runtimeutil.NewContainerEnvFromStringSlice([]string{"foo=bar"}), + inputEnvs: []string{"foo=bar"}, expect: *runtimeutil.NewContainerEnvFromStringSlice([]string{"foo=bar"}), }, { name: "empty declarative envs", instance: RunFns{ - Env: *runtimeutil.NewContainerEnvFromStringSlice([]string{"foo=bar"}), + Env: []string{"foo=bar"}, }, - inputEnvs: *runtimeutil.NewContainerEnv(), - expect: *runtimeutil.NewContainerEnvFromStringSlice([]string{"foo=bar"}), + expect: *runtimeutil.NewContainerEnvFromStringSlice([]string{"foo=bar"}), }, { name: "same key", instance: RunFns{ - Env: *runtimeutil.NewContainerEnvFromStringSlice([]string{"foo=bar", "foo"}), + Env: []string{"foo=bar", "foo"}, }, - inputEnvs: *runtimeutil.NewContainerEnvFromStringSlice([]string{"foo=bar1", "bar"}), + inputEnvs: []string{"foo=bar1", "bar"}, expect: *runtimeutil.NewContainerEnvFromStringSlice([]string{"foo=bar", "bar", "foo"}), }, { name: "same exported key", instance: RunFns{ - Env: *runtimeutil.NewContainerEnvFromStringSlice([]string{"foo=bar", "foo"}), + Env: []string{"foo=bar", "foo"}, }, - inputEnvs: *runtimeutil.NewContainerEnvFromStringSlice([]string{"foo1=bar1", "foo"}), + inputEnvs: []string{"foo1=bar1", "foo"}, expect: *runtimeutil.NewContainerEnvFromStringSlice([]string{"foo=bar", "foo1=bar1", "foo"}), }, } @@ -1036,7 +1034,7 @@ func TestRunfns_mergeContainerEnv(t *testing.T) { tc := testcases[i] t.Run(tc.name, func(t *testing.T) { envs := tc.instance.mergeContainerEnv(tc.inputEnvs) - assert.Equal(t, tc.expect.GetDockerFlags(), envs.GetDockerFlags()) + assert.Equal(t, tc.expect.GetDockerFlags(), runtimeutil.NewContainerEnvFromStringSlice(envs).GetDockerFlags()) }) } }