summaryrefslogtreecommitdiff
path: root/pkg/adapter/checkpoint_restore.go
diff options
context:
space:
mode:
authorBrent Baude <bbaude@redhat.com>2020-03-27 08:20:13 -0500
committerBrent Baude <bbaude@redhat.com>2020-04-03 09:32:06 -0500
commit8a16674722ab4a33ce66e57d151b09ac348e8e6d (patch)
tree03505f230a58e656e8b85c44b2505696e16c50c2 /pkg/adapter/checkpoint_restore.go
parentccb9e579c48141f70d016adfa9a9d4934bbdf976 (diff)
downloadpodman-8a16674722ab4a33ce66e57d151b09ac348e8e6d.tar.gz
podman-8a16674722ab4a33ce66e57d151b09ac348e8e6d.tar.bz2
podman-8a16674722ab4a33ce66e57d151b09ac348e8e6d.zip
podmanv2 checkpoint and restore
add the ability to checkpoint and restore containers on v2podman Signed-off-by: Brent Baude <bbaude@redhat.com>
Diffstat (limited to 'pkg/adapter/checkpoint_restore.go')
-rw-r--r--pkg/adapter/checkpoint_restore.go153
1 files changed, 0 insertions, 153 deletions
diff --git a/pkg/adapter/checkpoint_restore.go b/pkg/adapter/checkpoint_restore.go
deleted file mode 100644
index a5b74013b..000000000
--- a/pkg/adapter/checkpoint_restore.go
+++ /dev/null
@@ -1,153 +0,0 @@
-// +build !remoteclient
-
-package adapter
-
-import (
- "context"
- "io/ioutil"
- "os"
- "path/filepath"
-
- "github.com/containers/libpod/libpod"
- "github.com/containers/libpod/libpod/image"
- "github.com/containers/libpod/pkg/errorhandling"
- "github.com/containers/libpod/pkg/util"
- "github.com/containers/storage/pkg/archive"
- jsoniter "github.com/json-iterator/go"
- spec "github.com/opencontainers/runtime-spec/specs-go"
- "github.com/pkg/errors"
- "github.com/sirupsen/logrus"
-)
-
-// Prefixing the checkpoint/restore related functions with 'cr'
-
-// crImportFromJSON imports the JSON files stored in the exported
-// checkpoint tarball
-func crImportFromJSON(filePath string, v interface{}) error {
- jsonFile, err := os.Open(filePath)
- if err != nil {
- return errors.Wrapf(err, "Failed to open container definition %s for restore", filePath)
- }
- defer errorhandling.CloseQuiet(jsonFile)
-
- content, err := ioutil.ReadAll(jsonFile)
- if err != nil {
- return errors.Wrapf(err, "Failed to read container definition %s for restore", filePath)
- }
- json := jsoniter.ConfigCompatibleWithStandardLibrary
- if err = json.Unmarshal(content, v); err != nil {
- return errors.Wrapf(err, "Failed to unmarshal container definition %s for restore", filePath)
- }
-
- return nil
-}
-
-// crImportCheckpoint it the function which imports the information
-// from checkpoint tarball and re-creates the container from that information
-func crImportCheckpoint(ctx context.Context, runtime *libpod.Runtime, input string, name string) ([]*libpod.Container, error) {
- // First get the container definition from the
- // tarball to a temporary directory
- archiveFile, err := os.Open(input)
- if err != nil {
- return nil, errors.Wrapf(err, "Failed to open checkpoint archive %s for import", input)
- }
- defer errorhandling.CloseQuiet(archiveFile)
- options := &archive.TarOptions{
- // Here we only need the files config.dump and spec.dump
- ExcludePatterns: []string{
- "checkpoint",
- "artifacts",
- "ctr.log",
- "rootfs-diff.tar",
- "network.status",
- "deleted.files",
- },
- }
- dir, err := ioutil.TempDir("", "checkpoint")
- if err != nil {
- return nil, err
- }
- defer func() {
- if err := os.RemoveAll(dir); err != nil {
- logrus.Errorf("could not recursively remove %s: %q", dir, err)
- }
- }()
- err = archive.Untar(archiveFile, dir, options)
- if err != nil {
- return nil, errors.Wrapf(err, "Unpacking of checkpoint archive %s failed", input)
- }
-
- // Load spec.dump from temporary directory
- dumpSpec := new(spec.Spec)
- if err := crImportFromJSON(filepath.Join(dir, "spec.dump"), dumpSpec); err != nil {
- return nil, err
- }
-
- // Load config.dump from temporary directory
- config := new(libpod.ContainerConfig)
- if err = crImportFromJSON(filepath.Join(dir, "config.dump"), config); err != nil {
- return nil, err
- }
-
- // This should not happen as checkpoints with these options are not exported.
- if (len(config.Dependencies) > 0) || (len(config.NamedVolumes) > 0) {
- return nil, errors.Errorf("Cannot import checkpoints of containers with named volumes or dependencies")
- }
-
- ctrID := config.ID
- newName := false
-
- // Check if the restored container gets a new name
- if name != "" {
- config.ID = ""
- config.Name = name
- newName = true
- }
-
- ctrName := config.Name
-
- // The code to load the images is copied from create.go
- // In create.go this only set if '--quiet' does not exist.
- writer := os.Stderr
- rtc, err := runtime.GetConfig()
- if err != nil {
- return nil, err
- }
-
- _, err = runtime.ImageRuntime().New(ctx, config.RootfsImageName, rtc.Engine.SignaturePolicyPath, "", writer, nil, image.SigningOptions{}, nil, util.PullImageMissing)
- if err != nil {
- return nil, err
- }
-
- // Now create a new container from the just loaded information
- container, err := runtime.RestoreContainer(ctx, dumpSpec, config)
- if err != nil {
- return nil, err
- }
-
- var containers []*libpod.Container
- if container == nil {
- return nil, nil
- }
-
- containerConfig := container.Config()
- if containerConfig.Name != ctrName {
- return nil, errors.Errorf("Name of restored container (%s) does not match requested name (%s)", containerConfig.Name, ctrName)
- }
-
- if !newName {
- // Only check ID for a restore with the same name.
- // Using -n to request a new name for the restored container, will also create a new ID
- if containerConfig.ID != ctrID {
- return nil, errors.Errorf("ID of restored container (%s) does not match requested ID (%s)", containerConfig.ID, ctrID)
- }
- }
-
- // Check if the ExitCommand points to the correct container ID
- if containerConfig.ExitCommand[len(containerConfig.ExitCommand)-1] != containerConfig.ID {
- return nil, errors.Errorf("'ExitCommandID' uses ID %s instead of container ID %s", containerConfig.ExitCommand[len(containerConfig.ExitCommand)-1], containerConfig.ID)
- }
-
- containers = append(containers, container)
- return containers, nil
-}