Tizen_4.0 base
[platform/upstream/docker-engine.git] / integration-cli / docker_cli_run_test.go
1 package main
2
3 import (
4         "bufio"
5         "bytes"
6         "encoding/json"
7         "fmt"
8         "io"
9         "io/ioutil"
10         "net"
11         "os"
12         "os/exec"
13         "path"
14         "path/filepath"
15         "reflect"
16         "regexp"
17         "runtime"
18         "sort"
19         "strconv"
20         "strings"
21         "sync"
22         "time"
23
24         "github.com/docker/docker/integration-cli/checker"
25         "github.com/docker/docker/integration-cli/cli"
26         "github.com/docker/docker/integration-cli/cli/build"
27         "github.com/docker/docker/integration-cli/cli/build/fakecontext"
28         "github.com/docker/docker/pkg/mount"
29         "github.com/docker/docker/pkg/stringid"
30         "github.com/docker/docker/pkg/stringutils"
31         "github.com/docker/docker/pkg/testutil"
32         icmd "github.com/docker/docker/pkg/testutil/cmd"
33         "github.com/docker/docker/runconfig"
34         "github.com/docker/go-connections/nat"
35         "github.com/docker/libnetwork/resolvconf"
36         "github.com/docker/libnetwork/types"
37         "github.com/go-check/check"
38         libcontainerUser "github.com/opencontainers/runc/libcontainer/user"
39 )
40
41 // "test123" should be printed by docker run
42 func (s *DockerSuite) TestRunEchoStdout(c *check.C) {
43         out, _ := dockerCmd(c, "run", "busybox", "echo", "test123")
44         if out != "test123\n" {
45                 c.Fatalf("container should've printed 'test123', got '%s'", out)
46         }
47 }
48
49 // "test" should be printed
50 func (s *DockerSuite) TestRunEchoNamedContainer(c *check.C) {
51         out, _ := dockerCmd(c, "run", "--name", "testfoonamedcontainer", "busybox", "echo", "test")
52         if out != "test\n" {
53                 c.Errorf("container should've printed 'test'")
54         }
55 }
56
57 // docker run should not leak file descriptors. This test relies on Unix
58 // specific functionality and cannot run on Windows.
59 func (s *DockerSuite) TestRunLeakyFileDescriptors(c *check.C) {
60         testRequires(c, DaemonIsLinux)
61         out, _ := dockerCmd(c, "run", "busybox", "ls", "-C", "/proc/self/fd")
62
63         // normally, we should only get 0, 1, and 2, but 3 gets created by "ls" when it does "opendir" on the "fd" directory
64         if out != "0  1  2  3\n" {
65                 c.Errorf("container should've printed '0  1  2  3', not: %s", out)
66         }
67 }
68
69 // it should be possible to lookup Google DNS
70 // this will fail when Internet access is unavailable
71 func (s *DockerSuite) TestRunLookupGoogleDNS(c *check.C) {
72         testRequires(c, Network, NotArm)
73         if testEnv.DaemonPlatform() == "windows" {
74                 // nslookup isn't present in Windows busybox. Is built-in. Further,
75                 // nslookup isn't present in nanoserver. Hence just use PowerShell...
76                 dockerCmd(c, "run", testEnv.MinimalBaseImage(), "powershell", "Resolve-DNSName", "google.com")
77         } else {
78                 dockerCmd(c, "run", "busybox", "nslookup", "google.com")
79         }
80
81 }
82
83 // the exit code should be 0
84 func (s *DockerSuite) TestRunExitCodeZero(c *check.C) {
85         dockerCmd(c, "run", "busybox", "true")
86 }
87
88 // the exit code should be 1
89 func (s *DockerSuite) TestRunExitCodeOne(c *check.C) {
90         _, exitCode, err := dockerCmdWithError("run", "busybox", "false")
91         c.Assert(err, checker.NotNil)
92         c.Assert(exitCode, checker.Equals, 1)
93 }
94
95 // it should be possible to pipe in data via stdin to a process running in a container
96 func (s *DockerSuite) TestRunStdinPipe(c *check.C) {
97         // TODO Windows: This needs some work to make compatible.
98         testRequires(c, DaemonIsLinux)
99         result := icmd.RunCmd(icmd.Cmd{
100                 Command: []string{dockerBinary, "run", "-i", "-a", "stdin", "busybox", "cat"},
101                 Stdin:   strings.NewReader("blahblah"),
102         })
103         result.Assert(c, icmd.Success)
104         out := result.Stdout()
105
106         out = strings.TrimSpace(out)
107         dockerCmd(c, "wait", out)
108
109         logsOut, _ := dockerCmd(c, "logs", out)
110
111         containerLogs := strings.TrimSpace(logsOut)
112         if containerLogs != "blahblah" {
113                 c.Errorf("logs didn't print the container's logs %s", containerLogs)
114         }
115
116         dockerCmd(c, "rm", out)
117 }
118
119 // the container's ID should be printed when starting a container in detached mode
120 func (s *DockerSuite) TestRunDetachedContainerIDPrinting(c *check.C) {
121         out, _ := dockerCmd(c, "run", "-d", "busybox", "true")
122
123         out = strings.TrimSpace(out)
124         dockerCmd(c, "wait", out)
125
126         rmOut, _ := dockerCmd(c, "rm", out)
127
128         rmOut = strings.TrimSpace(rmOut)
129         if rmOut != out {
130                 c.Errorf("rm didn't print the container ID %s %s", out, rmOut)
131         }
132 }
133
134 // the working directory should be set correctly
135 func (s *DockerSuite) TestRunWorkingDirectory(c *check.C) {
136         dir := "/root"
137         image := "busybox"
138         if testEnv.DaemonPlatform() == "windows" {
139                 dir = `C:/Windows`
140         }
141
142         // First with -w
143         out, _ := dockerCmd(c, "run", "-w", dir, image, "pwd")
144         out = strings.TrimSpace(out)
145         if out != dir {
146                 c.Errorf("-w failed to set working directory")
147         }
148
149         // Then with --workdir
150         out, _ = dockerCmd(c, "run", "--workdir", dir, image, "pwd")
151         out = strings.TrimSpace(out)
152         if out != dir {
153                 c.Errorf("--workdir failed to set working directory")
154         }
155 }
156
157 // pinging Google's DNS resolver should fail when we disable the networking
158 func (s *DockerSuite) TestRunWithoutNetworking(c *check.C) {
159         count := "-c"
160         image := "busybox"
161         if testEnv.DaemonPlatform() == "windows" {
162                 count = "-n"
163                 image = testEnv.MinimalBaseImage()
164         }
165
166         // First using the long form --net
167         out, exitCode, err := dockerCmdWithError("run", "--net=none", image, "ping", count, "1", "8.8.8.8")
168         if err != nil && exitCode != 1 {
169                 c.Fatal(out, err)
170         }
171         if exitCode != 1 {
172                 c.Errorf("--net=none should've disabled the network; the container shouldn't have been able to ping 8.8.8.8")
173         }
174 }
175
176 //test --link use container name to link target
177 func (s *DockerSuite) TestRunLinksContainerWithContainerName(c *check.C) {
178         // TODO Windows: This test cannot run on a Windows daemon as the networking
179         // settings are not populated back yet on inspect.
180         testRequires(c, DaemonIsLinux)
181         dockerCmd(c, "run", "-i", "-t", "-d", "--name", "parent", "busybox")
182
183         ip := inspectField(c, "parent", "NetworkSettings.Networks.bridge.IPAddress")
184
185         out, _ := dockerCmd(c, "run", "--link", "parent:test", "busybox", "/bin/cat", "/etc/hosts")
186         if !strings.Contains(out, ip+"  test") {
187                 c.Fatalf("use a container name to link target failed")
188         }
189 }
190
191 //test --link use container id to link target
192 func (s *DockerSuite) TestRunLinksContainerWithContainerID(c *check.C) {
193         // TODO Windows: This test cannot run on a Windows daemon as the networking
194         // settings are not populated back yet on inspect.
195         testRequires(c, DaemonIsLinux)
196         cID, _ := dockerCmd(c, "run", "-i", "-t", "-d", "busybox")
197
198         cID = strings.TrimSpace(cID)
199         ip := inspectField(c, cID, "NetworkSettings.Networks.bridge.IPAddress")
200
201         out, _ := dockerCmd(c, "run", "--link", cID+":test", "busybox", "/bin/cat", "/etc/hosts")
202         if !strings.Contains(out, ip+"  test") {
203                 c.Fatalf("use a container id to link target failed")
204         }
205 }
206
207 func (s *DockerSuite) TestUserDefinedNetworkLinks(c *check.C) {
208         testRequires(c, DaemonIsLinux, NotUserNamespace, NotArm)
209         dockerCmd(c, "network", "create", "-d", "bridge", "udlinkNet")
210
211         dockerCmd(c, "run", "-d", "--net=udlinkNet", "--name=first", "busybox", "top")
212         c.Assert(waitRun("first"), check.IsNil)
213
214         // run a container in user-defined network udlinkNet with a link for an existing container
215         // and a link for a container that doesn't exist
216         dockerCmd(c, "run", "-d", "--net=udlinkNet", "--name=second", "--link=first:foo",
217                 "--link=third:bar", "busybox", "top")
218         c.Assert(waitRun("second"), check.IsNil)
219
220         // ping to first and its alias foo must succeed
221         _, _, err := dockerCmdWithError("exec", "second", "ping", "-c", "1", "first")
222         c.Assert(err, check.IsNil)
223         _, _, err = dockerCmdWithError("exec", "second", "ping", "-c", "1", "foo")
224         c.Assert(err, check.IsNil)
225
226         // ping to third and its alias must fail
227         _, _, err = dockerCmdWithError("exec", "second", "ping", "-c", "1", "third")
228         c.Assert(err, check.NotNil)
229         _, _, err = dockerCmdWithError("exec", "second", "ping", "-c", "1", "bar")
230         c.Assert(err, check.NotNil)
231
232         // start third container now
233         dockerCmd(c, "run", "-d", "--net=udlinkNet", "--name=third", "busybox", "top")
234         c.Assert(waitRun("third"), check.IsNil)
235
236         // ping to third and its alias must succeed now
237         _, _, err = dockerCmdWithError("exec", "second", "ping", "-c", "1", "third")
238         c.Assert(err, check.IsNil)
239         _, _, err = dockerCmdWithError("exec", "second", "ping", "-c", "1", "bar")
240         c.Assert(err, check.IsNil)
241 }
242
243 func (s *DockerSuite) TestUserDefinedNetworkLinksWithRestart(c *check.C) {
244         testRequires(c, DaemonIsLinux, NotUserNamespace, NotArm)
245         dockerCmd(c, "network", "create", "-d", "bridge", "udlinkNet")
246
247         dockerCmd(c, "run", "-d", "--net=udlinkNet", "--name=first", "busybox", "top")
248         c.Assert(waitRun("first"), check.IsNil)
249
250         dockerCmd(c, "run", "-d", "--net=udlinkNet", "--name=second", "--link=first:foo",
251                 "busybox", "top")
252         c.Assert(waitRun("second"), check.IsNil)
253
254         // ping to first and its alias foo must succeed
255         _, _, err := dockerCmdWithError("exec", "second", "ping", "-c", "1", "first")
256         c.Assert(err, check.IsNil)
257         _, _, err = dockerCmdWithError("exec", "second", "ping", "-c", "1", "foo")
258         c.Assert(err, check.IsNil)
259
260         // Restart first container
261         dockerCmd(c, "restart", "first")
262         c.Assert(waitRun("first"), check.IsNil)
263
264         // ping to first and its alias foo must still succeed
265         _, _, err = dockerCmdWithError("exec", "second", "ping", "-c", "1", "first")
266         c.Assert(err, check.IsNil)
267         _, _, err = dockerCmdWithError("exec", "second", "ping", "-c", "1", "foo")
268         c.Assert(err, check.IsNil)
269
270         // Restart second container
271         dockerCmd(c, "restart", "second")
272         c.Assert(waitRun("second"), check.IsNil)
273
274         // ping to first and its alias foo must still succeed
275         _, _, err = dockerCmdWithError("exec", "second", "ping", "-c", "1", "first")
276         c.Assert(err, check.IsNil)
277         _, _, err = dockerCmdWithError("exec", "second", "ping", "-c", "1", "foo")
278         c.Assert(err, check.IsNil)
279 }
280
281 func (s *DockerSuite) TestRunWithNetAliasOnDefaultNetworks(c *check.C) {
282         testRequires(c, DaemonIsLinux, NotUserNamespace, NotArm)
283
284         defaults := []string{"bridge", "host", "none"}
285         for _, net := range defaults {
286                 out, _, err := dockerCmdWithError("run", "-d", "--net", net, "--net-alias", "alias_"+net, "busybox", "top")
287                 c.Assert(err, checker.NotNil)
288                 c.Assert(out, checker.Contains, runconfig.ErrUnsupportedNetworkAndAlias.Error())
289         }
290 }
291
292 func (s *DockerSuite) TestUserDefinedNetworkAlias(c *check.C) {
293         testRequires(c, DaemonIsLinux, NotUserNamespace, NotArm)
294         dockerCmd(c, "network", "create", "-d", "bridge", "net1")
295
296         cid1, _ := dockerCmd(c, "run", "-d", "--net=net1", "--name=first", "--net-alias=foo1", "--net-alias=foo2", "busybox", "top")
297         c.Assert(waitRun("first"), check.IsNil)
298
299         // Check if default short-id alias is added automatically
300         id := strings.TrimSpace(cid1)
301         aliases := inspectField(c, id, "NetworkSettings.Networks.net1.Aliases")
302         c.Assert(aliases, checker.Contains, stringid.TruncateID(id))
303
304         cid2, _ := dockerCmd(c, "run", "-d", "--net=net1", "--name=second", "busybox", "top")
305         c.Assert(waitRun("second"), check.IsNil)
306
307         // Check if default short-id alias is added automatically
308         id = strings.TrimSpace(cid2)
309         aliases = inspectField(c, id, "NetworkSettings.Networks.net1.Aliases")
310         c.Assert(aliases, checker.Contains, stringid.TruncateID(id))
311
312         // ping to first and its network-scoped aliases
313         _, _, err := dockerCmdWithError("exec", "second", "ping", "-c", "1", "first")
314         c.Assert(err, check.IsNil)
315         _, _, err = dockerCmdWithError("exec", "second", "ping", "-c", "1", "foo1")
316         c.Assert(err, check.IsNil)
317         _, _, err = dockerCmdWithError("exec", "second", "ping", "-c", "1", "foo2")
318         c.Assert(err, check.IsNil)
319         // ping first container's short-id alias
320         _, _, err = dockerCmdWithError("exec", "second", "ping", "-c", "1", stringid.TruncateID(cid1))
321         c.Assert(err, check.IsNil)
322
323         // Restart first container
324         dockerCmd(c, "restart", "first")
325         c.Assert(waitRun("first"), check.IsNil)
326
327         // ping to first and its network-scoped aliases must succeed
328         _, _, err = dockerCmdWithError("exec", "second", "ping", "-c", "1", "first")
329         c.Assert(err, check.IsNil)
330         _, _, err = dockerCmdWithError("exec", "second", "ping", "-c", "1", "foo1")
331         c.Assert(err, check.IsNil)
332         _, _, err = dockerCmdWithError("exec", "second", "ping", "-c", "1", "foo2")
333         c.Assert(err, check.IsNil)
334         // ping first container's short-id alias
335         _, _, err = dockerCmdWithError("exec", "second", "ping", "-c", "1", stringid.TruncateID(cid1))
336         c.Assert(err, check.IsNil)
337 }
338
339 // Issue 9677.
340 func (s *DockerSuite) TestRunWithDaemonFlags(c *check.C) {
341         out, _, err := dockerCmdWithError("--exec-opt", "foo=bar", "run", "-i", "busybox", "true")
342         c.Assert(err, checker.NotNil)
343         c.Assert(out, checker.Contains, "unknown flag: --exec-opt")
344 }
345
346 // Regression test for #4979
347 func (s *DockerSuite) TestRunWithVolumesFromExited(c *check.C) {
348
349         var (
350                 out      string
351                 exitCode int
352         )
353
354         // Create a file in a volume
355         if testEnv.DaemonPlatform() == "windows" {
356                 out, exitCode = dockerCmd(c, "run", "--name", "test-data", "--volume", `c:\some\dir`, testEnv.MinimalBaseImage(), "cmd", "/c", `echo hello > c:\some\dir\file`)
357         } else {
358                 out, exitCode = dockerCmd(c, "run", "--name", "test-data", "--volume", "/some/dir", "busybox", "touch", "/some/dir/file")
359         }
360         if exitCode != 0 {
361                 c.Fatal("1", out, exitCode)
362         }
363
364         // Read the file from another container using --volumes-from to access the volume in the second container
365         if testEnv.DaemonPlatform() == "windows" {
366                 out, exitCode = dockerCmd(c, "run", "--volumes-from", "test-data", testEnv.MinimalBaseImage(), "cmd", "/c", `type c:\some\dir\file`)
367         } else {
368                 out, exitCode = dockerCmd(c, "run", "--volumes-from", "test-data", "busybox", "cat", "/some/dir/file")
369         }
370         if exitCode != 0 {
371                 c.Fatal("2", out, exitCode)
372         }
373 }
374
375 // Volume path is a symlink which also exists on the host, and the host side is a file not a dir
376 // But the volume call is just a normal volume, not a bind mount
377 func (s *DockerSuite) TestRunCreateVolumesInSymlinkDir(c *check.C) {
378         var (
379                 dockerFile    string
380                 containerPath string
381                 cmd           string
382         )
383         // This test cannot run on a Windows daemon as
384         // Windows does not support symlinks inside a volume path
385         testRequires(c, SameHostDaemon, DaemonIsLinux)
386         name := "test-volume-symlink"
387
388         dir, err := ioutil.TempDir("", name)
389         if err != nil {
390                 c.Fatal(err)
391         }
392         defer os.RemoveAll(dir)
393
394         // In the case of Windows to Windows CI, if the machine is setup so that
395         // the temp directory is not the C: drive, this test is invalid and will
396         // not work.
397         if testEnv.DaemonPlatform() == "windows" && strings.ToLower(dir[:1]) != "c" {
398                 c.Skip("Requires TEMP to point to C: drive")
399         }
400
401         f, err := os.OpenFile(filepath.Join(dir, "test"), os.O_CREATE, 0700)
402         if err != nil {
403                 c.Fatal(err)
404         }
405         f.Close()
406
407         if testEnv.DaemonPlatform() == "windows" {
408                 dockerFile = fmt.Sprintf("FROM %s\nRUN mkdir %s\nRUN mklink /D c:\\test %s", testEnv.MinimalBaseImage(), dir, dir)
409                 containerPath = `c:\test\test`
410                 cmd = "tasklist"
411         } else {
412                 dockerFile = fmt.Sprintf("FROM busybox\nRUN mkdir -p %s\nRUN ln -s %s /test", dir, dir)
413                 containerPath = "/test/test"
414                 cmd = "true"
415         }
416         buildImageSuccessfully(c, name, build.WithDockerfile(dockerFile))
417         dockerCmd(c, "run", "-v", containerPath, name, cmd)
418 }
419
420 // Volume path is a symlink in the container
421 func (s *DockerSuite) TestRunCreateVolumesInSymlinkDir2(c *check.C) {
422         var (
423                 dockerFile    string
424                 containerPath string
425                 cmd           string
426         )
427         // This test cannot run on a Windows daemon as
428         // Windows does not support symlinks inside a volume path
429         testRequires(c, SameHostDaemon, DaemonIsLinux)
430         name := "test-volume-symlink2"
431
432         if testEnv.DaemonPlatform() == "windows" {
433                 dockerFile = fmt.Sprintf("FROM %s\nRUN mkdir c:\\%s\nRUN mklink /D c:\\test c:\\%s", testEnv.MinimalBaseImage(), name, name)
434                 containerPath = `c:\test\test`
435                 cmd = "tasklist"
436         } else {
437                 dockerFile = fmt.Sprintf("FROM busybox\nRUN mkdir -p /%s\nRUN ln -s /%s /test", name, name)
438                 containerPath = "/test/test"
439                 cmd = "true"
440         }
441         buildImageSuccessfully(c, name, build.WithDockerfile(dockerFile))
442         dockerCmd(c, "run", "-v", containerPath, name, cmd)
443 }
444
445 func (s *DockerSuite) TestRunVolumesMountedAsReadonly(c *check.C) {
446         if _, code, err := dockerCmdWithError("run", "-v", "/test:/test:ro", "busybox", "touch", "/test/somefile"); err == nil || code == 0 {
447                 c.Fatalf("run should fail because volume is ro: exit code %d", code)
448         }
449 }
450
451 func (s *DockerSuite) TestRunVolumesFromInReadonlyModeFails(c *check.C) {
452         var (
453                 volumeDir string
454                 fileInVol string
455         )
456         if testEnv.DaemonPlatform() == "windows" {
457                 volumeDir = `c:/test` // Forward-slash as using busybox
458                 fileInVol = `c:/test/file`
459         } else {
460                 testRequires(c, DaemonIsLinux)
461                 volumeDir = "/test"
462                 fileInVol = `/test/file`
463         }
464         dockerCmd(c, "run", "--name", "parent", "-v", volumeDir, "busybox", "true")
465
466         if _, code, err := dockerCmdWithError("run", "--volumes-from", "parent:ro", "busybox", "touch", fileInVol); err == nil || code == 0 {
467                 c.Fatalf("run should fail because volume is ro: exit code %d", code)
468         }
469 }
470
471 // Regression test for #1201
472 func (s *DockerSuite) TestRunVolumesFromInReadWriteMode(c *check.C) {
473         var (
474                 volumeDir string
475                 fileInVol string
476         )
477         if testEnv.DaemonPlatform() == "windows" {
478                 volumeDir = `c:/test` // Forward-slash as using busybox
479                 fileInVol = `c:/test/file`
480         } else {
481                 volumeDir = "/test"
482                 fileInVol = "/test/file"
483         }
484
485         dockerCmd(c, "run", "--name", "parent", "-v", volumeDir, "busybox", "true")
486         dockerCmd(c, "run", "--volumes-from", "parent:rw", "busybox", "touch", fileInVol)
487
488         if out, _, err := dockerCmdWithError("run", "--volumes-from", "parent:bar", "busybox", "touch", fileInVol); err == nil || !strings.Contains(out, `invalid mode: bar`) {
489                 c.Fatalf("running --volumes-from parent:bar should have failed with invalid mode: %q", out)
490         }
491
492         dockerCmd(c, "run", "--volumes-from", "parent", "busybox", "touch", fileInVol)
493 }
494
495 func (s *DockerSuite) TestVolumesFromGetsProperMode(c *check.C) {
496         testRequires(c, SameHostDaemon)
497         prefix, slash := getPrefixAndSlashFromDaemonPlatform()
498         hostpath := testutil.RandomTmpDirPath("test", testEnv.DaemonPlatform())
499         if err := os.MkdirAll(hostpath, 0755); err != nil {
500                 c.Fatalf("Failed to create %s: %q", hostpath, err)
501         }
502         defer os.RemoveAll(hostpath)
503
504         dockerCmd(c, "run", "--name", "parent", "-v", hostpath+":"+prefix+slash+"test:ro", "busybox", "true")
505
506         // Expect this "rw" mode to be be ignored since the inherited volume is "ro"
507         if _, _, err := dockerCmdWithError("run", "--volumes-from", "parent:rw", "busybox", "touch", prefix+slash+"test"+slash+"file"); err == nil {
508                 c.Fatal("Expected volumes-from to inherit read-only volume even when passing in `rw`")
509         }
510
511         dockerCmd(c, "run", "--name", "parent2", "-v", hostpath+":"+prefix+slash+"test:ro", "busybox", "true")
512
513         // Expect this to be read-only since both are "ro"
514         if _, _, err := dockerCmdWithError("run", "--volumes-from", "parent2:ro", "busybox", "touch", prefix+slash+"test"+slash+"file"); err == nil {
515                 c.Fatal("Expected volumes-from to inherit read-only volume even when passing in `ro`")
516         }
517 }
518
519 // Test for GH#10618
520 func (s *DockerSuite) TestRunNoDupVolumes(c *check.C) {
521         path1 := testutil.RandomTmpDirPath("test1", testEnv.DaemonPlatform())
522         path2 := testutil.RandomTmpDirPath("test2", testEnv.DaemonPlatform())
523
524         someplace := ":/someplace"
525         if testEnv.DaemonPlatform() == "windows" {
526                 // Windows requires that the source directory exists before calling HCS
527                 testRequires(c, SameHostDaemon)
528                 someplace = `:c:\someplace`
529                 if err := os.MkdirAll(path1, 0755); err != nil {
530                         c.Fatalf("Failed to create %s: %q", path1, err)
531                 }
532                 defer os.RemoveAll(path1)
533                 if err := os.MkdirAll(path2, 0755); err != nil {
534                         c.Fatalf("Failed to create %s: %q", path1, err)
535                 }
536                 defer os.RemoveAll(path2)
537         }
538         mountstr1 := path1 + someplace
539         mountstr2 := path2 + someplace
540
541         if out, _, err := dockerCmdWithError("run", "-v", mountstr1, "-v", mountstr2, "busybox", "true"); err == nil {
542                 c.Fatal("Expected error about duplicate mount definitions")
543         } else {
544                 if !strings.Contains(out, "Duplicate mount point") {
545                         c.Fatalf("Expected 'duplicate mount point' error, got %v", out)
546                 }
547         }
548
549         // Test for https://github.com/docker/docker/issues/22093
550         volumename1 := "test1"
551         volumename2 := "test2"
552         volume1 := volumename1 + someplace
553         volume2 := volumename2 + someplace
554         if out, _, err := dockerCmdWithError("run", "-v", volume1, "-v", volume2, "busybox", "true"); err == nil {
555                 c.Fatal("Expected error about duplicate mount definitions")
556         } else {
557                 if !strings.Contains(out, "Duplicate mount point") {
558                         c.Fatalf("Expected 'duplicate mount point' error, got %v", out)
559                 }
560         }
561         // create failed should have create volume volumename1 or volumename2
562         // we should remove volumename2 or volumename2 successfully
563         out, _ := dockerCmd(c, "volume", "ls")
564         if strings.Contains(out, volumename1) {
565                 dockerCmd(c, "volume", "rm", volumename1)
566         } else {
567                 dockerCmd(c, "volume", "rm", volumename2)
568         }
569 }
570
571 // Test for #1351
572 func (s *DockerSuite) TestRunApplyVolumesFromBeforeVolumes(c *check.C) {
573         prefix := ""
574         if testEnv.DaemonPlatform() == "windows" {
575                 prefix = `c:`
576         }
577         dockerCmd(c, "run", "--name", "parent", "-v", prefix+"/test", "busybox", "touch", prefix+"/test/foo")
578         dockerCmd(c, "run", "--volumes-from", "parent", "-v", prefix+"/test", "busybox", "cat", prefix+"/test/foo")
579 }
580
581 func (s *DockerSuite) TestRunMultipleVolumesFrom(c *check.C) {
582         prefix := ""
583         if testEnv.DaemonPlatform() == "windows" {
584                 prefix = `c:`
585         }
586         dockerCmd(c, "run", "--name", "parent1", "-v", prefix+"/test", "busybox", "touch", prefix+"/test/foo")
587         dockerCmd(c, "run", "--name", "parent2", "-v", prefix+"/other", "busybox", "touch", prefix+"/other/bar")
588         dockerCmd(c, "run", "--volumes-from", "parent1", "--volumes-from", "parent2", "busybox", "sh", "-c", "cat /test/foo && cat /other/bar")
589 }
590
591 // this tests verifies the ID format for the container
592 func (s *DockerSuite) TestRunVerifyContainerID(c *check.C) {
593         out, exit, err := dockerCmdWithError("run", "-d", "busybox", "true")
594         if err != nil {
595                 c.Fatal(err)
596         }
597         if exit != 0 {
598                 c.Fatalf("expected exit code 0 received %d", exit)
599         }
600
601         match, err := regexp.MatchString("^[0-9a-f]{64}$", strings.TrimSuffix(out, "\n"))
602         if err != nil {
603                 c.Fatal(err)
604         }
605         if !match {
606                 c.Fatalf("Invalid container ID: %s", out)
607         }
608 }
609
610 // Test that creating a container with a volume doesn't crash. Regression test for #995.
611 func (s *DockerSuite) TestRunCreateVolume(c *check.C) {
612         prefix := ""
613         if testEnv.DaemonPlatform() == "windows" {
614                 prefix = `c:`
615         }
616         dockerCmd(c, "run", "-v", prefix+"/var/lib/data", "busybox", "true")
617 }
618
619 // Test that creating a volume with a symlink in its path works correctly. Test for #5152.
620 // Note that this bug happens only with symlinks with a target that starts with '/'.
621 func (s *DockerSuite) TestRunCreateVolumeWithSymlink(c *check.C) {
622         // Cannot run on Windows as relies on Linux-specific functionality (sh -c mount...)
623         testRequires(c, DaemonIsLinux)
624         workingDirectory, err := ioutil.TempDir("", "TestRunCreateVolumeWithSymlink")
625         image := "docker-test-createvolumewithsymlink"
626
627         buildCmd := exec.Command(dockerBinary, "build", "-t", image, "-")
628         buildCmd.Stdin = strings.NewReader(`FROM busybox
629                 RUN ln -s home /bar`)
630         buildCmd.Dir = workingDirectory
631         err = buildCmd.Run()
632         if err != nil {
633                 c.Fatalf("could not build '%s': %v", image, err)
634         }
635
636         _, exitCode, err := dockerCmdWithError("run", "-v", "/bar/foo", "--name", "test-createvolumewithsymlink", image, "sh", "-c", "mount | grep -q /home/foo")
637         if err != nil || exitCode != 0 {
638                 c.Fatalf("[run] err: %v, exitcode: %d", err, exitCode)
639         }
640
641         volPath, err := inspectMountSourceField("test-createvolumewithsymlink", "/bar/foo")
642         c.Assert(err, checker.IsNil)
643
644         _, exitCode, err = dockerCmdWithError("rm", "-v", "test-createvolumewithsymlink")
645         if err != nil || exitCode != 0 {
646                 c.Fatalf("[rm] err: %v, exitcode: %d", err, exitCode)
647         }
648
649         _, err = os.Stat(volPath)
650         if !os.IsNotExist(err) {
651                 c.Fatalf("[open] (expecting 'file does not exist' error) err: %v, volPath: %s", err, volPath)
652         }
653 }
654
655 // Tests that a volume path that has a symlink exists in a container mounting it with `--volumes-from`.
656 func (s *DockerSuite) TestRunVolumesFromSymlinkPath(c *check.C) {
657         // This test cannot run on a Windows daemon as
658         // Windows does not support symlinks inside a volume path
659         testRequires(c, DaemonIsLinux)
660
661         workingDirectory, err := ioutil.TempDir("", "TestRunVolumesFromSymlinkPath")
662         c.Assert(err, checker.IsNil)
663         name := "docker-test-volumesfromsymlinkpath"
664         prefix := ""
665         dfContents := `FROM busybox
666                 RUN ln -s home /foo
667                 VOLUME ["/foo/bar"]`
668
669         if testEnv.DaemonPlatform() == "windows" {
670                 prefix = `c:`
671                 dfContents = `FROM ` + testEnv.MinimalBaseImage() + `
672             RUN mkdir c:\home
673                 RUN mklink /D c:\foo c:\home
674                 VOLUME ["c:/foo/bar"]
675                 ENTRYPOINT c:\windows\system32\cmd.exe`
676         }
677
678         buildCmd := exec.Command(dockerBinary, "build", "-t", name, "-")
679         buildCmd.Stdin = strings.NewReader(dfContents)
680         buildCmd.Dir = workingDirectory
681         err = buildCmd.Run()
682         if err != nil {
683                 c.Fatalf("could not build 'docker-test-volumesfromsymlinkpath': %v", err)
684         }
685
686         out, exitCode, err := dockerCmdWithError("run", "--name", "test-volumesfromsymlinkpath", name)
687         if err != nil || exitCode != 0 {
688                 c.Fatalf("[run] (volume) err: %v, exitcode: %d, out: %s", err, exitCode, out)
689         }
690
691         _, exitCode, err = dockerCmdWithError("run", "--volumes-from", "test-volumesfromsymlinkpath", "busybox", "sh", "-c", "ls "+prefix+"/foo | grep -q bar")
692         if err != nil || exitCode != 0 {
693                 c.Fatalf("[run] err: %v, exitcode: %d", err, exitCode)
694         }
695 }
696
697 func (s *DockerSuite) TestRunExitCode(c *check.C) {
698         var (
699                 exit int
700                 err  error
701         )
702
703         _, exit, err = dockerCmdWithError("run", "busybox", "/bin/sh", "-c", "exit 72")
704
705         if err == nil {
706                 c.Fatal("should not have a non nil error")
707         }
708         if exit != 72 {
709                 c.Fatalf("expected exit code 72 received %d", exit)
710         }
711 }
712
713 func (s *DockerSuite) TestRunUserDefaults(c *check.C) {
714         expected := "uid=0(root) gid=0(root)"
715         if testEnv.DaemonPlatform() == "windows" {
716                 expected = "uid=1000(ContainerAdministrator) gid=1000(ContainerAdministrator)"
717         }
718         out, _ := dockerCmd(c, "run", "busybox", "id")
719         if !strings.Contains(out, expected) {
720                 c.Fatalf("expected '%s' got %s", expected, out)
721         }
722 }
723
724 func (s *DockerSuite) TestRunUserByName(c *check.C) {
725         // TODO Windows: This test cannot run on a Windows daemon as Windows does
726         // not support the use of -u
727         testRequires(c, DaemonIsLinux)
728         out, _ := dockerCmd(c, "run", "-u", "root", "busybox", "id")
729         if !strings.Contains(out, "uid=0(root) gid=0(root)") {
730                 c.Fatalf("expected root user got %s", out)
731         }
732 }
733
734 func (s *DockerSuite) TestRunUserByID(c *check.C) {
735         // TODO Windows: This test cannot run on a Windows daemon as Windows does
736         // not support the use of -u
737         testRequires(c, DaemonIsLinux)
738         out, _ := dockerCmd(c, "run", "-u", "1", "busybox", "id")
739         if !strings.Contains(out, "uid=1(daemon) gid=1(daemon)") {
740                 c.Fatalf("expected daemon user got %s", out)
741         }
742 }
743
744 func (s *DockerSuite) TestRunUserByIDBig(c *check.C) {
745         // TODO Windows: This test cannot run on a Windows daemon as Windows does
746         // not support the use of -u
747         testRequires(c, DaemonIsLinux, NotArm)
748         out, _, err := dockerCmdWithError("run", "-u", "2147483648", "busybox", "id")
749         if err == nil {
750                 c.Fatal("No error, but must be.", out)
751         }
752         if !strings.Contains(strings.ToUpper(out), strings.ToUpper(libcontainerUser.ErrRange.Error())) {
753                 c.Fatalf("expected error about uids range, got %s", out)
754         }
755 }
756
757 func (s *DockerSuite) TestRunUserByIDNegative(c *check.C) {
758         // TODO Windows: This test cannot run on a Windows daemon as Windows does
759         // not support the use of -u
760         testRequires(c, DaemonIsLinux)
761         out, _, err := dockerCmdWithError("run", "-u", "-1", "busybox", "id")
762         if err == nil {
763                 c.Fatal("No error, but must be.", out)
764         }
765         if !strings.Contains(strings.ToUpper(out), strings.ToUpper(libcontainerUser.ErrRange.Error())) {
766                 c.Fatalf("expected error about uids range, got %s", out)
767         }
768 }
769
770 func (s *DockerSuite) TestRunUserByIDZero(c *check.C) {
771         // TODO Windows: This test cannot run on a Windows daemon as Windows does
772         // not support the use of -u
773         testRequires(c, DaemonIsLinux)
774         out, _, err := dockerCmdWithError("run", "-u", "0", "busybox", "id")
775         if err != nil {
776                 c.Fatal(err, out)
777         }
778         if !strings.Contains(out, "uid=0(root) gid=0(root) groups=10(wheel)") {
779                 c.Fatalf("expected daemon user got %s", out)
780         }
781 }
782
783 func (s *DockerSuite) TestRunUserNotFound(c *check.C) {
784         // TODO Windows: This test cannot run on a Windows daemon as Windows does
785         // not support the use of -u
786         testRequires(c, DaemonIsLinux)
787         _, _, err := dockerCmdWithError("run", "-u", "notme", "busybox", "id")
788         if err == nil {
789                 c.Fatal("unknown user should cause container to fail")
790         }
791 }
792
793 func (s *DockerSuite) TestRunTwoConcurrentContainers(c *check.C) {
794         sleepTime := "2"
795         group := sync.WaitGroup{}
796         group.Add(2)
797
798         errChan := make(chan error, 2)
799         for i := 0; i < 2; i++ {
800                 go func() {
801                         defer group.Done()
802                         _, _, err := dockerCmdWithError("run", "busybox", "sleep", sleepTime)
803                         errChan <- err
804                 }()
805         }
806
807         group.Wait()
808         close(errChan)
809
810         for err := range errChan {
811                 c.Assert(err, check.IsNil)
812         }
813 }
814
815 func (s *DockerSuite) TestRunEnvironment(c *check.C) {
816         // TODO Windows: Environment handling is different between Linux and
817         // Windows and this test relies currently on unix functionality.
818         testRequires(c, DaemonIsLinux)
819         result := icmd.RunCmd(icmd.Cmd{
820                 Command: []string{dockerBinary, "run", "-h", "testing", "-e=FALSE=true", "-e=TRUE", "-e=TRICKY", "-e=HOME=", "busybox", "env"},
821                 Env: append(os.Environ(),
822                         "TRUE=false",
823                         "TRICKY=tri\ncky\n",
824                 ),
825         })
826         result.Assert(c, icmd.Success)
827
828         actualEnv := strings.Split(strings.TrimSpace(result.Combined()), "\n")
829         sort.Strings(actualEnv)
830
831         goodEnv := []string{
832                 // The first two should not be tested here, those are "inherent" environment variable. This test validates
833                 // the -e behavior, not the default environment variable (that could be subject to change)
834                 "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
835                 "HOSTNAME=testing",
836                 "FALSE=true",
837                 "TRUE=false",
838                 "TRICKY=tri",
839                 "cky",
840                 "",
841                 "HOME=/root",
842         }
843         sort.Strings(goodEnv)
844         if len(goodEnv) != len(actualEnv) {
845                 c.Fatalf("Wrong environment: should be %d variables, not %d: %q", len(goodEnv), len(actualEnv), strings.Join(actualEnv, ", "))
846         }
847         for i := range goodEnv {
848                 if actualEnv[i] != goodEnv[i] {
849                         c.Fatalf("Wrong environment variable: should be %s, not %s", goodEnv[i], actualEnv[i])
850                 }
851         }
852 }
853
854 func (s *DockerSuite) TestRunEnvironmentErase(c *check.C) {
855         // TODO Windows: Environment handling is different between Linux and
856         // Windows and this test relies currently on unix functionality.
857         testRequires(c, DaemonIsLinux)
858
859         // Test to make sure that when we use -e on env vars that are
860         // not set in our local env that they're removed (if present) in
861         // the container
862
863         result := icmd.RunCmd(icmd.Cmd{
864                 Command: []string{dockerBinary, "run", "-e", "FOO", "-e", "HOSTNAME", "busybox", "env"},
865                 Env:     appendBaseEnv(true),
866         })
867         result.Assert(c, icmd.Success)
868
869         actualEnv := strings.Split(strings.TrimSpace(result.Combined()), "\n")
870         sort.Strings(actualEnv)
871
872         goodEnv := []string{
873                 "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
874                 "HOME=/root",
875         }
876         sort.Strings(goodEnv)
877         if len(goodEnv) != len(actualEnv) {
878                 c.Fatalf("Wrong environment: should be %d variables, not %d: %q", len(goodEnv), len(actualEnv), strings.Join(actualEnv, ", "))
879         }
880         for i := range goodEnv {
881                 if actualEnv[i] != goodEnv[i] {
882                         c.Fatalf("Wrong environment variable: should be %s, not %s", goodEnv[i], actualEnv[i])
883                 }
884         }
885 }
886
887 func (s *DockerSuite) TestRunEnvironmentOverride(c *check.C) {
888         // TODO Windows: Environment handling is different between Linux and
889         // Windows and this test relies currently on unix functionality.
890         testRequires(c, DaemonIsLinux)
891
892         // Test to make sure that when we use -e on env vars that are
893         // already in the env that we're overriding them
894
895         result := icmd.RunCmd(icmd.Cmd{
896                 Command: []string{dockerBinary, "run", "-e", "HOSTNAME", "-e", "HOME=/root2", "busybox", "env"},
897                 Env:     appendBaseEnv(true, "HOSTNAME=bar"),
898         })
899         result.Assert(c, icmd.Success)
900
901         actualEnv := strings.Split(strings.TrimSpace(result.Combined()), "\n")
902         sort.Strings(actualEnv)
903
904         goodEnv := []string{
905                 "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
906                 "HOME=/root2",
907                 "HOSTNAME=bar",
908         }
909         sort.Strings(goodEnv)
910         if len(goodEnv) != len(actualEnv) {
911                 c.Fatalf("Wrong environment: should be %d variables, not %d: %q", len(goodEnv), len(actualEnv), strings.Join(actualEnv, ", "))
912         }
913         for i := range goodEnv {
914                 if actualEnv[i] != goodEnv[i] {
915                         c.Fatalf("Wrong environment variable: should be %s, not %s", goodEnv[i], actualEnv[i])
916                 }
917         }
918 }
919
920 func (s *DockerSuite) TestRunContainerNetwork(c *check.C) {
921         if testEnv.DaemonPlatform() == "windows" {
922                 // Windows busybox does not have ping. Use built in ping instead.
923                 dockerCmd(c, "run", testEnv.MinimalBaseImage(), "ping", "-n", "1", "127.0.0.1")
924         } else {
925                 dockerCmd(c, "run", "busybox", "ping", "-c", "1", "127.0.0.1")
926         }
927 }
928
929 func (s *DockerSuite) TestRunNetHostNotAllowedWithLinks(c *check.C) {
930         // TODO Windows: This is Linux specific as --link is not supported and
931         // this will be deprecated in favor of container networking model.
932         testRequires(c, DaemonIsLinux, NotUserNamespace)
933         dockerCmd(c, "run", "--name", "linked", "busybox", "true")
934
935         _, _, err := dockerCmdWithError("run", "--net=host", "--link", "linked:linked", "busybox", "true")
936         if err == nil {
937                 c.Fatal("Expected error")
938         }
939 }
940
941 // #7851 hostname outside container shows FQDN, inside only shortname
942 // For testing purposes it is not required to set host's hostname directly
943 // and use "--net=host" (as the original issue submitter did), as the same
944 // codepath is executed with "docker run -h <hostname>".  Both were manually
945 // tested, but this testcase takes the simpler path of using "run -h .."
946 func (s *DockerSuite) TestRunFullHostnameSet(c *check.C) {
947         // TODO Windows: -h is not yet functional.
948         testRequires(c, DaemonIsLinux)
949         out, _ := dockerCmd(c, "run", "-h", "foo.bar.baz", "busybox", "hostname")
950         if actual := strings.Trim(out, "\r\n"); actual != "foo.bar.baz" {
951                 c.Fatalf("expected hostname 'foo.bar.baz', received %s", actual)
952         }
953 }
954
955 func (s *DockerSuite) TestRunPrivilegedCanMknod(c *check.C) {
956         // Not applicable for Windows as Windows daemon does not support
957         // the concept of --privileged, and mknod is a Unix concept.
958         testRequires(c, DaemonIsLinux, NotUserNamespace)
959         out, _ := dockerCmd(c, "run", "--privileged", "busybox", "sh", "-c", "mknod /tmp/sda b 8 0 && echo ok")
960         if actual := strings.Trim(out, "\r\n"); actual != "ok" {
961                 c.Fatalf("expected output ok received %s", actual)
962         }
963 }
964
965 func (s *DockerSuite) TestRunUnprivilegedCanMknod(c *check.C) {
966         // Not applicable for Windows as Windows daemon does not support
967         // the concept of --privileged, and mknod is a Unix concept.
968         testRequires(c, DaemonIsLinux, NotUserNamespace)
969         out, _ := dockerCmd(c, "run", "busybox", "sh", "-c", "mknod /tmp/sda b 8 0 && echo ok")
970         if actual := strings.Trim(out, "\r\n"); actual != "ok" {
971                 c.Fatalf("expected output ok received %s", actual)
972         }
973 }
974
975 func (s *DockerSuite) TestRunCapDropInvalid(c *check.C) {
976         // Not applicable for Windows as there is no concept of --cap-drop
977         testRequires(c, DaemonIsLinux)
978         out, _, err := dockerCmdWithError("run", "--cap-drop=CHPASS", "busybox", "ls")
979         if err == nil {
980                 c.Fatal(err, out)
981         }
982 }
983
984 func (s *DockerSuite) TestRunCapDropCannotMknod(c *check.C) {
985         // Not applicable for Windows as there is no concept of --cap-drop or mknod
986         testRequires(c, DaemonIsLinux)
987         out, _, err := dockerCmdWithError("run", "--cap-drop=MKNOD", "busybox", "sh", "-c", "mknod /tmp/sda b 8 0 && echo ok")
988
989         if err == nil {
990                 c.Fatal(err, out)
991         }
992         if actual := strings.Trim(out, "\r\n"); actual == "ok" {
993                 c.Fatalf("expected output not ok received %s", actual)
994         }
995 }
996
997 func (s *DockerSuite) TestRunCapDropCannotMknodLowerCase(c *check.C) {
998         // Not applicable for Windows as there is no concept of --cap-drop or mknod
999         testRequires(c, DaemonIsLinux)
1000         out, _, err := dockerCmdWithError("run", "--cap-drop=mknod", "busybox", "sh", "-c", "mknod /tmp/sda b 8 0 && echo ok")
1001
1002         if err == nil {
1003                 c.Fatal(err, out)
1004         }
1005         if actual := strings.Trim(out, "\r\n"); actual == "ok" {
1006                 c.Fatalf("expected output not ok received %s", actual)
1007         }
1008 }
1009
1010 func (s *DockerSuite) TestRunCapDropALLCannotMknod(c *check.C) {
1011         // Not applicable for Windows as there is no concept of --cap-drop or mknod
1012         testRequires(c, DaemonIsLinux)
1013         out, _, err := dockerCmdWithError("run", "--cap-drop=ALL", "--cap-add=SETGID", "busybox", "sh", "-c", "mknod /tmp/sda b 8 0 && echo ok")
1014         if err == nil {
1015                 c.Fatal(err, out)
1016         }
1017         if actual := strings.Trim(out, "\r\n"); actual == "ok" {
1018                 c.Fatalf("expected output not ok received %s", actual)
1019         }
1020 }
1021
1022 func (s *DockerSuite) TestRunCapDropALLAddMknodCanMknod(c *check.C) {
1023         // Not applicable for Windows as there is no concept of --cap-drop or mknod
1024         testRequires(c, DaemonIsLinux, NotUserNamespace)
1025         out, _ := dockerCmd(c, "run", "--cap-drop=ALL", "--cap-add=MKNOD", "--cap-add=SETGID", "busybox", "sh", "-c", "mknod /tmp/sda b 8 0 && echo ok")
1026
1027         if actual := strings.Trim(out, "\r\n"); actual != "ok" {
1028                 c.Fatalf("expected output ok received %s", actual)
1029         }
1030 }
1031
1032 func (s *DockerSuite) TestRunCapAddInvalid(c *check.C) {
1033         // Not applicable for Windows as there is no concept of --cap-add
1034         testRequires(c, DaemonIsLinux)
1035         out, _, err := dockerCmdWithError("run", "--cap-add=CHPASS", "busybox", "ls")
1036         if err == nil {
1037                 c.Fatal(err, out)
1038         }
1039 }
1040
1041 func (s *DockerSuite) TestRunCapAddCanDownInterface(c *check.C) {
1042         // Not applicable for Windows as there is no concept of --cap-add
1043         testRequires(c, DaemonIsLinux)
1044         out, _ := dockerCmd(c, "run", "--cap-add=NET_ADMIN", "busybox", "sh", "-c", "ip link set eth0 down && echo ok")
1045
1046         if actual := strings.Trim(out, "\r\n"); actual != "ok" {
1047                 c.Fatalf("expected output ok received %s", actual)
1048         }
1049 }
1050
1051 func (s *DockerSuite) TestRunCapAddALLCanDownInterface(c *check.C) {
1052         // Not applicable for Windows as there is no concept of --cap-add
1053         testRequires(c, DaemonIsLinux)
1054         out, _ := dockerCmd(c, "run", "--cap-add=ALL", "busybox", "sh", "-c", "ip link set eth0 down && echo ok")
1055
1056         if actual := strings.Trim(out, "\r\n"); actual != "ok" {
1057                 c.Fatalf("expected output ok received %s", actual)
1058         }
1059 }
1060
1061 func (s *DockerSuite) TestRunCapAddALLDropNetAdminCanDownInterface(c *check.C) {
1062         // Not applicable for Windows as there is no concept of --cap-add
1063         testRequires(c, DaemonIsLinux)
1064         out, _, err := dockerCmdWithError("run", "--cap-add=ALL", "--cap-drop=NET_ADMIN", "busybox", "sh", "-c", "ip link set eth0 down && echo ok")
1065         if err == nil {
1066                 c.Fatal(err, out)
1067         }
1068         if actual := strings.Trim(out, "\r\n"); actual == "ok" {
1069                 c.Fatalf("expected output not ok received %s", actual)
1070         }
1071 }
1072
1073 func (s *DockerSuite) TestRunGroupAdd(c *check.C) {
1074         // Not applicable for Windows as there is no concept of --group-add
1075         testRequires(c, DaemonIsLinux)
1076         out, _ := dockerCmd(c, "run", "--group-add=audio", "--group-add=staff", "--group-add=777", "busybox", "sh", "-c", "id")
1077
1078         groupsList := "uid=0(root) gid=0(root) groups=10(wheel),29(audio),50(staff),777"
1079         if actual := strings.Trim(out, "\r\n"); actual != groupsList {
1080                 c.Fatalf("expected output %s received %s", groupsList, actual)
1081         }
1082 }
1083
1084 func (s *DockerSuite) TestRunPrivilegedCanMount(c *check.C) {
1085         // Not applicable for Windows as there is no concept of --privileged
1086         testRequires(c, DaemonIsLinux, NotUserNamespace)
1087         out, _ := dockerCmd(c, "run", "--privileged", "busybox", "sh", "-c", "mount -t tmpfs none /tmp && echo ok")
1088
1089         if actual := strings.Trim(out, "\r\n"); actual != "ok" {
1090                 c.Fatalf("expected output ok received %s", actual)
1091         }
1092 }
1093
1094 func (s *DockerSuite) TestRunUnprivilegedCannotMount(c *check.C) {
1095         // Not applicable for Windows as there is no concept of unprivileged
1096         testRequires(c, DaemonIsLinux)
1097         out, _, err := dockerCmdWithError("run", "busybox", "sh", "-c", "mount -t tmpfs none /tmp && echo ok")
1098
1099         if err == nil {
1100                 c.Fatal(err, out)
1101         }
1102         if actual := strings.Trim(out, "\r\n"); actual == "ok" {
1103                 c.Fatalf("expected output not ok received %s", actual)
1104         }
1105 }
1106
1107 func (s *DockerSuite) TestRunSysNotWritableInNonPrivilegedContainers(c *check.C) {
1108         // Not applicable for Windows as there is no concept of unprivileged
1109         testRequires(c, DaemonIsLinux, NotArm)
1110         if _, code, err := dockerCmdWithError("run", "busybox", "touch", "/sys/kernel/profiling"); err == nil || code == 0 {
1111                 c.Fatal("sys should not be writable in a non privileged container")
1112         }
1113 }
1114
1115 func (s *DockerSuite) TestRunSysWritableInPrivilegedContainers(c *check.C) {
1116         // Not applicable for Windows as there is no concept of unprivileged
1117         testRequires(c, DaemonIsLinux, NotUserNamespace, NotArm)
1118         if _, code, err := dockerCmdWithError("run", "--privileged", "busybox", "touch", "/sys/kernel/profiling"); err != nil || code != 0 {
1119                 c.Fatalf("sys should be writable in privileged container")
1120         }
1121 }
1122
1123 func (s *DockerSuite) TestRunProcNotWritableInNonPrivilegedContainers(c *check.C) {
1124         // Not applicable for Windows as there is no concept of unprivileged
1125         testRequires(c, DaemonIsLinux)
1126         if _, code, err := dockerCmdWithError("run", "busybox", "touch", "/proc/sysrq-trigger"); err == nil || code == 0 {
1127                 c.Fatal("proc should not be writable in a non privileged container")
1128         }
1129 }
1130
1131 func (s *DockerSuite) TestRunProcWritableInPrivilegedContainers(c *check.C) {
1132         // Not applicable for Windows as there is no concept of --privileged
1133         testRequires(c, DaemonIsLinux, NotUserNamespace)
1134         if _, code := dockerCmd(c, "run", "--privileged", "busybox", "sh", "-c", "touch /proc/sysrq-trigger"); code != 0 {
1135                 c.Fatalf("proc should be writable in privileged container")
1136         }
1137 }
1138
1139 func (s *DockerSuite) TestRunDeviceNumbers(c *check.C) {
1140         // Not applicable on Windows as /dev/ is a Unix specific concept
1141         // TODO: NotUserNamespace could be removed here if "root" "root" is replaced w user
1142         testRequires(c, DaemonIsLinux, NotUserNamespace)
1143         out, _ := dockerCmd(c, "run", "busybox", "sh", "-c", "ls -l /dev/null")
1144         deviceLineFields := strings.Fields(out)
1145         deviceLineFields[6] = ""
1146         deviceLineFields[7] = ""
1147         deviceLineFields[8] = ""
1148         expected := []string{"crw-rw-rw-", "1", "root", "root", "1,", "3", "", "", "", "/dev/null"}
1149
1150         if !(reflect.DeepEqual(deviceLineFields, expected)) {
1151                 c.Fatalf("expected output\ncrw-rw-rw- 1 root root 1, 3 May 24 13:29 /dev/null\n received\n %s\n", out)
1152         }
1153 }
1154
1155 func (s *DockerSuite) TestRunThatCharacterDevicesActLikeCharacterDevices(c *check.C) {
1156         // Not applicable on Windows as /dev/ is a Unix specific concept
1157         testRequires(c, DaemonIsLinux)
1158         out, _ := dockerCmd(c, "run", "busybox", "sh", "-c", "dd if=/dev/zero of=/zero bs=1k count=5 2> /dev/null ; du -h /zero")
1159         if actual := strings.Trim(out, "\r\n"); actual[0] == '0' {
1160                 c.Fatalf("expected a new file called /zero to be create that is greater than 0 bytes long, but du says: %s", actual)
1161         }
1162 }
1163
1164 func (s *DockerSuite) TestRunUnprivilegedWithChroot(c *check.C) {
1165         // Not applicable on Windows as it does not support chroot
1166         testRequires(c, DaemonIsLinux)
1167         dockerCmd(c, "run", "busybox", "chroot", "/", "true")
1168 }
1169
1170 func (s *DockerSuite) TestRunAddingOptionalDevices(c *check.C) {
1171         // Not applicable on Windows as Windows does not support --device
1172         testRequires(c, DaemonIsLinux, NotUserNamespace)
1173         out, _ := dockerCmd(c, "run", "--device", "/dev/zero:/dev/nulo", "busybox", "sh", "-c", "ls /dev/nulo")
1174         if actual := strings.Trim(out, "\r\n"); actual != "/dev/nulo" {
1175                 c.Fatalf("expected output /dev/nulo, received %s", actual)
1176         }
1177 }
1178
1179 func (s *DockerSuite) TestRunAddingOptionalDevicesNoSrc(c *check.C) {
1180         // Not applicable on Windows as Windows does not support --device
1181         testRequires(c, DaemonIsLinux, NotUserNamespace)
1182         out, _ := dockerCmd(c, "run", "--device", "/dev/zero:rw", "busybox", "sh", "-c", "ls /dev/zero")
1183         if actual := strings.Trim(out, "\r\n"); actual != "/dev/zero" {
1184                 c.Fatalf("expected output /dev/zero, received %s", actual)
1185         }
1186 }
1187
1188 func (s *DockerSuite) TestRunAddingOptionalDevicesInvalidMode(c *check.C) {
1189         // Not applicable on Windows as Windows does not support --device
1190         testRequires(c, DaemonIsLinux, NotUserNamespace)
1191         _, _, err := dockerCmdWithError("run", "--device", "/dev/zero:ro", "busybox", "sh", "-c", "ls /dev/zero")
1192         if err == nil {
1193                 c.Fatalf("run container with device mode ro should fail")
1194         }
1195 }
1196
1197 func (s *DockerSuite) TestRunModeHostname(c *check.C) {
1198         // Not applicable on Windows as Windows does not support -h
1199         testRequires(c, SameHostDaemon, DaemonIsLinux, NotUserNamespace)
1200
1201         out, _ := dockerCmd(c, "run", "-h=testhostname", "busybox", "cat", "/etc/hostname")
1202
1203         if actual := strings.Trim(out, "\r\n"); actual != "testhostname" {
1204                 c.Fatalf("expected 'testhostname', but says: %q", actual)
1205         }
1206
1207         out, _ = dockerCmd(c, "run", "--net=host", "busybox", "cat", "/etc/hostname")
1208
1209         hostname, err := os.Hostname()
1210         if err != nil {
1211                 c.Fatal(err)
1212         }
1213         if actual := strings.Trim(out, "\r\n"); actual != hostname {
1214                 c.Fatalf("expected %q, but says: %q", hostname, actual)
1215         }
1216 }
1217
1218 func (s *DockerSuite) TestRunRootWorkdir(c *check.C) {
1219         out, _ := dockerCmd(c, "run", "--workdir", "/", "busybox", "pwd")
1220         expected := "/\n"
1221         if testEnv.DaemonPlatform() == "windows" {
1222                 expected = "C:" + expected
1223         }
1224         if out != expected {
1225                 c.Fatalf("pwd returned %q (expected %s)", s, expected)
1226         }
1227 }
1228
1229 func (s *DockerSuite) TestRunAllowBindMountingRoot(c *check.C) {
1230         if testEnv.DaemonPlatform() == "windows" {
1231                 // Windows busybox will fail with Permission Denied on items such as pagefile.sys
1232                 dockerCmd(c, "run", "-v", `c:\:c:\host`, testEnv.MinimalBaseImage(), "cmd", "-c", "dir", `c:\host`)
1233         } else {
1234                 dockerCmd(c, "run", "-v", "/:/host", "busybox", "ls", "/host")
1235         }
1236 }
1237
1238 func (s *DockerSuite) TestRunDisallowBindMountingRootToRoot(c *check.C) {
1239         mount := "/:/"
1240         targetDir := "/host"
1241         if testEnv.DaemonPlatform() == "windows" {
1242                 mount = `c:\:c\`
1243                 targetDir = "c:/host" // Forward slash as using busybox
1244         }
1245         out, _, err := dockerCmdWithError("run", "-v", mount, "busybox", "ls", targetDir)
1246         if err == nil {
1247                 c.Fatal(out, err)
1248         }
1249 }
1250
1251 // Verify that a container gets default DNS when only localhost resolvers exist
1252 func (s *DockerSuite) TestRunDNSDefaultOptions(c *check.C) {
1253         // Not applicable on Windows as this is testing Unix specific functionality
1254         testRequires(c, SameHostDaemon, DaemonIsLinux)
1255
1256         // preserve original resolv.conf for restoring after test
1257         origResolvConf, err := ioutil.ReadFile("/etc/resolv.conf")
1258         if os.IsNotExist(err) {
1259                 c.Fatalf("/etc/resolv.conf does not exist")
1260         }
1261         // defer restored original conf
1262         defer func() {
1263                 if err := ioutil.WriteFile("/etc/resolv.conf", origResolvConf, 0644); err != nil {
1264                         c.Fatal(err)
1265                 }
1266         }()
1267
1268         // test 3 cases: standard IPv4 localhost, commented out localhost, and IPv6 localhost
1269         // 2 are removed from the file at container start, and the 3rd (commented out) one is ignored by
1270         // GetNameservers(), leading to a replacement of nameservers with the default set
1271         tmpResolvConf := []byte("nameserver 127.0.0.1\n#nameserver 127.0.2.1\nnameserver ::1")
1272         if err := ioutil.WriteFile("/etc/resolv.conf", tmpResolvConf, 0644); err != nil {
1273                 c.Fatal(err)
1274         }
1275
1276         actual, _ := dockerCmd(c, "run", "busybox", "cat", "/etc/resolv.conf")
1277         // check that the actual defaults are appended to the commented out
1278         // localhost resolver (which should be preserved)
1279         // NOTE: if we ever change the defaults from google dns, this will break
1280         expected := "#nameserver 127.0.2.1\n\nnameserver 8.8.8.8\nnameserver 8.8.4.4\n"
1281         if actual != expected {
1282                 c.Fatalf("expected resolv.conf be: %q, but was: %q", expected, actual)
1283         }
1284 }
1285
1286 func (s *DockerSuite) TestRunDNSOptions(c *check.C) {
1287         // Not applicable on Windows as Windows does not support --dns*, or
1288         // the Unix-specific functionality of resolv.conf.
1289         testRequires(c, DaemonIsLinux)
1290         result := cli.DockerCmd(c, "run", "--dns=127.0.0.1", "--dns-search=mydomain", "--dns-opt=ndots:9", "busybox", "cat", "/etc/resolv.conf")
1291
1292         // The client will get a warning on stderr when setting DNS to a localhost address; verify this:
1293         if !strings.Contains(result.Stderr(), "Localhost DNS setting") {
1294                 c.Fatalf("Expected warning on stderr about localhost resolver, but got %q", result.Stderr())
1295         }
1296
1297         actual := strings.Replace(strings.Trim(result.Stdout(), "\r\n"), "\n", " ", -1)
1298         if actual != "search mydomain nameserver 127.0.0.1 options ndots:9" {
1299                 c.Fatalf("expected 'search mydomain nameserver 127.0.0.1 options ndots:9', but says: %q", actual)
1300         }
1301
1302         out := cli.DockerCmd(c, "run", "--dns=1.1.1.1", "--dns-search=.", "--dns-opt=ndots:3", "busybox", "cat", "/etc/resolv.conf").Combined()
1303
1304         actual = strings.Replace(strings.Trim(strings.Trim(out, "\r\n"), " "), "\n", " ", -1)
1305         if actual != "nameserver 1.1.1.1 options ndots:3" {
1306                 c.Fatalf("expected 'nameserver 1.1.1.1 options ndots:3', but says: %q", actual)
1307         }
1308 }
1309
1310 func (s *DockerSuite) TestRunDNSRepeatOptions(c *check.C) {
1311         testRequires(c, DaemonIsLinux)
1312         out := cli.DockerCmd(c, "run", "--dns=1.1.1.1", "--dns=2.2.2.2", "--dns-search=mydomain", "--dns-search=mydomain2", "--dns-opt=ndots:9", "--dns-opt=timeout:3", "busybox", "cat", "/etc/resolv.conf").Stdout()
1313
1314         actual := strings.Replace(strings.Trim(out, "\r\n"), "\n", " ", -1)
1315         if actual != "search mydomain mydomain2 nameserver 1.1.1.1 nameserver 2.2.2.2 options ndots:9 timeout:3" {
1316                 c.Fatalf("expected 'search mydomain mydomain2 nameserver 1.1.1.1 nameserver 2.2.2.2 options ndots:9 timeout:3', but says: %q", actual)
1317         }
1318 }
1319
1320 func (s *DockerSuite) TestRunDNSOptionsBasedOnHostResolvConf(c *check.C) {
1321         // Not applicable on Windows as testing Unix specific functionality
1322         testRequires(c, SameHostDaemon, DaemonIsLinux)
1323
1324         origResolvConf, err := ioutil.ReadFile("/etc/resolv.conf")
1325         if os.IsNotExist(err) {
1326                 c.Fatalf("/etc/resolv.conf does not exist")
1327         }
1328
1329         hostNameservers := resolvconf.GetNameservers(origResolvConf, types.IP)
1330         hostSearch := resolvconf.GetSearchDomains(origResolvConf)
1331
1332         var out string
1333         out, _ = dockerCmd(c, "run", "--dns=127.0.0.1", "busybox", "cat", "/etc/resolv.conf")
1334
1335         if actualNameservers := resolvconf.GetNameservers([]byte(out), types.IP); string(actualNameservers[0]) != "127.0.0.1" {
1336                 c.Fatalf("expected '127.0.0.1', but says: %q", string(actualNameservers[0]))
1337         }
1338
1339         actualSearch := resolvconf.GetSearchDomains([]byte(out))
1340         if len(actualSearch) != len(hostSearch) {
1341                 c.Fatalf("expected %q search domain(s), but it has: %q", len(hostSearch), len(actualSearch))
1342         }
1343         for i := range actualSearch {
1344                 if actualSearch[i] != hostSearch[i] {
1345                         c.Fatalf("expected %q domain, but says: %q", actualSearch[i], hostSearch[i])
1346                 }
1347         }
1348
1349         out, _ = dockerCmd(c, "run", "--dns-search=mydomain", "busybox", "cat", "/etc/resolv.conf")
1350
1351         actualNameservers := resolvconf.GetNameservers([]byte(out), types.IP)
1352         if len(actualNameservers) != len(hostNameservers) {
1353                 c.Fatalf("expected %q nameserver(s), but it has: %q", len(hostNameservers), len(actualNameservers))
1354         }
1355         for i := range actualNameservers {
1356                 if actualNameservers[i] != hostNameservers[i] {
1357                         c.Fatalf("expected %q nameserver, but says: %q", actualNameservers[i], hostNameservers[i])
1358                 }
1359         }
1360
1361         if actualSearch = resolvconf.GetSearchDomains([]byte(out)); string(actualSearch[0]) != "mydomain" {
1362                 c.Fatalf("expected 'mydomain', but says: %q", string(actualSearch[0]))
1363         }
1364
1365         // test with file
1366         tmpResolvConf := []byte("search example.com\nnameserver 12.34.56.78\nnameserver 127.0.0.1")
1367         if err := ioutil.WriteFile("/etc/resolv.conf", tmpResolvConf, 0644); err != nil {
1368                 c.Fatal(err)
1369         }
1370         // put the old resolvconf back
1371         defer func() {
1372                 if err := ioutil.WriteFile("/etc/resolv.conf", origResolvConf, 0644); err != nil {
1373                         c.Fatal(err)
1374                 }
1375         }()
1376
1377         resolvConf, err := ioutil.ReadFile("/etc/resolv.conf")
1378         if os.IsNotExist(err) {
1379                 c.Fatalf("/etc/resolv.conf does not exist")
1380         }
1381
1382         hostSearch = resolvconf.GetSearchDomains(resolvConf)
1383
1384         out, _ = dockerCmd(c, "run", "busybox", "cat", "/etc/resolv.conf")
1385         if actualNameservers = resolvconf.GetNameservers([]byte(out), types.IP); string(actualNameservers[0]) != "12.34.56.78" || len(actualNameservers) != 1 {
1386                 c.Fatalf("expected '12.34.56.78', but has: %v", actualNameservers)
1387         }
1388
1389         actualSearch = resolvconf.GetSearchDomains([]byte(out))
1390         if len(actualSearch) != len(hostSearch) {
1391                 c.Fatalf("expected %q search domain(s), but it has: %q", len(hostSearch), len(actualSearch))
1392         }
1393         for i := range actualSearch {
1394                 if actualSearch[i] != hostSearch[i] {
1395                         c.Fatalf("expected %q domain, but says: %q", actualSearch[i], hostSearch[i])
1396                 }
1397         }
1398 }
1399
1400 // Test to see if a non-root user can resolve a DNS name. Also
1401 // check if the container resolv.conf file has at least 0644 perm.
1402 func (s *DockerSuite) TestRunNonRootUserResolvName(c *check.C) {
1403         // Not applicable on Windows as Windows does not support --user
1404         testRequires(c, SameHostDaemon, Network, DaemonIsLinux, NotArm)
1405
1406         dockerCmd(c, "run", "--name=testperm", "--user=nobody", "busybox", "nslookup", "apt.dockerproject.org")
1407
1408         cID := getIDByName(c, "testperm")
1409
1410         fmode := (os.FileMode)(0644)
1411         finfo, err := os.Stat(containerStorageFile(cID, "resolv.conf"))
1412         if err != nil {
1413                 c.Fatal(err)
1414         }
1415
1416         if (finfo.Mode() & fmode) != fmode {
1417                 c.Fatalf("Expected container resolv.conf mode to be at least %s, instead got %s", fmode.String(), finfo.Mode().String())
1418         }
1419 }
1420
1421 // Test if container resolv.conf gets updated the next time it restarts
1422 // if host /etc/resolv.conf has changed. This only applies if the container
1423 // uses the host's /etc/resolv.conf and does not have any dns options provided.
1424 func (s *DockerSuite) TestRunResolvconfUpdate(c *check.C) {
1425         // Not applicable on Windows as testing unix specific functionality
1426         testRequires(c, SameHostDaemon, DaemonIsLinux)
1427         c.Skip("Unstable test, to be re-activated once #19937 is resolved")
1428
1429         tmpResolvConf := []byte("search pommesfrites.fr\nnameserver 12.34.56.78\n")
1430         tmpLocalhostResolvConf := []byte("nameserver 127.0.0.1")
1431
1432         //take a copy of resolv.conf for restoring after test completes
1433         resolvConfSystem, err := ioutil.ReadFile("/etc/resolv.conf")
1434         if err != nil {
1435                 c.Fatal(err)
1436         }
1437
1438         // This test case is meant to test monitoring resolv.conf when it is
1439         // a regular file not a bind mounc. So we unmount resolv.conf and replace
1440         // it with a file containing the original settings.
1441         mounted, err := mount.Mounted("/etc/resolv.conf")
1442         if err != nil {
1443                 c.Fatal(err)
1444         }
1445         if mounted {
1446                 icmd.RunCommand("umount", "/etc/resolv.conf").Assert(c, icmd.Success)
1447         }
1448
1449         //cleanup
1450         defer func() {
1451                 if err := ioutil.WriteFile("/etc/resolv.conf", resolvConfSystem, 0644); err != nil {
1452                         c.Fatal(err)
1453                 }
1454         }()
1455
1456         //1. test that a restarting container gets an updated resolv.conf
1457         dockerCmd(c, "run", "--name=first", "busybox", "true")
1458         containerID1 := getIDByName(c, "first")
1459
1460         // replace resolv.conf with our temporary copy
1461         bytesResolvConf := []byte(tmpResolvConf)
1462         if err := ioutil.WriteFile("/etc/resolv.conf", bytesResolvConf, 0644); err != nil {
1463                 c.Fatal(err)
1464         }
1465
1466         // start the container again to pickup changes
1467         dockerCmd(c, "start", "first")
1468
1469         // check for update in container
1470         containerResolv := readContainerFile(c, containerID1, "resolv.conf")
1471         if !bytes.Equal(containerResolv, bytesResolvConf) {
1472                 c.Fatalf("Restarted container does not have updated resolv.conf; expected %q, got %q", tmpResolvConf, string(containerResolv))
1473         }
1474
1475         /*      //make a change to resolv.conf (in this case replacing our tmp copy with orig copy)
1476                 if err := ioutil.WriteFile("/etc/resolv.conf", resolvConfSystem, 0644); err != nil {
1477                                                 c.Fatal(err)
1478                                                                 } */
1479         //2. test that a restarting container does not receive resolv.conf updates
1480         //   if it modified the container copy of the starting point resolv.conf
1481         dockerCmd(c, "run", "--name=second", "busybox", "sh", "-c", "echo 'search mylittlepony.com' >>/etc/resolv.conf")
1482         containerID2 := getIDByName(c, "second")
1483
1484         //make a change to resolv.conf (in this case replacing our tmp copy with orig copy)
1485         if err := ioutil.WriteFile("/etc/resolv.conf", resolvConfSystem, 0644); err != nil {
1486                 c.Fatal(err)
1487         }
1488
1489         // start the container again
1490         dockerCmd(c, "start", "second")
1491
1492         // check for update in container
1493         containerResolv = readContainerFile(c, containerID2, "resolv.conf")
1494         if bytes.Equal(containerResolv, resolvConfSystem) {
1495                 c.Fatalf("Container's resolv.conf should not have been updated with host resolv.conf: %q", string(containerResolv))
1496         }
1497
1498         //3. test that a running container's resolv.conf is not modified while running
1499         out, _ := dockerCmd(c, "run", "-d", "busybox", "top")
1500         runningContainerID := strings.TrimSpace(out)
1501
1502         // replace resolv.conf
1503         if err := ioutil.WriteFile("/etc/resolv.conf", bytesResolvConf, 0644); err != nil {
1504                 c.Fatal(err)
1505         }
1506
1507         // check for update in container
1508         containerResolv = readContainerFile(c, runningContainerID, "resolv.conf")
1509         if bytes.Equal(containerResolv, bytesResolvConf) {
1510                 c.Fatalf("Running container should not have updated resolv.conf; expected %q, got %q", string(resolvConfSystem), string(containerResolv))
1511         }
1512
1513         //4. test that a running container's resolv.conf is updated upon restart
1514         //   (the above container is still running..)
1515         dockerCmd(c, "restart", runningContainerID)
1516
1517         // check for update in container
1518         containerResolv = readContainerFile(c, runningContainerID, "resolv.conf")
1519         if !bytes.Equal(containerResolv, bytesResolvConf) {
1520                 c.Fatalf("Restarted container should have updated resolv.conf; expected %q, got %q", string(bytesResolvConf), string(containerResolv))
1521         }
1522
1523         //5. test that additions of a localhost resolver are cleaned from
1524         //   host resolv.conf before updating container's resolv.conf copies
1525
1526         // replace resolv.conf with a localhost-only nameserver copy
1527         bytesResolvConf = []byte(tmpLocalhostResolvConf)
1528         if err = ioutil.WriteFile("/etc/resolv.conf", bytesResolvConf, 0644); err != nil {
1529                 c.Fatal(err)
1530         }
1531
1532         // start the container again to pickup changes
1533         dockerCmd(c, "start", "first")
1534
1535         // our first exited container ID should have been updated, but with default DNS
1536         // after the cleanup of resolv.conf found only a localhost nameserver:
1537         containerResolv = readContainerFile(c, containerID1, "resolv.conf")
1538         expected := "\nnameserver 8.8.8.8\nnameserver 8.8.4.4\n"
1539         if !bytes.Equal(containerResolv, []byte(expected)) {
1540                 c.Fatalf("Container does not have cleaned/replaced DNS in resolv.conf; expected %q, got %q", expected, string(containerResolv))
1541         }
1542
1543         //6. Test that replacing (as opposed to modifying) resolv.conf triggers an update
1544         //   of containers' resolv.conf.
1545
1546         // Restore the original resolv.conf
1547         if err := ioutil.WriteFile("/etc/resolv.conf", resolvConfSystem, 0644); err != nil {
1548                 c.Fatal(err)
1549         }
1550
1551         // Run the container so it picks up the old settings
1552         dockerCmd(c, "run", "--name=third", "busybox", "true")
1553         containerID3 := getIDByName(c, "third")
1554
1555         // Create a modified resolv.conf.aside and override resolv.conf with it
1556         bytesResolvConf = []byte(tmpResolvConf)
1557         if err := ioutil.WriteFile("/etc/resolv.conf.aside", bytesResolvConf, 0644); err != nil {
1558                 c.Fatal(err)
1559         }
1560
1561         err = os.Rename("/etc/resolv.conf.aside", "/etc/resolv.conf")
1562         if err != nil {
1563                 c.Fatal(err)
1564         }
1565
1566         // start the container again to pickup changes
1567         dockerCmd(c, "start", "third")
1568
1569         // check for update in container
1570         containerResolv = readContainerFile(c, containerID3, "resolv.conf")
1571         if !bytes.Equal(containerResolv, bytesResolvConf) {
1572                 c.Fatalf("Stopped container does not have updated resolv.conf; expected\n%q\n got\n%q", tmpResolvConf, string(containerResolv))
1573         }
1574
1575         //cleanup, restore original resolv.conf happens in defer func()
1576 }
1577
1578 func (s *DockerSuite) TestRunAddHost(c *check.C) {
1579         // Not applicable on Windows as it does not support --add-host
1580         testRequires(c, DaemonIsLinux)
1581         out, _ := dockerCmd(c, "run", "--add-host=extra:86.75.30.9", "busybox", "grep", "extra", "/etc/hosts")
1582
1583         actual := strings.Trim(out, "\r\n")
1584         if actual != "86.75.30.9\textra" {
1585                 c.Fatalf("expected '86.75.30.9\textra', but says: %q", actual)
1586         }
1587 }
1588
1589 // Regression test for #6983
1590 func (s *DockerSuite) TestRunAttachStdErrOnlyTTYMode(c *check.C) {
1591         _, exitCode := dockerCmd(c, "run", "-t", "-a", "stderr", "busybox", "true")
1592         if exitCode != 0 {
1593                 c.Fatalf("Container should have exited with error code 0")
1594         }
1595 }
1596
1597 // Regression test for #6983
1598 func (s *DockerSuite) TestRunAttachStdOutOnlyTTYMode(c *check.C) {
1599         _, exitCode := dockerCmd(c, "run", "-t", "-a", "stdout", "busybox", "true")
1600         if exitCode != 0 {
1601                 c.Fatalf("Container should have exited with error code 0")
1602         }
1603 }
1604
1605 // Regression test for #6983
1606 func (s *DockerSuite) TestRunAttachStdOutAndErrTTYMode(c *check.C) {
1607         _, exitCode := dockerCmd(c, "run", "-t", "-a", "stdout", "-a", "stderr", "busybox", "true")
1608         if exitCode != 0 {
1609                 c.Fatalf("Container should have exited with error code 0")
1610         }
1611 }
1612
1613 // Test for #10388 - this will run the same test as TestRunAttachStdOutAndErrTTYMode
1614 // but using --attach instead of -a to make sure we read the flag correctly
1615 func (s *DockerSuite) TestRunAttachWithDetach(c *check.C) {
1616         icmd.RunCommand(dockerBinary, "run", "-d", "--attach", "stdout", "busybox", "true").Assert(c, icmd.Expected{
1617                 ExitCode: 1,
1618                 Error:    "exit status 1",
1619                 Err:      "Conflicting options: -a and -d",
1620         })
1621 }
1622
1623 func (s *DockerSuite) TestRunState(c *check.C) {
1624         // TODO Windows: This needs some rework as Windows busybox does not support top
1625         testRequires(c, DaemonIsLinux)
1626         out, _ := dockerCmd(c, "run", "-d", "busybox", "top")
1627
1628         id := strings.TrimSpace(out)
1629         state := inspectField(c, id, "State.Running")
1630         if state != "true" {
1631                 c.Fatal("Container state is 'not running'")
1632         }
1633         pid1 := inspectField(c, id, "State.Pid")
1634         if pid1 == "0" {
1635                 c.Fatal("Container state Pid 0")
1636         }
1637
1638         dockerCmd(c, "stop", id)
1639         state = inspectField(c, id, "State.Running")
1640         if state != "false" {
1641                 c.Fatal("Container state is 'running'")
1642         }
1643         pid2 := inspectField(c, id, "State.Pid")
1644         if pid2 == pid1 {
1645                 c.Fatalf("Container state Pid %s, but expected %s", pid2, pid1)
1646         }
1647
1648         dockerCmd(c, "start", id)
1649         state = inspectField(c, id, "State.Running")
1650         if state != "true" {
1651                 c.Fatal("Container state is 'not running'")
1652         }
1653         pid3 := inspectField(c, id, "State.Pid")
1654         if pid3 == pid1 {
1655                 c.Fatalf("Container state Pid %s, but expected %s", pid2, pid1)
1656         }
1657 }
1658
1659 // Test for #1737
1660 func (s *DockerSuite) TestRunCopyVolumeUIDGID(c *check.C) {
1661         // Not applicable on Windows as it does not support uid or gid in this way
1662         testRequires(c, DaemonIsLinux)
1663         name := "testrunvolumesuidgid"
1664         buildImageSuccessfully(c, name, build.WithDockerfile(`FROM busybox
1665                 RUN echo 'dockerio:x:1001:1001::/bin:/bin/false' >> /etc/passwd
1666                 RUN echo 'dockerio:x:1001:' >> /etc/group
1667                 RUN mkdir -p /hello && touch /hello/test && chown dockerio.dockerio /hello`))
1668
1669         // Test that the uid and gid is copied from the image to the volume
1670         out, _ := dockerCmd(c, "run", "--rm", "-v", "/hello", name, "sh", "-c", "ls -l / | grep hello | awk '{print $3\":\"$4}'")
1671         out = strings.TrimSpace(out)
1672         if out != "dockerio:dockerio" {
1673                 c.Fatalf("Wrong /hello ownership: %s, expected dockerio:dockerio", out)
1674         }
1675 }
1676
1677 // Test for #1582
1678 func (s *DockerSuite) TestRunCopyVolumeContent(c *check.C) {
1679         // TODO Windows, post RS1. Windows does not yet support volume functionality
1680         // that copies from the image to the volume.
1681         testRequires(c, DaemonIsLinux)
1682         name := "testruncopyvolumecontent"
1683         buildImageSuccessfully(c, name, build.WithDockerfile(`FROM busybox
1684                 RUN mkdir -p /hello/local && echo hello > /hello/local/world`))
1685
1686         // Test that the content is copied from the image to the volume
1687         out, _ := dockerCmd(c, "run", "--rm", "-v", "/hello", name, "find", "/hello")
1688         if !(strings.Contains(out, "/hello/local/world") && strings.Contains(out, "/hello/local")) {
1689                 c.Fatal("Container failed to transfer content to volume")
1690         }
1691 }
1692
1693 func (s *DockerSuite) TestRunCleanupCmdOnEntrypoint(c *check.C) {
1694         name := "testrunmdcleanuponentrypoint"
1695         buildImageSuccessfully(c, name, build.WithDockerfile(`FROM busybox
1696                 ENTRYPOINT ["echo"]
1697                 CMD ["testingpoint"]`))
1698
1699         out, exit := dockerCmd(c, "run", "--entrypoint", "whoami", name)
1700         if exit != 0 {
1701                 c.Fatalf("expected exit code 0 received %d, out: %q", exit, out)
1702         }
1703         out = strings.TrimSpace(out)
1704         expected := "root"
1705         if testEnv.DaemonPlatform() == "windows" {
1706                 if strings.Contains(testEnv.MinimalBaseImage(), "windowsservercore") {
1707                         expected = `user manager\containeradministrator`
1708                 } else {
1709                         expected = `ContainerAdministrator` // nanoserver
1710                 }
1711         }
1712         if out != expected {
1713                 c.Fatalf("Expected output %s, got %q. %s", expected, out, testEnv.MinimalBaseImage())
1714         }
1715 }
1716
1717 // TestRunWorkdirExistsAndIsFile checks that if 'docker run -w' with existing file can be detected
1718 func (s *DockerSuite) TestRunWorkdirExistsAndIsFile(c *check.C) {
1719         existingFile := "/bin/cat"
1720         expected := "not a directory"
1721         if testEnv.DaemonPlatform() == "windows" {
1722                 existingFile = `\windows\system32\ntdll.dll`
1723                 expected = `The directory name is invalid.`
1724         }
1725
1726         out, exitCode, err := dockerCmdWithError("run", "-w", existingFile, "busybox")
1727         if !(err != nil && exitCode == 125 && strings.Contains(out, expected)) {
1728                 c.Fatalf("Existing binary as a directory should error out with exitCode 125; we got: %s, exitCode: %d", out, exitCode)
1729         }
1730 }
1731
1732 func (s *DockerSuite) TestRunExitOnStdinClose(c *check.C) {
1733         name := "testrunexitonstdinclose"
1734
1735         meow := "/bin/cat"
1736         delay := 60
1737         if testEnv.DaemonPlatform() == "windows" {
1738                 meow = "cat"
1739         }
1740         runCmd := exec.Command(dockerBinary, "run", "--name", name, "-i", "busybox", meow)
1741
1742         stdin, err := runCmd.StdinPipe()
1743         if err != nil {
1744                 c.Fatal(err)
1745         }
1746         stdout, err := runCmd.StdoutPipe()
1747         if err != nil {
1748                 c.Fatal(err)
1749         }
1750
1751         if err := runCmd.Start(); err != nil {
1752                 c.Fatal(err)
1753         }
1754         if _, err := stdin.Write([]byte("hello\n")); err != nil {
1755                 c.Fatal(err)
1756         }
1757
1758         r := bufio.NewReader(stdout)
1759         line, err := r.ReadString('\n')
1760         if err != nil {
1761                 c.Fatal(err)
1762         }
1763         line = strings.TrimSpace(line)
1764         if line != "hello" {
1765                 c.Fatalf("Output should be 'hello', got '%q'", line)
1766         }
1767         if err := stdin.Close(); err != nil {
1768                 c.Fatal(err)
1769         }
1770         finish := make(chan error)
1771         go func() {
1772                 finish <- runCmd.Wait()
1773                 close(finish)
1774         }()
1775         select {
1776         case err := <-finish:
1777                 c.Assert(err, check.IsNil)
1778         case <-time.After(time.Duration(delay) * time.Second):
1779                 c.Fatal("docker run failed to exit on stdin close")
1780         }
1781         state := inspectField(c, name, "State.Running")
1782
1783         if state != "false" {
1784                 c.Fatal("Container must be stopped after stdin closing")
1785         }
1786 }
1787
1788 // Test run -i --restart xxx doesn't hang
1789 func (s *DockerSuite) TestRunInteractiveWithRestartPolicy(c *check.C) {
1790         name := "test-inter-restart"
1791
1792         result := icmd.StartCmd(icmd.Cmd{
1793                 Command: []string{dockerBinary, "run", "-i", "--name", name, "--restart=always", "busybox", "sh"},
1794                 Stdin:   bytes.NewBufferString("exit 11"),
1795         })
1796         c.Assert(result.Error, checker.IsNil)
1797         defer func() {
1798                 dockerCmdWithResult("stop", name).Assert(c, icmd.Success)
1799         }()
1800
1801         result = icmd.WaitOnCmd(60*time.Second, result)
1802         c.Assert(result, icmd.Matches, icmd.Expected{ExitCode: 11})
1803 }
1804
1805 // Test for #2267
1806 func (s *DockerSuite) TestRunWriteSpecialFilesAndNotCommit(c *check.C) {
1807         // Cannot run on Windows as this files are not present in Windows
1808         testRequires(c, DaemonIsLinux)
1809
1810         testRunWriteSpecialFilesAndNotCommit(c, "writehosts", "/etc/hosts")
1811         testRunWriteSpecialFilesAndNotCommit(c, "writehostname", "/etc/hostname")
1812         testRunWriteSpecialFilesAndNotCommit(c, "writeresolv", "/etc/resolv.conf")
1813 }
1814
1815 func testRunWriteSpecialFilesAndNotCommit(c *check.C, name, path string) {
1816         command := fmt.Sprintf("echo test2267 >> %s && cat %s", path, path)
1817         out, _ := dockerCmd(c, "run", "--name", name, "busybox", "sh", "-c", command)
1818         if !strings.Contains(out, "test2267") {
1819                 c.Fatalf("%s should contain 'test2267'", path)
1820         }
1821
1822         out, _ = dockerCmd(c, "diff", name)
1823         if len(strings.Trim(out, "\r\n")) != 0 && !eqToBaseDiff(out, c) {
1824                 c.Fatal("diff should be empty")
1825         }
1826 }
1827
1828 func eqToBaseDiff(out string, c *check.C) bool {
1829         name := "eqToBaseDiff" + stringutils.GenerateRandomAlphaOnlyString(32)
1830         dockerCmd(c, "run", "--name", name, "busybox", "echo", "hello")
1831         cID := getIDByName(c, name)
1832         baseDiff, _ := dockerCmd(c, "diff", cID)
1833         baseArr := strings.Split(baseDiff, "\n")
1834         sort.Strings(baseArr)
1835         outArr := strings.Split(out, "\n")
1836         sort.Strings(outArr)
1837         return sliceEq(baseArr, outArr)
1838 }
1839
1840 func sliceEq(a, b []string) bool {
1841         if len(a) != len(b) {
1842                 return false
1843         }
1844
1845         for i := range a {
1846                 if a[i] != b[i] {
1847                         return false
1848                 }
1849         }
1850
1851         return true
1852 }
1853
1854 func (s *DockerSuite) TestRunWithBadDevice(c *check.C) {
1855         // Cannot run on Windows as Windows does not support --device
1856         testRequires(c, DaemonIsLinux)
1857         name := "baddevice"
1858         out, _, err := dockerCmdWithError("run", "--name", name, "--device", "/etc", "busybox", "true")
1859
1860         if err == nil {
1861                 c.Fatal("Run should fail with bad device")
1862         }
1863         expected := `"/etc": not a device node`
1864         if !strings.Contains(out, expected) {
1865                 c.Fatalf("Output should contain %q, actual out: %q", expected, out)
1866         }
1867 }
1868
1869 func (s *DockerSuite) TestRunEntrypoint(c *check.C) {
1870         name := "entrypoint"
1871
1872         out, _ := dockerCmd(c, "run", "--name", name, "--entrypoint", "echo", "busybox", "-n", "foobar")
1873         expected := "foobar"
1874
1875         if out != expected {
1876                 c.Fatalf("Output should be %q, actual out: %q", expected, out)
1877         }
1878 }
1879
1880 func (s *DockerSuite) TestRunBindMounts(c *check.C) {
1881         testRequires(c, SameHostDaemon)
1882         if testEnv.DaemonPlatform() == "linux" {
1883                 testRequires(c, DaemonIsLinux, NotUserNamespace)
1884         }
1885
1886         prefix, _ := getPrefixAndSlashFromDaemonPlatform()
1887
1888         tmpDir, err := ioutil.TempDir("", "docker-test-container")
1889         if err != nil {
1890                 c.Fatal(err)
1891         }
1892
1893         defer os.RemoveAll(tmpDir)
1894         writeFile(path.Join(tmpDir, "touch-me"), "", c)
1895
1896         // Test reading from a read-only bind mount
1897         out, _ := dockerCmd(c, "run", "-v", fmt.Sprintf("%s:%s/tmp:ro", tmpDir, prefix), "busybox", "ls", prefix+"/tmp")
1898         if !strings.Contains(out, "touch-me") {
1899                 c.Fatal("Container failed to read from bind mount")
1900         }
1901
1902         // test writing to bind mount
1903         if testEnv.DaemonPlatform() == "windows" {
1904                 dockerCmd(c, "run", "-v", fmt.Sprintf(`%s:c:\tmp:rw`, tmpDir), "busybox", "touch", "c:/tmp/holla")
1905         } else {
1906                 dockerCmd(c, "run", "-v", fmt.Sprintf("%s:/tmp:rw", tmpDir), "busybox", "touch", "/tmp/holla")
1907         }
1908
1909         readFile(path.Join(tmpDir, "holla"), c) // Will fail if the file doesn't exist
1910
1911         // test mounting to an illegal destination directory
1912         _, _, err = dockerCmdWithError("run", "-v", fmt.Sprintf("%s:.", tmpDir), "busybox", "ls", ".")
1913         if err == nil {
1914                 c.Fatal("Container bind mounted illegal directory")
1915         }
1916
1917         // Windows does not (and likely never will) support mounting a single file
1918         if testEnv.DaemonPlatform() != "windows" {
1919                 // test mount a file
1920                 dockerCmd(c, "run", "-v", fmt.Sprintf("%s/holla:/tmp/holla:rw", tmpDir), "busybox", "sh", "-c", "echo -n 'yotta' > /tmp/holla")
1921                 content := readFile(path.Join(tmpDir, "holla"), c) // Will fail if the file doesn't exist
1922                 expected := "yotta"
1923                 if content != expected {
1924                         c.Fatalf("Output should be %q, actual out: %q", expected, content)
1925                 }
1926         }
1927 }
1928
1929 // Ensure that CIDFile gets deleted if it's empty
1930 // Perform this test by making `docker run` fail
1931 func (s *DockerSuite) TestRunCidFileCleanupIfEmpty(c *check.C) {
1932         // Skip on Windows. Base image on Windows has a CMD set in the image.
1933         testRequires(c, DaemonIsLinux)
1934
1935         tmpDir, err := ioutil.TempDir("", "TestRunCidFile")
1936         if err != nil {
1937                 c.Fatal(err)
1938         }
1939         defer os.RemoveAll(tmpDir)
1940         tmpCidFile := path.Join(tmpDir, "cid")
1941
1942         image := "emptyfs"
1943         if testEnv.DaemonPlatform() == "windows" {
1944                 // Windows can't support an emptyfs image. Just use the regular Windows image
1945                 image = testEnv.MinimalBaseImage()
1946         }
1947         out, _, err := dockerCmdWithError("run", "--cidfile", tmpCidFile, image)
1948         if err == nil {
1949                 c.Fatalf("Run without command must fail. out=%s", out)
1950         } else if !strings.Contains(out, "No command specified") {
1951                 c.Fatalf("Run without command failed with wrong output. out=%s\nerr=%v", out, err)
1952         }
1953
1954         if _, err := os.Stat(tmpCidFile); err == nil {
1955                 c.Fatalf("empty CIDFile %q should've been deleted", tmpCidFile)
1956         }
1957 }
1958
1959 // #2098 - Docker cidFiles only contain short version of the containerId
1960 //sudo docker run --cidfile /tmp/docker_tesc.cid ubuntu echo "test"
1961 // TestRunCidFile tests that run --cidfile returns the longid
1962 func (s *DockerSuite) TestRunCidFileCheckIDLength(c *check.C) {
1963         tmpDir, err := ioutil.TempDir("", "TestRunCidFile")
1964         if err != nil {
1965                 c.Fatal(err)
1966         }
1967         tmpCidFile := path.Join(tmpDir, "cid")
1968         defer os.RemoveAll(tmpDir)
1969
1970         out, _ := dockerCmd(c, "run", "-d", "--cidfile", tmpCidFile, "busybox", "true")
1971
1972         id := strings.TrimSpace(out)
1973         buffer, err := ioutil.ReadFile(tmpCidFile)
1974         if err != nil {
1975                 c.Fatal(err)
1976         }
1977         cid := string(buffer)
1978         if len(cid) != 64 {
1979                 c.Fatalf("--cidfile should be a long id, not %q", id)
1980         }
1981         if cid != id {
1982                 c.Fatalf("cid must be equal to %s, got %s", id, cid)
1983         }
1984 }
1985
1986 func (s *DockerSuite) TestRunSetMacAddress(c *check.C) {
1987         mac := "12:34:56:78:9a:bc"
1988         var out string
1989         if testEnv.DaemonPlatform() == "windows" {
1990                 out, _ = dockerCmd(c, "run", "-i", "--rm", fmt.Sprintf("--mac-address=%s", mac), "busybox", "sh", "-c", "ipconfig /all | grep 'Physical Address' | awk '{print $12}'")
1991                 mac = strings.Replace(strings.ToUpper(mac), ":", "-", -1) // To Windows-style MACs
1992         } else {
1993                 out, _ = dockerCmd(c, "run", "-i", "--rm", fmt.Sprintf("--mac-address=%s", mac), "busybox", "/bin/sh", "-c", "ip link show eth0 | tail -1 | awk '{print $2}'")
1994         }
1995
1996         actualMac := strings.TrimSpace(out)
1997         if actualMac != mac {
1998                 c.Fatalf("Set MAC address with --mac-address failed. The container has an incorrect MAC address: %q, expected: %q", actualMac, mac)
1999         }
2000 }
2001
2002 func (s *DockerSuite) TestRunInspectMacAddress(c *check.C) {
2003         // TODO Windows. Network settings are not propagated back to inspect.
2004         testRequires(c, DaemonIsLinux)
2005         mac := "12:34:56:78:9a:bc"
2006         out, _ := dockerCmd(c, "run", "-d", "--mac-address="+mac, "busybox", "top")
2007
2008         id := strings.TrimSpace(out)
2009         inspectedMac := inspectField(c, id, "NetworkSettings.Networks.bridge.MacAddress")
2010         if inspectedMac != mac {
2011                 c.Fatalf("docker inspect outputs wrong MAC address: %q, should be: %q", inspectedMac, mac)
2012         }
2013 }
2014
2015 // test docker run use an invalid mac address
2016 func (s *DockerSuite) TestRunWithInvalidMacAddress(c *check.C) {
2017         out, _, err := dockerCmdWithError("run", "--mac-address", "92:d0:c6:0a:29", "busybox")
2018         //use an invalid mac address should with an error out
2019         if err == nil || !strings.Contains(out, "is not a valid mac address") {
2020                 c.Fatalf("run with an invalid --mac-address should with error out")
2021         }
2022 }
2023
2024 func (s *DockerSuite) TestRunDeallocatePortOnMissingIptablesRule(c *check.C) {
2025         // TODO Windows. Network settings are not propagated back to inspect.
2026         testRequires(c, SameHostDaemon, DaemonIsLinux)
2027
2028         out := cli.DockerCmd(c, "run", "-d", "-p", "23:23", "busybox", "top").Combined()
2029
2030         id := strings.TrimSpace(out)
2031         ip := inspectField(c, id, "NetworkSettings.Networks.bridge.IPAddress")
2032         icmd.RunCommand("iptables", "-D", "DOCKER", "-d", fmt.Sprintf("%s/32", ip),
2033                 "!", "-i", "docker0", "-o", "docker0", "-p", "tcp", "-m", "tcp", "--dport", "23", "-j", "ACCEPT").Assert(c, icmd.Success)
2034
2035         cli.DockerCmd(c, "rm", "-fv", id)
2036
2037         cli.DockerCmd(c, "run", "-d", "-p", "23:23", "busybox", "top")
2038 }
2039
2040 func (s *DockerSuite) TestRunPortInUse(c *check.C) {
2041         // TODO Windows. The duplicate NAT message returned by Windows will be
2042         // changing as is currently completely undecipherable. Does need modifying
2043         // to run sh rather than top though as top isn't in Windows busybox.
2044         testRequires(c, SameHostDaemon, DaemonIsLinux)
2045
2046         port := "1234"
2047         dockerCmd(c, "run", "-d", "-p", port+":80", "busybox", "top")
2048
2049         out, _, err := dockerCmdWithError("run", "-d", "-p", port+":80", "busybox", "top")
2050         if err == nil {
2051                 c.Fatalf("Binding on used port must fail")
2052         }
2053         if !strings.Contains(out, "port is already allocated") {
2054                 c.Fatalf("Out must be about \"port is already allocated\", got %s", out)
2055         }
2056 }
2057
2058 // https://github.com/docker/docker/issues/12148
2059 func (s *DockerSuite) TestRunAllocatePortInReservedRange(c *check.C) {
2060         // TODO Windows. -P is not yet supported
2061         testRequires(c, DaemonIsLinux)
2062         // allocate a dynamic port to get the most recent
2063         out, _ := dockerCmd(c, "run", "-d", "-P", "-p", "80", "busybox", "top")
2064
2065         id := strings.TrimSpace(out)
2066         out, _ = dockerCmd(c, "port", id, "80")
2067
2068         strPort := strings.Split(strings.TrimSpace(out), ":")[1]
2069         port, err := strconv.ParseInt(strPort, 10, 64)
2070         if err != nil {
2071                 c.Fatalf("invalid port, got: %s, error: %s", strPort, err)
2072         }
2073
2074         // allocate a static port and a dynamic port together, with static port
2075         // takes the next recent port in dynamic port range.
2076         dockerCmd(c, "run", "-d", "-P", "-p", "80", "-p", fmt.Sprintf("%d:8080", port+1), "busybox", "top")
2077 }
2078
2079 // Regression test for #7792
2080 func (s *DockerSuite) TestRunMountOrdering(c *check.C) {
2081         // TODO Windows: Post RS1. Windows does not support nested mounts.
2082         testRequires(c, SameHostDaemon, DaemonIsLinux, NotUserNamespace)
2083         prefix, _ := getPrefixAndSlashFromDaemonPlatform()
2084
2085         tmpDir, err := ioutil.TempDir("", "docker_nested_mount_test")
2086         if err != nil {
2087                 c.Fatal(err)
2088         }
2089         defer os.RemoveAll(tmpDir)
2090
2091         tmpDir2, err := ioutil.TempDir("", "docker_nested_mount_test2")
2092         if err != nil {
2093                 c.Fatal(err)
2094         }
2095         defer os.RemoveAll(tmpDir2)
2096
2097         // Create a temporary tmpfs mounc.
2098         fooDir := filepath.Join(tmpDir, "foo")
2099         if err := os.MkdirAll(filepath.Join(tmpDir, "foo"), 0755); err != nil {
2100                 c.Fatalf("failed to mkdir at %s - %s", fooDir, err)
2101         }
2102
2103         if err := ioutil.WriteFile(fmt.Sprintf("%s/touch-me", fooDir), []byte{}, 0644); err != nil {
2104                 c.Fatal(err)
2105         }
2106
2107         if err := ioutil.WriteFile(fmt.Sprintf("%s/touch-me", tmpDir), []byte{}, 0644); err != nil {
2108                 c.Fatal(err)
2109         }
2110
2111         if err := ioutil.WriteFile(fmt.Sprintf("%s/touch-me", tmpDir2), []byte{}, 0644); err != nil {
2112                 c.Fatal(err)
2113         }
2114
2115         dockerCmd(c, "run",
2116                 "-v", fmt.Sprintf("%s:"+prefix+"/tmp", tmpDir),
2117                 "-v", fmt.Sprintf("%s:"+prefix+"/tmp/foo", fooDir),
2118                 "-v", fmt.Sprintf("%s:"+prefix+"/tmp/tmp2", tmpDir2),
2119                 "-v", fmt.Sprintf("%s:"+prefix+"/tmp/tmp2/foo", fooDir),
2120                 "busybox:latest", "sh", "-c",
2121                 "ls "+prefix+"/tmp/touch-me && ls "+prefix+"/tmp/foo/touch-me && ls "+prefix+"/tmp/tmp2/touch-me && ls "+prefix+"/tmp/tmp2/foo/touch-me")
2122 }
2123
2124 // Regression test for https://github.com/docker/docker/issues/8259
2125 func (s *DockerSuite) TestRunReuseBindVolumeThatIsSymlink(c *check.C) {
2126         // Not applicable on Windows as Windows does not support volumes
2127         testRequires(c, SameHostDaemon, DaemonIsLinux, NotUserNamespace)
2128         prefix, _ := getPrefixAndSlashFromDaemonPlatform()
2129
2130         tmpDir, err := ioutil.TempDir(os.TempDir(), "testlink")
2131         if err != nil {
2132                 c.Fatal(err)
2133         }
2134         defer os.RemoveAll(tmpDir)
2135
2136         linkPath := os.TempDir() + "/testlink2"
2137         if err := os.Symlink(tmpDir, linkPath); err != nil {
2138                 c.Fatal(err)
2139         }
2140         defer os.RemoveAll(linkPath)
2141
2142         // Create first container
2143         dockerCmd(c, "run", "-v", fmt.Sprintf("%s:"+prefix+"/tmp/test", linkPath), "busybox", "ls", prefix+"/tmp/test")
2144
2145         // Create second container with same symlinked path
2146         // This will fail if the referenced issue is hit with a "Volume exists" error
2147         dockerCmd(c, "run", "-v", fmt.Sprintf("%s:"+prefix+"/tmp/test", linkPath), "busybox", "ls", prefix+"/tmp/test")
2148 }
2149
2150 //GH#10604: Test an "/etc" volume doesn't overlay special bind mounts in container
2151 func (s *DockerSuite) TestRunCreateVolumeEtc(c *check.C) {
2152         // While Windows supports volumes, it does not support --add-host hence
2153         // this test is not applicable on Windows.
2154         testRequires(c, DaemonIsLinux)
2155         out, _ := dockerCmd(c, "run", "--dns=127.0.0.1", "-v", "/etc", "busybox", "cat", "/etc/resolv.conf")
2156         if !strings.Contains(out, "nameserver 127.0.0.1") {
2157                 c.Fatal("/etc volume mount hides /etc/resolv.conf")
2158         }
2159
2160         out, _ = dockerCmd(c, "run", "-h=test123", "-v", "/etc", "busybox", "cat", "/etc/hostname")
2161         if !strings.Contains(out, "test123") {
2162                 c.Fatal("/etc volume mount hides /etc/hostname")
2163         }
2164
2165         out, _ = dockerCmd(c, "run", "--add-host=test:192.168.0.1", "-v", "/etc", "busybox", "cat", "/etc/hosts")
2166         out = strings.Replace(out, "\n", " ", -1)
2167         if !strings.Contains(out, "192.168.0.1\ttest") || !strings.Contains(out, "127.0.0.1\tlocalhost") {
2168                 c.Fatal("/etc volume mount hides /etc/hosts")
2169         }
2170 }
2171
2172 func (s *DockerSuite) TestVolumesNoCopyData(c *check.C) {
2173         // TODO Windows (Post RS1). Windows does not support volumes which
2174         // are pre-populated such as is built in the dockerfile used in this test.
2175         testRequires(c, DaemonIsLinux)
2176         prefix, slash := getPrefixAndSlashFromDaemonPlatform()
2177         buildImageSuccessfully(c, "dataimage", build.WithDockerfile(`FROM busybox
2178                 RUN ["mkdir", "-p", "/foo"]
2179                 RUN ["touch", "/foo/bar"]`))
2180         dockerCmd(c, "run", "--name", "test", "-v", prefix+slash+"foo", "busybox")
2181
2182         if out, _, err := dockerCmdWithError("run", "--volumes-from", "test", "dataimage", "ls", "-lh", "/foo/bar"); err == nil || !strings.Contains(out, "No such file or directory") {
2183                 c.Fatalf("Data was copied on volumes-from but shouldn't be:\n%q", out)
2184         }
2185
2186         tmpDir := testutil.RandomTmpDirPath("docker_test_bind_mount_copy_data", testEnv.DaemonPlatform())
2187         if out, _, err := dockerCmdWithError("run", "-v", tmpDir+":/foo", "dataimage", "ls", "-lh", "/foo/bar"); err == nil || !strings.Contains(out, "No such file or directory") {
2188                 c.Fatalf("Data was copied on bind-mount but shouldn't be:\n%q", out)
2189         }
2190 }
2191
2192 func (s *DockerSuite) TestRunNoOutputFromPullInStdout(c *check.C) {
2193         // just run with unknown image
2194         cmd := exec.Command(dockerBinary, "run", "asdfsg")
2195         stdout := bytes.NewBuffer(nil)
2196         cmd.Stdout = stdout
2197         if err := cmd.Run(); err == nil {
2198                 c.Fatal("Run with unknown image should fail")
2199         }
2200         if stdout.Len() != 0 {
2201                 c.Fatalf("Stdout contains output from pull: %s", stdout)
2202         }
2203 }
2204
2205 func (s *DockerSuite) TestRunVolumesCleanPaths(c *check.C) {
2206         testRequires(c, SameHostDaemon)
2207         prefix, slash := getPrefixAndSlashFromDaemonPlatform()
2208         buildImageSuccessfully(c, "run_volumes_clean_paths", build.WithDockerfile(`FROM busybox
2209                 VOLUME `+prefix+`/foo/`))
2210         dockerCmd(c, "run", "-v", prefix+"/foo", "-v", prefix+"/bar/", "--name", "dark_helmet", "run_volumes_clean_paths")
2211
2212         out, err := inspectMountSourceField("dark_helmet", prefix+slash+"foo"+slash)
2213         if err != errMountNotFound {
2214                 c.Fatalf("Found unexpected volume entry for '%s/foo/' in volumes\n%q", prefix, out)
2215         }
2216
2217         out, err = inspectMountSourceField("dark_helmet", prefix+slash+`foo`)
2218         c.Assert(err, check.IsNil)
2219         if !strings.Contains(strings.ToLower(out), strings.ToLower(testEnv.VolumesConfigPath())) {
2220                 c.Fatalf("Volume was not defined for %s/foo\n%q", prefix, out)
2221         }
2222
2223         out, err = inspectMountSourceField("dark_helmet", prefix+slash+"bar"+slash)
2224         if err != errMountNotFound {
2225                 c.Fatalf("Found unexpected volume entry for '%s/bar/' in volumes\n%q", prefix, out)
2226         }
2227
2228         out, err = inspectMountSourceField("dark_helmet", prefix+slash+"bar")
2229         c.Assert(err, check.IsNil)
2230         if !strings.Contains(strings.ToLower(out), strings.ToLower(testEnv.VolumesConfigPath())) {
2231                 c.Fatalf("Volume was not defined for %s/bar\n%q", prefix, out)
2232         }
2233 }
2234
2235 // Regression test for #3631
2236 func (s *DockerSuite) TestRunSlowStdoutConsumer(c *check.C) {
2237         // TODO Windows: This should be able to run on Windows if can find an
2238         // alternate to /dev/zero and /dev/stdout.
2239         testRequires(c, DaemonIsLinux)
2240         cont := exec.Command(dockerBinary, "run", "--rm", "busybox", "/bin/sh", "-c", "dd if=/dev/zero of=/dev/stdout bs=1024 count=2000 | catv")
2241
2242         stdout, err := cont.StdoutPipe()
2243         if err != nil {
2244                 c.Fatal(err)
2245         }
2246
2247         if err := cont.Start(); err != nil {
2248                 c.Fatal(err)
2249         }
2250         n, err := testutil.ConsumeWithSpeed(stdout, 10000, 5*time.Millisecond, nil)
2251         if err != nil {
2252                 c.Fatal(err)
2253         }
2254
2255         expected := 2 * 1024 * 2000
2256         if n != expected {
2257                 c.Fatalf("Expected %d, got %d", expected, n)
2258         }
2259 }
2260
2261 func (s *DockerSuite) TestRunAllowPortRangeThroughExpose(c *check.C) {
2262         // TODO Windows: -P is not currently supported. Also network
2263         // settings are not propagated back.
2264         testRequires(c, DaemonIsLinux)
2265         out, _ := dockerCmd(c, "run", "-d", "--expose", "3000-3003", "-P", "busybox", "top")
2266
2267         id := strings.TrimSpace(out)
2268         portstr := inspectFieldJSON(c, id, "NetworkSettings.Ports")
2269         var ports nat.PortMap
2270         if err := json.Unmarshal([]byte(portstr), &ports); err != nil {
2271                 c.Fatal(err)
2272         }
2273         for port, binding := range ports {
2274                 portnum, _ := strconv.Atoi(strings.Split(string(port), "/")[0])
2275                 if portnum < 3000 || portnum > 3003 {
2276                         c.Fatalf("Port %d is out of range ", portnum)
2277                 }
2278                 if binding == nil || len(binding) != 1 || len(binding[0].HostPort) == 0 {
2279                         c.Fatalf("Port is not mapped for the port %s", port)
2280                 }
2281         }
2282 }
2283
2284 func (s *DockerSuite) TestRunExposePort(c *check.C) {
2285         out, _, err := dockerCmdWithError("run", "--expose", "80000", "busybox")
2286         c.Assert(err, checker.NotNil, check.Commentf("--expose with an invalid port should error out"))
2287         c.Assert(out, checker.Contains, "invalid range format for --expose")
2288 }
2289
2290 func (s *DockerSuite) TestRunModeIpcHost(c *check.C) {
2291         // Not applicable on Windows as uses Unix-specific capabilities
2292         testRequires(c, SameHostDaemon, DaemonIsLinux, NotUserNamespace)
2293
2294         hostIpc, err := os.Readlink("/proc/1/ns/ipc")
2295         if err != nil {
2296                 c.Fatal(err)
2297         }
2298
2299         out, _ := dockerCmd(c, "run", "--ipc=host", "busybox", "readlink", "/proc/self/ns/ipc")
2300         out = strings.Trim(out, "\n")
2301         if hostIpc != out {
2302                 c.Fatalf("IPC different with --ipc=host %s != %s\n", hostIpc, out)
2303         }
2304
2305         out, _ = dockerCmd(c, "run", "busybox", "readlink", "/proc/self/ns/ipc")
2306         out = strings.Trim(out, "\n")
2307         if hostIpc == out {
2308                 c.Fatalf("IPC should be different without --ipc=host %s == %s\n", hostIpc, out)
2309         }
2310 }
2311
2312 func (s *DockerSuite) TestRunModeIpcContainer(c *check.C) {
2313         // Not applicable on Windows as uses Unix-specific capabilities
2314         testRequires(c, SameHostDaemon, DaemonIsLinux)
2315
2316         out, _ := dockerCmd(c, "run", "-d", "busybox", "sh", "-c", "echo -n test > /dev/shm/test && touch /dev/mqueue/toto && top")
2317
2318         id := strings.TrimSpace(out)
2319         state := inspectField(c, id, "State.Running")
2320         if state != "true" {
2321                 c.Fatal("Container state is 'not running'")
2322         }
2323         pid1 := inspectField(c, id, "State.Pid")
2324
2325         parentContainerIpc, err := os.Readlink(fmt.Sprintf("/proc/%s/ns/ipc", pid1))
2326         if err != nil {
2327                 c.Fatal(err)
2328         }
2329
2330         out, _ = dockerCmd(c, "run", fmt.Sprintf("--ipc=container:%s", id), "busybox", "readlink", "/proc/self/ns/ipc")
2331         out = strings.Trim(out, "\n")
2332         if parentContainerIpc != out {
2333                 c.Fatalf("IPC different with --ipc=container:%s %s != %s\n", id, parentContainerIpc, out)
2334         }
2335
2336         catOutput, _ := dockerCmd(c, "run", fmt.Sprintf("--ipc=container:%s", id), "busybox", "cat", "/dev/shm/test")
2337         if catOutput != "test" {
2338                 c.Fatalf("Output of /dev/shm/test expected test but found: %s", catOutput)
2339         }
2340
2341         // check that /dev/mqueue is actually of mqueue type
2342         grepOutput, _ := dockerCmd(c, "run", fmt.Sprintf("--ipc=container:%s", id), "busybox", "grep", "/dev/mqueue", "/proc/mounts")
2343         if !strings.HasPrefix(grepOutput, "mqueue /dev/mqueue mqueue rw") {
2344                 c.Fatalf("Output of 'grep /proc/mounts' expected 'mqueue /dev/mqueue mqueue rw' but found: %s", grepOutput)
2345         }
2346
2347         lsOutput, _ := dockerCmd(c, "run", fmt.Sprintf("--ipc=container:%s", id), "busybox", "ls", "/dev/mqueue")
2348         lsOutput = strings.Trim(lsOutput, "\n")
2349         if lsOutput != "toto" {
2350                 c.Fatalf("Output of 'ls /dev/mqueue' expected 'toto' but found: %s", lsOutput)
2351         }
2352 }
2353
2354 func (s *DockerSuite) TestRunModeIpcContainerNotExists(c *check.C) {
2355         // Not applicable on Windows as uses Unix-specific capabilities
2356         testRequires(c, DaemonIsLinux)
2357         out, _, err := dockerCmdWithError("run", "-d", "--ipc", "container:abcd1234", "busybox", "top")
2358         if !strings.Contains(out, "abcd1234") || err == nil {
2359                 c.Fatalf("run IPC from a non exists container should with correct error out")
2360         }
2361 }
2362
2363 func (s *DockerSuite) TestRunModeIpcContainerNotRunning(c *check.C) {
2364         // Not applicable on Windows as uses Unix-specific capabilities
2365         testRequires(c, SameHostDaemon, DaemonIsLinux)
2366
2367         out, _ := dockerCmd(c, "create", "busybox")
2368
2369         id := strings.TrimSpace(out)
2370         out, _, err := dockerCmdWithError("run", fmt.Sprintf("--ipc=container:%s", id), "busybox")
2371         if err == nil {
2372                 c.Fatalf("Run container with ipc mode container should fail with non running container: %s\n%s", out, err)
2373         }
2374 }
2375
2376 func (s *DockerSuite) TestRunModePIDContainer(c *check.C) {
2377         // Not applicable on Windows as uses Unix-specific capabilities
2378         testRequires(c, SameHostDaemon, DaemonIsLinux)
2379
2380         out, _ := dockerCmd(c, "run", "-d", "busybox", "sh", "-c", "top")
2381
2382         id := strings.TrimSpace(out)
2383         state := inspectField(c, id, "State.Running")
2384         if state != "true" {
2385                 c.Fatal("Container state is 'not running'")
2386         }
2387         pid1 := inspectField(c, id, "State.Pid")
2388
2389         parentContainerPid, err := os.Readlink(fmt.Sprintf("/proc/%s/ns/pid", pid1))
2390         if err != nil {
2391                 c.Fatal(err)
2392         }
2393
2394         out, _ = dockerCmd(c, "run", fmt.Sprintf("--pid=container:%s", id), "busybox", "readlink", "/proc/self/ns/pid")
2395         out = strings.Trim(out, "\n")
2396         if parentContainerPid != out {
2397                 c.Fatalf("PID different with --pid=container:%s %s != %s\n", id, parentContainerPid, out)
2398         }
2399 }
2400
2401 func (s *DockerSuite) TestRunModePIDContainerNotExists(c *check.C) {
2402         // Not applicable on Windows as uses Unix-specific capabilities
2403         testRequires(c, DaemonIsLinux)
2404         out, _, err := dockerCmdWithError("run", "-d", "--pid", "container:abcd1234", "busybox", "top")
2405         if !strings.Contains(out, "abcd1234") || err == nil {
2406                 c.Fatalf("run PID from a non exists container should with correct error out")
2407         }
2408 }
2409
2410 func (s *DockerSuite) TestRunModePIDContainerNotRunning(c *check.C) {
2411         // Not applicable on Windows as uses Unix-specific capabilities
2412         testRequires(c, SameHostDaemon, DaemonIsLinux)
2413
2414         out, _ := dockerCmd(c, "create", "busybox")
2415
2416         id := strings.TrimSpace(out)
2417         out, _, err := dockerCmdWithError("run", fmt.Sprintf("--pid=container:%s", id), "busybox")
2418         if err == nil {
2419                 c.Fatalf("Run container with pid mode container should fail with non running container: %s\n%s", out, err)
2420         }
2421 }
2422
2423 func (s *DockerSuite) TestRunMountShmMqueueFromHost(c *check.C) {
2424         // Not applicable on Windows as uses Unix-specific capabilities
2425         testRequires(c, SameHostDaemon, DaemonIsLinux, NotUserNamespace)
2426
2427         dockerCmd(c, "run", "-d", "--name", "shmfromhost", "-v", "/dev/shm:/dev/shm", "-v", "/dev/mqueue:/dev/mqueue", "busybox", "sh", "-c", "echo -n test > /dev/shm/test && touch /dev/mqueue/toto && top")
2428         defer os.Remove("/dev/mqueue/toto")
2429         defer os.Remove("/dev/shm/test")
2430         volPath, err := inspectMountSourceField("shmfromhost", "/dev/shm")
2431         c.Assert(err, checker.IsNil)
2432         if volPath != "/dev/shm" {
2433                 c.Fatalf("volumePath should have been /dev/shm, was %s", volPath)
2434         }
2435
2436         out, _ := dockerCmd(c, "run", "--name", "ipchost", "--ipc", "host", "busybox", "cat", "/dev/shm/test")
2437         if out != "test" {
2438                 c.Fatalf("Output of /dev/shm/test expected test but found: %s", out)
2439         }
2440
2441         // Check that the mq was created
2442         if _, err := os.Stat("/dev/mqueue/toto"); err != nil {
2443                 c.Fatalf("Failed to confirm '/dev/mqueue/toto' presence on host: %s", err.Error())
2444         }
2445 }
2446
2447 func (s *DockerSuite) TestContainerNetworkMode(c *check.C) {
2448         // Not applicable on Windows as uses Unix-specific capabilities
2449         testRequires(c, SameHostDaemon, DaemonIsLinux)
2450
2451         out, _ := dockerCmd(c, "run", "-d", "busybox", "top")
2452         id := strings.TrimSpace(out)
2453         c.Assert(waitRun(id), check.IsNil)
2454         pid1 := inspectField(c, id, "State.Pid")
2455
2456         parentContainerNet, err := os.Readlink(fmt.Sprintf("/proc/%s/ns/net", pid1))
2457         if err != nil {
2458                 c.Fatal(err)
2459         }
2460
2461         out, _ = dockerCmd(c, "run", fmt.Sprintf("--net=container:%s", id), "busybox", "readlink", "/proc/self/ns/net")
2462         out = strings.Trim(out, "\n")
2463         if parentContainerNet != out {
2464                 c.Fatalf("NET different with --net=container:%s %s != %s\n", id, parentContainerNet, out)
2465         }
2466 }
2467
2468 func (s *DockerSuite) TestRunModePIDHost(c *check.C) {
2469         // Not applicable on Windows as uses Unix-specific capabilities
2470         testRequires(c, SameHostDaemon, DaemonIsLinux, NotUserNamespace)
2471
2472         hostPid, err := os.Readlink("/proc/1/ns/pid")
2473         if err != nil {
2474                 c.Fatal(err)
2475         }
2476
2477         out, _ := dockerCmd(c, "run", "--pid=host", "busybox", "readlink", "/proc/self/ns/pid")
2478         out = strings.Trim(out, "\n")
2479         if hostPid != out {
2480                 c.Fatalf("PID different with --pid=host %s != %s\n", hostPid, out)
2481         }
2482
2483         out, _ = dockerCmd(c, "run", "busybox", "readlink", "/proc/self/ns/pid")
2484         out = strings.Trim(out, "\n")
2485         if hostPid == out {
2486                 c.Fatalf("PID should be different without --pid=host %s == %s\n", hostPid, out)
2487         }
2488 }
2489
2490 func (s *DockerSuite) TestRunModeUTSHost(c *check.C) {
2491         // Not applicable on Windows as uses Unix-specific capabilities
2492         testRequires(c, SameHostDaemon, DaemonIsLinux)
2493
2494         hostUTS, err := os.Readlink("/proc/1/ns/uts")
2495         if err != nil {
2496                 c.Fatal(err)
2497         }
2498
2499         out, _ := dockerCmd(c, "run", "--uts=host", "busybox", "readlink", "/proc/self/ns/uts")
2500         out = strings.Trim(out, "\n")
2501         if hostUTS != out {
2502                 c.Fatalf("UTS different with --uts=host %s != %s\n", hostUTS, out)
2503         }
2504
2505         out, _ = dockerCmd(c, "run", "busybox", "readlink", "/proc/self/ns/uts")
2506         out = strings.Trim(out, "\n")
2507         if hostUTS == out {
2508                 c.Fatalf("UTS should be different without --uts=host %s == %s\n", hostUTS, out)
2509         }
2510
2511         out, _ = dockerCmdWithFail(c, "run", "-h=name", "--uts=host", "busybox", "ps")
2512         c.Assert(out, checker.Contains, runconfig.ErrConflictUTSHostname.Error())
2513 }
2514
2515 func (s *DockerSuite) TestRunTLSVerify(c *check.C) {
2516         // Remote daemons use TLS and this test is not applicable when TLS is required.
2517         testRequires(c, SameHostDaemon)
2518         if out, code, err := dockerCmdWithError("ps"); err != nil || code != 0 {
2519                 c.Fatalf("Should have worked: %v:\n%v", err, out)
2520         }
2521
2522         // Regardless of whether we specify true or false we need to
2523         // test to make sure tls is turned on if --tlsverify is specified at all
2524         result := dockerCmdWithResult("--tlsverify=false", "ps")
2525         result.Assert(c, icmd.Expected{ExitCode: 1, Err: "error during connect"})
2526
2527         result = dockerCmdWithResult("--tlsverify=true", "ps")
2528         result.Assert(c, icmd.Expected{ExitCode: 1, Err: "cert"})
2529 }
2530
2531 func (s *DockerSuite) TestRunPortFromDockerRangeInUse(c *check.C) {
2532         // TODO Windows. Once moved to libnetwork/CNM, this may be able to be
2533         // re-instated.
2534         testRequires(c, DaemonIsLinux)
2535         // first find allocator current position
2536         out, _ := dockerCmd(c, "run", "-d", "-p", ":80", "busybox", "top")
2537
2538         id := strings.TrimSpace(out)
2539         out, _ = dockerCmd(c, "port", id)
2540
2541         out = strings.TrimSpace(out)
2542         if out == "" {
2543                 c.Fatal("docker port command output is empty")
2544         }
2545         out = strings.Split(out, ":")[1]
2546         lastPort, err := strconv.Atoi(out)
2547         if err != nil {
2548                 c.Fatal(err)
2549         }
2550         port := lastPort + 1
2551         l, err := net.Listen("tcp", ":"+strconv.Itoa(port))
2552         if err != nil {
2553                 c.Fatal(err)
2554         }
2555         defer l.Close()
2556
2557         out, _ = dockerCmd(c, "run", "-d", "-p", ":80", "busybox", "top")
2558
2559         id = strings.TrimSpace(out)
2560         dockerCmd(c, "port", id)
2561 }
2562
2563 func (s *DockerSuite) TestRunTTYWithPipe(c *check.C) {
2564         errChan := make(chan error)
2565         go func() {
2566                 defer close(errChan)
2567
2568                 cmd := exec.Command(dockerBinary, "run", "-ti", "busybox", "true")
2569                 if _, err := cmd.StdinPipe(); err != nil {
2570                         errChan <- err
2571                         return
2572                 }
2573
2574                 expected := "the input device is not a TTY"
2575                 if runtime.GOOS == "windows" {
2576                         expected += ".  If you are using mintty, try prefixing the command with 'winpty'"
2577                 }
2578                 if out, _, err := runCommandWithOutput(cmd); err == nil {
2579                         errChan <- fmt.Errorf("run should have failed")
2580                         return
2581                 } else if !strings.Contains(out, expected) {
2582                         errChan <- fmt.Errorf("run failed with error %q: expected %q", out, expected)
2583                         return
2584                 }
2585         }()
2586
2587         select {
2588         case err := <-errChan:
2589                 c.Assert(err, check.IsNil)
2590         case <-time.After(30 * time.Second):
2591                 c.Fatal("container is running but should have failed")
2592         }
2593 }
2594
2595 func (s *DockerSuite) TestRunNonLocalMacAddress(c *check.C) {
2596         addr := "00:16:3E:08:00:50"
2597         args := []string{"run", "--mac-address", addr}
2598         expected := addr
2599
2600         if testEnv.DaemonPlatform() != "windows" {
2601                 args = append(args, "busybox", "ifconfig")
2602         } else {
2603                 args = append(args, testEnv.MinimalBaseImage(), "ipconfig", "/all")
2604                 expected = strings.Replace(strings.ToUpper(addr), ":", "-", -1)
2605         }
2606
2607         if out, _ := dockerCmd(c, args...); !strings.Contains(out, expected) {
2608                 c.Fatalf("Output should have contained %q: %s", expected, out)
2609         }
2610 }
2611
2612 func (s *DockerSuite) TestRunNetHost(c *check.C) {
2613         // Not applicable on Windows as uses Unix-specific capabilities
2614         testRequires(c, SameHostDaemon, DaemonIsLinux, NotUserNamespace)
2615
2616         hostNet, err := os.Readlink("/proc/1/ns/net")
2617         if err != nil {
2618                 c.Fatal(err)
2619         }
2620
2621         out, _ := dockerCmd(c, "run", "--net=host", "busybox", "readlink", "/proc/self/ns/net")
2622         out = strings.Trim(out, "\n")
2623         if hostNet != out {
2624                 c.Fatalf("Net namespace different with --net=host %s != %s\n", hostNet, out)
2625         }
2626
2627         out, _ = dockerCmd(c, "run", "busybox", "readlink", "/proc/self/ns/net")
2628         out = strings.Trim(out, "\n")
2629         if hostNet == out {
2630                 c.Fatalf("Net namespace should be different without --net=host %s == %s\n", hostNet, out)
2631         }
2632 }
2633
2634 func (s *DockerSuite) TestRunNetHostTwiceSameName(c *check.C) {
2635         // TODO Windows. As Windows networking evolves and converges towards
2636         // CNM, this test may be possible to enable on Windows.
2637         testRequires(c, SameHostDaemon, DaemonIsLinux, NotUserNamespace)
2638
2639         dockerCmd(c, "run", "--rm", "--name=thost", "--net=host", "busybox", "true")
2640         dockerCmd(c, "run", "--rm", "--name=thost", "--net=host", "busybox", "true")
2641 }
2642
2643 func (s *DockerSuite) TestRunNetContainerWhichHost(c *check.C) {
2644         // Not applicable on Windows as uses Unix-specific capabilities
2645         testRequires(c, SameHostDaemon, DaemonIsLinux, NotUserNamespace)
2646
2647         hostNet, err := os.Readlink("/proc/1/ns/net")
2648         if err != nil {
2649                 c.Fatal(err)
2650         }
2651
2652         dockerCmd(c, "run", "-d", "--net=host", "--name=test", "busybox", "top")
2653
2654         out, _ := dockerCmd(c, "run", "--net=container:test", "busybox", "readlink", "/proc/self/ns/net")
2655         out = strings.Trim(out, "\n")
2656         if hostNet != out {
2657                 c.Fatalf("Container should have host network namespace")
2658         }
2659 }
2660
2661 func (s *DockerSuite) TestRunAllowPortRangeThroughPublish(c *check.C) {
2662         // TODO Windows. This may be possible to enable in the future. However,
2663         // Windows does not currently support --expose, or populate the network
2664         // settings seen through inspect.
2665         testRequires(c, DaemonIsLinux)
2666         out, _ := dockerCmd(c, "run", "-d", "--expose", "3000-3003", "-p", "3000-3003", "busybox", "top")
2667
2668         id := strings.TrimSpace(out)
2669         portstr := inspectFieldJSON(c, id, "NetworkSettings.Ports")
2670
2671         var ports nat.PortMap
2672         err := json.Unmarshal([]byte(portstr), &ports)
2673         c.Assert(err, checker.IsNil, check.Commentf("failed to unmarshal: %v", portstr))
2674         for port, binding := range ports {
2675                 portnum, _ := strconv.Atoi(strings.Split(string(port), "/")[0])
2676                 if portnum < 3000 || portnum > 3003 {
2677                         c.Fatalf("Port %d is out of range ", portnum)
2678                 }
2679                 if binding == nil || len(binding) != 1 || len(binding[0].HostPort) == 0 {
2680                         c.Fatal("Port is not mapped for the port "+port, out)
2681                 }
2682         }
2683 }
2684
2685 func (s *DockerSuite) TestRunSetDefaultRestartPolicy(c *check.C) {
2686         runSleepingContainer(c, "--name=testrunsetdefaultrestartpolicy")
2687         out := inspectField(c, "testrunsetdefaultrestartpolicy", "HostConfig.RestartPolicy.Name")
2688         if out != "no" {
2689                 c.Fatalf("Set default restart policy failed")
2690         }
2691 }
2692
2693 func (s *DockerSuite) TestRunRestartMaxRetries(c *check.C) {
2694         out, _ := dockerCmd(c, "run", "-d", "--restart=on-failure:3", "busybox", "false")
2695         timeout := 10 * time.Second
2696         if testEnv.DaemonPlatform() == "windows" {
2697                 timeout = 120 * time.Second
2698         }
2699
2700         id := strings.TrimSpace(string(out))
2701         if err := waitInspect(id, "{{ .State.Restarting }} {{ .State.Running }}", "false false", timeout); err != nil {
2702                 c.Fatal(err)
2703         }
2704
2705         count := inspectField(c, id, "RestartCount")
2706         if count != "3" {
2707                 c.Fatalf("Container was restarted %s times, expected %d", count, 3)
2708         }
2709
2710         MaximumRetryCount := inspectField(c, id, "HostConfig.RestartPolicy.MaximumRetryCount")
2711         if MaximumRetryCount != "3" {
2712                 c.Fatalf("Container Maximum Retry Count is %s, expected %s", MaximumRetryCount, "3")
2713         }
2714 }
2715
2716 func (s *DockerSuite) TestRunContainerWithWritableRootfs(c *check.C) {
2717         dockerCmd(c, "run", "--rm", "busybox", "touch", "/file")
2718 }
2719
2720 func (s *DockerSuite) TestRunContainerWithReadonlyRootfs(c *check.C) {
2721         // Not applicable on Windows which does not support --read-only
2722         testRequires(c, DaemonIsLinux, UserNamespaceROMount)
2723
2724         testPriv := true
2725         // don't test privileged mode subtest if user namespaces enabled
2726         if root := os.Getenv("DOCKER_REMAP_ROOT"); root != "" {
2727                 testPriv = false
2728         }
2729         testReadOnlyFile(c, testPriv, "/file", "/etc/hosts", "/etc/resolv.conf", "/etc/hostname", "/sys/kernel", "/dev/.dont.touch.me")
2730 }
2731
2732 func (s *DockerSuite) TestPermissionsPtsReadonlyRootfs(c *check.C) {
2733         // Not applicable on Windows due to use of Unix specific functionality, plus
2734         // the use of --read-only which is not supported.
2735         testRequires(c, DaemonIsLinux, UserNamespaceROMount)
2736
2737         // Ensure we have not broken writing /dev/pts
2738         out, status := dockerCmd(c, "run", "--read-only", "--rm", "busybox", "mount")
2739         if status != 0 {
2740                 c.Fatal("Could not obtain mounts when checking /dev/pts mntpnt.")
2741         }
2742         expected := "type devpts (rw,"
2743         if !strings.Contains(string(out), expected) {
2744                 c.Fatalf("expected output to contain %s but contains %s", expected, out)
2745         }
2746 }
2747
2748 func testReadOnlyFile(c *check.C, testPriv bool, filenames ...string) {
2749         touch := "touch " + strings.Join(filenames, " ")
2750         out, _, err := dockerCmdWithError("run", "--read-only", "--rm", "busybox", "sh", "-c", touch)
2751         c.Assert(err, checker.NotNil)
2752
2753         for _, f := range filenames {
2754                 expected := "touch: " + f + ": Read-only file system"
2755                 c.Assert(out, checker.Contains, expected)
2756         }
2757
2758         if !testPriv {
2759                 return
2760         }
2761
2762         out, _, err = dockerCmdWithError("run", "--read-only", "--privileged", "--rm", "busybox", "sh", "-c", touch)
2763         c.Assert(err, checker.NotNil)
2764
2765         for _, f := range filenames {
2766                 expected := "touch: " + f + ": Read-only file system"
2767                 c.Assert(out, checker.Contains, expected)
2768         }
2769 }
2770
2771 func (s *DockerSuite) TestRunContainerWithReadonlyEtcHostsAndLinkedContainer(c *check.C) {
2772         // Not applicable on Windows which does not support --link
2773         testRequires(c, DaemonIsLinux, UserNamespaceROMount)
2774
2775         dockerCmd(c, "run", "-d", "--name", "test-etc-hosts-ro-linked", "busybox", "top")
2776
2777         out, _ := dockerCmd(c, "run", "--read-only", "--link", "test-etc-hosts-ro-linked:testlinked", "busybox", "cat", "/etc/hosts")
2778         if !strings.Contains(string(out), "testlinked") {
2779                 c.Fatal("Expected /etc/hosts to be updated even if --read-only enabled")
2780         }
2781 }
2782
2783 func (s *DockerSuite) TestRunContainerWithReadonlyRootfsWithDNSFlag(c *check.C) {
2784         // Not applicable on Windows which does not support either --read-only or --dns.
2785         testRequires(c, DaemonIsLinux, UserNamespaceROMount)
2786
2787         out, _ := dockerCmd(c, "run", "--read-only", "--dns", "1.1.1.1", "busybox", "/bin/cat", "/etc/resolv.conf")
2788         if !strings.Contains(string(out), "1.1.1.1") {
2789                 c.Fatal("Expected /etc/resolv.conf to be updated even if --read-only enabled and --dns flag used")
2790         }
2791 }
2792
2793 func (s *DockerSuite) TestRunContainerWithReadonlyRootfsWithAddHostFlag(c *check.C) {
2794         // Not applicable on Windows which does not support --read-only
2795         testRequires(c, DaemonIsLinux, UserNamespaceROMount)
2796
2797         out, _ := dockerCmd(c, "run", "--read-only", "--add-host", "testreadonly:127.0.0.1", "busybox", "/bin/cat", "/etc/hosts")
2798         if !strings.Contains(string(out), "testreadonly") {
2799                 c.Fatal("Expected /etc/hosts to be updated even if --read-only enabled and --add-host flag used")
2800         }
2801 }
2802
2803 func (s *DockerSuite) TestRunVolumesFromRestartAfterRemoved(c *check.C) {
2804         prefix, _ := getPrefixAndSlashFromDaemonPlatform()
2805         runSleepingContainer(c, "--name=voltest", "-v", prefix+"/foo")
2806         runSleepingContainer(c, "--name=restarter", "--volumes-from", "voltest")
2807
2808         // Remove the main volume container and restart the consuming container
2809         dockerCmd(c, "rm", "-f", "voltest")
2810
2811         // This should not fail since the volumes-from were already applied
2812         dockerCmd(c, "restart", "restarter")
2813 }
2814
2815 // run container with --rm should remove container if exit code != 0
2816 func (s *DockerSuite) TestRunContainerWithRmFlagExitCodeNotEqualToZero(c *check.C) {
2817         name := "flowers"
2818         cli.Docker(cli.Args("run", "--name", name, "--rm", "busybox", "ls", "/notexists")).Assert(c, icmd.Expected{
2819                 ExitCode: 1,
2820         })
2821
2822         out := cli.DockerCmd(c, "ps", "-q", "-a").Combined()
2823         if out != "" {
2824                 c.Fatal("Expected not to have containers", out)
2825         }
2826 }
2827
2828 func (s *DockerSuite) TestRunContainerWithRmFlagCannotStartContainer(c *check.C) {
2829         name := "sparkles"
2830         cli.Docker(cli.Args("run", "--name", name, "--rm", "busybox", "commandNotFound")).Assert(c, icmd.Expected{
2831                 ExitCode: 127,
2832         })
2833         out := cli.DockerCmd(c, "ps", "-q", "-a").Combined()
2834         if out != "" {
2835                 c.Fatal("Expected not to have containers", out)
2836         }
2837 }
2838
2839 func (s *DockerSuite) TestRunPIDHostWithChildIsKillable(c *check.C) {
2840         // Not applicable on Windows as uses Unix specific functionality
2841         testRequires(c, DaemonIsLinux, NotUserNamespace)
2842         name := "ibuildthecloud"
2843         dockerCmd(c, "run", "-d", "--pid=host", "--name", name, "busybox", "sh", "-c", "sleep 30; echo hi")
2844
2845         c.Assert(waitRun(name), check.IsNil)
2846
2847         errchan := make(chan error)
2848         go func() {
2849                 if out, _, err := dockerCmdWithError("kill", name); err != nil {
2850                         errchan <- fmt.Errorf("%v:\n%s", err, out)
2851                 }
2852                 close(errchan)
2853         }()
2854         select {
2855         case err := <-errchan:
2856                 c.Assert(err, check.IsNil)
2857         case <-time.After(5 * time.Second):
2858                 c.Fatal("Kill container timed out")
2859         }
2860 }
2861
2862 func (s *DockerSuite) TestRunWithTooSmallMemoryLimit(c *check.C) {
2863         // TODO Windows. This may be possible to enable once Windows supports
2864         // memory limits on containers
2865         testRequires(c, DaemonIsLinux)
2866         // this memory limit is 1 byte less than the min, which is 4MB
2867         // https://github.com/docker/docker/blob/v1.5.0/daemon/create.go#L22
2868         out, _, err := dockerCmdWithError("run", "-m", "4194303", "busybox")
2869         if err == nil || !strings.Contains(out, "Minimum memory limit allowed is 4MB") {
2870                 c.Fatalf("expected run to fail when using too low a memory limit: %q", out)
2871         }
2872 }
2873
2874 func (s *DockerSuite) TestRunWriteToProcAsound(c *check.C) {
2875         // Not applicable on Windows as uses Unix specific functionality
2876         testRequires(c, DaemonIsLinux)
2877         _, code, err := dockerCmdWithError("run", "busybox", "sh", "-c", "echo 111 >> /proc/asound/version")
2878         if err == nil || code == 0 {
2879                 c.Fatal("standard container should not be able to write to /proc/asound")
2880         }
2881 }
2882
2883 func (s *DockerSuite) TestRunReadProcTimer(c *check.C) {
2884         // Not applicable on Windows as uses Unix specific functionality
2885         testRequires(c, DaemonIsLinux)
2886         out, code, err := dockerCmdWithError("run", "busybox", "cat", "/proc/timer_stats")
2887         if code != 0 {
2888                 return
2889         }
2890         if err != nil {
2891                 c.Fatal(err)
2892         }
2893         if strings.Trim(out, "\n ") != "" {
2894                 c.Fatalf("expected to receive no output from /proc/timer_stats but received %q", out)
2895         }
2896 }
2897
2898 func (s *DockerSuite) TestRunReadProcLatency(c *check.C) {
2899         // Not applicable on Windows as uses Unix specific functionality
2900         testRequires(c, DaemonIsLinux)
2901         // some kernels don't have this configured so skip the test if this file is not found
2902         // on the host running the tests.
2903         if _, err := os.Stat("/proc/latency_stats"); err != nil {
2904                 c.Skip("kernel doesn't have latency_stats configured")
2905                 return
2906         }
2907         out, code, err := dockerCmdWithError("run", "busybox", "cat", "/proc/latency_stats")
2908         if code != 0 {
2909                 return
2910         }
2911         if err != nil {
2912                 c.Fatal(err)
2913         }
2914         if strings.Trim(out, "\n ") != "" {
2915                 c.Fatalf("expected to receive no output from /proc/latency_stats but received %q", out)
2916         }
2917 }
2918
2919 func (s *DockerSuite) TestRunReadFilteredProc(c *check.C) {
2920         // Not applicable on Windows as uses Unix specific functionality
2921         testRequires(c, Apparmor, DaemonIsLinux, NotUserNamespace)
2922
2923         testReadPaths := []string{
2924                 "/proc/latency_stats",
2925                 "/proc/timer_stats",
2926                 "/proc/kcore",
2927         }
2928         for i, filePath := range testReadPaths {
2929                 name := fmt.Sprintf("procsieve-%d", i)
2930                 shellCmd := fmt.Sprintf("exec 3<%s", filePath)
2931
2932                 out, exitCode, err := dockerCmdWithError("run", "--privileged", "--security-opt", "apparmor=docker-default", "--name", name, "busybox", "sh", "-c", shellCmd)
2933                 if exitCode != 0 {
2934                         return
2935                 }
2936                 if err != nil {
2937                         c.Fatalf("Open FD for read should have failed with permission denied, got: %s, %v", out, err)
2938                 }
2939         }
2940 }
2941
2942 func (s *DockerSuite) TestMountIntoProc(c *check.C) {
2943         // Not applicable on Windows as uses Unix specific functionality
2944         testRequires(c, DaemonIsLinux)
2945         _, code, err := dockerCmdWithError("run", "-v", "/proc//sys", "busybox", "true")
2946         if err == nil || code == 0 {
2947                 c.Fatal("container should not be able to mount into /proc")
2948         }
2949 }
2950
2951 func (s *DockerSuite) TestMountIntoSys(c *check.C) {
2952         // Not applicable on Windows as uses Unix specific functionality
2953         testRequires(c, DaemonIsLinux)
2954         testRequires(c, NotUserNamespace)
2955         dockerCmd(c, "run", "-v", "/sys/fs/cgroup", "busybox", "true")
2956 }
2957
2958 func (s *DockerSuite) TestRunUnshareProc(c *check.C) {
2959         // Not applicable on Windows as uses Unix specific functionality
2960         testRequires(c, Apparmor, DaemonIsLinux, NotUserNamespace)
2961
2962         // In this test goroutines are used to run test cases in parallel to prevent the test from taking a long time to run.
2963         errChan := make(chan error)
2964
2965         go func() {
2966                 name := "acidburn"
2967                 out, _, err := dockerCmdWithError("run", "--name", name, "--security-opt", "seccomp=unconfined", "debian:jessie", "unshare", "-p", "-m", "-f", "-r", "--mount-proc=/proc", "mount")
2968                 if err == nil ||
2969                         !(strings.Contains(strings.ToLower(out), "permission denied") ||
2970                                 strings.Contains(strings.ToLower(out), "operation not permitted")) {
2971                         errChan <- fmt.Errorf("unshare with --mount-proc should have failed with 'permission denied' or 'operation not permitted', got: %s, %v", out, err)
2972                 } else {
2973                         errChan <- nil
2974                 }
2975         }()
2976
2977         go func() {
2978                 name := "cereal"
2979                 out, _, err := dockerCmdWithError("run", "--name", name, "--security-opt", "seccomp=unconfined", "debian:jessie", "unshare", "-p", "-m", "-f", "-r", "mount", "-t", "proc", "none", "/proc")
2980                 if err == nil ||
2981                         !(strings.Contains(strings.ToLower(out), "mount: cannot mount none") ||
2982                                 strings.Contains(strings.ToLower(out), "permission denied") ||
2983                                 strings.Contains(strings.ToLower(out), "operation not permitted")) {
2984                         errChan <- fmt.Errorf("unshare and mount of /proc should have failed with 'mount: cannot mount none' or 'permission denied', got: %s, %v", out, err)
2985                 } else {
2986                         errChan <- nil
2987                 }
2988         }()
2989
2990         /* Ensure still fails if running privileged with the default policy */
2991         go func() {
2992                 name := "crashoverride"
2993                 out, _, err := dockerCmdWithError("run", "--privileged", "--security-opt", "seccomp=unconfined", "--security-opt", "apparmor=docker-default", "--name", name, "debian:jessie", "unshare", "-p", "-m", "-f", "-r", "mount", "-t", "proc", "none", "/proc")
2994                 if err == nil ||
2995                         !(strings.Contains(strings.ToLower(out), "mount: cannot mount none") ||
2996                                 strings.Contains(strings.ToLower(out), "permission denied") ||
2997                                 strings.Contains(strings.ToLower(out), "operation not permitted")) {
2998                         errChan <- fmt.Errorf("privileged unshare with apparmor should have failed with 'mount: cannot mount none' or 'permission denied', got: %s, %v", out, err)
2999                 } else {
3000                         errChan <- nil
3001                 }
3002         }()
3003
3004         var retErr error
3005         for i := 0; i < 3; i++ {
3006                 err := <-errChan
3007                 if retErr == nil && err != nil {
3008                         retErr = err
3009                 }
3010         }
3011         if retErr != nil {
3012                 c.Fatal(retErr)
3013         }
3014 }
3015
3016 func (s *DockerSuite) TestRunPublishPort(c *check.C) {
3017         // TODO Windows: This may be possible once Windows moves to libnetwork and CNM
3018         testRequires(c, DaemonIsLinux)
3019         dockerCmd(c, "run", "-d", "--name", "test", "--expose", "8080", "busybox", "top")
3020         out, _ := dockerCmd(c, "port", "test")
3021         out = strings.Trim(out, "\r\n")
3022         if out != "" {
3023                 c.Fatalf("run without --publish-all should not publish port, out should be nil, but got: %s", out)
3024         }
3025 }
3026
3027 // Issue #10184.
3028 func (s *DockerSuite) TestDevicePermissions(c *check.C) {
3029         // Not applicable on Windows as uses Unix specific functionality
3030         testRequires(c, DaemonIsLinux)
3031         const permissions = "crw-rw-rw-"
3032         out, status := dockerCmd(c, "run", "--device", "/dev/fuse:/dev/fuse:mrw", "busybox:latest", "ls", "-l", "/dev/fuse")
3033         if status != 0 {
3034                 c.Fatalf("expected status 0, got %d", status)
3035         }
3036         if !strings.HasPrefix(out, permissions) {
3037                 c.Fatalf("output should begin with %q, got %q", permissions, out)
3038         }
3039 }
3040
3041 func (s *DockerSuite) TestRunCapAddCHOWN(c *check.C) {
3042         // Not applicable on Windows as uses Unix specific functionality
3043         testRequires(c, DaemonIsLinux)
3044         out, _ := dockerCmd(c, "run", "--cap-drop=ALL", "--cap-add=CHOWN", "busybox", "sh", "-c", "adduser -D -H newuser && chown newuser /home && echo ok")
3045
3046         if actual := strings.Trim(out, "\r\n"); actual != "ok" {
3047                 c.Fatalf("expected output ok received %s", actual)
3048         }
3049 }
3050
3051 // https://github.com/docker/docker/pull/14498
3052 func (s *DockerSuite) TestVolumeFromMixedRWOptions(c *check.C) {
3053         prefix, slash := getPrefixAndSlashFromDaemonPlatform()
3054
3055         dockerCmd(c, "run", "--name", "parent", "-v", prefix+"/test", "busybox", "true")
3056
3057         dockerCmd(c, "run", "--volumes-from", "parent:ro", "--name", "test-volumes-1", "busybox", "true")
3058         dockerCmd(c, "run", "--volumes-from", "parent:rw", "--name", "test-volumes-2", "busybox", "true")
3059
3060         if testEnv.DaemonPlatform() != "windows" {
3061                 mRO, err := inspectMountPoint("test-volumes-1", prefix+slash+"test")
3062                 c.Assert(err, checker.IsNil, check.Commentf("failed to inspect mount point"))
3063                 if mRO.RW {
3064                         c.Fatalf("Expected RO volume was RW")
3065                 }
3066         }
3067
3068         mRW, err := inspectMountPoint("test-volumes-2", prefix+slash+"test")
3069         c.Assert(err, checker.IsNil, check.Commentf("failed to inspect mount point"))
3070         if !mRW.RW {
3071                 c.Fatalf("Expected RW volume was RO")
3072         }
3073 }
3074
3075 func (s *DockerSuite) TestRunWriteFilteredProc(c *check.C) {
3076         // Not applicable on Windows as uses Unix specific functionality
3077         testRequires(c, Apparmor, DaemonIsLinux, NotUserNamespace)
3078
3079         testWritePaths := []string{
3080                 /* modprobe and core_pattern should both be denied by generic
3081                  * policy of denials for /proc/sys/kernel. These files have been
3082                  * picked to be checked as they are particularly sensitive to writes */
3083                 "/proc/sys/kernel/modprobe",
3084                 "/proc/sys/kernel/core_pattern",
3085                 "/proc/sysrq-trigger",
3086                 "/proc/kcore",
3087         }
3088         for i, filePath := range testWritePaths {
3089                 name := fmt.Sprintf("writeprocsieve-%d", i)
3090
3091                 shellCmd := fmt.Sprintf("exec 3>%s", filePath)
3092                 out, code, err := dockerCmdWithError("run", "--privileged", "--security-opt", "apparmor=docker-default", "--name", name, "busybox", "sh", "-c", shellCmd)
3093                 if code != 0 {
3094                         return
3095                 }
3096                 if err != nil {
3097                         c.Fatalf("Open FD for write should have failed with permission denied, got: %s, %v", out, err)
3098                 }
3099         }
3100 }
3101
3102 func (s *DockerSuite) TestRunNetworkFilesBindMount(c *check.C) {
3103         // Not applicable on Windows as uses Unix specific functionality
3104         testRequires(c, SameHostDaemon, DaemonIsLinux)
3105
3106         expected := "test123"
3107
3108         filename := createTmpFile(c, expected)
3109         defer os.Remove(filename)
3110
3111         nwfiles := []string{"/etc/resolv.conf", "/etc/hosts", "/etc/hostname"}
3112
3113         for i := range nwfiles {
3114                 actual, _ := dockerCmd(c, "run", "-v", filename+":"+nwfiles[i], "busybox", "cat", nwfiles[i])
3115                 if actual != expected {
3116                         c.Fatalf("expected %s be: %q, but was: %q", nwfiles[i], expected, actual)
3117                 }
3118         }
3119 }
3120
3121 func (s *DockerSuite) TestRunNetworkFilesBindMountRO(c *check.C) {
3122         // Not applicable on Windows as uses Unix specific functionality
3123         testRequires(c, SameHostDaemon, DaemonIsLinux)
3124
3125         filename := createTmpFile(c, "test123")
3126         defer os.Remove(filename)
3127
3128         nwfiles := []string{"/etc/resolv.conf", "/etc/hosts", "/etc/hostname"}
3129
3130         for i := range nwfiles {
3131                 _, exitCode, err := dockerCmdWithError("run", "-v", filename+":"+nwfiles[i]+":ro", "busybox", "touch", nwfiles[i])
3132                 if err == nil || exitCode == 0 {
3133                         c.Fatalf("run should fail because bind mount of %s is ro: exit code %d", nwfiles[i], exitCode)
3134                 }
3135         }
3136 }
3137
3138 func (s *DockerSuite) TestRunNetworkFilesBindMountROFilesystem(c *check.C) {
3139         // Not applicable on Windows as uses Unix specific functionality
3140         testRequires(c, SameHostDaemon, DaemonIsLinux, UserNamespaceROMount)
3141
3142         filename := createTmpFile(c, "test123")
3143         defer os.Remove(filename)
3144
3145         nwfiles := []string{"/etc/resolv.conf", "/etc/hosts", "/etc/hostname"}
3146
3147         for i := range nwfiles {
3148                 _, exitCode := dockerCmd(c, "run", "-v", filename+":"+nwfiles[i], "--read-only", "busybox", "touch", nwfiles[i])
3149                 if exitCode != 0 {
3150                         c.Fatalf("run should not fail because %s is mounted writable on read-only root filesystem: exit code %d", nwfiles[i], exitCode)
3151                 }
3152         }
3153
3154         for i := range nwfiles {
3155                 _, exitCode, err := dockerCmdWithError("run", "-v", filename+":"+nwfiles[i]+":ro", "--read-only", "busybox", "touch", nwfiles[i])
3156                 if err == nil || exitCode == 0 {
3157                         c.Fatalf("run should fail because %s is mounted read-only on read-only root filesystem: exit code %d", nwfiles[i], exitCode)
3158                 }
3159         }
3160 }
3161
3162 func (s *DockerTrustSuite) TestTrustedRun(c *check.C) {
3163         // Windows does not support this functionality
3164         testRequires(c, DaemonIsLinux)
3165         repoName := s.setupTrustedImage(c, "trusted-run")
3166
3167         // Try run
3168         cli.Docker(cli.Args("run", repoName), trustedCmd).Assert(c, SuccessTagging)
3169         cli.DockerCmd(c, "rmi", repoName)
3170
3171         // Try untrusted run to ensure we pushed the tag to the registry
3172         cli.Docker(cli.Args("run", "--disable-content-trust=true", repoName), trustedCmd).Assert(c, SuccessDownloadedOnStderr)
3173 }
3174
3175 func (s *DockerTrustSuite) TestUntrustedRun(c *check.C) {
3176         // Windows does not support this functionality
3177         testRequires(c, DaemonIsLinux)
3178         repoName := fmt.Sprintf("%v/dockercliuntrusted/runtest:latest", privateRegistryURL)
3179         // tag the image and upload it to the private registry
3180         cli.DockerCmd(c, "tag", "busybox", repoName)
3181         cli.DockerCmd(c, "push", repoName)
3182         cli.DockerCmd(c, "rmi", repoName)
3183
3184         // Try trusted run on untrusted tag
3185         cli.Docker(cli.Args("run", repoName), trustedCmd).Assert(c, icmd.Expected{
3186                 ExitCode: 125,
3187                 Err:      "does not have trust data for",
3188         })
3189 }
3190
3191 func (s *DockerTrustSuite) TestTrustedRunFromBadTrustServer(c *check.C) {
3192         // Windows does not support this functionality
3193         testRequires(c, DaemonIsLinux)
3194         repoName := fmt.Sprintf("%v/dockerclievilrun/trusted:latest", privateRegistryURL)
3195         evilLocalConfigDir, err := ioutil.TempDir("", "evilrun-local-config-dir")
3196         if err != nil {
3197                 c.Fatalf("Failed to create local temp dir")
3198         }
3199
3200         // tag the image and upload it to the private registry
3201         cli.DockerCmd(c, "tag", "busybox", repoName)
3202
3203         cli.Docker(cli.Args("push", repoName), trustedCmd).Assert(c, SuccessSigningAndPushing)
3204         cli.DockerCmd(c, "rmi", repoName)
3205
3206         // Try run
3207         cli.Docker(cli.Args("run", repoName), trustedCmd).Assert(c, SuccessTagging)
3208         cli.DockerCmd(c, "rmi", repoName)
3209
3210         // Kill the notary server, start a new "evil" one.
3211         s.not.Close()
3212         s.not, err = newTestNotary(c)
3213         if err != nil {
3214                 c.Fatalf("Restarting notary server failed.")
3215         }
3216
3217         // In order to make an evil server, lets re-init a client (with a different trust dir) and push new data.
3218         // tag an image and upload it to the private registry
3219         cli.DockerCmd(c, "--config", evilLocalConfigDir, "tag", "busybox", repoName)
3220
3221         // Push up to the new server
3222         cli.Docker(cli.Args("--config", evilLocalConfigDir, "push", repoName), trustedCmd).Assert(c, SuccessSigningAndPushing)
3223
3224         // Now, try running with the original client from this new trust server. This should fail because the new root is invalid.
3225         cli.Docker(cli.Args("run", repoName), trustedCmd).Assert(c, icmd.Expected{
3226                 ExitCode: 125,
3227                 Err:      "could not rotate trust to a new trusted root",
3228         })
3229 }
3230
3231 func (s *DockerSuite) TestPtraceContainerProcsFromHost(c *check.C) {
3232         // Not applicable on Windows as uses Unix specific functionality
3233         testRequires(c, DaemonIsLinux, SameHostDaemon)
3234
3235         out, _ := dockerCmd(c, "run", "-d", "busybox", "top")
3236         id := strings.TrimSpace(out)
3237         c.Assert(waitRun(id), check.IsNil)
3238         pid1 := inspectField(c, id, "State.Pid")
3239
3240         _, err := os.Readlink(fmt.Sprintf("/proc/%s/ns/net", pid1))
3241         if err != nil {
3242                 c.Fatal(err)
3243         }
3244 }
3245
3246 func (s *DockerSuite) TestAppArmorDeniesPtrace(c *check.C) {
3247         // Not applicable on Windows as uses Unix specific functionality
3248         testRequires(c, SameHostDaemon, Apparmor, DaemonIsLinux)
3249
3250         // Run through 'sh' so we are NOT pid 1. Pid 1 may be able to trace
3251         // itself, but pid>1 should not be able to trace pid1.
3252         _, exitCode, _ := dockerCmdWithError("run", "busybox", "sh", "-c", "sh -c readlink /proc/1/ns/net")
3253         if exitCode == 0 {
3254                 c.Fatal("ptrace was not successfully restricted by AppArmor")
3255         }
3256 }
3257
3258 func (s *DockerSuite) TestAppArmorTraceSelf(c *check.C) {
3259         // Not applicable on Windows as uses Unix specific functionality
3260         testRequires(c, DaemonIsLinux, SameHostDaemon, Apparmor)
3261
3262         _, exitCode, _ := dockerCmdWithError("run", "busybox", "readlink", "/proc/1/ns/net")
3263         if exitCode != 0 {
3264                 c.Fatal("ptrace of self failed.")
3265         }
3266 }
3267
3268 func (s *DockerSuite) TestAppArmorDeniesChmodProc(c *check.C) {
3269         // Not applicable on Windows as uses Unix specific functionality
3270         testRequires(c, SameHostDaemon, Apparmor, DaemonIsLinux, NotUserNamespace)
3271         _, exitCode, _ := dockerCmdWithError("run", "busybox", "chmod", "744", "/proc/cpuinfo")
3272         if exitCode == 0 {
3273                 // If our test failed, attempt to repair the host system...
3274                 _, exitCode, _ := dockerCmdWithError("run", "busybox", "chmod", "444", "/proc/cpuinfo")
3275                 if exitCode == 0 {
3276                         c.Fatal("AppArmor was unsuccessful in prohibiting chmod of /proc/* files.")
3277                 }
3278         }
3279 }
3280
3281 func (s *DockerSuite) TestRunCapAddSYSTIME(c *check.C) {
3282         // Not applicable on Windows as uses Unix specific functionality
3283         testRequires(c, DaemonIsLinux)
3284
3285         dockerCmd(c, "run", "--cap-drop=ALL", "--cap-add=SYS_TIME", "busybox", "sh", "-c", "grep ^CapEff /proc/self/status | sed 's/^CapEff:\t//' | grep ^0000000002000000$")
3286 }
3287
3288 // run create container failed should clean up the container
3289 func (s *DockerSuite) TestRunCreateContainerFailedCleanUp(c *check.C) {
3290         // TODO Windows. This may be possible to enable once link is supported
3291         testRequires(c, DaemonIsLinux)
3292         name := "unique_name"
3293         _, _, err := dockerCmdWithError("run", "--name", name, "--link", "nothing:nothing", "busybox")
3294         c.Assert(err, check.NotNil, check.Commentf("Expected docker run to fail!"))
3295
3296         containerID, err := inspectFieldWithError(name, "Id")
3297         c.Assert(err, checker.NotNil, check.Commentf("Expected not to have this container: %s!", containerID))
3298         c.Assert(containerID, check.Equals, "", check.Commentf("Expected not to have this container: %s!", containerID))
3299 }
3300
3301 func (s *DockerSuite) TestRunNamedVolume(c *check.C) {
3302         prefix, _ := getPrefixAndSlashFromDaemonPlatform()
3303         testRequires(c, DaemonIsLinux)
3304         dockerCmd(c, "run", "--name=test", "-v", "testing:"+prefix+"/foo", "busybox", "sh", "-c", "echo hello > "+prefix+"/foo/bar")
3305
3306         out, _ := dockerCmd(c, "run", "--volumes-from", "test", "busybox", "sh", "-c", "cat "+prefix+"/foo/bar")
3307         c.Assert(strings.TrimSpace(out), check.Equals, "hello")
3308
3309         out, _ = dockerCmd(c, "run", "-v", "testing:"+prefix+"/foo", "busybox", "sh", "-c", "cat "+prefix+"/foo/bar")
3310         c.Assert(strings.TrimSpace(out), check.Equals, "hello")
3311 }
3312
3313 func (s *DockerSuite) TestRunWithUlimits(c *check.C) {
3314         // Not applicable on Windows as uses Unix specific functionality
3315         testRequires(c, DaemonIsLinux)
3316
3317         out, _ := dockerCmd(c, "run", "--name=testulimits", "--ulimit", "nofile=42", "busybox", "/bin/sh", "-c", "ulimit -n")
3318         ul := strings.TrimSpace(out)
3319         if ul != "42" {
3320                 c.Fatalf("expected `ulimit -n` to be 42, got %s", ul)
3321         }
3322 }
3323
3324 func (s *DockerSuite) TestRunContainerWithCgroupParent(c *check.C) {
3325         // Not applicable on Windows as uses Unix specific functionality
3326         testRequires(c, DaemonIsLinux)
3327
3328         // cgroup-parent relative path
3329         testRunContainerWithCgroupParent(c, "test", "cgroup-test")
3330
3331         // cgroup-parent absolute path
3332         testRunContainerWithCgroupParent(c, "/cgroup-parent/test", "cgroup-test-absolute")
3333 }
3334
3335 func testRunContainerWithCgroupParent(c *check.C, cgroupParent, name string) {
3336         out, _, err := dockerCmdWithError("run", "--cgroup-parent", cgroupParent, "--name", name, "busybox", "cat", "/proc/self/cgroup")
3337         if err != nil {
3338                 c.Fatalf("unexpected failure when running container with --cgroup-parent option - %s\n%v", string(out), err)
3339         }
3340         cgroupPaths := testutil.ParseCgroupPaths(string(out))
3341         if len(cgroupPaths) == 0 {
3342                 c.Fatalf("unexpected output - %q", string(out))
3343         }
3344         id := getIDByName(c, name)
3345         expectedCgroup := path.Join(cgroupParent, id)
3346         found := false
3347         for _, path := range cgroupPaths {
3348                 if strings.HasSuffix(path, expectedCgroup) {
3349                         found = true
3350                         break
3351                 }
3352         }
3353         if !found {
3354                 c.Fatalf("unexpected cgroup paths. Expected at least one cgroup path to have suffix %q. Cgroup Paths: %v", expectedCgroup, cgroupPaths)
3355         }
3356 }
3357
3358 // TestRunInvalidCgroupParent checks that a specially-crafted cgroup parent doesn't cause Docker to crash or start modifying /.
3359 func (s *DockerSuite) TestRunInvalidCgroupParent(c *check.C) {
3360         // Not applicable on Windows as uses Unix specific functionality
3361         testRequires(c, DaemonIsLinux)
3362
3363         testRunInvalidCgroupParent(c, "../../../../../../../../SHOULD_NOT_EXIST", "SHOULD_NOT_EXIST", "cgroup-invalid-test")
3364
3365         testRunInvalidCgroupParent(c, "/../../../../../../../../SHOULD_NOT_EXIST", "/SHOULD_NOT_EXIST", "cgroup-absolute-invalid-test")
3366 }
3367
3368 func testRunInvalidCgroupParent(c *check.C, cgroupParent, cleanCgroupParent, name string) {
3369         out, _, err := dockerCmdWithError("run", "--cgroup-parent", cgroupParent, "--name", name, "busybox", "cat", "/proc/self/cgroup")
3370         if err != nil {
3371                 // XXX: This may include a daemon crash.
3372                 c.Fatalf("unexpected failure when running container with --cgroup-parent option - %s\n%v", string(out), err)
3373         }
3374
3375         // We expect "/SHOULD_NOT_EXIST" to not exist. If not, we have a security issue.
3376         if _, err := os.Stat("/SHOULD_NOT_EXIST"); err == nil || !os.IsNotExist(err) {
3377                 c.Fatalf("SECURITY: --cgroup-parent with ../../ relative paths cause files to be created in the host (this is bad) !!")
3378         }
3379
3380         cgroupPaths := testutil.ParseCgroupPaths(string(out))
3381         if len(cgroupPaths) == 0 {
3382                 c.Fatalf("unexpected output - %q", string(out))
3383         }
3384         id := getIDByName(c, name)
3385         expectedCgroup := path.Join(cleanCgroupParent, id)
3386         found := false
3387         for _, path := range cgroupPaths {
3388                 if strings.HasSuffix(path, expectedCgroup) {
3389                         found = true
3390                         break
3391                 }
3392         }
3393         if !found {
3394                 c.Fatalf("unexpected cgroup paths. Expected at least one cgroup path to have suffix %q. Cgroup Paths: %v", expectedCgroup, cgroupPaths)
3395         }
3396 }
3397
3398 func (s *DockerSuite) TestRunContainerWithCgroupMountRO(c *check.C) {
3399         // Not applicable on Windows as uses Unix specific functionality
3400         // --read-only + userns has remount issues
3401         testRequires(c, DaemonIsLinux, NotUserNamespace)
3402
3403         filename := "/sys/fs/cgroup/devices/test123"
3404         out, _, err := dockerCmdWithError("run", "busybox", "touch", filename)
3405         if err == nil {
3406                 c.Fatal("expected cgroup mount point to be read-only, touch file should fail")
3407         }
3408         expected := "Read-only file system"
3409         if !strings.Contains(out, expected) {
3410                 c.Fatalf("expected output from failure to contain %s but contains %s", expected, out)
3411         }
3412 }
3413
3414 func (s *DockerSuite) TestRunContainerNetworkModeToSelf(c *check.C) {
3415         // Not applicable on Windows which does not support --net=container
3416         testRequires(c, DaemonIsLinux)
3417         out, _, err := dockerCmdWithError("run", "--name=me", "--net=container:me", "busybox", "true")
3418         if err == nil || !strings.Contains(out, "cannot join own network") {
3419                 c.Fatalf("using container net mode to self should result in an error\nerr: %q\nout: %s", err, out)
3420         }
3421 }
3422
3423 func (s *DockerSuite) TestRunContainerNetModeWithDNSMacHosts(c *check.C) {
3424         // Not applicable on Windows which does not support --net=container
3425         testRequires(c, DaemonIsLinux)
3426         out, _, err := dockerCmdWithError("run", "-d", "--name", "parent", "busybox", "top")
3427         if err != nil {
3428                 c.Fatalf("failed to run container: %v, output: %q", err, out)
3429         }
3430
3431         out, _, err = dockerCmdWithError("run", "--dns", "1.2.3.4", "--net=container:parent", "busybox")
3432         if err == nil || !strings.Contains(out, runconfig.ErrConflictNetworkAndDNS.Error()) {
3433                 c.Fatalf("run --net=container with --dns should error out")
3434         }
3435
3436         out, _, err = dockerCmdWithError("run", "--mac-address", "92:d0:c6:0a:29:33", "--net=container:parent", "busybox")
3437         if err == nil || !strings.Contains(out, runconfig.ErrConflictContainerNetworkAndMac.Error()) {
3438                 c.Fatalf("run --net=container with --mac-address should error out")
3439         }
3440
3441         out, _, err = dockerCmdWithError("run", "--add-host", "test:192.168.2.109", "--net=container:parent", "busybox")
3442         if err == nil || !strings.Contains(out, runconfig.ErrConflictNetworkHosts.Error()) {
3443                 c.Fatalf("run --net=container with --add-host should error out")
3444         }
3445 }
3446
3447 func (s *DockerSuite) TestRunContainerNetModeWithExposePort(c *check.C) {
3448         // Not applicable on Windows which does not support --net=container
3449         testRequires(c, DaemonIsLinux)
3450         dockerCmd(c, "run", "-d", "--name", "parent", "busybox", "top")
3451
3452         out, _, err := dockerCmdWithError("run", "-p", "5000:5000", "--net=container:parent", "busybox")
3453         if err == nil || !strings.Contains(out, runconfig.ErrConflictNetworkPublishPorts.Error()) {
3454                 c.Fatalf("run --net=container with -p should error out")
3455         }
3456
3457         out, _, err = dockerCmdWithError("run", "-P", "--net=container:parent", "busybox")
3458         if err == nil || !strings.Contains(out, runconfig.ErrConflictNetworkPublishPorts.Error()) {
3459                 c.Fatalf("run --net=container with -P should error out")
3460         }
3461
3462         out, _, err = dockerCmdWithError("run", "--expose", "5000", "--net=container:parent", "busybox")
3463         if err == nil || !strings.Contains(out, runconfig.ErrConflictNetworkExposePorts.Error()) {
3464                 c.Fatalf("run --net=container with --expose should error out")
3465         }
3466 }
3467
3468 func (s *DockerSuite) TestRunLinkToContainerNetMode(c *check.C) {
3469         // Not applicable on Windows which does not support --net=container or --link
3470         testRequires(c, DaemonIsLinux)
3471         dockerCmd(c, "run", "--name", "test", "-d", "busybox", "top")
3472         dockerCmd(c, "run", "--name", "parent", "-d", "--net=container:test", "busybox", "top")
3473         dockerCmd(c, "run", "-d", "--link=parent:parent", "busybox", "top")
3474         dockerCmd(c, "run", "--name", "child", "-d", "--net=container:parent", "busybox", "top")
3475         dockerCmd(c, "run", "-d", "--link=child:child", "busybox", "top")
3476 }
3477
3478 func (s *DockerSuite) TestRunLoopbackOnlyExistsWhenNetworkingDisabled(c *check.C) {
3479         // TODO Windows: This may be possible to convert.
3480         testRequires(c, DaemonIsLinux)
3481         out, _ := dockerCmd(c, "run", "--net=none", "busybox", "ip", "-o", "-4", "a", "show", "up")
3482
3483         var (
3484                 count = 0
3485                 parts = strings.Split(out, "\n")
3486         )
3487
3488         for _, l := range parts {
3489                 if l != "" {
3490                         count++
3491                 }
3492         }
3493
3494         if count != 1 {
3495                 c.Fatalf("Wrong interface count in container %d", count)
3496         }
3497
3498         if !strings.HasPrefix(out, "1: lo") {
3499                 c.Fatalf("Wrong interface in test container: expected [1: lo], got %s", out)
3500         }
3501 }
3502
3503 // Issue #4681
3504 func (s *DockerSuite) TestRunLoopbackWhenNetworkDisabled(c *check.C) {
3505         if testEnv.DaemonPlatform() == "windows" {
3506                 dockerCmd(c, "run", "--net=none", testEnv.MinimalBaseImage(), "ping", "-n", "1", "127.0.0.1")
3507         } else {
3508                 dockerCmd(c, "run", "--net=none", "busybox", "ping", "-c", "1", "127.0.0.1")
3509         }
3510 }
3511
3512 func (s *DockerSuite) TestRunModeNetContainerHostname(c *check.C) {
3513         // Windows does not support --net=container
3514         testRequires(c, DaemonIsLinux, ExecSupport)
3515
3516         dockerCmd(c, "run", "-i", "-d", "--name", "parent", "busybox", "top")
3517         out, _ := dockerCmd(c, "exec", "parent", "cat", "/etc/hostname")
3518         out1, _ := dockerCmd(c, "run", "--net=container:parent", "busybox", "cat", "/etc/hostname")
3519
3520         if out1 != out {
3521                 c.Fatal("containers with shared net namespace should have same hostname")
3522         }
3523 }
3524
3525 func (s *DockerSuite) TestRunNetworkNotInitializedNoneMode(c *check.C) {
3526         // TODO Windows: Network settings are not currently propagated. This may
3527         // be resolved in the future with the move to libnetwork and CNM.
3528         testRequires(c, DaemonIsLinux)
3529         out, _ := dockerCmd(c, "run", "-d", "--net=none", "busybox", "top")
3530         id := strings.TrimSpace(out)
3531         res := inspectField(c, id, "NetworkSettings.Networks.none.IPAddress")
3532         if res != "" {
3533                 c.Fatalf("For 'none' mode network must not be initialized, but container got IP: %s", res)
3534         }
3535 }
3536
3537 func (s *DockerSuite) TestTwoContainersInNetHost(c *check.C) {
3538         // Not applicable as Windows does not support --net=host
3539         testRequires(c, DaemonIsLinux, NotUserNamespace, NotUserNamespace)
3540         dockerCmd(c, "run", "-d", "--net=host", "--name=first", "busybox", "top")
3541         dockerCmd(c, "run", "-d", "--net=host", "--name=second", "busybox", "top")
3542         dockerCmd(c, "stop", "first")
3543         dockerCmd(c, "stop", "second")
3544 }
3545
3546 func (s *DockerSuite) TestContainersInUserDefinedNetwork(c *check.C) {
3547         testRequires(c, DaemonIsLinux, NotUserNamespace, NotArm)
3548         dockerCmd(c, "network", "create", "-d", "bridge", "testnetwork")
3549         dockerCmd(c, "run", "-d", "--net=testnetwork", "--name=first", "busybox", "top")
3550         c.Assert(waitRun("first"), check.IsNil)
3551         dockerCmd(c, "run", "-t", "--net=testnetwork", "--name=second", "busybox", "ping", "-c", "1", "first")
3552 }
3553
3554 func (s *DockerSuite) TestContainersInMultipleNetworks(c *check.C) {
3555         testRequires(c, DaemonIsLinux, NotUserNamespace, NotArm)
3556         // Create 2 networks using bridge driver
3557         dockerCmd(c, "network", "create", "-d", "bridge", "testnetwork1")
3558         dockerCmd(c, "network", "create", "-d", "bridge", "testnetwork2")
3559         // Run and connect containers to testnetwork1
3560         dockerCmd(c, "run", "-d", "--net=testnetwork1", "--name=first", "busybox", "top")
3561         c.Assert(waitRun("first"), check.IsNil)
3562         dockerCmd(c, "run", "-d", "--net=testnetwork1", "--name=second", "busybox", "top")
3563         c.Assert(waitRun("second"), check.IsNil)
3564         // Check connectivity between containers in testnetwork2
3565         dockerCmd(c, "exec", "first", "ping", "-c", "1", "second.testnetwork1")
3566         // Connect containers to testnetwork2
3567         dockerCmd(c, "network", "connect", "testnetwork2", "first")
3568         dockerCmd(c, "network", "connect", "testnetwork2", "second")
3569         // Check connectivity between containers
3570         dockerCmd(c, "exec", "second", "ping", "-c", "1", "first.testnetwork2")
3571 }
3572
3573 func (s *DockerSuite) TestContainersNetworkIsolation(c *check.C) {
3574         testRequires(c, DaemonIsLinux, NotUserNamespace, NotArm)
3575         // Create 2 networks using bridge driver
3576         dockerCmd(c, "network", "create", "-d", "bridge", "testnetwork1")
3577         dockerCmd(c, "network", "create", "-d", "bridge", "testnetwork2")
3578         // Run 1 container in testnetwork1 and another in testnetwork2
3579         dockerCmd(c, "run", "-d", "--net=testnetwork1", "--name=first", "busybox", "top")
3580         c.Assert(waitRun("first"), check.IsNil)
3581         dockerCmd(c, "run", "-d", "--net=testnetwork2", "--name=second", "busybox", "top")
3582         c.Assert(waitRun("second"), check.IsNil)
3583
3584         // Check Isolation between containers : ping must fail
3585         _, _, err := dockerCmdWithError("exec", "first", "ping", "-c", "1", "second")
3586         c.Assert(err, check.NotNil)
3587         // Connect first container to testnetwork2
3588         dockerCmd(c, "network", "connect", "testnetwork2", "first")
3589         // ping must succeed now
3590         _, _, err = dockerCmdWithError("exec", "first", "ping", "-c", "1", "second")
3591         c.Assert(err, check.IsNil)
3592
3593         // Disconnect first container from testnetwork2
3594         dockerCmd(c, "network", "disconnect", "testnetwork2", "first")
3595         // ping must fail again
3596         _, _, err = dockerCmdWithError("exec", "first", "ping", "-c", "1", "second")
3597         c.Assert(err, check.NotNil)
3598 }
3599
3600 func (s *DockerSuite) TestNetworkRmWithActiveContainers(c *check.C) {
3601         testRequires(c, DaemonIsLinux, NotUserNamespace)
3602         // Create 2 networks using bridge driver
3603         dockerCmd(c, "network", "create", "-d", "bridge", "testnetwork1")
3604         // Run and connect containers to testnetwork1
3605         dockerCmd(c, "run", "-d", "--net=testnetwork1", "--name=first", "busybox", "top")
3606         c.Assert(waitRun("first"), check.IsNil)
3607         dockerCmd(c, "run", "-d", "--net=testnetwork1", "--name=second", "busybox", "top")
3608         c.Assert(waitRun("second"), check.IsNil)
3609         // Network delete with active containers must fail
3610         _, _, err := dockerCmdWithError("network", "rm", "testnetwork1")
3611         c.Assert(err, check.NotNil)
3612
3613         dockerCmd(c, "stop", "first")
3614         _, _, err = dockerCmdWithError("network", "rm", "testnetwork1")
3615         c.Assert(err, check.NotNil)
3616 }
3617
3618 func (s *DockerSuite) TestContainerRestartInMultipleNetworks(c *check.C) {
3619         testRequires(c, DaemonIsLinux, NotUserNamespace, NotArm)
3620         // Create 2 networks using bridge driver
3621         dockerCmd(c, "network", "create", "-d", "bridge", "testnetwork1")
3622         dockerCmd(c, "network", "create", "-d", "bridge", "testnetwork2")
3623
3624         // Run and connect containers to testnetwork1
3625         dockerCmd(c, "run", "-d", "--net=testnetwork1", "--name=first", "busybox", "top")
3626         c.Assert(waitRun("first"), check.IsNil)
3627         dockerCmd(c, "run", "-d", "--net=testnetwork1", "--name=second", "busybox", "top")
3628         c.Assert(waitRun("second"), check.IsNil)
3629         // Check connectivity between containers in testnetwork2
3630         dockerCmd(c, "exec", "first", "ping", "-c", "1", "second.testnetwork1")
3631         // Connect containers to testnetwork2
3632         dockerCmd(c, "network", "connect", "testnetwork2", "first")
3633         dockerCmd(c, "network", "connect", "testnetwork2", "second")
3634         // Check connectivity between containers
3635         dockerCmd(c, "exec", "second", "ping", "-c", "1", "first.testnetwork2")
3636
3637         // Stop second container and test ping failures on both networks
3638         dockerCmd(c, "stop", "second")
3639         _, _, err := dockerCmdWithError("exec", "first", "ping", "-c", "1", "second.testnetwork1")
3640         c.Assert(err, check.NotNil)
3641         _, _, err = dockerCmdWithError("exec", "first", "ping", "-c", "1", "second.testnetwork2")
3642         c.Assert(err, check.NotNil)
3643
3644         // Start second container and connectivity must be restored on both networks
3645         dockerCmd(c, "start", "second")
3646         dockerCmd(c, "exec", "first", "ping", "-c", "1", "second.testnetwork1")
3647         dockerCmd(c, "exec", "second", "ping", "-c", "1", "first.testnetwork2")
3648 }
3649
3650 func (s *DockerSuite) TestContainerWithConflictingHostNetworks(c *check.C) {
3651         testRequires(c, DaemonIsLinux, NotUserNamespace)
3652         // Run a container with --net=host
3653         dockerCmd(c, "run", "-d", "--net=host", "--name=first", "busybox", "top")
3654         c.Assert(waitRun("first"), check.IsNil)
3655
3656         // Create a network using bridge driver
3657         dockerCmd(c, "network", "create", "-d", "bridge", "testnetwork1")
3658
3659         // Connecting to the user defined network must fail
3660         _, _, err := dockerCmdWithError("network", "connect", "testnetwork1", "first")
3661         c.Assert(err, check.NotNil)
3662 }
3663
3664 func (s *DockerSuite) TestContainerWithConflictingSharedNetwork(c *check.C) {
3665         testRequires(c, DaemonIsLinux)
3666         dockerCmd(c, "run", "-d", "--name=first", "busybox", "top")
3667         c.Assert(waitRun("first"), check.IsNil)
3668         // Run second container in first container's network namespace
3669         dockerCmd(c, "run", "-d", "--net=container:first", "--name=second", "busybox", "top")
3670         c.Assert(waitRun("second"), check.IsNil)
3671
3672         // Create a network using bridge driver
3673         dockerCmd(c, "network", "create", "-d", "bridge", "testnetwork1")
3674
3675         // Connecting to the user defined network must fail
3676         out, _, err := dockerCmdWithError("network", "connect", "testnetwork1", "second")
3677         c.Assert(err, check.NotNil)
3678         c.Assert(out, checker.Contains, runconfig.ErrConflictSharedNetwork.Error())
3679 }
3680
3681 func (s *DockerSuite) TestContainerWithConflictingNoneNetwork(c *check.C) {
3682         testRequires(c, DaemonIsLinux)
3683         dockerCmd(c, "run", "-d", "--net=none", "--name=first", "busybox", "top")
3684         c.Assert(waitRun("first"), check.IsNil)
3685
3686         // Create a network using bridge driver
3687         dockerCmd(c, "network", "create", "-d", "bridge", "testnetwork1")
3688
3689         // Connecting to the user defined network must fail
3690         out, _, err := dockerCmdWithError("network", "connect", "testnetwork1", "first")
3691         c.Assert(err, check.NotNil)
3692         c.Assert(out, checker.Contains, runconfig.ErrConflictNoNetwork.Error())
3693
3694         // create a container connected to testnetwork1
3695         dockerCmd(c, "run", "-d", "--net=testnetwork1", "--name=second", "busybox", "top")
3696         c.Assert(waitRun("second"), check.IsNil)
3697
3698         // Connect second container to none network. it must fail as well
3699         _, _, err = dockerCmdWithError("network", "connect", "none", "second")
3700         c.Assert(err, check.NotNil)
3701 }
3702
3703 // #11957 - stdin with no tty does not exit if stdin is not closed even though container exited
3704 func (s *DockerSuite) TestRunStdinBlockedAfterContainerExit(c *check.C) {
3705         cmd := exec.Command(dockerBinary, "run", "-i", "--name=test", "busybox", "true")
3706         in, err := cmd.StdinPipe()
3707         c.Assert(err, check.IsNil)
3708         defer in.Close()
3709         stdout := bytes.NewBuffer(nil)
3710         cmd.Stdout = stdout
3711         cmd.Stderr = stdout
3712         c.Assert(cmd.Start(), check.IsNil)
3713
3714         waitChan := make(chan error)
3715         go func() {
3716                 waitChan <- cmd.Wait()
3717         }()
3718
3719         select {
3720         case err := <-waitChan:
3721                 c.Assert(err, check.IsNil, check.Commentf(stdout.String()))
3722         case <-time.After(30 * time.Second):
3723                 c.Fatal("timeout waiting for command to exit")
3724         }
3725 }
3726
3727 func (s *DockerSuite) TestRunWrongCpusetCpusFlagValue(c *check.C) {
3728         // TODO Windows: This needs validation (error out) in the daemon.
3729         testRequires(c, DaemonIsLinux)
3730         out, exitCode, err := dockerCmdWithError("run", "--cpuset-cpus", "1-10,11--", "busybox", "true")
3731         c.Assert(err, check.NotNil)
3732         expected := "Error response from daemon: Invalid value 1-10,11-- for cpuset cpus.\n"
3733         if !(strings.Contains(out, expected) || exitCode == 125) {
3734                 c.Fatalf("Expected output to contain %q with exitCode 125, got out: %q exitCode: %v", expected, out, exitCode)
3735         }
3736 }
3737
3738 func (s *DockerSuite) TestRunWrongCpusetMemsFlagValue(c *check.C) {
3739         // TODO Windows: This needs validation (error out) in the daemon.
3740         testRequires(c, DaemonIsLinux)
3741         out, exitCode, err := dockerCmdWithError("run", "--cpuset-mems", "1-42--", "busybox", "true")
3742         c.Assert(err, check.NotNil)
3743         expected := "Error response from daemon: Invalid value 1-42-- for cpuset mems.\n"
3744         if !(strings.Contains(out, expected) || exitCode == 125) {
3745                 c.Fatalf("Expected output to contain %q with exitCode 125, got out: %q exitCode: %v", expected, out, exitCode)
3746         }
3747 }
3748
3749 // TestRunNonExecutableCmd checks that 'docker run busybox foo' exits with error code 127'
3750 func (s *DockerSuite) TestRunNonExecutableCmd(c *check.C) {
3751         name := "testNonExecutableCmd"
3752         icmd.RunCommand(dockerBinary, "run", "--name", name, "busybox", "foo").Assert(c, icmd.Expected{
3753                 ExitCode: 127,
3754                 Error:    "exit status 127",
3755         })
3756 }
3757
3758 // TestRunNonExistingCmd checks that 'docker run busybox /bin/foo' exits with code 127.
3759 func (s *DockerSuite) TestRunNonExistingCmd(c *check.C) {
3760         name := "testNonExistingCmd"
3761         icmd.RunCommand(dockerBinary, "run", "--name", name, "busybox", "/bin/foo").Assert(c, icmd.Expected{
3762                 ExitCode: 127,
3763                 Error:    "exit status 127",
3764         })
3765 }
3766
3767 // TestCmdCannotBeInvoked checks that 'docker run busybox /etc' exits with 126, or
3768 // 127 on Windows. The difference is that in Windows, the container must be started
3769 // as that's when the check is made (and yes, by its design...)
3770 func (s *DockerSuite) TestCmdCannotBeInvoked(c *check.C) {
3771         expected := 126
3772         if testEnv.DaemonPlatform() == "windows" {
3773                 expected = 127
3774         }
3775         name := "testCmdCannotBeInvoked"
3776         icmd.RunCommand(dockerBinary, "run", "--name", name, "busybox", "/etc").Assert(c, icmd.Expected{
3777                 ExitCode: expected,
3778                 Error:    fmt.Sprintf("exit status %d", expected),
3779         })
3780 }
3781
3782 // TestRunNonExistingImage checks that 'docker run foo' exits with error msg 125 and contains  'Unable to find image'
3783 // FIXME(vdemeester) should be a unit test
3784 func (s *DockerSuite) TestRunNonExistingImage(c *check.C) {
3785         icmd.RunCommand(dockerBinary, "run", "foo").Assert(c, icmd.Expected{
3786                 ExitCode: 125,
3787                 Err:      "Unable to find image",
3788         })
3789 }
3790
3791 // TestDockerFails checks that 'docker run -foo busybox' exits with 125 to signal docker run failed
3792 // FIXME(vdemeester) should be a unit test
3793 func (s *DockerSuite) TestDockerFails(c *check.C) {
3794         icmd.RunCommand(dockerBinary, "run", "-foo", "busybox").Assert(c, icmd.Expected{
3795                 ExitCode: 125,
3796                 Error:    "exit status 125",
3797         })
3798 }
3799
3800 // TestRunInvalidReference invokes docker run with a bad reference.
3801 func (s *DockerSuite) TestRunInvalidReference(c *check.C) {
3802         out, exit, _ := dockerCmdWithError("run", "busybox@foo")
3803         if exit == 0 {
3804                 c.Fatalf("expected non-zero exist code; received %d", exit)
3805         }
3806
3807         if !strings.Contains(out, "invalid reference format") {
3808                 c.Fatalf(`Expected "invalid reference format" in output; got: %s`, out)
3809         }
3810 }
3811
3812 // Test fix for issue #17854
3813 func (s *DockerSuite) TestRunInitLayerPathOwnership(c *check.C) {
3814         // Not applicable on Windows as it does not support Linux uid/gid ownership
3815         testRequires(c, DaemonIsLinux)
3816         name := "testetcfileownership"
3817         buildImageSuccessfully(c, name, build.WithDockerfile(`FROM busybox
3818                 RUN echo 'dockerio:x:1001:1001::/bin:/bin/false' >> /etc/passwd
3819                 RUN echo 'dockerio:x:1001:' >> /etc/group
3820                 RUN chown dockerio:dockerio /etc`))
3821
3822         // Test that dockerio ownership of /etc is retained at runtime
3823         out, _ := dockerCmd(c, "run", "--rm", name, "stat", "-c", "%U:%G", "/etc")
3824         out = strings.TrimSpace(out)
3825         if out != "dockerio:dockerio" {
3826                 c.Fatalf("Wrong /etc ownership: expected dockerio:dockerio, got %q", out)
3827         }
3828 }
3829
3830 func (s *DockerSuite) TestRunWithOomScoreAdj(c *check.C) {
3831         testRequires(c, DaemonIsLinux)
3832
3833         expected := "642"
3834         out, _ := dockerCmd(c, "run", "--oom-score-adj", expected, "busybox", "cat", "/proc/self/oom_score_adj")
3835         oomScoreAdj := strings.TrimSpace(out)
3836         if oomScoreAdj != "642" {
3837                 c.Fatalf("Expected oom_score_adj set to %q, got %q instead", expected, oomScoreAdj)
3838         }
3839 }
3840
3841 func (s *DockerSuite) TestRunWithOomScoreAdjInvalidRange(c *check.C) {
3842         testRequires(c, DaemonIsLinux)
3843
3844         out, _, err := dockerCmdWithError("run", "--oom-score-adj", "1001", "busybox", "true")
3845         c.Assert(err, check.NotNil)
3846         expected := "Invalid value 1001, range for oom score adj is [-1000, 1000]."
3847         if !strings.Contains(out, expected) {
3848                 c.Fatalf("Expected output to contain %q, got %q instead", expected, out)
3849         }
3850         out, _, err = dockerCmdWithError("run", "--oom-score-adj", "-1001", "busybox", "true")
3851         c.Assert(err, check.NotNil)
3852         expected = "Invalid value -1001, range for oom score adj is [-1000, 1000]."
3853         if !strings.Contains(out, expected) {
3854                 c.Fatalf("Expected output to contain %q, got %q instead", expected, out)
3855         }
3856 }
3857
3858 func (s *DockerSuite) TestRunVolumesMountedAsShared(c *check.C) {
3859         // Volume propagation is linux only. Also it creates directories for
3860         // bind mounting, so needs to be same host.
3861         testRequires(c, DaemonIsLinux, SameHostDaemon, NotUserNamespace)
3862
3863         // Prepare a source directory to bind mount
3864         tmpDir, err := ioutil.TempDir("", "volume-source")
3865         if err != nil {
3866                 c.Fatal(err)
3867         }
3868         defer os.RemoveAll(tmpDir)
3869
3870         if err := os.Mkdir(path.Join(tmpDir, "mnt1"), 0755); err != nil {
3871                 c.Fatal(err)
3872         }
3873
3874         // Convert this directory into a shared mount point so that we do
3875         // not rely on propagation properties of parent mount.
3876         icmd.RunCommand("mount", "--bind", tmpDir, tmpDir).Assert(c, icmd.Success)
3877         icmd.RunCommand("mount", "--make-private", "--make-shared", tmpDir).Assert(c, icmd.Success)
3878
3879         dockerCmd(c, "run", "--privileged", "-v", fmt.Sprintf("%s:/volume-dest:shared", tmpDir), "busybox", "mount", "--bind", "/volume-dest/mnt1", "/volume-dest/mnt1")
3880
3881         // Make sure a bind mount under a shared volume propagated to host.
3882         if mounted, _ := mount.Mounted(path.Join(tmpDir, "mnt1")); !mounted {
3883                 c.Fatalf("Bind mount under shared volume did not propagate to host")
3884         }
3885
3886         mount.Unmount(path.Join(tmpDir, "mnt1"))
3887 }
3888
3889 func (s *DockerSuite) TestRunVolumesMountedAsSlave(c *check.C) {
3890         // Volume propagation is linux only. Also it creates directories for
3891         // bind mounting, so needs to be same host.
3892         testRequires(c, DaemonIsLinux, SameHostDaemon, NotUserNamespace)
3893
3894         // Prepare a source directory to bind mount
3895         tmpDir, err := ioutil.TempDir("", "volume-source")
3896         if err != nil {
3897                 c.Fatal(err)
3898         }
3899         defer os.RemoveAll(tmpDir)
3900
3901         if err := os.Mkdir(path.Join(tmpDir, "mnt1"), 0755); err != nil {
3902                 c.Fatal(err)
3903         }
3904
3905         // Prepare a source directory with file in it. We will bind mount this
3906         // directory and see if file shows up.
3907         tmpDir2, err := ioutil.TempDir("", "volume-source2")
3908         if err != nil {
3909                 c.Fatal(err)
3910         }
3911         defer os.RemoveAll(tmpDir2)
3912
3913         if err := ioutil.WriteFile(path.Join(tmpDir2, "slave-testfile"), []byte("Test"), 0644); err != nil {
3914                 c.Fatal(err)
3915         }
3916
3917         // Convert this directory into a shared mount point so that we do
3918         // not rely on propagation properties of parent mount.
3919         icmd.RunCommand("mount", "--bind", tmpDir, tmpDir).Assert(c, icmd.Success)
3920         icmd.RunCommand("mount", "--make-private", "--make-shared", tmpDir).Assert(c, icmd.Success)
3921
3922         dockerCmd(c, "run", "-i", "-d", "--name", "parent", "-v", fmt.Sprintf("%s:/volume-dest:slave", tmpDir), "busybox", "top")
3923
3924         // Bind mount tmpDir2/ onto tmpDir/mnt1. If mount propagates inside
3925         // container then contents of tmpDir2/slave-testfile should become
3926         // visible at "/volume-dest/mnt1/slave-testfile"
3927         icmd.RunCommand("mount", "--bind", tmpDir2, path.Join(tmpDir, "mnt1")).Assert(c, icmd.Success)
3928
3929         out, _ := dockerCmd(c, "exec", "parent", "cat", "/volume-dest/mnt1/slave-testfile")
3930
3931         mount.Unmount(path.Join(tmpDir, "mnt1"))
3932
3933         if out != "Test" {
3934                 c.Fatalf("Bind mount under slave volume did not propagate to container")
3935         }
3936 }
3937
3938 func (s *DockerSuite) TestRunNamedVolumesMountedAsShared(c *check.C) {
3939         testRequires(c, DaemonIsLinux, NotUserNamespace)
3940         out, exitCode, _ := dockerCmdWithError("run", "-v", "foo:/test:shared", "busybox", "touch", "/test/somefile")
3941         c.Assert(exitCode, checker.Not(checker.Equals), 0)
3942         c.Assert(out, checker.Contains, "invalid mount config")
3943 }
3944
3945 func (s *DockerSuite) TestRunNamedVolumeCopyImageData(c *check.C) {
3946         testRequires(c, DaemonIsLinux)
3947
3948         testImg := "testvolumecopy"
3949         buildImageSuccessfully(c, testImg, build.WithDockerfile(`
3950         FROM busybox
3951         RUN mkdir -p /foo && echo hello > /foo/hello
3952         `))
3953
3954         dockerCmd(c, "run", "-v", "foo:/foo", testImg)
3955         out, _ := dockerCmd(c, "run", "-v", "foo:/foo", "busybox", "cat", "/foo/hello")
3956         c.Assert(strings.TrimSpace(out), check.Equals, "hello")
3957 }
3958
3959 func (s *DockerSuite) TestRunNamedVolumeNotRemoved(c *check.C) {
3960         prefix, _ := getPrefixAndSlashFromDaemonPlatform()
3961
3962         dockerCmd(c, "volume", "create", "test")
3963
3964         dockerCmd(c, "run", "--rm", "-v", "test:"+prefix+"/foo", "-v", prefix+"/bar", "busybox", "true")
3965         dockerCmd(c, "volume", "inspect", "test")
3966         out, _ := dockerCmd(c, "volume", "ls", "-q")
3967         c.Assert(strings.TrimSpace(out), checker.Equals, "test")
3968
3969         dockerCmd(c, "run", "--name=test", "-v", "test:"+prefix+"/foo", "-v", prefix+"/bar", "busybox", "true")
3970         dockerCmd(c, "rm", "-fv", "test")
3971         dockerCmd(c, "volume", "inspect", "test")
3972         out, _ = dockerCmd(c, "volume", "ls", "-q")
3973         c.Assert(strings.TrimSpace(out), checker.Equals, "test")
3974 }
3975
3976 func (s *DockerSuite) TestRunNamedVolumesFromNotRemoved(c *check.C) {
3977         prefix, _ := getPrefixAndSlashFromDaemonPlatform()
3978
3979         dockerCmd(c, "volume", "create", "test")
3980         dockerCmd(c, "run", "--name=parent", "-v", "test:"+prefix+"/foo", "-v", prefix+"/bar", "busybox", "true")
3981         dockerCmd(c, "run", "--name=child", "--volumes-from=parent", "busybox", "true")
3982
3983         // Remove the parent so there are not other references to the volumes
3984         dockerCmd(c, "rm", "-f", "parent")
3985         // now remove the child and ensure the named volume (and only the named volume) still exists
3986         dockerCmd(c, "rm", "-fv", "child")
3987         dockerCmd(c, "volume", "inspect", "test")
3988         out, _ := dockerCmd(c, "volume", "ls", "-q")
3989         c.Assert(strings.TrimSpace(out), checker.Equals, "test")
3990 }
3991
3992 func (s *DockerSuite) TestRunAttachFailedNoLeak(c *check.C) {
3993         nroutines, err := getGoroutineNumber()
3994         c.Assert(err, checker.IsNil)
3995
3996         runSleepingContainer(c, "--name=test", "-p", "8000:8000")
3997
3998         // Wait until container is fully up and running
3999         c.Assert(waitRun("test"), check.IsNil)
4000
4001         out, _, err := dockerCmdWithError("run", "--name=fail", "-p", "8000:8000", "busybox", "true")
4002         // We will need the following `inspect` to diagnose the issue if test fails (#21247)
4003         out1, err1 := dockerCmd(c, "inspect", "--format", "{{json .State}}", "test")
4004         out2, err2 := dockerCmd(c, "inspect", "--format", "{{json .State}}", "fail")
4005         c.Assert(err, checker.NotNil, check.Commentf("Command should have failed but succeeded with: %s\nContainer 'test' [%+v]: %s\nContainer 'fail' [%+v]: %s", out, err1, out1, err2, out2))
4006         // check for windows error as well
4007         // TODO Windows Post TP5. Fix the error message string
4008         c.Assert(strings.Contains(string(out), "port is already allocated") ||
4009                 strings.Contains(string(out), "were not connected because a duplicate name exists") ||
4010                 strings.Contains(string(out), "HNS failed with error : Failed to create endpoint") ||
4011                 strings.Contains(string(out), "HNS failed with error : The object already exists"), checker.Equals, true, check.Commentf("Output: %s", out))
4012         dockerCmd(c, "rm", "-f", "test")
4013
4014         // NGoroutines is not updated right away, so we need to wait before failing
4015         c.Assert(waitForGoroutines(nroutines), checker.IsNil)
4016 }
4017
4018 // Test for one character directory name case (#20122)
4019 func (s *DockerSuite) TestRunVolumeWithOneCharacter(c *check.C) {
4020         testRequires(c, DaemonIsLinux)
4021
4022         out, _ := dockerCmd(c, "run", "-v", "/tmp/q:/foo", "busybox", "sh", "-c", "find /foo")
4023         c.Assert(strings.TrimSpace(out), checker.Equals, "/foo")
4024 }
4025
4026 func (s *DockerSuite) TestRunVolumeCopyFlag(c *check.C) {
4027         testRequires(c, DaemonIsLinux) // Windows does not support copying data from image to the volume
4028         buildImageSuccessfully(c, "volumecopy", build.WithDockerfile(`FROM busybox
4029                 RUN mkdir /foo && echo hello > /foo/bar
4030                 CMD cat /foo/bar`))
4031         dockerCmd(c, "volume", "create", "test")
4032
4033         // test with the nocopy flag
4034         out, _, err := dockerCmdWithError("run", "-v", "test:/foo:nocopy", "volumecopy")
4035         c.Assert(err, checker.NotNil, check.Commentf(out))
4036         // test default behavior which is to copy for non-binds
4037         out, _ = dockerCmd(c, "run", "-v", "test:/foo", "volumecopy")
4038         c.Assert(strings.TrimSpace(out), checker.Equals, "hello")
4039         // error out when the volume is already populated
4040         out, _, err = dockerCmdWithError("run", "-v", "test:/foo:copy", "volumecopy")
4041         c.Assert(err, checker.NotNil, check.Commentf(out))
4042         // do not error out when copy isn't explicitly set even though it's already populated
4043         out, _ = dockerCmd(c, "run", "-v", "test:/foo", "volumecopy")
4044         c.Assert(strings.TrimSpace(out), checker.Equals, "hello")
4045
4046         // do not allow copy modes on volumes-from
4047         dockerCmd(c, "run", "--name=test", "-v", "/foo", "busybox", "true")
4048         out, _, err = dockerCmdWithError("run", "--volumes-from=test:copy", "busybox", "true")
4049         c.Assert(err, checker.NotNil, check.Commentf(out))
4050         out, _, err = dockerCmdWithError("run", "--volumes-from=test:nocopy", "busybox", "true")
4051         c.Assert(err, checker.NotNil, check.Commentf(out))
4052
4053         // do not allow copy modes on binds
4054         out, _, err = dockerCmdWithError("run", "-v", "/foo:/bar:copy", "busybox", "true")
4055         c.Assert(err, checker.NotNil, check.Commentf(out))
4056         out, _, err = dockerCmdWithError("run", "-v", "/foo:/bar:nocopy", "busybox", "true")
4057         c.Assert(err, checker.NotNil, check.Commentf(out))
4058 }
4059
4060 // Test case for #21976
4061 func (s *DockerSuite) TestRunDNSInHostMode(c *check.C) {
4062         testRequires(c, DaemonIsLinux, NotUserNamespace)
4063
4064         expectedOutput := "nameserver 127.0.0.1"
4065         expectedWarning := "Localhost DNS setting"
4066         cli.DockerCmd(c, "run", "--dns=127.0.0.1", "--net=host", "busybox", "cat", "/etc/resolv.conf").Assert(c, icmd.Expected{
4067                 Out: expectedOutput,
4068                 Err: expectedWarning,
4069         })
4070
4071         expectedOutput = "nameserver 1.2.3.4"
4072         cli.DockerCmd(c, "run", "--dns=1.2.3.4", "--net=host", "busybox", "cat", "/etc/resolv.conf").Assert(c, icmd.Expected{
4073                 Out: expectedOutput,
4074         })
4075
4076         expectedOutput = "search example.com"
4077         cli.DockerCmd(c, "run", "--dns-search=example.com", "--net=host", "busybox", "cat", "/etc/resolv.conf").Assert(c, icmd.Expected{
4078                 Out: expectedOutput,
4079         })
4080
4081         expectedOutput = "options timeout:3"
4082         cli.DockerCmd(c, "run", "--dns-opt=timeout:3", "--net=host", "busybox", "cat", "/etc/resolv.conf").Assert(c, icmd.Expected{
4083                 Out: expectedOutput,
4084         })
4085
4086         expectedOutput1 := "nameserver 1.2.3.4"
4087         expectedOutput2 := "search example.com"
4088         expectedOutput3 := "options timeout:3"
4089         out := cli.DockerCmd(c, "run", "--dns=1.2.3.4", "--dns-search=example.com", "--dns-opt=timeout:3", "--net=host", "busybox", "cat", "/etc/resolv.conf").Combined()
4090         c.Assert(out, checker.Contains, expectedOutput1, check.Commentf("Expected '%s', but got %q", expectedOutput1, out))
4091         c.Assert(out, checker.Contains, expectedOutput2, check.Commentf("Expected '%s', but got %q", expectedOutput2, out))
4092         c.Assert(out, checker.Contains, expectedOutput3, check.Commentf("Expected '%s', but got %q", expectedOutput3, out))
4093 }
4094
4095 // Test case for #21976
4096 func (s *DockerSuite) TestRunAddHostInHostMode(c *check.C) {
4097         testRequires(c, DaemonIsLinux, NotUserNamespace)
4098
4099         expectedOutput := "1.2.3.4\textra"
4100         out, _ := dockerCmd(c, "run", "--add-host=extra:1.2.3.4", "--net=host", "busybox", "cat", "/etc/hosts")
4101         c.Assert(out, checker.Contains, expectedOutput, check.Commentf("Expected '%s', but got %q", expectedOutput, out))
4102 }
4103
4104 func (s *DockerSuite) TestRunRmAndWait(c *check.C) {
4105         dockerCmd(c, "run", "--name=test", "--rm", "-d", "busybox", "sh", "-c", "sleep 3;exit 2")
4106
4107         out, code, err := dockerCmdWithError("wait", "test")
4108         c.Assert(err, checker.IsNil, check.Commentf("out: %s; exit code: %d", out, code))
4109         c.Assert(out, checker.Equals, "2\n", check.Commentf("exit code: %d", code))
4110         c.Assert(code, checker.Equals, 0)
4111 }
4112
4113 // Test that auto-remove is performed by the daemon (API 1.25 and above)
4114 func (s *DockerSuite) TestRunRm(c *check.C) {
4115         name := "miss-me-when-im-gone"
4116         cli.DockerCmd(c, "run", "--name="+name, "--rm", "busybox")
4117
4118         cli.Docker(cli.Inspect(name), cli.Format(".name")).Assert(c, icmd.Expected{
4119                 ExitCode: 1,
4120                 Err:      "No such object: " + name,
4121         })
4122 }
4123
4124 // Test that auto-remove is performed by the client on API versions that do not support daemon-side api-remove (API < 1.25)
4125 func (s *DockerSuite) TestRunRmPre125Api(c *check.C) {
4126         name := "miss-me-when-im-gone"
4127         envs := appendBaseEnv(false, "DOCKER_API_VERSION=1.24")
4128         cli.Docker(cli.Args("run", "--name="+name, "--rm", "busybox"), cli.WithEnvironmentVariables(envs...)).Assert(c, icmd.Success)
4129
4130         cli.Docker(cli.Inspect(name), cli.Format(".name")).Assert(c, icmd.Expected{
4131                 ExitCode: 1,
4132                 Err:      "No such object: " + name,
4133         })
4134 }
4135
4136 // Test case for #23498
4137 func (s *DockerSuite) TestRunUnsetEntrypoint(c *check.C) {
4138         testRequires(c, DaemonIsLinux)
4139         name := "test-entrypoint"
4140         dockerfile := `FROM busybox
4141 ADD entrypoint.sh /entrypoint.sh
4142 RUN chmod 755 /entrypoint.sh
4143 ENTRYPOINT ["/entrypoint.sh"]
4144 CMD echo foobar`
4145
4146         ctx := fakecontext.New(c, "",
4147                 fakecontext.WithDockerfile(dockerfile),
4148                 fakecontext.WithFiles(map[string]string{
4149                         "entrypoint.sh": `#!/bin/sh
4150 echo "I am an entrypoint"
4151 exec "$@"`,
4152                 }))
4153         defer ctx.Close()
4154
4155         cli.BuildCmd(c, name, build.WithExternalBuildContext(ctx))
4156
4157         out := cli.DockerCmd(c, "run", "--entrypoint=", "-t", name, "echo", "foo").Combined()
4158         c.Assert(strings.TrimSpace(out), check.Equals, "foo")
4159
4160         // CMD will be reset as well (the same as setting a custom entrypoint)
4161         cli.Docker(cli.Args("run", "--entrypoint=", "-t", name)).Assert(c, icmd.Expected{
4162                 ExitCode: 125,
4163                 Err:      "No command specified",
4164         })
4165 }
4166
4167 func (s *DockerDaemonSuite) TestRunWithUlimitAndDaemonDefault(c *check.C) {
4168         s.d.StartWithBusybox(c, "--debug", "--default-ulimit=nofile=65535")
4169
4170         name := "test-A"
4171         _, err := s.d.Cmd("run", "--name", name, "-d", "busybox", "top")
4172         c.Assert(err, checker.IsNil)
4173         c.Assert(s.d.WaitRun(name), check.IsNil)
4174
4175         out, err := s.d.Cmd("inspect", "--format", "{{.HostConfig.Ulimits}}", name)
4176         c.Assert(err, checker.IsNil)
4177         c.Assert(out, checker.Contains, "[nofile=65535:65535]")
4178
4179         name = "test-B"
4180         _, err = s.d.Cmd("run", "--name", name, "--ulimit=nofile=42", "-d", "busybox", "top")
4181         c.Assert(err, checker.IsNil)
4182         c.Assert(s.d.WaitRun(name), check.IsNil)
4183
4184         out, err = s.d.Cmd("inspect", "--format", "{{.HostConfig.Ulimits}}", name)
4185         c.Assert(err, checker.IsNil)
4186         c.Assert(out, checker.Contains, "[nofile=42:42]")
4187 }
4188
4189 func (s *DockerSuite) TestRunStoppedLoggingDriverNoLeak(c *check.C) {
4190         c.Skip("Splunk log-driver isn't supported")
4191
4192         nroutines, err := getGoroutineNumber()
4193         c.Assert(err, checker.IsNil)
4194
4195         out, _, err := dockerCmdWithError("run", "--name=fail", "--log-driver=splunk", "busybox", "true")
4196         c.Assert(err, checker.NotNil)
4197         c.Assert(out, checker.Contains, "failed to initialize logging driver", check.Commentf("error should be about logging driver, got output %s", out))
4198
4199         // NGoroutines is not updated right away, so we need to wait before failing
4200         c.Assert(waitForGoroutines(nroutines), checker.IsNil)
4201 }
4202
4203 // Handles error conditions for --credentialspec. Validating E2E success cases
4204 // requires additional infrastructure (AD for example) on CI servers.
4205 func (s *DockerSuite) TestRunCredentialSpecFailures(c *check.C) {
4206         testRequires(c, DaemonIsWindows)
4207         attempts := []struct{ value, expectedError string }{
4208                 {"rubbish", "invalid credential spec security option - value must be prefixed file:// or registry://"},
4209                 {"rubbish://", "invalid credential spec security option - value must be prefixed file:// or registry://"},
4210                 {"file://", "no value supplied for file:// credential spec security option"},
4211                 {"registry://", "no value supplied for registry:// credential spec security option"},
4212                 {`file://c:\blah.txt`, "path cannot be absolute"},
4213                 {`file://doesnotexist.txt`, "The system cannot find the file specified"},
4214         }
4215         for _, attempt := range attempts {
4216                 _, _, err := dockerCmdWithError("run", "--security-opt=credentialspec="+attempt.value, "busybox", "true")
4217                 c.Assert(err, checker.NotNil, check.Commentf("%s expected non-nil err", attempt.value))
4218                 c.Assert(err.Error(), checker.Contains, attempt.expectedError, check.Commentf("%s expected %s got %s", attempt.value, attempt.expectedError, err))
4219         }
4220 }
4221
4222 // Windows specific test to validate credential specs with a well-formed spec.
4223 // Note it won't actually do anything in CI configuration with the spec, but
4224 // it should not fail to run a container.
4225 func (s *DockerSuite) TestRunCredentialSpecWellFormed(c *check.C) {
4226         testRequires(c, DaemonIsWindows, SameHostDaemon)
4227         validCS := readFile(`fixtures\credentialspecs\valid.json`, c)
4228         writeFile(filepath.Join(testEnv.DockerBasePath(), `credentialspecs\valid.json`), validCS, c)
4229         dockerCmd(c, "run", `--security-opt=credentialspec=file://valid.json`, "busybox", "true")
4230 }
4231
4232 // Windows specific test to ensure that a servicing app container is started
4233 // if necessary once a container exits. It does this by forcing a no-op
4234 // servicing event and verifying the event from Hyper-V-Compute
4235 func (s *DockerSuite) TestRunServicingContainer(c *check.C) {
4236         testRequires(c, DaemonIsWindows, SameHostDaemon)
4237
4238         out := cli.DockerCmd(c, "run", "-d", testEnv.MinimalBaseImage(), "cmd", "/c", "mkdir c:\\programdata\\Microsoft\\Windows\\ContainerUpdates\\000_000_d99f45d0-ffc8-4af7-bd9c-ea6a62e035c9_200 && sc control cexecsvc 255").Combined()
4239         containerID := strings.TrimSpace(out)
4240         cli.WaitExited(c, containerID, 60*time.Second)
4241
4242         result := icmd.RunCommand("powershell", "echo", `(Get-WinEvent -ProviderName "Microsoft-Windows-Hyper-V-Compute" -FilterXPath 'Event[System[EventID=2010]]' -MaxEvents 1).Message`)
4243         result.Assert(c, icmd.Success)
4244         out2 := result.Combined()
4245         c.Assert(out2, checker.Contains, `"Servicing":true`, check.Commentf("Servicing container does not appear to have been started: %s", out2))
4246         c.Assert(out2, checker.Contains, `Windows Container (Servicing)`, check.Commentf("Didn't find 'Windows Container (Servicing): %s", out2))
4247         c.Assert(out2, checker.Contains, containerID+"_servicing", check.Commentf("Didn't find '%s_servicing': %s", containerID+"_servicing", out2))
4248 }
4249
4250 func (s *DockerSuite) TestRunDuplicateMount(c *check.C) {
4251         testRequires(c, SameHostDaemon, DaemonIsLinux, NotUserNamespace)
4252
4253         tmpFile, err := ioutil.TempFile("", "touch-me")
4254         c.Assert(err, checker.IsNil)
4255         defer tmpFile.Close()
4256
4257         data := "touch-me-foo-bar\n"
4258         if _, err := tmpFile.Write([]byte(data)); err != nil {
4259                 c.Fatal(err)
4260         }
4261
4262         name := "test"
4263         out, _ := dockerCmd(c, "run", "--name", name, "-v", "/tmp:/tmp", "-v", "/tmp:/tmp", "busybox", "sh", "-c", "cat "+tmpFile.Name()+" && ls /")
4264         c.Assert(out, checker.Not(checker.Contains), "tmp:")
4265         c.Assert(out, checker.Contains, data)
4266
4267         out = inspectFieldJSON(c, name, "Config.Volumes")
4268         c.Assert(out, checker.Contains, "null")
4269 }
4270
4271 func (s *DockerSuite) TestRunWindowsWithCPUCount(c *check.C) {
4272         testRequires(c, DaemonIsWindows)
4273
4274         out, _ := dockerCmd(c, "run", "--cpu-count=1", "--name", "test", "busybox", "echo", "testing")
4275         c.Assert(strings.TrimSpace(out), checker.Equals, "testing")
4276
4277         out = inspectField(c, "test", "HostConfig.CPUCount")
4278         c.Assert(out, check.Equals, "1")
4279 }
4280
4281 func (s *DockerSuite) TestRunWindowsWithCPUShares(c *check.C) {
4282         testRequires(c, DaemonIsWindows)
4283
4284         out, _ := dockerCmd(c, "run", "--cpu-shares=1000", "--name", "test", "busybox", "echo", "testing")
4285         c.Assert(strings.TrimSpace(out), checker.Equals, "testing")
4286
4287         out = inspectField(c, "test", "HostConfig.CPUShares")
4288         c.Assert(out, check.Equals, "1000")
4289 }
4290
4291 func (s *DockerSuite) TestRunWindowsWithCPUPercent(c *check.C) {
4292         testRequires(c, DaemonIsWindows)
4293
4294         out, _ := dockerCmd(c, "run", "--cpu-percent=80", "--name", "test", "busybox", "echo", "testing")
4295         c.Assert(strings.TrimSpace(out), checker.Equals, "testing")
4296
4297         out = inspectField(c, "test", "HostConfig.CPUPercent")
4298         c.Assert(out, check.Equals, "80")
4299 }
4300
4301 func (s *DockerSuite) TestRunProcessIsolationWithCPUCountCPUSharesAndCPUPercent(c *check.C) {
4302         testRequires(c, DaemonIsWindows, IsolationIsProcess)
4303
4304         out, _ := dockerCmd(c, "run", "--cpu-count=1", "--cpu-shares=1000", "--cpu-percent=80", "--name", "test", "busybox", "echo", "testing")
4305         c.Assert(strings.TrimSpace(out), checker.Contains, "WARNING: Conflicting options: CPU count takes priority over CPU shares on Windows Server Containers. CPU shares discarded")
4306         c.Assert(strings.TrimSpace(out), checker.Contains, "WARNING: Conflicting options: CPU count takes priority over CPU percent on Windows Server Containers. CPU percent discarded")
4307         c.Assert(strings.TrimSpace(out), checker.Contains, "testing")
4308
4309         out = inspectField(c, "test", "HostConfig.CPUCount")
4310         c.Assert(out, check.Equals, "1")
4311
4312         out = inspectField(c, "test", "HostConfig.CPUShares")
4313         c.Assert(out, check.Equals, "0")
4314
4315         out = inspectField(c, "test", "HostConfig.CPUPercent")
4316         c.Assert(out, check.Equals, "0")
4317 }
4318
4319 func (s *DockerSuite) TestRunHypervIsolationWithCPUCountCPUSharesAndCPUPercent(c *check.C) {
4320         testRequires(c, DaemonIsWindows, IsolationIsHyperv)
4321
4322         out, _ := dockerCmd(c, "run", "--cpu-count=1", "--cpu-shares=1000", "--cpu-percent=80", "--name", "test", "busybox", "echo", "testing")
4323         c.Assert(strings.TrimSpace(out), checker.Contains, "testing")
4324
4325         out = inspectField(c, "test", "HostConfig.CPUCount")
4326         c.Assert(out, check.Equals, "1")
4327
4328         out = inspectField(c, "test", "HostConfig.CPUShares")
4329         c.Assert(out, check.Equals, "1000")
4330
4331         out = inspectField(c, "test", "HostConfig.CPUPercent")
4332         c.Assert(out, check.Equals, "80")
4333 }
4334
4335 // Test for #25099
4336 func (s *DockerSuite) TestRunEmptyEnv(c *check.C) {
4337         testRequires(c, DaemonIsLinux)
4338
4339         expectedOutput := "invalid environment variable:"
4340
4341         out, _, err := dockerCmdWithError("run", "-e", "", "busybox", "true")
4342         c.Assert(err, checker.NotNil)
4343         c.Assert(out, checker.Contains, expectedOutput)
4344
4345         out, _, err = dockerCmdWithError("run", "-e", "=", "busybox", "true")
4346         c.Assert(err, checker.NotNil)
4347         c.Assert(out, checker.Contains, expectedOutput)
4348
4349         out, _, err = dockerCmdWithError("run", "-e", "=foo", "busybox", "true")
4350         c.Assert(err, checker.NotNil)
4351         c.Assert(out, checker.Contains, expectedOutput)
4352 }
4353
4354 // #28658
4355 func (s *DockerSuite) TestSlowStdinClosing(c *check.C) {
4356         name := "testslowstdinclosing"
4357         repeat := 3 // regression happened 50% of the time
4358         for i := 0; i < repeat; i++ {
4359                 cmd := icmd.Cmd{
4360                         Command: []string{dockerBinary, "run", "--rm", "--name", name, "-i", "busybox", "cat"},
4361                         Stdin:   &delayedReader{},
4362                 }
4363                 done := make(chan error, 1)
4364                 go func() {
4365                         err := icmd.RunCmd(cmd).Error
4366                         done <- err
4367                 }()
4368
4369                 select {
4370                 case <-time.After(15 * time.Second):
4371                         c.Fatal("running container timed out") // cleanup in teardown
4372                 case err := <-done:
4373                         c.Assert(err, checker.IsNil)
4374                 }
4375         }
4376 }
4377
4378 type delayedReader struct{}
4379
4380 func (s *delayedReader) Read([]byte) (int, error) {
4381         time.Sleep(500 * time.Millisecond)
4382         return 0, io.EOF
4383 }
4384
4385 // #28823 (originally #28639)
4386 func (s *DockerSuite) TestRunMountReadOnlyDevShm(c *check.C) {
4387         testRequires(c, SameHostDaemon, DaemonIsLinux, NotUserNamespace)
4388         emptyDir, err := ioutil.TempDir("", "test-read-only-dev-shm")
4389         c.Assert(err, check.IsNil)
4390         defer os.RemoveAll(emptyDir)
4391         out, _, err := dockerCmdWithError("run", "--rm", "--read-only",
4392                 "-v", fmt.Sprintf("%s:/dev/shm:ro", emptyDir),
4393                 "busybox", "touch", "/dev/shm/foo")
4394         c.Assert(err, checker.NotNil, check.Commentf(out))
4395         c.Assert(out, checker.Contains, "Read-only file system")
4396 }
4397
4398 func (s *DockerSuite) TestRunMount(c *check.C) {
4399         testRequires(c, DaemonIsLinux, SameHostDaemon, NotUserNamespace)
4400
4401         // mnt1, mnt2, and testCatFooBar are commonly used in multiple test cases
4402         tmpDir, err := ioutil.TempDir("", "mount")
4403         if err != nil {
4404                 c.Fatal(err)
4405         }
4406         defer os.RemoveAll(tmpDir)
4407         mnt1, mnt2 := path.Join(tmpDir, "mnt1"), path.Join(tmpDir, "mnt2")
4408         if err := os.Mkdir(mnt1, 0755); err != nil {
4409                 c.Fatal(err)
4410         }
4411         if err := os.Mkdir(mnt2, 0755); err != nil {
4412                 c.Fatal(err)
4413         }
4414         if err := ioutil.WriteFile(path.Join(mnt1, "test1"), []byte("test1"), 0644); err != nil {
4415                 c.Fatal(err)
4416         }
4417         if err := ioutil.WriteFile(path.Join(mnt2, "test2"), []byte("test2"), 0644); err != nil {
4418                 c.Fatal(err)
4419         }
4420         testCatFooBar := func(cName string) error {
4421                 out, _ := dockerCmd(c, "exec", cName, "cat", "/foo/test1")
4422                 if out != "test1" {
4423                         return fmt.Errorf("%s not mounted on /foo", mnt1)
4424                 }
4425                 out, _ = dockerCmd(c, "exec", cName, "cat", "/bar/test2")
4426                 if out != "test2" {
4427                         return fmt.Errorf("%s not mounted on /bar", mnt2)
4428                 }
4429                 return nil
4430         }
4431
4432         type testCase struct {
4433                 equivalents [][]string
4434                 valid       bool
4435                 // fn should be nil if valid==false
4436                 fn func(cName string) error
4437         }
4438         cases := []testCase{
4439                 {
4440                         equivalents: [][]string{
4441                                 {
4442                                         "--mount", fmt.Sprintf("type=bind,src=%s,dst=/foo", mnt1),
4443                                         "--mount", fmt.Sprintf("type=bind,src=%s,dst=/bar", mnt2),
4444                                 },
4445                                 {
4446                                         "--mount", fmt.Sprintf("type=bind,src=%s,dst=/foo", mnt1),
4447                                         "--mount", fmt.Sprintf("type=bind,src=%s,target=/bar", mnt2),
4448                                 },
4449                                 {
4450                                         "--volume", mnt1 + ":/foo",
4451                                         "--mount", fmt.Sprintf("type=bind,src=%s,target=/bar", mnt2),
4452                                 },
4453                         },
4454                         valid: true,
4455                         fn:    testCatFooBar,
4456                 },
4457                 {
4458                         equivalents: [][]string{
4459                                 {
4460                                         "--mount", fmt.Sprintf("type=volume,src=%s,dst=/foo", mnt1),
4461                                         "--mount", fmt.Sprintf("type=volume,src=%s,dst=/bar", mnt2),
4462                                 },
4463                                 {
4464                                         "--mount", fmt.Sprintf("type=volume,src=%s,dst=/foo", mnt1),
4465                                         "--mount", fmt.Sprintf("type=volume,src=%s,target=/bar", mnt2),
4466                                 },
4467                         },
4468                         valid: false,
4469                 },
4470                 {
4471                         equivalents: [][]string{
4472                                 {
4473                                         "--mount", fmt.Sprintf("type=bind,src=%s,dst=/foo", mnt1),
4474                                         "--mount", fmt.Sprintf("type=volume,src=%s,dst=/bar", mnt2),
4475                                 },
4476                                 {
4477                                         "--volume", mnt1 + ":/foo",
4478                                         "--mount", fmt.Sprintf("type=volume,src=%s,target=/bar", mnt2),
4479                                 },
4480                         },
4481                         valid: false,
4482                         fn:    testCatFooBar,
4483                 },
4484                 {
4485                         equivalents: [][]string{
4486                                 {
4487                                         "--read-only",
4488                                         "--mount", "type=volume,dst=/bar",
4489                                 },
4490                         },
4491                         valid: true,
4492                         fn: func(cName string) error {
4493                                 _, _, err := dockerCmdWithError("exec", cName, "touch", "/bar/icanwritehere")
4494                                 return err
4495                         },
4496                 },
4497                 {
4498                         equivalents: [][]string{
4499                                 {
4500                                         "--read-only",
4501                                         "--mount", fmt.Sprintf("type=bind,src=%s,dst=/foo", mnt1),
4502                                         "--mount", "type=volume,dst=/bar",
4503                                 },
4504                                 {
4505                                         "--read-only",
4506                                         "--volume", fmt.Sprintf("%s:/foo", mnt1),
4507                                         "--mount", "type=volume,dst=/bar",
4508                                 },
4509                         },
4510                         valid: true,
4511                         fn: func(cName string) error {
4512                                 out, _ := dockerCmd(c, "exec", cName, "cat", "/foo/test1")
4513                                 if out != "test1" {
4514                                         return fmt.Errorf("%s not mounted on /foo", mnt1)
4515                                 }
4516                                 _, _, err := dockerCmdWithError("exec", cName, "touch", "/bar/icanwritehere")
4517                                 return err
4518                         },
4519                 },
4520                 {
4521                         equivalents: [][]string{
4522                                 {
4523                                         "--mount", fmt.Sprintf("type=bind,src=%s,dst=/foo", mnt1),
4524                                         "--mount", fmt.Sprintf("type=bind,src=%s,dst=/foo", mnt2),
4525                                 },
4526                                 {
4527                                         "--mount", fmt.Sprintf("type=bind,src=%s,dst=/foo", mnt1),
4528                                         "--mount", fmt.Sprintf("type=bind,src=%s,target=/foo", mnt2),
4529                                 },
4530                                 {
4531                                         "--volume", fmt.Sprintf("%s:/foo", mnt1),
4532                                         "--mount", fmt.Sprintf("type=bind,src=%s,target=/foo", mnt2),
4533                                 },
4534                         },
4535                         valid: false,
4536                 },
4537                 {
4538                         equivalents: [][]string{
4539                                 {
4540                                         "--volume", fmt.Sprintf("%s:/foo", mnt1),
4541                                         "--mount", fmt.Sprintf("type=volume,src=%s,target=/foo", mnt2),
4542                                 },
4543                         },
4544                         valid: false,
4545                 },
4546                 {
4547                         equivalents: [][]string{
4548                                 {
4549                                         "--mount", "type=volume,target=/foo",
4550                                         "--mount", "type=volume,target=/foo",
4551                                 },
4552                         },
4553                         valid: false,
4554                 },
4555         }
4556
4557         for i, testCase := range cases {
4558                 for j, opts := range testCase.equivalents {
4559                         cName := fmt.Sprintf("mount-%d-%d", i, j)
4560                         _, _, err := dockerCmdWithError(append([]string{"run", "-i", "-d", "--name", cName},
4561                                 append(opts, []string{"busybox", "top"}...)...)...)
4562                         if testCase.valid {
4563                                 c.Assert(err, check.IsNil,
4564                                         check.Commentf("got error while creating a container with %v (%s)", opts, cName))
4565                                 c.Assert(testCase.fn(cName), check.IsNil,
4566                                         check.Commentf("got error while executing test for %v (%s)", opts, cName))
4567                                 dockerCmd(c, "rm", "-f", cName)
4568                         } else {
4569                                 c.Assert(err, checker.NotNil,
4570                                         check.Commentf("got nil while creating a container with %v (%s)", opts, cName))
4571                         }
4572                 }
4573         }
4574 }
4575
4576 // Test that passing a FQDN as hostname properly sets hostname, and
4577 // /etc/hostname. Test case for 29100
4578 func (s *DockerSuite) TestRunHostnameFQDN(c *check.C) {
4579         testRequires(c, DaemonIsLinux)
4580
4581         expectedOutput := "foobar.example.com\nfoobar.example.com\nfoobar\nexample.com\nfoobar.example.com"
4582         out, _ := dockerCmd(c, "run", "--hostname=foobar.example.com", "busybox", "sh", "-c", `cat /etc/hostname && hostname && hostname -s && hostname -d && hostname -f`)
4583         c.Assert(strings.TrimSpace(out), checker.Equals, expectedOutput)
4584
4585         out, _ = dockerCmd(c, "run", "--hostname=foobar.example.com", "busybox", "sh", "-c", `cat /etc/hosts`)
4586         expectedOutput = "foobar.example.com foobar"
4587         c.Assert(strings.TrimSpace(out), checker.Contains, expectedOutput)
4588 }
4589
4590 // Test case for 29129
4591 func (s *DockerSuite) TestRunHostnameInHostMode(c *check.C) {
4592         testRequires(c, DaemonIsLinux, NotUserNamespace)
4593
4594         expectedOutput := "foobar\nfoobar"
4595         out, _ := dockerCmd(c, "run", "--net=host", "--hostname=foobar", "busybox", "sh", "-c", `echo $HOSTNAME && hostname`)
4596         c.Assert(strings.TrimSpace(out), checker.Equals, expectedOutput)
4597 }
4598
4599 func (s *DockerSuite) TestRunAddDeviceCgroupRule(c *check.C) {
4600         testRequires(c, DaemonIsLinux)
4601
4602         deviceRule := "c 7:128 rwm"
4603
4604         out, _ := dockerCmd(c, "run", "--rm", "busybox", "cat", "/sys/fs/cgroup/devices/devices.list")
4605         if strings.Contains(out, deviceRule) {
4606                 c.Fatalf("%s shouldn't been in the device.list", deviceRule)
4607         }
4608
4609         out, _ = dockerCmd(c, "run", "--rm", fmt.Sprintf("--device-cgroup-rule=%s", deviceRule), "busybox", "grep", deviceRule, "/sys/fs/cgroup/devices/devices.list")
4610         c.Assert(strings.TrimSpace(out), checker.Equals, deviceRule)
4611 }
4612
4613 // Verifies that running as local system is operating correctly on Windows
4614 func (s *DockerSuite) TestWindowsRunAsSystem(c *check.C) {
4615         testRequires(c, DaemonIsWindows)
4616         if testEnv.DaemonKernelVersionNumeric() < 15000 {
4617                 c.Skip("Requires build 15000 or later")
4618         }
4619         out, _ := dockerCmd(c, "run", "--net=none", `--user=nt authority\system`, "--hostname=XYZZY", minimalBaseImage(), "cmd", "/c", `@echo %USERNAME%`)
4620         c.Assert(strings.TrimSpace(out), checker.Equals, "XYZZY$")
4621 }