Skip to content

Commit

Permalink
Merge pull request #10 from resin-os/bootable-containers
Browse files Browse the repository at this point in the history
Bootable containers
  • Loading branch information
petrosagg authored Aug 2, 2017
2 parents 9d1e6e4 + 1a06eec commit 93710d6
Show file tree
Hide file tree
Showing 4 changed files with 113 additions and 3 deletions.
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")
}

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

0 comments on commit 93710d6

Please sign in to comment.