github.com/containers/podman/v5@v5.1.0-rc1/test/e2e/commit_test.go (about)

     1  package integration
     2  
     3  import (
     4  	"os"
     5  	"path/filepath"
     6  	"strings"
     7  
     8  	. "github.com/containers/podman/v5/test/utils"
     9  	. "github.com/onsi/ginkgo/v2"
    10  	. "github.com/onsi/gomega"
    11  	. "github.com/onsi/gomega/gexec"
    12  )
    13  
    14  var _ = Describe("Podman commit", func() {
    15  
    16  	It("podman commit container", func() {
    17  		_, ec, _ := podmanTest.RunLsContainer("test1")
    18  		Expect(ec).To(Equal(0))
    19  		Expect(podmanTest.NumberOfContainers()).To(Equal(1))
    20  
    21  		session := podmanTest.Podman([]string{"commit", "test1", "--change", "BOGUS=foo", "foobar.com/test1-image:latest"})
    22  		session.WaitWithDefaultTimeout()
    23  		Expect(session).Should(ExitWithError(125, `applying changes: processing change "BOGUS foo": did not understand change instruction "BOGUS foo"`))
    24  
    25  		session = podmanTest.Podman([]string{"commit", "test1", "foobar.com/test1-image:latest"})
    26  		session.WaitWithDefaultTimeout()
    27  		Expect(session).Should(Exit(0))
    28  
    29  		messages := session.ErrorToString()
    30  		Expect(messages).To(ContainSubstring("Getting image source signatures"))
    31  		Expect(messages).To(ContainSubstring("Copying blob"))
    32  		Expect(messages).To(ContainSubstring("Writing manifest to image destination"))
    33  		Expect(messages).To(Not(ContainSubstring("level=")), "Unexpected logrus messages in stderr")
    34  
    35  		check := podmanTest.Podman([]string{"inspect", "foobar.com/test1-image:latest"})
    36  		check.WaitWithDefaultTimeout()
    37  		data := check.InspectImageJSON()
    38  		Expect(data[0].RepoTags).To(ContainElement("foobar.com/test1-image:latest"))
    39  
    40  		// commit second time with --quiet, should not write to stderr
    41  		session = podmanTest.Podman([]string{"commit", "--quiet", "test1", "foobar.com/test1-image:latest"})
    42  		session.WaitWithDefaultTimeout()
    43  		Expect(session).Should(Exit(0))
    44  		Expect(session.ErrorToString()).To(BeEmpty())
    45  
    46  		// commit second time with --quiet, should not write to stderr
    47  		session = podmanTest.Podman([]string{"commit", "--quiet", "bogus", "foobar.com/test1-image:latest"})
    48  		session.WaitWithDefaultTimeout()
    49  		Expect(session).Should(ExitWithError(125, `no container with name or ID "bogus" found: no such container`))
    50  	})
    51  
    52  	It("podman commit single letter container", func() {
    53  		_, ec, _ := podmanTest.RunLsContainer("test1")
    54  		Expect(ec).To(Equal(0))
    55  		Expect(podmanTest.NumberOfContainers()).To(Equal(1))
    56  
    57  		session := podmanTest.Podman([]string{"commit", "-q", "test1", "a"})
    58  		session.WaitWithDefaultTimeout()
    59  		Expect(session).Should(ExitCleanly())
    60  
    61  		check := podmanTest.Podman([]string{"inspect", "localhost/a:latest"})
    62  		check.WaitWithDefaultTimeout()
    63  		data := check.InspectImageJSON()
    64  		Expect(data[0].RepoTags).To(ContainElement("localhost/a:latest"))
    65  	})
    66  
    67  	It("podman container commit container", func() {
    68  		_, ec, _ := podmanTest.RunLsContainer("test1")
    69  		Expect(ec).To(Equal(0))
    70  		Expect(podmanTest.NumberOfContainers()).To(Equal(1))
    71  
    72  		session := podmanTest.Podman([]string{"container", "commit", "-q", "test1", "foobar.com/test1-image:latest"})
    73  		session.WaitWithDefaultTimeout()
    74  		Expect(session).Should(ExitCleanly())
    75  
    76  		check := podmanTest.Podman([]string{"image", "inspect", "foobar.com/test1-image:latest"})
    77  		check.WaitWithDefaultTimeout()
    78  		data := check.InspectImageJSON()
    79  		Expect(data[0].RepoTags).To(ContainElement("foobar.com/test1-image:latest"))
    80  	})
    81  
    82  	It("podman commit container with message", func() {
    83  		_, ec, _ := podmanTest.RunLsContainer("test1")
    84  		Expect(ec).To(Equal(0))
    85  		Expect(podmanTest.NumberOfContainers()).To(Equal(1))
    86  
    87  		session := podmanTest.Podman([]string{"commit", "-q", "-f", "docker", "--message", "testing-commit", "test1", "foobar.com/test1-image:latest"})
    88  		session.WaitWithDefaultTimeout()
    89  		Expect(session).Should(ExitCleanly())
    90  
    91  		check := podmanTest.Podman([]string{"inspect", "foobar.com/test1-image:latest"})
    92  		check.WaitWithDefaultTimeout()
    93  		data := check.InspectImageJSON()
    94  		Expect(data[0]).To(HaveField("Comment", "testing-commit"))
    95  	})
    96  
    97  	It("podman commit container with author", func() {
    98  		_, ec, _ := podmanTest.RunLsContainer("test1")
    99  		Expect(ec).To(Equal(0))
   100  		Expect(podmanTest.NumberOfContainers()).To(Equal(1))
   101  
   102  		session := podmanTest.Podman([]string{"commit", "-q", "--author", "snoopy", "test1", "foobar.com/test1-image:latest"})
   103  		session.WaitWithDefaultTimeout()
   104  		Expect(session).Should(ExitCleanly())
   105  
   106  		check := podmanTest.Podman([]string{"inspect", "foobar.com/test1-image:latest"})
   107  		check.WaitWithDefaultTimeout()
   108  		data := check.InspectImageJSON()
   109  		Expect(data[0]).To(HaveField("Author", "snoopy"))
   110  	})
   111  
   112  	It("podman commit container with change flag", func() {
   113  		test := podmanTest.Podman([]string{"run", "--name", "test1", "-d", ALPINE, "ls"})
   114  		test.WaitWithDefaultTimeout()
   115  		Expect(test).Should(ExitCleanly())
   116  		Expect(podmanTest.NumberOfContainers()).To(Equal(1))
   117  
   118  		session := podmanTest.Podman([]string{"commit", "-q", "--change", "LABEL=image=blue", "test1", "foobar.com/test1-image:latest"})
   119  		session.WaitWithDefaultTimeout()
   120  		Expect(session).Should(ExitCleanly())
   121  
   122  		check := podmanTest.Podman([]string{"inspect", "foobar.com/test1-image:latest"})
   123  		check.WaitWithDefaultTimeout()
   124  		inspectResults := check.InspectImageJSON()
   125  		Expect(inspectResults[0].Labels).To(HaveKeyWithValue("image", "blue"))
   126  	})
   127  
   128  	It("podman commit container with --config flag", func() {
   129  		test := podmanTest.Podman([]string{"run", "--name", "test1", "-d", ALPINE, "ls"})
   130  		test.WaitWithDefaultTimeout()
   131  		Expect(test).Should(ExitCleanly())
   132  		Expect(podmanTest.NumberOfContainers()).To(Equal(1))
   133  
   134  		configFile, err := os.CreateTemp(podmanTest.TempDir, "")
   135  		Expect(err).Should(Succeed())
   136  		_, err = configFile.WriteString(`{"Labels":{"image":"green"}}`)
   137  		Expect(err).Should(Succeed())
   138  		configFile.Close()
   139  
   140  		session := podmanTest.Podman([]string{"commit", "-q", "--config", configFile.Name(), "test1", "foobar.com/test1-image:latest"})
   141  		session.WaitWithDefaultTimeout()
   142  		Expect(session).Should(ExitCleanly())
   143  
   144  		check := podmanTest.Podman([]string{"inspect", "foobar.com/test1-image:latest"})
   145  		check.WaitWithDefaultTimeout()
   146  		inspectResults := check.InspectImageJSON()
   147  		Expect(inspectResults[0].Labels).To(HaveKeyWithValue("image", "green"))
   148  	})
   149  
   150  	It("podman commit container with --config pointing to trash", func() {
   151  		test := podmanTest.Podman([]string{"run", "--name", "test1", "-d", ALPINE, "ls"})
   152  		test.WaitWithDefaultTimeout()
   153  		Expect(test).Should(ExitCleanly())
   154  		Expect(podmanTest.NumberOfContainers()).To(Equal(1))
   155  
   156  		configFile, err := os.CreateTemp(podmanTest.TempDir, "")
   157  		Expect(err).Should(Succeed())
   158  		_, err = configFile.WriteString("this is not valid JSON\n")
   159  		Expect(err).Should(Succeed())
   160  		configFile.Close()
   161  
   162  		session := podmanTest.Podman([]string{"commit", "-q", "--config", configFile.Name(), "test1", "foobar.com/test1-image:latest"})
   163  		session.WaitWithDefaultTimeout()
   164  		Expect(session).Should(Not(ExitCleanly()))
   165  	})
   166  
   167  	It("podman commit container with --squash", func() {
   168  		test := podmanTest.Podman([]string{"run", "--name", "test1", "-d", ALPINE, "ls"})
   169  		test.WaitWithDefaultTimeout()
   170  		Expect(test).Should(ExitCleanly())
   171  		Expect(podmanTest.NumberOfContainers()).To(Equal(1))
   172  
   173  		session := podmanTest.Podman([]string{"commit", "-q", "--squash", "test1", "foobar.com/test1-image:latest"})
   174  		session.WaitWithDefaultTimeout()
   175  		Expect(session).Should(ExitCleanly())
   176  
   177  		session = podmanTest.Podman([]string{"inspect", "--format", "{{.RootFS.Layers}}", "foobar.com/test1-image:latest"})
   178  		session.WaitWithDefaultTimeout()
   179  		Expect(session).Should(ExitCleanly())
   180  		// Check for one layers
   181  		Expect(strings.Fields(session.OutputToString())).To(HaveLen(1))
   182  	})
   183  
   184  	It("podman commit container with change flag and JSON entrypoint with =", func() {
   185  		test := podmanTest.Podman([]string{"run", "--name", "test1", "-d", ALPINE, "ls"})
   186  		test.WaitWithDefaultTimeout()
   187  		Expect(test).Should(ExitCleanly())
   188  		Expect(podmanTest.NumberOfContainers()).To(Equal(1))
   189  
   190  		session := podmanTest.Podman([]string{"commit", "-q", "--change", `ENTRYPOINT ["foo", "bar=baz"]`, "test1", "foobar.com/test1-image:latest"})
   191  		session.WaitWithDefaultTimeout()
   192  		Expect(session).Should(ExitCleanly())
   193  
   194  		check := podmanTest.Podman([]string{"inspect", "foobar.com/test1-image:latest"})
   195  		check.WaitWithDefaultTimeout()
   196  		data := check.InspectImageJSON()
   197  		Expect(data).To(HaveLen(1))
   198  		Expect(data[0].Config.Entrypoint).To(HaveLen(2))
   199  		Expect(data[0].Config.Entrypoint[0]).To(Equal("foo"))
   200  		Expect(data[0].Config.Entrypoint[1]).To(Equal("bar=baz"))
   201  	})
   202  
   203  	It("podman commit container with change CMD flag", func() {
   204  		test := podmanTest.Podman([]string{"run", "--name", "test1", "-d", ALPINE, "ls"})
   205  		test.WaitWithDefaultTimeout()
   206  		Expect(test).Should(ExitCleanly())
   207  		Expect(podmanTest.NumberOfContainers()).To(Equal(1))
   208  
   209  		session := podmanTest.Podman([]string{"commit", "-q", "--change", "CMD a b c", "test1", "foobar.com/test1-image:latest"})
   210  		session.WaitWithDefaultTimeout()
   211  		Expect(session).Should(ExitCleanly())
   212  
   213  		session = podmanTest.Podman([]string{"inspect", "--format", "{{.Config.Cmd}}", "foobar.com/test1-image:latest"})
   214  		session.WaitWithDefaultTimeout()
   215  		Expect(session).Should(ExitCleanly())
   216  		Expect(session.OutputToString()).To(ContainSubstring("sh -c a b c"))
   217  
   218  		session = podmanTest.Podman([]string{"commit", "-q", "--change", "CMD=[\"a\",\"b\",\"c\"]", "test1", "foobar.com/test1-image:latest"})
   219  		session.WaitWithDefaultTimeout()
   220  		Expect(session).Should(ExitCleanly())
   221  
   222  		session = podmanTest.Podman([]string{"inspect", "--format", "{{.Config.Cmd}}", "foobar.com/test1-image:latest"})
   223  		session.WaitWithDefaultTimeout()
   224  		Expect(session).Should(ExitCleanly())
   225  		Expect(session.OutputToString()).To(Not(ContainSubstring("sh -c")))
   226  	})
   227  
   228  	It("podman commit container with pause flag", func() {
   229  		_, ec, _ := podmanTest.RunLsContainer("test1")
   230  		Expect(ec).To(Equal(0))
   231  		Expect(podmanTest.NumberOfContainers()).To(Equal(1))
   232  
   233  		session := podmanTest.Podman([]string{"commit", "-q", "--pause=false", "test1", "foobar.com/test1-image:latest"})
   234  		session.WaitWithDefaultTimeout()
   235  		Expect(session).Should(ExitCleanly())
   236  
   237  		check := podmanTest.Podman([]string{"inspect", "foobar.com/test1-image:latest"})
   238  		check.WaitWithDefaultTimeout()
   239  		Expect(check).Should(ExitCleanly())
   240  	})
   241  
   242  	It("podman commit with volumes mounts and no include-volumes", func() {
   243  		s := podmanTest.Podman([]string{"run", "--name", "test1", "-v", "/tmp:/foo", "alpine", "date"})
   244  		s.WaitWithDefaultTimeout()
   245  		Expect(s).Should(ExitCleanly())
   246  
   247  		c := podmanTest.Podman([]string{"commit", "-q", "test1", "newimage"})
   248  		c.WaitWithDefaultTimeout()
   249  		Expect(c).Should(ExitCleanly())
   250  
   251  		inspect := podmanTest.Podman([]string{"inspect", "newimage"})
   252  		inspect.WaitWithDefaultTimeout()
   253  		Expect(inspect).Should(ExitCleanly())
   254  		image := inspect.InspectImageJSON()
   255  		Expect(image[0].Config.Volumes).To(Not(HaveKey("/foo")))
   256  	})
   257  
   258  	It("podman commit with volume mounts and --include-volumes", func() {
   259  		// We need to figure out how volumes are going to work correctly with the remote
   260  		// client.  This does not currently work.
   261  		SkipIfRemote("--testing Remote Volumes")
   262  		s := podmanTest.Podman([]string{"run", "--name", "test1", "-v", "/tmp:/foo", "alpine", "date"})
   263  		s.WaitWithDefaultTimeout()
   264  		Expect(s).Should(ExitCleanly())
   265  
   266  		c := podmanTest.Podman([]string{"commit", "-q", "--include-volumes", "test1", "newimage"})
   267  		c.WaitWithDefaultTimeout()
   268  		Expect(c).Should(ExitCleanly())
   269  
   270  		inspect := podmanTest.Podman([]string{"inspect", "newimage"})
   271  		inspect.WaitWithDefaultTimeout()
   272  		Expect(inspect).Should(ExitCleanly())
   273  		image := inspect.InspectImageJSON()
   274  		Expect(image[0].Config.Volumes).To(HaveKey("/foo"))
   275  
   276  		r := podmanTest.Podman([]string{"run", "newimage"})
   277  		r.WaitWithDefaultTimeout()
   278  		Expect(r).Should(ExitCleanly())
   279  	})
   280  
   281  	It("podman commit container check env variables", func() {
   282  		s := podmanTest.Podman([]string{"run", "--name", "test1", "-e", "TEST=1=1-01=9.01", "alpine", "true"})
   283  		s.WaitWithDefaultTimeout()
   284  		Expect(s).Should(ExitCleanly())
   285  
   286  		c := podmanTest.Podman([]string{"commit", "-q", "test1", "newimage"})
   287  		c.WaitWithDefaultTimeout()
   288  		Expect(c).Should(ExitCleanly())
   289  
   290  		inspect := podmanTest.Podman([]string{"inspect", "newimage"})
   291  		inspect.WaitWithDefaultTimeout()
   292  		Expect(inspect).Should(ExitCleanly())
   293  		image := inspect.InspectImageJSON()
   294  
   295  		envMap := make(map[string]bool)
   296  		for _, v := range image[0].Config.Env {
   297  			envMap[v] = true
   298  		}
   299  		Expect(envMap).To(HaveKey("TEST=1=1-01=9.01"))
   300  	})
   301  
   302  	It("podman commit container and print id to external file", func() {
   303  		// Switch to temp dir and restore it afterwards
   304  		cwd, err := os.Getwd()
   305  		Expect(err).ToNot(HaveOccurred())
   306  		Expect(os.Chdir(os.TempDir())).To(Succeed())
   307  		targetPath := podmanTest.TempDir
   308  		targetFile := filepath.Join(targetPath, "idFile")
   309  		defer Expect(os.Chdir(cwd)).To(BeNil())
   310  
   311  		_, ec, _ := podmanTest.RunLsContainer("test1")
   312  		Expect(ec).To(Equal(0))
   313  		Expect(podmanTest.NumberOfContainers()).To(Equal(1))
   314  
   315  		session := podmanTest.Podman([]string{"commit", "-q", "test1", "foobar.com/test1-image:latest", "--iidfile", targetFile})
   316  		session.WaitWithDefaultTimeout()
   317  		Expect(session).Should(ExitCleanly())
   318  
   319  		id, _ := os.ReadFile(targetFile)
   320  		check := podmanTest.Podman([]string{"inspect", "foobar.com/test1-image:latest"})
   321  		check.WaitWithDefaultTimeout()
   322  		data := check.InspectImageJSON()
   323  		Expect(data[0]).To(HaveField("ID", string(id)))
   324  	})
   325  
   326  	It("podman commit should not commit secret", func() {
   327  		secretsString := "somesecretdata"
   328  		secretFilePath := filepath.Join(podmanTest.TempDir, "secret")
   329  		err := os.WriteFile(secretFilePath, []byte(secretsString), 0755)
   330  		Expect(err).ToNot(HaveOccurred())
   331  
   332  		session := podmanTest.Podman([]string{"secret", "create", "mysecret", secretFilePath})
   333  		session.WaitWithDefaultTimeout()
   334  		Expect(session).Should(ExitCleanly())
   335  
   336  		session = podmanTest.Podman([]string{"run", "--secret", "mysecret", "--name", "secr", ALPINE, "cat", "/run/secrets/mysecret"})
   337  		session.WaitWithDefaultTimeout()
   338  		Expect(session).Should(ExitCleanly())
   339  		Expect(session.OutputToString()).To(Equal(secretsString))
   340  
   341  		session = podmanTest.Podman([]string{"commit", "-q", "secr", "foobar.com/test1-image:latest"})
   342  		session.WaitWithDefaultTimeout()
   343  		Expect(session).Should(ExitCleanly())
   344  
   345  		session = podmanTest.Podman([]string{"run", "foobar.com/test1-image:latest", "cat", "/run/secrets/mysecret"})
   346  		session.WaitWithDefaultTimeout()
   347  		Expect(session).To(ExitWithError(1, "can't open '/run/secrets/mysecret': No such file or directory"))
   348  
   349  	})
   350  
   351  	It("podman commit should not commit env secret", func() {
   352  		secretsString := "somesecretdata"
   353  		secretFilePath := filepath.Join(podmanTest.TempDir, "secret")
   354  		err := os.WriteFile(secretFilePath, []byte(secretsString), 0755)
   355  		Expect(err).ToNot(HaveOccurred())
   356  
   357  		session := podmanTest.Podman([]string{"secret", "create", "mysecret", secretFilePath})
   358  		session.WaitWithDefaultTimeout()
   359  		Expect(session).Should(ExitCleanly())
   360  
   361  		session = podmanTest.Podman([]string{"run", "--secret", "source=mysecret,type=env", "--name", "secr", ALPINE, "printenv", "mysecret"})
   362  		session.WaitWithDefaultTimeout()
   363  		Expect(session).Should(ExitCleanly())
   364  		Expect(session.OutputToString()).To(Equal(secretsString))
   365  
   366  		session = podmanTest.Podman([]string{"commit", "-q", "secr", "foobar.com/test1-image:latest"})
   367  		session.WaitWithDefaultTimeout()
   368  		Expect(session).Should(ExitCleanly())
   369  
   370  		session = podmanTest.Podman([]string{"run", "foobar.com/test1-image:latest", "printenv", "mysecret"})
   371  		session.WaitWithDefaultTimeout()
   372  		Expect(session.OutputToString()).To(Not(ContainSubstring(secretsString)))
   373  	})
   374  
   375  	It("podman commit adds exposed ports", func() {
   376  		name := "testcon"
   377  		s := podmanTest.Podman([]string{"run", "--name", name, "-p", "8585:80", ALPINE, "true"})
   378  		s.WaitWithDefaultTimeout()
   379  		Expect(s).Should(ExitCleanly())
   380  
   381  		newImageName := "newimage"
   382  		c := podmanTest.Podman([]string{"commit", "-q", name, newImageName})
   383  		c.WaitWithDefaultTimeout()
   384  		Expect(c).Should(ExitCleanly())
   385  
   386  		inspect := podmanTest.Podman([]string{"inspect", newImageName})
   387  		inspect.WaitWithDefaultTimeout()
   388  		Expect(inspect).Should(ExitCleanly())
   389  		images := inspect.InspectImageJSON()
   390  		Expect(images).To(HaveLen(1))
   391  		Expect(images[0].Config.ExposedPorts).To(HaveKey("80/tcp"))
   392  
   393  		name = "testcon2"
   394  		s = podmanTest.Podman([]string{"run", "--name", name, "-d", NGINX_IMAGE})
   395  		s.WaitWithDefaultTimeout()
   396  		Expect(s).Should(ExitCleanly())
   397  
   398  		newImageName = "newimage2"
   399  		c = podmanTest.Podman([]string{"commit", "-q", name, newImageName})
   400  		c.WaitWithDefaultTimeout()
   401  		Expect(c).Should(ExitCleanly())
   402  
   403  		inspect = podmanTest.Podman([]string{"inspect", newImageName})
   404  		inspect.WaitWithDefaultTimeout()
   405  		Expect(inspect).Should(ExitCleanly())
   406  		images = inspect.InspectImageJSON()
   407  		Expect(images).To(HaveLen(1))
   408  		Expect(images[0].Config.ExposedPorts).To(HaveKey("80/tcp"))
   409  	})
   410  })