Merge pull request #4221 from mheon/reset_runtime

Migrate can move containers to a user-defined runtime
This commit is contained in:
OpenShift Merge Robot 2019-10-11 19:56:13 +02:00 committed by GitHub
commit cee6478f9e
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 73 additions and 9 deletions

View file

@ -651,6 +651,7 @@ type SystemRenumberValues struct {
type SystemMigrateValues struct {
PodmanCommand
NewRuntime string
}
type SystemDfValues struct {

View file

@ -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 {

View file

@ -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")
}

View file

@ -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**

View file

@ -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.

View file

@ -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(),

View file

@ -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())
}