summaryrefslogtreecommitdiff
path: root/libpod
diff options
context:
space:
mode:
authorGiuseppe Scrivano <gscrivan@redhat.com>2019-04-15 22:03:47 +0200
committerGiuseppe Scrivano <gscrivan@redhat.com>2019-04-26 22:23:45 +0200
commit525f0b30ac280565a1f98fd4208821a4984a7515 (patch)
tree795c0e3bac1f9baf11fd6ecfbebf73518f5009f1 /libpod
parentb6e2cbad0a4581a8fe4954ff4a9202461a526781 (diff)
downloadpodman-525f0b30ac280565a1f98fd4208821a4984a7515.tar.gz
podman-525f0b30ac280565a1f98fd4208821a4984a7515.tar.bz2
podman-525f0b30ac280565a1f98fd4208821a4984a7515.zip
system: add new subcommand "migrate"
it is useful to migrate existing containers to a new version of podman. Currently, it is needed to migrate rootless containers that were created with podman <= 1.2 to a newer version which requires all containers to be running in the same user namespace. Closes: https://github.com/containers/libpod/issues/2935 Signed-off-by: Giuseppe Scrivano <gscrivan@redhat.com>
Diffstat (limited to 'libpod')
-rw-r--r--libpod/options.go16
-rw-r--r--libpod/runtime.go20
-rw-r--r--libpod/runtime_migrate.go48
3 files changed, 84 insertions, 0 deletions
diff --git a/libpod/options.go b/libpod/options.go
index 8038f1935..949894dcb 100644
--- a/libpod/options.go
+++ b/libpod/options.go
@@ -436,6 +436,22 @@ func WithRenumber() RuntimeOption {
}
}
+// WithMigrate instructs libpod to perform a lock migrateing while
+// initializing. This will handle migrations from early versions of libpod with
+// file locks to newer versions with SHM locking, as well as changes in the
+// number of configured locks.
+func WithMigrate() RuntimeOption {
+ return func(rt *Runtime) error {
+ if rt.valid {
+ return ErrRuntimeFinalized
+ }
+
+ rt.doMigrate = true
+
+ return nil
+ }
+}
+
// Container Creation Options
// WithShmDir sets the directory that should be mounted on /dev/shm.
diff --git a/libpod/runtime.go b/libpod/runtime.go
index 69cc10389..6d279a107 100644
--- a/libpod/runtime.go
+++ b/libpod/runtime.go
@@ -100,6 +100,8 @@ type Runtime struct {
// unused.
doRenumber bool
+ doMigrate bool
+
// valid indicates whether the runtime is ready to use.
// valid is set to true when a runtime is returned from GetRuntime(),
// and remains true until the runtime is shut down (rendering its
@@ -962,6 +964,24 @@ func makeRuntime(runtime *Runtime) (err error) {
// further
runtime.valid = true
+ if runtime.doMigrate {
+ if os.Geteuid() != 0 {
+ aliveLock.Unlock()
+ locked = false
+
+ became, ret, err := rootless.BecomeRootInUserNS()
+ if err != nil {
+ return err
+ }
+ if became {
+ os.Exit(ret)
+ }
+ }
+ if err := runtime.migrate(); err != nil {
+ return err
+ }
+ }
+
return nil
}
diff --git a/libpod/runtime_migrate.go b/libpod/runtime_migrate.go
new file mode 100644
index 000000000..7d7fa108d
--- /dev/null
+++ b/libpod/runtime_migrate.go
@@ -0,0 +1,48 @@
+package libpod
+
+import (
+ "context"
+ "path/filepath"
+
+ "github.com/pkg/errors"
+ "github.com/sirupsen/logrus"
+)
+
+func (r *Runtime) migrate() error {
+ runningContainers, err := r.GetRunningContainers()
+ if err != nil {
+ return err
+ }
+
+ allCtrs, err := r.state.AllContainers()
+ if err != nil {
+ return err
+ }
+
+ logrus.Infof("stopping all containers")
+ for _, ctr := range runningContainers {
+ logrus.Infof("stopping %s", ctr.ID())
+ if err := ctr.Stop(); err != nil {
+ return errors.Wrapf(err, "cannot stop container %s", ctr.ID())
+ }
+ }
+
+ for _, ctr := range allCtrs {
+ 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")
+ if err := r.state.RewriteContainerConfig(ctr, ctr.config); err != nil {
+ return errors.Wrapf(err, "error rewriting config for container %s", ctr.ID())
+ }
+ }
+ }
+
+ for _, ctr := range runningContainers {
+ if err := ctr.Start(context.Background(), true); err != nil {
+ logrus.Errorf("error restarting container %s", ctr.ID())
+ }
+ }
+
+ return nil
+}