aboutsummaryrefslogtreecommitdiff
path: root/libpod
diff options
context:
space:
mode:
authorMatthew Heon <matthew.heon@pm.me>2019-10-08 14:12:58 -0400
committerMatthew Heon <matthew.heon@pm.me>2019-10-10 10:25:06 -0400
commitfeba94eb95f93fd571efff039cb7d7cdb5139169 (patch)
treeb1ef3ed2c7278599c0df6f17971fa28a035a248d /libpod
parentc3c40f970e6441b70ac62fb050a35f79fedb8896 (diff)
downloadpodman-feba94eb95f93fd571efff039cb7d7cdb5139169.tar.gz
podman-feba94eb95f93fd571efff039cb7d7cdb5139169.tar.bz2
podman-feba94eb95f93fd571efff039cb7d7cdb5139169.zip
Migrate can move containers to a new runtime
This is a horrible hack to work around issues with Fedora 31, but other distros might need it to, so we'll move it upstream. I do not recommend this functionality for general use, and the manpages and other documentation will reflect this. But for some upgrade cases, it will be the only thing that allows for a working system. Signed-off-by: Matthew Heon <matthew.heon@pm.me>
Diffstat (limited to 'libpod')
-rw-r--r--libpod/options.go22
-rw-r--r--libpod/runtime.go4
-rw-r--r--libpod/runtime_migrate.go26
3 files changed, 51 insertions, 1 deletions
diff --git a/libpod/options.go b/libpod/options.go
index ee44439ac..ddc5993af 100644
--- a/libpod/options.go
+++ b/libpod/options.go
@@ -463,6 +463,28 @@ func WithMigrate() RuntimeOption {
}
}
+// WithMigrateRuntime instructs Libpod to change the default OCI runtime on all
+// containers during a migration. This is not used if `MigrateRuntime()` is not
+// also passed.
+// Libpod makes no promises that your containers continue to work with the new
+// runtime - migrations between dissimilar runtimes may well break things.
+// Use with caution.
+func WithMigrateRuntime(requestedRuntime string) RuntimeOption {
+ return func(rt *Runtime) error {
+ if rt.valid {
+ return define.ErrRuntimeFinalized
+ }
+
+ if requestedRuntime == "" {
+ return errors.Wrapf(define.ErrInvalidArg, "must provide a non-empty name for new runtime")
+ }
+
+ rt.migrateRuntime = requestedRuntime
+
+ return nil
+ }
+}
+
// WithEventsLogger sets the events backend to use.
// Currently supported values are "file" for file backend and "journald" for
// journald backend.
diff --git a/libpod/runtime.go b/libpod/runtime.go
index cdb5670ba..53165b830 100644
--- a/libpod/runtime.go
+++ b/libpod/runtime.go
@@ -114,6 +114,10 @@ type Runtime struct {
doRenumber bool
doMigrate bool
+ // System migrate can move containers to a new runtime.
+ // We make no promises that these migrated containers work on the new
+ // runtime, though.
+ migrateRuntime string
// valid indicates whether the runtime is ready to use.
// valid is set to true when a runtime is returned from GetRuntime(),
diff --git a/libpod/runtime_migrate.go b/libpod/runtime_migrate.go
index c363991e6..d85652232 100644
--- a/libpod/runtime_migrate.go
+++ b/libpod/runtime_migrate.go
@@ -5,14 +5,15 @@ package libpod
import (
"context"
"fmt"
- "github.com/containers/libpod/pkg/util"
"io/ioutil"
"os"
"path/filepath"
"strconv"
"syscall"
+ "github.com/containers/libpod/libpod/define"
"github.com/containers/libpod/pkg/rootless"
+ "github.com/containers/libpod/pkg/util"
"github.com/pkg/errors"
"github.com/sirupsen/logrus"
)
@@ -63,11 +64,34 @@ func (r *Runtime) migrate(ctx context.Context) error {
}
}
+ // Did the user request a new runtime?
+ runtimeChangeRequested := r.migrateRuntime != ""
+ requestedRuntime, runtimeExists := r.ociRuntimes[r.migrateRuntime]
+ if !runtimeExists && runtimeChangeRequested {
+ return errors.Wrapf(define.ErrInvalidArg, "change to runtime %q requested but no such runtime is defined", r.migrateRuntime)
+ }
+
for _, ctr := range allCtrs {
+ needsWrite := false
+
+ // Reset pause process location
oldLocation := filepath.Join(ctr.state.RunDir, "conmon.pid")
if ctr.config.ConmonPidFile == oldLocation {
logrus.Infof("changing conmon PID file for %s", ctr.ID())
ctr.config.ConmonPidFile = filepath.Join(ctr.config.StaticDir, "conmon.pid")
+ needsWrite = true
+ }
+
+ // Reset runtime
+ if runtimeChangeRequested {
+ logrus.Infof("Resetting container %s runtime to runtime %s", ctr.ID(), r.migrateRuntime)
+ ctr.config.OCIRuntime = r.migrateRuntime
+ ctr.ociRuntime = requestedRuntime
+
+ needsWrite = true
+ }
+
+ if needsWrite {
if err := r.state.RewriteContainerConfig(ctr, ctr.config); err != nil {
return errors.Wrapf(err, "error rewriting config for container %s", ctr.ID())
}