diff options
author | OpenShift Merge Robot <openshift-merge-robot@users.noreply.github.com> | 2021-11-17 12:02:37 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-11-17 12:02:37 +0100 |
commit | 85733e0b4a1d246debcc453f4248cbd9bb91a9d1 (patch) | |
tree | aa775d674d2e499972066c56e6da34ec2682cdce /pkg/api/handlers/libpod | |
parent | bd6fbb190ba701ff77c084a36b05e64ba9884a78 (diff) | |
parent | 33ec8c6698473ab650df65b958e910e03e240fe6 (diff) | |
download | podman-85733e0b4a1d246debcc453f4248cbd9bb91a9d1.tar.gz podman-85733e0b4a1d246debcc453f4248cbd9bb91a9d1.tar.bz2 podman-85733e0b4a1d246debcc453f4248cbd9bb91a9d1.zip |
Merge pull request #12281 from vrothberg/fix-12007
fix remote checkpoint/restore
Diffstat (limited to 'pkg/api/handlers/libpod')
-rw-r--r-- | pkg/api/handlers/libpod/containers.go | 143 |
1 files changed, 76 insertions, 67 deletions
diff --git a/pkg/api/handlers/libpod/containers.go b/pkg/api/handlers/libpod/containers.go index 3aeebc334..b0cec2b1f 100644 --- a/pkg/api/handlers/libpod/containers.go +++ b/pkg/api/handlers/libpod/containers.go @@ -1,9 +1,11 @@ package libpod import ( + "fmt" "io/ioutil" "net/http" "os" + "strings" "github.com/containers/podman/v3/libpod" "github.com/containers/podman/v3/libpod/define" @@ -206,7 +208,9 @@ func ShowMountedContainers(w http.ResponseWriter, r *http.Request) { } func Checkpoint(w http.ResponseWriter, r *http.Request) { - var targetFile string + runtime := r.Context().Value(api.RuntimeKey).(*libpod.Runtime) + containerEngine := abi.ContainerEngine{Libpod: runtime} + decoder := r.Context().Value(api.DecoderKey).(*schema.Decoder) query := struct { Keep bool `schema:"keep"` @@ -224,66 +228,68 @@ func Checkpoint(w http.ResponseWriter, r *http.Request) { errors.Wrapf(err, "failed to parse parameters for %s", r.URL.String())) return } + name := utils.GetName(r) - runtime := r.Context().Value(api.RuntimeKey).(*libpod.Runtime) - ctr, err := runtime.LookupContainer(name) - if err != nil { + if _, err := runtime.LookupContainer(name); err != nil { utils.ContainerNotFound(w, name, err) return } + names := []string{name} + + options := entities.CheckpointOptions{ + Keep: query.Keep, + LeaveRunning: query.LeaveRunning, + TCPEstablished: query.TCPEstablished, + IgnoreRootFS: query.IgnoreRootFS, + PrintStats: query.PrintStats, + } + if query.Export { - tmpFile, err := ioutil.TempFile("", "checkpoint") + f, err := ioutil.TempFile("", "checkpoint") if err != nil { utils.InternalServerError(w, err) return } - defer os.Remove(tmpFile.Name()) - if err := tmpFile.Close(); err != nil { + defer os.Remove(f.Name()) + if err := f.Close(); err != nil { utils.InternalServerError(w, err) return } - targetFile = tmpFile.Name() - } - options := libpod.ContainerCheckpointOptions{ - Keep: query.Keep, - KeepRunning: query.LeaveRunning, - TCPEstablished: query.TCPEstablished, - IgnoreRootfs: query.IgnoreRootFS, - PrintStats: query.PrintStats, - } - if query.Export { - options.TargetFile = targetFile + options.Export = f.Name() } - criuStatistics, runtimeCheckpointDuration, err := ctr.Checkpoint(r.Context(), options) + + reports, err := containerEngine.ContainerCheckpoint(r.Context(), names, options) if err != nil { utils.InternalServerError(w, err) return } - if query.Export { - f, err := os.Open(targetFile) - if err != nil { - utils.InternalServerError(w, err) + + if !query.Export { + if len(reports) != 1 { + utils.InternalServerError(w, fmt.Errorf("expected 1 restore report but got %d", len(reports))) return } - defer f.Close() - utils.WriteResponse(w, http.StatusOK, f) + if reports[0].Err != nil { + utils.InternalServerError(w, reports[0].Err) + return + } + utils.WriteResponse(w, http.StatusOK, reports[0]) + return + } + + f, err := os.Open(options.Export) + if err != nil { + utils.InternalServerError(w, err) return } - utils.WriteResponse( - w, - http.StatusOK, - entities.CheckpointReport{ - Id: ctr.ID(), - RuntimeDuration: runtimeCheckpointDuration, - CRIUStatistics: criuStatistics, - }, - ) + defer f.Close() + utils.WriteResponse(w, http.StatusOK, f) } func Restore(w http.ResponseWriter, r *http.Request) { - var ( - targetFile string - ) + runtime := r.Context().Value(api.RuntimeKey).(*libpod.Runtime) + containerEngine := abi.ContainerEngine{Libpod: runtime} + decoder := r.Context().Value(api.DecoderKey).(*schema.Decoder) query := struct { Keep bool `schema:"keep"` @@ -295,6 +301,7 @@ func Restore(w http.ResponseWriter, r *http.Request) { IgnoreStaticIP bool `schema:"ignoreStaticIP"` IgnoreStaticMAC bool `schema:"ignoreStaticMAC"` PrintStats bool `schema:"printStats"` + PublishPorts string `schema:"publishPorts"` }{ // override any golang type defaults } @@ -303,53 +310,55 @@ func Restore(w http.ResponseWriter, r *http.Request) { errors.Wrapf(err, "failed to parse parameters for %s", r.URL.String())) return } - name := utils.GetName(r) - runtime := r.Context().Value(api.RuntimeKey).(*libpod.Runtime) - ctr, err := runtime.LookupContainer(name) - if err != nil { - utils.ContainerNotFound(w, name, err) - return + + options := entities.RestoreOptions{ + Name: query.Name, + Keep: query.Keep, + TCPEstablished: query.TCPEstablished, + IgnoreRootFS: query.IgnoreRootFS, + IgnoreVolumes: query.IgnoreVolumes, + IgnoreStaticIP: query.IgnoreStaticIP, + IgnoreStaticMAC: query.IgnoreStaticMAC, + PrintStats: query.PrintStats, + PublishPorts: strings.Fields(query.PublishPorts), } + + var names []string if query.Import { t, err := ioutil.TempFile("", "restore") if err != nil { utils.InternalServerError(w, err) return } - defer t.Close() + defer os.Remove(t.Name()) if err := compat.SaveFromBody(t, r); err != nil { utils.InternalServerError(w, err) return } - targetFile = t.Name() + options.Import = t.Name() + } else { + name := utils.GetName(r) + if _, err := runtime.LookupContainer(name); err != nil { + utils.ContainerNotFound(w, name, err) + return + } + names = []string{name} } - options := libpod.ContainerCheckpointOptions{ - Keep: query.Keep, - TCPEstablished: query.TCPEstablished, - IgnoreRootfs: query.IgnoreRootFS, - IgnoreStaticIP: query.IgnoreStaticIP, - IgnoreStaticMAC: query.IgnoreStaticMAC, - PrintStats: query.PrintStats, - } - if query.Import { - options.TargetFile = targetFile - options.Name = query.Name - } - criuStatistics, runtimeRestoreDuration, err := ctr.Restore(r.Context(), options) + reports, err := containerEngine.ContainerRestore(r.Context(), names, options) if err != nil { utils.InternalServerError(w, err) return } - utils.WriteResponse( - w, - http.StatusOK, - entities.RestoreReport{ - Id: ctr.ID(), - RuntimeDuration: runtimeRestoreDuration, - CRIUStatistics: criuStatistics, - }, - ) + if len(reports) != 1 { + utils.InternalServerError(w, fmt.Errorf("expected 1 restore report but got %d", len(reports))) + return + } + if reports[0].Err != nil { + utils.InternalServerError(w, reports[0].Err) + return + } + utils.WriteResponse(w, http.StatusOK, reports[0]) } func InitContainer(w http.ResponseWriter, r *http.Request) { |