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  }