github.com/shiroyuki/docker@v1.9.0/integration-cli/docker_cli_experimental_test.go (about)

     1  // +build experimental
     2  
     3  package main
     4  
     5  import (
     6  	"fmt"
     7  	"io/ioutil"
     8  	"os"
     9  	"os/exec"
    10  	"path/filepath"
    11  	"strconv"
    12  	"strings"
    13  
    14  	"github.com/docker/docker/pkg/system"
    15  	"github.com/go-check/check"
    16  )
    17  
    18  func (s *DockerSuite) TestExperimentalVersion(c *check.C) {
    19  	out, _ := dockerCmd(c, "version")
    20  	for _, line := range strings.Split(out, "\n") {
    21  		if strings.HasPrefix(line, "Experimental (client):") || strings.HasPrefix(line, "Experimental (server):") {
    22  			c.Assert(line, check.Matches, "*true")
    23  		}
    24  	}
    25  
    26  	out, _ = dockerCmd(c, "-v")
    27  	if !strings.Contains(out, ", experimental") {
    28  		c.Fatalf("docker version did not contain experimental: %s", out)
    29  	}
    30  }
    31  
    32  // user namespaces test: run daemon with remapped root setting
    33  // 1. validate uid/gid maps are set properly
    34  // 2. verify that files created are owned by remapped root
    35  func (s *DockerDaemonSuite) TestDaemonUserNamespaceRootSetting(c *check.C) {
    36  	testRequires(c, NativeExecDriver)
    37  	testRequires(c, SameHostDaemon)
    38  
    39  	c.Assert(s.d.StartWithBusybox("--userns-remap", "default"), check.IsNil)
    40  
    41  	tmpDir, err := ioutil.TempDir("", "userns")
    42  	if err != nil {
    43  		c.Fatal(err)
    44  	}
    45  	defer os.RemoveAll(tmpDir)
    46  
    47  	// we need to find the uid and gid of the remapped root from the daemon's root dir info
    48  	uidgid := strings.Split(filepath.Base(s.d.root), ".")
    49  	c.Assert(len(uidgid), check.Equals, 2, check.Commentf("Should have gotten uid/gid strings from root dirname: %s", filepath.Base(s.d.root)))
    50  	uid, err := strconv.Atoi(uidgid[0])
    51  	c.Assert(err, check.IsNil, check.Commentf("Can't parse uid: %v", err))
    52  	gid, err := strconv.Atoi(uidgid[1])
    53  	c.Assert(err, check.IsNil, check.Commentf("Can't parse gid: %v", err))
    54  
    55  	//writeable by the remapped root UID/GID pair
    56  	c.Assert(os.Chown(tmpDir, uid, gid), check.IsNil)
    57  
    58  	out, err := s.d.Cmd("run", "-d", "--name", "userns", "-v", tmpDir+":/goofy", "busybox", "sh", "-c", "touch /goofy/testfile; top")
    59  	c.Assert(err, check.IsNil, check.Commentf("Output: %s", out))
    60  
    61  	pid, err := s.d.Cmd("inspect", "--format='{{.State.Pid}}'", "userns")
    62  	if err != nil {
    63  		c.Fatalf("Could not inspect running container: out: %q; err: %v", pid, err)
    64  	}
    65  	// check the uid and gid maps for the PID to ensure root is remapped
    66  	// (cmd = cat /proc/<pid>/uid_map | grep -E '0\s+9999\s+1')
    67  	out, rc1, err := runCommandPipelineWithOutput(
    68  		exec.Command("cat", "/proc/"+strings.TrimSpace(pid)+"/uid_map"),
    69  		exec.Command("grep", "-E", fmt.Sprintf("0[[:space:]]+%d[[:space:]]+", uid)))
    70  	c.Assert(rc1, check.Equals, 0, check.Commentf("Didn't match uid_map: output: %s", out))
    71  
    72  	out, rc2, err := runCommandPipelineWithOutput(
    73  		exec.Command("cat", "/proc/"+strings.TrimSpace(pid)+"/gid_map"),
    74  		exec.Command("grep", "-E", fmt.Sprintf("0[[:space:]]+%d[[:space:]]+", gid)))
    75  	c.Assert(rc2, check.Equals, 0, check.Commentf("Didn't match gid_map: output: %s", out))
    76  
    77  	// check that the touched file is owned by remapped uid:gid
    78  	stat, err := system.Stat(filepath.Join(tmpDir, "testfile"))
    79  	if err != nil {
    80  		c.Fatal(err)
    81  	}
    82  	c.Assert(stat.UID(), check.Equals, uint32(uid), check.Commentf("Touched file not owned by remapped root UID"))
    83  	c.Assert(stat.GID(), check.Equals, uint32(gid), check.Commentf("Touched file not owned by remapped root GID"))
    84  }