summaryrefslogtreecommitdiffhomepage
path: root/runsc/cmd
diff options
context:
space:
mode:
Diffstat (limited to 'runsc/cmd')
-rw-r--r--runsc/cmd/BUILD3
-rw-r--r--runsc/cmd/boot.go31
-rw-r--r--runsc/cmd/capability.go2
-rw-r--r--runsc/cmd/capability_test.go19
-rw-r--r--runsc/cmd/checkpoint.go15
-rw-r--r--runsc/cmd/chroot.go4
-rw-r--r--runsc/cmd/cmd.go4
-rw-r--r--runsc/cmd/create.go24
-rw-r--r--runsc/cmd/debug.go99
-rw-r--r--runsc/cmd/delete.go6
-rw-r--r--runsc/cmd/delete_test.go2
-rw-r--r--runsc/cmd/do.go64
-rw-r--r--runsc/cmd/error.go2
-rw-r--r--runsc/cmd/events.go6
-rw-r--r--runsc/cmd/exec.go22
-rw-r--r--runsc/cmd/exec_test.go8
-rw-r--r--runsc/cmd/gofer.go18
-rw-r--r--runsc/cmd/kill.go4
-rw-r--r--runsc/cmd/list.go4
-rw-r--r--runsc/cmd/pause.go4
-rw-r--r--runsc/cmd/ps.go6
-rw-r--r--runsc/cmd/restore.go27
-rw-r--r--runsc/cmd/resume.go4
-rw-r--r--runsc/cmd/run.go25
-rw-r--r--runsc/cmd/start.go4
-rw-r--r--runsc/cmd/state.go6
-rw-r--r--runsc/cmd/syscalls.go4
-rw-r--r--runsc/cmd/wait.go4
28 files changed, 288 insertions, 133 deletions
diff --git a/runsc/cmd/BUILD b/runsc/cmd/BUILD
index df6af0ced..5223b9972 100644
--- a/runsc/cmd/BUILD
+++ b/runsc/cmd/BUILD
@@ -33,7 +33,7 @@ go_library(
"syscalls.go",
"wait.go",
],
- importpath = "gvisor.googlesource.com/gvisor/runsc/cmd",
+ importpath = "gvisor.dev/gvisor/runsc/cmd",
visibility = [
"//runsc:__subpackages__",
],
@@ -46,6 +46,7 @@ go_library(
"//pkg/unet",
"//pkg/urpc",
"//runsc/boot",
+ "//runsc/boot/platforms",
"//runsc/console",
"//runsc/container",
"//runsc/fsgofer",
diff --git a/runsc/cmd/boot.go b/runsc/cmd/boot.go
index 3a547d4aa..b40fded5b 100644
--- a/runsc/cmd/boot.go
+++ b/runsc/cmd/boot.go
@@ -24,9 +24,10 @@ import (
"flag"
"github.com/google/subcommands"
specs "github.com/opencontainers/runtime-spec/specs-go"
- "gvisor.googlesource.com/gvisor/pkg/log"
- "gvisor.googlesource.com/gvisor/runsc/boot"
- "gvisor.googlesource.com/gvisor/runsc/specutils"
+ "gvisor.dev/gvisor/pkg/log"
+ "gvisor.dev/gvisor/runsc/boot"
+ "gvisor.dev/gvisor/runsc/boot/platforms"
+ "gvisor.dev/gvisor/runsc/specutils"
)
// Boot implements subcommands.Command for the "boot" command which starts a
@@ -130,6 +131,8 @@ func (b *Boot) Execute(_ context.Context, f *flag.FlagSet, args ...interface{})
// Ensure that if there is a panic, all goroutine stacks are printed.
debug.SetTraceback("all")
+ conf := args[0].(*boot.Config)
+
if b.setUpRoot {
if err := setUpChroot(b.pidns); err != nil {
Fatalf("error setting up chroot: %v", err)
@@ -143,14 +146,16 @@ func (b *Boot) Execute(_ context.Context, f *flag.FlagSet, args ...interface{})
args = append(args, arg)
}
}
- // Note that we've already read the spec from the spec FD, and
- // we will read it again after the exec call. This works
- // because the ReadSpecFromFile function seeks to the beginning
- // of the file before reading.
- if err := callSelfAsNobody(args); err != nil {
- Fatalf("%v", err)
+ if !conf.Rootless {
+ // Note that we've already read the spec from the spec FD, and
+ // we will read it again after the exec call. This works
+ // because the ReadSpecFromFile function seeks to the beginning
+ // of the file before reading.
+ if err := callSelfAsNobody(args); err != nil {
+ Fatalf("%v", err)
+ }
+ panic("callSelfAsNobody must never return success")
}
- panic("callSelfAsNobody must never return success")
}
}
@@ -163,15 +168,12 @@ func (b *Boot) Execute(_ context.Context, f *flag.FlagSet, args ...interface{})
}
specutils.LogSpec(spec)
- conf := args[0].(*boot.Config)
- waitStatus := args[1].(*syscall.WaitStatus)
-
if b.applyCaps {
caps := spec.Process.Capabilities
if caps == nil {
caps = &specs.LinuxCapabilities{}
}
- if conf.Platform == boot.PlatformPtrace {
+ if conf.Platform == platforms.Ptrace {
// Ptrace platform requires extra capabilities.
const c = "CAP_SYS_PTRACE"
caps.Bounding = append(caps.Bounding, c)
@@ -251,6 +253,7 @@ func (b *Boot) Execute(_ context.Context, f *flag.FlagSet, args ...interface{})
ws := l.WaitExit()
log.Infof("application exiting with %+v", ws)
+ waitStatus := args[1].(*syscall.WaitStatus)
*waitStatus = syscall.WaitStatus(ws.Status())
l.Destroy()
return subcommands.ExitSuccess
diff --git a/runsc/cmd/capability.go b/runsc/cmd/capability.go
index 312e5b471..abfbb7cfc 100644
--- a/runsc/cmd/capability.go
+++ b/runsc/cmd/capability.go
@@ -19,7 +19,7 @@ import (
specs "github.com/opencontainers/runtime-spec/specs-go"
"github.com/syndtr/gocapability/capability"
- "gvisor.googlesource.com/gvisor/pkg/log"
+ "gvisor.dev/gvisor/pkg/log"
)
var allCapTypes = []capability.CapType{
diff --git a/runsc/cmd/capability_test.go b/runsc/cmd/capability_test.go
index ee74d33d8..3ae25a257 100644
--- a/runsc/cmd/capability_test.go
+++ b/runsc/cmd/capability_test.go
@@ -21,11 +21,11 @@ import (
specs "github.com/opencontainers/runtime-spec/specs-go"
"github.com/syndtr/gocapability/capability"
- "gvisor.googlesource.com/gvisor/pkg/log"
- "gvisor.googlesource.com/gvisor/runsc/boot"
- "gvisor.googlesource.com/gvisor/runsc/container"
- "gvisor.googlesource.com/gvisor/runsc/specutils"
- "gvisor.googlesource.com/gvisor/runsc/test/testutil"
+ "gvisor.dev/gvisor/pkg/log"
+ "gvisor.dev/gvisor/runsc/boot"
+ "gvisor.dev/gvisor/runsc/container"
+ "gvisor.dev/gvisor/runsc/specutils"
+ "gvisor.dev/gvisor/runsc/test/testutil"
)
func init() {
@@ -97,7 +97,12 @@ func TestCapabilities(t *testing.T) {
defer os.RemoveAll(bundleDir)
// Create and start the container.
- c, err := container.Create(testutil.UniqueContainerID(), spec, conf, bundleDir, "", "", "")
+ args := container.Args{
+ ID: testutil.UniqueContainerID(),
+ Spec: spec,
+ BundleDir: bundleDir,
+ }
+ c, err := container.New(conf, args)
if err != nil {
t.Fatalf("error creating container: %v", err)
}
@@ -116,6 +121,6 @@ func TestCapabilities(t *testing.T) {
}
func TestMain(m *testing.M) {
- testutil.RunAsRoot()
+ specutils.MaybeRunAsRoot()
os.Exit(m.Run())
}
diff --git a/runsc/cmd/checkpoint.go b/runsc/cmd/checkpoint.go
index 96d3c3378..d8b3a8573 100644
--- a/runsc/cmd/checkpoint.go
+++ b/runsc/cmd/checkpoint.go
@@ -22,10 +22,10 @@ import (
"flag"
"github.com/google/subcommands"
- "gvisor.googlesource.com/gvisor/pkg/log"
- "gvisor.googlesource.com/gvisor/runsc/boot"
- "gvisor.googlesource.com/gvisor/runsc/container"
- "gvisor.googlesource.com/gvisor/runsc/specutils"
+ "gvisor.dev/gvisor/pkg/log"
+ "gvisor.dev/gvisor/runsc/boot"
+ "gvisor.dev/gvisor/runsc/container"
+ "gvisor.dev/gvisor/runsc/specutils"
)
// File containing the container's saved image/state within the given image-path's directory.
@@ -133,7 +133,12 @@ func (c *Checkpoint) Execute(_ context.Context, f *flag.FlagSet, args ...interfa
Fatalf("destroying container: %v", err)
}
- cont, err = container.Create(id, spec, conf, bundleDir, "", "", "")
+ contArgs := container.Args{
+ ID: id,
+ Spec: spec,
+ BundleDir: bundleDir,
+ }
+ cont, err = container.New(conf, contArgs)
if err != nil {
Fatalf("restoring container: %v", err)
}
diff --git a/runsc/cmd/chroot.go b/runsc/cmd/chroot.go
index 1a774db04..b5a0ce17d 100644
--- a/runsc/cmd/chroot.go
+++ b/runsc/cmd/chroot.go
@@ -20,8 +20,8 @@ import (
"path/filepath"
"syscall"
- "gvisor.googlesource.com/gvisor/pkg/log"
- "gvisor.googlesource.com/gvisor/runsc/specutils"
+ "gvisor.dev/gvisor/pkg/log"
+ "gvisor.dev/gvisor/runsc/specutils"
)
// mountInChroot creates the destination mount point in the given chroot and
diff --git a/runsc/cmd/cmd.go b/runsc/cmd/cmd.go
index 5b4cc4a39..f1a4887ef 100644
--- a/runsc/cmd/cmd.go
+++ b/runsc/cmd/cmd.go
@@ -22,8 +22,8 @@ import (
"syscall"
specs "github.com/opencontainers/runtime-spec/specs-go"
- "gvisor.googlesource.com/gvisor/pkg/log"
- "gvisor.googlesource.com/gvisor/runsc/specutils"
+ "gvisor.dev/gvisor/pkg/log"
+ "gvisor.dev/gvisor/runsc/specutils"
)
// intFlags can be used with int flags that appear multiple times.
diff --git a/runsc/cmd/create.go b/runsc/cmd/create.go
index 8bf9b7dcf..a4e3071b3 100644
--- a/runsc/cmd/create.go
+++ b/runsc/cmd/create.go
@@ -18,9 +18,9 @@ import (
"context"
"flag"
"github.com/google/subcommands"
- "gvisor.googlesource.com/gvisor/runsc/boot"
- "gvisor.googlesource.com/gvisor/runsc/container"
- "gvisor.googlesource.com/gvisor/runsc/specutils"
+ "gvisor.dev/gvisor/runsc/boot"
+ "gvisor.dev/gvisor/runsc/container"
+ "gvisor.dev/gvisor/runsc/specutils"
)
// Create implements subcommands.Command for the "create" command.
@@ -82,21 +82,33 @@ func (c *Create) Execute(_ context.Context, f *flag.FlagSet, args ...interface{}
id := f.Arg(0)
conf := args[0].(*boot.Config)
+ if conf.Rootless {
+ return Errorf("Rootless mode not supported with %q", c.Name())
+ }
+
bundleDir := c.bundleDir
if bundleDir == "" {
bundleDir = getwdOrDie()
}
spec, err := specutils.ReadSpec(bundleDir)
if err != nil {
- Fatalf("reading spec: %v", err)
+ return Errorf("reading spec: %v", err)
}
specutils.LogSpec(spec)
// Create the container. A new sandbox will be created for the
// container unless the metadata specifies that it should be run in an
// existing container.
- if _, err := container.Create(id, spec, conf, bundleDir, c.consoleSocket, c.pidFile, c.userLog); err != nil {
- Fatalf("creating container: %v", err)
+ contArgs := container.Args{
+ ID: id,
+ Spec: spec,
+ BundleDir: bundleDir,
+ ConsoleSocket: c.consoleSocket,
+ PIDFile: c.pidFile,
+ UserLog: c.userLog,
+ }
+ if _, err := container.New(conf, contArgs); err != nil {
+ return Errorf("creating container: %v", err)
}
return subcommands.ExitSuccess
}
diff --git a/runsc/cmd/debug.go b/runsc/cmd/debug.go
index 27eb51172..7313e473f 100644
--- a/runsc/cmd/debug.go
+++ b/runsc/cmd/debug.go
@@ -17,14 +17,17 @@ package cmd
import (
"context"
"os"
+ "strconv"
+ "strings"
"syscall"
"time"
"flag"
"github.com/google/subcommands"
- "gvisor.googlesource.com/gvisor/pkg/log"
- "gvisor.googlesource.com/gvisor/runsc/boot"
- "gvisor.googlesource.com/gvisor/runsc/container"
+ "gvisor.dev/gvisor/pkg/log"
+ "gvisor.dev/gvisor/pkg/sentry/control"
+ "gvisor.dev/gvisor/runsc/boot"
+ "gvisor.dev/gvisor/runsc/container"
)
// Debug implements subcommands.Command for the "debug" command.
@@ -36,6 +39,9 @@ type Debug struct {
profileCPU string
profileDelay int
trace string
+ strace string
+ logLevel string
+ logPackets string
}
// Name implements subcommands.Command.
@@ -62,6 +68,9 @@ func (d *Debug) SetFlags(f *flag.FlagSet) {
f.IntVar(&d.profileDelay, "profile-delay", 5, "amount of time to wait before stoping CPU profile")
f.StringVar(&d.trace, "trace", "", "writes an execution trace to the given file.")
f.IntVar(&d.signal, "signal", -1, "sends signal to the sandbox")
+ f.StringVar(&d.strace, "strace", "", `A comma separated list of syscalls to trace. "all" enables all traces, "off" disables all`)
+ f.StringVar(&d.logLevel, "log-level", "", "The log level to set: warning (0), info (1), or debug (2).")
+ f.StringVar(&d.logPackets, "log-packets", "", "A boolean value to enable or disable packet logging: true or false.")
}
// Execute implements subcommands.Command.Execute.
@@ -78,7 +87,7 @@ func (d *Debug) Execute(_ context.Context, f *flag.FlagSet, args ...interface{})
var err error
c, err = container.Load(conf.RootDir, f.Arg(0))
if err != nil {
- Fatalf("loading container %q: %v", f.Arg(0), err)
+ return Errorf("loading container %q: %v", f.Arg(0), err)
}
} else {
if f.NArg() != 0 {
@@ -88,12 +97,12 @@ func (d *Debug) Execute(_ context.Context, f *flag.FlagSet, args ...interface{})
// Go over all sandboxes and find the one that matches PID.
ids, err := container.List(conf.RootDir)
if err != nil {
- Fatalf("listing containers: %v", err)
+ return Errorf("listing containers: %v", err)
}
for _, id := range ids {
candidate, err := container.Load(conf.RootDir, id)
if err != nil {
- Fatalf("loading container %q: %v", id, err)
+ return Errorf("loading container %q: %v", id, err)
}
if candidate.SandboxPid() == d.pid {
c = candidate
@@ -101,38 +110,38 @@ func (d *Debug) Execute(_ context.Context, f *flag.FlagSet, args ...interface{})
}
}
if c == nil {
- Fatalf("container with PID %d not found", d.pid)
+ return Errorf("container with PID %d not found", d.pid)
}
}
if c.Sandbox == nil || !c.Sandbox.IsRunning() {
- Fatalf("container sandbox is not running")
+ return Errorf("container sandbox is not running")
}
log.Infof("Found sandbox %q, PID: %d", c.Sandbox.ID, c.Sandbox.Pid)
if d.signal > 0 {
log.Infof("Sending signal %d to process: %d", d.signal, c.Sandbox.Pid)
if err := syscall.Kill(c.Sandbox.Pid, syscall.Signal(d.signal)); err != nil {
- Fatalf("failed to send signal %d to processs %d", d.signal, c.Sandbox.Pid)
+ return Errorf("failed to send signal %d to processs %d", d.signal, c.Sandbox.Pid)
}
}
if d.stacks {
log.Infof("Retrieving sandbox stacks")
stacks, err := c.Sandbox.Stacks()
if err != nil {
- Fatalf("retrieving stacks: %v", err)
+ return Errorf("retrieving stacks: %v", err)
}
log.Infof(" *** Stack dump ***\n%s", stacks)
}
if d.profileHeap != "" {
f, err := os.Create(d.profileHeap)
if err != nil {
- Fatalf(err.Error())
+ return Errorf(err.Error())
}
defer f.Close()
if err := c.Sandbox.HeapProfile(f); err != nil {
- Fatalf(err.Error())
+ return Errorf(err.Error())
}
log.Infof("Heap profile written to %q", d.profileHeap)
}
@@ -142,7 +151,7 @@ func (d *Debug) Execute(_ context.Context, f *flag.FlagSet, args ...interface{})
delay = true
f, err := os.Create(d.profileCPU)
if err != nil {
- Fatalf(err.Error())
+ return Errorf(err.Error())
}
defer func() {
f.Close()
@@ -152,7 +161,7 @@ func (d *Debug) Execute(_ context.Context, f *flag.FlagSet, args ...interface{})
log.Infof("CPU profile written to %q", d.profileCPU)
}()
if err := c.Sandbox.StartCPUProfile(f); err != nil {
- Fatalf(err.Error())
+ return Errorf(err.Error())
}
log.Infof("CPU profile started for %d sec, writing to %q", d.profileDelay, d.profileCPU)
}
@@ -160,7 +169,7 @@ func (d *Debug) Execute(_ context.Context, f *flag.FlagSet, args ...interface{})
delay = true
f, err := os.Create(d.trace)
if err != nil {
- Fatalf(err.Error())
+ return Errorf(err.Error())
}
defer func() {
f.Close()
@@ -170,15 +179,71 @@ func (d *Debug) Execute(_ context.Context, f *flag.FlagSet, args ...interface{})
log.Infof("Trace written to %q", d.trace)
}()
if err := c.Sandbox.StartTrace(f); err != nil {
- Fatalf(err.Error())
+ return Errorf(err.Error())
}
log.Infof("Tracing started for %d sec, writing to %q", d.profileDelay, d.trace)
}
+ if d.strace != "" || len(d.logLevel) != 0 || len(d.logPackets) != 0 {
+ args := control.LoggingArgs{}
+ switch strings.ToLower(d.strace) {
+ case "":
+ // strace not set, nothing to do here.
+
+ case "off":
+ log.Infof("Disabling strace")
+ args.SetStrace = true
+
+ case "all":
+ log.Infof("Enabling all straces")
+ args.SetStrace = true
+ args.EnableStrace = true
+
+ default:
+ log.Infof("Enabling strace for syscalls: %s", d.strace)
+ args.SetStrace = true
+ args.EnableStrace = true
+ args.StraceWhitelist = strings.Split(d.strace, ",")
+ }
+
+ if len(d.logLevel) != 0 {
+ args.SetLevel = true
+ switch strings.ToLower(d.logLevel) {
+ case "warning", "0":
+ args.Level = log.Warning
+ case "info", "1":
+ args.Level = log.Info
+ case "debug", "2":
+ args.Level = log.Debug
+ default:
+ return Errorf("invalid log level %q", d.logLevel)
+ }
+ log.Infof("Setting log level %v", args.Level)
+ }
+
+ if len(d.logPackets) != 0 {
+ args.SetLogPackets = true
+ lp, err := strconv.ParseBool(d.logPackets)
+ if err != nil {
+ return Errorf("invalid value for log_packets %q", d.logPackets)
+ }
+ args.LogPackets = lp
+ if args.LogPackets {
+ log.Infof("Enabling packet logging")
+ } else {
+ log.Infof("Disabling packet logging")
+ }
+ }
+
+ if err := c.Sandbox.ChangeLogging(args); err != nil {
+ return Errorf(err.Error())
+ }
+ log.Infof("Logging options changed")
+ }
+
if delay {
time.Sleep(time.Duration(d.profileDelay) * time.Second)
-
}
return subcommands.ExitSuccess
diff --git a/runsc/cmd/delete.go b/runsc/cmd/delete.go
index 9039723e9..30d8164b1 100644
--- a/runsc/cmd/delete.go
+++ b/runsc/cmd/delete.go
@@ -21,9 +21,9 @@ import (
"flag"
"github.com/google/subcommands"
- "gvisor.googlesource.com/gvisor/pkg/log"
- "gvisor.googlesource.com/gvisor/runsc/boot"
- "gvisor.googlesource.com/gvisor/runsc/container"
+ "gvisor.dev/gvisor/pkg/log"
+ "gvisor.dev/gvisor/runsc/boot"
+ "gvisor.dev/gvisor/runsc/container"
)
// Delete implements subcommands.Command for the "delete" command.
diff --git a/runsc/cmd/delete_test.go b/runsc/cmd/delete_test.go
index 45fc91016..cb59516a3 100644
--- a/runsc/cmd/delete_test.go
+++ b/runsc/cmd/delete_test.go
@@ -18,7 +18,7 @@ import (
"io/ioutil"
"testing"
- "gvisor.googlesource.com/gvisor/runsc/boot"
+ "gvisor.dev/gvisor/runsc/boot"
)
func TestNotFound(t *testing.T) {
diff --git a/runsc/cmd/do.go b/runsc/cmd/do.go
index 8ea59046c..9a8a49054 100644
--- a/runsc/cmd/do.go
+++ b/runsc/cmd/do.go
@@ -30,19 +30,19 @@ import (
"flag"
"github.com/google/subcommands"
specs "github.com/opencontainers/runtime-spec/specs-go"
- "gvisor.googlesource.com/gvisor/pkg/log"
- "gvisor.googlesource.com/gvisor/runsc/boot"
- "gvisor.googlesource.com/gvisor/runsc/container"
- "gvisor.googlesource.com/gvisor/runsc/specutils"
+ "gvisor.dev/gvisor/pkg/log"
+ "gvisor.dev/gvisor/runsc/boot"
+ "gvisor.dev/gvisor/runsc/container"
+ "gvisor.dev/gvisor/runsc/specutils"
)
// 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
- networkNamespace bool
+ root string
+ cwd string
+ ip string
+ quiet bool
}
// Name implements subcommands.Command.Name.
@@ -72,7 +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.networkNamespace, "netns", true, "run in a new network namespace")
+ 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.
@@ -85,15 +85,21 @@ func (c *Do) Execute(_ context.Context, f *flag.FlagSet, args ...interface{}) su
conf := args[0].(*boot.Config)
waitStatus := args[1].(*syscall.WaitStatus)
- // Map the entire host file system, but make it readonly with a writable
- // overlay on top (ignore --overlay option).
- conf.Overlay = true
+ if conf.Rootless {
+ if err := specutils.MaybeRunAsRoot(); err != nil {
+ return Errorf("Error executing inside namespace: %v", err)
+ }
+ // Execution will continue here if no more capabilities are needed...
+ }
hostname, err := os.Hostname()
if err != nil {
return Errorf("Error to retrieve hostname: %v", err)
}
+ // Map the entire host file system, but make it readonly with a writable
+ // overlay on top (ignore --overlay option).
+ conf.Overlay = true
absRoot, err := resolvePath(c.root)
if err != nil {
return Errorf("Error resolving root: %v", err)
@@ -119,11 +125,22 @@ func (c *Do) Execute(_ context.Context, f *flag.FlagSet, args ...interface{}) su
specutils.LogSpec(spec)
cid := fmt.Sprintf("runsc-%06d", rand.Int31n(1000000))
- if !c.networkNamespace {
- if conf.Network != boot.NetworkHost {
- Fatalf("The current network namespace can be used only if --network=host is set", nil)
+ if conf.Network == boot.NetworkNone {
+ netns := specs.LinuxNamespace{
+ Type: specs.NetworkNamespace,
}
- } else if conf.Network != boot.NetworkNone {
+ if spec.Linux != nil {
+ panic("spec.Linux is not nil")
+ }
+ spec.Linux = &specs.Linux{Namespaces: []specs.LinuxNamespace{netns}}
+
+ } else if conf.Rootless {
+ if conf.Network == boot.NetworkSandbox {
+ c.notifyUser("*** Warning: using host network due to --rootless ***")
+ conf.Network = boot.NetworkHost
+ }
+
+ } else {
clean, err := c.setupNet(cid, spec)
if err != nil {
return Errorf("Error setting up network: %v", err)
@@ -149,7 +166,13 @@ func (c *Do) Execute(_ context.Context, f *flag.FlagSet, args ...interface{}) su
return Errorf("Error write spec: %v", err)
}
- ws, err := container.Run(cid, spec, conf, tmpDir, "", "", "", false)
+ runArgs := container.Args{
+ ID: cid,
+ Spec: spec,
+ BundleDir: tmpDir,
+ Attached: true,
+ }
+ ws, err := container.Run(conf, runArgs)
if err != nil {
return Errorf("running container: %v", err)
}
@@ -158,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)
diff --git a/runsc/cmd/error.go b/runsc/cmd/error.go
index 700b19f14..3585b5448 100644
--- a/runsc/cmd/error.go
+++ b/runsc/cmd/error.go
@@ -22,7 +22,7 @@ import (
"time"
"github.com/google/subcommands"
- "gvisor.googlesource.com/gvisor/pkg/log"
+ "gvisor.dev/gvisor/pkg/log"
)
// ErrorLogger is where error messages should be written to. These messages are
diff --git a/runsc/cmd/events.go b/runsc/cmd/events.go
index c6bc8fc3a..3972e9224 100644
--- a/runsc/cmd/events.go
+++ b/runsc/cmd/events.go
@@ -22,9 +22,9 @@ import (
"flag"
"github.com/google/subcommands"
- "gvisor.googlesource.com/gvisor/pkg/log"
- "gvisor.googlesource.com/gvisor/runsc/boot"
- "gvisor.googlesource.com/gvisor/runsc/container"
+ "gvisor.dev/gvisor/pkg/log"
+ "gvisor.dev/gvisor/runsc/boot"
+ "gvisor.dev/gvisor/runsc/container"
)
// Events implements subcommands.Command for the "events" command.
diff --git a/runsc/cmd/exec.go b/runsc/cmd/exec.go
index 0eeaaadba..e817eff77 100644
--- a/runsc/cmd/exec.go
+++ b/runsc/cmd/exec.go
@@ -30,14 +30,14 @@ import (
"flag"
"github.com/google/subcommands"
specs "github.com/opencontainers/runtime-spec/specs-go"
- "gvisor.googlesource.com/gvisor/pkg/log"
- "gvisor.googlesource.com/gvisor/pkg/sentry/control"
- "gvisor.googlesource.com/gvisor/pkg/sentry/kernel/auth"
- "gvisor.googlesource.com/gvisor/pkg/urpc"
- "gvisor.googlesource.com/gvisor/runsc/boot"
- "gvisor.googlesource.com/gvisor/runsc/console"
- "gvisor.googlesource.com/gvisor/runsc/container"
- "gvisor.googlesource.com/gvisor/runsc/specutils"
+ "gvisor.dev/gvisor/pkg/log"
+ "gvisor.dev/gvisor/pkg/sentry/control"
+ "gvisor.dev/gvisor/pkg/sentry/kernel/auth"
+ "gvisor.dev/gvisor/pkg/urpc"
+ "gvisor.dev/gvisor/runsc/boot"
+ "gvisor.dev/gvisor/runsc/console"
+ "gvisor.dev/gvisor/runsc/container"
+ "gvisor.dev/gvisor/runsc/specutils"
)
// Exec implements subcommands.Command for the "exec" command.
@@ -235,7 +235,11 @@ func (ex *Exec) execChildAndWait(waitStatus *syscall.WaitStatus) subcommands.Exi
cmd.SysProcAttr = &syscall.SysProcAttr{
Setsid: true,
Setctty: true,
- Ctty: int(tty.Fd()),
+ // The Ctty FD must be the FD in the child process's FD
+ // table. Since we set cmd.Stdin/Stdout/Stderr to the
+ // tty FD, we can use any of 0, 1, or 2 here.
+ // See https://github.com/golang/go/issues/29458.
+ Ctty: 0,
}
}
diff --git a/runsc/cmd/exec_test.go b/runsc/cmd/exec_test.go
index 6f0f258c0..eb38a431f 100644
--- a/runsc/cmd/exec_test.go
+++ b/runsc/cmd/exec_test.go
@@ -21,10 +21,10 @@ import (
"github.com/google/go-cmp/cmp"
"github.com/google/go-cmp/cmp/cmpopts"
specs "github.com/opencontainers/runtime-spec/specs-go"
- "gvisor.googlesource.com/gvisor/pkg/abi/linux"
- "gvisor.googlesource.com/gvisor/pkg/sentry/control"
- "gvisor.googlesource.com/gvisor/pkg/sentry/kernel/auth"
- "gvisor.googlesource.com/gvisor/pkg/urpc"
+ "gvisor.dev/gvisor/pkg/abi/linux"
+ "gvisor.dev/gvisor/pkg/sentry/control"
+ "gvisor.dev/gvisor/pkg/sentry/kernel/auth"
+ "gvisor.dev/gvisor/pkg/urpc"
)
func TestUser(t *testing.T) {
diff --git a/runsc/cmd/gofer.go b/runsc/cmd/gofer.go
index bccb29397..9faabf494 100644
--- a/runsc/cmd/gofer.go
+++ b/runsc/cmd/gofer.go
@@ -27,13 +27,13 @@ import (
"flag"
"github.com/google/subcommands"
specs "github.com/opencontainers/runtime-spec/specs-go"
- "gvisor.googlesource.com/gvisor/pkg/log"
- "gvisor.googlesource.com/gvisor/pkg/p9"
- "gvisor.googlesource.com/gvisor/pkg/unet"
- "gvisor.googlesource.com/gvisor/runsc/boot"
- "gvisor.googlesource.com/gvisor/runsc/fsgofer"
- "gvisor.googlesource.com/gvisor/runsc/fsgofer/filter"
- "gvisor.googlesource.com/gvisor/runsc/specutils"
+ "gvisor.dev/gvisor/pkg/log"
+ "gvisor.dev/gvisor/pkg/p9"
+ "gvisor.dev/gvisor/pkg/unet"
+ "gvisor.dev/gvisor/runsc/boot"
+ "gvisor.dev/gvisor/runsc/fsgofer"
+ "gvisor.dev/gvisor/runsc/fsgofer/filter"
+ "gvisor.dev/gvisor/runsc/specutils"
)
var caps = []string{
@@ -152,6 +152,10 @@ func (g *Gofer) Execute(_ context.Context, f *flag.FlagSet, args ...interface{})
// modes exactly as sent by the sandbox, which will have applied its own umask.
syscall.Umask(0)
+ if err := fsgofer.OpenProcSelfFD(); err != nil {
+ Fatalf("failed to open /proc/self/fd: %v", err)
+ }
+
if err := syscall.Chroot(root); err != nil {
Fatalf("failed to chroot to %q: %v", root, err)
}
diff --git a/runsc/cmd/kill.go b/runsc/cmd/kill.go
index aed5f3291..6c1f197a6 100644
--- a/runsc/cmd/kill.go
+++ b/runsc/cmd/kill.go
@@ -24,8 +24,8 @@ import (
"flag"
"github.com/google/subcommands"
"golang.org/x/sys/unix"
- "gvisor.googlesource.com/gvisor/runsc/boot"
- "gvisor.googlesource.com/gvisor/runsc/container"
+ "gvisor.dev/gvisor/runsc/boot"
+ "gvisor.dev/gvisor/runsc/container"
)
// Kill implements subcommands.Command for the "kill" command.
diff --git a/runsc/cmd/list.go b/runsc/cmd/list.go
index 1f5ca2473..dd2d99a6b 100644
--- a/runsc/cmd/list.go
+++ b/runsc/cmd/list.go
@@ -25,8 +25,8 @@ import (
"flag"
"github.com/google/subcommands"
specs "github.com/opencontainers/runtime-spec/specs-go"
- "gvisor.googlesource.com/gvisor/runsc/boot"
- "gvisor.googlesource.com/gvisor/runsc/container"
+ "gvisor.dev/gvisor/runsc/boot"
+ "gvisor.dev/gvisor/runsc/container"
)
// List implements subcommands.Command for the "list" command for the "list" command.
diff --git a/runsc/cmd/pause.go b/runsc/cmd/pause.go
index 11b36aa10..9c0e92001 100644
--- a/runsc/cmd/pause.go
+++ b/runsc/cmd/pause.go
@@ -19,8 +19,8 @@ import (
"flag"
"github.com/google/subcommands"
- "gvisor.googlesource.com/gvisor/runsc/boot"
- "gvisor.googlesource.com/gvisor/runsc/container"
+ "gvisor.dev/gvisor/runsc/boot"
+ "gvisor.dev/gvisor/runsc/container"
)
// Pause implements subcommands.Command for the "pause" command.
diff --git a/runsc/cmd/ps.go b/runsc/cmd/ps.go
index 3a3e6f17a..45c644f3f 100644
--- a/runsc/cmd/ps.go
+++ b/runsc/cmd/ps.go
@@ -20,9 +20,9 @@ import (
"flag"
"github.com/google/subcommands"
- "gvisor.googlesource.com/gvisor/pkg/sentry/control"
- "gvisor.googlesource.com/gvisor/runsc/boot"
- "gvisor.googlesource.com/gvisor/runsc/container"
+ "gvisor.dev/gvisor/pkg/sentry/control"
+ "gvisor.dev/gvisor/runsc/boot"
+ "gvisor.dev/gvisor/runsc/container"
)
// PS implements subcommands.Command for the "ps" command.
diff --git a/runsc/cmd/restore.go b/runsc/cmd/restore.go
index 3ab2f5676..7be60cd7d 100644
--- a/runsc/cmd/restore.go
+++ b/runsc/cmd/restore.go
@@ -21,9 +21,9 @@ import (
"flag"
"github.com/google/subcommands"
- "gvisor.googlesource.com/gvisor/runsc/boot"
- "gvisor.googlesource.com/gvisor/runsc/container"
- "gvisor.googlesource.com/gvisor/runsc/specutils"
+ "gvisor.dev/gvisor/runsc/boot"
+ "gvisor.dev/gvisor/runsc/container"
+ "gvisor.dev/gvisor/runsc/specutils"
)
// Restore implements subcommands.Command for the "restore" command.
@@ -80,25 +80,38 @@ func (r *Restore) Execute(_ context.Context, f *flag.FlagSet, args ...interface{
conf := args[0].(*boot.Config)
waitStatus := args[1].(*syscall.WaitStatus)
+ if conf.Rootless {
+ return Errorf("Rootless mode not supported with %q", r.Name())
+ }
+
bundleDir := r.bundleDir
if bundleDir == "" {
bundleDir = getwdOrDie()
}
spec, err := specutils.ReadSpec(bundleDir)
if err != nil {
- Fatalf("reading spec: %v", err)
+ return Errorf("reading spec: %v", err)
}
specutils.LogSpec(spec)
if r.imagePath == "" {
- Fatalf("image-path flag must be provided")
+ return Errorf("image-path flag must be provided")
}
conf.RestoreFile = filepath.Join(r.imagePath, checkpointFileName)
- ws, err := container.Run(id, spec, conf, bundleDir, r.consoleSocket, r.pidFile, r.userLog, r.detach)
+ runArgs := container.Args{
+ ID: id,
+ Spec: spec,
+ BundleDir: bundleDir,
+ ConsoleSocket: r.consoleSocket,
+ PIDFile: r.pidFile,
+ UserLog: r.userLog,
+ Attached: !r.detach,
+ }
+ ws, err := container.Run(conf, runArgs)
if err != nil {
- Fatalf("running container: %v", err)
+ return Errorf("running container: %v", err)
}
*waitStatus = ws
diff --git a/runsc/cmd/resume.go b/runsc/cmd/resume.go
index 9a2ade41e..b2df5c640 100644
--- a/runsc/cmd/resume.go
+++ b/runsc/cmd/resume.go
@@ -19,8 +19,8 @@ import (
"flag"
"github.com/google/subcommands"
- "gvisor.googlesource.com/gvisor/runsc/boot"
- "gvisor.googlesource.com/gvisor/runsc/container"
+ "gvisor.dev/gvisor/runsc/boot"
+ "gvisor.dev/gvisor/runsc/container"
)
// Resume implements subcommands.Command for the "resume" command.
diff --git a/runsc/cmd/run.go b/runsc/cmd/run.go
index c228b4f93..33f4bc12b 100644
--- a/runsc/cmd/run.go
+++ b/runsc/cmd/run.go
@@ -20,9 +20,9 @@ import (
"flag"
"github.com/google/subcommands"
- "gvisor.googlesource.com/gvisor/runsc/boot"
- "gvisor.googlesource.com/gvisor/runsc/container"
- "gvisor.googlesource.com/gvisor/runsc/specutils"
+ "gvisor.dev/gvisor/runsc/boot"
+ "gvisor.dev/gvisor/runsc/container"
+ "gvisor.dev/gvisor/runsc/specutils"
)
// Run implements subcommands.Command for the "run" command.
@@ -67,19 +67,32 @@ func (r *Run) Execute(_ context.Context, f *flag.FlagSet, args ...interface{}) s
conf := args[0].(*boot.Config)
waitStatus := args[1].(*syscall.WaitStatus)
+ if conf.Rootless {
+ return Errorf("Rootless mode not supported with %q", r.Name())
+ }
+
bundleDir := r.bundleDir
if bundleDir == "" {
bundleDir = getwdOrDie()
}
spec, err := specutils.ReadSpec(bundleDir)
if err != nil {
- Fatalf("reading spec: %v", err)
+ return Errorf("reading spec: %v", err)
}
specutils.LogSpec(spec)
- ws, err := container.Run(id, spec, conf, bundleDir, r.consoleSocket, r.pidFile, r.userLog, r.detach)
+ runArgs := container.Args{
+ ID: id,
+ Spec: spec,
+ BundleDir: bundleDir,
+ ConsoleSocket: r.consoleSocket,
+ PIDFile: r.pidFile,
+ UserLog: r.userLog,
+ Attached: !r.detach,
+ }
+ ws, err := container.Run(conf, runArgs)
if err != nil {
- Fatalf("running container: %v", err)
+ return Errorf("running container: %v", err)
}
*waitStatus = ws
diff --git a/runsc/cmd/start.go b/runsc/cmd/start.go
index 31e8f42bb..de2115dff 100644
--- a/runsc/cmd/start.go
+++ b/runsc/cmd/start.go
@@ -18,8 +18,8 @@ import (
"context"
"flag"
"github.com/google/subcommands"
- "gvisor.googlesource.com/gvisor/runsc/boot"
- "gvisor.googlesource.com/gvisor/runsc/container"
+ "gvisor.dev/gvisor/runsc/boot"
+ "gvisor.dev/gvisor/runsc/container"
)
// Start implements subcommands.Command for the "start" command.
diff --git a/runsc/cmd/state.go b/runsc/cmd/state.go
index f0d449b19..e9f41cbd8 100644
--- a/runsc/cmd/state.go
+++ b/runsc/cmd/state.go
@@ -21,9 +21,9 @@ import (
"flag"
"github.com/google/subcommands"
- "gvisor.googlesource.com/gvisor/pkg/log"
- "gvisor.googlesource.com/gvisor/runsc/boot"
- "gvisor.googlesource.com/gvisor/runsc/container"
+ "gvisor.dev/gvisor/pkg/log"
+ "gvisor.dev/gvisor/runsc/boot"
+ "gvisor.dev/gvisor/runsc/container"
)
// State implements subcommands.Command for the "state" command.
diff --git a/runsc/cmd/syscalls.go b/runsc/cmd/syscalls.go
index 9c8a66490..fb6c1ab29 100644
--- a/runsc/cmd/syscalls.go
+++ b/runsc/cmd/syscalls.go
@@ -27,7 +27,7 @@ import (
"flag"
"github.com/google/subcommands"
- "gvisor.googlesource.com/gvisor/pkg/sentry/kernel"
+ "gvisor.dev/gvisor/pkg/sentry/kernel"
)
// Syscalls implements subcommands.Command for the "syscalls" command.
@@ -41,7 +41,7 @@ type Syscalls struct {
// Maps operating system to architecture to ArchInfo.
type CompatibilityInfo map[string]map[string]ArchInfo
-// ArchInfo is compatbility doc for an architecture.
+// ArchInfo is compatibility doc for an architecture.
type ArchInfo struct {
// Syscalls maps syscall number for the architecture to the doc.
Syscalls map[uintptr]SyscallDoc `json:"syscalls"`
diff --git a/runsc/cmd/wait.go b/runsc/cmd/wait.go
index 58fd01974..046489687 100644
--- a/runsc/cmd/wait.go
+++ b/runsc/cmd/wait.go
@@ -22,8 +22,8 @@ import (
"flag"
"github.com/google/subcommands"
- "gvisor.googlesource.com/gvisor/runsc/boot"
- "gvisor.googlesource.com/gvisor/runsc/container"
+ "gvisor.dev/gvisor/runsc/boot"
+ "gvisor.dev/gvisor/runsc/container"
)
const (