mirror of
https://github.com/netbirdio/gvisor.git
synced 2026-05-22 17:12:49 -07:00
Merge pull request #8706 from sitano:restore_can_load
PiperOrigin-RevId: 518375542
This commit is contained in:
@@ -53,6 +53,7 @@ go_library(
|
||||
deps = [
|
||||
"//pkg/abi/linux",
|
||||
"//pkg/atomicbitops",
|
||||
"//pkg/cleanup",
|
||||
"//pkg/coretag",
|
||||
"//pkg/coverage",
|
||||
"//pkg/cpuid",
|
||||
|
||||
+56
-9
@@ -16,10 +16,13 @@ package cmd
|
||||
|
||||
import (
|
||||
"context"
|
||||
"os"
|
||||
"path/filepath"
|
||||
|
||||
"github.com/google/subcommands"
|
||||
"golang.org/x/sys/unix"
|
||||
"gvisor.dev/gvisor/pkg/cleanup"
|
||||
"gvisor.dev/gvisor/pkg/log"
|
||||
"gvisor.dev/gvisor/runsc/cmd/util"
|
||||
"gvisor.dev/gvisor/runsc/config"
|
||||
"gvisor.dev/gvisor/runsc/container"
|
||||
@@ -89,32 +92,76 @@ func (r *Restore) Execute(_ context.Context, f *flag.FlagSet, args ...any) subco
|
||||
if bundleDir == "" {
|
||||
bundleDir = getwdOrDie()
|
||||
}
|
||||
spec, err := specutils.ReadSpec(bundleDir, conf)
|
||||
if err != nil {
|
||||
return util.Errorf("reading spec: %v", err)
|
||||
}
|
||||
specutils.LogSpecDebug(spec, conf.OCISeccomp)
|
||||
|
||||
if r.imagePath == "" {
|
||||
return util.Errorf("image-path flag must be provided")
|
||||
}
|
||||
|
||||
var cu cleanup.Cleanup
|
||||
defer cu.Clean()
|
||||
|
||||
conf.RestoreFile = filepath.Join(r.imagePath, checkpointFileName)
|
||||
|
||||
runArgs := container.Args{
|
||||
ID: id,
|
||||
Spec: spec,
|
||||
Spec: nil,
|
||||
BundleDir: bundleDir,
|
||||
ConsoleSocket: r.consoleSocket,
|
||||
PIDFile: r.pidFile,
|
||||
UserLog: r.userLog,
|
||||
Attached: !r.detach,
|
||||
}
|
||||
ws, err := container.Run(conf, runArgs)
|
||||
|
||||
log.Debugf("Restore container, cid: %s, rootDir: %q", id, conf.RootDir)
|
||||
c, err := container.Load(conf.RootDir, container.FullID{ContainerID: id}, container.LoadOpts{})
|
||||
if err != nil {
|
||||
return util.Errorf("running container: %v", err)
|
||||
if err != os.ErrNotExist {
|
||||
return util.Errorf("loading container: %v", err)
|
||||
}
|
||||
|
||||
log.Warningf("Container not found, creating new one, cid: %s, spec from: %s", id, bundleDir)
|
||||
|
||||
// Read the spec again here to ensure flag annotations from the spec are
|
||||
// applied to "conf".
|
||||
if runArgs.Spec, err = specutils.ReadSpec(bundleDir, conf); err != nil {
|
||||
return util.Errorf("reading spec: %v", err)
|
||||
}
|
||||
specutils.LogSpecDebug(runArgs.Spec, conf.OCISeccomp)
|
||||
|
||||
if c, err = container.New(conf, runArgs); err != nil {
|
||||
return util.Errorf("creating container: %v", err)
|
||||
}
|
||||
|
||||
// Clean up partially created container if an error occurs.
|
||||
// Any errors returned by Destroy() itself are ignored.
|
||||
cu.Add(func() {
|
||||
c.Destroy()
|
||||
})
|
||||
} else {
|
||||
runArgs.Spec = c.Spec
|
||||
}
|
||||
|
||||
log.Debugf("Restore: %v", conf.RestoreFile)
|
||||
if err := c.Restore(runArgs.Spec, conf, conf.RestoreFile); err != nil {
|
||||
return util.Errorf("starting container: %v", err)
|
||||
}
|
||||
|
||||
// If we allocate a terminal, forward signals to the sandbox process.
|
||||
// Otherwise, Ctrl+C will terminate this process and its children,
|
||||
// including the terminal.
|
||||
if c.Spec.Process.Terminal {
|
||||
stopForwarding := c.ForwardSignals(0, true /* fgProcess */)
|
||||
defer stopForwarding()
|
||||
}
|
||||
|
||||
var ws unix.WaitStatus
|
||||
if runArgs.Attached {
|
||||
if ws, err = c.Wait(); err != nil {
|
||||
return util.Errorf("running container: %v", err)
|
||||
}
|
||||
}
|
||||
*waitStatus = ws
|
||||
|
||||
cu.Release()
|
||||
|
||||
return subcommands.ExitSuccess
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user