diff options
author | openshift-ci[bot] <75433959+openshift-ci[bot]@users.noreply.github.com> | 2022-06-16 20:05:27 +0000 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-06-16 20:05:27 +0000 |
commit | 2af8851787d2c34d6264945372deaec4c387882a (patch) | |
tree | 29d25cc8cd50f804a36fa9f3d98032d5333757fb /pkg/domain/infra/abi | |
parent | 5cba4dc2e490b5c652ba0821067b63d7b2e4cf8f (diff) | |
parent | 958759a71955860b01b17bd3bebf38f9dae1018e (diff) | |
download | podman-2af8851787d2c34d6264945372deaec4c387882a.tar.gz podman-2af8851787d2c34d6264945372deaec4c387882a.tar.bz2 podman-2af8851787d2c34d6264945372deaec4c387882a.zip |
Merge pull request #14299 from cdoern/podClone
implement podman pod clone
Diffstat (limited to 'pkg/domain/infra/abi')
-rw-r--r-- | pkg/domain/infra/abi/containers.go | 9 | ||||
-rw-r--r-- | pkg/domain/infra/abi/pods.go | 85 |
2 files changed, 92 insertions, 2 deletions
diff --git a/pkg/domain/infra/abi/containers.go b/pkg/domain/infra/abi/containers.go index 8bd84a310..c7cd0cb56 100644 --- a/pkg/domain/infra/abi/containers.go +++ b/pkg/domain/infra/abi/containers.go @@ -1593,6 +1593,11 @@ func (ic *ContainerEngine) ContainerClone(ctx context.Context, ctrCloneOpts enti return nil, err } + conf := c.Config() + if conf.Spec != nil && conf.Spec.Process != nil && conf.Spec.Process.Terminal { // if we do not pass term, running ctrs exit + spec.Terminal = true + } + // Print warnings if len(out) > 0 { for _, w := range out { @@ -1612,8 +1617,8 @@ func (ic *ContainerEngine) ContainerClone(ctx context.Context, ctrCloneOpts enti switch { case strings.Contains(n, "-clone"): ind := strings.Index(n, "-clone") + 6 - num, _ := strconv.Atoi(n[ind:]) - if num == 0 { // clone1 is hard to get with this logic, just check for it here. + num, err := strconv.Atoi(n[ind:]) + if num == 0 && err != nil { // clone1 is hard to get with this logic, just check for it here. _, err = ic.Libpod.LookupContainer(n + "1") if err != nil { spec.Name = n + "1" diff --git a/pkg/domain/infra/abi/pods.go b/pkg/domain/infra/abi/pods.go index 32deb20e0..8638f4783 100644 --- a/pkg/domain/infra/abi/pods.go +++ b/pkg/domain/infra/abi/pods.go @@ -2,12 +2,15 @@ package abi import ( "context" + "strconv" + "strings" "github.com/containers/podman/v4/libpod" "github.com/containers/podman/v4/libpod/define" "github.com/containers/podman/v4/pkg/domain/entities" dfilters "github.com/containers/podman/v4/pkg/domain/filters" "github.com/containers/podman/v4/pkg/signal" + "github.com/containers/podman/v4/pkg/specgen" "github.com/containers/podman/v4/pkg/specgen/generate" "github.com/pkg/errors" "github.com/sirupsen/logrus" @@ -295,6 +298,88 @@ func (ic *ContainerEngine) PodCreate(ctx context.Context, specg entities.PodSpec return &entities.PodCreateReport{Id: pod.ID()}, nil } +func (ic *ContainerEngine) PodClone(ctx context.Context, podClone entities.PodCloneOptions) (*entities.PodCloneReport, error) { + spec := specgen.NewPodSpecGenerator() + p, err := generate.PodConfigToSpec(ic.Libpod, spec, &podClone.InfraOptions, podClone.ID) + if err != nil { + return nil, err + } + + if len(podClone.CreateOpts.Name) > 0 { + spec.Name = podClone.CreateOpts.Name + } else { + n := p.Name() + _, err := ic.Libpod.LookupPod(n + "-clone") + if err == nil { + n += "-clone" + } + switch { + case strings.Contains(n, "-clone"): // meaning this name is taken! + ind := strings.Index(n, "-clone") + 6 + num, err := strconv.Atoi(n[ind:]) + if num == 0 && err != nil { // meaning invalid + _, err = ic.Libpod.LookupPod(n + "1") + if err != nil { + spec.Name = n + "1" + break + } + } else { // else we already have a number + n = n[0:ind] + } + err = nil + count := num + for err == nil { // until we cannot find a pod w/ this name, increment num and try again + count++ + tempN := n + strconv.Itoa(count) + _, err = ic.Libpod.LookupPod(tempN) + } + n += strconv.Itoa(count) + spec.Name = n + default: + spec.Name = p.Name() + "-clone" + } + } + + podSpec := entities.PodSpec{PodSpecGen: *spec} + pod, err := generate.MakePod(&podSpec, ic.Libpod) + if err != nil { + return nil, err + } + + ctrs, err := p.AllContainers() + if err != nil { + return nil, err + } + for _, ctr := range ctrs { + if ctr.IsInfra() { + continue // already copied infra + } + + podClone.PerContainerOptions.Pod = pod.ID() + _, err := ic.ContainerClone(ctx, entities.ContainerCloneOptions{ID: ctr.ID(), CreateOpts: podClone.PerContainerOptions}) + if err != nil { + return nil, err + } + } + + if podClone.Destroy { + var timeout *uint + err = ic.Libpod.RemovePod(ctx, p, true, true, timeout) + if err != nil { + return &entities.PodCloneReport{Id: pod.ID()}, err + } + } + + if podClone.Start { + _, err := ic.PodStart(ctx, []string{pod.ID()}, entities.PodStartOptions{}) + if err != nil { + return &entities.PodCloneReport{Id: pod.ID()}, err + } + } + + return &entities.PodCloneReport{Id: pod.ID()}, nil +} + func (ic *ContainerEngine) PodTop(ctx context.Context, options entities.PodTopOptions) (*entities.StringSliceReport, error) { var ( pod *libpod.Pod |