1
0
Fork 0
mirror of https://github.com/moby/moby.git synced 2022-11-09 12:21:53 -05:00

Allow root non-userns metadata backwards compatibility

Instead of creating a "0.0" subdirectory and migrating graphroot
metadata into it when user namespaces are available in the daemon
(currently only in experimental), change the graphroot dir permissions
to only include the execute bit for "other" users.

This allows easy migration to and from user namespaces and will allow
easier integration of user namespace support into the master build.

Docker-DCO-1.1-Signed-off-by: Phil Estes <estesp@linux.vnet.ibm.com> (github: estesp)
This commit is contained in:
Phil Estes 2016-01-05 11:51:14 -05:00
parent b2d00e312b
commit e8532023f2
3 changed files with 22 additions and 40 deletions

View file

@ -10,7 +10,6 @@ import (
"github.com/Sirupsen/logrus"
"github.com/docker/docker/api/types/container"
"github.com/docker/docker/pkg/directory"
"github.com/docker/docker/pkg/idtools"
)
@ -48,54 +47,37 @@ func setupRemappedRoot(config *Config) ([]idtools.IDMap, []idtools.IDMap, error)
}
func setupDaemonRoot(config *Config, rootDir string, rootUID, rootGID int) error {
// the main docker root needs to be accessible by all users, as user namespace support
// will create subdirectories owned by either a) the real system root (when no remapping
// is setup) or b) the remapped root host ID (when --root=uid:gid is used)
// for "first time" users of user namespaces, we need to migrate the current directory
// contents to the "0.0" (root == root "namespace" daemon root)
nsRoot := "0.0"
config.Root = rootDir
// the docker root metadata directory needs to have execute permissions for all users (o+x)
// so that syscalls executing as non-root, operating on subdirectories of the graph root
// (e.g. mounted layers of a container) can traverse this path.
// The user namespace support will create subdirectories for the remapped root host uid:gid
// pair owned by that same uid:gid pair for proper write access to those needed metadata and
// layer content subtrees.
if _, err := os.Stat(rootDir); err == nil {
// root current exists; we need to check for a prior migration
if _, err := os.Stat(filepath.Join(rootDir, nsRoot)); err != nil && os.IsNotExist(err) {
// need to migrate current root to "0.0" subroot
// 1. create non-usernamespaced root as "0.0"
if err := os.Mkdir(filepath.Join(rootDir, nsRoot), 0700); err != nil {
return fmt.Errorf("Cannot create daemon root %q: %v", filepath.Join(rootDir, nsRoot), err)
}
// 2. move current root content to "0.0" new subroot
if err := directory.MoveToSubdir(rootDir, nsRoot); err != nil {
return fmt.Errorf("Cannot migrate current daemon root %q for user namespaces: %v", rootDir, err)
}
// 3. chmod outer root to 755
if chmodErr := os.Chmod(rootDir, 0755); chmodErr != nil {
return chmodErr
}
}
} else if os.IsNotExist(err) {
// no root exists yet, create it 0755 with root:root ownership
if err := os.MkdirAll(rootDir, 0755); err != nil {
// root current exists; verify the access bits are correct by setting them
if err = os.Chmod(rootDir, 0701); err != nil {
return err
}
// create the "0.0" subroot (so no future "migration" happens of the root)
if err := os.Mkdir(filepath.Join(rootDir, nsRoot), 0700); err != nil {
} else if os.IsNotExist(err) {
// no root exists yet, create it 0701 with root:root ownership
if err := os.MkdirAll(rootDir, 0701); err != nil {
return err
}
}
// for user namespaces we will create a subtree underneath the specified root
// if user namespaces are enabled we will create a subtree underneath the specified root
// with any/all specified remapped root uid/gid options on the daemon creating
// a new subdirectory with ownership set to the remapped uid/gid (so as to allow
// `chdir()` to work for containers namespaced to that uid/gid)
if config.RemappedRoot != "" {
nsRoot = fmt.Sprintf("%d.%d", rootUID, rootGID)
}
config.Root = filepath.Join(rootDir, nsRoot)
logrus.Debugf("Creating actual daemon root: %s", config.Root)
config.Root = filepath.Join(rootDir, fmt.Sprintf("%d.%d", rootUID, rootGID))
logrus.Debugf("Creating user namespaced daemon root: %s", config.Root)
// Create the root directory if it doesn't exists
if err := idtools.MkdirAllAs(config.Root, 0700, rootUID, rootGID); err != nil {
return fmt.Errorf("Cannot create daemon root: %s: %v", config.Root, err)
}
}
return nil
}

View file

@ -123,7 +123,7 @@ func Init(root string, options []string, uidMaps, gidMaps []idtools.IDMap) (grap
// Create the root aufs driver dir and return
// if it already exists
// If not populate the dir structure
if err := idtools.MkdirAllAs(root, 0755, rootUID, rootGID); err != nil {
if err := idtools.MkdirAllAs(root, 0700, rootUID, rootGID); err != nil {
if os.IsExist(err) {
return a, nil
}
@ -136,7 +136,7 @@ func Init(root string, options []string, uidMaps, gidMaps []idtools.IDMap) (grap
// Populate the dir structure
for _, p := range paths {
if err := idtools.MkdirAllAs(path.Join(root, p), 0755, rootUID, rootGID); err != nil {
if err := idtools.MkdirAllAs(path.Join(root, p), 0700, rootUID, rootGID); err != nil {
return nil, err
}
}

View file

@ -146,7 +146,7 @@ func Init(home string, options []string, uidMaps, gidMaps []idtools.IDMap) (grap
return nil, err
}
// Create the driver home dir
if err := idtools.MkdirAllAs(home, 0755, rootUID, rootGID); err != nil && !os.IsExist(err) {
if err := idtools.MkdirAllAs(home, 0700, rootUID, rootGID); err != nil && !os.IsExist(err) {
return nil, err
}