From 9c3d8bb494f358ecff785ba81a58f2e05f1a98a1 Mon Sep 17 00:00:00 2001 From: Radostin Stoyanov Date: Sat, 27 Aug 2022 15:38:34 +0200 Subject: cmd/podman: add support for checkpoint images This patch extends the podman run command with support for checkpoint images. When `podman run` is invoked with an image that contains a checkpoint, it would restore the container from that checkpoint. Example: podman run -d --name looper busybox /bin/sh -c \ 'i=0; while true; do echo $i; i=$(expr $i + 1); sleep 1; done' podman container checkpoint --create-image checkpoint-image-1 looper podman run checkpoint-image-1 Signed-off-by: Radostin Stoyanov --- cmd/podman/containers/restore.go | 14 +++++++------- cmd/podman/containers/run.go | 29 +++++++++++++++++++++++++++++ 2 files changed, 36 insertions(+), 7 deletions(-) diff --git a/cmd/podman/containers/restore.go b/cmd/podman/containers/restore.go index d094ac246..144925a54 100644 --- a/cmd/podman/containers/restore.go +++ b/cmd/podman/containers/restore.go @@ -93,7 +93,7 @@ func init() { func restore(cmd *cobra.Command, args []string) error { var ( - e error + err error errs utils.OutputErrors ) podmanStart := time.Now() @@ -104,9 +104,9 @@ func restore(cmd *cobra.Command, args []string) error { // 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 + exists, err = registry.ContainerEngine().ContainerExists(registry.GetContext(), ctr, entities.ContainerExistsOptions{}) + if err != nil { + return err } if exists.Value { break @@ -115,9 +115,9 @@ func restore(cmd *cobra.Command, args []string) error { if !exists.Value { // Find out if this is an image - restoreOptions.CheckpointImage, e = utils.IsCheckpointImage(context.Background(), args) - if e != nil { - return e + restoreOptions.CheckpointImage, err = utils.IsCheckpointImage(context.Background(), args) + if err != nil { + return err } } diff --git a/cmd/podman/containers/run.go b/cmd/podman/containers/run.go index f66d4d4d3..d8d020c63 100644 --- a/cmd/podman/containers/run.go +++ b/cmd/podman/containers/run.go @@ -148,6 +148,35 @@ func run(cmd *cobra.Command, args []string) error { imageName = name } + // If this is a checkpoint image, invoke container restore. + // We do not return `err` when checkpointImage is false, because the value + // of `err` could be "image is not a checkpoint". In this case, the run + // command should continue as usual, preserving backwards compatibility. + checkpointImage, err := utils.IsCheckpointImage(registry.GetContext(), []string{imageName}) + if checkpointImage { + if err != nil { + return err + } + var restoreOptions entities.RestoreOptions + responses, err := registry.ContainerEngine().ContainerRestore(registry.GetContext(), []string{imageName}, restoreOptions) + if err != nil { + return err + } + + var errs utils.OutputErrors + for _, r := range responses { + switch { + case r.Err != nil: + errs = append(errs, r.Err) + case r.RawInput != "": + fmt.Println(r.RawInput) + default: + fmt.Println(r.Id) + } + } + return errs.PrintErrors() + } + if cliVals.Replace { if err := replaceContainer(cliVals.Name); err != nil { return err -- cgit v1.2.3-54-g00ecf