container: allow clone to an existing pod

Closes: https://github.com/containers/podman/issues/3979

Signed-off-by: Giuseppe Scrivano <gscrivan@redhat.com>
This commit is contained in:
Giuseppe Scrivano 2022-03-22 11:04:46 +01:00
parent 809f82bdbd
commit b469bf5c05
No known key found for this signature in database
GPG key ID: 67E38F7A8BA21772
4 changed files with 80 additions and 8 deletions

View file

@ -394,14 +394,6 @@ func DefineCreateFlags(cmd *cobra.Command, cf *entities.ContainerCreateOptions,
)
_ = cmd.RegisterFlagCompletionFunc(platformFlagName, completion.AutocompleteNone)
podFlagName := "pod"
createFlags.StringVar(
&cf.Pod,
podFlagName, "",
"Run container in an existing pod",
)
_ = cmd.RegisterFlagCompletionFunc(podFlagName, AutocompletePods)
podIDFileFlagName := "pod-id-file"
createFlags.StringVar(
&cf.PodIDFile,
@ -837,6 +829,14 @@ func DefineCreateFlags(cmd *cobra.Command, cf *entities.ContainerCreateOptions,
)
_ = cmd.RegisterFlagCompletionFunc(nameFlagName, completion.AutocompleteNone)
podFlagName := "pod"
createFlags.StringVar(
&cf.Pod,
podFlagName, "",
"Run container in an existing pod",
)
_ = cmd.RegisterFlagCompletionFunc(podFlagName, AutocompletePods)
cpuPeriodFlagName := "cpu-period"
createFlags.Uint64Var(
&cf.CPUPeriod,

View file

@ -141,6 +141,12 @@ If no memory limits are specified, the original container's will be used.
Set a custom name for the cloned container. The default if not specified is of the syntax: **<ORIGINAL_NAME>-clone**
#### **--pod**=*name*
Clone the container in an existing pod. It is helpful to move a container to an
existing pod. The container will join the pod shared namespaces, losing its configuration
that conflicts with the shared namespaces.
#### **--run**
When set to true, this flag runs the newly created container after the

View file

@ -1496,6 +1496,35 @@ func (ic *ContainerEngine) ContainerClone(ctx context.Context, ctrCloneOpts enti
return nil, err
}
if ctrCloneOpts.CreateOpts.Pod != "" {
pod, err := ic.Libpod.LookupPod(ctrCloneOpts.CreateOpts.Pod)
if err != nil {
return nil, err
}
allNamespaces := []struct {
isShared bool
value *specgen.Namespace
}{
{pod.SharesPID(), &spec.PidNS},
{pod.SharesNet(), &spec.NetNS},
{pod.SharesCgroup(), &spec.CgroupNS},
{pod.SharesIPC(), &spec.IpcNS},
{pod.SharesUTS(), &spec.UtsNS},
}
printWarning := false
for _, n := range allNamespaces {
if n.isShared && !n.value.IsDefault() {
*n.value = specgen.Namespace{NSMode: specgen.Default}
printWarning = true
}
}
if printWarning {
logrus.Warning("At least one namespace was reset to the default configuration")
}
}
err = specgenutil.FillOutSpecGen(spec, &ctrCloneOpts.CreateOpts, []string{})
if err != nil {
return nil, err

View file

@ -184,4 +184,41 @@ var _ = Describe("Podman container clone", func() {
Expect(ctrInspect.InspectContainerToJSON()[0].HostConfig.NetworkMode).Should(Equal(runInspect.InspectContainerToJSON()[0].HostConfig.NetworkMode))
})
It("podman container clone to a pod", func() {
createPod := podmanTest.Podman([]string{"pod", "create", "--share", "uts", "--name", "foo-pod"})
createPod.WaitWithDefaultTimeout()
Expect(createPod).To(Exit(0))
ctr := podmanTest.RunTopContainer("ctr")
ctr.WaitWithDefaultTimeout()
Expect(ctr).Should(Exit(0))
clone := podmanTest.Podman([]string{"container", "clone", "--name", "cloned", "--pod", "foo-pod", "ctr"})
clone.WaitWithDefaultTimeout()
Expect(clone).To(Exit(0))
ctrInspect := podmanTest.Podman([]string{"inspect", "cloned"})
ctrInspect.WaitWithDefaultTimeout()
Expect(ctrInspect).Should(Exit(0))
Expect(ctrInspect.InspectContainerToJSON()[0].Pod).Should(Equal(createPod.OutputToString()))
Expect(ctrInspect.InspectContainerToJSON()[0].HostConfig.NetworkMode).Should(Not(ContainSubstring("container:")))
createPod = podmanTest.Podman([]string{"pod", "create", "--share", "uts,net", "--name", "bar-pod"})
createPod.WaitWithDefaultTimeout()
Expect(createPod).To(Exit(0))
clone = podmanTest.Podman([]string{"container", "clone", "--name", "cloned2", "--pod", "bar-pod", "ctr"})
clone.WaitWithDefaultTimeout()
Expect(clone).To(Exit(0))
ctrInspect = podmanTest.Podman([]string{"inspect", "cloned2"})
ctrInspect.WaitWithDefaultTimeout()
Expect(ctrInspect).Should(Exit(0))
Expect(ctrInspect.InspectContainerToJSON()[0].Pod).Should(Equal(createPod.OutputToString()))
Expect(ctrInspect.InspectContainerToJSON()[0].HostConfig.NetworkMode).Should(ContainSubstring("container:"))
})
})