func getIPTables(host cmd.Cmd) (string, error) { rules, _, err := host.Run("sudo", "iptables-save") if err != nil { return "", err } return rules, nil }
func isRunning(containerId string, dstCmd cmd.Cmd) bool { _, _, err := dstCmd.Run("stat", fmt.Sprintf("/var/run/opencontainer/containers/%s", containerId)) if err != nil { return true } return false }
func getVersion(command cmd.Cmd, name string) (string, error) { version, _, err := command.Run("sudo", name, "--version") if _, ok := err.(*ssh.ExitError); ok { return "", fmt.Errorf("Error %s does not exist", name) } else if _, ok := err.(*exec.ExitError); ok { return "", fmt.Errorf("Error %s does not exist", name) } else if err != nil { return "", fmt.Errorf("Connection error: %s ", err) } return version, nil }
func checkKernelCap(c cmd.Cmd) error { _, _, err := c.Run("sudo", "criu", "check", "--ms") if _, ok := err.(*ssh.ExitError); ok { return fmt.Errorf("Error criu checks do not pass") } else if _, ok := err.(*exec.ExitError); ok { return fmt.Errorf("Error criu checks do not pass") } else if err != nil { return fmt.Errorf("Connection error: %s ", err) } return err }
func applyIPTablesRules(host cmd.Cmd, rules []string) error { for _, rule := range rules { args := []string{"iptables"} args = append(args, strings.Fields(rule)...) _, _, err := host.Run("sudo", args...) if err != nil { return err } } return nil }
func checkCPUCompat(srcCmd, dstCmd cmd.Cmd) error { // Dump _, _, err := srcCmd.Run("sudo", "criu", "cpuinfo", "dump") if _, ok := err.(*ssh.ExitError); ok { return fmt.Errorf("Error dumping CPU info") } else if _, ok := err.(*exec.ExitError); ok { return fmt.Errorf("Error dumping CPU info") } else if err != nil { return fmt.Errorf("Connection error: %s ", err) } // Copy err = cmd.Scp(srcCmd.URL("./cpuinfo.img"), dstCmd.URL(".")) if _, ok := err.(*ssh.ExitError); ok { return fmt.Errorf("Error copying dump image") } else if _, ok := err.(*exec.ExitError); ok { return fmt.Errorf("Error copying dump image") } else if err != nil { return fmt.Errorf("Connection error: %s ", err) } // Check _, _, err = srcCmd.Run("sudo", "criu", "cpuinfo", "check") if _, ok := err.(*ssh.ExitError); ok { return fmt.Errorf("Error checking CPU info") } else if _, ok := err.(*exec.ExitError); ok { return fmt.Errorf("Error checking CPU info") } else if err != nil { return fmt.Errorf("Connection error: %s ", err) } return nil }
func unpackTar(cmd cmd.Cmd, tarFile, workDir string) { log.Println("Preparing image at destination host") _, _, err := cmd.Run("sudo", "tar", "-C", workDir, "-xvzf", tarFile) if err != nil { log.Fatal("Error uncompressing image in destination:", err) } }
func checkpoint(cmd cmd.Cmd, containerId, imagesPath string, predump bool) { log.Printf("Performing the checkpoint predump = %t\n", predump) args := []string{"runc", "--id", containerId, "checkpoint", "--track-mem", "--image-path", imagesPath} if predump { args = append(args, "--pre-dump") } _, _, err := cmd.Run("sudo", args...) if err != nil { log.Fatal("Error performing checkpoint:", err) } }
func prepareDir(cmd cmd.Cmd, path string) { _, _, err := cmd.Run("mkdir", "-p", path) if err != nil { log.Fatal("Error preparing pre-dump dir:", err) } }
func prepareTar(cmd cmd.Cmd, tarFile, workDir string) { _, _, err := cmd.Run("sudo", "tar", "-czf", tarFile, "-C", fmt.Sprintf("%s/", workDir), ".") if err != nil { log.Fatal("Error compressing image in source:", err) } }
cli.StringFlag{ Name: "hook-failed-restore", Usage: "Command to run right after a failed process restoration", }, }, Action: func(c *cli.Context) { srcUrl := validate.ParseURL(c.String("src")) dstUrl := validate.ParseURL(c.String("dst")) log.Println("Performing validations") src, dst := validate.Validate(srcUrl, dstUrl, c.Bool("force")) log.Println("Preparing everything to do a checkpoint") containerId := getContainerId(srcUrl.Path) var imagesPath string var restoreCmd cmd.Cmd var migrateStart time.Time var downtime time.Duration if c.Bool("pre-dump") { // Process pre-dump predumpPath := fmt.Sprintf("%s/images/0", srcUrl.Path) prepareDir(src, predumpPath) checkpoint(src, containerId, predumpPath, true) srcTarFile := fmt.Sprintf("%s/predump.tar.gz", srcUrl.Path) prepareTar(src, srcTarFile, predumpPath) prepareDir(dst, fmt.Sprintf("%s/images/0", dstUrl.Path))