diff options
author | cdoern <cdoern@redhat.com> | 2022-01-14 13:49:34 -0500 |
---|---|---|
committer | cdoern <cdoern@redhat.com> | 2022-02-20 21:11:14 -0500 |
commit | 94df7015121759ce69f35f7e7735aa2e4a2dc71a (patch) | |
tree | 154e04dc3073acc57cecedfc703e6c1c4daf4bf1 /test | |
parent | f918a9418f5eeb00b289c127142953da2c394867 (diff) | |
download | podman-94df7015121759ce69f35f7e7735aa2e4a2dc71a.tar.gz podman-94df7015121759ce69f35f7e7735aa2e4a2dc71a.tar.bz2 podman-94df7015121759ce69f35f7e7735aa2e4a2dc71a.zip |
Implement Podman Container Clone
podman container clone takes the id of an existing continer and creates a specgen from the given container's config
recreating all proper namespaces and overriding spec options like resource limits and the container name if given in the cli options
this command utilizes the common function DefineCreateFlags meaning that we can funnel as many create options as we want
into clone over time allowing the user to clone with as much or as little of the original config as they want.
container clone takes a second argument which is a new name and a third argument which is an image name to use instead of the original container's
the current supported flags are:
--destroy (remove the original container)
--name (new ctr name)
--cpus (sets cpu period and quota)
--cpuset-cpus
--cpu-period
--cpu-rt-period
--cpu-rt-runtime
--cpu-shares
--cpuset-mems
--memory
--run
resolves #10875
Signed-off-by: cdoern <cdoern@redhat.com>
Signed-off-by: cdoern <cbdoer23@g.holycross.edu>
Signed-off-by: cdoern <cdoern@redhat.com>
Diffstat (limited to 'test')
-rw-r--r-- | test/e2e/container_clone_test.go | 187 |
1 files changed, 187 insertions, 0 deletions
diff --git a/test/e2e/container_clone_test.go b/test/e2e/container_clone_test.go new file mode 100644 index 000000000..bebc6872b --- /dev/null +++ b/test/e2e/container_clone_test.go @@ -0,0 +1,187 @@ +package integration + +import ( + "os" + + . "github.com/containers/podman/v4/test/utils" + . "github.com/onsi/ginkgo" + . "github.com/onsi/gomega" + . "github.com/onsi/gomega/gexec" +) + +var _ = Describe("Podman container clone", func() { + var ( + tempdir string + err error + podmanTest *PodmanTestIntegration + ) + + BeforeEach(func() { + SkipIfRemote("podman container clone is not supported in remote") + tempdir, err = CreateTempDirInTempDir() + if err != nil { + os.Exit(1) + } + podmanTest = PodmanTestCreate(tempdir) + podmanTest.Setup() + podmanTest.SeedImages() + }) + + AfterEach(func() { + podmanTest.Cleanup() + f := CurrentGinkgoTestDescription() + processTestResult(f) + + }) + + It("podman container clone basic test", func() { + SkipIfRootlessCgroupsV1("starting a container with the memory limits not supported") + create := podmanTest.Podman([]string{"create", ALPINE}) + create.WaitWithDefaultTimeout() + Expect(create).To(Exit(0)) + clone := podmanTest.Podman([]string{"container", "clone", create.OutputToString()}) + clone.WaitWithDefaultTimeout() + Expect(clone).To(Exit(0)) + + clone = podmanTest.Podman([]string{"container", "clone", clone.OutputToString()}) + clone.WaitWithDefaultTimeout() + Expect(clone).To(Exit(0)) + + ctrInspect := podmanTest.Podman([]string{"inspect", clone.OutputToString()}) + ctrInspect.WaitWithDefaultTimeout() + Expect(ctrInspect).To(Exit(0)) + Expect(ctrInspect.InspectContainerToJSON()[0].Name).To(ContainSubstring("-clone1")) + + ctrStart := podmanTest.Podman([]string{"container", "start", clone.OutputToString()}) + ctrStart.WaitWithDefaultTimeout() + Expect(ctrStart).To(Exit(0)) + }) + + It("podman container clone image test", func() { + create := podmanTest.Podman([]string{"create", ALPINE}) + create.WaitWithDefaultTimeout() + Expect(create).To(Exit(0)) + clone := podmanTest.Podman([]string{"container", "clone", create.OutputToString(), "new_name", fedoraMinimal}) + clone.WaitWithDefaultTimeout() + Expect(clone).To(Exit(0)) + + ctrInspect := podmanTest.Podman([]string{"inspect", clone.OutputToString()}) + ctrInspect.WaitWithDefaultTimeout() + Expect(ctrInspect).To(Exit(0)) + Expect(ctrInspect.InspectContainerToJSON()[0].ImageName).To(Equal(fedoraMinimal)) + Expect(ctrInspect.InspectContainerToJSON()[0].Name).To(Equal("new_name")) + }) + + It("podman container clone name test", func() { + create := podmanTest.Podman([]string{"create", ALPINE}) + create.WaitWithDefaultTimeout() + Expect(create).To(Exit(0)) + clone := podmanTest.Podman([]string{"container", "clone", "--name", "testing123", create.OutputToString()}) + clone.WaitWithDefaultTimeout() + Expect(clone).To(Exit(0)) + + cloneInspect := podmanTest.Podman([]string{"inspect", clone.OutputToString()}) + cloneInspect.WaitWithDefaultTimeout() + Expect(cloneInspect).To(Exit(0)) + cloneData := cloneInspect.InspectContainerToJSON() + Expect(cloneData[0].Name).To(Equal("testing123")) + }) + + It("podman container clone resource limits override", func() { + create := podmanTest.Podman([]string{"create", "--cpus=5", ALPINE}) + create.WaitWithDefaultTimeout() + Expect(create).To(Exit(0)) + clone := podmanTest.Podman([]string{"container", "clone", create.OutputToString()}) + clone.WaitWithDefaultTimeout() + Expect(clone).To(Exit(0)) + + createInspect := podmanTest.Podman([]string{"inspect", create.OutputToString()}) + createInspect.WaitWithDefaultTimeout() + Expect(createInspect).To(Exit(0)) + createData := createInspect.InspectContainerToJSON() + + cloneInspect := podmanTest.Podman([]string{"inspect", clone.OutputToString()}) + cloneInspect.WaitWithDefaultTimeout() + Expect(cloneInspect).To(Exit(0)) + cloneData := cloneInspect.InspectContainerToJSON() + Expect(createData[0].HostConfig.NanoCpus).To(Equal(cloneData[0].HostConfig.NanoCpus)) + + create = podmanTest.Podman([]string{"create", "--memory=5", ALPINE}) + create.WaitWithDefaultTimeout() + Expect(create).To(Exit(0)) + clone = podmanTest.Podman([]string{"container", "clone", "--cpus=6", create.OutputToString()}) + clone.WaitWithDefaultTimeout() + Expect(clone).To(Exit(0)) + + createInspect = podmanTest.Podman([]string{"inspect", create.OutputToString()}) + createInspect.WaitWithDefaultTimeout() + Expect(createInspect).To(Exit(0)) + createData = createInspect.InspectContainerToJSON() + + cloneInspect = podmanTest.Podman([]string{"inspect", clone.OutputToString()}) + cloneInspect.WaitWithDefaultTimeout() + Expect(cloneInspect).To(Exit(0)) + cloneData = cloneInspect.InspectContainerToJSON() + Expect(createData[0].HostConfig.MemorySwap).To(Equal(cloneData[0].HostConfig.MemorySwap)) + + create = podmanTest.Podman([]string{"create", "--cpus=5", ALPINE}) + create.WaitWithDefaultTimeout() + Expect(create).To(Exit(0)) + clone = podmanTest.Podman([]string{"container", "clone", "--cpus=4", create.OutputToString()}) + clone.WaitWithDefaultTimeout() + Expect(clone).To(Exit(0)) + + var nanoCPUs int64 + numCpus := 4 + nanoCPUs = int64(numCpus * 1000000000) + + createInspect = podmanTest.Podman([]string{"inspect", create.OutputToString()}) + createInspect.WaitWithDefaultTimeout() + Expect(createInspect).To(Exit(0)) + createData = createInspect.InspectContainerToJSON() + + cloneInspect = podmanTest.Podman([]string{"inspect", clone.OutputToString()}) + cloneInspect.WaitWithDefaultTimeout() + Expect(cloneInspect).To(Exit(0)) + cloneData = cloneInspect.InspectContainerToJSON() + Expect(createData[0].HostConfig.NanoCpus).ToNot(Equal(cloneData[0].HostConfig.NanoCpus)) + Expect(cloneData[0].HostConfig.NanoCpus).To(Equal(nanoCPUs)) + }) + + It("podman container clone in a pod", func() { + SkipIfRootlessCgroupsV1("starting a container with the memory limits not supported") + run := podmanTest.Podman([]string{"run", "-dt", "--pod", "new:1234", ALPINE, "sleep", "20"}) + run.WaitWithDefaultTimeout() + Expect(run).To(Exit(0)) + clone := podmanTest.Podman([]string{"container", "clone", run.OutputToString()}) + clone.WaitWithDefaultTimeout() + Expect(clone).To(Exit(0)) + ctrStart := podmanTest.Podman([]string{"container", "start", clone.OutputToString()}) + ctrStart.WaitWithDefaultTimeout() + Expect(ctrStart).To(Exit(0)) + + checkClone := podmanTest.Podman([]string{"ps", "-f", "id=" + clone.OutputToString(), "--ns", "--format", "{{.Namespaces.IPC}} {{.Namespaces.UTS}} {{.Namespaces.NET}}"}) + checkClone.WaitWithDefaultTimeout() + Expect(checkClone).Should(Exit(0)) + cloneArray := checkClone.OutputToStringArray() + + checkCreate := podmanTest.Podman([]string{"ps", "-f", "id=" + run.OutputToString(), "--ns", "--format", "{{.Namespaces.IPC}} {{.Namespaces.UTS}} {{.Namespaces.NET}}"}) + checkCreate.WaitWithDefaultTimeout() + Expect(checkCreate).Should(Exit(0)) + createArray := checkCreate.OutputToStringArray() + + Expect(cloneArray).To(ContainElements(createArray[:])) + + ctrInspect := podmanTest.Podman([]string{"inspect", clone.OutputToString()}) + ctrInspect.WaitWithDefaultTimeout() + Expect(ctrInspect).Should(Exit(0)) + + runInspect := podmanTest.Podman([]string{"inspect", run.OutputToString()}) + runInspect.WaitWithDefaultTimeout() + Expect(runInspect).Should(Exit(0)) + + Expect(ctrInspect.InspectContainerToJSON()[0].Pod).Should(Equal(runInspect.InspectContainerToJSON()[0].Pod)) + Expect(ctrInspect.InspectContainerToJSON()[0].HostConfig.NetworkMode).Should(Equal(runInspect.InspectContainerToJSON()[0].HostConfig.NetworkMode)) + }) + +}) |