docker_cli_commit_test.go 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179
  1. package main
  2. import (
  3. "context"
  4. "strings"
  5. "testing"
  6. "github.com/docker/docker/api/types/versions"
  7. "github.com/docker/docker/integration-cli/cli"
  8. "gotest.tools/v3/assert"
  9. "gotest.tools/v3/skip"
  10. )
  11. type DockerCLICommitSuite struct {
  12. ds *DockerSuite
  13. }
  14. func (s *DockerCLICommitSuite) TearDownTest(ctx context.Context, c *testing.T) {
  15. s.ds.TearDownTest(ctx, c)
  16. }
  17. func (s *DockerCLICommitSuite) OnTimeout(c *testing.T) {
  18. s.ds.OnTimeout(c)
  19. }
  20. func (s *DockerCLICommitSuite) TestCommitAfterContainerIsDone(c *testing.T) {
  21. skip.If(c, RuntimeIsWindowsContainerd(), "FIXME: Broken on Windows + containerd combination")
  22. out := cli.DockerCmd(c, "run", "-i", "-a", "stdin", "busybox", "echo", "foo").Combined()
  23. cleanedContainerID := strings.TrimSpace(out)
  24. cli.DockerCmd(c, "wait", cleanedContainerID)
  25. out = cli.DockerCmd(c, "commit", cleanedContainerID).Combined()
  26. cleanedImageID := strings.TrimSpace(out)
  27. cli.DockerCmd(c, "inspect", cleanedImageID)
  28. }
  29. func (s *DockerCLICommitSuite) TestCommitWithoutPause(c *testing.T) {
  30. testRequires(c, DaemonIsLinux)
  31. out := cli.DockerCmd(c, "run", "-i", "-a", "stdin", "busybox", "echo", "foo").Combined()
  32. cleanedContainerID := strings.TrimSpace(out)
  33. cli.DockerCmd(c, "wait", cleanedContainerID)
  34. out = cli.DockerCmd(c, "commit", "-p=false", cleanedContainerID).Combined()
  35. cleanedImageID := strings.TrimSpace(out)
  36. cli.DockerCmd(c, "inspect", cleanedImageID)
  37. }
  38. // TestCommitPausedContainer tests that a paused container is not unpaused after being committed
  39. func (s *DockerCLICommitSuite) TestCommitPausedContainer(c *testing.T) {
  40. testRequires(c, DaemonIsLinux)
  41. containerID := cli.DockerCmd(c, "run", "-i", "-d", "busybox").Stdout()
  42. containerID = strings.TrimSpace(containerID)
  43. cli.DockerCmd(c, "pause", containerID)
  44. cli.DockerCmd(c, "commit", containerID)
  45. out := inspectField(c, containerID, "State.Paused")
  46. // commit should not unpause a paused container
  47. assert.Assert(c, strings.Contains(out, "true"))
  48. }
  49. func (s *DockerCLICommitSuite) TestCommitNewFile(c *testing.T) {
  50. cli.DockerCmd(c, "run", "--name", "committer", "busybox", "/bin/sh", "-c", "echo koye > /foo")
  51. imageID := cli.DockerCmd(c, "commit", "committer").Stdout()
  52. imageID = strings.TrimSpace(imageID)
  53. out := cli.DockerCmd(c, "run", imageID, "cat", "/foo").Combined()
  54. actual := strings.TrimSpace(out)
  55. assert.Equal(c, actual, "koye")
  56. }
  57. func (s *DockerCLICommitSuite) TestCommitHardlink(c *testing.T) {
  58. testRequires(c, DaemonIsLinux)
  59. firstOutput := cli.DockerCmd(c, "run", "-t", "--name", "hardlinks", "busybox", "sh", "-c", "touch file1 && ln file1 file2 && ls -di file1 file2").Combined()
  60. chunks := strings.Split(strings.TrimSpace(firstOutput), " ")
  61. inode := chunks[0]
  62. chunks = strings.SplitAfterN(strings.TrimSpace(firstOutput), " ", 2)
  63. assert.Assert(c, strings.Contains(chunks[1], chunks[0]), "Failed to create hardlink in a container. Expected to find %q in %q", inode, chunks[1:])
  64. imageID := cli.DockerCmd(c, "commit", "hardlinks", "hardlinks").Stdout()
  65. imageID = strings.TrimSpace(imageID)
  66. secondOutput := cli.DockerCmd(c, "run", "-t", imageID, "ls", "-di", "file1", "file2").Combined()
  67. chunks = strings.Split(strings.TrimSpace(secondOutput), " ")
  68. inode = chunks[0]
  69. chunks = strings.SplitAfterN(strings.TrimSpace(secondOutput), " ", 2)
  70. assert.Assert(c, strings.Contains(chunks[1], chunks[0]), "Failed to create hardlink in a container. Expected to find %q in %q", inode, chunks[1:])
  71. }
  72. func (s *DockerCLICommitSuite) TestCommitTTY(c *testing.T) {
  73. cli.DockerCmd(c, "run", "-t", "--name", "tty", "busybox", "/bin/ls")
  74. imageID := cli.DockerCmd(c, "commit", "tty", "ttytest").Stdout()
  75. imageID = strings.TrimSpace(imageID)
  76. cli.DockerCmd(c, "run", imageID, "/bin/ls")
  77. }
  78. func (s *DockerCLICommitSuite) TestCommitWithHostBindMount(c *testing.T) {
  79. testRequires(c, DaemonIsLinux)
  80. cli.DockerCmd(c, "run", "--name", "bind-commit", "-v", "/dev/null:/winning", "busybox", "true")
  81. imageID := cli.DockerCmd(c, "commit", "bind-commit", "bindtest").Stdout()
  82. imageID = strings.TrimSpace(imageID)
  83. cli.DockerCmd(c, "run", imageID, "true")
  84. }
  85. func (s *DockerCLICommitSuite) TestCommitChange(c *testing.T) {
  86. cli.DockerCmd(c, "run", "--name", "test", "busybox", "true")
  87. imageID := cli.DockerCmd(c, "commit",
  88. "--change", `EXPOSE 8080`,
  89. "--change", `ENV DEBUG true`,
  90. "--change", `ENV test 1`,
  91. "--change", `ENV PATH /foo`,
  92. "--change", `LABEL foo bar`,
  93. "--change", `CMD ["/bin/sh"]`,
  94. "--change", `WORKDIR /opt`,
  95. "--change", `ENTRYPOINT ["/bin/sh"]`,
  96. "--change", `USER testuser`,
  97. "--change", `VOLUME /var/lib/docker`,
  98. "--change", `ONBUILD /usr/local/bin/python-build --dir /app/src`,
  99. "test", "test-commit",
  100. ).Stdout()
  101. imageID = strings.TrimSpace(imageID)
  102. expectedEnv := "[DEBUG=true test=1 PATH=/foo]"
  103. // bug fixed in 1.36, add min APi >= 1.36 requirement
  104. // PR record https://github.com/moby/moby/pull/35582
  105. if versions.GreaterThan(testEnv.DaemonAPIVersion(), "1.35") && testEnv.DaemonInfo.OSType != "windows" {
  106. // The ordering here is due to `PATH` being overridden from the container's
  107. // ENV. On windows, the container doesn't have a `PATH` ENV variable so
  108. // the ordering is the same as the cli.
  109. expectedEnv = "[PATH=/foo DEBUG=true test=1]"
  110. }
  111. prefix, slash := getPrefixAndSlashFromDaemonPlatform()
  112. prefix = strings.ToUpper(prefix) // Force C: as that's how WORKDIR is normalized on Windows
  113. expected := map[string]string{
  114. "Config.ExposedPorts": "map[8080/tcp:{}]",
  115. "Config.Env": expectedEnv,
  116. "Config.Labels": "map[foo:bar]",
  117. "Config.Cmd": "[/bin/sh]",
  118. "Config.WorkingDir": prefix + slash + "opt",
  119. "Config.Entrypoint": "[/bin/sh]",
  120. "Config.User": "testuser",
  121. "Config.Volumes": "map[/var/lib/docker:{}]",
  122. "Config.OnBuild": "[/usr/local/bin/python-build --dir /app/src]",
  123. }
  124. for conf, value := range expected {
  125. res := inspectField(c, imageID, conf)
  126. if res != value {
  127. c.Errorf("%s('%s'), expected %s", conf, res, value)
  128. }
  129. }
  130. }
  131. func (s *DockerCLICommitSuite) TestCommitChangeLabels(c *testing.T) {
  132. cli.DockerCmd(c, "run", "--name", "test", "--label", "some=label", "busybox", "true")
  133. imageID := cli.DockerCmd(c, "commit", "--change", "LABEL some=label2", "test", "test-commit").Stdout()
  134. imageID = strings.TrimSpace(imageID)
  135. assert.Equal(c, inspectField(c, imageID, "Config.Labels"), "map[some:label2]")
  136. // check that container labels didn't change
  137. assert.Equal(c, inspectField(c, "test", "Config.Labels"), "map[some:label]")
  138. }