github.1git.de/docker/cli@v26.1.3+incompatible/e2e/container/run_test.go (about)

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