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  }