From b7f887a9a24a2df61fa53612ae42b7e9d62fe858 Mon Sep 17 00:00:00 2001 From: Stephen J Day Date: Tue, 16 Jun 2015 11:06:53 -0700 Subject: [PATCH] Move graph.SetupInitLayer to daemon package where it is used An inspection of the graph package showed this function to be way out of place. It is only depended upon by the daemon code. The function prepares a top-level readonly layer used to provide a consistent runtime environment for docker images. Signed-off-by: Stephen J Day --- daemon/daemon_aufs.go | 3 +-- daemon/daemon_unix.go | 63 +++++++++++++++++++++++++++++++++++++++++-- graph/graph.go | 59 ---------------------------------------- 3 files changed, 62 insertions(+), 63 deletions(-) diff --git a/daemon/daemon_aufs.go b/daemon/daemon_aufs.go index 4bb553d0af..0848ea920f 100644 --- a/daemon/daemon_aufs.go +++ b/daemon/daemon_aufs.go @@ -6,7 +6,6 @@ import ( "github.com/Sirupsen/logrus" "github.com/docker/docker/daemon/graphdriver" "github.com/docker/docker/daemon/graphdriver/aufs" - "github.com/docker/docker/graph" ) // Given the graphdriver ad, if it is aufs, then migrate it. @@ -14,7 +13,7 @@ import ( func migrateIfAufs(driver graphdriver.Driver, root string) error { if ad, ok := driver.(*aufs.Driver); ok { logrus.Debugf("Migrating existing containers") - if err := ad.Migrate(root, graph.SetupInitLayer); err != nil { + if err := ad.Migrate(root, setupInitLayer); err != nil { return err } } diff --git a/daemon/daemon_unix.go b/daemon/daemon_unix.go index 29a3c5d3dc..3a2e62106d 100644 --- a/daemon/daemon_unix.go +++ b/daemon/daemon_unix.go @@ -9,14 +9,15 @@ import ( "path/filepath" "runtime" "strings" + "syscall" "github.com/Sirupsen/logrus" "github.com/docker/docker/autogen/dockerversion" "github.com/docker/docker/daemon/graphdriver" - "github.com/docker/docker/graph" "github.com/docker/docker/pkg/archive" "github.com/docker/docker/pkg/fileutils" "github.com/docker/docker/pkg/parsers/kernel" + "github.com/docker/docker/pkg/system" "github.com/docker/docker/runconfig" "github.com/docker/docker/utils" volumedrivers "github.com/docker/docker/volume/drivers" @@ -81,7 +82,7 @@ func (daemon *Daemon) createRootfs(container *Container) error { } defer daemon.driver.Put(initID) - if err := graph.SetupInitLayer(initPath); err != nil { + if err := setupInitLayer(initPath); err != nil { return err } @@ -360,3 +361,61 @@ func initNetworkController(config *Config) (libnetwork.NetworkController, error) return controller, nil } + +// setupInitLayer populates a directory with mountpoints suitable +// for bind-mounting dockerinit into the container. The mountpoint is simply an +// empty file at /.dockerinit +// +// This extra layer is used by all containers as the top-most ro layer. It protects +// the container from unwanted side-effects on the rw layer. +func setupInitLayer(initLayer string) error { + for pth, typ := range map[string]string{ + "/dev/pts": "dir", + "/dev/shm": "dir", + "/proc": "dir", + "/sys": "dir", + "/.dockerinit": "file", + "/.dockerenv": "file", + "/etc/resolv.conf": "file", + "/etc/hosts": "file", + "/etc/hostname": "file", + "/dev/console": "file", + "/etc/mtab": "/proc/mounts", + } { + parts := strings.Split(pth, "/") + prev := "/" + for _, p := range parts[1:] { + prev = filepath.Join(prev, p) + syscall.Unlink(filepath.Join(initLayer, prev)) + } + + if _, err := os.Stat(filepath.Join(initLayer, pth)); err != nil { + if os.IsNotExist(err) { + if err := system.MkdirAll(filepath.Join(initLayer, filepath.Dir(pth)), 0755); err != nil { + return err + } + switch typ { + case "dir": + if err := system.MkdirAll(filepath.Join(initLayer, pth), 0755); err != nil { + return err + } + case "file": + f, err := os.OpenFile(filepath.Join(initLayer, pth), os.O_CREATE, 0755) + if err != nil { + return err + } + f.Close() + default: + if err := os.Symlink(typ, filepath.Join(initLayer, pth)); err != nil { + return err + } + } + } else { + return err + } + } + } + + // Layer is ready to use, if it wasn't before. + return nil +} diff --git a/graph/graph.go b/graph/graph.go index 0f27e8c56a..5c5b5f0656 100644 --- a/graph/graph.go +++ b/graph/graph.go @@ -13,7 +13,6 @@ import ( "runtime" "strconv" "strings" - "syscall" "time" "github.com/Sirupsen/logrus" @@ -271,64 +270,6 @@ func bufferToFile(f *os.File, src io.Reader) (int64, digest.Digest, error) { return n, digest.NewDigest("sha256", h), nil } -// setupInitLayer populates a directory with mountpoints suitable -// for bind-mounting dockerinit into the container. The mountpoint is simply an -// empty file at /.dockerinit -// -// This extra layer is used by all containers as the top-most ro layer. It protects -// the container from unwanted side-effects on the rw layer. -func SetupInitLayer(initLayer string) error { - for pth, typ := range map[string]string{ - "/dev/pts": "dir", - "/dev/shm": "dir", - "/proc": "dir", - "/sys": "dir", - "/.dockerinit": "file", - "/.dockerenv": "file", - "/etc/resolv.conf": "file", - "/etc/hosts": "file", - "/etc/hostname": "file", - "/dev/console": "file", - "/etc/mtab": "/proc/mounts", - } { - parts := strings.Split(pth, "/") - prev := "/" - for _, p := range parts[1:] { - prev = filepath.Join(prev, p) - syscall.Unlink(filepath.Join(initLayer, prev)) - } - - if _, err := os.Stat(filepath.Join(initLayer, pth)); err != nil { - if os.IsNotExist(err) { - if err := system.MkdirAll(filepath.Join(initLayer, filepath.Dir(pth)), 0755); err != nil { - return err - } - switch typ { - case "dir": - if err := system.MkdirAll(filepath.Join(initLayer, pth), 0755); err != nil { - return err - } - case "file": - f, err := os.OpenFile(filepath.Join(initLayer, pth), os.O_CREATE, 0755) - if err != nil { - return err - } - f.Close() - default: - if err := os.Symlink(typ, filepath.Join(initLayer, pth)); err != nil { - return err - } - } - } else { - return err - } - } - } - - // Layer is ready to use, if it wasn't before. - return nil -} - // Check if given error is "not empty". // Note: this is the way golang does it internally with os.IsNotExists. func isNotEmpty(err error) bool {