diff --git a/cmd/buildah/run.go b/cmd/buildah/run.go index 674e8d88ff7..c8e57833b22 100644 --- a/cmd/buildah/run.go +++ b/cmd/buildah/run.go @@ -27,6 +27,7 @@ type runInputOptions struct { mounts []string runtime string runtimeFlag []string + noHostname bool noHosts bool noPivot bool terminal bool @@ -70,6 +71,7 @@ func init() { // Do not set a default runtime here, we'll do that later in the processing. flags.StringVar(&opts.runtime, "runtime", util.Runtime(), "`path` to an alternate OCI runtime") flags.StringSliceVar(&opts.runtimeFlag, "runtime-flag", []string{}, "add global flags for the container runtime") + flags.BoolVar(&opts.noHostname, "no-hostname", false, "do not override the /etc/hostname file within the container") flags.BoolVar(&opts.noHosts, "no-hosts", false, "do not override the /etc/hosts file within the container") flags.BoolVar(&opts.noPivot, "no-pivot", false, "do not use pivot root to jail process inside rootfs") flags.BoolVarP(&opts.terminal, "terminal", "t", false, "allocate a pseudo-TTY in the container") @@ -137,10 +139,15 @@ func runCmd(c *cobra.Command, args []string, iopts runInputOptions) error { } } + if len(iopts.hostname) > 0 && iopts.noHostname { + return errors.New("--no-hostname and --hostname conflict, can not be used together") + } + options := buildah.RunOptions{ Hostname: iopts.hostname, Runtime: iopts.runtime, Args: runtimeFlags, + NoHostname: iopts.noHostname, NoHosts: iopts.noHosts, NoPivot: noPivot, User: c.Flag("user").Value.String(), diff --git a/define/build.go b/define/build.go index 59d2fcf10d7..95c9b910864 100644 --- a/define/build.go +++ b/define/build.go @@ -64,6 +64,9 @@ type CommonBuildOptions struct { LabelOpts []string // MemorySwap limits the amount of memory and swap together. MemorySwap int64 + // NoHostname tells the builder not to create /etc/hostname content when running + // containers. + NoHostname bool // NoHosts tells the builder not to create /etc/hosts content when running // containers. NoHosts bool diff --git a/docs/buildah-build.1.md b/docs/buildah-build.1.md index 3638ac66558..d4c2ea9f430 100644 --- a/docs/buildah-build.1.md +++ b/docs/buildah-build.1.md @@ -645,6 +645,13 @@ Valid _mode_ values are: Do not use existing cached images for the container build. Build from the start with a new set of cached layers. +**--no-hostname** + +Do not create _/etc/hostname_ for the container. + +By default, Buildah manages _/etc/hostname_, adding the container's own hostname. +**--no-hostname** disables this, and the image's _/etc/hostname_ will be preserved unmodified. + **--no-hosts** Do not create _/etc/hosts_ for the container. diff --git a/docs/buildah-run.1.md b/docs/buildah-run.1.md index 1bf157d99b1..619793acfbe 100644 --- a/docs/buildah-run.1.md +++ b/docs/buildah-run.1.md @@ -217,6 +217,13 @@ Valid _mode_ values are: host, using the loopback interface instead of the tap interface for improved performance +**--no-hostname** + +Do not create _/etc/hostname_ for the container. + +By default, Buildah manages _/etc/hostname_, adding the container's own hostname. +**--no-hostname** disables this, and the image's _/etc/hostname_ will be preserved unmodified. + **--no-hosts** Do not create _/etc/hosts_ for the container. diff --git a/imagebuildah/executor.go b/imagebuildah/executor.go index a5ee4293486..b9fd14b9bd1 100644 --- a/imagebuildah/executor.go +++ b/imagebuildah/executor.go @@ -103,6 +103,7 @@ type Executor struct { layerLabels []string annotations []string layers bool + noHostname bool noHosts bool useCache bool removeIntermediateCtrs bool @@ -270,6 +271,7 @@ func newExecutor(logger *logrus.Logger, logPrefix string, store storage.Store, o layerLabels: append([]string{}, options.LayerLabels...), annotations: append([]string{}, options.Annotations...), layers: options.Layers, + noHostname: options.CommonBuildOpts.NoHostname, noHosts: options.CommonBuildOpts.NoHosts, useCache: !options.NoCache, removeIntermediateCtrs: options.RemoveIntermediateCtrs, diff --git a/imagebuildah/stage_executor.go b/imagebuildah/stage_executor.go index c5325444718..d4d88699f77 100644 --- a/imagebuildah/stage_executor.go +++ b/imagebuildah/stage_executor.go @@ -622,6 +622,7 @@ func (s *StageExecutor) Run(run imagebuilder.Run, config docker.Config) error { Logger: s.executor.logger, Mounts: append([]Mount{}, s.executor.transientMounts...), NamespaceOptions: namespaceOptions, + NoHostname: s.executor.noHostname, NoHosts: s.executor.noHosts, NoPivot: os.Getenv("BUILDAH_NOPIVOT") != "", Quiet: s.executor.quiet, diff --git a/internal/mkcw/embed/entrypoint.gz b/internal/mkcw/embed/entrypoint.gz index 7f23fa15cad..810d9357d8e 100755 Binary files a/internal/mkcw/embed/entrypoint.gz and b/internal/mkcw/embed/entrypoint.gz differ diff --git a/pkg/cli/common.go b/pkg/cli/common.go index 99d59912612..cc6a883be26 100644 --- a/pkg/cli/common.go +++ b/pkg/cli/common.go @@ -76,6 +76,7 @@ type BudResults struct { Logfile string LogSplitByPlatform bool Manifest string + NoHostname bool NoHosts bool NoCache bool Timestamp int64 @@ -246,8 +247,9 @@ func GetBudFlags(flags *BudResults) pflag.FlagSet { panic(fmt.Sprintf("error marking the rusage-logfile flag as hidden: %v", err)) } fs.StringVar(&flags.Manifest, "manifest", "", "add the image to the specified manifest list. Creates manifest list if it does not exist") - fs.BoolVar(&flags.NoHosts, "no-hosts", false, "do not create new /etc/hosts files for RUN instructions, use the one from the base image.") fs.BoolVar(&flags.NoCache, "no-cache", false, "do not use existing cached images for the container build. Build from the start with a new set of cached layers.") + fs.BoolVar(&flags.NoHostname, "no-hostname", false, "do not create new /etc/hostname file for RUN instructions, use the one from the base image.") + fs.BoolVar(&flags.NoHosts, "no-hosts", false, "do not create new /etc/hosts file for RUN instructions, use the one from the base image.") fs.String("os", runtime.GOOS, "set the OS to the provided value instead of the current operating system of the host") fs.StringArrayVar(&flags.OSFeatures, "os-feature", []string{}, "set required OS `feature` for the target image in addition to values from the base image") fs.StringVar(&flags.OSVersion, "os-version", "", "set required OS `version` for the target image instead of the value from the base image") diff --git a/pkg/parse/parse.go b/pkg/parse/parse.go index 96ec3078a74..492d3dbee99 100644 --- a/pkg/parse/parse.go +++ b/pkg/parse/parse.go @@ -104,6 +104,7 @@ func CommonBuildOptionsFromFlagSet(flags *pflag.FlagSet, findFlagFunc func(name } } + noHostname, _ := flags.GetBool("no-hostname") noHosts, _ := flags.GetBool("no-hosts") addHost, _ := flags.GetStringSlice("add-host") @@ -183,6 +184,7 @@ func CommonBuildOptionsFromFlagSet(flags *pflag.FlagSet, findFlagFunc func(name IdentityLabel: types.NewOptionalBool(identityLabel), Memory: memoryLimit, MemorySwap: memorySwap, + NoHostname: noHostname, NoHosts: noHosts, OmitHistory: omitHistory, ShmSize: findFlagFunc("shm-size").Value.String(), diff --git a/run.go b/run.go index acb8aa9bfee..647853808bc 100644 --- a/run.go +++ b/run.go @@ -86,6 +86,8 @@ type RunOptions struct { Runtime string // Args adds global arguments for the runtime. Args []string + // NoHostname use the images /etc/hostname file + NoHostname bool // NoHosts use the images /etc/hosts file NoHosts bool // NoPivot adds the --no-pivot runtime flag. diff --git a/run_linux.go b/run_linux.go index 586b706dafd..473d84353dc 100644 --- a/run_linux.go +++ b/run_linux.go @@ -269,8 +269,7 @@ func (b *Builder) Run(command []string, options RunOptions) error { bindFiles[config.DefaultHostsFile] = hostFile } - // generate /etc/hostname if the user intentionally did not override - if !(contains(volumes, "/etc/hostname")) { + if !options.NoHostname && !(contains(volumes, "/etc/hostname")) { if _, ok := bindFiles["/etc/hostname"]; !ok { hostFile, err := b.generateHostname(path, spec.Hostname, rootIDPair) if err != nil { diff --git a/tests/bud.bats b/tests/bud.bats index 488e60a79b7..67491378c08 100644 --- a/tests/bud.bats +++ b/tests/bud.bats @@ -5258,6 +5258,37 @@ _EOF assert "$output" =~ ".*accepts at most 1 arg\(s\), received 2" "Should fail when passed extra arg after context directory" } +@test "bud with --no-hostname" { + skip_if_no_runtime + + _prefetch alpine + + mytmpdir=${TEST_SCRATCH_DIR}/my-dir + mkdir -p ${mytmpdir} + cat > $mytmpdir/Containerfile << _EOF +from alpine +run cat /etc/hostname +_EOF + + run_buildah build --no-cache -t testbud \ + $WITH_POLICY_JSON --file ${mytmpdir}/Containerfile . + assert "${lines[2]}" != "localhost" "Should be set to something other then localhost" + + run_buildah build --no-hostname --no-cache -t testbud \ + $WITH_POLICY_JSON --file ${mytmpdir}/Containerfile . + assert "${lines[2]}" == "localhost" "Should be set to localhost" + + cat > $mytmpdir/Containerfile << _EOF +from alpine +RUN mv /etc /usr/ +RUN ls -l /etc +_EOF + run_buildah 1 build --network=none --no-hostname --no-cache -t testbud \ + $WITH_POLICY_JSON --file ${mytmpdir}/Containerfile . + assert "$output" =~ ".*ls: /etc: No such file or directory" "/etc/ directory should be gone" + +} + @test "bud with --add-host" { skip_if_no_runtime diff --git a/tests/run.bats b/tests/run.bats index 7764be9e24f..e318d50e1c9 100644 --- a/tests/run.bats +++ b/tests/run.bats @@ -295,6 +295,16 @@ function configure_and_check_user() { hostname=$output run_buildah run --hostname foobar $cid cat /etc/hostname expect_output $hostname + run_buildah from --quiet --pull=false $WITH_POLICY_JSON alpine + cid=$output + run_buildah 125 run --no-hostname --hostname foobar $cid cat /etc/hostname + expect_output --substring 'no-hostname and --hostname conflict, can not be used together' + run_buildah inspect --format "{{ .ContainerID }}" $cid + id=$output + run_buildah run $cid cat /etc/hostname + expect_output "${id:0:12}" + run_buildah run --no-hostname $cid cat /etc/hostname + expect_output 'localhost' } @test "run --volume" {