From 6f6cc8b7cea230a00d1f188d81668daa534cb6d3 Mon Sep 17 00:00:00 2001 From: Petros Angelatos Date: Tue, 25 Jul 2017 13:13:30 -0700 Subject: [PATCH 1/3] cmd: add mobynit for host app booting Signed-off-by: Petros Angelatos --- cmd/mobynit/main.go | 91 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 91 insertions(+) create mode 100644 cmd/mobynit/main.go diff --git a/cmd/mobynit/main.go b/cmd/mobynit/main.go new file mode 100644 index 0000000000..db5a29568b --- /dev/null +++ b/cmd/mobynit/main.go @@ -0,0 +1,91 @@ +package main + +import ( + "io/ioutil" + "log" + "os" + "path/filepath" + "strings" + "syscall" + + _ "github.com/docker/docker/daemon/graphdriver/aufs" + _ "github.com/docker/docker/daemon/graphdriver/overlay2" + "github.com/docker/docker/layer" + "github.com/docker/docker/pkg/idtools" + "golang.org/x/sys/unix" +) + +const ( + LAYER_ROOT = "/docker" + PIVOT_PATH = "/mnt/sysroot" +) + +func mountContainer(containerID string) string { + if err := unix.Mount("", "/", "", unix.MS_REMOUNT, ""); err != nil { + log.Fatal("error remounting root as read/write:", err) + } + defer unix.Mount("", "/", "", unix.MS_REMOUNT | unix.MS_RDONLY, "") + + if err := os.MkdirAll("/dev/shm", os.ModePerm); err != nil { + log.Fatal("creating /dev/shm failed:", err) + } + + if err := unix.Mount("shm", "/dev/shm", "tmpfs", 0, ""); err != nil { + log.Fatal("error mounting /dev/shm:", err) + } + defer unix.Unmount("/dev/shm", unix.MNT_DETACH) + + ls, err := layer.NewStoreFromOptions(layer.StoreOptions{ + StorePath: LAYER_ROOT, + MetadataStorePathTemplate: filepath.Join(LAYER_ROOT, "image", "%s", "layerdb"), + IDMappings: &idtools.IDMappings{}, + GraphDriver: "aufs", + Platform: "linux", + }) + if err != nil { + log.Fatal("error loading layer store:", err) + } + + rwlayer, err := ls.GetRWLayer(containerID) + if err != nil { + log.Fatal("error getting container layer:", err) + } + + newRoot, err := rwlayer.Mount("") + if err != nil { + log.Fatal("error mounting container fs:", err) + } + + if err := unix.Mount("", newRoot, "", unix.MS_REMOUNT, ""); err != nil { + log.Fatal("error remounting container as read/write:", err) + } + defer unix.Mount("", newRoot, "", unix.MS_REMOUNT | unix.MS_RDONLY, "") + + if err := os.MkdirAll(filepath.Join(newRoot, PIVOT_PATH), os.ModePerm); err != nil { + log.Fatal("creating /mnt/sysroot failed:", err) + } + + return newRoot +} + +func main() { + rawID, err := ioutil.ReadFile("/current/container_id") + if err != nil { + log.Fatal("could not get container ID:", err) + } + containerID := strings.TrimSpace(string(rawID)) + + newRoot := mountContainer(containerID) + + if err := syscall.PivotRoot(newRoot, filepath.Join(newRoot, PIVOT_PATH)); err != nil { + log.Fatal("error while pivoting root:", err) + } + + if err := unix.Chdir("/"); err != nil { + log.Fatal(err) + } + + if err := syscall.Exec("/sbin/init", os.Args, os.Environ()); err != nil { + log.Fatal("error executing init:", err) + } +} From 6dd67d62ff8ad8375757b6855c30da55460072b8 Mon Sep 17 00:00:00 2001 From: Petros Angelatos Date: Thu, 27 Jul 2017 13:38:23 -0700 Subject: [PATCH 2/3] daemon: skip initLayer for bare runtime containers Containers that are meant to be booted from do not need the initLayer. The default init layer shadows /etc/resolv.conf and other files from the filesystem but this can cause problems if we're bootstrapping the system. Signed-off-by: Petros Angelatos --- daemon/create.go | 11 ++++++++--- daemon/create_unix.go | 3 +++ daemon/daemon_unix.go | 1 + 3 files changed, 12 insertions(+), 3 deletions(-) diff --git a/daemon/create.go b/daemon/create.go index 78070fd29d..2f7fa7c54e 100644 --- a/daemon/create.go +++ b/daemon/create.go @@ -138,7 +138,7 @@ func (daemon *Daemon) create(params types.ContainerCreateConfig, managed bool) ( container.HostConfig.StorageOpt = params.HostConfig.StorageOpt // Set RWLayer for container after mount labels have been set - if err := daemon.setRWLayer(container); err != nil { + if err := daemon.setRWLayer(container, params.HostConfig.Runtime); err != nil { return nil, err } @@ -234,7 +234,7 @@ func (daemon *Daemon) generateSecurityOpt(hostConfig *containertypes.HostConfig) return nil, nil } -func (daemon *Daemon) setRWLayer(container *container.Container) error { +func (daemon *Daemon) setRWLayer(container *container.Container, runtime string) error { var layerID layer.ChainID if container.ImageID != "" { img, err := daemon.stores[container.Platform].imageStore.Get(container.ImageID) @@ -244,9 +244,14 @@ func (daemon *Daemon) setRWLayer(container *container.Container) error { layerID = img.RootFS.ChainID() } + initFunc := daemon.getLayerInit() + if runtime == "bare" { + initFunc = nil + } + rwLayerOpts := &layer.CreateRWLayerOpts{ MountLabel: container.MountLabel, - InitFunc: daemon.getLayerInit(), + InitFunc: initFunc, StorageOpt: container.HostConfig.StorageOpt, } diff --git a/daemon/create_unix.go b/daemon/create_unix.go index 2501a3374a..dc3b737445 100644 --- a/daemon/create_unix.go +++ b/daemon/create_unix.go @@ -17,6 +17,9 @@ import ( // createContainerPlatformSpecificSettings performs platform specific container create functionality func (daemon *Daemon) createContainerPlatformSpecificSettings(container *container.Container, config *containertypes.Config, hostConfig *containertypes.HostConfig) error { + if hostConfig.Runtime == "bare" { + return nil + } if err := daemon.Mount(container); err != nil { return err } diff --git a/daemon/daemon_unix.go b/daemon/daemon_unix.go index 0778dde4f7..21e3acc6ba 100644 --- a/daemon/daemon_unix.go +++ b/daemon/daemon_unix.go @@ -641,6 +641,7 @@ func verifyDaemonSettings(conf *config.Config) error { conf.Runtimes = make(map[string]types.Runtime) } conf.Runtimes[config.StockRuntimeName] = types.Runtime{Path: DefaultRuntimeBinary} + conf.Runtimes["bare"] = types.Runtime{} return nil } From 1a06eecd235b28181422fde165fd215038fac1b8 Mon Sep 17 00:00:00 2001 From: Petros Angelatos Date: Tue, 1 Aug 2017 17:15:01 -0700 Subject: [PATCH 3/3] cmd/mobynit: accept a flag for the graph driver Signed-off-by: Petros Angelatos --- cmd/mobynit/main.go | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/cmd/mobynit/main.go b/cmd/mobynit/main.go index db5a29568b..c8074e36e9 100644 --- a/cmd/mobynit/main.go +++ b/cmd/mobynit/main.go @@ -1,6 +1,7 @@ package main import ( + "flag" "io/ioutil" "log" "os" @@ -20,6 +21,13 @@ const ( PIVOT_PATH = "/mnt/sysroot" ) +var graphDriver string + +func init() { + flag.StringVar(&graphDriver, "storage-driver", "aufs", "Storage driver to use") + flag.StringVar(&graphDriver, "s", "aufs", "Storage driver to use") +} + func mountContainer(containerID string) string { if err := unix.Mount("", "/", "", unix.MS_REMOUNT, ""); err != nil { log.Fatal("error remounting root as read/write:", err) @@ -39,7 +47,7 @@ func mountContainer(containerID string) string { StorePath: LAYER_ROOT, MetadataStorePathTemplate: filepath.Join(LAYER_ROOT, "image", "%s", "layerdb"), IDMappings: &idtools.IDMappings{}, - GraphDriver: "aufs", + GraphDriver: graphDriver, Platform: "linux", }) if err != nil { @@ -69,6 +77,8 @@ func mountContainer(containerID string) string { } func main() { + flag.Parse() + rawID, err := ioutil.ReadFile("/current/container_id") if err != nil { log.Fatal("could not get container ID:", err)