summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--cmd/podman/containers/restore.go51
-rw-r--r--libpod/container_internal.go8
-rw-r--r--pkg/domain/infra/abi/manifest.go3
-rw-r--r--pkg/domain/infra/tunnel/manifest.go10
-rw-r--r--test/e2e/checkpoint_test.go20
-rw-r--r--test/e2e/manifest_test.go44
6 files changed, 108 insertions, 28 deletions
diff --git a/cmd/podman/containers/restore.go b/cmd/podman/containers/restore.go
index 1e4745354..6106f2bed 100644
--- a/cmd/podman/containers/restore.go
+++ b/cmd/podman/containers/restore.go
@@ -93,32 +93,49 @@ func init() {
}
func restore(cmd *cobra.Command, args []string) error {
- var errs utils.OutputErrors
+ var (
+ e error
+ errs utils.OutputErrors
+ )
podmanStart := time.Now()
if rootless.IsRootless() {
return fmt.Errorf("restoring a container requires root")
}
- // Find out if this is an image
- inspectOpts := entities.InspectOptions{}
- imgData, _, err := registry.ImageEngine().Inspect(context.Background(), args, inspectOpts)
- if err != nil {
- return err
+ // Check if the container exists (#15055)
+ exists := &entities.BoolReport{Value: false}
+ for _, ctr := range args {
+ exists, e = registry.ContainerEngine().ContainerExists(registry.GetContext(), ctr, entities.ContainerExistsOptions{})
+ if e != nil {
+ return e
+ }
+ if exists.Value {
+ break
+ }
}
- hostInfo, err := registry.ContainerEngine().Info(context.Background())
- if err != nil {
- return err
- }
+ if !exists.Value {
+ // Find out if this is an image
+ inspectOpts := entities.InspectOptions{}
+ imgData, _, err := registry.ImageEngine().Inspect(context.Background(), args, inspectOpts)
+ if err != nil {
+ return err
+ }
- for i := range imgData {
- restoreOptions.CheckpointImage = true
- checkpointRuntimeName, found := imgData[i].Annotations[define.CheckpointAnnotationRuntimeName]
- if !found {
- return fmt.Errorf("image is not a checkpoint: %s", imgData[i].ID)
+ hostInfo, err := registry.ContainerEngine().Info(context.Background())
+ if err != nil {
+ return err
}
- if hostInfo.Host.OCIRuntime.Name != checkpointRuntimeName {
- return fmt.Errorf("container image \"%s\" requires runtime: \"%s\"", imgData[i].ID, checkpointRuntimeName)
+
+ for i := range imgData {
+ restoreOptions.CheckpointImage = true
+ checkpointRuntimeName, found := imgData[i].Annotations[define.CheckpointAnnotationRuntimeName]
+ if !found {
+ return fmt.Errorf("image is not a checkpoint: %s", imgData[i].ID)
+ }
+ if hostInfo.Host.OCIRuntime.Name != checkpointRuntimeName {
+ return fmt.Errorf("container image \"%s\" requires runtime: \"%s\"", imgData[i].ID, checkpointRuntimeName)
+ }
}
}
diff --git a/libpod/container_internal.go b/libpod/container_internal.go
index 7e330430c..bad68991b 100644
--- a/libpod/container_internal.go
+++ b/libpod/container_internal.go
@@ -347,7 +347,7 @@ func (c *Container) syncContainer() error {
}
// If runtime knows about the container, update its status in runtime
// And then save back to disk
- if c.ensureState(define.ContainerStateCreated, define.ContainerStateRunning, define.ContainerStateStopped, define.ContainerStatePaused) {
+ if c.ensureState(define.ContainerStateCreated, define.ContainerStateRunning, define.ContainerStateStopped, define.ContainerStateStopping, define.ContainerStatePaused) {
oldState := c.state.State
if err := c.checkExitFile(); err != nil {
@@ -1316,10 +1316,10 @@ func (c *Container) stop(timeout uint) error {
// Since we're now subject to a race condition with other processes who
// may have altered the state (and other data), let's check if the
- // state has changed. If so, we should return immediately and log a
- // warning.
+ // state has changed. If so, we should return immediately and leave
+ // breadcrumbs for debugging if needed.
if c.state.State != define.ContainerStateStopping {
- logrus.Warnf(
+ logrus.Debugf(
"Container %q state changed from %q to %q while waiting for it to be stopped: discontinuing stop procedure as another process interfered",
c.ID(), define.ContainerStateStopping, c.state.State,
)
diff --git a/pkg/domain/infra/abi/manifest.go b/pkg/domain/infra/abi/manifest.go
index d20744d76..bdc3d9513 100644
--- a/pkg/domain/infra/abi/manifest.go
+++ b/pkg/domain/infra/abi/manifest.go
@@ -331,7 +331,8 @@ func (ir *ImageEngine) ManifestPush(ctx context.Context, name, destination strin
}
if opts.Rm {
- if _, rmErrors := ir.Libpod.LibimageRuntime().RemoveImages(ctx, []string{manifestList.ID()}, nil); len(rmErrors) > 0 {
+ rmOpts := &libimage.RemoveImagesOptions{LookupManifest: true}
+ if _, rmErrors := ir.Libpod.LibimageRuntime().RemoveImages(ctx, []string{manifestList.ID()}, rmOpts); len(rmErrors) > 0 {
return "", fmt.Errorf("error removing manifest after push: %w", rmErrors[0])
}
}
diff --git a/pkg/domain/infra/tunnel/manifest.go b/pkg/domain/infra/tunnel/manifest.go
index d2554f198..4a3148fac 100644
--- a/pkg/domain/infra/tunnel/manifest.go
+++ b/pkg/domain/infra/tunnel/manifest.go
@@ -110,5 +110,15 @@ func (ir *ImageEngine) ManifestPush(ctx context.Context, name, destination strin
}
}
digest, err := manifests.Push(ir.ClientCtx, name, destination, options)
+ if err != nil {
+ return "", fmt.Errorf("error adding to manifest list %s: %w", name, err)
+ }
+
+ if opts.Rm {
+ if _, rmErrors := ir.Remove(ctx, []string{name}, entities.ImageRemoveOptions{LookupManifest: true}); len(rmErrors) > 0 {
+ return "", fmt.Errorf("error removing manifest after push: %w", rmErrors[0])
+ }
+ }
+
return digest, err
}
diff --git a/test/e2e/checkpoint_test.go b/test/e2e/checkpoint_test.go
index d1771f336..8f5e1a0b6 100644
--- a/test/e2e/checkpoint_test.go
+++ b/test/e2e/checkpoint_test.go
@@ -223,6 +223,26 @@ var _ = Describe("Podman checkpoint", func() {
Expect(result).Should(Exit(0))
Expect(podmanTest.NumberOfContainersRunning()).To(Equal(1))
Expect(podmanTest.GetContainerStatus()).To(ContainSubstring("Up"))
+
+ // Restore a container which name is equal to a image name (#15055)
+ localRunString = getRunString([]string{"--name", "alpine", "quay.io/libpod/alpine:latest", "top"})
+ session = podmanTest.Podman(localRunString)
+ session.WaitWithDefaultTimeout()
+ Expect(session).Should(Exit(0))
+
+ result = podmanTest.Podman([]string{"container", "checkpoint", "alpine"})
+ result.WaitWithDefaultTimeout()
+
+ Expect(result).Should(Exit(0))
+ Expect(podmanTest.NumberOfContainersRunning()).To(Equal(1))
+ Expect(podmanTest.GetContainerStatus()).To(ContainSubstring("Exited"))
+
+ result = podmanTest.Podman([]string{"container", "restore", "alpine"})
+ result.WaitWithDefaultTimeout()
+
+ Expect(result).Should(Exit(0))
+ Expect(podmanTest.NumberOfContainersRunning()).To(Equal(2))
+ Expect(podmanTest.GetContainerStatus()).To(ContainSubstring("Up"))
})
It("podman pause a checkpointed container by id", func() {
diff --git a/test/e2e/manifest_test.go b/test/e2e/manifest_test.go
index 1f58419a1..a7fcd1559 100644
--- a/test/e2e/manifest_test.go
+++ b/test/e2e/manifest_test.go
@@ -339,6 +339,16 @@ var _ = Describe("Podman manifest", func() {
push = podmanTest.Podman([]string{"manifest", "push", "--tls-verify=false", "--creds=podmantest:wrongpasswd", "foo", "localhost:" + registry.Port + "/credstest"})
push.WaitWithDefaultTimeout()
Expect(push).To(ExitWithError())
+
+ // push --rm after pull image (#15033)
+ push = podmanTest.Podman([]string{"manifest", "push", "--rm", "--tls-verify=false", "--creds=" + registry.User + ":" + registry.Password, "foo", "localhost:" + registry.Port + "/rmtest"})
+ push.WaitWithDefaultTimeout()
+ Expect(push).Should(Exit(0))
+
+ session = podmanTest.Podman([]string{"images", "-q", "foo"})
+ session.WaitWithDefaultTimeout()
+ Expect(session).Should(Exit(0))
+ Expect(podmanTest.NumberOfContainersRunning()).To(Equal(0))
})
It("push with error", func() {
@@ -348,8 +358,8 @@ var _ = Describe("Podman manifest", func() {
Expect(session.ErrorToString()).NotTo(BeEmpty())
})
- It("push --rm", func() {
- SkipIfRemote("remote does not support --rm")
+ It("push --rm to local directory", func() {
+ SkipIfRemote("manifest push to dir not supported in remote mode")
session := podmanTest.Podman([]string{"manifest", "create", "foo"})
session.WaitWithDefaultTimeout()
Expect(session).Should(Exit(0))
@@ -365,13 +375,35 @@ var _ = Describe("Podman manifest", func() {
session = podmanTest.Podman([]string{"manifest", "push", "--purge", "foo", "dir:" + dest})
session.WaitWithDefaultTimeout()
Expect(session).Should(Exit(0))
- session = podmanTest.Podman([]string{"manifest", "inspect", "foo"})
+ session = podmanTest.Podman([]string{"images", "-q", "foo"})
session.WaitWithDefaultTimeout()
- Expect(session).To(ExitWithError())
+ Expect(session).Should(Exit(0))
+ Expect(podmanTest.NumberOfContainersRunning()).To(Equal(0))
- session = podmanTest.Podman([]string{"manifest", "rm", "foo1", "foo2"})
+ // push --rm after pull image (#15033)
+ session = podmanTest.Podman([]string{"pull", "quay.io/libpod/testdigest_v2s2"})
session.WaitWithDefaultTimeout()
- Expect(session).To(ExitWithError())
+ Expect(session).Should(Exit(0))
+
+ session = podmanTest.Podman([]string{"manifest", "create", "bar"})
+ session.WaitWithDefaultTimeout()
+ Expect(session).Should(Exit(0))
+ session = podmanTest.Podman([]string{"manifest", "add", "bar", "quay.io/libpod/testdigest_v2s2"})
+ session.WaitWithDefaultTimeout()
+ Expect(session).Should(Exit(0))
+ session = podmanTest.Podman([]string{"manifest", "push", "--rm", "bar", "dir:" + dest})
+ session.WaitWithDefaultTimeout()
+ Expect(session).Should(Exit(0))
+ session = podmanTest.Podman([]string{"images", "-q", "bar"})
+ session.WaitWithDefaultTimeout()
+ Expect(session).Should(Exit(0))
+ Expect(podmanTest.NumberOfContainersRunning()).To(Equal(0))
+
+ session = podmanTest.Podman([]string{"manifest", "rm", "foo", "bar"})
+ session.WaitWithDefaultTimeout()
+ Expect(session).Should(ExitWithError())
+ Expect(session.ErrorToString()).To(ContainSubstring("foo: image not known"))
+ Expect(session.ErrorToString()).To(ContainSubstring("bar: image not known"))
})
It("exists", func() {