Przeglądaj źródła

add test-integration-cli specifics for userns

Signed-off-by: Jessica Frazelle <acidburn@docker.com>
Docker-DCO-1.1-Signed-off-by: Jessica Frazelle <acidburn@docker.com>
Jessica Frazelle 9 lat temu
rodzic
commit
ea3afdad61

+ 1 - 0
Makefile

@@ -9,6 +9,7 @@ DOCKER_ENVS := \
 	-e DOCKER_DEBUG \
 	-e DOCKER_DEBUG \
 	-e DOCKER_EXECDRIVER \
 	-e DOCKER_EXECDRIVER \
 	-e DOCKER_EXPERIMENTAL \
 	-e DOCKER_EXPERIMENTAL \
+	-e DOCKER_REMAP_ROOT \
 	-e DOCKER_GRAPHDRIVER \
 	-e DOCKER_GRAPHDRIVER \
 	-e DOCKER_STORAGE_OPTS \
 	-e DOCKER_STORAGE_OPTS \
 	-e DOCKER_USERLANDPROXY \
 	-e DOCKER_USERLANDPROXY \

+ 1 - 1
hack/make.sh

@@ -96,7 +96,7 @@ if [ ! "$GOPATH" ]; then
 	exit 1
 	exit 1
 fi
 fi
 
 
-if [ "$DOCKER_EXPERIMENTAL" ]; then
+if [ "$DOCKER_EXPERIMENTAL" ] || [ "$DOCKER_REMAP_ROOT" ]; then
 	echo >&2 '# WARNING! DOCKER_EXPERIMENTAL is set: building experimental features'
 	echo >&2 '# WARNING! DOCKER_EXPERIMENTAL is set: building experimental features'
 	echo >&2
 	echo >&2
 	DOCKER_BUILDTAGS+=" experimental"
 	DOCKER_BUILDTAGS+=" experimental"

+ 7 - 0
hack/make/.integration-daemon-start

@@ -26,6 +26,12 @@ if [ -n "$DOCKER_STORAGE_OPTS" ]; then
 	unset IFS
 	unset IFS
 fi
 fi
 
 
+# example usage: DOCKER_STORAGE_OPTS="dm.basesize=20G,dm.loopdatasize=200G"
+extra_params=""
+if [ "$DOCKER_REMAP_ROOT" ]; then
+	extra_params="--root $DOCKER_REMAP_ROOT"
+fi
+
 if [ -z "$DOCKER_TEST_HOST" ]; then
 if [ -z "$DOCKER_TEST_HOST" ]; then
 	# Start apparmor if it is enabled
 	# Start apparmor if it is enabled
 	if [ -e "/sys/module/apparmor/parameters/enabled" ] && [ "$(cat /sys/module/apparmor/parameters/enabled)" == "Y" ]; then
 	if [ -e "/sys/module/apparmor/parameters/enabled" ] && [ "$(cat /sys/module/apparmor/parameters/enabled)" == "Y" ]; then
@@ -47,6 +53,7 @@ if [ -z "$DOCKER_TEST_HOST" ]; then
 		--pidfile "$DEST/docker.pid" \
 		--pidfile "$DEST/docker.pid" \
 		--userland-proxy="$DOCKER_USERLANDPROXY" \
 		--userland-proxy="$DOCKER_USERLANDPROXY" \
 		$storage_params \
 		$storage_params \
+		$extra_params \
 			&> "$DEST/docker.log"
 			&> "$DEST/docker.log"
 	) &
 	) &
 	# make sure that if the script exits unexpectedly, we stop this daemon we just started
 	# make sure that if the script exits unexpectedly, we stop this daemon we just started

+ 1 - 0
integration-cli/docker_api_build_test.go

