Merge pull request #13587 from giuseppe/clone-to-pod

container: allow clone to an existing pod
This commit is contained in:
OpenShift Merge Robot 2022-03-24 18:09:43 +01:00 committed by GitHub
commit caaaf07c1e
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 82 additions and 10 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

@ -338,8 +338,8 @@ func FinishThrottleDevices(s *specgen.SpecGenerator) error {
}
// ConfigToSpec takes a completed container config and converts it back into a specgenerator for purposes of cloning an exisiting container
func ConfigToSpec(rt *libpod.Runtime, specg *specgen.SpecGenerator, contaierID string) (*libpod.Container, error) {
c, err := rt.LookupContainer(contaierID)
func ConfigToSpec(rt *libpod.Runtime, specg *specgen.SpecGenerator, containerID string) (*libpod.Container, error) {
c, err := rt.LookupContainer(containerID)
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:"))
})
})