Update with lxc unconfined changes
Docker-DCO-1.1-Signed-off-by: Michael Crosby <michael@crosbymichael.com> (github: crosbymichael)
This commit is contained in:
parent
66782730b8
commit
93ead2fe78
6 changed files with 73 additions and 105 deletions
69
container.go
69
container.go
|
@ -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()
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
|
|
@ -38,7 +38,6 @@ func mkRuntime(f utils.Fataler) *docker.Runtime {
|
|||
if err != nil {
|
||||
f.Fatal(err)
|
||||
}
|
||||
r.UpdateCapabilities(true)
|
||||
return r
|
||||
}
|
||||
|
||||
|
|
48
runtime.go
48
runtime.go
|
@ -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
|
||||
|
|
|
@ -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())
|
||||
|
|
Loading…
Reference in a new issue