فهرست منبع

test: Add a test for userns remapped daemon commit

The files in an image created by a commit should have the right uid and gid set

Signed-off-by: Djordje Lukic <djordje.lukic@docker.com>
Djordje Lukic 1 سال پیش
والد
کامیت
a7acfffea6
3فایلهای تغییر یافته به همراه36 افزوده شده و 0 حذف شده
  1. 25 0
      integration/image/commit_test.go
  2. 5 0
      testutil/daemon/daemon.go
  3. 6 0
      testutil/daemon/ops.go

+ 25 - 0
integration/image/commit_test.go

@@ -1,12 +1,14 @@
 package image // import "github.com/docker/docker/integration/image"
 package image // import "github.com/docker/docker/integration/image"
 
 
 import (
 import (
+	"context"
 	"strings"
 	"strings"
 	"testing"
 	"testing"
 
 
 	containertypes "github.com/docker/docker/api/types/container"
 	containertypes "github.com/docker/docker/api/types/container"
 	"github.com/docker/docker/api/types/versions"
 	"github.com/docker/docker/api/types/versions"
 	"github.com/docker/docker/integration/internal/container"
 	"github.com/docker/docker/integration/internal/container"
+	"github.com/docker/docker/testutil/daemon"
 	"gotest.tools/v3/assert"
 	"gotest.tools/v3/assert"
 	is "gotest.tools/v3/assert/cmp"
 	is "gotest.tools/v3/assert/cmp"
 	"gotest.tools/v3/skip"
 	"gotest.tools/v3/skip"
@@ -47,3 +49,26 @@ func TestCommitInheritsEnv(t *testing.T) {
 	expectedEnv2 := []string{"PATH=/usr/bin:/bin"}
 	expectedEnv2 := []string{"PATH=/usr/bin:/bin"}
 	assert.Check(t, is.DeepEqual(expectedEnv2, image2.Config.Env))
 	assert.Check(t, is.DeepEqual(expectedEnv2, image2.Config.Env))
 }
 }
+
+// Verify that files created are owned by the remapped user even after a commit
+func TestUsernsCommit(t *testing.T) {
+	skip.If(t, testEnv.DaemonInfo.OSType != "linux")
+	skip.If(t, testEnv.IsRemoteDaemon())
+	skip.If(t, !testEnv.IsUserNamespaceInKernel())
+	skip.If(t, testEnv.IsRootless())
+
+	ctx := context.Background()
+	dUserRemap := daemon.New(t, daemon.WithUserNsRemap("default"))
+	dUserRemap.StartWithBusybox(ctx, t)
+	clientUserRemap := dUserRemap.NewClientT(t)
+	defer clientUserRemap.Close()
+
+	container.Run(ctx, t, clientUserRemap, container.WithName(t.Name()), container.WithImage("busybox"), container.WithCmd("sh", "-c", "echo hello world > /hello.txt && chown 1000:1000 /hello.txt"))
+	img, err := clientUserRemap.ContainerCommit(ctx, t.Name(), containertypes.CommitOptions{})
+	assert.NilError(t, err)
+
+	res := container.RunAttach(ctx, t, clientUserRemap, container.WithImage(img.ID), container.WithCmd("sh", "-c", "stat -c %u:%g /hello.txt"))
+	assert.Check(t, is.Equal(res.ExitCode, 0))
+	assert.Check(t, is.Equal(res.Stderr.String(), ""))
+	assert.Assert(t, is.Equal(strings.TrimSpace(res.Stdout.String()), "1000:1000"))
+}

+ 5 - 0
testutil/daemon/daemon.go

@@ -83,6 +83,7 @@ type Daemon struct {
 	args                       []string
 	args                       []string
 	extraEnv                   []string
 	extraEnv                   []string
 	containerdSocket           string
 	containerdSocket           string
+	usernsRemap                string
 	rootlessUser               *user.User
 	rootlessUser               *user.User
 	rootlessXDGRuntimeDir      string
 	rootlessXDGRuntimeDir      string
 
 
@@ -457,6 +458,10 @@ func (d *Daemon) StartWithLogFile(out *os.File, providedArgs ...string) error {
 		d.args = append(d.args, "--containerd", d.containerdSocket)
 		d.args = append(d.args, "--containerd", d.containerdSocket)
 	}
 	}
 
 
+	if d.usernsRemap != "" {
+		d.args = append(d.args, "--userns-remap", d.usernsRemap)
+	}
+
 	if d.defaultCgroupNamespaceMode != "" {
 	if d.defaultCgroupNamespaceMode != "" {
 		d.args = append(d.args, "--default-cgroupns-mode", d.defaultCgroupNamespaceMode)
 		d.args = append(d.args, "--default-cgroupns-mode", d.defaultCgroupNamespaceMode)
 	}
 	}

+ 6 - 0
testutil/daemon/ops.go

@@ -19,6 +19,12 @@ func WithContainerdSocket(socket string) Option {
 	}
 	}
 }
 }
 
 
+func WithUserNsRemap(remap string) Option {
+	return func(d *Daemon) {
+		d.usernsRemap = remap
+	}
+}
+
 // WithDefaultCgroupNamespaceMode sets the default cgroup namespace mode for the daemon
 // WithDefaultCgroupNamespaceMode sets the default cgroup namespace mode for the daemon
 func WithDefaultCgroupNamespaceMode(mode string) Option {
 func WithDefaultCgroupNamespaceMode(mode string) Option {
 	return func(d *Daemon) {
 	return func(d *Daemon) {