diff options
author | Aditya R <arajan@redhat.com> | 2022-08-24 11:22:33 +0530 |
---|---|---|
committer | Aditya R <arajan@redhat.com> | 2022-08-24 14:06:25 +0530 |
commit | b4584ea8546be227c74174130ec3a04a93996d28 (patch) | |
tree | a18b2250fbbbc64f297415df7e27b37c2e659352 | |
parent | 2538bea8da2a4dba96f1c80594a66f6319d2d872 (diff) | |
download | podman-b4584ea8546be227c74174130ec3a04a93996d28.tar.gz podman-b4584ea8546be227c74174130ec3a04a93996d28.tar.bz2 podman-b4584ea8546be227c74174130ec3a04a93996d28.zip |
run,create: add support for --env-merge for preprocessing vars
Allow end users to preprocess default environment variables before
injecting them into container using `--env-merge`
Usage
```
podman run -it --rm --env-merge some=${some}-edit --env-merge
some2=${some2}-edit2 myimage sh
```
Closes: https://github.com/containers/podman/issues/15288
Signed-off-by: Aditya R <arajan@redhat.com>
-rw-r--r-- | cmd/podman/common/create.go | 8 | ||||
-rw-r--r-- | docs/source/markdown/options/env-merge.md | 5 | ||||
-rw-r--r-- | docs/source/markdown/podman-create.1.md.in | 2 | ||||
-rw-r--r-- | docs/source/markdown/podman-run.1.md.in | 2 | ||||
-rw-r--r-- | go.mod | 1 | ||||
-rw-r--r-- | pkg/api/handlers/compat/containers_create.go | 1 | ||||
-rw-r--r-- | pkg/api/handlers/types.go | 1 | ||||
-rw-r--r-- | pkg/domain/entities/pods.go | 1 | ||||
-rw-r--r-- | pkg/specgen/generate/container.go | 12 | ||||
-rw-r--r-- | pkg/specgen/specgen.go | 3 | ||||
-rw-r--r-- | pkg/specgenutil/specgen.go | 3 | ||||
-rw-r--r-- | test/e2e/run_env_test.go | 11 | ||||
-rw-r--r-- | vendor/modules.txt | 1 |
13 files changed, 51 insertions, 0 deletions
diff --git a/cmd/podman/common/create.go b/cmd/podman/common/create.go index 00873b95b..1e573cc2d 100644 --- a/cmd/podman/common/create.go +++ b/cmd/podman/common/create.go @@ -124,6 +124,14 @@ func DefineCreateFlags(cmd *cobra.Command, cf *entities.ContainerCreateOptions, "This is a Docker specific option and is a NOOP", ) + envMergeFlagName := "env-merge" + createFlags.StringArrayVar( + &cf.EnvMerge, + envMergeFlagName, []string{}, + "Preprocess environment variables from image before injecting them into the container", + ) + _ = cmd.RegisterFlagCompletionFunc(envMergeFlagName, completion.AutocompleteNone) + envFlagName := "env" createFlags.StringArrayP( envFlagName, "e", Env(), diff --git a/docs/source/markdown/options/env-merge.md b/docs/source/markdown/options/env-merge.md new file mode 100644 index 000000000..aa1aa003d --- /dev/null +++ b/docs/source/markdown/options/env-merge.md @@ -0,0 +1,5 @@ +#### **--env-merge**=*env* + +Preprocess default environment variables for the containers. For example +if image contains environment variable `hello=world` user can preprocess +it using `--env-merge hello=${hello}-some` so new value will be `hello=world-some`. diff --git a/docs/source/markdown/podman-create.1.md.in b/docs/source/markdown/podman-create.1.md.in index 9518568bb..0e65e7e3a 100644 --- a/docs/source/markdown/podman-create.1.md.in +++ b/docs/source/markdown/podman-create.1.md.in @@ -208,6 +208,8 @@ Read in a line delimited file of environment variables. See **Environment** note @@option env-host +@@option env-merge + @@option expose #### **--gidmap**=*container_gid:host_gid:amount* diff --git a/docs/source/markdown/podman-run.1.md.in b/docs/source/markdown/podman-run.1.md.in index 3e31ccc45..98d57a9c1 100644 --- a/docs/source/markdown/podman-run.1.md.in +++ b/docs/source/markdown/podman-run.1.md.in @@ -243,6 +243,8 @@ Read in a line delimited file of environment variables. See **Environment** note @@option env-host +@@option env-merge + @@option expose #### **--gidmap**=*container_gid:host_gid:amount* @@ -49,6 +49,7 @@ require ( github.com/opencontainers/runtime-spec v1.0.3-0.20211214071223-8958f93039ab github.com/opencontainers/runtime-tools v0.9.1-0.20220714195903-17b3287fafb7 github.com/opencontainers/selinux v1.10.1 + github.com/openshift/imagebuilder v1.2.4-0.20220711175835-4151e43600df github.com/rootless-containers/rootlesskit v1.0.1 github.com/sirupsen/logrus v1.9.0 github.com/spf13/cobra v1.5.0 diff --git a/pkg/api/handlers/compat/containers_create.go b/pkg/api/handlers/compat/containers_create.go index 9fff8b4c8..d4f5d5f36 100644 --- a/pkg/api/handlers/compat/containers_create.go +++ b/pkg/api/handlers/compat/containers_create.go @@ -408,6 +408,7 @@ func cliOpts(cc handlers.CreateContainerConfig, rtc *config.Config) (*entities.C Systemd: "true", // podman default TmpFS: parsedTmp, TTY: cc.Config.Tty, + EnvMerge: cc.EnvMerge, UnsetEnv: cc.UnsetEnv, UnsetEnvAll: cc.UnsetEnvAll, User: cc.Config.User, diff --git a/pkg/api/handlers/types.go b/pkg/api/handlers/types.go index b533e131c..ebbc5f63a 100644 --- a/pkg/api/handlers/types.go +++ b/pkg/api/handlers/types.go @@ -127,6 +127,7 @@ type CreateContainerConfig struct { dockerContainer.Config // desired container configuration HostConfig dockerContainer.HostConfig // host dependent configuration for container NetworkingConfig dockerNetwork.NetworkingConfig // network configuration for container + EnvMerge []string // preprocess env variables from image before injecting into containers UnsetEnv []string // unset specified default environment variables UnsetEnvAll bool // unset all default environment variables } diff --git a/pkg/domain/entities/pods.go b/pkg/domain/entities/pods.go index 14ce370c1..33ca2c807 100644 --- a/pkg/domain/entities/pods.go +++ b/pkg/domain/entities/pods.go @@ -263,6 +263,7 @@ type ContainerCreateOptions struct { TTY bool Timezone string Umask string + EnvMerge []string UnsetEnv []string UnsetEnvAll bool UIDMap []string diff --git a/pkg/specgen/generate/container.go b/pkg/specgen/generate/container.go index 85cd8f5ca..e293ce010 100644 --- a/pkg/specgen/generate/container.go +++ b/pkg/specgen/generate/container.go @@ -19,6 +19,7 @@ import ( "github.com/containers/podman/v4/pkg/signal" "github.com/containers/podman/v4/pkg/specgen" spec "github.com/opencontainers/runtime-spec/specs-go" + "github.com/openshift/imagebuilder" "github.com/sirupsen/logrus" "golang.org/x/sys/unix" ) @@ -131,6 +132,17 @@ func CompleteSpec(ctx context.Context, r *libpod.Runtime, s *specgen.SpecGenerat defaultEnvs = envLib.Join(envLib.DefaultEnvVariables(), envLib.Join(defaultEnvs, envs)) } + for _, e := range s.EnvMerge { + processedWord, err := imagebuilder.ProcessWord(e, envLib.Slice(defaultEnvs)) + if err != nil { + return nil, fmt.Errorf("unable to process variables for --env-merge %s: %w", e, err) + } + splitWord := strings.Split(processedWord, "=") + if _, ok := defaultEnvs[splitWord[0]]; ok { + defaultEnvs[splitWord[0]] = splitWord[1] + } + } + for _, e := range s.UnsetEnv { delete(defaultEnvs, e) } diff --git a/pkg/specgen/specgen.go b/pkg/specgen/specgen.go index b90f07ef8..51b6736a9 100644 --- a/pkg/specgen/specgen.go +++ b/pkg/specgen/specgen.go @@ -204,6 +204,9 @@ type ContainerBasicConfig struct { // The execution domain system allows Linux to provide limited support // for binaries compiled under other UNIX-like operating systems. Personality *spec.LinuxPersonality `json:"personality,omitempty"` + // EnvMerge takes the specified environment variables from image and preprocess them before injecting them into the + // container. + EnvMerge []string `json:"envmerge,omitempty"` // UnsetEnv unsets the specified default environment variables from the image or from buildin or containers.conf // Optional. UnsetEnv []string `json:"unsetenv,omitempty"` diff --git a/pkg/specgenutil/specgen.go b/pkg/specgenutil/specgen.go index 7392e7b44..aab2eebd5 100644 --- a/pkg/specgenutil/specgen.go +++ b/pkg/specgenutil/specgen.go @@ -839,6 +839,9 @@ func FillOutSpecGen(s *specgen.SpecGenerator, c *entities.ContainerCreateOptions if !s.Volatile { s.Volatile = c.Rm } + if len(s.EnvMerge) == 0 || len(c.EnvMerge) != 0 { + s.EnvMerge = c.EnvMerge + } if len(s.UnsetEnv) == 0 || len(c.UnsetEnv) != 0 { s.UnsetEnv = c.UnsetEnv } diff --git a/test/e2e/run_env_test.go b/test/e2e/run_env_test.go index bab52efc5..9e78e150a 100644 --- a/test/e2e/run_env_test.go +++ b/test/e2e/run_env_test.go @@ -82,6 +82,17 @@ var _ = Describe("Podman run", func() { Expect(session.OutputToString()).To(ContainSubstring("HOSTNAME")) }) + It("podman run with --env-merge", func() { + dockerfile := `FROM quay.io/libpod/alpine:latest +ENV hello=world +` + podmanTest.BuildImage(dockerfile, "test", "false") + session := podmanTest.Podman([]string{"run", "--rm", "--env-merge", "hello=${hello}-earth", "test", "env"}) + session.WaitWithDefaultTimeout() + Expect(session).Should(Exit(0)) + Expect(session.OutputToString()).To(ContainSubstring("world-earth")) + }) + It("podman run --env-host environment test", func() { env := append(os.Environ(), "FOO=BAR") session := podmanTest.PodmanAsUser([]string{"run", "--rm", "--env-host", ALPINE, "/bin/printenv", "FOO"}, 0, 0, "", env) diff --git a/vendor/modules.txt b/vendor/modules.txt index eb9c7a34d..feb9f00d5 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -620,6 +620,7 @@ github.com/opencontainers/selinux/go-selinux/label github.com/opencontainers/selinux/pkg/pwalk github.com/opencontainers/selinux/pkg/pwalkdir # github.com/openshift/imagebuilder v1.2.4-0.20220711175835-4151e43600df +## explicit github.com/openshift/imagebuilder github.com/openshift/imagebuilder/dockerfile/command github.com/openshift/imagebuilder/dockerfile/parser |