Add user namespace (mapping) support to the Docker engine

Adds support for the daemon to handle user namespace maps as a
per-daemon setting.

Support for handling uid/gid mapping is added to the builder,
archive/unarchive packages and functions, all graphdrivers (except
Windows), and the test suite is updated to handle user namespace daemon
rootgraph changes.

Docker-DCO-1.1-Signed-off-by: Phil Estes <estesp@linux.vnet.ibm.com> (github: estesp)
This commit is contained in:
Phil Estes
2015-10-09 17:47:37 -04:00
parent 9a3ab0358e
commit 442b45628e
56 changed files with 878 additions and 203 deletions
+52 -5
View File
@@ -41,6 +41,7 @@ type Daemon struct {
c *check.C
logFile *os.File
folder string
root string
stdin io.WriteCloser
stdout, stderr io.ReadCloser
cmd *exec.Cmd
@@ -65,9 +66,10 @@ func NewDaemon(c *check.C) *Daemon {
if err != nil {
c.Fatalf("Could not make %q an absolute path: %v", dir, err)
}
daemonRoot := filepath.Join(daemonFolder, "root")
if err := os.MkdirAll(filepath.Join(daemonFolder, "graph"), 0600); err != nil {
c.Fatalf("Could not create %s/graph directory", daemonFolder)
if err := os.MkdirAll(daemonRoot, 0755); err != nil {
c.Fatalf("Could not create daemon root %q: %v", dir, err)
}
userlandProxy := true
@@ -82,6 +84,7 @@ func NewDaemon(c *check.C) *Daemon {
id: id,
c: c,
folder: daemonFolder,
root: daemonRoot,
storageDriver: os.Getenv("DOCKER_GRAPHDRIVER"),
execDriver: os.Getenv("DOCKER_EXECDRIVER"),
userlandProxy: userlandProxy,
@@ -99,7 +102,7 @@ func (d *Daemon) Start(arg ...string) error {
args := append(d.GlobalFlags,
d.Command,
"--host", d.sock(),
"--graph", fmt.Sprintf("%s/graph", d.folder),
"--graph", d.root,
"--pidfile", fmt.Sprintf("%s/docker.pid", d.folder),
fmt.Sprintf("--userland-proxy=%t", d.userlandProxy),
)
@@ -181,8 +184,11 @@ func (d *Daemon) Start(arg ...string) error {
if resp.StatusCode != http.StatusOK {
d.c.Logf("[%s] received status != 200 OK: %s", d.id, resp.Status)
}
d.c.Logf("[%s] daemon started", d.id)
d.root, err = d.queryRootDir()
if err != nil {
return fmt.Errorf("[%s] error querying daemon for root directory: %v", d.id, err)
}
return nil
}
}
@@ -278,6 +284,47 @@ func (d *Daemon) Restart(arg ...string) error {
return d.Start(arg...)
}
func (d *Daemon) queryRootDir() (string, error) {
// update daemon root by asking /info endpoint (to support user
// namespaced daemon with root remapped uid.gid directory)
conn, err := net.Dial("unix", filepath.Join(d.folder, "docker.sock"))
if err != nil {
return "", err
}
client := httputil.NewClientConn(conn, nil)
req, err := http.NewRequest("GET", "/info", nil)
if err != nil {
client.Close()
return "", err
}
req.Header.Set("Content-Type", "application/json")
resp, err := client.Do(req)
if err != nil {
client.Close()
return "", err
}
body := ioutils.NewReadCloserWrapper(resp.Body, func() error {
defer client.Close()
return resp.Body.Close()
})
type Info struct {
DockerRootDir string
}
var b []byte
var i Info
b, err = readBody(body)
if err == nil && resp.StatusCode == 200 {
// read the docker root dir
if err = json.Unmarshal(b, &i); err == nil {
return i.DockerRootDir, nil
}
}
return "", err
}
func (d *Daemon) sock() string {
return fmt.Sprintf("unix://%s/docker.sock", d.folder)
}
@@ -1236,7 +1283,7 @@ func readFile(src string, c *check.C) (content string) {
}
func containerStorageFile(containerID, basename string) string {
return filepath.Join("/var/lib/docker/containers", containerID, basename)
return filepath.Join(containerStoragePath, containerID, basename)
}
// docker commands that use this function must be run with the '-d' switch.