Update with lxc unconfined changes

Docker-DCO-1.1-Signed-off-by: Michael Crosby <michael@crosbymichael.com> (github: crosbymichael)
This commit is contained in:
Michael Crosby 2014-01-10 18:09:07 -08:00
parent 66782730b8
commit 93ead2fe78
6 changed files with 73 additions and 105 deletions

View file

@ -17,7 +17,6 @@ import (
"net"
"os"
"path"
"strconv"
"strings"
"sync"
"syscall"
@ -563,34 +562,6 @@ func (container *Container) Start() (err error) {
return err
}
var lxcStart string = "lxc-start"
if container.hostConfig.Privileged && container.runtime.capabilities.AppArmor {
lxcStart = path.Join(container.runtime.config.Root, "lxc-start-unconfined")
}
params := []string{
lxcStart,
"-n", container.ID,
"-f", container.lxcConfigPath(),
"--",
"/.dockerinit",
}
// Networking
if !container.Config.NetworkDisabled {
network := container.NetworkSettings
params = append(params,
"-g", network.Gateway,
"-i", fmt.Sprintf("%s/%d", network.IPAddress, network.IPPrefixLen),
"-mtu", strconv.Itoa(container.runtime.config.Mtu),
)
}
// User
if container.Config.User != "" {
params = append(params, "-u", container.Config.User)
}
// Setup environment
env := []string{
"HOME=/",
@ -602,10 +573,6 @@ func (container *Container) Start() (err error) {
env = append(env, "TERM=xterm")
}
if container.hostConfig.Privileged {
params = append(params, "-privileged")
}
// Init any links between the parent and children
runtime := container.runtime
@ -661,31 +628,25 @@ func (container *Container) Start() (err error) {
if err := os.MkdirAll(path.Join(container.RootfsPath(), workingDir), 0755); err != nil {
return nil
}
params = append(params,
"-w", workingDir,
)
}
// Program
params = append(params, "--", container.Path)
params = append(params, container.Args...)
/*
if RootIsShared() {
// lxc-start really needs / to be non-shared, or all kinds of stuff break
// when lxc-start unmount things and those unmounts propagate to the main
// mount namespace.
// What we really want is to clone into a new namespace and then
// mount / MS_REC|MS_SLAVE, but since we can't really clone or fork
// without exec in go we have to do this horrible shell hack...
shellString :=
"mount --make-rslave /; exec " +
utils.ShellQuoteArguments(params)
if RootIsShared() {
// lxc-start really needs / to be non-shared, or all kinds of stuff break
// when lxc-start unmount things and those unmounts propagate to the main
// mount namespace.
// What we really want is to clone into a new namespace and then
// mount / MS_REC|MS_SLAVE, but since we can't really clone or fork
// without exec in go we have to do this horrible shell hack...
shellString :=
"mount --make-rslave /; exec " +
utils.ShellQuoteArguments(params)
params = []string{
"unshare", "-m", "--", "/bin/sh", "-c", shellString,
params = []string{
"unshare", "-m", "--", "/bin/sh", "-c", shellString,
}
}
}
*/
root := container.RootfsPath()
envPath, err := container.EnvConfigPath()

View file

@ -10,6 +10,7 @@ type Driver interface {
Start(c *Process) error
Kill(c *Process, sig int) error
Wait(id string, duration time.Duration) error // Wait on an out of process option - lxc ghosts
Version() string
}
// Network settings of the container

View file

@ -4,7 +4,9 @@ import (
"errors"
"fmt"
"github.com/dotcloud/docker/execdriver"
"os"
"os/exec"
"path"
"strconv"
"strings"
"time"
@ -17,21 +19,21 @@ const (
var (
ErrNotRunning = errors.New("Process could not be started")
ErrWaitTimeoutReached = errors.New("Wait timeout reached")
Debug bool
)
func init() {
// Register driver
}
type driver struct {
root string // root path for the driver to use
root string // root path for the driver to use
apparmor bool
}
func NewDriver(root string) (execdriver.Driver, error) {
func NewDriver(root string, apparmor bool) (execdriver.Driver, error) {
// setup unconfined symlink
if err := linkLxcStart(root); err != nil {
return nil, err
}
return &driver{
root: root,
apparmor: apparmor,
root: root,
}, nil
}
@ -57,6 +59,10 @@ func (d *driver) Start(c *execdriver.Process) error {
}
if c.Privileged {
if d.apparmor {
params[0] = path.Join(d.root, "lxc-start-unconfined")
}
params = append(params, "-privileged")
}
@ -120,6 +126,17 @@ func (d *driver) Wait(id string, duration time.Duration) error {
return nil
}
func (d *driver) Version() string {
version := ""
if output, err := exec.Command("lxc-version").CombinedOutput(); err == nil {
outputStr := string(output)
if len(strings.SplitN(outputStr, ":", 2)) == 2 {
version = strings.TrimSpace(strings.SplitN(outputStr, ":", 2)[1])
}
}
return version
}
func (d *driver) kill(c *execdriver.Process, sig int) error {
output, err := exec.Command("lxc-kill", "-n", c.ID, strconv.Itoa(sig)).CombinedOutput()
if err != nil {
@ -184,3 +201,20 @@ func (d *driver) waitLxc(id string, kill *bool) <-chan error {
func (d *driver) getInfo(c *execdriver.Process) ([]byte, error) {
return exec.Command("lxc-info", "-s", "-n", c.ID).CombinedOutput()
}
func linkLxcStart(root string) error {
sourcePath, err := exec.LookPath("lxc-start")
if err != nil {
return err
}
targetPath := path.Join(root, "lxc-start-unconfined")
if _, err := os.Lstat(targetPath); err != nil && !os.IsNotExist(err) {
return err
} else if err == nil {
if err := os.Remove(targetPath); err != nil {
return err
}
}
return os.Symlink(sourcePath, targetPath)
}

View file

@ -38,7 +38,6 @@ func mkRuntime(f utils.Fataler) *docker.Runtime {
if err != nil {
f.Fatal(err)
}
r.UpdateCapabilities(true)
return r
}

View file

@ -334,8 +334,8 @@ func (runtime *Runtime) restore() error {
return nil
}
// FIXME: comment please!
func (runtime *Runtime) UpdateCapabilities(quiet bool) {
func NewRuntimeCapabilities(quiet bool) *Capabilities {
capabilities := &Capabilities{}
if cgroupMemoryMountpoint, err := cgroups.FindCgroupMountpoint("memory"); err != nil {
if !quiet {
log.Printf("WARNING: %s\n", err)
@ -343,32 +343,33 @@ func (runtime *Runtime) UpdateCapabilities(quiet bool) {
} else {
_, err1 := ioutil.ReadFile(path.Join(cgroupMemoryMountpoint, "memory.limit_in_bytes"))
_, err2 := ioutil.ReadFile(path.Join(cgroupMemoryMountpoint, "memory.soft_limit_in_bytes"))
runtime.capabilities.MemoryLimit = err1 == nil && err2 == nil
if !runtime.capabilities.MemoryLimit && !quiet {
capabilities.MemoryLimit = err1 == nil && err2 == nil
if !capabilities.MemoryLimit && !quiet {
log.Printf("WARNING: Your kernel does not support cgroup memory limit.")
}
_, err = ioutil.ReadFile(path.Join(cgroupMemoryMountpoint, "memory.memsw.limit_in_bytes"))
runtime.capabilities.SwapLimit = err == nil
if !runtime.capabilities.SwapLimit && !quiet {
capabilities.SwapLimit = err == nil
if !capabilities.SwapLimit && !quiet {
log.Printf("WARNING: Your kernel does not support cgroup swap limit.")
}
}
content, err3 := ioutil.ReadFile("/proc/sys/net/ipv4/ip_forward")
runtime.capabilities.IPv4ForwardingDisabled = err3 != nil || len(content) == 0 || content[0] != '1'
if runtime.capabilities.IPv4ForwardingDisabled && !quiet {
capabilities.IPv4ForwardingDisabled = err3 != nil || len(content) == 0 || content[0] != '1'
if capabilities.IPv4ForwardingDisabled && !quiet {
log.Printf("WARNING: IPv4 forwarding is disabled.")
}
// Check if AppArmor seems to be enabled on this system.
if _, err := os.Stat("/sys/kernel/security/apparmor"); os.IsNotExist(err) {
utils.Debugf("/sys/kernel/security/apparmor not found; assuming AppArmor is not enabled.")
runtime.capabilities.AppArmor = false
capabilities.AppArmor = false
} else {
utils.Debugf("/sys/kernel/security/apparmor found; assuming AppArmor is enabled.")
runtime.capabilities.AppArmor = true
capabilities.AppArmor = true
}
return capabilities
}
// Create creates a new container from the given configuration with a given name.
@ -649,7 +650,6 @@ func NewRuntime(config *DaemonConfig) (*Runtime, error) {
if err != nil {
return nil, err
}
runtime.UpdateCapabilities(false)
return runtime, nil
}
@ -678,10 +678,6 @@ func NewRuntimeFromDirectory(config *DaemonConfig) (*Runtime, error) {
}
}
utils.Debugf("Escaping AppArmor confinement")
if err := linkLxcStart(config.Root); err != nil {
return nil, err
}
utils.Debugf("Creating images graph")
g, err := NewGraph(path.Join(config.Root, "graph"), driver)
if err != nil {
@ -738,7 +734,8 @@ func NewRuntimeFromDirectory(config *DaemonConfig) (*Runtime, error) {
sysInitPath = localCopy
}
ed, err := lxc.NewDriver("")
capabilities := NewRuntimeCapabilities(false)
ed, err := lxc.NewDriver(config.Root, capabilities.AppArmor)
if err != nil {
return nil, err
}
@ -750,7 +747,7 @@ func NewRuntimeFromDirectory(config *DaemonConfig) (*Runtime, error) {
graph: g,
repositories: repositories,
idIndex: utils.NewTruncIndex(),
capabilities: &Capabilities{},
capabilities: capabilities,
volumes: volumes,
config: config,
containerGraph: graph,
@ -869,23 +866,6 @@ func (runtime *Runtime) Nuke() error {
return os.RemoveAll(runtime.config.Root)
}
func linkLxcStart(root string) error {
sourcePath, err := exec.LookPath("lxc-start")
if err != nil {
return err
}
targetPath := path.Join(root, "lxc-start-unconfined")
if _, err := os.Lstat(targetPath); err != nil && !os.IsNotExist(err) {
return err
} else if err == nil {
if err := os.Remove(targetPath); err != nil {
return err
}
}
return os.Symlink(sourcePath, targetPath)
}
// FIXME: this is a convenience function for integration tests
// which need direct access to runtime.graph.
// Once the tests switch to using engine and jobs, this method

View file

@ -661,13 +661,6 @@ func (srv *Server) DockerInfo(job *engine.Job) engine.Status {
} else {
imgcount = len(images)
}
lxcVersion := ""
if output, err := exec.Command("lxc-version").CombinedOutput(); err == nil {
outputStr := string(output)
if len(strings.SplitN(outputStr, ":", 2)) == 2 {
lxcVersion = strings.TrimSpace(strings.SplitN(string(output), ":", 2)[1])
}
}
kernelVersion := "<unknown>"
if kv, err := utils.GetKernelVersion(); err == nil {
kernelVersion = kv.String()
@ -691,7 +684,7 @@ func (srv *Server) DockerInfo(job *engine.Job) engine.Status {
v.SetBool("Debug", os.Getenv("DEBUG") != "")
v.SetInt("NFd", utils.GetTotalUsedFds())
v.SetInt("NGoroutines", runtime.NumGoroutine())
v.Set("LXCVersion", lxcVersion)
v.Set("LXCVersion", srv.runtime.execDriver.Version())
v.SetInt("NEventsListener", len(srv.events))
v.Set("KernelVersion", kernelVersion)
v.Set("IndexServerAddress", auth.IndexServerAddress())