diff --git a/cmd/buildah/run.go b/cmd/buildah/run.go index 674e8d88f..a7c16971b 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") @@ -141,6 +143,7 @@ func runCmd(c *cobra.Command, args []string, iopts runInputOptions) error { 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 59d2fcf10..95c9b9108 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 3638ac665..c2ebe95af 100644 --- a/docs/buildah-build.1.md +++ b/docs/buildah-build.1.md @@ -645,9 +645,15 @@ 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 the _/etc/hostname_ file in the container for RUN instructions. + +By default, Buildah manages the _/etc/hostname_ file, adding the container's own hostname. When the **--no-hostname** option is set, the image's _/etc/hostname_ will be preserved unmodified if it exists. + **--no-hosts** -Do not create _/etc/hosts_ for the container. +Do not create the _/etc/hosts_ file in the container for RUN instructions. By default, Buildah manages _/etc/hosts_, adding the container's own IP address. **--no-hosts** disables this, and the image's _/etc/hosts_ will be preserved unmodified. Conflicts with the --add-host option. diff --git a/docs/buildah-run.1.md b/docs/buildah-run.1.md index 1bf157d99..d96ddef3d 100644 --- a/docs/buildah-run.1.md +++ b/docs/buildah-run.1.md @@ -217,9 +217,15 @@ Valid _mode_ values are: host, using the loopback interface instead of the tap interface for improved performance +**--no-hostname** + +Do not create the _/etc/hostname_ file in the container for RUN instructions. + +By default, Buildah manages the _/etc/hostname_ file, adding the container's own hostname. When the **--no-hostname** option is set, the image's _/etc/hostname_ will be preserved unmodified if it exists. + **--no-hosts** -Do not create _/etc/hosts_ for the container. +Do not create the _/etc/hosts_ file in the container for RUN instructions. By default, Buildah manages _/etc/hosts_, adding the container's own IP address. **--no-hosts** disables this, and the image's _/etc/hosts_ will be preserved unmodified. diff --git a/imagebuildah/executor.go b/imagebuildah/executor.go index faff61418..5efaede65 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 c53254447..d4d88699f 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/pkg/cli/common.go b/pkg/cli/common.go index b4c95adcd..3038ad236 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 96ec3078a..492d3dbee 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 acb8aa9bf..77887dfe8 100644 --- a/run.go +++ b/run.go @@ -86,7 +86,9 @@ type RunOptions struct { Runtime string // Args adds global arguments for the runtime. Args []string - // NoHosts use the images /etc/hosts file + // NoHostname won't create new /etc/hostname file + NoHostname bool + // NoHosts won't create new /etc/hosts file NoHosts bool // NoPivot adds the --no-pivot runtime flag. NoPivot bool diff --git a/run_linux.go b/run_linux.go index 586b706da..718f5db80 100644 --- a/run_linux.go +++ b/run_linux.go @@ -269,16 +269,13 @@ 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 _, ok := bindFiles["/etc/hostname"]; !ok { - hostFile, err := b.generateHostname(path, spec.Hostname, rootIDPair) - if err != nil { - return err - } - // Bind /etc/hostname - bindFiles["/etc/hostname"] = hostFile + if !options.NoHostname && !(contains(volumes, "/etc/hostname")) { + hostFile, err := b.generateHostname(path, spec.Hostname, rootIDPair) + if err != nil { + return err } + // Bind /etc/hostname + bindFiles["/etc/hostname"] = hostFile } if !contains(volumes, resolvconf.DefaultResolvConf) && options.ConfigureNetwork != define.NetworkDisabled && !(len(b.CommonBuildOpts.DNSServers) == 1 && strings.ToLower(b.CommonBuildOpts.DNSServers[0]) == "none") { diff --git a/tests/bud.bats b/tests/bud.bats index 488e60a79..a4060f922 100644 --- a/tests/bud.bats +++ b/tests/bud.bats @@ -5258,6 +5258,27 @@ _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 + + run_buildah build --no-cache -t testbud \ + $WITH_POLICY_JSON $BUDFILES/no-hostname + assert "${lines[2]}" != "localhost" "Should be set to something other then localhost" + + run_buildah build --no-hostname --no-cache -t testbud \ + $WITH_POLICY_JSON \ + $BUDFILES/no-hostname + assert "${lines[2]}" == "localhost" "Should be set to localhost" + + run_buildah 1 build --network=none --no-hostname --no-cache -t testbud \ + $WITH_POLICY_JSON \ + -f $BUDFILES/no-hostname/Containerfile.noetc \ + $BUDFILES/no-hostname + 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/bud/no-hostname/Containerfile b/tests/bud/no-hostname/Containerfile new file mode 100644 index 000000000..3fe1bb65f --- /dev/null +++ b/tests/bud/no-hostname/Containerfile @@ -0,0 +1,3 @@ +from alpine +run cat /etc/hostname + diff --git a/tests/bud/no-hostname/Containerfile.noetc b/tests/bud/no-hostname/Containerfile.noetc new file mode 100644 index 000000000..5df7822af --- /dev/null +++ b/tests/bud/no-hostname/Containerfile.noetc @@ -0,0 +1,3 @@ +from alpine +RUN mv /etc /usr/ +RUN ls -l /etc diff --git a/tests/run.bats b/tests/run.bats index 7764be9e2..5be689556 100644 --- a/tests/run.bats +++ b/tests/run.bats @@ -295,6 +295,14 @@ 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 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" {