Merge branch 'master' into pluginflag

Conflicts:
	pkg/cgroups/cgroups.go
	pkg/libcontainer/nsinit/exec.go
	pkg/libcontainer/nsinit/init.go
	pkg/libcontainer/nsinit/mount.go
	runconfig/hostconfig.go
	runconfig/parse.go
	runtime/execdriver/driver.go
	runtime/execdriver/lxc/lxc_template.go
	runtime/execdriver/lxc/lxc_template_unit_test.go
	runtime/execdriver/native/default_template.go
	runtime/execdriver/native/driver.go

Docker-DCO-1.1-Signed-off-by: Michael Crosby <michael@crosbymichael.com> (github: crosbymichael)
This commit is contained in:
Michael Crosby 2014-03-27 08:00:18 +00:00
commit 4619830a18
4 changed files with 40 additions and 17 deletions

View File

@ -7,6 +7,7 @@ import (
"os/exec" "os/exec"
"syscall" "syscall"
"github.com/dotcloud/docker/pkg/cgroups"
"github.com/dotcloud/docker/pkg/libcontainer" "github.com/dotcloud/docker/pkg/libcontainer"
"github.com/dotcloud/docker/pkg/libcontainer/network" "github.com/dotcloud/docker/pkg/libcontainer/network"
"github.com/dotcloud/docker/pkg/system" "github.com/dotcloud/docker/pkg/system"
@ -62,10 +63,15 @@ func (ns *linuxNs) Exec(container *libcontainer.Container, term Terminal, args [
// Do this before syncing with child so that no children // Do this before syncing with child so that no children
// can escape the cgroup // can escape the cgroup
ns.logger.Println("setting cgroups") ns.logger.Println("setting cgroups")
if err := ns.SetupCgroups(container, command.Process.Pid); err != nil { activeCgroup, err := ns.SetupCgroups(container, command.Process.Pid)
if err != nil {
command.Process.Kill() command.Process.Kill()
return -1, err return -1, err
} }
if activeCgroup != nil {
defer activeCgroup.Cleanup()
}
ns.logger.Println("setting up network") ns.logger.Println("setting up network")
if err := ns.InitializeNetworking(container, command.Process.Pid, syncPipe); err != nil { if err := ns.InitializeNetworking(container, command.Process.Pid, syncPipe); err != nil {
command.Process.Kill() command.Process.Kill()
@ -86,13 +92,11 @@ func (ns *linuxNs) Exec(container *libcontainer.Container, term Terminal, args [
return status, err return status, err
} }
func (ns *linuxNs) SetupCgroups(container *libcontainer.Container, nspid int) error { func (ns *linuxNs) SetupCgroups(container *libcontainer.Container, nspid int) (cgroups.ActiveCgroup, error) {
if container.Cgroups != nil { if container.Cgroups != nil {
if err := container.Cgroups.Apply(nspid); err != nil { return container.Cgroups.Apply(nspid)
return err
}
} }
return nil return nil, nil
} }
func (ns *linuxNs) InitializeNetworking(container *libcontainer.Container, nspid int, pipe *SyncPipe) error { func (ns *linuxNs) InitializeNetworking(container *libcontainer.Container, nspid int, pipe *SyncPipe) error {

View File

@ -4,6 +4,7 @@ package nsinit
import ( import (
"fmt" "fmt"
"github.com/dotcloud/docker/pkg/label"
"github.com/dotcloud/docker/pkg/libcontainer" "github.com/dotcloud/docker/pkg/libcontainer"
"github.com/dotcloud/docker/pkg/system" "github.com/dotcloud/docker/pkg/system"
"os" "os"
@ -32,7 +33,11 @@ func (ns *linuxNs) ExecIn(container *libcontainer.Container, nspid int, args []s
closeFds() closeFds()
return -1, err return -1, err
} }
processLabel, err := label.GetPidCon(nspid)
if err != nil {
closeFds()
return -1, err
}
// foreach namespace fd, use setns to join an existing container's namespaces // foreach namespace fd, use setns to join an existing container's namespaces
for _, fd := range fds { for _, fd := range fds {
if fd > 0 { if fd > 0 {
@ -80,6 +85,10 @@ dropAndExec:
if err := finalizeNamespace(container); err != nil { if err := finalizeNamespace(container); err != nil {
return -1, err return -1, err
} }
err = label.SetProcessLabel(processLabel)
if err != nil {
return -1, err
}
if err := system.Execv(args[0], args[0:], container.Env); err != nil { if err := system.Execv(args[0], args[0:], container.Env); err != nil {
return -1, err return -1, err
} }

View File

@ -5,8 +5,10 @@ package nsinit
import ( import (
"fmt" "fmt"
"os" "os"
"runtime"
"syscall" "syscall"
"github.com/dotcloud/docker/pkg/label"
"github.com/dotcloud/docker/pkg/libcontainer" "github.com/dotcloud/docker/pkg/libcontainer"
"github.com/dotcloud/docker/pkg/libcontainer/apparmor" "github.com/dotcloud/docker/pkg/libcontainer/apparmor"
"github.com/dotcloud/docker/pkg/libcontainer/capabilities" "github.com/dotcloud/docker/pkg/libcontainer/capabilities"
@ -61,7 +63,7 @@ func (ns *linuxNs) Init(container *libcontainer.Container, uncleanRootfs, consol
return fmt.Errorf("setup networking %s", err) return fmt.Errorf("setup networking %s", err)
} }
ns.logger.Println("setup mount namespace") ns.logger.Println("setup mount namespace")
if err := setupNewMountNamespace(rootfs, container.Mounts, console, container.ReadonlyFs, container.NoPivotRoot); err != nil { if err := setupNewMountNamespace(rootfs, container.Mounts, console, container.ReadonlyFs, container.NoPivotRoot, container.Context["mount_label"]); err != nil {
return fmt.Errorf("setup mount namespace %s", err) return fmt.Errorf("setup mount namespace %s", err)
} }
if err := system.Sethostname(container.Hostname); err != nil { if err := system.Sethostname(container.Hostname); err != nil {
@ -77,6 +79,10 @@ func (ns *linuxNs) Init(container *libcontainer.Container, uncleanRootfs, consol
return err return err
} }
} }
runtime.LockOSThread()
if err := label.SetProcessLabel(container.Context["process_label"]); err != nil {
return fmt.Errorf("SetProcessLabel label %s", err)
}
ns.logger.Printf("execing %s\n", args[0]) ns.logger.Printf("execing %s\n", args[0])
return system.Execv(args[0], args[0:], container.Env) return system.Execv(args[0], args[0:], container.Env)
} }

View File

@ -4,6 +4,7 @@ package nsinit
import ( import (
"fmt" "fmt"
"github.com/dotcloud/docker/pkg/label"
"github.com/dotcloud/docker/pkg/libcontainer" "github.com/dotcloud/docker/pkg/libcontainer"
"github.com/dotcloud/docker/pkg/system" "github.com/dotcloud/docker/pkg/system"
"io/ioutil" "io/ioutil"
@ -20,7 +21,7 @@ const defaultMountFlags = syscall.MS_NOEXEC | syscall.MS_NOSUID | syscall.MS_NOD
// //
// There is no need to unmount the new mounts because as soon as the mount namespace // There is no need to unmount the new mounts because as soon as the mount namespace
// is no longer in use, the mounts will be removed automatically // is no longer in use, the mounts will be removed automatically
func setupNewMountNamespace(rootfs string, bindMounts []libcontainer.Mount, console string, readonly, noPivotRoot bool) error { func setupNewMountNamespace(rootfs string, bindMounts []libcontainer.Mount, console string, readonly, noPivotRoot bool, mountLabel string) error {
flag := syscall.MS_PRIVATE flag := syscall.MS_PRIVATE
if noPivotRoot { if noPivotRoot {
flag = syscall.MS_SLAVE flag = syscall.MS_SLAVE
@ -31,7 +32,7 @@ func setupNewMountNamespace(rootfs string, bindMounts []libcontainer.Mount, cons
if err := system.Mount(rootfs, rootfs, "bind", syscall.MS_BIND|syscall.MS_REC, ""); err != nil { if err := system.Mount(rootfs, rootfs, "bind", syscall.MS_BIND|syscall.MS_REC, ""); err != nil {
return fmt.Errorf("mouting %s as bind %s", rootfs, err) return fmt.Errorf("mouting %s as bind %s", rootfs, err)
} }
if err := mountSystem(rootfs); err != nil { if err := mountSystem(rootfs, mountLabel); err != nil {
return fmt.Errorf("mount system %s", err) return fmt.Errorf("mount system %s", err)
} }
@ -59,7 +60,7 @@ func setupNewMountNamespace(rootfs string, bindMounts []libcontainer.Mount, cons
if err := setupDev(rootfs); err != nil { if err := setupDev(rootfs); err != nil {
return err return err
} }
if err := setupPtmx(rootfs, console); err != nil { if err := setupPtmx(rootfs, console, mountLabel); err != nil {
return err return err
} }
if err := system.Chdir(rootfs); err != nil { if err := system.Chdir(rootfs); err != nil {
@ -197,7 +198,7 @@ func setupDev(rootfs string) error {
} }
// setupConsole ensures that the container has a proper /dev/console setup // setupConsole ensures that the container has a proper /dev/console setup
func setupConsole(rootfs, console string) error { func setupConsole(rootfs, console string, mountLabel string) error {
oldMask := system.Umask(0000) oldMask := system.Umask(0000)
defer system.Umask(oldMask) defer system.Umask(oldMask)
@ -221,6 +222,9 @@ func setupConsole(rootfs, console string) error {
if err := system.Mknod(dest, (st.Mode&^07777)|0600, int(st.Rdev)); err != nil { if err := system.Mknod(dest, (st.Mode&^07777)|0600, int(st.Rdev)); err != nil {
return fmt.Errorf("mknod %s %s", dest, err) return fmt.Errorf("mknod %s %s", dest, err)
} }
if err := label.SetFileLabel(console, mountLabel); err != nil {
return fmt.Errorf("SetFileLabel Failed %s %s", dest, err)
}
if err := system.Mount(console, dest, "bind", syscall.MS_BIND, ""); err != nil { if err := system.Mount(console, dest, "bind", syscall.MS_BIND, ""); err != nil {
return fmt.Errorf("bind %s to %s %s", console, dest, err) return fmt.Errorf("bind %s to %s %s", console, dest, err)
} }
@ -229,7 +233,7 @@ func setupConsole(rootfs, console string) error {
// mountSystem sets up linux specific system mounts like sys, proc, shm, and devpts // mountSystem sets up linux specific system mounts like sys, proc, shm, and devpts
// inside the mount namespace // inside the mount namespace
func mountSystem(rootfs string) error { func mountSystem(rootfs string, mountLabel string) error {
for _, m := range []struct { for _, m := range []struct {
source string source string
path string path string
@ -239,8 +243,8 @@ func mountSystem(rootfs string) error {
}{ }{
{source: "proc", path: filepath.Join(rootfs, "proc"), device: "proc", flags: defaultMountFlags}, {source: "proc", path: filepath.Join(rootfs, "proc"), device: "proc", flags: defaultMountFlags},
{source: "sysfs", path: filepath.Join(rootfs, "sys"), device: "sysfs", flags: defaultMountFlags}, {source: "sysfs", path: filepath.Join(rootfs, "sys"), device: "sysfs", flags: defaultMountFlags},
{source: "shm", path: filepath.Join(rootfs, "dev", "shm"), device: "tmpfs", flags: defaultMountFlags, data: "mode=1777,size=65536k"}, {source: "shm", path: filepath.Join(rootfs, "dev", "shm"), device: "tmpfs", flags: defaultMountFlags, data: label.FormatMountLabel("mode=1755,size=65536k", mountLabel)},
{source: "devpts", path: filepath.Join(rootfs, "dev", "pts"), device: "devpts", flags: syscall.MS_NOSUID | syscall.MS_NOEXEC, data: "newinstance,ptmxmode=0666,mode=620,gid=5"}, {source: "devpts", path: filepath.Join(rootfs, "dev", "pts"), device: "devpts", flags: syscall.MS_NOSUID | syscall.MS_NOEXEC, data: label.FormatMountLabel("newinstance,ptmxmode=0666,mode=620,gid=5", mountLabel)},
} { } {
if err := os.MkdirAll(m.path, 0755); err != nil && !os.IsExist(err) { if err := os.MkdirAll(m.path, 0755); err != nil && !os.IsExist(err) {
return fmt.Errorf("mkdirall %s %s", m.path, err) return fmt.Errorf("mkdirall %s %s", m.path, err)
@ -254,7 +258,7 @@ func mountSystem(rootfs string) error {
// setupPtmx adds a symlink to pts/ptmx for /dev/ptmx and // setupPtmx adds a symlink to pts/ptmx for /dev/ptmx and
// finishes setting up /dev/console // finishes setting up /dev/console
func setupPtmx(rootfs, console string) error { func setupPtmx(rootfs, console string, mountLabel string) error {
ptmx := filepath.Join(rootfs, "dev/ptmx") ptmx := filepath.Join(rootfs, "dev/ptmx")
if err := os.Remove(ptmx); err != nil && !os.IsNotExist(err) { if err := os.Remove(ptmx); err != nil && !os.IsNotExist(err) {
return err return err
@ -263,7 +267,7 @@ func setupPtmx(rootfs, console string) error {
return fmt.Errorf("symlink dev ptmx %s", err) return fmt.Errorf("symlink dev ptmx %s", err)
} }
if console != "" { if console != "" {
if err := setupConsole(rootfs, console); err != nil { if err := setupConsole(rootfs, console, mountLabel); err != nil {
return err return err
} }
} }