github.com/demonoid81/moby@v0.0.0-20200517203328-62dd8e17c460/integration/build/build_cgroupns_linux_test.go (about) 1 package build // import "github.com/demonoid81/moby/integration/build" 2 3 import ( 4 "context" 5 "encoding/json" 6 "io" 7 "strings" 8 "testing" 9 10 "github.com/demonoid81/moby/api/types" 11 "github.com/demonoid81/moby/integration/internal/requirement" 12 "github.com/demonoid81/moby/pkg/jsonmessage" 13 "github.com/demonoid81/moby/testutil/daemon" 14 "github.com/demonoid81/moby/testutil/fakecontext" 15 "gotest.tools/v3/assert" 16 "gotest.tools/v3/skip" 17 ) 18 19 // Finds the output of `readlink /proc/<pid>/ns/cgroup` in build output 20 func getCgroupFromBuildOutput(buildOutput io.Reader) (string, error) { 21 const prefix = "cgroup:" 22 23 dec := json.NewDecoder(buildOutput) 24 for { 25 m := jsonmessage.JSONMessage{} 26 err := dec.Decode(&m) 27 if err == io.EOF { 28 return "", nil 29 } 30 if err != nil { 31 return "", err 32 } 33 if ix := strings.Index(m.Stream, prefix); ix == 0 { 34 return strings.TrimSpace(m.Stream), nil 35 } 36 } 37 } 38 39 // Runs a docker build against a daemon with the given cgroup namespace default value. 40 // Returns the container cgroup and daemon cgroup. 41 func testBuildWithCgroupNs(t *testing.T, daemonNsMode string) (string, string) { 42 d := daemon.New(t, daemon.WithDefaultCgroupNamespaceMode(daemonNsMode)) 43 d.StartWithBusybox(t) 44 defer d.Stop(t) 45 46 dockerfile := ` 47 FROM busybox 48 RUN readlink /proc/self/ns/cgroup 49 ` 50 ctx := context.Background() 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 // When the daemon defaults to private cgroup namespaces, containers launched 78 // should be in their own private cgroup namespace by default 79 containerCgroup, daemonCgroup := testBuildWithCgroupNs(t, "private") 80 assert.Assert(t, daemonCgroup != containerCgroup) 81 } 82 83 func TestCgroupNamespacesBuildDaemonHostMode(t *testing.T) { 84 skip.If(t, testEnv.DaemonInfo.OSType != "linux") 85 skip.If(t, testEnv.IsRemoteDaemon()) 86 skip.If(t, !requirement.CgroupNamespacesEnabled()) 87 88 // When the daemon defaults to host cgroup namespaces, containers 89 // launched should not be inside their own cgroup namespaces 90 containerCgroup, daemonCgroup := testBuildWithCgroupNs(t, "host") 91 assert.Assert(t, daemonCgroup == containerCgroup) 92 }