|
@@ -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,53 +47,36 @@ 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)
|
|
|
-
|
|
|
- // 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)
|
|
|
+ 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
|
|
|
}
|