buildah build: add a --env
Add a `--env` option to `buildah build` that functions similarly to the `buildah config --env` option, to complement `buildah build`'s `--unsetenv` option. Document that `buildah config`'s `--env` function fetches the current value for a variable when the name is supplied, but no `=` or value follows it. Signed-off-by: Nalin Dahyabhai <nalin@redhat.com>
This commit is contained in:
parent
0828507728
commit
4be3b7dec9
|
@ -394,6 +394,7 @@ func buildCmd(c *cobra.Command, inputArgs []string, iopts buildOptions) error {
|
|||
Timestamp: timestamp,
|
||||
Platforms: platforms,
|
||||
UnsetEnvs: iopts.UnsetEnvs,
|
||||
Envs: iopts.Envs,
|
||||
}
|
||||
if iopts.Quiet {
|
||||
options.ReportWriter = ioutil.Discard
|
||||
|
|
|
@ -226,7 +226,6 @@ func updateConfig(builder *buildah.Builder, c *cobra.Command, iopts configResult
|
|||
}
|
||||
env[1] = os.Expand(env[1], getenv)
|
||||
builder.SetEnv(env[0], env[1])
|
||||
|
||||
case env[0] == "-":
|
||||
builder.ClearEnv()
|
||||
case strings.HasSuffix(env[0], "-"):
|
||||
|
|
|
@ -102,6 +102,7 @@ type CommitOptions struct {
|
|||
// indexing. i.e. 0 is the first layer, -1 is the last (top-most) layer.
|
||||
OciEncryptLayers *[]int
|
||||
// UnsetEnvs is a list of environments to not add to final image.
|
||||
// Deprecated: use UnsetEnv() before committing instead.
|
||||
UnsetEnvs []string
|
||||
}
|
||||
|
||||
|
|
|
@ -260,4 +260,6 @@ type BuildOptions struct {
|
|||
AllPlatforms bool
|
||||
// UnsetEnvs is a list of environments to not add to final image.
|
||||
UnsetEnvs []string
|
||||
// Envs is a list of environment variables to set in the final image.
|
||||
Envs []string
|
||||
}
|
||||
|
|
|
@ -241,6 +241,14 @@ Set custom DNS options
|
|||
|
||||
Set custom DNS search domains
|
||||
|
||||
**--env** *env[=value]*
|
||||
|
||||
Add a value (e.g. env=*value*) to the built image. Can be used multiple times.
|
||||
If neither `=` nor a `*value*` are specified, but *env* is set in the current
|
||||
environment, the value from the current environment will be added to the image.
|
||||
To remove an environment variable from the built image, use the `--unsetenv`
|
||||
option.
|
||||
|
||||
**--file**, **-f** *Containerfile*
|
||||
|
||||
Specifies a Containerfile which contains instructions for building the image,
|
||||
|
@ -829,6 +837,12 @@ buildah build -f Containerfile.in -t imageName .
|
|||
|
||||
buildah build --network mynet .
|
||||
|
||||
buildah build --env LANG=en_US.UTF-8 -t imageName .
|
||||
|
||||
buildah build --env EDITOR -t imageName .
|
||||
|
||||
buildah build --unsetenv LANG -t imageName .
|
||||
|
||||
### Building an multi-architecture image using the --manifest option (requires emulation software)
|
||||
|
||||
buildah build --arch arm --manifest myimage /tmp/mysrc
|
||||
|
|
|
@ -77,10 +77,12 @@ ignore the `cmd` value of the container image. However if you use the array
|
|||
form, then the cmd will be appended onto the end of the entrypoint cmd and be
|
||||
executed together.
|
||||
|
||||
**--env**, **-e** *env=value*
|
||||
**--env**, **-e** *env[=value]*
|
||||
|
||||
Add a value (e.g. env=*value*) to the environment for containers based on any
|
||||
images which will be built using the specified container. Can be used multiple times.
|
||||
If *env* is named but neither `=` nor a `value` is specified, then the value
|
||||
will be taken from the current process environment.
|
||||
If *env* has a trailing `-`, then the *env* is removed from the config.
|
||||
If the *env* is set to "-" then all environment variables are removed from the config.
|
||||
|
||||
|
@ -229,6 +231,8 @@ buildah config --volume /usr/myvol- containerID
|
|||
|
||||
buildah config --port 1234 --port 8080 containerID
|
||||
|
||||
buildah config --env 1234=5678 containerID
|
||||
|
||||
buildah config --env 1234- containerID
|
||||
|
||||
## SEE ALSO
|
||||
|
|
|
@ -134,6 +134,7 @@ type Executor struct {
|
|||
processLabel string // Shares processLabel of first stage container with containers of other stages in same build
|
||||
mountLabel string // Shares mountLabel of first stage container with containers of other stages in same build
|
||||
buildOutput string // Specifies instructions for any custom build output
|
||||
envs []string
|
||||
}
|
||||
|
||||
type imageTypeAndHistoryAndDiffIDs struct {
|
||||
|
@ -276,8 +277,9 @@ func newExecutor(logger *logrus.Logger, logPrefix string, store storage.Store, o
|
|||
secrets: secrets,
|
||||
sshsources: sshsources,
|
||||
logPrefix: logPrefix,
|
||||
unsetEnvs: options.UnsetEnvs,
|
||||
unsetEnvs: append([]string{}, options.UnsetEnvs...),
|
||||
buildOutput: options.BuildOutput,
|
||||
envs: append([]string{}, options.Envs...),
|
||||
}
|
||||
if exec.err == nil {
|
||||
exec.err = os.Stderr
|
||||
|
|
|
@ -1494,6 +1494,28 @@ func (s *StageExecutor) commit(ctx context.Context, createdBy string, emptyLayer
|
|||
spec := strings.SplitN(envSpec, "=", 2)
|
||||
s.builder.SetEnv(spec[0], spec[1])
|
||||
}
|
||||
for _, envSpec := range s.executor.envs {
|
||||
env := strings.SplitN(envSpec, "=", 2)
|
||||
if len(env) > 1 {
|
||||
getenv := func(name string) string {
|
||||
for _, envvar := range s.builder.Env() {
|
||||
val := strings.SplitN(envvar, "=", 2)
|
||||
if len(val) == 2 && val[0] == name {
|
||||
return val[1]
|
||||
}
|
||||
}
|
||||
logrus.Errorf("error expanding variable %q: no value set in image", name)
|
||||
return name
|
||||
}
|
||||
env[1] = os.Expand(env[1], getenv)
|
||||
s.builder.SetEnv(env[0], env[1])
|
||||
} else {
|
||||
s.builder.SetEnv(env[0], os.Getenv(env[0]))
|
||||
}
|
||||
}
|
||||
for _, envSpec := range s.executor.unsetEnvs {
|
||||
s.builder.UnsetEnv(envSpec)
|
||||
}
|
||||
s.builder.SetCmd(config.Cmd)
|
||||
s.builder.ClearVolumes()
|
||||
for v := range config.Volumes {
|
||||
|
@ -1566,7 +1588,6 @@ func (s *StageExecutor) commit(ctx context.Context, createdBy string, emptyLayer
|
|||
RetryDelay: s.executor.retryPullPushDelay,
|
||||
HistoryTimestamp: s.executor.timestamp,
|
||||
Manifest: s.executor.manifest,
|
||||
UnsetEnvs: s.executor.unsetEnvs,
|
||||
}
|
||||
// generate build output
|
||||
if s.executor.buildOutput != "" {
|
||||
|
|
|
@ -92,6 +92,7 @@ type BudResults struct {
|
|||
LogRusage bool
|
||||
RusageLogFile string
|
||||
UnsetEnvs []string
|
||||
Envs []string
|
||||
}
|
||||
|
||||
// FromAndBugResults represents the results for common flags
|
||||
|
@ -194,6 +195,7 @@ func GetBudFlags(flags *BudResults) pflag.FlagSet {
|
|||
fs.StringVar(&flags.Creds, "creds", "", "use `[username[:password]]` for accessing the registry")
|
||||
fs.BoolVarP(&flags.DisableCompression, "disable-compression", "D", true, "don't compress layers by default")
|
||||
fs.BoolVar(&flags.DisableContentTrust, "disable-content-trust", false, "This is a Docker specific option and is a NOOP")
|
||||
fs.StringArrayVar(&flags.Envs, "env", []string{}, "set environment variable for the image")
|
||||
fs.StringVar(&flags.From, "from", "", "image name used to replace the value in the first FROM instruction in the Containerfile")
|
||||
fs.StringVar(&flags.IgnoreFile, "ignorefile", "", "path to an alternate .dockerignore file")
|
||||
fs.StringSliceVarP(&flags.File, "file", "f", []string{}, "`pathname or URL` of a Dockerfile")
|
||||
|
@ -262,6 +264,7 @@ func GetBudFlagsCompletions() commonComp.FlagCompletions {
|
|||
flagCompletion["cache-from"] = commonComp.AutocompleteNone
|
||||
flagCompletion["cert-dir"] = commonComp.AutocompleteDefault
|
||||
flagCompletion["creds"] = commonComp.AutocompleteNone
|
||||
flagCompletion["env"] = commonComp.AutocompleteNone
|
||||
flagCompletion["file"] = commonComp.AutocompleteDefault
|
||||
flagCompletion["from"] = commonComp.AutocompleteDefault
|
||||
flagCompletion["format"] = commonComp.AutocompleteNone
|
||||
|
|
|
@ -582,6 +582,25 @@ _EOF
|
|||
expect_output "[container=buildah date=tomorrow]" "No Path should be defined"
|
||||
}
|
||||
|
||||
@test "bud with --env" {
|
||||
target=scratch-image
|
||||
run_buildah build --quiet=false --iidfile ${TEST_SCRATCH_DIR}/output.iid --env PATH $WITH_POLICY_JSON -t ${target} $BUDFILES/from-scratch
|
||||
iid=$(cat ${TEST_SCRATCH_DIR}/output.iid)
|
||||
run_buildah inspect --format '{{.Docker.Config.Env}}' $iid
|
||||
expect_output "[PATH=$PATH]"
|
||||
|
||||
run_buildah build --quiet=false --iidfile ${TEST_SCRATCH_DIR}/output.iid --env PATH=foo $WITH_POLICY_JSON -t ${target} $BUDFILES/from-scratch
|
||||
iid=$(cat ${TEST_SCRATCH_DIR}/output.iid)
|
||||
run_buildah inspect --format '{{.Docker.Config.Env}}' $iid
|
||||
expect_output "[PATH=foo]"
|
||||
|
||||
# --unsetenv takes precedence over --env, since we don't know the relative order of the two
|
||||
run_buildah build --quiet=false --iidfile ${TEST_SCRATCH_DIR}/output.iid --unsetenv PATH --env PATH=foo --env PATH= $WITH_POLICY_JSON -t ${target} $BUDFILES/from-scratch
|
||||
iid=$(cat ${TEST_SCRATCH_DIR}/output.iid)
|
||||
run_buildah inspect --format '{{.Docker.Config.Env}}' $iid
|
||||
expect_output "[]"
|
||||
}
|
||||
|
||||
@test "build with custom build output and output rootfs to directory" {
|
||||
_prefetch alpine
|
||||
mytmpdir=${TEST_SCRATCH_DIR}/my-dir
|
||||
|
@ -659,7 +678,7 @@ _EOF
|
|||
expect_output "" "no base name for untagged base image"
|
||||
}
|
||||
|
||||
@test "bud with --tag " {
|
||||
@test "bud with --tag" {
|
||||
target=scratch-image
|
||||
run_buildah build --quiet=false --tag test1 $WITH_POLICY_JSON -t ${target} $BUDFILES/from-scratch
|
||||
expect_output --substring "Successfully tagged localhost/test1:latest"
|
||||
|
@ -669,7 +688,7 @@ _EOF
|
|||
expect_output --substring "Successfully tagged localhost/test2:latest"
|
||||
}
|
||||
|
||||
@test "bud with bad --tag " {
|
||||
@test "bud with bad --tag" {
|
||||
target=scratch-image
|
||||
run_buildah 125 build --quiet=false --tag TEST1 $WITH_POLICY_JSON -t ${target} $BUDFILES/from-scratch
|
||||
expect_output --substring "tag TEST1: invalid reference format: repository name must be lowercase"
|
||||
|
|
Loading…
Reference in New Issue