Skip to content

Commit

Permalink
add support for podman create/run --domainname
Browse files Browse the repository at this point in the history
domainname functions similarly to --hostname, it sets the value in /etc/hosts
to whatever you speficy in conjunction with --hostname. so if you pass
--hostname=foo --domainmame=baz.net, /etc/hosts will get the combined entry and /proc/sys/kernel/domainname will get
baz.net
resolves #15102

Signed-off-by: Charlie Doern <cdoern@redhat.com>
  • Loading branch information
cdoern committed Oct 11, 2022
1 parent 619366d commit 1282d38
Show file tree
Hide file tree
Showing 19 changed files with 151 additions and 19 deletions.
8 changes: 8 additions & 0 deletions cmd/podman/common/create.go
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,14 @@ func DefineCreateFlags(cmd *cobra.Command, cf *entities.ContainerCreateOptions,
"This is a Docker specific option and is a NOOP",
)

domainNameFlagName := "domainname"
createFlags.StringVar(
&cf.Domainname,
domainNameFlagName, "",
"Set container domain name",
)
_ = cmd.RegisterFlagCompletionFunc(domainNameFlagName, completion.AutocompleteNone)

envMergeFlagName := "env-merge"
createFlags.StringArrayVar(
&cf.EnvMerge,
Expand Down
7 changes: 7 additions & 0 deletions cmd/podman/containers/create.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import (
"github.com/containers/podman/v4/cmd/podman/utils"
"github.com/containers/podman/v4/libpod/define"
"github.com/containers/podman/v4/pkg/domain/entities"
"github.com/containers/podman/v4/pkg/rootless"
"github.com/containers/podman/v4/pkg/specgen"
"github.com/containers/podman/v4/pkg/specgenutil"
"github.com/containers/podman/v4/pkg/util"
Expand Down Expand Up @@ -296,6 +297,12 @@ func CreateInit(c *cobra.Command, vals entities.ContainerCreateOptions, isInfra
vals.Entrypoint = &val
}

if _, err = c.Flags().GetString("domainname"); err == nil {
if rootless.IsRootless() && c.Flag("domainname").Changed {
return vals, fmt.Errorf("%w: cannot specify domainname when running rootless", define.ErrInvalidArg)
}
}

// Docker-compatibility: the "-h" flag for run/create is reserved for
// the hostname (see https://github.com/containers/podman/issues/1367).

Expand Down
5 changes: 5 additions & 0 deletions docs/source/markdown/options/domainname.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
#### **--domainname**=*name*

Container domain name

Sets the container domain name that is available inside the container. Can only be used with a private UTS namespace `--uts=private` (default). This option is only curently only available in rootful mode.
4 changes: 4 additions & 0 deletions docs/source/markdown/podman-create.1.md.in
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,8 @@ each of stdin, stdout, and stderr.

@@option blkio-weight-device

Block IO weight (relative device weight, format: `DEVICE_NAME:WEIGHT`).

@@option cap-add

@@option cap-drop
Expand Down Expand Up @@ -149,6 +151,8 @@ This option cannot be combined with **--network** that is set to **none** or **c

@@option dns-search.container

@@option domainname

@@option entrypoint

@@option env
Expand Down
2 changes: 2 additions & 0 deletions docs/source/markdown/podman-run.1.md.in
Original file line number Diff line number Diff line change
Expand Up @@ -185,6 +185,8 @@ This option cannot be combined with **--network** that is set to **none** or **c

@@option dns-search.container

@@option domainname

@@option entrypoint

@@option env
Expand Down
4 changes: 3 additions & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ require (
github.com/opencontainers/go-digest v1.0.0
github.com/opencontainers/image-spec v1.1.0-rc2
github.com/opencontainers/runc v1.1.4
github.com/opencontainers/runtime-spec v1.0.3-0.20211214071223-8958f93039ab
github.com/opencontainers/runtime-spec v1.0.3-0.20220825212826-86290f6a00fb
github.com/opencontainers/runtime-tools v0.9.1-0.20220714195903-17b3287fafb7
github.com/opencontainers/selinux v1.10.2
github.com/openshift/imagebuilder v1.2.4-0.20220711175835-4151e43600df
Expand Down Expand Up @@ -148,3 +148,5 @@ require (
)

replace github.com/opencontainers/runc => github.com/opencontainers/runc v1.1.1-0.20220617142545-8b9452f75cbc

replace github.com/opencontainers/runtime-tools => github.com/cdoern/runtime-tools v0.0.0-20220905181351-e97231895f30
11 changes: 4 additions & 7 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -243,6 +243,8 @@ github.com/bugsnag/osext v0.0.0-20130617224835-0dd3f918b21b/go.mod h1:obH5gd0Bsq
github.com/bugsnag/panicwrap v0.0.0-20151223152923-e2c28503fcd0/go.mod h1:D/8v3kj0zr8ZAKg1AQ6crr+5VwKN5eIywRkfhyM/+dE=
github.com/butuzov/ireturn v0.1.1/go.mod h1:Wh6Zl3IMtTpaIKbmwzqi6olnM9ptYQxxVacMsOEFPoc=
github.com/bwesterb/go-ristretto v1.2.0/go.mod h1:fUIoIZaG73pV5biE2Blr2xEzDoMj7NFEuV9ekS419A0=
github.com/cdoern/runtime-tools v0.0.0-20220905181351-e97231895f30 h1:do/5fHIAe+ATHZTMuHsIX26IfOV83xllXfMP5GVsEqI=
github.com/cdoern/runtime-tools v0.0.0-20220905181351-e97231895f30/go.mod h1:nbTs0+m/W+o9MmEUQKxfQLrwNDR3/oQBJ71hUaZteqw=
github.com/cenkalti/backoff/v3 v3.0.0/go.mod h1:cIeZDE3IrqwwJl6VUwCN6trj1oXrTS4rc0ij+ULvLYs=
github.com/cenkalti/backoff/v3 v3.2.2/go.mod h1:cIeZDE3IrqwwJl6VUwCN6trj1oXrTS4rc0ij+ULvLYs=
github.com/cenkalti/backoff/v4 v4.1.1/go.mod h1:scbssz8iZGpm3xbr14ovlUdkxfGXNInqkPWOWmG2CLw=
Expand Down Expand Up @@ -1386,14 +1388,9 @@ github.com/opencontainers/runtime-spec v1.0.1/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/
github.com/opencontainers/runtime-spec v1.0.2-0.20190207185410-29686dbc5559/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0=
github.com/opencontainers/runtime-spec v1.0.2/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0=
github.com/opencontainers/runtime-spec v1.0.3-0.20200929063507-e6143ca7d51d/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0=
github.com/opencontainers/runtime-spec v1.0.3-0.20201121164853-7413a7f753e1/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0=
github.com/opencontainers/runtime-spec v1.0.3-0.20210326190908-1c3f411f0417/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0=
github.com/opencontainers/runtime-spec v1.0.3-0.20211214071223-8958f93039ab h1:YQZXa3elcHgKXAa2GjVFC9M3JeP7ZPyFD1YByDx/dgQ=
github.com/opencontainers/runtime-spec v1.0.3-0.20211214071223-8958f93039ab/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0=
github.com/opencontainers/runtime-tools v0.0.0-20181011054405-1d69bd0f9c39/go.mod h1:r3f7wjNzSs2extwzU3Y+6pKfobzPh+kKFJ3ofN+3nfs=
github.com/opencontainers/runtime-tools v0.0.0-20190417131837-cd1349b7c47e/go.mod h1:r3f7wjNzSs2extwzU3Y+6pKfobzPh+kKFJ3ofN+3nfs=
github.com/opencontainers/runtime-tools v0.9.1-0.20220714195903-17b3287fafb7 h1:Rf+QsQGxrYCia8mVyOPnoQZ+vJkZGL+ESWBDUM5s9cQ=
github.com/opencontainers/runtime-tools v0.9.1-0.20220714195903-17b3287fafb7/go.mod h1:/tgP02fPXGHkU3/qKK1Y0Db4yqNyGm03vLq/mzHzcS4=
github.com/opencontainers/runtime-spec v1.0.3-0.20220825212826-86290f6a00fb h1:1xSVPOd7/UA+39/hXEGnBJ13p6JFB0E1EvQFlrRDOXI=
github.com/opencontainers/runtime-spec v1.0.3-0.20220825212826-86290f6a00fb/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0=
github.com/opencontainers/selinux v1.6.0/go.mod h1:VVGKuOLlE7v4PJyT6h7mNWvq1rzqiriPsEqVhc+svHE=
github.com/opencontainers/selinux v1.8.0/go.mod h1:RScLhm78qiWa2gbVCcGkC7tCGdgk3ogry1nUQF8Evvo=
github.com/opencontainers/selinux v1.8.2/go.mod h1:MUIHuUEvKB1wtJjQdOyYRgOnLD2xAPP8dBsCoU0KuF8=
Expand Down
20 changes: 20 additions & 0 deletions libpod/container.go
Original file line number Diff line number Diff line change
Expand Up @@ -672,6 +672,26 @@ func (c *Container) Hostname() string {
return c.ID()[:12]
}

// Domainname gets the container's domainname
func (c *Container) Domainname() string {
if c.config.UTSNsCtr != "" {
utsNsCtr, err := c.runtime.GetContainer(c.config.UTSNsCtr)
if err != nil {
logrus.Errorf("unable to look up uts namespace for container %s: %v", c.ID(), err)
return ""
}
return utsNsCtr.Domainname()
}
if c.config.Spec.Domainname != "" {
return c.config.Spec.Domainname
}

if len(c.ID()) < 11 {
return c.ID()
}
return c.ID()[:12]
}

// WorkingDir returns the containers working dir
func (c *Container) WorkingDir() string {
if c.config.Spec.Process != nil {
Expand Down
3 changes: 3 additions & 0 deletions libpod/container_config.go
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,9 @@ type ContainerConfig struct {
// This field should never be written to the db, the json tag ensures this.
rewrite bool `json:"-"`

// Domainname defines the containers domainname
Domainname string `json:"domainname,omitempty"`

// embedded sub-configs
ContainerRootFSConfig
ContainerSecurityConfig
Expand Down
16 changes: 14 additions & 2 deletions libpod/container_internal_common.go
Original file line number Diff line number Diff line change
Expand Up @@ -2012,13 +2012,25 @@ func (c *Container) removeNameserver(ips []string) error {
}

func getLocalhostHostEntry(c *Container) etchosts.HostEntries {
return etchosts.HostEntries{{IP: "127.0.0.1", Names: []string{c.Hostname(), c.config.Name}}}
hostname := c.Hostname()
domainname := c.Domainname()
fullname := hostname
if len(domainname) > 0 {
fullname = fullname + "." + domainname
}
return etchosts.HostEntries{{IP: "127.0.0.1", Names: []string{fullname, c.config.Name}}}
}

// getHostsEntries returns the container ip host entries for the correct netmode
func (c *Container) getHostsEntries() (etchosts.HostEntries, error) {
var entries etchosts.HostEntries
names := []string{c.Hostname(), c.config.Name}
hostname := c.Hostname()
domainname := c.Domainname()
fullname := hostname
if len(domainname) > 0 {
fullname = fullname + "." + domainname
}
names := []string{fullname, c.config.Name}
switch {
case c.config.NetMode.IsBridge():
entries = etchosts.GetNetworkHostEntries(c.state.NetworkStatus, names...)
Expand Down
1 change: 1 addition & 0 deletions pkg/domain/entities/pods.go
Original file line number Diff line number Diff line change
Expand Up @@ -200,6 +200,7 @@ type ContainerCreateOptions struct {
DeviceReadIOPs []string
DeviceWriteBPs []string
DeviceWriteIOPs []string
Domainname string
Entrypoint *string `json:"container_command,omitempty"`
Env []string
EnvHost bool
Expand Down
5 changes: 5 additions & 0 deletions pkg/specgen/generate/container_create.go
Original file line number Diff line number Diff line change
Expand Up @@ -178,7 +178,12 @@ func MakeContainer(ctx context.Context, rt *libpod.Runtime, s *specgen.SpecGener
opts = ExtractCDIDevices(s)
options = append(options, opts...)
}

runtimeSpec, err := SpecGenToOCI(ctx, s, rt, rtc, newImage, finalMounts, pod, command, compatibleOptions)
if err != nil {
return nil, nil, nil, err
}

if clone { // the container fails to start if cloned due to missing Linux spec entries
if c == nil {
return nil, nil, nil, errors.New("the given container could not be retrieved")
Expand Down
9 changes: 9 additions & 0 deletions pkg/specgen/generate/namespaces_linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -71,22 +71,26 @@ func specConfigureNamespaces(s *specgen.SpecGenerator, g *generate.Generator, rt
}

hostname := s.Hostname
domainname := s.Domainname
if hostname == "" {
switch {
case s.UtsNS.NSMode == specgen.FromPod:
hostname = pod.Hostname()
domainname = ""
case s.UtsNS.NSMode == specgen.FromContainer:
utsCtr, err := rt.LookupContainer(s.UtsNS.Value)
if err != nil {
return fmt.Errorf("looking up container to share uts namespace with: %w", err)
}
hostname = utsCtr.Hostname()
domainname = ""
case (s.NetNS.NSMode == specgen.Host && hostname == "") || s.UtsNS.NSMode == specgen.Host:
tmpHostname, err := os.Hostname()
if err != nil {
return fmt.Errorf("unable to retrieve hostname of the host: %w", err)
}
hostname = tmpHostname
domainname = ""
default:
logrus.Debug("No hostname set; container's hostname will default to runtime default")
}
Expand All @@ -98,8 +102,13 @@ func specConfigureNamespaces(s *specgen.SpecGenerator, g *generate.Generator, rt
// the user or if we are creating a new UTS namespace.
// TODO: Should we be doing this for pod or container shared
// namespaces?
// we do not want to add domainname to the hostname, we need to keep track of it for later
g.SetHostname(hostname)
}

if s.Domainname != "" {
g.SetDomainName(domainname)
}
if _, ok := s.Env["HOSTNAME"]; !ok && s.Hostname != "" {
g.AddProcessEnv("HOSTNAME", hostname)
}
Expand Down
2 changes: 2 additions & 0 deletions pkg/specgen/specgen.go
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,8 @@ type ContainerBasicConfig struct {
// Conflicts with UtsNS if UtsNS is not set to private.
// Optional.
Hostname string `json:"hostname,omitempty"`
// Domainname is the container's domain name. Must be specified in conjunction with hostname
Domainname string `json:"domainname,omitempty"`
// HostUses is a list of host usernames or UIDs to add to the container
// /etc/passwd file
HostUsers []string `json:"hostusers,omitempty"`
Expand Down
4 changes: 4 additions & 0 deletions pkg/specgenutil/specgen.go
Original file line number Diff line number Diff line change
Expand Up @@ -543,6 +543,10 @@ func FillOutSpecGen(s *specgen.SpecGenerator, c *entities.ContainerCreateOptions
if len(s.Hostname) == 0 || len(c.Hostname) != 0 {
s.Hostname = c.Hostname
}

if len(s.Domainname) == 0 || len(c.Domainname) != 0 {
s.Domainname = c.Domainname
}
sysctl := map[string]string{}
if ctl := c.Sysctl; len(ctl) > 0 {
sysctl, err = util.ValidateSysctls(ctl)
Expand Down
12 changes: 12 additions & 0 deletions test/e2e/run_dns_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,18 @@ var _ = Describe("Podman run dns", func() {
Expect(session.OutputToString()).To(ContainSubstring("foobar"))
})

It("podman run domainname sets /etc/hosts and /proc/sys/kernel/domainname", func() {
session := podmanTest.Podman([]string{"run", "--hostname", "foobar", "--domainname", "foobar.fake_domain", ALPINE, "cat", "/etc/hosts"})
session.WaitWithDefaultTimeout()
Expect(session).Should(Exit(0))
Expect(session.OutputToString()).To(ContainSubstring("foobar.foobar.fake_domain"))

session = podmanTest.Podman([]string{"run", "--hostname", "foobar", "--domainname", "foobar.fake_domain", ALPINE, "cat", "/proc/sys/kernel/domainname"})
session.WaitWithDefaultTimeout()
Expect(session).Should(Exit(0))
Expect(session.OutputToString()).To(ContainSubstring("foobar.fake_domain"))
})

It("podman run mutually excludes --dns* and --network", func() {
session := podmanTest.Podman([]string{"run", "--dns=1.2.3.4", "--network", "container:ALPINE", ALPINE})
session.WaitWithDefaultTimeout()
Expand Down
46 changes: 39 additions & 7 deletions vendor/github.com/opencontainers/runtime-spec/specs-go/config.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit 1282d38

Please sign in to comment.