mirror of
https://github.com/netbirdio/gvisor.git
synced 2026-05-22 17:12:49 -07:00
Kill sandbox process when 'runsc do' exits
PiperOrigin-RevId: 253882115
This commit is contained in:
committed by
gVisor bot
parent
bdb19b82ef
commit
0e07c94d54
+15
-5
@@ -39,9 +39,10 @@ import (
|
||||
// Do implements subcommands.Command for the "do" command. It sets up a simple
|
||||
// sandbox and executes the command inside it. See Usage() for more details.
|
||||
type Do struct {
|
||||
root string
|
||||
cwd string
|
||||
ip string
|
||||
root string
|
||||
cwd string
|
||||
ip string
|
||||
quiet bool
|
||||
}
|
||||
|
||||
// Name implements subcommands.Command.Name.
|
||||
@@ -71,6 +72,7 @@ func (c *Do) SetFlags(f *flag.FlagSet) {
|
||||
f.StringVar(&c.root, "root", "/", `path to the root directory, defaults to "/"`)
|
||||
f.StringVar(&c.cwd, "cwd", ".", "path to the current directory, defaults to the current directory")
|
||||
f.StringVar(&c.ip, "ip", "192.168.10.2", "IPv4 address for the sandbox")
|
||||
f.BoolVar(&c.quiet, "quiet", false, "suppress runsc messages to stdout. Application output is still sent to stdout and stderr")
|
||||
}
|
||||
|
||||
// Execute implements subcommands.Command.Execute.
|
||||
@@ -134,7 +136,7 @@ func (c *Do) Execute(_ context.Context, f *flag.FlagSet, args ...interface{}) su
|
||||
|
||||
} else if conf.Rootless {
|
||||
if conf.Network == boot.NetworkSandbox {
|
||||
fmt.Println("*** Rootless requires changing network type to host ***")
|
||||
c.notifyUser("*** Warning: using host network due to --rootless ***")
|
||||
conf.Network = boot.NetworkHost
|
||||
}
|
||||
|
||||
@@ -168,8 +170,9 @@ func (c *Do) Execute(_ context.Context, f *flag.FlagSet, args ...interface{}) su
|
||||
ID: cid,
|
||||
Spec: spec,
|
||||
BundleDir: tmpDir,
|
||||
Attached: true,
|
||||
}
|
||||
ws, err := container.Run(conf, runArgs, false)
|
||||
ws, err := container.Run(conf, runArgs)
|
||||
if err != nil {
|
||||
return Errorf("running container: %v", err)
|
||||
}
|
||||
@@ -178,6 +181,13 @@ func (c *Do) Execute(_ context.Context, f *flag.FlagSet, args ...interface{}) su
|
||||
return subcommands.ExitSuccess
|
||||
}
|
||||
|
||||
func (c *Do) notifyUser(format string, v ...interface{}) {
|
||||
if !c.quiet {
|
||||
fmt.Printf(format+"\n", v...)
|
||||
}
|
||||
log.Warningf(format, v...)
|
||||
}
|
||||
|
||||
func resolvePath(path string) (string, error) {
|
||||
var err error
|
||||
path, err = filepath.Abs(path)
|
||||
|
||||
@@ -107,8 +107,9 @@ func (r *Restore) Execute(_ context.Context, f *flag.FlagSet, args ...interface{
|
||||
ConsoleSocket: r.consoleSocket,
|
||||
PIDFile: r.pidFile,
|
||||
UserLog: r.userLog,
|
||||
Attached: !r.detach,
|
||||
}
|
||||
ws, err := container.Run(conf, runArgs, r.detach)
|
||||
ws, err := container.Run(conf, runArgs)
|
||||
if err != nil {
|
||||
return Errorf("running container: %v", err)
|
||||
}
|
||||
|
||||
+2
-1
@@ -88,8 +88,9 @@ func (r *Run) Execute(_ context.Context, f *flag.FlagSet, args ...interface{}) s
|
||||
ConsoleSocket: r.consoleSocket,
|
||||
PIDFile: r.pidFile,
|
||||
UserLog: r.userLog,
|
||||
Attached: !r.detach,
|
||||
}
|
||||
ws, err := container.Run(conf, runArgs, r.detach)
|
||||
ws, err := container.Run(conf, runArgs)
|
||||
if err != nil {
|
||||
return Errorf("running container: %v", err)
|
||||
}
|
||||
|
||||
@@ -262,7 +262,15 @@ type Args struct {
|
||||
PIDFile string
|
||||
|
||||
// UserLog is the filename to send user-visible logs to. It may be empty.
|
||||
//
|
||||
// It only applies for the init container.
|
||||
UserLog string
|
||||
|
||||
// Attached indicates that the sandbox lifecycle is attached with the caller.
|
||||
// If the caller exits, the sandbox should exit too.
|
||||
//
|
||||
// It only applies for the init container.
|
||||
Attached bool
|
||||
}
|
||||
|
||||
// Create creates the container in a new Sandbox process, unless the metadata
|
||||
@@ -349,6 +357,7 @@ func New(conf *boot.Config, args Args) (*Container, error) {
|
||||
IOFiles: ioFiles,
|
||||
MountsFile: specFile,
|
||||
Cgroup: cg,
|
||||
Attached: args.Attached,
|
||||
}
|
||||
sand, err := sandbox.New(conf, sandArgs)
|
||||
if err != nil {
|
||||
@@ -499,7 +508,7 @@ func (c *Container) Restore(spec *specs.Spec, conf *boot.Config, restoreFile str
|
||||
}
|
||||
|
||||
// Run is a helper that calls Create + Start + Wait.
|
||||
func Run(conf *boot.Config, args Args, detach bool) (syscall.WaitStatus, error) {
|
||||
func Run(conf *boot.Config, args Args) (syscall.WaitStatus, error) {
|
||||
log.Debugf("Run container %q in root dir: %s", args.ID, conf.RootDir)
|
||||
c, err := New(conf, args)
|
||||
if err != nil {
|
||||
@@ -522,11 +531,11 @@ func Run(conf *boot.Config, args Args, detach bool) (syscall.WaitStatus, error)
|
||||
return 0, fmt.Errorf("starting container: %v", err)
|
||||
}
|
||||
}
|
||||
if detach {
|
||||
cu.Release()
|
||||
return 0, nil
|
||||
if args.Attached {
|
||||
return c.Wait()
|
||||
}
|
||||
return c.Wait()
|
||||
cu.Release()
|
||||
return 0, nil
|
||||
}
|
||||
|
||||
// Execute runs the specified command in the container. It returns the PID of
|
||||
|
||||
@@ -215,8 +215,9 @@ func run(spec *specs.Spec, conf *boot.Config) error {
|
||||
ID: testutil.UniqueContainerID(),
|
||||
Spec: spec,
|
||||
BundleDir: bundleDir,
|
||||
Attached: true,
|
||||
}
|
||||
ws, err := Run(conf, args, false)
|
||||
ws, err := Run(conf, args)
|
||||
if err != nil {
|
||||
return fmt.Errorf("running container: %v", err)
|
||||
}
|
||||
@@ -430,8 +431,9 @@ func TestExePath(t *testing.T) {
|
||||
ID: testutil.UniqueContainerID(),
|
||||
Spec: spec,
|
||||
BundleDir: bundleDir,
|
||||
Attached: true,
|
||||
}
|
||||
ws, err := Run(conf, args, false)
|
||||
ws, err := Run(conf, args)
|
||||
|
||||
os.RemoveAll(rootDir)
|
||||
os.RemoveAll(bundleDir)
|
||||
@@ -468,8 +470,9 @@ func TestAppExitStatus(t *testing.T) {
|
||||
ID: testutil.UniqueContainerID(),
|
||||
Spec: succSpec,
|
||||
BundleDir: bundleDir,
|
||||
Attached: true,
|
||||
}
|
||||
ws, err := Run(conf, args, false)
|
||||
ws, err := Run(conf, args)
|
||||
if err != nil {
|
||||
t.Fatalf("error running container: %v", err)
|
||||
}
|
||||
@@ -492,8 +495,9 @@ func TestAppExitStatus(t *testing.T) {
|
||||
ID: testutil.UniqueContainerID(),
|
||||
Spec: errSpec,
|
||||
BundleDir: bundleDir2,
|
||||
Attached: true,
|
||||
}
|
||||
ws, err = Run(conf, args2, false)
|
||||
ws, err = Run(conf, args2)
|
||||
if err != nil {
|
||||
t.Fatalf("error running container: %v", err)
|
||||
}
|
||||
@@ -1624,8 +1628,9 @@ func TestUserLog(t *testing.T) {
|
||||
Spec: spec,
|
||||
BundleDir: bundleDir,
|
||||
UserLog: userLog,
|
||||
Attached: true,
|
||||
}
|
||||
ws, err := Run(conf, args, false)
|
||||
ws, err := Run(conf, args)
|
||||
if err != nil {
|
||||
t.Fatalf("error running container: %v", err)
|
||||
}
|
||||
|
||||
@@ -103,6 +103,10 @@ type Args struct {
|
||||
|
||||
// Gcgroup is the cgroup that the sandbox is part of.
|
||||
Cgroup *cgroup.Cgroup
|
||||
|
||||
// Attached indicates that the sandbox lifecycle is attached with the caller.
|
||||
// If the caller exits, the sandbox should exit too.
|
||||
Attached bool
|
||||
}
|
||||
|
||||
// New creates the sandbox process. The caller must call Destroy() on the
|
||||
@@ -650,6 +654,11 @@ func (s *Sandbox) createSandboxProcess(conf *boot.Config, args *Args, startSyncF
|
||||
log.Debugf("Donating FD %d: %q", i+3, f.Name())
|
||||
}
|
||||
|
||||
if args.Attached {
|
||||
// Kill sandbox if parent process exits in attached mode.
|
||||
cmd.SysProcAttr.Pdeathsig = syscall.SIGKILL
|
||||
}
|
||||
|
||||
log.Debugf("Starting sandbox: %s %v", binPath, cmd.Args)
|
||||
log.Debugf("SysProcAttr: %+v", cmd.SysProcAttr)
|
||||
if err := specutils.StartInNS(cmd, nss); err != nil {
|
||||
|
||||
Reference in New Issue
Block a user