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