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 }