github.com/containers/libpod@v1.9.4-0.20220419124438-4284fd425507/libpod/runtime_migrate.go (about) 1 // +build linux 2 3 package libpod 4 5 import ( 6 "context" 7 "fmt" 8 "io/ioutil" 9 "os" 10 "path/filepath" 11 "strconv" 12 "syscall" 13 14 "github.com/containers/libpod/libpod/define" 15 "github.com/containers/libpod/pkg/rootless" 16 "github.com/containers/libpod/pkg/util" 17 "github.com/pkg/errors" 18 "github.com/sirupsen/logrus" 19 ) 20 21 func stopPauseProcess() error { 22 if rootless.IsRootless() { 23 pausePidPath, err := util.GetRootlessPauseProcessPidPath() 24 if err != nil { 25 return errors.Wrapf(err, "could not get pause process pid file path") 26 } 27 data, err := ioutil.ReadFile(pausePidPath) 28 if err != nil { 29 if os.IsNotExist(err) { 30 return nil 31 } 32 return errors.Wrapf(err, "cannot read pause process pid file %s", pausePidPath) 33 } 34 pausePid, err := strconv.Atoi(string(data)) 35 if err != nil { 36 return errors.Wrapf(err, "cannot parse pause pid file %s", pausePidPath) 37 } 38 if err := os.Remove(pausePidPath); err != nil { 39 return errors.Wrapf(err, "cannot delete pause pid file %s", pausePidPath) 40 } 41 if err := syscall.Kill(pausePid, syscall.SIGKILL); err != nil { 42 return err 43 } 44 } 45 return nil 46 } 47 48 func (r *Runtime) migrate(ctx context.Context) error { 49 runningContainers, err := r.GetRunningContainers() 50 if err != nil { 51 return err 52 } 53 54 allCtrs, err := r.state.AllContainers() 55 if err != nil { 56 return err 57 } 58 59 logrus.Infof("stopping all containers") 60 for _, ctr := range runningContainers { 61 fmt.Printf("stopped %s\n", ctr.ID()) 62 if err := ctr.Stop(); err != nil { 63 return errors.Wrapf(err, "cannot stop container %s", ctr.ID()) 64 } 65 } 66 67 // Did the user request a new runtime? 68 runtimeChangeRequested := r.migrateRuntime != "" 69 requestedRuntime, runtimeExists := r.ociRuntimes[r.migrateRuntime] 70 if !runtimeExists && runtimeChangeRequested { 71 return errors.Wrapf(define.ErrInvalidArg, "change to runtime %q requested but no such runtime is defined", r.migrateRuntime) 72 } 73 74 for _, ctr := range allCtrs { 75 needsWrite := false 76 77 // Reset pause process location 78 oldLocation := filepath.Join(ctr.state.RunDir, "conmon.pid") 79 if ctr.config.ConmonPidFile == oldLocation { 80 logrus.Infof("changing conmon PID file for %s", ctr.ID()) 81 ctr.config.ConmonPidFile = filepath.Join(ctr.config.StaticDir, "conmon.pid") 82 needsWrite = true 83 } 84 85 // Reset runtime 86 if runtimeChangeRequested { 87 logrus.Infof("Resetting container %s runtime to runtime %s", ctr.ID(), r.migrateRuntime) 88 ctr.config.OCIRuntime = r.migrateRuntime 89 ctr.ociRuntime = requestedRuntime 90 91 needsWrite = true 92 } 93 94 if needsWrite { 95 if err := r.state.RewriteContainerConfig(ctr, ctr.config); err != nil { 96 return errors.Wrapf(err, "error rewriting config for container %s", ctr.ID()) 97 } 98 } 99 } 100 101 return stopPauseProcess() 102 }