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 }