diff --git a/libpod/container_internal_linux.go b/libpod/container_internal_linux.go index 05b149e03f..cefe122099 100644 --- a/libpod/container_internal_linux.go +++ b/libpod/container_internal_linux.go @@ -529,14 +529,37 @@ func (c *Container) generateSpec(ctx context.Context) (*spec.Spec, error) { } } + // Hostname handling: + // If we have a UTS namespace, set Hostname in the OCI spec. + // Set the HOSTNAME environment variable unless explicitly overridden by + // the user (already present in OCI spec). If we don't have a UTS ns, + // set it to the host's hostname instead. + hostname := c.Hostname() + foundUTS := false for _, i := range c.config.Spec.Linux.Namespaces { if i.Type == spec.UTSNamespace && i.Path == "" { - hostname := c.Hostname() + foundUTS = true g.SetHostname(hostname) - g.AddProcessEnv("HOSTNAME", hostname) break } } + if !foundUTS { + tmpHostname, err := os.Hostname() + if err != nil { + return nil, err + } + hostname = tmpHostname + } + needEnv := true + for _, checkEnv := range g.Config.Process.Env { + if strings.SplitN(checkEnv, "=", 2)[0] == "HOSTNAME" { + needEnv = false + break + } + } + if needEnv { + g.AddProcessEnv("HOSTNAME", hostname) + } if c.config.UTSNsCtr != "" { if err := c.addNamespaceContainer(&g, UTSNS, c.config.UTSNsCtr, spec.UTSNamespace); err != nil { diff --git a/pkg/specgen/generate/namespaces.go b/pkg/specgen/generate/namespaces.go index 036c7b7a16..3cd5a3c9c5 100644 --- a/pkg/specgen/generate/namespaces.go +++ b/pkg/specgen/generate/namespaces.go @@ -364,7 +364,9 @@ func specConfigureNamespaces(s *specgen.SpecGenerator, g *generate.Generator, rt // namespaces? g.SetHostname(hostname) } - g.AddProcessEnv("HOSTNAME", hostname) + if _, ok := s.Env["HOSTNAME"]; !ok && s.Hostname != "" { + g.AddProcessEnv("HOSTNAME", hostname) + } // User switch s.UserNS.NSMode { diff --git a/test/e2e/run_test.go b/test/e2e/run_test.go index 4888a676b1..92d7d222e4 100644 --- a/test/e2e/run_test.go +++ b/test/e2e/run_test.go @@ -1415,4 +1415,12 @@ WORKDIR /madethis` Expect(session.ExitCode()).To(Equal(0)) Expect(session.ErrorToString()).To(ContainSubstring("Trying to pull")) }) + + It("podman run container with hostname and hostname environment variable", func() { + hostnameEnv := "test123" + session := podmanTest.Podman([]string{"run", "--hostname", "testctr", "--env", fmt.Sprintf("HOSTNAME=%s", hostnameEnv), ALPINE, "printenv", "HOSTNAME"}) + session.WaitWithDefaultTimeout() + Expect(session.ExitCode()).To(Equal(0)) + Expect(session.OutputToString()).To(ContainSubstring(hostnameEnv)) + }) })