@@ -45,6 +45,7 @@ func (s *DockerSuite) TestBuildApiDockerfilePath(c *check.C) {
 }
 }
 
 
 func (s *DockerSuite) TestBuildApiDockerFileRemote(c *check.C) {
 func (s *DockerSuite) TestBuildApiDockerFileRemote(c *check.C) {
+	testRequires(c, NotUserNamespace)
 	testRequires(c, DaemonIsLinux)
 	testRequires(c, DaemonIsLinux)
 	server, err := fakeStorage(map[string]string{
 	server, err := fakeStorage(map[string]string{
 		"testD": `FROM busybox
 		"testD": `FROM busybox

+ 3 - 1
integration-cli/docker_api_containers_test.go

@@ -1487,7 +1487,9 @@ func (s *DockerSuite) TestContainersApiCreateNoHostConfig118(c *check.C) {
 // extract an archive to a symlink in a writable volume which points to a
 // extract an archive to a symlink in a writable volume which points to a
 // directory outside of the volume.
 // directory outside of the volume.
 func (s *DockerSuite) TestPutContainerArchiveErrSymlinkInVolumeToReadOnlyRootfs(c *check.C) {
 func (s *DockerSuite) TestPutContainerArchiveErrSymlinkInVolumeToReadOnlyRootfs(c *check.C) {
-	testRequires(c, SameHostDaemon) // Requires local volume mount bind.
+	// Requires local volume mount bind.
+	// --read-only + userns has remount issues
+	testRequires(c, SameHostDaemon, NotUserNamespace)
 
 
 	testVol := getTestDir(c, "test-put-container-archive-err-symlink-in-volume-to-read-only-rootfs-")
 	testVol := getTestDir(c, "test-put-container-archive-err-symlink-in-volume-to-read-only-rootfs-")
 	defer os.RemoveAll(testVol)
 	defer os.RemoveAll(testVol)

+ 18 - 1
integration-cli/docker_cli_build_test.go

@@ -2183,6 +2183,8 @@ func (s *DockerSuite) TestBuildWorkdirWithEnvVariables(c *check.C) {
 }
 }
 
 
 func (s *DockerSuite) TestBuildRelativeCopy(c *check.C) {
 func (s *DockerSuite) TestBuildRelativeCopy(c *check.C) {
+	// cat /test1/test2/foo gets permission denied for the user
+	testRequires(c, NotUserNamespace)
 	testRequires(c, DaemonIsLinux)
 	testRequires(c, DaemonIsLinux)
 	name := "testbuildrelativecopy"
 	name := "testbuildrelativecopy"
 	dockerfile := `
 	dockerfile := `
@@ -2683,6 +2685,8 @@ func (s *DockerSuite) TestBuildConditionalCache(c *check.C) {
 }
 }
 
 
 func (s *DockerSuite) TestBuildAddLocalFileWithCache(c *check.C) {
 func (s *DockerSuite) TestBuildAddLocalFileWithCache(c *check.C) {
+	// local files are not owned by the correct user
+	testRequires(c, NotUserNamespace)
 	testRequires(c, DaemonIsLinux)
 	testRequires(c, DaemonIsLinux)
 	name := "testbuildaddlocalfilewithcache"
 	name := "testbuildaddlocalfilewithcache"
 	name2 := "testbuildaddlocalfilewithcache2"
 	name2 := "testbuildaddlocalfilewithcache2"
@@ -2741,6 +2745,8 @@ func (s *DockerSuite) TestBuildAddMultipleLocalFileWithCache(c *check.C) {
 }
 }
 
 
 func (s *DockerSuite) TestBuildAddLocalFileWithoutCache(c *check.C) {
 func (s *DockerSuite) TestBuildAddLocalFileWithoutCache(c *check.C) {
+	// local files are not owned by the correct user
+	testRequires(c, NotUserNamespace)
 	testRequires(c, DaemonIsLinux)
 	testRequires(c, DaemonIsLinux)
 	name := "testbuildaddlocalfilewithoutcache"
 	name := "testbuildaddlocalfilewithoutcache"
 	name2 := "testbuildaddlocalfilewithoutcache2"
 	name2 := "testbuildaddlocalfilewithoutcache2"
@@ -3862,6 +3868,8 @@ RUN [ "$(id -u):$(id -g)/$(id -un):$(id -gn)/$(id -G):$(id -Gn)" = '1042:1043/10
 }
 }
 
 
 func (s *DockerSuite) TestBuildEnvUsage(c *check.C) {
 func (s *DockerSuite) TestBuildEnvUsage(c *check.C) {
+	// /docker/world/hello is not owned by the correct user
+	testRequires(c, NotUserNamespace)
 	testRequires(c, DaemonIsLinux)
 	testRequires(c, DaemonIsLinux)
 	name := "testbuildenvusage"
 	name := "testbuildenvusage"
 	dockerfile := `FROM busybox
 	dockerfile := `FROM busybox
@@ -3898,6 +3906,8 @@ RUN    [ "$ghi" = "def" ]
 }
 }
 
 
 func (s *DockerSuite) TestBuildEnvUsage2(c *check.C) {
 func (s *DockerSuite) TestBuildEnvUsage2(c *check.C) {
+	// /docker/world/hello is not owned by the correct user
+	testRequires(c, NotUserNamespace)
 	testRequires(c, DaemonIsLinux)
 	testRequires(c, DaemonIsLinux)
 	name := "testbuildenvusage2"
 	name := "testbuildenvusage2"
 	dockerfile := `FROM busybox
 	dockerfile := `FROM busybox
@@ -4024,6 +4034,8 @@ RUN [ "$(cat /testfile)" = 'test!' ]`
 }
 }
 
 
 func (s *DockerSuite) TestBuildAddTar(c *check.C) {
 func (s *DockerSuite) TestBuildAddTar(c *check.C) {
+	// /test/foo is not owned by the correct user
+	testRequires(c, NotUserNamespace)
 	testRequires(c, DaemonIsLinux)
 	testRequires(c, DaemonIsLinux)
 	name := "testbuildaddtar"
 	name := "testbuildaddtar"
 
 
@@ -4080,7 +4092,8 @@ RUN cat /existing-directory-trailing-slash/test/foo | grep Hi`
 }
 }
 
 
 func (s *DockerSuite) TestBuildAddTarXz(c *check.C) {
 func (s *DockerSuite) TestBuildAddTarXz(c *check.C) {
-	testRequires(c, DaemonIsLinux)
+	// /test/foo is not owned by the correct user
+	testRequires(c, NotUserNamespace)
 	testRequires(c, DaemonIsLinux)
 	testRequires(c, DaemonIsLinux)
 	name := "testbuildaddtarxz"
 	name := "testbuildaddtarxz"
 
 
@@ -4839,6 +4852,8 @@ func (s *DockerSuite) TestBuildSymlinkBreakout(c *check.C) {
 }
 }
 
 
 func (s *DockerSuite) TestBuildXZHost(c *check.C) {
 func (s *DockerSuite) TestBuildXZHost(c *check.C) {
+	// /usr/local/sbin/xz gets permission denied for the user
+	testRequires(c, NotUserNamespace)
 	testRequires(c, DaemonIsLinux)
 	testRequires(c, DaemonIsLinux)
 	name := "testbuildxzhost"
 	name := "testbuildxzhost"
 
 
@@ -4867,6 +4882,8 @@ RUN [ ! -e /injected ]`,
 }
 }
 
 
 func (s *DockerSuite) TestBuildVolumesRetainContents(c *check.C) {
 func (s *DockerSuite) TestBuildVolumesRetainContents(c *check.C) {
+	// /foo/file gets permission denied for the user
+	testRequires(c, NotUserNamespace)
 	testRequires(c, DaemonIsLinux)
 	testRequires(c, DaemonIsLinux)
 	var (
 	var (
 		name     = "testbuildvolumescontent"
 		name     = "testbuildvolumescontent"

+ 2 - 0
integration-cli/docker_cli_cp_test.go

@@ -589,6 +589,8 @@ func (s *DockerSuite) TestCpSpecialFiles(c *check.C) {
 }
 }
 
 
 func (s *DockerSuite) TestCpVolumePath(c *check.C) {
 func (s *DockerSuite) TestCpVolumePath(c *check.C) {
+	//  stat /tmp/cp-test-volumepath851508420/test gets permission denied for the user
+	testRequires(c, NotUserNamespace)
 	testRequires(c, DaemonIsLinux)
 	testRequires(c, DaemonIsLinux)
 	testRequires(c, SameHostDaemon)
 	testRequires(c, SameHostDaemon)
 
 

+ 6 - 2
integration-cli/docker_cli_cp_to_container_test.go

@@ -153,6 +153,8 @@ func (s *DockerSuite) TestCpToErrDstNotDir(c *check.C) {
 // Check that copying from a local path to a symlink in a container copies to
 // Check that copying from a local path to a symlink in a container copies to
 // the symlink target and does not overwrite the container symlink itself.
 // the symlink target and does not overwrite the container symlink itself.
 func (s *DockerSuite) TestCpToSymlinkDestination(c *check.C) {
 func (s *DockerSuite) TestCpToSymlinkDestination(c *check.C) {
+	//  stat /tmp/test-cp-to-symlink-destination-262430901/vol3 gets permission denied for the user
+	testRequires(c, NotUserNamespace)
 	testRequires(c, DaemonIsLinux)
 	testRequires(c, DaemonIsLinux)
 	testRequires(c, SameHostDaemon) // Requires local volume mount bind.
 	testRequires(c, SameHostDaemon) // Requires local volume mount bind.
 
 
@@ -699,7 +701,8 @@ func (s *DockerSuite) TestCpToCaseJ(c *check.C) {
 // The `docker cp` command should also ensure that you cannot
 // The `docker cp` command should also ensure that you cannot
 // write to a container rootfs that is marked as read-only.
 // write to a container rootfs that is marked as read-only.
 func (s *DockerSuite) TestCpToErrReadOnlyRootfs(c *check.C) {
 func (s *DockerSuite) TestCpToErrReadOnlyRootfs(c *check.C) {
-	testRequires(c, DaemonIsLinux)
+	// --read-only + userns has remount issues
+	testRequires(c, DaemonIsLinux, NotUserNamespace)
 	tmpDir := getTestDir(c, "test-cp-to-err-read-only-rootfs")
 	tmpDir := getTestDir(c, "test-cp-to-err-read-only-rootfs")
 	defer os.RemoveAll(tmpDir)
 	defer os.RemoveAll(tmpDir)
 
 
@@ -732,7 +735,8 @@ func (s *DockerSuite) TestCpToErrReadOnlyRootfs(c *check.C) {
 // The `docker cp` command should also ensure that you
 // The `docker cp` command should also ensure that you
 // cannot write to a volume that is mounted as read-only.
 // cannot write to a volume that is mounted as read-only.
 func (s *DockerSuite) TestCpToErrReadOnlyVolume(c *check.C) {
 func (s *DockerSuite) TestCpToErrReadOnlyVolume(c *check.C) {
-	testRequires(c, DaemonIsLinux)
+	// --read-only + userns has remount issues
+	testRequires(c, DaemonIsLinux, NotUserNamespace)
 	tmpDir := getTestDir(c, "test-cp-to-err-read-only-volume")
 	tmpDir := getTestDir(c, "test-cp-to-err-read-only-volume")
 	defer os.RemoveAll(tmpDir)
 	defer os.RemoveAll(tmpDir)
 
 

+ 1 - 1
integration-cli/docker_cli_create_test.go

@@ -276,7 +276,7 @@ func (s *DockerSuite) TestCreateRM(c *check.C) {
 
 
 func (s *DockerSuite) TestCreateModeIpcContainer(c *check.C) {
 func (s *DockerSuite) TestCreateModeIpcContainer(c *check.C) {
 	testRequires(c, DaemonIsLinux)
 	testRequires(c, DaemonIsLinux)
-	testRequires(c, SameHostDaemon)
+	testRequires(c, SameHostDaemon, NotUserNamespace)
 
 
 	out, _ := dockerCmd(c, "create", "busybox")
 	out, _ := dockerCmd(c, "create", "busybox")
 	id := strings.TrimSpace(out)
 	id := strings.TrimSpace(out)

+ 1 - 1
integration-cli/docker_cli_daemon_test.go

@@ -1483,7 +1483,7 @@ func (s *DockerDaemonSuite) TestCleanupMountsAfterCrash(c *check.C) {
 }
 }
 
 
 func (s *DockerDaemonSuite) TestRunContainerWithBridgeNone(c *check.C) {
 func (s *DockerDaemonSuite) TestRunContainerWithBridgeNone(c *check.C) {
-	testRequires(c, NativeExecDriver)
+	testRequires(c, NativeExecDriver, NotUserNamespace)
 	c.Assert(s.d.StartWithBusybox("-b", "none"), check.IsNil)
 	c.Assert(s.d.StartWithBusybox("-b", "none"), check.IsNil)
 
 
 	out, err := s.d.Cmd("run", "--rm", "busybox", "ip", "l")
 	out, err := s.d.Cmd("run", "--rm", "busybox", "ip", "l")

+ 4 - 2
integration-cli/docker_cli_exec_test.go

@@ -265,6 +265,7 @@ func (s *DockerSuite) TestExecStopNotHanging(c *check.C) {
 }
 }
 
 
 func (s *DockerSuite) TestExecCgroup(c *check.C) {
 func (s *DockerSuite) TestExecCgroup(c *check.C) {
+	testRequires(c, NotUserNamespace)
 	testRequires(c, DaemonIsLinux)
 	testRequires(c, DaemonIsLinux)
 	dockerCmd(c, "run", "-d", "--name", "testing", "busybox", "top")
 	dockerCmd(c, "run", "-d", "--name", "testing", "busybox", "top")
 
 
@@ -547,7 +548,7 @@ func (s *DockerSuite) TestExecWithUser(c *check.C) {
 }
 }
 
 
 func (s *DockerSuite) TestExecWithPrivileged(c *check.C) {
 func (s *DockerSuite) TestExecWithPrivileged(c *check.C) {
-	testRequires(c, DaemonIsLinux)
+	testRequires(c, DaemonIsLinux, NotUserNamespace)
 	// Start main loop which attempts mknod repeatedly
 	// Start main loop which attempts mknod repeatedly
 	dockerCmd(c, "run", "-d", "--name", "parent", "--cap-drop=ALL", "busybox", "sh", "-c", `while (true); do if [ -e /exec_priv ]; then cat /exec_priv && mknod /tmp/sda b 8 0 && echo "Success"; else echo "Privileged exec has not run yet"; fi; usleep 10000; done`)
 	dockerCmd(c, "run", "-d", "--name", "parent", "--cap-drop=ALL", "busybox", "sh", "-c", `while (true); do if [ -e /exec_priv ]; then cat /exec_priv && mknod /tmp/sda b 8 0 && echo "Success"; else echo "Privileged exec has not run yet"; fi; usleep 10000; done`)
 
 
@@ -605,7 +606,8 @@ func (s *DockerSuite) TestExecWithImageUser(c *check.C) {
 }
 }
 
 
 func (s *DockerSuite) TestExecOnReadonlyContainer(c *check.C) {
 func (s *DockerSuite) TestExecOnReadonlyContainer(c *check.C) {
-	testRequires(c, DaemonIsLinux)
+	// --read-only + userns has remount issues
+	testRequires(c, DaemonIsLinux, NotUserNamespace)
 	dockerCmd(c, "run", "-d", "--read-only", "--name", "parent", "busybox", "top")
 	dockerCmd(c, "run", "-d", "--read-only", "--name", "parent", "busybox", "top")
 	if _, status := dockerCmd(c, "exec", "parent", "true"); status != 0 {
 	if _, status := dockerCmd(c, "exec", "parent", "true"); status != 0 {
 		c.Fatalf("exec into a read-only container failed with exit status %d", status)
 		c.Fatalf("exec into a read-only container failed with exit status %d", status)

+ 4 - 3
integration-cli/docker_cli_links_test.go

@@ -2,10 +2,11 @@ package main
 
 
 import (
 import (
 	"fmt"
 	"fmt"
-	"github.com/go-check/check"
 	"reflect"
 	"reflect"
 	"regexp"
 	"regexp"
 	"strings"
 	"strings"
+
+	"github.com/go-check/check"
 )
 )
 
 
 func (s *DockerSuite) TestLinksPingUnlinkedContainers(c *check.C) {
 func (s *DockerSuite) TestLinksPingUnlinkedContainers(c *check.C) {
@@ -233,7 +234,7 @@ func (s *DockerSuite) TestLinkShortDefinition(c *check.C) {
 }
 }
 
 
 func (s *DockerSuite) TestLinksNetworkHostContainer(c *check.C) {
 func (s *DockerSuite) TestLinksNetworkHostContainer(c *check.C) {
-	testRequires(c, DaemonIsLinux)
+	testRequires(c, DaemonIsLinux, NotUserNamespace)
 	dockerCmd(c, "run", "-d", "--net", "host", "--name", "host_container", "busybox", "top")
 	dockerCmd(c, "run", "-d", "--net", "host", "--name", "host_container", "busybox", "top")
 	out, _, err := dockerCmdWithError("run", "--name", "should_fail", "--link", "host_container:tester", "busybox", "true")
 	out, _, err := dockerCmdWithError("run", "--name", "should_fail", "--link", "host_container:tester", "busybox", "true")
 	if err == nil || !strings.Contains(out, "--net=host can't be used with links. This would result in undefined behavior") {
 	if err == nil || !strings.Contains(out, "--net=host can't be used with links. This would result in undefined behavior") {
@@ -242,7 +243,7 @@ func (s *DockerSuite) TestLinksNetworkHostContainer(c *check.C) {
 }
 }
 
 
 func (s *DockerSuite) TestLinksEtcHostsRegularFile(c *check.C) {
 func (s *DockerSuite) TestLinksEtcHostsRegularFile(c *check.C) {
-	testRequires(c, DaemonIsLinux)
+	testRequires(c, DaemonIsLinux, NotUserNamespace)
 	out, _ := dockerCmd(c, "run", "--net=host", "busybox", "ls", "-la", "/etc/hosts")
 	out, _ := dockerCmd(c, "run", "--net=host", "busybox", "ls", "-la", "/etc/hosts")
 	if !strings.HasPrefix(out, "-") {
 	if !strings.HasPrefix(out, "-") {
 		c.Errorf("/etc/hosts should be a regular file")
 		c.Errorf("/etc/hosts should be a regular file")

+ 1 - 1
integration-cli/docker_cli_links_unix_test.go

@@ -12,7 +12,7 @@ import (
 func (s *DockerSuite) TestLinksEtcHostsContentMatch(c *check.C) {
 func (s *DockerSuite) TestLinksEtcHostsContentMatch(c *check.C) {
 	// In a _unix file as using Unix specific files, and must be on the
 	// In a _unix file as using Unix specific files, and must be on the
 	// same host as the daemon.
 	// same host as the daemon.
-	testRequires(c, SameHostDaemon)
+	testRequires(c, SameHostDaemon, NotUserNamespace)
 
 
 	out, _ := dockerCmd(c, "run", "--net=host", "busybox", "cat", "/etc/hosts")
 	out, _ := dockerCmd(c, "run", "--net=host", "busybox", "cat", "/etc/hosts")
 	hosts, err := ioutil.ReadFile("/etc/hosts")
 	hosts, err := ioutil.ReadFile("/etc/hosts")

+ 1 - 1
integration-cli/docker_cli_nat_test.go

@@ -98,7 +98,7 @@ func (s *DockerSuite) TestNetworkLocalhostTCPNat(c *check.C) {
 
 
 func (s *DockerSuite) TestNetworkLoopbackNat(c *check.C) {
 func (s *DockerSuite) TestNetworkLoopbackNat(c *check.C) {
 	testRequires(c, DaemonIsLinux)
 	testRequires(c, DaemonIsLinux)
-	testRequires(c, SameHostDaemon, NativeExecDriver)
+	testRequires(c, SameHostDaemon, NativeExecDriver, NotUserNamespace)
 	msg := "it works"
 	msg := "it works"
 	startServerContainer(c, msg, 8080)
 	startServerContainer(c, msg, 8080)
 	endpoint := getExternalAddress(c)
 	endpoint := getExternalAddress(c)

+ 3 - 3
integration-cli/docker_cli_netmode_test.go

@@ -23,7 +23,7 @@ func checkContains(expected string, out string, c *check.C) {
 }
 }
 
 
 func (s *DockerSuite) TestNetHostname(c *check.C) {
 func (s *DockerSuite) TestNetHostname(c *check.C) {
-	testRequires(c, DaemonIsLinux)
+	testRequires(c, DaemonIsLinux, NotUserNamespace)
 
 
 	var (
 	var (
 		out    string
 		out    string
@@ -81,7 +81,7 @@ func (s *DockerSuite) TestNetHostname(c *check.C) {
 }
 }
 
 
 func (s *DockerSuite) TestConflictContainerNetworkAndLinks(c *check.C) {
 func (s *DockerSuite) TestConflictContainerNetworkAndLinks(c *check.C) {
-	testRequires(c, DaemonIsLinux)
+	testRequires(c, DaemonIsLinux, NotUserNamespace)
 	var (
 	var (
 		out    string
 		out    string
 		err    error
 		err    error
@@ -102,7 +102,7 @@ func (s *DockerSuite) TestConflictContainerNetworkAndLinks(c *check.C) {
 }
 }
 
 
 func (s *DockerSuite) TestConflictNetworkModeAndOptions(c *check.C) {
 func (s *DockerSuite) TestConflictNetworkModeAndOptions(c *check.C) {
-	testRequires(c, DaemonIsLinux)
+	testRequires(c, DaemonIsLinux, NotUserNamespace)
 	var (
 	var (
 		out    string
 		out    string
 		err    error
 		err    error

+ 2 - 2
integration-cli/docker_cli_port_test.go

@@ -249,7 +249,7 @@ func (s *DockerSuite) TestUnpublishedPortsInPsOutput(c *check.C) {
 }
 }
 
 
 func (s *DockerSuite) TestPortHostBinding(c *check.C) {
 func (s *DockerSuite) TestPortHostBinding(c *check.C) {
-	testRequires(c, DaemonIsLinux)
+	testRequires(c, DaemonIsLinux, NotUserNamespace)
 	out, _ := dockerCmd(c, "run", "-d", "-p", "9876:80", "busybox",
 	out, _ := dockerCmd(c, "run", "-d", "-p", "9876:80", "busybox",
 		"nc", "-l", "-p", "80")
 		"nc", "-l", "-p", "80")
 	firstID := strings.TrimSpace(out)
 	firstID := strings.TrimSpace(out)
@@ -272,7 +272,7 @@ func (s *DockerSuite) TestPortHostBinding(c *check.C) {
 }
 }
 
 
 func (s *DockerSuite) TestPortExposeHostBinding(c *check.C) {
 func (s *DockerSuite) TestPortExposeHostBinding(c *check.C) {
-	testRequires(c, DaemonIsLinux)
+	testRequires(c, DaemonIsLinux, NotUserNamespace)
 	out, _ := dockerCmd(c, "run", "-d", "-P", "--expose", "80", "busybox",
 	out, _ := dockerCmd(c, "run", "-d", "-P", "--expose", "80", "busybox",
 		"nc", "-l", "-p", "80")
 		"nc", "-l", "-p", "80")
 	firstID := strings.TrimSpace(out)
 	firstID := strings.TrimSpace(out)

+ 61 - 48
integration-cli/docker_cli_run_test.go

@@ -707,7 +707,7 @@ func (s *DockerSuite) TestRunContainerNetwork(c *check.C) {
 func (s *DockerSuite) TestRunNetHostNotAllowedWithLinks(c *check.C) {
 func (s *DockerSuite) TestRunNetHostNotAllowedWithLinks(c *check.C) {
 	// TODO Windows: This is Linux specific as --link is not supported and
 	// TODO Windows: This is Linux specific as --link is not supported and
 	// this will be deprecated in favour of container networking model.
 	// this will be deprecated in favour of container networking model.
-	testRequires(c, DaemonIsLinux)
+	testRequires(c, DaemonIsLinux, NotUserNamespace)
 	dockerCmd(c, "run", "--name", "linked", "busybox", "true")
 	dockerCmd(c, "run", "--name", "linked", "busybox", "true")
 
 
 	_, _, err := dockerCmdWithError("run", "--net=host", "--link", "linked:linked", "busybox", "true")
 	_, _, err := dockerCmdWithError("run", "--net=host", "--link", "linked:linked", "busybox", "true")
@@ -733,7 +733,7 @@ func (s *DockerSuite) TestRunFullHostnameSet(c *check.C) {
 func (s *DockerSuite) TestRunPrivilegedCanMknod(c *check.C) {
 func (s *DockerSuite) TestRunPrivilegedCanMknod(c *check.C) {
 	// Not applicable for Windows as Windows daemon does not support
 	// Not applicable for Windows as Windows daemon does not support
 	// the concept of --privileged, and mknod is a Unix concept.
 	// the concept of --privileged, and mknod is a Unix concept.
-	testRequires(c, DaemonIsLinux)
+	testRequires(c, DaemonIsLinux, NotUserNamespace)
 	out, _ := dockerCmd(c, "run", "--privileged", "busybox", "sh", "-c", "mknod /tmp/sda b 8 0 && echo ok")
 	out, _ := dockerCmd(c, "run", "--privileged", "busybox", "sh", "-c", "mknod /tmp/sda b 8 0 && echo ok")
 	if actual := strings.Trim(out, "\r\n"); actual != "ok" {
 	if actual := strings.Trim(out, "\r\n"); actual != "ok" {
 		c.Fatalf("expected output ok received %s", actual)
 		c.Fatalf("expected output ok received %s", actual)
@@ -743,7 +743,7 @@ func (s *DockerSuite) TestRunPrivilegedCanMknod(c *check.C) {
 func (s *DockerSuite) TestRunUnprivilegedCanMknod(c *check.C) {
 func (s *DockerSuite) TestRunUnprivilegedCanMknod(c *check.C) {
 	// Not applicable for Windows as Windows daemon does not support
 	// Not applicable for Windows as Windows daemon does not support
 	// the concept of --privileged, and mknod is a Unix concept.
 	// the concept of --privileged, and mknod is a Unix concept.
-	testRequires(c, DaemonIsLinux)
+	testRequires(c, DaemonIsLinux, NotUserNamespace)
 	out, _ := dockerCmd(c, "run", "busybox", "sh", "-c", "mknod /tmp/sda b 8 0 && echo ok")
 	out, _ := dockerCmd(c, "run", "busybox", "sh", "-c", "mknod /tmp/sda b 8 0 && echo ok")
 	if actual := strings.Trim(out, "\r\n"); actual != "ok" {
 	if actual := strings.Trim(out, "\r\n"); actual != "ok" {
 		c.Fatalf("expected output ok received %s", actual)
 		c.Fatalf("expected output ok received %s", actual)
@@ -799,7 +799,7 @@ func (s *DockerSuite) TestRunCapDropALLCannotMknod(c *check.C) {
 
 
 func (s *DockerSuite) TestRunCapDropALLAddMknodCanMknod(c *check.C) {
 func (s *DockerSuite) TestRunCapDropALLAddMknodCanMknod(c *check.C) {
 	// Not applicable for Windows as there is no concept of --cap-drop or mknod
 	// Not applicable for Windows as there is no concept of --cap-drop or mknod
-	testRequires(c, DaemonIsLinux)
+	testRequires(c, DaemonIsLinux, NotUserNamespace)
 	out, _ := dockerCmd(c, "run", "--cap-drop=ALL", "--cap-add=MKNOD", "--cap-add=SETGID", "busybox", "sh", "-c", "mknod /tmp/sda b 8 0 && echo ok")
 	out, _ := dockerCmd(c, "run", "--cap-drop=ALL", "--cap-add=MKNOD", "--cap-add=SETGID", "busybox", "sh", "-c", "mknod /tmp/sda b 8 0 && echo ok")
 
 
 	if actual := strings.Trim(out, "\r\n"); actual != "ok" {
 	if actual := strings.Trim(out, "\r\n"); actual != "ok" {
@@ -861,7 +861,7 @@ func (s *DockerSuite) TestRunGroupAdd(c *check.C) {
 
 
 func (s *DockerSuite) TestRunPrivilegedCanMount(c *check.C) {
 func (s *DockerSuite) TestRunPrivilegedCanMount(c *check.C) {
 	// Not applicable for Windows as there is no concept of --privileged
 	// Not applicable for Windows as there is no concept of --privileged
-	testRequires(c, DaemonIsLinux)
+	testRequires(c, DaemonIsLinux, NotUserNamespace)
 	out, _ := dockerCmd(c, "run", "--privileged", "busybox", "sh", "-c", "mount -t tmpfs none /tmp && echo ok")
 	out, _ := dockerCmd(c, "run", "--privileged", "busybox", "sh", "-c", "mount -t tmpfs none /tmp && echo ok")
 
 
 	if actual := strings.Trim(out, "\r\n"); actual != "ok" {
 	if actual := strings.Trim(out, "\r\n"); actual != "ok" {
@@ -892,7 +892,7 @@ func (s *DockerSuite) TestRunSysNotWritableInNonPrivilegedContainers(c *check.C)
 
 
 func (s *DockerSuite) TestRunSysWritableInPrivilegedContainers(c *check.C) {
 func (s *DockerSuite) TestRunSysWritableInPrivilegedContainers(c *check.C) {
 	// Not applicable for Windows as there is no concept of unprivileged
 	// Not applicable for Windows as there is no concept of unprivileged
-	testRequires(c, DaemonIsLinux)
+	testRequires(c, DaemonIsLinux, NotUserNamespace)
 	if _, code, err := dockerCmdWithError("run", "--privileged", "busybox", "touch", "/sys/kernel/profiling"); err != nil || code != 0 {
 	if _, code, err := dockerCmdWithError("run", "--privileged", "busybox", "touch", "/sys/kernel/profiling"); err != nil || code != 0 {
 		c.Fatalf("sys should be writable in privileged container")
 		c.Fatalf("sys should be writable in privileged container")
 	}
 	}
@@ -908,7 +908,7 @@ func (s *DockerSuite) TestRunProcNotWritableInNonPrivilegedContainers(c *check.C
 
 
 func (s *DockerSuite) TestRunProcWritableInPrivilegedContainers(c *check.C) {
 func (s *DockerSuite) TestRunProcWritableInPrivilegedContainers(c *check.C) {
 	// Not applicable for Windows as there is no concept of --privileged
 	// Not applicable for Windows as there is no concept of --privileged
-	testRequires(c, DaemonIsLinux)
+	testRequires(c, DaemonIsLinux, NotUserNamespace)
 	if _, code := dockerCmd(c, "run", "--privileged", "busybox", "touch", "/proc/sysrq-trigger"); code != 0 {
 	if _, code := dockerCmd(c, "run", "--privileged", "busybox", "touch", "/proc/sysrq-trigger"); code != 0 {
 		c.Fatalf("proc should be writable in privileged container")
 		c.Fatalf("proc should be writable in privileged container")
 	}
 	}
@@ -916,7 +916,8 @@ func (s *DockerSuite) TestRunProcWritableInPrivilegedContainers(c *check.C) {
 
 
 func (s *DockerSuite) TestRunDeviceNumbers(c *check.C) {
 func (s *DockerSuite) TestRunDeviceNumbers(c *check.C) {
 	// Not applicable on Windows as /dev/ is a Unix specific concept
 	// Not applicable on Windows as /dev/ is a Unix specific concept
-	testRequires(c, DaemonIsLinux)
+	// TODO: NotUserNamespace could be removed here if "root" "root" is replaced w user
+	testRequires(c, DaemonIsLinux, NotUserNamespace)
 	out, _ := dockerCmd(c, "run", "busybox", "sh", "-c", "ls -l /dev/null")
 	out, _ := dockerCmd(c, "run", "busybox", "sh", "-c", "ls -l /dev/null")
 	deviceLineFields := strings.Fields(out)
 	deviceLineFields := strings.Fields(out)
 	deviceLineFields[6] = ""
 	deviceLineFields[6] = ""
@@ -946,7 +947,7 @@ func (s *DockerSuite) TestRunUnprivilegedWithChroot(c *check.C) {
 
 
 func (s *DockerSuite) TestRunAddingOptionalDevices(c *check.C) {
 func (s *DockerSuite) TestRunAddingOptionalDevices(c *check.C) {
 	// Not applicable on Windows as Windows does not support --device
 	// Not applicable on Windows as Windows does not support --device
-	testRequires(c, DaemonIsLinux)
+	testRequires(c, DaemonIsLinux, NotUserNamespace)
 	out, _ := dockerCmd(c, "run", "--device", "/dev/zero:/dev/nulo", "busybox", "sh", "-c", "ls /dev/nulo")
 	out, _ := dockerCmd(c, "run", "--device", "/dev/zero:/dev/nulo", "busybox", "sh", "-c", "ls /dev/nulo")
 	if actual := strings.Trim(out, "\r\n"); actual != "/dev/nulo" {
 	if actual := strings.Trim(out, "\r\n"); actual != "/dev/nulo" {
 		c.Fatalf("expected output /dev/nulo, received %s", actual)
 		c.Fatalf("expected output /dev/nulo, received %s", actual)
@@ -955,7 +956,7 @@ func (s *DockerSuite) TestRunAddingOptionalDevices(c *check.C) {
 
 
 func (s *DockerSuite) TestRunAddingOptionalDevicesNoSrc(c *check.C) {
 func (s *DockerSuite) TestRunAddingOptionalDevicesNoSrc(c *check.C) {
 	// Not applicable on Windows as Windows does not support --device
 	// Not applicable on Windows as Windows does not support --device
-	testRequires(c, DaemonIsLinux)
+	testRequires(c, DaemonIsLinux, NotUserNamespace)
 	out, _ := dockerCmd(c, "run", "--device", "/dev/zero:rw", "busybox", "sh", "-c", "ls /dev/zero")
 	out, _ := dockerCmd(c, "run", "--device", "/dev/zero:rw", "busybox", "sh", "-c", "ls /dev/zero")
 	if actual := strings.Trim(out, "\r\n"); actual != "/dev/zero" {
 	if actual := strings.Trim(out, "\r\n"); actual != "/dev/zero" {
 		c.Fatalf("expected output /dev/zero, received %s", actual)
 		c.Fatalf("expected output /dev/zero, received %s", actual)
@@ -964,7 +965,7 @@ func (s *DockerSuite) TestRunAddingOptionalDevicesNoSrc(c *check.C) {
 
 
 func (s *DockerSuite) TestRunAddingOptionalDevicesInvalidMode(c *check.C) {
 func (s *DockerSuite) TestRunAddingOptionalDevicesInvalidMode(c *check.C) {
 	// Not applicable on Windows as Windows does not support --device
 	// Not applicable on Windows as Windows does not support --device
-	testRequires(c, DaemonIsLinux)
+	testRequires(c, DaemonIsLinux, NotUserNamespace)
 	_, _, err := dockerCmdWithError("run", "--device", "/dev/zero:ro", "busybox", "sh", "-c", "ls /dev/zero")
 	_, _, err := dockerCmdWithError("run", "--device", "/dev/zero:ro", "busybox", "sh", "-c", "ls /dev/zero")
 	if err == nil {
 	if err == nil {
 		c.Fatalf("run container with device mode ro should fail")
 		c.Fatalf("run container with device mode ro should fail")
@@ -973,7 +974,7 @@ func (s *DockerSuite) TestRunAddingOptionalDevicesInvalidMode(c *check.C) {
 
 
 func (s *DockerSuite) TestRunModeHostname(c *check.C) {
 func (s *DockerSuite) TestRunModeHostname(c *check.C) {
 	// Not applicable on Windows as Windows does not support -h
 	// Not applicable on Windows as Windows does not support -h
-	testRequires(c, SameHostDaemon, DaemonIsLinux)
+	testRequires(c, SameHostDaemon, DaemonIsLinux, NotUserNamespace)
 
 
 	out, _ := dockerCmd(c, "run", "-h=testhostname", "busybox", "cat", "/etc/hostname")
 	out, _ := dockerCmd(c, "run", "-h=testhostname", "busybox", "cat", "/etc/hostname")
 
 
@@ -1711,6 +1712,8 @@ func (s *DockerSuite) TestRunEntrypoint(c *check.C) {
 }
 }
 
 
 func (s *DockerSuite) TestRunBindMounts(c *check.C) {
 func (s *DockerSuite) TestRunBindMounts(c *check.C) {
+	// /tmp gets permission denied
+	testRequires(c, NotUserNamespace)
 	// Cannot run on Windows as Windows does not support volumes
 	// Cannot run on Windows as Windows does not support volumes
 	testRequires(c, DaemonIsLinux, SameHostDaemon)
 	testRequires(c, DaemonIsLinux, SameHostDaemon)
 
 
@@ -1909,6 +1912,8 @@ func (s *DockerSuite) TestRunAllocatePortInReservedRange(c *check.C) {
 
 
 // Regression test for #7792
 // Regression test for #7792
 func (s *DockerSuite) TestRunMountOrdering(c *check.C) {
 func (s *DockerSuite) TestRunMountOrdering(c *check.C) {
+	// tmp gets permission denied
+	testRequires(c, NotUserNamespace)
 	// Not applicable on Windows as Windows does not support volumes
 	// Not applicable on Windows as Windows does not support volumes
 	testRequires(c, SameHostDaemon, DaemonIsLinux)
 	testRequires(c, SameHostDaemon, DaemonIsLinux)
 
 
@@ -1953,6 +1958,8 @@ func (s *DockerSuite) TestRunMountOrdering(c *check.C) {
 
 
 // Regression test for https://github.com/docker/docker/issues/8259
 // Regression test for https://github.com/docker/docker/issues/8259
 func (s *DockerSuite) TestRunReuseBindVolumeThatIsSymlink(c *check.C) {
 func (s *DockerSuite) TestRunReuseBindVolumeThatIsSymlink(c *check.C) {
+	// /tmp gets permission denied
+	testRequires(c, NotUserNamespace)
 	// Not applicable on Windows as Windows does not support volumes
 	// Not applicable on Windows as Windows does not support volumes
 	testRequires(c, SameHostDaemon, DaemonIsLinux)
 	testRequires(c, SameHostDaemon, DaemonIsLinux)
 
 
@@ -2157,7 +2164,7 @@ func (s *DockerSuite) TestRunUnknownCommand(c *check.C) {
 
 
 func (s *DockerSuite) TestRunModeIpcHost(c *check.C) {
 func (s *DockerSuite) TestRunModeIpcHost(c *check.C) {
 	// Not applicable on Windows as uses Unix-specific capabilities
 	// Not applicable on Windows as uses Unix-specific capabilities
-	testRequires(c, SameHostDaemon, DaemonIsLinux)
+	testRequires(c, SameHostDaemon, DaemonIsLinux, NotUserNamespace)
 
 
 	hostIpc, err := os.Readlink("/proc/1/ns/ipc")
 	hostIpc, err := os.Readlink("/proc/1/ns/ipc")
 	if err != nil {
 	if err != nil {
@@ -2179,7 +2186,7 @@ func (s *DockerSuite) TestRunModeIpcHost(c *check.C) {
 
 
 func (s *DockerSuite) TestRunModeIpcContainer(c *check.C) {
 func (s *DockerSuite) TestRunModeIpcContainer(c *check.C) {
 	// Not applicable on Windows as uses Unix-specific capabilities
 	// Not applicable on Windows as uses Unix-specific capabilities
-	testRequires(c, SameHostDaemon, DaemonIsLinux)
+	testRequires(c, SameHostDaemon, DaemonIsLinux, NotUserNamespace)
 
 
 	out, _ := dockerCmd(c, "run", "-d", "busybox", "sh", "-c", "echo -n test > /dev/shm/test && top")
 	out, _ := dockerCmd(c, "run", "-d", "busybox", "sh", "-c", "echo -n test > /dev/shm/test && top")
 
 
@@ -2211,7 +2218,7 @@ func (s *DockerSuite) TestRunModeIpcContainer(c *check.C) {
 
 
 func (s *DockerSuite) TestRunModeIpcContainerNotExists(c *check.C) {
 func (s *DockerSuite) TestRunModeIpcContainerNotExists(c *check.C) {
 	// Not applicable on Windows as uses Unix-specific capabilities
 	// Not applicable on Windows as uses Unix-specific capabilities
-	testRequires(c, DaemonIsLinux)
+	testRequires(c, DaemonIsLinux, NotUserNamespace)
 	out, _, err := dockerCmdWithError("run", "-d", "--ipc", "container:abcd1234", "busybox", "top")
 	out, _, err := dockerCmdWithError("run", "-d", "--ipc", "container:abcd1234", "busybox", "top")
 	if !strings.Contains(out, "abcd1234") || err == nil {
 	if !strings.Contains(out, "abcd1234") || err == nil {
 		c.Fatalf("run IPC from a non exists container should with correct error out")
 		c.Fatalf("run IPC from a non exists container should with correct error out")
@@ -2220,7 +2227,7 @@ func (s *DockerSuite) TestRunModeIpcContainerNotExists(c *check.C) {
 
 
 func (s *DockerSuite) TestRunModeIpcContainerNotRunning(c *check.C) {
 func (s *DockerSuite) TestRunModeIpcContainerNotRunning(c *check.C) {
 	// Not applicable on Windows as uses Unix-specific capabilities
 	// Not applicable on Windows as uses Unix-specific capabilities
-	testRequires(c, SameHostDaemon, DaemonIsLinux)
+	testRequires(c, SameHostDaemon, DaemonIsLinux, NotUserNamespace)
 
 
 	out, _ := dockerCmd(c, "create", "busybox")
 	out, _ := dockerCmd(c, "create", "busybox")
 
 
@@ -2250,7 +2257,7 @@ func (s *DockerSuite) TestRunMountShmMqueueFromHost(c *check.C) {
 
 
 func (s *DockerSuite) TestContainerNetworkMode(c *check.C) {
 func (s *DockerSuite) TestContainerNetworkMode(c *check.C) {
 	// Not applicable on Windows as uses Unix-specific capabilities
 	// Not applicable on Windows as uses Unix-specific capabilities
-	testRequires(c, SameHostDaemon, DaemonIsLinux)
+	testRequires(c, SameHostDaemon, DaemonIsLinux, NotUserNamespace)
 
 
 	out, _ := dockerCmd(c, "run", "-d", "busybox", "top")
 	out, _ := dockerCmd(c, "run", "-d", "busybox", "top")
 	id := strings.TrimSpace(out)
 	id := strings.TrimSpace(out)
@@ -2272,7 +2279,7 @@ func (s *DockerSuite) TestContainerNetworkMode(c *check.C) {
 
 
 func (s *DockerSuite) TestRunModePidHost(c *check.C) {
 func (s *DockerSuite) TestRunModePidHost(c *check.C) {
 	// Not applicable on Windows as uses Unix-specific capabilities
 	// Not applicable on Windows as uses Unix-specific capabilities
-	testRequires(c, NativeExecDriver, SameHostDaemon, DaemonIsLinux)
+	testRequires(c, NativeExecDriver, SameHostDaemon, DaemonIsLinux, NotUserNamespace)
 
 
 	hostPid, err := os.Readlink("/proc/1/ns/pid")
 	hostPid, err := os.Readlink("/proc/1/ns/pid")
 	if err != nil {
 	if err != nil {
@@ -2413,7 +2420,7 @@ func (s *DockerSuite) TestRunNonLocalMacAddress(c *check.C) {
 
 
 func (s *DockerSuite) TestRunNetHost(c *check.C) {
 func (s *DockerSuite) TestRunNetHost(c *check.C) {
 	// Not applicable on Windows as uses Unix-specific capabilities
 	// Not applicable on Windows as uses Unix-specific capabilities
-	testRequires(c, SameHostDaemon, DaemonIsLinux)
+	testRequires(c, SameHostDaemon, DaemonIsLinux, NotUserNamespace)
 
 
 	hostNet, err := os.Readlink("/proc/1/ns/net")
 	hostNet, err := os.Readlink("/proc/1/ns/net")
 	if err != nil {
 	if err != nil {
@@ -2436,7 +2443,7 @@ func (s *DockerSuite) TestRunNetHost(c *check.C) {
 func (s *DockerSuite) TestRunNetHostTwiceSameName(c *check.C) {
 func (s *DockerSuite) TestRunNetHostTwiceSameName(c *check.C) {
 	// TODO Windows. As Windows networking evolves and converges towards
 	// TODO Windows. As Windows networking evolves and converges towards
 	// CNM, this test may be possible to enable on Windows.
 	// CNM, this test may be possible to enable on Windows.
-	testRequires(c, SameHostDaemon, DaemonIsLinux)
+	testRequires(c, SameHostDaemon, DaemonIsLinux, NotUserNamespace)
 
 
 	dockerCmd(c, "run", "--rm", "--name=thost", "--net=host", "busybox", "true")
 	dockerCmd(c, "run", "--rm", "--name=thost", "--net=host", "busybox", "true")
 	dockerCmd(c, "run", "--rm", "--name=thost", "--net=host", "busybox", "true")
 	dockerCmd(c, "run", "--rm", "--name=thost", "--net=host", "busybox", "true")
@@ -2444,7 +2451,7 @@ func (s *DockerSuite) TestRunNetHostTwiceSameName(c *check.C) {
 
 
 func (s *DockerSuite) TestRunNetContainerWhichHost(c *check.C) {
 func (s *DockerSuite) TestRunNetContainerWhichHost(c *check.C) {
 	// Not applicable on Windows as uses Unix-specific capabilities
 	// Not applicable on Windows as uses Unix-specific capabilities
-	testRequires(c, SameHostDaemon, DaemonIsLinux)
+	testRequires(c, SameHostDaemon, DaemonIsLinux, NotUserNamespace)
 
 
 	hostNet, err := os.Readlink("/proc/1/ns/net")
 	hostNet, err := os.Readlink("/proc/1/ns/net")
 	if err != nil {
 	if err != nil {
@@ -2534,7 +2541,8 @@ func (s *DockerSuite) TestRunContainerWithReadonlyRootfs(c *check.C) {
 func (s *DockerSuite) TestPermissionsPtsReadonlyRootfs(c *check.C) {
 func (s *DockerSuite) TestPermissionsPtsReadonlyRootfs(c *check.C) {
 	// Not applicable on Windows due to use of Unix specific functionality, plus
 	// Not applicable on Windows due to use of Unix specific functionality, plus
 	// the use of --read-only which is not supported.
 	// the use of --read-only which is not supported.
-	testRequires(c, DaemonIsLinux, NativeExecDriver)
+	// --read-only + userns has remount issues
+	testRequires(c, DaemonIsLinux, NativeExecDriver, NotUserNamespace)
 
 
 	// Ensure we have not broken writing /dev/pts
 	// Ensure we have not broken writing /dev/pts
 	out, status := dockerCmd(c, "run", "--read-only", "--rm", "busybox", "mount")
 	out, status := dockerCmd(c, "run", "--read-only", "--rm", "busybox", "mount")
@@ -2549,7 +2557,7 @@ func (s *DockerSuite) TestPermissionsPtsReadonlyRootfs(c *check.C) {
 
 
 func testReadOnlyFile(filename string, c *check.C) {
 func testReadOnlyFile(filename string, c *check.C) {
 	// Not applicable on Windows which does not support --read-only
 	// Not applicable on Windows which does not support --read-only
-	testRequires(c, NativeExecDriver, DaemonIsLinux)
+	testRequires(c, NativeExecDriver, DaemonIsLinux, NotUserNamespace)
 
 
 	out, _, err := dockerCmdWithError("run", "--read-only", "--rm", "busybox", "touch", filename)
 	out, _, err := dockerCmdWithError("run", "--read-only", "--rm", "busybox", "touch", filename)
 	if err == nil {
 	if err == nil {
@@ -2572,7 +2580,8 @@ func testReadOnlyFile(filename string, c *check.C) {
 
 
 func (s *DockerSuite) TestRunContainerWithReadonlyEtcHostsAndLinkedContainer(c *check.C) {
 func (s *DockerSuite) TestRunContainerWithReadonlyEtcHostsAndLinkedContainer(c *check.C) {
 	// Not applicable on Windows which does not support --link
 	// Not applicable on Windows which does not support --link
-	testRequires(c, NativeExecDriver, DaemonIsLinux)
+	// --read-only + userns has remount issues
+	testRequires(c, NativeExecDriver, DaemonIsLinux, NotUserNamespace)
 
 
 	dockerCmd(c, "run", "-d", "--name", "test-etc-hosts-ro-linked", "busybox", "top")
 	dockerCmd(c, "run", "-d", "--name", "test-etc-hosts-ro-linked", "busybox", "top")
 
 
@@ -2583,9 +2592,9 @@ func (s *DockerSuite) TestRunContainerWithReadonlyEtcHostsAndLinkedContainer(c *
 }
 }
 
 
 func (s *DockerSuite) TestRunContainerWithReadonlyRootfsWithDnsFlag(c *check.C) {
 func (s *DockerSuite) TestRunContainerWithReadonlyRootfsWithDnsFlag(c *check.C) {
-	// Not applicable on Windows which does not support either --read-only or
-	// --dns.
-	testRequires(c, NativeExecDriver, DaemonIsLinux)
+	// Not applicable on Windows which does not support either --read-only or --dns.
+	// --read-only + userns has remount issues
+	testRequires(c, NativeExecDriver, DaemonIsLinux, NotUserNamespace)
 
 
 	out, _ := dockerCmd(c, "run", "--read-only", "--dns", "1.1.1.1", "busybox", "/bin/cat", "/etc/resolv.conf")
 	out, _ := dockerCmd(c, "run", "--read-only", "--dns", "1.1.1.1", "busybox", "/bin/cat", "/etc/resolv.conf")
 	if !strings.Contains(string(out), "1.1.1.1") {
 	if !strings.Contains(string(out), "1.1.1.1") {
@@ -2595,7 +2604,8 @@ func (s *DockerSuite) TestRunContainerWithReadonlyRootfsWithDnsFlag(c *check.C)
 
 
 func (s *DockerSuite) TestRunContainerWithReadonlyRootfsWithAddHostFlag(c *check.C) {
 func (s *DockerSuite) TestRunContainerWithReadonlyRootfsWithAddHostFlag(c *check.C) {
 	// Not applicable on Windows which does not support --read-only
 	// Not applicable on Windows which does not support --read-only
-	testRequires(c, NativeExecDriver, DaemonIsLinux)
+	// --read-only + userns has remount issues
+	testRequires(c, NativeExecDriver, DaemonIsLinux, NotUserNamespace)
 
 
 	out, _ := dockerCmd(c, "run", "--read-only", "--add-host", "testreadonly:127.0.0.1", "busybox", "/bin/cat", "/etc/hosts")
 	out, _ := dockerCmd(c, "run", "--read-only", "--add-host", "testreadonly:127.0.0.1", "busybox", "/bin/cat", "/etc/hosts")
 	if !strings.Contains(string(out), "testreadonly") {
 	if !strings.Contains(string(out), "testreadonly") {
@@ -2654,7 +2664,7 @@ func (s *DockerSuite) TestRunContainerWithRmFlagCannotStartContainer(c *check.C)
 
 
 func (s *DockerSuite) TestRunPidHostWithChildIsKillable(c *check.C) {
 func (s *DockerSuite) TestRunPidHostWithChildIsKillable(c *check.C) {
 	// Not applicable on Windows as uses Unix specific functionality
 	// Not applicable on Windows as uses Unix specific functionality
-	testRequires(c, DaemonIsLinux)
+	testRequires(c, DaemonIsLinux, NotUserNamespace)
 	name := "ibuildthecloud"
 	name := "ibuildthecloud"
 	dockerCmd(c, "run", "-d", "--pid=host", "--name", name, "busybox", "sh", "-c", "sleep 30; echo hi")
 	dockerCmd(c, "run", "-d", "--pid=host", "--name", name, "busybox", "sh", "-c", "sleep 30; echo hi")
 
 
@@ -2734,7 +2744,7 @@ func (s *DockerSuite) TestRunReadProcLatency(c *check.C) {
 
 
 func (s *DockerSuite) TestRunReadFilteredProc(c *check.C) {
 func (s *DockerSuite) TestRunReadFilteredProc(c *check.C) {
 	// Not applicable on Windows as uses Unix specific functionality
 	// Not applicable on Windows as uses Unix specific functionality
-	testRequires(c, Apparmor, DaemonIsLinux)
+	testRequires(c, Apparmor, DaemonIsLinux, NotUserNamespace)
 
 
 	testReadPaths := []string{
 	testReadPaths := []string{
 		"/proc/latency_stats",
 		"/proc/latency_stats",
@@ -2767,7 +2777,8 @@ func (s *DockerSuite) TestMountIntoProc(c *check.C) {
 
 
 func (s *DockerSuite) TestMountIntoSys(c *check.C) {
 func (s *DockerSuite) TestMountIntoSys(c *check.C) {
 	// Not applicable on Windows as uses Unix specific functionality
 	// Not applicable on Windows as uses Unix specific functionality
-	testRequires(c, DaemonIsLinux, NativeExecDriver)
+	testRequires(c, DaemonIsLinux)
+	testRequires(c, NativeExecDriver, NotUserNamespace)
 	dockerCmd(c, "run", "-v", "/sys/fs/cgroup", "busybox", "true")
 	dockerCmd(c, "run", "-v", "/sys/fs/cgroup", "busybox", "true")
 }
 }
 
 
@@ -2854,7 +2865,7 @@ func (s *DockerSuite) TestVolumeFromMixedRWOptions(c *check.C) {
 
 
 func (s *DockerSuite) TestRunWriteFilteredProc(c *check.C) {
 func (s *DockerSuite) TestRunWriteFilteredProc(c *check.C) {
 	// Not applicable on Windows as uses Unix specific functionality
 	// Not applicable on Windows as uses Unix specific functionality
-	testRequires(c, Apparmor, NativeExecDriver, DaemonIsLinux)
+	testRequires(c, Apparmor, NativeExecDriver, DaemonIsLinux, NotUserNamespace)
 
 
 	testWritePaths := []string{
 	testWritePaths := []string{
 		/* modprobe and core_pattern should both be denied by generic
 		/* modprobe and core_pattern should both be denied by generic
@@ -2917,7 +2928,8 @@ func (s *DockerSuite) TestRunNetworkFilesBindMountRO(c *check.C) {
 
 
 func (s *DockerSuite) TestRunNetworkFilesBindMountROFilesystem(c *check.C) {
 func (s *DockerSuite) TestRunNetworkFilesBindMountROFilesystem(c *check.C) {
 	// Not applicable on Windows as uses Unix specific functionality
 	// Not applicable on Windows as uses Unix specific functionality
-	testRequires(c, SameHostDaemon, DaemonIsLinux)
+	// --read-only + userns has remount issues
+	testRequires(c, SameHostDaemon, DaemonIsLinux, NotUserNamespace)
 
 
 	filename := createTmpFile(c, "test123")
 	filename := createTmpFile(c, "test123")
 	defer os.Remove(filename)
 	defer os.Remove(filename)
@@ -3260,7 +3272,8 @@ func (s *DockerSuite) TestRunContainerWithCgroupParentAbsPath(c *check.C) {
 
 
 func (s *DockerSuite) TestRunContainerWithCgroupMountRO(c *check.C) {
 func (s *DockerSuite) TestRunContainerWithCgroupMountRO(c *check.C) {
 	// Not applicable on Windows as uses Unix specific functionality
 	// Not applicable on Windows as uses Unix specific functionality
-	testRequires(c, DaemonIsLinux, NativeExecDriver)
+	// --read-only + userns has remount issues
+	testRequires(c, DaemonIsLinux, NativeExecDriver, NotUserNamespace)
 
 
 	filename := "/sys/fs/cgroup/devices/test123"
 	filename := "/sys/fs/cgroup/devices/test123"
 	out, _, err := dockerCmdWithError("run", "busybox", "touch", filename)
 	out, _, err := dockerCmdWithError("run", "busybox", "touch", filename)
@@ -3275,7 +3288,7 @@ func (s *DockerSuite) TestRunContainerWithCgroupMountRO(c *check.C) {
 
 
 func (s *DockerSuite) TestRunContainerNetworkModeToSelf(c *check.C) {
 func (s *DockerSuite) TestRunContainerNetworkModeToSelf(c *check.C) {
 	// Not applicable on Windows which does not support --net=container
 	// Not applicable on Windows which does not support --net=container
-	testRequires(c, DaemonIsLinux)
+	testRequires(c, DaemonIsLinux, NotUserNamespace)
 	out, _, err := dockerCmdWithError("run", "--name=me", "--net=container:me", "busybox", "true")
 	out, _, err := dockerCmdWithError("run", "--name=me", "--net=container:me", "busybox", "true")
 	if err == nil || !strings.Contains(out, "cannot join own network") {
 	if err == nil || !strings.Contains(out, "cannot join own network") {
 		c.Fatalf("using container net mode to self should result in an error\nerr: %q\nout: %s", err, out)
 		c.Fatalf("using container net mode to self should result in an error\nerr: %q\nout: %s", err, out)
@@ -3284,7 +3297,7 @@ func (s *DockerSuite) TestRunContainerNetworkModeToSelf(c *check.C) {
 
 
 func (s *DockerSuite) TestRunContainerNetModeWithDnsMacHosts(c *check.C) {
 func (s *DockerSuite) TestRunContainerNetModeWithDnsMacHosts(c *check.C) {
 	// Not applicable on Windows which does not support --net=container
 	// Not applicable on Windows which does not support --net=container
-	testRequires(c, DaemonIsLinux)
+	testRequires(c, DaemonIsLinux, NotUserNamespace)
 	out, _, err := dockerCmdWithError("run", "-d", "--name", "parent", "busybox", "top")
 	out, _, err := dockerCmdWithError("run", "-d", "--name", "parent", "busybox", "top")
 	if err != nil {
 	if err != nil {
 		c.Fatalf("failed to run container: %v, output: %q", err, out)
 		c.Fatalf("failed to run container: %v, output: %q", err, out)
@@ -3308,7 +3321,7 @@ func (s *DockerSuite) TestRunContainerNetModeWithDnsMacHosts(c *check.C) {
 
 
 func (s *DockerSuite) TestRunContainerNetModeWithExposePort(c *check.C) {
 func (s *DockerSuite) TestRunContainerNetModeWithExposePort(c *check.C) {
 	// Not applicable on Windows which does not support --net=container
 	// Not applicable on Windows which does not support --net=container
-	testRequires(c, DaemonIsLinux)
+	testRequires(c, DaemonIsLinux, NotUserNamespace)
 	dockerCmd(c, "run", "-d", "--name", "parent", "busybox", "top")
 	dockerCmd(c, "run", "-d", "--name", "parent", "busybox", "top")
 
 
 	out, _, err := dockerCmdWithError("run", "-p", "5000:5000", "--net=container:parent", "busybox")
 	out, _, err := dockerCmdWithError("run", "-p", "5000:5000", "--net=container:parent", "busybox")
@@ -3329,7 +3342,7 @@ func (s *DockerSuite) TestRunContainerNetModeWithExposePort(c *check.C) {
 
 
 func (s *DockerSuite) TestRunLinkToContainerNetMode(c *check.C) {
 func (s *DockerSuite) TestRunLinkToContainerNetMode(c *check.C) {
 	// Not applicable on Windows which does not support --net=container or --link
 	// Not applicable on Windows which does not support --net=container or --link
-	testRequires(c, DaemonIsLinux)
+	testRequires(c, DaemonIsLinux, NotUserNamespace)
 	dockerCmd(c, "run", "--name", "test", "-d", "busybox", "top")
 	dockerCmd(c, "run", "--name", "test", "-d", "busybox", "top")
 	dockerCmd(c, "run", "--name", "parent", "-d", "--net=container:test", "busybox", "top")
 	dockerCmd(c, "run", "--name", "parent", "-d", "--net=container:test", "busybox", "top")
 	dockerCmd(c, "run", "-d", "--link=parent:parent", "busybox", "top")
 	dockerCmd(c, "run", "-d", "--link=parent:parent", "busybox", "top")
@@ -3373,7 +3386,7 @@ func (s *DockerSuite) TestRunLoopbackWhenNetworkDisabled(c *check.C) {
 
 
 func (s *DockerSuite) TestRunModeNetContainerHostname(c *check.C) {
 func (s *DockerSuite) TestRunModeNetContainerHostname(c *check.C) {
 	// Windows does not support --net=container
 	// Windows does not support --net=container
-	testRequires(c, DaemonIsLinux, ExecSupport)
+	testRequires(c, DaemonIsLinux, ExecSupport, NotUserNamespace)
 
 
 	dockerCmd(c, "run", "-i", "-d", "--name", "parent", "busybox", "top")
 	dockerCmd(c, "run", "-i", "-d", "--name", "parent", "busybox", "top")
 	out, _ := dockerCmd(c, "exec", "parent", "cat", "/etc/hostname")
 	out, _ := dockerCmd(c, "exec", "parent", "cat", "/etc/hostname")
@@ -3399,7 +3412,7 @@ func (s *DockerSuite) TestRunNetworkNotInitializedNoneMode(c *check.C) {
 
 
 func (s *DockerSuite) TestTwoContainersInNetHost(c *check.C) {
 func (s *DockerSuite) TestTwoContainersInNetHost(c *check.C) {
 	// Not applicable as Windows does not support --net=host
 	// Not applicable as Windows does not support --net=host
-	testRequires(c, DaemonIsLinux)
+	testRequires(c, DaemonIsLinux, NotUserNamespace, NotUserNamespace)
 	dockerCmd(c, "run", "-d", "--net=host", "--name=first", "busybox", "top")
 	dockerCmd(c, "run", "-d", "--net=host", "--name=first", "busybox", "top")
 	dockerCmd(c, "run", "-d", "--net=host", "--name=second", "busybox", "top")
 	dockerCmd(c, "run", "-d", "--net=host", "--name=second", "busybox", "top")
 	dockerCmd(c, "stop", "first")
 	dockerCmd(c, "stop", "first")
@@ -3407,7 +3420,7 @@ func (s *DockerSuite) TestTwoContainersInNetHost(c *check.C) {
 }
 }
 
 
 func (s *DockerSuite) TestContainersInUserDefinedNetwork(c *check.C) {
 func (s *DockerSuite) TestContainersInUserDefinedNetwork(c *check.C) {
-	testRequires(c, DaemonIsLinux)
+	testRequires(c, DaemonIsLinux, NotUserNamespace)
 	dockerCmd(c, "network", "create", "-d", "bridge", "testnetwork")
 	dockerCmd(c, "network", "create", "-d", "bridge", "testnetwork")
 	dockerCmd(c, "run", "-d", "--net=testnetwork", "--name=first", "busybox", "top")
 	dockerCmd(c, "run", "-d", "--net=testnetwork", "--name=first", "busybox", "top")
 	c.Assert(waitRun("first"), check.IsNil)
 	c.Assert(waitRun("first"), check.IsNil)
@@ -3418,7 +3431,7 @@ func (s *DockerSuite) TestContainersInUserDefinedNetwork(c *check.C) {
 }
 }
 
 
 func (s *DockerSuite) TestContainersInMultipleNetworks(c *check.C) {
 func (s *DockerSuite) TestContainersInMultipleNetworks(c *check.C) {
-	testRequires(c, DaemonIsLinux)
+	testRequires(c, DaemonIsLinux, NotUserNamespace)
 	// Create 2 networks using bridge driver
 	// Create 2 networks using bridge driver
 	dockerCmd(c, "network", "create", "-d", "bridge", "testnetwork1")
 	dockerCmd(c, "network", "create", "-d", "bridge", "testnetwork1")
 	dockerCmd(c, "network", "create", "-d", "bridge", "testnetwork2")
 	dockerCmd(c, "network", "create", "-d", "bridge", "testnetwork2")
@@ -3441,7 +3454,7 @@ func (s *DockerSuite) TestContainersInMultipleNetworks(c *check.C) {
 }
 }
 
 
 func (s *DockerSuite) TestContainersNetworkIsolation(c *check.C) {
 func (s *DockerSuite) TestContainersNetworkIsolation(c *check.C) {
-	testRequires(c, DaemonIsLinux)
+	testRequires(c, DaemonIsLinux, NotUserNamespace)
 	// Create 2 networks using bridge driver
 	// Create 2 networks using bridge driver
 	dockerCmd(c, "network", "create", "-d", "bridge", "testnetwork1")
 	dockerCmd(c, "network", "create", "-d", "bridge", "testnetwork1")
 	dockerCmd(c, "network", "create", "-d", "bridge", "testnetwork2")
 	dockerCmd(c, "network", "create", "-d", "bridge", "testnetwork2")
@@ -3473,7 +3486,7 @@ func (s *DockerSuite) TestContainersNetworkIsolation(c *check.C) {
 }
 }
 
 
 func (s *DockerSuite) TestNetworkRmWithActiveContainers(c *check.C) {
 func (s *DockerSuite) TestNetworkRmWithActiveContainers(c *check.C) {
-	testRequires(c, DaemonIsLinux)
+	testRequires(c, DaemonIsLinux, NotUserNamespace)
 	// Create 2 networks using bridge driver
 	// Create 2 networks using bridge driver
 	dockerCmd(c, "network", "create", "-d", "bridge", "testnetwork1")
 	dockerCmd(c, "network", "create", "-d", "bridge", "testnetwork1")
 	// Run and connect containers to testnetwork1
 	// Run and connect containers to testnetwork1
@@ -3495,7 +3508,7 @@ func (s *DockerSuite) TestNetworkRmWithActiveContainers(c *check.C) {
 }
 }
 
 
 func (s *DockerSuite) TestContainerRestartInMultipleNetworks(c *check.C) {
 func (s *DockerSuite) TestContainerRestartInMultipleNetworks(c *check.C) {
-	testRequires(c, DaemonIsLinux)
+	testRequires(c, DaemonIsLinux, NotUserNamespace)
 	// Create 2 networks using bridge driver
 	// Create 2 networks using bridge driver
 	dockerCmd(c, "network", "create", "-d", "bridge", "testnetwork1")
 	dockerCmd(c, "network", "create", "-d", "bridge", "testnetwork1")
 	dockerCmd(c, "network", "create", "-d", "bridge", "testnetwork2")
 	dockerCmd(c, "network", "create", "-d", "bridge", "testnetwork2")
@@ -3531,7 +3544,7 @@ func (s *DockerSuite) TestContainerRestartInMultipleNetworks(c *check.C) {
 }
 }
 
 
 func (s *DockerSuite) TestContainerWithConflictingHostNetworks(c *check.C) {
 func (s *DockerSuite) TestContainerWithConflictingHostNetworks(c *check.C) {
-	testRequires(c, DaemonIsLinux)
+	testRequires(c, DaemonIsLinux, NotUserNamespace)
 	// Run a container with --net=host
 	// Run a container with --net=host
 	dockerCmd(c, "run", "-d", "--net=host", "--name=first", "busybox", "top")
 	dockerCmd(c, "run", "-d", "--net=host", "--name=first", "busybox", "top")
 	c.Assert(waitRun("first"), check.IsNil)
 	c.Assert(waitRun("first"), check.IsNil)
@@ -3547,7 +3560,7 @@ func (s *DockerSuite) TestContainerWithConflictingHostNetworks(c *check.C) {
 }
 }
 
 
 func (s *DockerSuite) TestContainerWithConflictingSharedNetwork(c *check.C) {
 func (s *DockerSuite) TestContainerWithConflictingSharedNetwork(c *check.C) {
-	testRequires(c, DaemonIsLinux)
+	testRequires(c, DaemonIsLinux, NotUserNamespace)
 	dockerCmd(c, "run", "-d", "--name=first", "busybox", "top")
 	dockerCmd(c, "run", "-d", "--name=first", "busybox", "top")
 	c.Assert(waitRun("first"), check.IsNil)
 	c.Assert(waitRun("first"), check.IsNil)
 	// Run second container in first container's network namespace
 	// Run second container in first container's network namespace
@@ -3568,7 +3581,7 @@ func (s *DockerSuite) TestContainerWithConflictingSharedNetwork(c *check.C) {
 }
 }
 
 
 func (s *DockerSuite) TestContainerWithConflictingNoneNetwork(c *check.C) {
 func (s *DockerSuite) TestContainerWithConflictingNoneNetwork(c *check.C) {
-	testRequires(c, DaemonIsLinux)
+	testRequires(c, DaemonIsLinux, NotUserNamespace)
 	dockerCmd(c, "run", "-d", "--net=none", "--name=first", "busybox", "top")
 	dockerCmd(c, "run", "-d", "--net=none", "--name=first", "busybox", "top")
 	c.Assert(waitRun("first"), check.IsNil)
 	c.Assert(waitRun("first"), check.IsNil)
 
 

+ 3 - 1
integration-cli/docker_cli_run_unix_test.go

@@ -57,6 +57,8 @@ func (s *DockerSuite) TestRunRedirectStdout(c *check.C) {
 
 
 // Test recursive bind mount works by default
 // Test recursive bind mount works by default
 func (s *DockerSuite) TestRunWithVolumesIsRecursive(c *check.C) {
 func (s *DockerSuite) TestRunWithVolumesIsRecursive(c *check.C) {
+	// /tmp gets permission denied
+	testRequires(c, NotUserNamespace)
 	tmpDir, err := ioutil.TempDir("", "docker_recursive_mount_test")
 	tmpDir, err := ioutil.TempDir("", "docker_recursive_mount_test")
 	if err != nil {
 	if err != nil {
 		c.Fatal(err)
 		c.Fatal(err)
@@ -90,7 +92,7 @@ func (s *DockerSuite) TestRunWithVolumesIsRecursive(c *check.C) {
 }
 }
 
 
 func (s *DockerSuite) TestRunDeviceDirectory(c *check.C) {
 func (s *DockerSuite) TestRunDeviceDirectory(c *check.C) {
-	testRequires(c, NativeExecDriver)
+	testRequires(c, NativeExecDriver, NotUserNamespace)
 	if _, err := os.Stat("/dev/snd"); err != nil {
 	if _, err := os.Stat("/dev/snd"); err != nil {
 		c.Skip("Host does not have /dev/snd")
 		c.Skip("Host does not have /dev/snd")
 	}
 	}

+ 1 - 1
integration-cli/docker_cli_top_test.go

@@ -39,7 +39,7 @@ func (s *DockerSuite) TestTopNonPrivileged(c *check.C) {
 }
 }
 
 
 func (s *DockerSuite) TestTopPrivileged(c *check.C) {
 func (s *DockerSuite) TestTopPrivileged(c *check.C) {
-	testRequires(c, DaemonIsLinux)
+	testRequires(c, DaemonIsLinux, NotUserNamespace)
 	out, _ := dockerCmd(c, "run", "--privileged", "-i", "-d", "busybox", "top")
 	out, _ := dockerCmd(c, "run", "--privileged", "-i", "-d", "busybox", "top")
 	cleanedContainerID := strings.TrimSpace(out)
 	cleanedContainerID := strings.TrimSpace(out)
 
 

+ 4 - 0
integration-cli/docker_utils.go

@@ -107,6 +107,10 @@ func (d *Daemon) Start(arg ...string) error {
 		fmt.Sprintf("--userland-proxy=%t", d.userlandProxy),
 		fmt.Sprintf("--userland-proxy=%t", d.userlandProxy),
 	)
 	)
 
 
+	if root := os.Getenv("DOCKER_REMAP_ROOT"); root != "" {
+		args = append(args, []string{"--root", root}...)
+	}
+
 	// If we don't explicitly set the log-level or debug flag(-D) then
 	// If we don't explicitly set the log-level or debug flag(-D) then
 	// turn on debug mode
 	// turn on debug mode
 	foundIt := false
 	foundIt := false

+ 11 - 0
integration-cli/requirements.go

@@ -6,6 +6,7 @@ import (
 	"io/ioutil"
 	"io/ioutil"
 	"log"
 	"log"
 	"net/http"
 	"net/http"
+	"os"
 	"os/exec"
 	"os/exec"
 	"strings"
 	"strings"
 	"time"
 	"time"
@@ -147,6 +148,16 @@ var (
 		},
 		},
 		"Test requires native Golang compiler instead of GCCGO",
 		"Test requires native Golang compiler instead of GCCGO",
 	}
 	}
+	NotUserNamespace = testRequirement{
+		func() bool {
+			root := os.Getenv("DOCKER_REMAP_ROOT")
+			if root != "" {
+				return true
+			}
+			return false
+		},
+		"Test cannot be run when remapping root",
+	}
 )
 )
 
 
 // testRequires checks if the environment satisfies the requirements
 // testRequires checks if the environment satisfies the requirements