Skip to content

Commit

Permalink
Merge pull request moby#12667 from ibuildthecloud/host-uts
Browse files Browse the repository at this point in the history
Add --uts=host to allow sharing the UTS namespace
  • Loading branch information
thaJeztah committed May 14, 2015
2 parents f2bc54f + f2e5207 commit ed25742
Show file tree
Hide file tree
Showing 10 changed files with 119 additions and 0 deletions.
5 changes: 5 additions & 0 deletions daemon/container.go
Original file line number Diff line number Diff line change
Expand Up @@ -335,6 +335,10 @@ func populateCommand(c *Container, env []string) error {
pid := &execdriver.Pid{}
pid.HostPid = c.hostConfig.PidMode.IsHost()

uts := &execdriver.UTS{
HostUTS: c.hostConfig.UTSMode.IsHost(),
}

// Build lists of devices allowed and created within the container.
var userSpecifiedDevices []*configs.Device
for _, deviceMapping := range c.hostConfig.Devices {
Expand Down Expand Up @@ -410,6 +414,7 @@ func populateCommand(c *Container, env []string) error {
Network: en,
Ipc: ipc,
Pid: pid,
UTS: uts,
Resources: resources,
AllowedDevices: allowedDevices,
AutoCreatedDevices: autoCreatedDevices,
Expand Down
6 changes: 6 additions & 0 deletions daemon/execdriver/driver.go
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,11 @@ type Pid struct {
HostPid bool `json:"host_pid"`
}

// UTS settings of the container
type UTS struct {
HostUTS bool `json:"host_uts"`
}

type NetworkInterface struct {
Gateway string `json:"gateway"`
IPAddress string `json:"ip"`
Expand Down Expand Up @@ -155,6 +160,7 @@ type Command struct {
Network *Network `json:"network"`
Ipc *Ipc `json:"ipc"`
Pid *Pid `json:"pid"`
UTS *UTS `json:"uts"`
Resources *Resources `json:"resources"`
Mounts []Mount `json:"mounts"`
AllowedDevices []*configs.Device `json:"allowed_devices"`
Expand Down
14 changes: 14 additions & 0 deletions daemon/execdriver/native/create.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,10 @@ func (d *driver) createContainer(c *execdriver.Command) (*configs.Config, error)
return nil, err
}

if err := d.createUTS(container, c); err != nil {
return nil, err
}

if err := d.createNetwork(container, c); err != nil {
return nil, err
}
Expand Down Expand Up @@ -173,6 +177,16 @@ func (d *driver) createPid(container *configs.Config, c *execdriver.Command) err
return nil
}

func (d *driver) createUTS(container *configs.Config, c *execdriver.Command) error {
if c.UTS.HostUTS {
container.Namespaces.Remove(configs.NEWUTS)
container.Hostname = ""
return nil
}

return nil
}

func (d *driver) setPrivileged(container *configs.Config) (err error) {
container.Capabilities = execdriver.GetAllCapabilities()
container.Cgroups.AllowAllDevices = true
Expand Down
6 changes: 6 additions & 0 deletions docs/man/docker-create.1.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ docker-create - Create a new container
[**-P**|**--publish-all**[=*false*]]
[**-p**|**--publish**[=*[]*]]
[**--pid**[=*[]*]]
[**--uts**[=*[]*]]
[**--privileged**[=*false*]]
[**--read-only**[=*false*]]
[**--restart**[=*RESTART*]]
Expand Down Expand Up @@ -193,6 +194,11 @@ This value should always larger than **-m**, so you should alway use this with *
**host**: use the host's PID namespace inside the container.
Note: the host mode gives the container full access to local PID and is therefore considered insecure.

**--uts**=host
Set the UTS mode for the container
**host**: use the host's UTS namespace inside the container.
Note: the host mode gives the container access to changing the host's hostname and is therefore considered insecure.

**--privileged**=*true*|*false*
Give extended privileges to this container. The default is *false*.

Expand Down
6 changes: 6 additions & 0 deletions docs/man/docker-run.1.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ docker-run - Run a command in a new container
[**-P**|**--publish-all**[=*false*]]
[**-p**|**--publish**[=*[]*]]
[**--pid**[=*[]*]]
[**--uts**[=*[]*]]
[**--privileged**[=*false*]]
[**--read-only**[=*false*]]
[**--restart**[=*RESTART*]]
Expand Down Expand Up @@ -323,6 +324,11 @@ ports and the exposed ports, use `docker port`.
**host**: use the host's PID namespace inside the container.
Note: the host mode gives the container full access to local PID and is therefore considered insecure.

**--uts**=host
Set the UTS mode for the container
**host**: use the host's UTS namespace inside the container.
Note: the host mode gives the container access to changing the host's hostname and is therefore considered insecure.

**--privileged**=*true*|*false*
Give extended privileges to this container. The default is *false*.

Expand Down
3 changes: 3 additions & 0 deletions docs/sources/reference/commandline/cli.md
Original file line number Diff line number Diff line change
Expand Up @@ -991,6 +991,8 @@ Creates a new container.
--oom-kill-disable=false Whether to disable OOM Killer for the container or not
-P, --publish-all=false Publish all exposed ports to random ports
-p, --publish=[] Publish a container's port(s) to the host
--pid="" PID namespace to use
--uts="" UTS namespace to use
--privileged=false Give extended privileges to this container
--read-only=false Mount the container's root filesystem as read only
--restart="no" Restart policy (no, on-failure[:max-retry], always)
Expand Down Expand Up @@ -1958,6 +1960,7 @@ To remove an image using its digest:
-P, --publish-all=false Publish all exposed ports to random ports
-p, --publish=[] Publish a container's port(s) to the host
--pid="" PID namespace to use
--uts="" UTS namespace to use
--privileged=false Give extended privileges to this container
--read-only=false Mount the container's root filesystem as read only
--restart="no" Restart policy (no, on-failure[:max-retry], always)
Expand Down
18 changes: 18 additions & 0 deletions docs/sources/reference/run.md
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,7 @@ called a digest. As long as the input used to generate the image is unchanged,
the digest value is predictable and referenceable.

## PID settings (--pid)

--pid="" : Set the PID (Process) Namespace mode for the container,
'host': use the host's PID namespace inside the container

Expand All @@ -177,6 +178,23 @@ within the container.
This command would allow you to use `strace` inside the container on pid 1234 on
the host.

## UTS settings (--uts)

--uts="" : Set the UTS namespace mode for the container,
'host': use the host's UTS namespace inside the container

The UTS namespace is for setting the hostname and the domain that is visible
to running processes in that namespace. By default, all containers, including
those with `--net=host`, have their own UTS namespace. The `host` setting will
result in the container using the same UTS namespace as the host.

You may wish to share the UTS namespace with the host if you would like the
hostname of the container to change as the hostname of the host changes. A
more advanced use case would be changing the host's hostname from a container.

> **Note**: `--uts="host"` gives the container full access to change the
> hostname of the host and is therefore considered insecure.
## IPC settings (--ipc)

--ipc="" : Set the IPC mode for the container,
Expand Down
32 changes: 32 additions & 0 deletions integration-cli/docker_cli_run_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2765,6 +2765,38 @@ func (s *DockerSuite) TestRunModePidHost(c *check.C) {
}
}

func (s *DockerSuite) TestRunModeUTSHost(c *check.C) {
testRequires(c, NativeExecDriver, SameHostDaemon)
defer deleteAllContainers()

hostUTS, err := os.Readlink("/proc/1/ns/uts")
if err != nil {
c.Fatal(err)
}

cmd := exec.Command(dockerBinary, "run", "--uts=host", "busybox", "readlink", "/proc/self/ns/uts")
out2, _, err := runCommandWithOutput(cmd)
if err != nil {
c.Fatal(err, out2)
}

out2 = strings.Trim(out2, "\n")
if hostUTS != out2 {
c.Fatalf("UTS different with --uts=host %s != %s\n", hostUTS, out2)
}

cmd = exec.Command(dockerBinary, "run", "busybox", "readlink", "/proc/self/ns/uts")
out2, _, err = runCommandWithOutput(cmd)
if err != nil {
c.Fatal(err, out2)
}

out2 = strings.Trim(out2, "\n")
if hostUTS == out2 {
c.Fatalf("UTS should be different without --uts=host %s == %s\n", hostUTS, out2)
}
}

func (s *DockerSuite) TestRunTLSverify(c *check.C) {
cmd := exec.Command(dockerBinary, "ps")
out, ec, err := runCommandWithOutput(cmd)
Expand Down
22 changes: 22 additions & 0 deletions runconfig/hostconfig.go
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,27 @@ func (n IpcMode) Container() string {
return ""
}

type UTSMode string

// IsPrivate indicates whether container use it's private UTS namespace
func (n UTSMode) IsPrivate() bool {
return !(n.IsHost())
}

func (n UTSMode) IsHost() bool {
return n == "host"
}

func (n UTSMode) Valid() bool {
parts := strings.Split(string(n), ":")
switch mode := parts[0]; mode {
case "", "host":
default:
return false
}
return true
}

type PidMode string

// IsPrivate indicates whether container use it's private pid stack
Expand Down Expand Up @@ -187,6 +208,7 @@ type HostConfig struct {
NetworkMode NetworkMode
IpcMode IpcMode
PidMode PidMode
UTSMode UTSMode
CapAdd []string
CapDrop []string
RestartPolicy RestartPolicy
Expand Down
7 changes: 7 additions & 0 deletions runconfig/parse.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ func Parse(cmd *flag.FlagSet, args []string) (*Config, *HostConfig, *flag.FlagSe
flNetwork = cmd.Bool([]string{"#n", "#-networking"}, true, "Enable networking for this container")
flPrivileged = cmd.Bool([]string{"#privileged", "-privileged"}, false, "Give extended privileges to this container")
flPidMode = cmd.String([]string{"-pid"}, "", "PID namespace to use")
flUTSMode = cmd.String([]string{"-uts"}, "", "UTS namespace to use")
flPublishAll = cmd.Bool([]string{"P", "-publish-all"}, false, "Publish all exposed ports to random ports")
flStdin = cmd.Bool([]string{"i", "-interactive"}, false, "Keep STDIN open even if not attached")
flTty = cmd.Bool([]string{"t", "-tty"}, false, "Allocate a pseudo-TTY")
Expand Down Expand Up @@ -281,6 +282,11 @@ func Parse(cmd *flag.FlagSet, args []string) (*Config, *HostConfig, *flag.FlagSe
return nil, nil, cmd, fmt.Errorf("--pid: invalid PID mode")
}

utsMode := UTSMode(*flUTSMode)
if !utsMode.Valid() {
return nil, nil, cmd, fmt.Errorf("--uts: invalid UTS mode")
}

restartPolicy, err := ParseRestartPolicy(*flRestartPolicy)
if err != nil {
return nil, nil, cmd, err
Expand Down Expand Up @@ -337,6 +343,7 @@ func Parse(cmd *flag.FlagSet, args []string) (*Config, *HostConfig, *flag.FlagSe
NetworkMode: netMode,
IpcMode: ipcMode,
PidMode: pidMode,
UTSMode: utsMode,
Devices: deviceMappings,
CapAdd: flCapAdd.GetAll(),
CapDrop: flCapDrop.GetAll(),
Expand Down

0 comments on commit ed25742

Please sign in to comment.