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

     1  package integration
     2  
     3  import (
     4  	. "github.com/containers/podman/v5/test/utils"
     5  	. "github.com/onsi/ginkgo/v2"
     6  	. "github.com/onsi/gomega"
     7  	. "github.com/onsi/gomega/gexec"
     8  )
     9  
    10  var _ = Describe("Podman container clone", func() {
    11  	BeforeEach(func() {
    12  		SkipIfRemote("podman container clone is not supported in remote")
    13  	})
    14  
    15  	It("podman container clone basic test", func() {
    16  		SkipIfRootlessCgroupsV1("starting a container with the memory limits not supported")
    17  		create := podmanTest.Podman([]string{"create", ALPINE})
    18  		create.WaitWithDefaultTimeout()
    19  		Expect(create).To(ExitCleanly())
    20  		clone := podmanTest.Podman([]string{"container", "clone", create.OutputToString()})
    21  		clone.WaitWithDefaultTimeout()
    22  		Expect(clone).To(ExitCleanly())
    23  
    24  		clone = podmanTest.Podman([]string{"container", "clone", clone.OutputToString()})
    25  		clone.WaitWithDefaultTimeout()
    26  		Expect(clone).To(ExitCleanly())
    27  
    28  		ctrInspect := podmanTest.Podman([]string{"inspect", clone.OutputToString()})
    29  		ctrInspect.WaitWithDefaultTimeout()
    30  		Expect(ctrInspect).To(ExitCleanly())
    31  		Expect(ctrInspect.InspectContainerToJSON()[0].Name).To(ContainSubstring("-clone1"))
    32  
    33  		ctrStart := podmanTest.Podman([]string{"container", "start", clone.OutputToString()})
    34  		ctrStart.WaitWithDefaultTimeout()
    35  		Expect(ctrStart).To(ExitCleanly())
    36  	})
    37  
    38  	It("podman container clone image test", func() {
    39  		create := podmanTest.Podman([]string{"create", ALPINE})
    40  		create.WaitWithDefaultTimeout()
    41  		Expect(create).To(ExitCleanly())
    42  		clone := podmanTest.Podman([]string{"container", "clone", create.OutputToString(), "new_name", fedoraMinimal})
    43  		clone.WaitWithDefaultTimeout()
    44  		Expect(clone).To(ExitCleanly())
    45  
    46  		ctrInspect := podmanTest.Podman([]string{"inspect", clone.OutputToString()})
    47  		ctrInspect.WaitWithDefaultTimeout()
    48  		Expect(ctrInspect).To(ExitCleanly())
    49  		Expect(ctrInspect.InspectContainerToJSON()[0]).To(HaveField("ImageName", fedoraMinimal))
    50  		Expect(ctrInspect.InspectContainerToJSON()[0]).To(HaveField("Name", "new_name"))
    51  	})
    52  
    53  	It("podman container clone name test", func() {
    54  		create := podmanTest.Podman([]string{"create", ALPINE})
    55  		create.WaitWithDefaultTimeout()
    56  		Expect(create).To(ExitCleanly())
    57  		clone := podmanTest.Podman([]string{"container", "clone", "--name", "testing123", create.OutputToString()})
    58  		clone.WaitWithDefaultTimeout()
    59  		Expect(clone).To(ExitCleanly())
    60  
    61  		cloneInspect := podmanTest.Podman([]string{"inspect", clone.OutputToString()})
    62  		cloneInspect.WaitWithDefaultTimeout()
    63  		Expect(cloneInspect).To(ExitCleanly())
    64  		cloneData := cloneInspect.InspectContainerToJSON()
    65  		Expect(cloneData[0]).To(HaveField("Name", "testing123"))
    66  	})
    67  
    68  	It("podman container clone resource limits override", func() {
    69  		SkipIfRootlessCgroupsV1("Not supported for rootless + CgroupsV1")
    70  		create := podmanTest.Podman([]string{"create", "--cpus=5", ALPINE})
    71  		create.WaitWithDefaultTimeout()
    72  		Expect(create).To(ExitCleanly())
    73  		clone := podmanTest.Podman([]string{"container", "clone", create.OutputToString()})
    74  		clone.WaitWithDefaultTimeout()
    75  		Expect(clone).To(ExitCleanly())
    76  
    77  		createInspect := podmanTest.Podman([]string{"inspect", create.OutputToString()})
    78  		createInspect.WaitWithDefaultTimeout()
    79  		Expect(createInspect).To(ExitCleanly())
    80  		createData := createInspect.InspectContainerToJSON()
    81  
    82  		cloneInspect := podmanTest.Podman([]string{"inspect", clone.OutputToString()})
    83  		cloneInspect.WaitWithDefaultTimeout()
    84  		Expect(cloneInspect).To(ExitCleanly())
    85  		cloneData := cloneInspect.InspectContainerToJSON()
    86  		Expect(createData[0].HostConfig).To(HaveField("NanoCpus", cloneData[0].HostConfig.NanoCpus))
    87  
    88  		create = podmanTest.Podman([]string{"create", "--memory=5", ALPINE})
    89  		create.WaitWithDefaultTimeout()
    90  		Expect(create).To(ExitCleanly())
    91  		clone = podmanTest.Podman([]string{"container", "clone", "--cpus=6", create.OutputToString()})
    92  		clone.WaitWithDefaultTimeout()
    93  		Expect(clone).To(ExitCleanly())
    94  
    95  		createInspect = podmanTest.Podman([]string{"inspect", create.OutputToString()})
    96  		createInspect.WaitWithDefaultTimeout()
    97  		Expect(createInspect).To(ExitCleanly())
    98  		createData = createInspect.InspectContainerToJSON()
    99  
   100  		cloneInspect = podmanTest.Podman([]string{"inspect", clone.OutputToString()})
   101  		cloneInspect.WaitWithDefaultTimeout()
   102  		Expect(cloneInspect).To(ExitCleanly())
   103  		cloneData = cloneInspect.InspectContainerToJSON()
   104  		Expect(createData[0].HostConfig).To(HaveField("MemorySwap", cloneData[0].HostConfig.MemorySwap))
   105  
   106  		create = podmanTest.Podman([]string{"create", "--cpus=5", ALPINE})
   107  		create.WaitWithDefaultTimeout()
   108  		Expect(create).To(ExitCleanly())
   109  		clone = podmanTest.Podman([]string{"container", "clone", "--cpus=4", create.OutputToString()})
   110  		clone.WaitWithDefaultTimeout()
   111  		Expect(clone).To(ExitCleanly())
   112  
   113  		var nanoCPUs int64
   114  		numCpus := 4
   115  		nanoCPUs = int64(numCpus * 1000000000)
   116  
   117  		createInspect = podmanTest.Podman([]string{"inspect", create.OutputToString()})
   118  		createInspect.WaitWithDefaultTimeout()
   119  		Expect(createInspect).To(ExitCleanly())
   120  		createData = createInspect.InspectContainerToJSON()
   121  
   122  		cloneInspect = podmanTest.Podman([]string{"inspect", clone.OutputToString()})
   123  		cloneInspect.WaitWithDefaultTimeout()
   124  		Expect(cloneInspect).To(ExitCleanly())
   125  		cloneData = cloneInspect.InspectContainerToJSON()
   126  		Expect(createData[0].HostConfig.NanoCpus).ToNot(Equal(cloneData[0].HostConfig.NanoCpus))
   127  		Expect(cloneData[0].HostConfig).To(HaveField("NanoCpus", nanoCPUs))
   128  
   129  		create = podmanTest.Podman([]string{"create", ALPINE})
   130  		create.WaitWithDefaultTimeout()
   131  		Expect(create).To(ExitCleanly())
   132  		clone = podmanTest.Podman([]string{"container", "clone", "--cpus=4", create.OutputToString()})
   133  		clone.WaitWithDefaultTimeout()
   134  		Expect(clone).To(ExitCleanly())
   135  
   136  		cloneInspect = podmanTest.Podman([]string{"inspect", clone.OutputToString()})
   137  		cloneInspect.WaitWithDefaultTimeout()
   138  		Expect(cloneInspect).To(ExitCleanly())
   139  		cloneData = cloneInspect.InspectContainerToJSON()
   140  		Expect(cloneData[0].HostConfig).To(HaveField("MemorySwappiness", int64(0)))
   141  
   142  	})
   143  
   144  	It("podman container clone in a pod", func() {
   145  		SkipIfRootlessCgroupsV1("starting a container with the memory limits not supported")
   146  		run := podmanTest.Podman([]string{"run", "-dt", "--pod", "new:1234", ALPINE, "sleep", "20"})
   147  		run.WaitWithDefaultTimeout()
   148  		Expect(run).To(ExitCleanly())
   149  		clone := podmanTest.Podman([]string{"container", "clone", run.OutputToString()})
   150  		clone.WaitWithDefaultTimeout()
   151  		Expect(clone).To(ExitCleanly())
   152  		ctrStart := podmanTest.Podman([]string{"container", "start", clone.OutputToString()})
   153  		ctrStart.WaitWithDefaultTimeout()
   154  		Expect(ctrStart).To(ExitCleanly())
   155  
   156  		checkClone := podmanTest.Podman([]string{"ps", "-f", "id=" + clone.OutputToString(), "--ns", "--format", "{{.Namespaces.IPC}} {{.Namespaces.UTS}} {{.Namespaces.NET}}"})
   157  		checkClone.WaitWithDefaultTimeout()
   158  		Expect(checkClone).Should(ExitCleanly())
   159  		cloneArray := checkClone.OutputToStringArray()
   160  
   161  		checkCreate := podmanTest.Podman([]string{"ps", "-f", "id=" + run.OutputToString(), "--ns", "--format", "{{.Namespaces.IPC}} {{.Namespaces.UTS}} {{.Namespaces.NET}}"})
   162  		checkCreate.WaitWithDefaultTimeout()
   163  		Expect(checkCreate).Should(ExitCleanly())
   164  		createArray := checkCreate.OutputToStringArray()
   165  
   166  		Expect(cloneArray).To(ContainElements(createArray))
   167  
   168  		ctrInspect := podmanTest.Podman([]string{"inspect", clone.OutputToString()})
   169  		ctrInspect.WaitWithDefaultTimeout()
   170  		Expect(ctrInspect).Should(ExitCleanly())
   171  
   172  		runInspect := podmanTest.Podman([]string{"inspect", run.OutputToString()})
   173  		runInspect.WaitWithDefaultTimeout()
   174  		Expect(runInspect).Should(ExitCleanly())
   175  
   176  		Expect(ctrInspect.InspectContainerToJSON()[0].Pod).Should(Equal(runInspect.InspectContainerToJSON()[0].Pod))
   177  		Expect(ctrInspect.InspectContainerToJSON()[0].HostConfig.NetworkMode).Should(Equal(runInspect.InspectContainerToJSON()[0].HostConfig.NetworkMode))
   178  	})
   179  
   180  	It("podman container clone to a pod", func() {
   181  		createPod := podmanTest.Podman([]string{"pod", "create", "--share", "uts", "--name", "foo-pod"})
   182  		createPod.WaitWithDefaultTimeout()
   183  		Expect(createPod).To(ExitCleanly())
   184  
   185  		ctr := podmanTest.RunTopContainer("ctr")
   186  		ctr.WaitWithDefaultTimeout()
   187  		Expect(ctr).Should(ExitCleanly())
   188  
   189  		clone := podmanTest.Podman([]string{"container", "clone", "--name", "cloned", "--pod", "foo-pod", "ctr"})
   190  		clone.WaitWithDefaultTimeout()
   191  		// Cannot use ExitCleanly() because of warning: "At least one namespace was reset to the default configuration"
   192  		Expect(clone).To(Exit(0))
   193  
   194  		ctrInspect := podmanTest.Podman([]string{"inspect", "cloned"})
   195  		ctrInspect.WaitWithDefaultTimeout()
   196  		Expect(ctrInspect).Should(ExitCleanly())
   197  
   198  		Expect(ctrInspect.InspectContainerToJSON()[0].Pod).Should(Equal(createPod.OutputToString()))
   199  
   200  		Expect(ctrInspect.InspectContainerToJSON()[0].HostConfig.NetworkMode).Should(Not(ContainSubstring("container:")))
   201  
   202  		createPod = podmanTest.Podman([]string{"pod", "create", "--share", "uts,net", "--name", "bar-pod"})
   203  		createPod.WaitWithDefaultTimeout()
   204  		Expect(createPod).To(ExitCleanly())
   205  
   206  		clone = podmanTest.Podman([]string{"container", "clone", "--name", "cloned2", "--pod", "bar-pod", "ctr"})
   207  		clone.WaitWithDefaultTimeout()
   208  		// Cannot use ExitCleanly() because of warning: "At least one namespace was reset to the default configuration"
   209  		Expect(clone).To(Exit(0))
   210  
   211  		ctrInspect = podmanTest.Podman([]string{"inspect", "cloned2"})
   212  		ctrInspect.WaitWithDefaultTimeout()
   213  		Expect(ctrInspect).Should(ExitCleanly())
   214  
   215  		Expect(ctrInspect.InspectContainerToJSON()[0].Pod).Should(Equal(createPod.OutputToString()))
   216  
   217  		Expect(ctrInspect.InspectContainerToJSON()[0].HostConfig.NetworkMode).Should(ContainSubstring("container:"))
   218  	})
   219  
   220  	It("podman container clone --destroy --force test", func() {
   221  		create := podmanTest.Podman([]string{"create", ALPINE})
   222  		create.WaitWithDefaultTimeout()
   223  		Expect(create).To(ExitCleanly())
   224  		clone := podmanTest.Podman([]string{"container", "clone", "--destroy", create.OutputToString()})
   225  		clone.WaitWithDefaultTimeout()
   226  		Expect(clone).To(ExitCleanly())
   227  
   228  		inspect := podmanTest.Podman([]string{"inspect", create.OutputToString()})
   229  		inspect.WaitWithDefaultTimeout()
   230  		Expect(inspect).ToNot(ExitCleanly())
   231  
   232  		run := podmanTest.Podman([]string{"run", "-dt", ALPINE, "top"})
   233  		run.WaitWithDefaultTimeout()
   234  		Expect(run).To(ExitCleanly())
   235  		clone = podmanTest.Podman([]string{"container", "clone", "--destroy", "-f", run.OutputToString()})
   236  		clone.WaitWithDefaultTimeout()
   237  		Expect(clone).To(ExitCleanly())
   238  
   239  		inspect = podmanTest.Podman([]string{"inspect", run.OutputToString()})
   240  		inspect.WaitWithDefaultTimeout()
   241  		Expect(inspect).ToNot(ExitCleanly())
   242  
   243  		run = podmanTest.Podman([]string{"run", "-dt", ALPINE})
   244  		run.WaitWithDefaultTimeout()
   245  		Expect(run).To(ExitCleanly())
   246  		clone = podmanTest.Podman([]string{"container", "clone", "-f", run.OutputToString()})
   247  		clone.WaitWithDefaultTimeout()
   248  		Expect(clone).ToNot(ExitCleanly())
   249  
   250  	})
   251  
   252  	It("podman container clone network passing", func() {
   253  		networkCreate := podmanTest.Podman([]string{"network", "create", "testing123"})
   254  		networkCreate.WaitWithDefaultTimeout()
   255  		defer podmanTest.removeNetwork("testing123")
   256  		Expect(networkCreate).To(ExitCleanly())
   257  		run := podmanTest.Podman([]string{"run", "--network", "bridge", "-dt", ALPINE})
   258  		run.WaitWithDefaultTimeout()
   259  		Expect(run).To(ExitCleanly())
   260  
   261  		connect := podmanTest.Podman([]string{"network", "connect", "testing123", run.OutputToString()})
   262  		connect.WaitWithDefaultTimeout()
   263  		Expect(connect).To(ExitCleanly())
   264  
   265  		clone := podmanTest.Podman([]string{"container", "clone", run.OutputToString()})
   266  		clone.WaitWithDefaultTimeout()
   267  		Expect(clone).To(ExitCleanly())
   268  
   269  		inspect := podmanTest.Podman([]string{"inspect", clone.OutputToString()})
   270  		inspect.WaitWithDefaultTimeout()
   271  		Expect(inspect).To(ExitCleanly())
   272  		networks := inspect.InspectContainerToJSON()[0].NetworkSettings.Networks
   273  		Expect(networks).To(HaveLen(2))
   274  		Expect(networks).To(HaveKey("testing123"))
   275  	})
   276  
   277  	It("podman container clone env test", func() {
   278  		session := podmanTest.Podman([]string{"run", "--name", "env_ctr", "-e", "ENV_TEST=123", ALPINE, "printenv", "ENV_TEST"})
   279  		session.WaitWithDefaultTimeout()
   280  		Expect(session).Should(ExitCleanly())
   281  
   282  		session = podmanTest.Podman([]string{"container", "clone", "env_ctr"})
   283  		session.WaitWithDefaultTimeout()
   284  		Expect(session).Should(ExitCleanly())
   285  
   286  		session = podmanTest.Podman([]string{"start", "-a", "env_ctr-clone"})
   287  		session.WaitWithDefaultTimeout()
   288  		Expect(session).Should(ExitCleanly())
   289  		Expect(session.OutputToString()).Should(ContainSubstring("123"))
   290  
   291  		session = podmanTest.Podman([]string{"run", "--name", "env_ctr2", "-e", "ENV_TEST=12=3", ALPINE, "printenv", "ENV_TEST"})
   292  		session.WaitWithDefaultTimeout()
   293  		Expect(session).Should(ExitCleanly())
   294  
   295  		session = podmanTest.Podman([]string{"container", "clone", "env_ctr2"})
   296  		session.WaitWithDefaultTimeout()
   297  		Expect(session).Should(ExitCleanly())
   298  
   299  		session = podmanTest.Podman([]string{"start", "-a", "env_ctr2-clone"})
   300  		session.WaitWithDefaultTimeout()
   301  		Expect(session).Should(ExitCleanly())
   302  		Expect(session.OutputToString()).Should(ContainSubstring("12=3"))
   303  
   304  	})
   305  })