mirror of
https://github.com/moby/moby.git
synced 2026-08-09 01:21:37 +00:00
Merge pull request #53080 from vvoland/ci-userns
gha/test: Add userns integration mode
This commit is contained in:
3
.github/workflows/.test.yml
vendored
3
.github/workflows/.test.yml
vendored
@@ -216,6 +216,9 @@ jobs:
|
||||
if [[ "$MODE" == *"rootless"* ]]; then
|
||||
echo "DOCKER_ROOTLESS=1" >> $GITHUB_ENV
|
||||
fi
|
||||
if [[ "$MODE" == *"userns"* ]]; then
|
||||
echo "DOCKER_REMAP_ROOT=default" >> $GITHUB_ENV
|
||||
fi
|
||||
if [[ "$MODE" == *"systemd"* ]]; then
|
||||
echo "SYSTEMD=true" >> $GITHUB_ENV
|
||||
CACHE_DEV_SCOPE="dev-systemd-${ARCH}"
|
||||
|
||||
2
.github/workflows/test.yml
vendored
2
.github/workflows/test.yml
vendored
@@ -96,7 +96,7 @@ jobs:
|
||||
- arch: amd64
|
||||
storage: graphdriver
|
||||
runnerSuffix: ""
|
||||
extraModes: '["rootless", "systemd"]'
|
||||
extraModes: '["rootless", "systemd", "userns"]'
|
||||
- arch: arm64
|
||||
storage: snapshotter
|
||||
runnerSuffix: "-arm"
|
||||
|
||||
@@ -279,6 +279,7 @@ func TestCreateWithCustomMaskedPaths(t *testing.T) {
|
||||
|
||||
for i, tc := range testCases {
|
||||
t.Run(tc.doc, func(t *testing.T) {
|
||||
skip.If(t, tc.privileged && testEnv.IsUserNamespace(), "privileged mode is incompatible with user namespaces")
|
||||
t.Parallel()
|
||||
|
||||
// Create the container.
|
||||
@@ -352,6 +353,7 @@ func TestCreateWithCustomReadonlyPaths(t *testing.T) {
|
||||
|
||||
for i, tc := range testCases {
|
||||
t.Run(tc.doc, func(t *testing.T) {
|
||||
skip.If(t, tc.privileged && testEnv.IsUserNamespace(), "privileged mode is incompatible with user namespaces")
|
||||
t.Parallel()
|
||||
ctr, err := apiClient.ContainerCreate(ctx, client.ContainerCreateOptions{
|
||||
Config: &container.Config{
|
||||
|
||||
@@ -52,6 +52,7 @@ func TestNetworkAliasesAreEmpty(t *testing.T) {
|
||||
|
||||
for _, nwMode := range netModes {
|
||||
t.Run(nwMode, func(t *testing.T) {
|
||||
skip.If(t, nwMode == "host" && testEnv.IsUserNamespace(), "host network mode is incompatible with user namespaces")
|
||||
ctr := container.Create(ctx, t, apiClient,
|
||||
container.WithName("ctr-"+nwMode),
|
||||
container.WithImage("busybox:latest"),
|
||||
|
||||
@@ -13,6 +13,7 @@ import (
|
||||
|
||||
func TestLinksEtcHostsContentMatch(t *testing.T) {
|
||||
skip.If(t, testEnv.IsRemoteDaemon)
|
||||
skip.If(t, testEnv.IsUserNamespace, "host network mode is incompatible with user namespaces")
|
||||
|
||||
hosts, err := os.ReadFile("/etc/hosts")
|
||||
skip.If(t, os.IsNotExist(err))
|
||||
|
||||
@@ -350,6 +350,7 @@ func TestMountDaemonRoot(t *testing.T) {
|
||||
func TestContainerBindMountNonRecursive(t *testing.T) {
|
||||
skip.If(t, testEnv.IsRemoteDaemon)
|
||||
skip.If(t, testEnv.IsRootless, "cannot be tested because RootlessKit executes the daemon in private mount namespace (https://github.com/rootless-containers/rootlesskit/issues/97)")
|
||||
skip.If(t, testEnv.IsUserNamespace, "non-recursive bind mounts of directories containing submounts fail with EINVAL in a user namespace")
|
||||
|
||||
ctx := setupTest(t)
|
||||
|
||||
|
||||
@@ -15,6 +15,7 @@ import (
|
||||
func TestPIDModeHost(t *testing.T) {
|
||||
skip.If(t, testEnv.DaemonInfo.OSType != "linux")
|
||||
skip.If(t, testEnv.IsRemoteDaemon())
|
||||
skip.If(t, testEnv.IsUserNamespace, "host PID mode is incompatible with user namespaces")
|
||||
|
||||
hostPid, err := os.Readlink("/proc/1/ns/pid")
|
||||
assert.NilError(t, err)
|
||||
|
||||
@@ -60,6 +60,7 @@ func TestCgroupNamespacesRunPrivileged(t *testing.T) {
|
||||
skip.If(t, testEnv.IsRemoteDaemon())
|
||||
skip.If(t, !requirement.CgroupNamespacesEnabled())
|
||||
skip.If(t, testEnv.DaemonInfo.CgroupVersion == "2", "on cgroup v2, privileged containers use private cgroupns")
|
||||
skip.If(t, testEnv.IsUserNamespace, "privileged mode is incompatible with user namespaces")
|
||||
|
||||
t.Parallel()
|
||||
|
||||
@@ -120,6 +121,7 @@ func TestCgroupNamespacesRunPrivilegedAndPrivate(t *testing.T) {
|
||||
skip.If(t, testEnv.DaemonInfo.OSType != "linux")
|
||||
skip.If(t, testEnv.IsRemoteDaemon())
|
||||
skip.If(t, !requirement.CgroupNamespacesEnabled())
|
||||
skip.If(t, testEnv.IsUserNamespace, "privileged mode is incompatible with user namespaces")
|
||||
|
||||
t.Parallel()
|
||||
|
||||
|
||||
@@ -33,6 +33,7 @@ import (
|
||||
|
||||
func TestNISDomainname(t *testing.T) {
|
||||
skip.If(t, testEnv.DaemonInfo.OSType != "linux")
|
||||
skip.If(t, testEnv.IsUserNamespace, "user namespaces cannot write the kernel domainname sysctl")
|
||||
|
||||
// Rootless supports custom Hostname but doesn't support custom Domainname
|
||||
// OCI runtime create failed: container_linux.go:349: starting container process caused "process_linux.go:449: container init caused \
|
||||
@@ -114,15 +115,17 @@ func TestUnprivilegedPortsAndPing(t *testing.T) {
|
||||
c.Config.User = "1000:1000"
|
||||
})
|
||||
|
||||
// Check net.ipv4.ping_group_range.
|
||||
res, err := container.Exec(ctx, apiClient, cID, []string{"cat", "/proc/sys/net/ipv4/ping_group_range"})
|
||||
assert.NilError(t, err)
|
||||
assert.Assert(t, is.Len(res.Stderr(), 0))
|
||||
assert.Equal(t, 0, res.ExitCode)
|
||||
assert.Equal(t, `0 2147483647`, strings.TrimSpace(res.Stdout()))
|
||||
if !testEnv.IsUserNamespace() {
|
||||
// Check net.ipv4.ping_group_range.
|
||||
res, err := container.Exec(ctx, apiClient, cID, []string{"cat", "/proc/sys/net/ipv4/ping_group_range"})
|
||||
assert.NilError(t, err)
|
||||
assert.Assert(t, is.Len(res.Stderr(), 0))
|
||||
assert.Equal(t, 0, res.ExitCode)
|
||||
assert.Equal(t, `0 2147483647`, strings.TrimSpace(res.Stdout()))
|
||||
}
|
||||
|
||||
// Check net.ipv4.ip_unprivileged_port_start.
|
||||
res, err = container.Exec(ctx, apiClient, cID, []string{"cat", "/proc/sys/net/ipv4/ip_unprivileged_port_start"})
|
||||
res, err := container.Exec(ctx, apiClient, cID, []string{"cat", "/proc/sys/net/ipv4/ip_unprivileged_port_start"})
|
||||
assert.NilError(t, err)
|
||||
assert.Assert(t, is.Len(res.Stderr(), 0))
|
||||
assert.Equal(t, 0, res.ExitCode)
|
||||
@@ -134,6 +137,7 @@ func TestPrivilegedHostDevices(t *testing.T) {
|
||||
// so needs to be same host.
|
||||
skip.If(t, testEnv.IsRemoteDaemon)
|
||||
skip.If(t, testEnv.DaemonInfo.OSType != "linux")
|
||||
skip.If(t, testEnv.IsUserNamespace, "privileged mode is incompatible with user namespaces")
|
||||
|
||||
ctx := setupTest(t)
|
||||
apiClient := testEnv.APIClient()
|
||||
@@ -373,6 +377,7 @@ func TestWorkingDirNormalization(t *testing.T) {
|
||||
|
||||
func TestSeccomp(t *testing.T) {
|
||||
skip.If(t, testEnv.DaemonInfo.OSType != "linux")
|
||||
skip.If(t, testEnv.IsUserNamespace, "privileged test cases are incompatible with user namespaces")
|
||||
|
||||
ctx := setupTest(t)
|
||||
apiClient := testEnv.APIClient()
|
||||
|
||||
@@ -186,8 +186,12 @@ func TestUpdatePidsLimit(t *testing.T) {
|
||||
|
||||
t.Run(test.desc, func(t *testing.T) {
|
||||
ctx := testutil.StartSpan(ctx, t)
|
||||
opts := []func(*container.TestContainerConfig){container.WithPidsLimit(test.initial)}
|
||||
// Using "network=host" to speed up creation (13.96s vs 6.54s)
|
||||
cID := container.Run(ctx, t, apiClient, container.WithPidsLimit(test.initial), container.WithNetworkMode("host"))
|
||||
if !testEnv.IsUserNamespace() {
|
||||
opts = append(opts, container.WithNetworkMode("host"))
|
||||
}
|
||||
cID := container.Run(ctx, t, apiClient, opts...)
|
||||
|
||||
_, err := c.ContainerUpdate(ctx, cID, client.ContainerUpdateOptions{
|
||||
Resources: &containertypes.Resources{
|
||||
|
||||
@@ -15,6 +15,7 @@ import (
|
||||
|
||||
func TestDefaultStorageDriver(t *testing.T) {
|
||||
skip.If(t, testEnv.DaemonInfo.OSType == "windows", "Windows does not support running sub-daemons")
|
||||
skip.If(t, testEnv.IsUserNamespace(), "containerd snapshotters are disabled with user namespace remapping")
|
||||
t.Setenv("DOCKER_DRIVER", "")
|
||||
t.Setenv("DOCKER_GRAPHDRIVER", "")
|
||||
t.Setenv("TEST_INTEGRATION_USE_GRAPHDRIVER", "")
|
||||
@@ -127,6 +128,8 @@ func TestInspectGraphDriverAPIBC(t *testing.T) {
|
||||
|
||||
for _, tc := range tests {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
skip.If(t, tc.expContainerdSnapshotter && testEnv.IsUserNamespace(), "containerd snapshotters are disabled with user namespace remapping")
|
||||
|
||||
d := daemon.New(t)
|
||||
defer d.Stop(t)
|
||||
d.StartWithBusybox(ctx, t, "--iptables=false", "--ip6tables=false", "--storage-driver="+tc.storageDriver)
|
||||
|
||||
@@ -25,6 +25,7 @@ func TestMigrateNativeSnapshotter(t *testing.T) {
|
||||
|
||||
func testMigrateSnapshotter(t *testing.T, graphdriver, snapshotter string) {
|
||||
skip.If(t, runtime.GOOS != "linux")
|
||||
skip.If(t, testEnv.IsUserNamespace(), "containerd snapshotters are disabled with user namespace remapping")
|
||||
|
||||
t.Setenv("DOCKER_MIGRATE_SNAPSHOTTER_THRESHOLD", "200M")
|
||||
t.Setenv("DOCKER_DRIVER", "")
|
||||
|
||||
@@ -158,7 +158,12 @@ func TestNRIContainerCreateAddMount(t *testing.T) {
|
||||
|
||||
// Create and populate a directory for containers to mount.
|
||||
dirToMount := t.TempDir()
|
||||
if err := os.WriteFile(filepath.Join(dirToMount, "testfile.txt"), []byte("hello\n"), 0o644); err != nil {
|
||||
testFile := filepath.Join(dirToMount, "testfile.txt")
|
||||
if err := os.WriteFile(testFile, []byte("hello\n"), 0o666); err != nil {
|
||||
assert.NilError(t, err)
|
||||
}
|
||||
// The process umask may remove write bits needed by remapped container root.
|
||||
if err := os.Chmod(testFile, 0o666); err != nil {
|
||||
assert.NilError(t, err)
|
||||
}
|
||||
const (
|
||||
|
||||
@@ -1231,6 +1231,8 @@ func TestBridgeIPAMStatus(t *testing.T) {
|
||||
// rolled back properly - the failed connection should not show up in container
|
||||
// or network inspect, and the container should not gain a network interface.
|
||||
func TestJoinError(t *testing.T) {
|
||||
skip.If(t, testEnv.IsUserNamespace, "privileged mode is incompatible with user namespaces")
|
||||
|
||||
ctx := setupTest(t)
|
||||
d := daemon.New(t)
|
||||
d.StartWithBusybox(ctx, t)
|
||||
|
||||
@@ -226,6 +226,7 @@ func TestDaemonWithBipAndDefaultNetworkPool(t *testing.T) {
|
||||
func TestServiceWithPredefinedNetwork(t *testing.T) {
|
||||
skip.If(t, testEnv.DaemonInfo.OSType == "windows")
|
||||
skip.If(t, testEnv.IsRootless, "rootless mode doesn't support Swarm-mode")
|
||||
skip.If(t, testEnv.IsUserNamespace, "host network mode is incompatible with user namespaces")
|
||||
ctx := setupTest(t)
|
||||
|
||||
d := swarm.NewSwarm(ctx, t, testEnv)
|
||||
|
||||
@@ -325,7 +325,7 @@ func setupTestImage(t *testing.T, ctx context.Context, apiClient client.APIClien
|
||||
FROM busybox as symlink
|
||||
RUN mkdir /hack \
|
||||
&& ln -s "../subdir" /hack/good \
|
||||
&& ln -s "../../../../../docker" /hack/bad
|
||||
&& ln -s ../../../../../ /hack/bad
|
||||
#--
|
||||
FROM scratch
|
||||
COPY foo /
|
||||
|
||||
Reference in New Issue
Block a user