github.com/rish1988/moby@v25.0.2+incompatible/integration/build/build_cgroupns_linux_test.go (about) 1 package build // import "github.com/docker/docker/integration/build" 2 3 import ( 4 "context" 5 "encoding/json" 6 "io" 7 "strings" 8 "testing" 9 10 "github.com/docker/docker/api/types" 11 "github.com/docker/docker/integration/internal/requirement" 12 "github.com/docker/docker/pkg/jsonmessage" 13 "github.com/docker/docker/testutil" 14 "github.com/docker/docker/testutil/daemon" 15 "github.com/docker/docker/testutil/fakecontext" 16 "gotest.tools/v3/assert" 17 "gotest.tools/v3/skip" 18 ) 19 20 // Finds the output of `readlink /proc/<pid>/ns/cgroup` in build output 21 func getCgroupFromBuildOutput(buildOutput io.Reader) (string, error) { 22 const prefix = "cgroup:" 23 24 dec := json.NewDecoder(buildOutput) 25 for { 26 m := jsonmessage.JSONMessage{} 27 err := dec.Decode(&m) 28 if err == io.EOF { 29 return "", nil 30 } 31 if err != nil { 32 return "", err 33 } 34 if ix := strings.Index(m.Stream, prefix); ix == 0 { 35 return strings.TrimSpace(m.Stream), nil 36 } 37 } 38 } 39 40 // Runs a docker build against a daemon with the given cgroup namespace default value. 41 // Returns the container cgroup and daemon cgroup. 42 func testBuildWithCgroupNs(ctx context.Context, t *testing.T, daemonNsMode string) (string, string) { 43 d := daemon.New(t, daemon.WithDefaultCgroupNamespaceMode(daemonNsMode)) 44 d.StartWithBusybox(ctx, t) 45 defer d.Stop(t) 46 47 dockerfile := ` 48 FROM busybox 49 RUN readlink /proc/self/ns/cgroup 50 ` 51 source := fakecontext.New(t, "", fakecontext.WithDockerfile(dockerfile)) 52 defer source.Close() 53 54 client := d.NewClientT(t) 55 resp, err := client.ImageBuild(ctx, 56 source.AsTarReader(t), 57 types.ImageBuildOptions{ 58 Remove: true, 59 ForceRemove: true, 60 Tags: []string{"buildcgroupns"}, 61 }) 62 assert.NilError(t, err) 63 defer resp.Body.Close() 64 65 containerCgroup, err := getCgroupFromBuildOutput(resp.Body) 66 assert.NilError(t, err) 67 daemonCgroup := d.CgroupNamespace(t) 68 69 return containerCgroup, daemonCgroup 70 } 71 72 func TestCgroupNamespacesBuild(t *testing.T) { 73 skip.If(t, testEnv.DaemonInfo.OSType != "linux") 74 skip.If(t, testEnv.IsRemoteDaemon()) 75 skip.If(t, !requirement.CgroupNamespacesEnabled()) 76 77 ctx := testutil.StartSpan(baseContext, t) 78 79 // When the daemon defaults to private cgroup namespaces, containers launched 80 // should be in their own private cgroup namespace by default 81 containerCgroup, daemonCgroup := testBuildWithCgroupNs(ctx, t, "private") 82 assert.Assert(t, daemonCgroup != containerCgroup) 83 } 84 85 func TestCgroupNamespacesBuildDaemonHostMode(t *testing.T) { 86 skip.If(t, testEnv.DaemonInfo.OSType != "linux") 87 skip.If(t, testEnv.IsRemoteDaemon()) 88 skip.If(t, !requirement.CgroupNamespacesEnabled()) 89 90 ctx := testutil.StartSpan(baseContext, t) 91 92 // When the daemon defaults to host cgroup namespaces, containers 93 // launched should not be inside their own cgroup namespaces 94 containerCgroup, daemonCgroup := testBuildWithCgroupNs(ctx, t, "host") 95 assert.Assert(t, daemonCgroup == containerCgroup) 96 }