github.com/rish1988/moby@v25.0.2+incompatible/integration/build/build_userns_linux_test.go (about) 1 package build // import "github.com/docker/docker/integration/build" 2 3 import ( 4 "bufio" 5 "bytes" 6 "io" 7 "os" 8 "strings" 9 "testing" 10 11 "github.com/docker/docker/api/types" 12 containertypes "github.com/docker/docker/api/types/container" 13 "github.com/docker/docker/integration/internal/container" 14 "github.com/docker/docker/pkg/jsonmessage" 15 "github.com/docker/docker/pkg/stdcopy" 16 "github.com/docker/docker/testutil" 17 "github.com/docker/docker/testutil/daemon" 18 "github.com/docker/docker/testutil/fakecontext" 19 "github.com/docker/docker/testutil/fixtures/load" 20 "gotest.tools/v3/assert" 21 "gotest.tools/v3/skip" 22 ) 23 24 // Implements a test for https://github.com/moby/moby/issues/41723 25 // Images built in a user-namespaced daemon should have capabilities serialised in 26 // VFS_CAP_REVISION_2 (no user-namespace root uid) format rather than V3 (that includes 27 // the root uid). 28 func TestBuildUserNamespaceValidateCapabilitiesAreV2(t *testing.T) { 29 skip.If(t, testEnv.DaemonInfo.OSType != "linux") 30 skip.If(t, testEnv.IsRemoteDaemon()) 31 skip.If(t, !testEnv.IsUserNamespaceInKernel()) 32 skip.If(t, testEnv.IsRootless()) 33 34 ctx := testutil.StartSpan(baseContext, t) 35 36 const imageTag = "capabilities:1.0" 37 38 tmp, err := os.MkdirTemp("", "integration-") 39 assert.NilError(t, err) 40 defer os.RemoveAll(tmp) 41 42 dUserRemap := daemon.New(t) 43 dUserRemap.Start(t, "--userns-remap", "default") 44 clientUserRemap := dUserRemap.NewClientT(t) 45 defer clientUserRemap.Close() 46 47 err = load.FrozenImagesLinux(ctx, clientUserRemap, "debian:bookworm-slim") 48 assert.NilError(t, err) 49 50 dUserRemapRunning := true 51 defer func() { 52 if dUserRemapRunning { 53 dUserRemap.Stop(t) 54 dUserRemap.Cleanup(t) 55 } 56 }() 57 58 dockerfile := ` 59 FROM debian:bookworm-slim 60 RUN apt-get update && apt-get install -y libcap2-bin --no-install-recommends 61 RUN setcap CAP_NET_BIND_SERVICE=+eip /bin/sleep 62 ` 63 64 source := fakecontext.New(t, "", fakecontext.WithDockerfile(dockerfile)) 65 defer source.Close() 66 67 resp, err := clientUserRemap.ImageBuild(ctx, 68 source.AsTarReader(t), 69 types.ImageBuildOptions{ 70 Tags: []string{imageTag}, 71 }) 72 assert.NilError(t, err) 73 defer resp.Body.Close() 74 75 buf := bytes.NewBuffer(nil) 76 err = jsonmessage.DisplayJSONMessagesStream(resp.Body, buf, 0, false, nil) 77 assert.NilError(t, err) 78 79 reader, err := clientUserRemap.ImageSave(ctx, []string{imageTag}) 80 assert.NilError(t, err, "failed to download capabilities image") 81 defer reader.Close() 82 83 tar, err := os.Create(tmp + "/image.tar") 84 assert.NilError(t, err, "failed to create image tar file") 85 defer tar.Close() 86 87 _, err = io.Copy(tar, reader) 88 assert.NilError(t, err, "failed to write image tar file") 89 90 dUserRemap.Stop(t) 91 dUserRemap.Cleanup(t) 92 dUserRemapRunning = false 93 94 dNoUserRemap := daemon.New(t) 95 dNoUserRemap.Start(t) 96 defer func() { 97 dNoUserRemap.Stop(t) 98 dNoUserRemap.Cleanup(t) 99 }() 100 101 clientNoUserRemap := dNoUserRemap.NewClientT(t) 102 defer clientNoUserRemap.Close() 103 104 tarFile, err := os.Open(tmp + "/image.tar") 105 assert.NilError(t, err, "failed to open image tar file") 106 defer tarFile.Close() 107 108 tarReader := bufio.NewReader(tarFile) 109 loadResp, err := clientNoUserRemap.ImageLoad(ctx, tarReader, false) 110 assert.NilError(t, err, "failed to load image tar file") 111 defer loadResp.Body.Close() 112 buf = bytes.NewBuffer(nil) 113 err = jsonmessage.DisplayJSONMessagesStream(loadResp.Body, buf, 0, false, nil) 114 assert.NilError(t, err) 115 116 cid := container.Run(ctx, t, clientNoUserRemap, 117 container.WithImage(imageTag), 118 container.WithCmd("/sbin/getcap", "-n", "/bin/sleep"), 119 ) 120 logReader, err := clientNoUserRemap.ContainerLogs(ctx, cid, containertypes.LogsOptions{ 121 ShowStdout: true, 122 }) 123 assert.NilError(t, err) 124 defer logReader.Close() 125 126 actualStdout := new(bytes.Buffer) 127 actualStderr := io.Discard 128 _, err = stdcopy.StdCopy(actualStdout, actualStderr, logReader) 129 assert.NilError(t, err) 130 if strings.TrimSpace(actualStdout.String()) != "/bin/sleep cap_net_bind_service=eip" { 131 t.Fatalf("run produced invalid output: %q, expected %q", actualStdout.String(), "/bin/sleep cap_net_bind_service=eip") 132 } 133 }