Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bootable containers #10

Merged
merged 3 commits into from
Aug 2, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
101 changes: 101 additions & 0 deletions cmd/mobynit/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
package main

import (
"flag"
"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"
)

var graphDriver string

func init() {
flag.StringVar(&graphDriver, "storage-driver", "aufs", "Storage driver to use")
flag.StringVar(&graphDriver, "s", "aufs", "Storage driver to use")
Copy link
Contributor

@zozo123 zozo123 Aug 2, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The second flag.StringVar will override the first one. I am not sure I get this. https://play.golang.org/p/7Pr_o3He8V

}

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: graphDriver,
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() {
flag.Parse()

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)
}
}
11 changes: 8 additions & 3 deletions daemon/create.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
}

Expand Down Expand Up @@ -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)
Expand All @@ -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,
}

Expand Down
3 changes: 3 additions & 0 deletions daemon/create_unix.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
Expand Down
1 change: 1 addition & 0 deletions daemon/daemon_unix.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
Expand Down