mirror of
https://github.com/containers/podman.git
synced 2025-05-22 01:27:07 +08:00
Merge pull request #4221 from mheon/reset_runtime
Migrate can move containers to a user-defined runtime
This commit is contained in:
@ -651,6 +651,7 @@ type SystemRenumberValues struct {
|
||||
|
||||
type SystemMigrateValues struct {
|
||||
PodmanCommand
|
||||
NewRuntime string
|
||||
}
|
||||
|
||||
type SystemDfValues struct {
|
||||
|
@ -14,31 +14,31 @@ import (
|
||||
)
|
||||
|
||||
// GetRuntimeMigrate gets a libpod runtime that will perform a migration of existing containers
|
||||
func GetRuntimeMigrate(ctx context.Context, c *cliconfig.PodmanCommand) (*libpod.Runtime, error) {
|
||||
return getRuntime(ctx, c, false, true, false, true)
|
||||
func GetRuntimeMigrate(ctx context.Context, c *cliconfig.PodmanCommand, newRuntime string) (*libpod.Runtime, error) {
|
||||
return getRuntime(ctx, c, false, true, false, true, newRuntime)
|
||||
}
|
||||
|
||||
// GetRuntimeDisableFDs gets a libpod runtime that will disable sd notify
|
||||
func GetRuntimeDisableFDs(ctx context.Context, c *cliconfig.PodmanCommand) (*libpod.Runtime, error) {
|
||||
return getRuntime(ctx, c, false, false, false, false)
|
||||
return getRuntime(ctx, c, false, false, false, false, "")
|
||||
}
|
||||
|
||||
// GetRuntimeRenumber gets a libpod runtime that will perform a lock renumber
|
||||
func GetRuntimeRenumber(ctx context.Context, c *cliconfig.PodmanCommand) (*libpod.Runtime, error) {
|
||||
return getRuntime(ctx, c, true, false, false, true)
|
||||
return getRuntime(ctx, c, true, false, false, true, "")
|
||||
}
|
||||
|
||||
// GetRuntime generates a new libpod runtime configured by command line options
|
||||
func GetRuntime(ctx context.Context, c *cliconfig.PodmanCommand) (*libpod.Runtime, error) {
|
||||
return getRuntime(ctx, c, false, false, false, true)
|
||||
return getRuntime(ctx, c, false, false, false, true, "")
|
||||
}
|
||||
|
||||
// GetRuntimeNoStore generates a new libpod runtime configured by command line options
|
||||
func GetRuntimeNoStore(ctx context.Context, c *cliconfig.PodmanCommand) (*libpod.Runtime, error) {
|
||||
return getRuntime(ctx, c, false, false, true, true)
|
||||
return getRuntime(ctx, c, false, false, true, true, "")
|
||||
}
|
||||
|
||||
func getRuntime(ctx context.Context, c *cliconfig.PodmanCommand, renumber, migrate, noStore, withFDS bool) (*libpod.Runtime, error) {
|
||||
func getRuntime(ctx context.Context, c *cliconfig.PodmanCommand, renumber, migrate, noStore, withFDS bool, newRuntime string) (*libpod.Runtime, error) {
|
||||
options := []libpod.RuntimeOption{}
|
||||
storageOpts := storage.StoreOptions{}
|
||||
storageSet := false
|
||||
@ -88,6 +88,9 @@ func getRuntime(ctx context.Context, c *cliconfig.PodmanCommand, renumber, migra
|
||||
}
|
||||
if migrate {
|
||||
options = append(options, libpod.WithMigrate())
|
||||
if newRuntime != "" {
|
||||
options = append(options, libpod.WithMigrateRuntime(newRuntime))
|
||||
}
|
||||
}
|
||||
|
||||
if renumber {
|
||||
|
@ -32,13 +32,15 @@ func init() {
|
||||
migrateCommand.Command = _migrateCommand
|
||||
migrateCommand.SetHelpTemplate(HelpTemplate())
|
||||
migrateCommand.SetUsageTemplate(UsageTemplate())
|
||||
flags := migrateCommand.Flags()
|
||||
flags.StringVar(&migrateCommand.NewRuntime, "new-runtime", "", "Specify a new runtime for all containers")
|
||||
}
|
||||
|
||||
func migrateCmd(c *cliconfig.SystemMigrateValues) error {
|
||||
// We need to pass one extra option to NewRuntime.
|
||||
// This will inform the OCI runtime to start a migrate.
|
||||
// That's controlled by the last argument to GetRuntime.
|
||||
r, err := libpodruntime.GetRuntimeMigrate(getContext(), &c.PodmanCommand)
|
||||
r, err := libpodruntime.GetRuntimeMigrate(getContext(), &c.PodmanCommand, c.NewRuntime)
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "error migrating containers")
|
||||
}
|
||||
|
@ -24,6 +24,14 @@ pause process. The `/etc/subuid` and `/etc/subgid` files can then be
|
||||
edited or changed with usermod to recreate the user namespace with the
|
||||
newly configured mappings.
|
||||
|
||||
## OPTIONS
|
||||
|
||||
**--new-runtime**=*runtime*
|
||||
|
||||
Set a new OCI runtime for all containers.
|
||||
This can be used after a system upgrade which changes the default OCI runtime to move all containers to the new runtime.
|
||||
There are no guarantees that the containers will continue to work under the new runtime, as some runtimes support differing options and configurations.
|
||||
|
||||
## SYNOPSIS
|
||||
**podman system migrate**
|
||||
|
||||
|
@ -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.
|
||||
|
@ -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(),
|
||||
|
@ -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())
|
||||
}
|
||||
|
Reference in New Issue
Block a user