github.com/khulnasoft/cli@v0.0.0-20240402070845-01bcad7beefa/e2e/container/run_test.go (about)

     1  package container
     2  
     3  import (
     4  	"fmt"
     5  	"strings"
     6  	"testing"
     7  
     8  	"github.com/docker/docker/api/types/versions"
     9  	"github.com/khulnasoft/cli/e2e/internal/fixtures"
    10  	"github.com/khulnasoft/cli/internal/test/environment"
    11  	"gotest.tools/v3/assert"
    12  	is "gotest.tools/v3/assert/cmp"
    13  	"gotest.tools/v3/golden"
    14  	"gotest.tools/v3/icmd"
    15  	"gotest.tools/v3/skip"
    16  )
    17  
    18  const registryPrefix = "registry:5000"
    19  
    20  func TestRunAttachedFromRemoteImageAndRemove(t *testing.T) {
    21  	skip.If(t, environment.RemoteDaemon())
    22  
    23  	// Digests in golden file are linux/amd64 specific.
    24  	// TODO: Fix this test and make it work on all platforms.
    25  	environment.SkipIfNotPlatform(t, "linux/amd64")
    26  
    27  	image := createRemoteImage(t)
    28  
    29  	result := icmd.RunCommand("docker", "run", "--rm", image,
    30  		"echo", "this", "is", "output")
    31  
    32  	result.Assert(t, icmd.Success)
    33  	assert.Check(t, is.Equal("this is output\n", result.Stdout()))
    34  	golden.Assert(t, result.Stderr(), "run-attached-from-remote-and-remove.golden")
    35  }
    36  
    37  func TestRunWithContentTrust(t *testing.T) {
    38  	skip.If(t, environment.RemoteDaemon())
    39  
    40  	dir := fixtures.SetupConfigFile(t)
    41  	defer dir.Remove()
    42  	image := fixtures.CreateMaskedTrustedRemoteImage(t, registryPrefix, "trust-run", "latest")
    43  
    44  	defer func() {
    45  		icmd.RunCommand("docker", "image", "rm", image).Assert(t, icmd.Success)
    46  	}()
    47  
    48  	result := icmd.RunCmd(
    49  		icmd.Command("docker", "run", image),
    50  		fixtures.WithConfig(dir.Path()),
    51  		fixtures.WithTrust,
    52  		fixtures.WithNotary,
    53  	)
    54  	result.Assert(t, icmd.Expected{
    55  		Err: fmt.Sprintf("Tagging %s@sha", image[:len(image)-7]),
    56  	})
    57  }
    58  
    59  func TestUntrustedRun(t *testing.T) {
    60  	dir := fixtures.SetupConfigFile(t)
    61  	defer dir.Remove()
    62  	image := registryPrefix + "/alpine:untrusted"
    63  	// tag the image and upload it to the private registry
    64  	icmd.RunCommand("docker", "tag", fixtures.AlpineImage, image).Assert(t, icmd.Success)
    65  	defer func() {
    66  		icmd.RunCommand("docker", "image", "rm", image).Assert(t, icmd.Success)
    67  	}()
    68  
    69  	// try trusted run on untrusted tag
    70  	result := icmd.RunCmd(
    71  		icmd.Command("docker", "run", image),
    72  		fixtures.WithConfig(dir.Path()),
    73  		fixtures.WithTrust,
    74  		fixtures.WithNotary,
    75  	)
    76  	result.Assert(t, icmd.Expected{
    77  		ExitCode: 125,
    78  		Err:      "does not have trust data for",
    79  	})
    80  }
    81  
    82  func TestTrustedRunFromBadTrustServer(t *testing.T) {
    83  	evilImageName := registryPrefix + "/evil-alpine:latest"
    84  	dir := fixtures.SetupConfigFile(t)
    85  	defer dir.Remove()
    86  
    87  	// tag the image and upload it to the private registry
    88  	icmd.RunCmd(icmd.Command("docker", "tag", fixtures.AlpineImage, evilImageName),
    89  		fixtures.WithConfig(dir.Path()),
    90  	).Assert(t, icmd.Success)
    91  	icmd.RunCmd(icmd.Command("docker", "image", "push", evilImageName),
    92  		fixtures.WithConfig(dir.Path()),
    93  		fixtures.WithPassphrase("root_password", "repo_password"),
    94  		fixtures.WithTrust,
    95  		fixtures.WithNotary,
    96  	).Assert(t, icmd.Success)
    97  	icmd.RunCmd(icmd.Command("docker", "image", "rm", evilImageName)).Assert(t, icmd.Success)
    98  
    99  	// try run
   100  	icmd.RunCmd(icmd.Command("docker", "run", evilImageName),
   101  		fixtures.WithConfig(dir.Path()),
   102  		fixtures.WithTrust,
   103  		fixtures.WithNotary,
   104  	).Assert(t, icmd.Success)
   105  	icmd.RunCmd(icmd.Command("docker", "image", "rm", evilImageName)).Assert(t, icmd.Success)
   106  
   107  	// init a client with the evil-server and a new trust dir
   108  	evilNotaryDir := fixtures.SetupConfigWithNotaryURL(t, "evil-test", fixtures.EvilNotaryURL)
   109  	defer evilNotaryDir.Remove()
   110  
   111  	// tag the same image and upload it to the private registry but signed with evil notary server
   112  	icmd.RunCmd(icmd.Command("docker", "tag", fixtures.AlpineImage, evilImageName),
   113  		fixtures.WithConfig(evilNotaryDir.Path()),
   114  	).Assert(t, icmd.Success)
   115  	icmd.RunCmd(icmd.Command("docker", "image", "push", evilImageName),
   116  		fixtures.WithConfig(evilNotaryDir.Path()),
   117  		fixtures.WithPassphrase("root_password", "repo_password"),
   118  		fixtures.WithTrust,
   119  		fixtures.WithNotaryServer(fixtures.EvilNotaryURL),
   120  	).Assert(t, icmd.Success)
   121  	icmd.RunCmd(icmd.Command("docker", "image", "rm", evilImageName)).Assert(t, icmd.Success)
   122  
   123  	// try running with the original client from the evil notary server. This should failed
   124  	// because the new root is invalid
   125  	icmd.RunCmd(icmd.Command("docker", "run", evilImageName),
   126  		fixtures.WithConfig(dir.Path()),
   127  		fixtures.WithTrust,
   128  		fixtures.WithNotaryServer(fixtures.EvilNotaryURL),
   129  	).Assert(t, icmd.Expected{
   130  		ExitCode: 125,
   131  		Err:      "could not rotate trust to a new trusted root",
   132  	})
   133  }
   134  
   135  // TODO: create this with registry API instead of engine API
   136  func createRemoteImage(t *testing.T) string {
   137  	t.Helper()
   138  	image := registryPrefix + "/alpine:test-run-pulls"
   139  	icmd.RunCommand("docker", "pull", fixtures.AlpineImage).Assert(t, icmd.Success)
   140  	icmd.RunCommand("docker", "tag", fixtures.AlpineImage, image).Assert(t, icmd.Success)
   141  	icmd.RunCommand("docker", "push", image).Assert(t, icmd.Success)
   142  	icmd.RunCommand("docker", "rmi", image).Assert(t, icmd.Success)
   143  	return image
   144  }
   145  
   146  func TestRunWithCgroupNamespace(t *testing.T) {
   147  	environment.SkipIfDaemonNotLinux(t)
   148  	environment.SkipIfCgroupNamespacesNotSupported(t)
   149  
   150  	result := icmd.RunCommand("docker", "run", "--cgroupns=private", "--rm", fixtures.AlpineImage,
   151  		"cat", "/sys/fs/cgroup/cgroup.controllers")
   152  	result.Assert(t, icmd.Success)
   153  }
   154  
   155  func TestMountSubvolume(t *testing.T) {
   156  	skip.If(t, versions.LessThan(environment.DaemonAPIVersion(t), "1.45"))
   157  
   158  	volName := "test-volume-" + t.Name()
   159  	icmd.RunCommand("docker", "volume", "create", volName).Assert(t, icmd.Success)
   160  
   161  	t.Cleanup(func() {
   162  		icmd.RunCommand("docker", "volume", "remove", "-f", volName).Assert(t, icmd.Success)
   163  	})
   164  
   165  	defaultMountOpts := []string{
   166  		"type=volume",
   167  		"src=" + volName,
   168  		"dst=/volume",
   169  	}
   170  
   171  	// Populate the volume with test data.
   172  	icmd.RunCommand("docker", "run", "--rm", "--mount", strings.Join(defaultMountOpts, ","), fixtures.AlpineImage, "sh", "-c",
   173  		"echo foo > /volume/bar.txt && "+
   174  			"mkdir /volume/etc && echo root > /volume/etc/passwd && "+
   175  			"mkdir /volume/subdir && echo world > /volume/subdir/hello.txt;",
   176  	).Assert(t, icmd.Success)
   177  
   178  	runMount := func(cmd string, mountOpts ...string) *icmd.Result {
   179  		mountArg := strings.Join(append(defaultMountOpts, mountOpts...), ",")
   180  		return icmd.RunCommand("docker", "run", "--rm", "--mount", mountArg, fixtures.AlpineImage, cmd, "/volume")
   181  	}
   182  
   183  	for _, tc := range []struct {
   184  		name    string
   185  		cmd     string
   186  		subpath string
   187  
   188  		expectedOut  string
   189  		expectedErr  string
   190  		expectedCode int
   191  	}{
   192  		{name: "absolute", cmd: "cat", subpath: "/etc/passwd", expectedErr: "subpath must be a relative path within the volume", expectedCode: 125},
   193  		{name: "subpath not exists", cmd: "ls", subpath: "some-path/that/doesnt-exist", expectedErr: "cannot access path ", expectedCode: 127},
   194  		{name: "subdirectory mount", cmd: "ls", subpath: "subdir", expectedOut: "hello.txt"},
   195  		{name: "file mount", cmd: "cat", subpath: "bar.txt", expectedOut: "foo"},
   196  	} {
   197  		tc := tc
   198  		t.Run(tc.name, func(t *testing.T) {
   199  			runMount(tc.cmd, "volume-subpath="+tc.subpath).Assert(t, icmd.Expected{
   200  				Err:      tc.expectedErr,
   201  				ExitCode: tc.expectedCode,
   202  				Out:      tc.expectedOut,
   203  			})
   204  		})
   205  	}
   206  }