diff --git a/runsc/cli/BUILD b/runsc/cli/BUILD index 360e3cea6..f2ae169e5 100644 --- a/runsc/cli/BUILD +++ b/runsc/cli/BUILD @@ -16,6 +16,7 @@ go_library( "//pkg/refsvfs2", "//pkg/sentry/platform", "//runsc/cmd", + "//runsc/cmd/util", "//runsc/config", "//runsc/flag", "//runsc/specutils", diff --git a/runsc/cli/main.go b/runsc/cli/main.go index cccd1cb96..550bc6f10 100644 --- a/runsc/cli/main.go +++ b/runsc/cli/main.go @@ -33,6 +33,7 @@ import ( "gvisor.dev/gvisor/pkg/refsvfs2" "gvisor.dev/gvisor/pkg/sentry/platform" "gvisor.dev/gvisor/runsc/cmd" + "gvisor.dev/gvisor/runsc/cmd/util" "gvisor.dev/gvisor/runsc/config" "gvisor.dev/gvisor/runsc/flag" "gvisor.dev/gvisor/runsc/specutils" @@ -115,7 +116,7 @@ func Main(version string) { // Create a new Config from the flags. conf, err := config.NewFromFlags(flag.CommandLine) if err != nil { - cmd.Fatalf(err.Error()) + util.Fatalf(err.Error()) } var errorLogger io.Writer @@ -129,13 +130,13 @@ func Main(version string) { var err error errorLogger, err = os.OpenFile(conf.LogFilename, os.O_WRONLY|os.O_CREATE|os.O_APPEND, 0644) if err != nil { - cmd.Fatalf("error opening log file %q: %v", conf.LogFilename, err) + util.Fatalf("error opening log file %q: %v", conf.LogFilename, err) } } - cmd.ErrorLogger = errorLogger + util.ErrorLogger = errorLogger if _, err := platform.Lookup(conf.Platform); err != nil { - cmd.Fatalf("%v", err) + util.Fatalf("%v", err) } // Sets the reference leak check mode. Also set it in config below to @@ -170,7 +171,7 @@ func Main(version string) { } else if conf.DebugLog != "" { f, err := specutils.DebugLogFile(conf.DebugLog, subcommand, "" /* name */) if err != nil { - cmd.Fatalf("error opening debug log file in %q: %v", conf.DebugLog, err) + util.Fatalf("error opening debug log file in %q: %v", conf.DebugLog, err) } e = newEmitter(conf.DebugLogFormat, f) @@ -188,7 +189,7 @@ func Main(version string) { // Quick sanity check to make sure no other commands get passed // a log fd (they should use log dir instead). if subcommand != "boot" && subcommand != "gofer" { - cmd.Fatalf("flags --debug-log-fd and --panic-log-fd should only be passed to 'boot' and 'gofer' command, but was passed to %q", subcommand) + util.Fatalf("flags --debug-log-fd and --panic-log-fd should only be passed to 'boot' and 'gofer' command, but was passed to %q", subcommand) } // If we are the boot process, then we own our stdio FDs and can do what we @@ -196,7 +197,7 @@ func Main(version string) { // dup our stderr to the provided log FD so that panics will appear in the // logs, rather than just disappear. if err := unix.Dup3(fd, int(os.Stderr.Fd()), 0); err != nil { - cmd.Fatalf("error dup'ing fd %d to stderr: %v", fd, err) + util.Fatalf("error dup'ing fd %d to stderr: %v", fd, err) } } else if conf.AlsoLogToStderr { e = &log.MultiEmitter{e, newEmitter(conf.DebugLogFormat, os.Stderr)} @@ -262,6 +263,6 @@ func newEmitter(format string, logFile io.Writer) log.Emitter { case "json-k8s": return log.K8sJSONEmitter{&log.Writer{Next: logFile}} } - cmd.Fatalf("invalid log format %q, must be 'text', 'json', or 'json-k8s'", format) + util.Fatalf("invalid log format %q, must be 'text', 'json', or 'json-k8s'", format) panic("unreachable") } diff --git a/runsc/cmd/BUILD b/runsc/cmd/BUILD index 829ed3af8..aedf1947c 100644 --- a/runsc/cmd/BUILD +++ b/runsc/cmd/BUILD @@ -14,7 +14,6 @@ go_library( "debug.go", "delete.go", "do.go", - "error.go", "events.go", "exec.go", "gofer.go", @@ -59,6 +58,7 @@ go_library( "//pkg/unet", "//pkg/urpc", "//runsc/boot", + "//runsc/cmd/util", "//runsc/config", "//runsc/console", "//runsc/container", @@ -95,6 +95,7 @@ go_test( "//pkg/sentry/kernel/auth", "//pkg/test/testutil", "//pkg/urpc", + "//runsc/cmd/util", "//runsc/config", "//runsc/container", "//runsc/mitigate", diff --git a/runsc/cmd/boot.go b/runsc/cmd/boot.go index 676b0189e..a389dcac7 100644 --- a/runsc/cmd/boot.go +++ b/runsc/cmd/boot.go @@ -28,6 +28,7 @@ import ( "gvisor.dev/gvisor/pkg/log" "gvisor.dev/gvisor/pkg/sentry/platform" "gvisor.dev/gvisor/runsc/boot" + "gvisor.dev/gvisor/runsc/cmd/util" "gvisor.dev/gvisor/runsc/config" "gvisor.dev/gvisor/runsc/flag" "gvisor.dev/gvisor/runsc/specutils" @@ -190,13 +191,13 @@ func (b *Boot) Execute(_ context.Context, f *flag.FlagSet, args ...interface{}) // attached mode is enabled. In the unfortunate event that the parent // terminates before this point, this process leaks. if err := unix.Prctl(unix.PR_SET_PDEATHSIG, uintptr(unix.SIGKILL), 0, 0, 0); err != nil { - Fatalf("error setting parent death signal: %v", err) + util.Fatalf("error setting parent death signal: %v", err) } } if b.setUpRoot { if err := setUpChroot(b.pidns); err != nil { - Fatalf("error setting up chroot: %v", err) + util.Fatalf("error setting up chroot: %v", err) } if !b.applyCaps && !conf.Rootless { @@ -207,7 +208,7 @@ func (b *Boot) Execute(_ context.Context, f *flag.FlagSet, args ...interface{}) // we will read it again after the exec call. This works // because the ReadSpecFromFile function seeks to the beginning // of the file before reading. - Fatalf("callSelfAsNobody(%v): %v", args, callSelfAsNobody(args)) + util.Fatalf("callSelfAsNobody(%v): %v", args, callSelfAsNobody(args)) panic("unreachable") } } @@ -217,7 +218,7 @@ func (b *Boot) Execute(_ context.Context, f *flag.FlagSet, args ...interface{}) defer specFile.Close() spec, err := specutils.ReadSpecFromFile(b.bundleDir, specFile, conf) if err != nil { - Fatalf("reading spec: %v", err) + util.Fatalf("reading spec: %v", err) } specutils.LogSpec(spec) @@ -229,7 +230,7 @@ func (b *Boot) Execute(_ context.Context, f *flag.FlagSet, args ...interface{}) gPlatform, err := platform.Lookup(conf.Platform) if err != nil { - Fatalf("loading platform: %v", err) + util.Fatalf("loading platform: %v", err) } if gPlatform.Requirements().RequiresCapSysPtrace { // Ptrace platform requires extra capabilities. @@ -247,7 +248,7 @@ func (b *Boot) Execute(_ context.Context, f *flag.FlagSet, args ...interface{}) // we will read it again after the exec call. This works // because the ReadSpecFromFile function seeks to the beginning // of the file before reading. - Fatalf("setCapsAndCallSelf(%v, %v): %v", args, caps, setCapsAndCallSelf(args, caps)) + util.Fatalf("setCapsAndCallSelf(%v, %v): %v", args, caps, setCapsAndCallSelf(args, caps)) panic("unreachable") } @@ -256,24 +257,24 @@ func (b *Boot) Execute(_ context.Context, f *flag.FlagSet, args ...interface{}) cleanMounts, err := specutils.ReadMounts(mountsFile) if err != nil { mountsFile.Close() - Fatalf("Error reading mounts file: %v", err) + util.Fatalf("Error reading mounts file: %v", err) } mountsFile.Close() spec.Mounts = cleanMounts if conf.EnableCoreTags { if err := coretag.Enable(); err != nil { - Fatalf("Failed to core tag sentry: %v", err) + util.Fatalf("Failed to core tag sentry: %v", err) } // Verify that all sentry threads are properly core tagged, and log // current core tag. coreTags, err := coretag.GetAllCoreTags(os.Getpid()) if err != nil { - Fatalf("Failed read current core tags: %v", err) + util.Fatalf("Failed read current core tags: %v", err) } if len(coreTags) != 1 { - Fatalf("Not all child threads were core tagged the same. Tags=%v", coreTags) + util.Fatalf("Not all child threads were core tagged the same. Tags=%v", coreTags) } log.Infof("Core tag enabled (core tag=%d)", coreTags[0]) } @@ -301,7 +302,7 @@ func (b *Boot) Execute(_ context.Context, f *flag.FlagSet, args ...interface{}) } l, err := boot.New(bootArgs) if err != nil { - Fatalf("creating loader: %v", err) + util.Fatalf("creating loader: %v", err) } // Fatalf exits the process and doesn't run defers. @@ -313,7 +314,7 @@ func (b *Boot) Execute(_ context.Context, f *flag.FlagSet, args ...interface{}) buf := make([]byte, 1) if w, err := startSyncFile.Write(buf); err != nil || w != 1 { l.Destroy() - Fatalf("unable to write into the start-sync descriptor: %v", err) + util.Fatalf("unable to write into the start-sync descriptor: %v", err) } // Closes startSyncFile because 'l.Run()' only returns when the sandbox exits. startSyncFile.Close() @@ -324,7 +325,7 @@ func (b *Boot) Execute(_ context.Context, f *flag.FlagSet, args ...interface{}) // Run the application and wait for it to finish. if err := l.Run(); err != nil { l.Destroy() - Fatalf("running sandbox: %v", err) + util.Fatalf("running sandbox: %v", err) } ws := l.WaitExit() diff --git a/runsc/cmd/checkpoint.go b/runsc/cmd/checkpoint.go index a9dbe86de..4d73ebd11 100644 --- a/runsc/cmd/checkpoint.go +++ b/runsc/cmd/checkpoint.go @@ -22,6 +22,7 @@ import ( "github.com/google/subcommands" "golang.org/x/sys/unix" "gvisor.dev/gvisor/pkg/log" + "gvisor.dev/gvisor/runsc/cmd/util" "gvisor.dev/gvisor/runsc/config" "gvisor.dev/gvisor/runsc/container" "gvisor.dev/gvisor/runsc/flag" @@ -77,15 +78,15 @@ func (c *Checkpoint) Execute(_ context.Context, f *flag.FlagSet, args ...interfa cont, err := container.Load(conf.RootDir, container.FullID{ContainerID: id}, container.LoadOpts{}) if err != nil { - Fatalf("loading container: %v", err) + util.Fatalf("loading container: %v", err) } if c.imagePath == "" { - Fatalf("image-path flag must be provided") + util.Fatalf("image-path flag must be provided") } if err := os.MkdirAll(c.imagePath, 0755); err != nil { - Fatalf("making directories at path provided: %v", err) + util.Fatalf("making directories at path provided: %v", err) } fullImagePath := filepath.Join(c.imagePath, checkpointFileName) @@ -93,12 +94,12 @@ func (c *Checkpoint) Execute(_ context.Context, f *flag.FlagSet, args ...interfa // Create the image file and open for writing. file, err := os.OpenFile(fullImagePath, os.O_CREATE|os.O_EXCL|os.O_RDWR, 0644) if err != nil { - Fatalf("os.OpenFile(%q) failed: %v", fullImagePath, err) + util.Fatalf("os.OpenFile(%q) failed: %v", fullImagePath, err) } defer file.Close() if err := cont.Checkpoint(file); err != nil { - Fatalf("checkpoint failed: %v", err) + util.Fatalf("checkpoint failed: %v", err) } if !c.leaveRunning { @@ -115,12 +116,12 @@ func (c *Checkpoint) Execute(_ context.Context, f *flag.FlagSet, args ...interfa // Restore into new container with same ID. bundleDir := cont.BundleDir if bundleDir == "" { - Fatalf("setting bundleDir") + util.Fatalf("setting bundleDir") } spec, err := specutils.ReadSpec(bundleDir, conf) if err != nil { - Fatalf("reading spec: %v", err) + util.Fatalf("reading spec: %v", err) } specutils.LogSpec(spec) @@ -130,7 +131,7 @@ func (c *Checkpoint) Execute(_ context.Context, f *flag.FlagSet, args ...interfa } if err := cont.Destroy(); err != nil { - Fatalf("destroying container: %v", err) + util.Fatalf("destroying container: %v", err) } contArgs := container.Args{ @@ -140,17 +141,17 @@ func (c *Checkpoint) Execute(_ context.Context, f *flag.FlagSet, args ...interfa } cont, err = container.New(conf, contArgs) if err != nil { - Fatalf("restoring container: %v", err) + util.Fatalf("restoring container: %v", err) } defer cont.Destroy() if err := cont.Restore(spec, conf, fullImagePath); err != nil { - Fatalf("starting container: %v", err) + util.Fatalf("starting container: %v", err) } ws, err := cont.Wait() if err != nil { - Fatalf("Error waiting for container: %v", err) + util.Fatalf("Error waiting for container: %v", err) } *waitStatus = ws diff --git a/runsc/cmd/create.go b/runsc/cmd/create.go index e76f7ba1d..9c4a5663b 100644 --- a/runsc/cmd/create.go +++ b/runsc/cmd/create.go @@ -18,6 +18,7 @@ import ( "context" "github.com/google/subcommands" + "gvisor.dev/gvisor/runsc/cmd/util" "gvisor.dev/gvisor/runsc/config" "gvisor.dev/gvisor/runsc/container" "gvisor.dev/gvisor/runsc/flag" @@ -84,7 +85,7 @@ func (c *Create) Execute(_ context.Context, f *flag.FlagSet, args ...interface{} conf := args[0].(*config.Config) if conf.Rootless { - return Errorf("Rootless mode not supported with %q", c.Name()) + return util.Errorf("Rootless mode not supported with %q", c.Name()) } bundleDir := c.bundleDir @@ -93,7 +94,7 @@ func (c *Create) Execute(_ context.Context, f *flag.FlagSet, args ...interface{} } spec, err := specutils.ReadSpec(bundleDir, conf) if err != nil { - return Errorf("reading spec: %v", err) + return util.Errorf("reading spec: %v", err) } specutils.LogSpec(spec) @@ -109,7 +110,7 @@ func (c *Create) Execute(_ context.Context, f *flag.FlagSet, args ...interface{} UserLog: c.userLog, } if _, err := container.New(conf, contArgs); err != nil { - return Errorf("creating container: %v", err) + return util.Errorf("creating container: %v", err) } return subcommands.ExitSuccess } diff --git a/runsc/cmd/debug.go b/runsc/cmd/debug.go index 3f6c1bbcd..dae7f5542 100644 --- a/runsc/cmd/debug.go +++ b/runsc/cmd/debug.go @@ -27,6 +27,7 @@ import ( "golang.org/x/sys/unix" "gvisor.dev/gvisor/pkg/log" "gvisor.dev/gvisor/pkg/sentry/control" + "gvisor.dev/gvisor/runsc/cmd/util" "gvisor.dev/gvisor/runsc/config" "gvisor.dev/gvisor/runsc/container" "gvisor.dev/gvisor/runsc/flag" @@ -91,10 +92,10 @@ func (d *Debug) Execute(_ context.Context, f *flag.FlagSet, args ...interface{}) conf := args[0].(*config.Config) if conf.ProfileBlock != "" || conf.ProfileCPU != "" || conf.ProfileHeap != "" || conf.ProfileMutex != "" { - return Errorf("global -profile-{block,cpu,heap,mutex} flags have no effect on runsc debug. Pass runsc debug -profile-{block,cpu,heap,mutex} instead") + return util.Errorf("global -profile-{block,cpu,heap,mutex} flags have no effect on runsc debug. Pass runsc debug -profile-{block,cpu,heap,mutex} instead") } if conf.TraceFile != "" { - return Errorf("global -trace flag has no effect on runsc debug. Pass runsc debug -trace instead") + return util.Errorf("global -trace flag has no effect on runsc debug. Pass runsc debug -trace instead") } if d.pid == 0 { @@ -108,7 +109,7 @@ func (d *Debug) Execute(_ context.Context, f *flag.FlagSet, args ...interface{}) var err error c, err = container.Load(conf.RootDir, container.FullID{ContainerID: id}, container.LoadOpts{}) if err != nil { - return Errorf("loading container %q: %v", f.Arg(0), err) + return util.Errorf("loading container %q: %v", f.Arg(0), err) } } else { if f.NArg() != 0 { @@ -118,7 +119,7 @@ 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 { - return Errorf("listing containers: %v", err) + return util.Errorf("listing containers: %v", err) } for _, id := range ids { candidate, err := container.Load(conf.RootDir, id, container.LoadOpts{Exact: true, SkipCheck: true}) @@ -132,12 +133,12 @@ func (d *Debug) Execute(_ context.Context, f *flag.FlagSet, args ...interface{}) } } if c == nil { - return Errorf("container with PID %d not found", d.pid) + return util.Errorf("container with PID %d not found", d.pid) } } if !c.IsSandboxRunning() { - return Errorf("container sandbox is not running") + return util.Errorf("container sandbox is not running") } log.Infof("Found sandbox %q, PID: %d", c.Sandbox.ID, c.Sandbox.Getpid()) @@ -146,14 +147,14 @@ func (d *Debug) Execute(_ context.Context, f *flag.FlagSet, args ...interface{}) pid := c.Sandbox.Getpid() log.Infof("Sending signal %d to process: %d", d.signal, pid) if err := unix.Kill(pid, unix.Signal(d.signal)); err != nil { - return Errorf("failed to send signal %d to processs %d", d.signal, pid) + return util.Errorf("failed to send signal %d to processs %d", d.signal, pid) } } if d.stacks { log.Infof("Retrieving sandbox stacks") stacks, err := c.Sandbox.Stacks() if err != nil { - return Errorf("retrieving stacks: %v", err) + return util.Errorf("retrieving stacks: %v", err) } log.Infof(" *** Stack dump ***\n%s", stacks) } @@ -189,7 +190,7 @@ func (d *Debug) Execute(_ context.Context, f *flag.FlagSet, args ...interface{}) case "debug", "2": args.Level = log.Debug default: - return Errorf("invalid log level %q", d.logLevel) + return util.Errorf("invalid log level %q", d.logLevel) } log.Infof("Setting log level %v", args.Level) } @@ -198,7 +199,7 @@ func (d *Debug) Execute(_ context.Context, f *flag.FlagSet, args ...interface{}) args.SetLogPackets = true lp, err := strconv.ParseBool(d.logPackets) if err != nil { - return Errorf("invalid value for log_packets %q", d.logPackets) + return util.Errorf("invalid value for log_packets %q", d.logPackets) } args.LogPackets = lp if args.LogPackets { @@ -209,18 +210,18 @@ func (d *Debug) Execute(_ context.Context, f *flag.FlagSet, args ...interface{}) } if err := c.Sandbox.ChangeLogging(args); err != nil { - return Errorf(err.Error()) + return util.Errorf(err.Error()) } log.Infof("Logging options changed") } if d.ps { pList, err := c.Processes() if err != nil { - Fatalf("getting processes for container: %v", err) + util.Fatalf("getting processes for container: %v", err) } o, err := control.ProcessListToJSON(pList) if err != nil { - Fatalf("generating JSON: %v", err) + util.Fatalf("generating JSON: %v", err) } log.Infof(o) } @@ -236,7 +237,7 @@ func (d *Debug) Execute(_ context.Context, f *flag.FlagSet, args ...interface{}) if d.profileBlock != "" { f, err := os.OpenFile(d.profileBlock, os.O_CREATE|os.O_WRONLY|os.O_TRUNC, 0644) if err != nil { - return Errorf("error opening blocking profile output: %v", err) + return util.Errorf("error opening blocking profile output: %v", err) } defer f.Close() blockFile = f @@ -244,7 +245,7 @@ func (d *Debug) Execute(_ context.Context, f *flag.FlagSet, args ...interface{}) if d.profileCPU != "" { f, err := os.OpenFile(d.profileCPU, os.O_CREATE|os.O_WRONLY|os.O_TRUNC, 0644) if err != nil { - return Errorf("error opening cpu profile output: %v", err) + return util.Errorf("error opening cpu profile output: %v", err) } defer f.Close() cpuFile = f @@ -252,7 +253,7 @@ func (d *Debug) Execute(_ context.Context, f *flag.FlagSet, args ...interface{}) if d.profileHeap != "" { f, err := os.OpenFile(d.profileHeap, os.O_CREATE|os.O_WRONLY|os.O_TRUNC, 0644) if err != nil { - return Errorf("error opening heap profile output: %v", err) + return util.Errorf("error opening heap profile output: %v", err) } defer f.Close() heapFile = f @@ -260,7 +261,7 @@ func (d *Debug) Execute(_ context.Context, f *flag.FlagSet, args ...interface{}) if d.profileMutex != "" { f, err := os.OpenFile(d.profileMutex, os.O_CREATE|os.O_WRONLY|os.O_TRUNC, 0644) if err != nil { - return Errorf("error opening mutex profile output: %v", err) + return util.Errorf("error opening mutex profile output: %v", err) } defer f.Close() mutexFile = f @@ -268,7 +269,7 @@ func (d *Debug) Execute(_ context.Context, f *flag.FlagSet, args ...interface{}) if d.trace != "" { f, err := os.OpenFile(d.trace, os.O_CREATE|os.O_WRONLY|os.O_TRUNC, 0644) if err != nil { - return Errorf("error opening trace profile output: %v", err) + return util.Errorf("error opening trace profile output: %v", err) } traceFile = f } @@ -379,7 +380,7 @@ func (d *Debug) Execute(_ context.Context, f *flag.FlagSet, args ...interface{}) if d.cat != nil { if err := c.Cat(d.cat, os.Stdout); err != nil { - return Errorf("Cat failed: %v", err) + return util.Errorf("Cat failed: %v", err) } } diff --git a/runsc/cmd/delete.go b/runsc/cmd/delete.go index a750be131..39bd0aaee 100644 --- a/runsc/cmd/delete.go +++ b/runsc/cmd/delete.go @@ -21,6 +21,7 @@ import ( "github.com/google/subcommands" "gvisor.dev/gvisor/pkg/log" + "gvisor.dev/gvisor/runsc/cmd/util" "gvisor.dev/gvisor/runsc/config" "gvisor.dev/gvisor/runsc/container" "gvisor.dev/gvisor/runsc/flag" @@ -61,7 +62,7 @@ func (d *Delete) Execute(_ context.Context, f *flag.FlagSet, args ...interface{} conf := args[0].(*config.Config) if err := d.execute(f.Args(), conf); err != nil { - Fatalf("%v", err) + util.Fatalf("%v", err) } return subcommands.ExitSuccess } diff --git a/runsc/cmd/do.go b/runsc/cmd/do.go index ffbebca03..977fdf27d 100644 --- a/runsc/cmd/do.go +++ b/runsc/cmd/do.go @@ -31,6 +31,7 @@ import ( specs "github.com/opencontainers/runtime-spec/specs-go" "golang.org/x/sys/unix" "gvisor.dev/gvisor/pkg/log" + "gvisor.dev/gvisor/runsc/cmd/util" "gvisor.dev/gvisor/runsc/config" "gvisor.dev/gvisor/runsc/container" "gvisor.dev/gvisor/runsc/flag" @@ -92,25 +93,25 @@ func (c *Do) Execute(_ context.Context, f *flag.FlagSet, args ...interface{}) su if conf.Rootless { if err := specutils.MaybeRunAsRoot(); err != nil { - return Errorf("Error executing inside namespace: %v", err) + return util.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) + return util.Errorf("Error to retrieve hostname: %v", err) } // Map the entire host file system, optionally using an overlay. conf.Overlay = c.overlay absRoot, err := resolvePath(c.root) if err != nil { - return Errorf("Error resolving root: %v", err) + return util.Errorf("Error resolving root: %v", err) } absCwd, err := resolvePath(c.cwd) if err != nil { - return Errorf("Error resolving current directory: %v", err) + return util.Errorf("Error resolving current directory: %v", err) } spec := &specs.Spec{ @@ -148,7 +149,7 @@ func (c *Do) Execute(_ context.Context, f *flag.FlagSet, args ...interface{}) su defer clean() default: - return Errorf("Error setting up network: %v", err) + return util.Errorf("Error setting up network: %v", err) } } @@ -356,11 +357,11 @@ func startContainerAndWait(spec *specs.Spec, conf *config.Config, cid string, wa out, err := json.Marshal(spec) if err != nil { - return Errorf("Error to marshal spec: %v", err) + return util.Errorf("Error to marshal spec: %v", err) } tmpDir, err := ioutil.TempDir("", "runsc-do") if err != nil { - return Errorf("Error to create tmp dir: %v", err) + return util.Errorf("Error to create tmp dir: %v", err) } defer os.RemoveAll(tmpDir) @@ -369,7 +370,7 @@ func startContainerAndWait(spec *specs.Spec, conf *config.Config, cid string, wa cfgPath := filepath.Join(tmpDir, "config.json") if err := ioutil.WriteFile(cfgPath, out, 0755); err != nil { - return Errorf("Error write spec: %v", err) + return util.Errorf("Error write spec: %v", err) } containerArgs := container.Args{ @@ -381,12 +382,12 @@ func startContainerAndWait(spec *specs.Spec, conf *config.Config, cid string, wa ct, err := container.New(conf, containerArgs) if err != nil { - return Errorf("creating container: %v", err) + return util.Errorf("creating container: %v", err) } defer ct.Destroy() if err := ct.Start(conf); err != nil { - return Errorf("starting container: %v", err) + return util.Errorf("starting container: %v", err) } // Forward signals to init in the container. Thus if we get SIGINT from @@ -399,7 +400,7 @@ func startContainerAndWait(spec *specs.Spec, conf *config.Config, cid string, wa ws, err := ct.Wait() if err != nil { - return Errorf("waiting for container: %v", err) + return util.Errorf("waiting for container: %v", err) } *waitStatus = ws diff --git a/runsc/cmd/events.go b/runsc/cmd/events.go index 08246e543..beb0c1258 100644 --- a/runsc/cmd/events.go +++ b/runsc/cmd/events.go @@ -22,6 +22,7 @@ import ( "github.com/google/subcommands" "gvisor.dev/gvisor/pkg/log" + "gvisor.dev/gvisor/runsc/cmd/util" "gvisor.dev/gvisor/runsc/config" "gvisor.dev/gvisor/runsc/container" "gvisor.dev/gvisor/runsc/flag" @@ -82,12 +83,12 @@ func (evs *Events) Execute(ctx context.Context, f *flag.FlagSet, args ...interfa c, err := container.Load(conf.RootDir, container.FullID{ContainerID: id}, container.LoadOpts{}) if err != nil { - Fatalf("loading sandbox: %v", err) + util.Fatalf("loading sandbox: %v", err) } if evs.stream { if err := c.Stream(evs.filters, os.Stdout); err != nil { - Fatalf("Stream failed: %v", err) + util.Fatalf("Stream failed: %v", err) } return subcommands.ExitSuccess } @@ -111,7 +112,7 @@ func (evs *Events) Execute(ctx context.Context, f *flag.FlagSet, args ...interfa log.Warningf("Error while marshalling event %v: %v", ev.Event, err) } else { if _, err := os.Stdout.Write(b); err != nil { - Fatalf("Error writing to stdout: %v", err) + util.Fatalf("Error writing to stdout: %v", err) } } diff --git a/runsc/cmd/exec.go b/runsc/cmd/exec.go index 2139fdf53..b39bc4f02 100644 --- a/runsc/cmd/exec.go +++ b/runsc/cmd/exec.go @@ -33,6 +33,7 @@ import ( "gvisor.dev/gvisor/pkg/sentry/control" "gvisor.dev/gvisor/pkg/sentry/kernel/auth" "gvisor.dev/gvisor/pkg/urpc" + "gvisor.dev/gvisor/runsc/cmd/util" "gvisor.dev/gvisor/runsc/config" "gvisor.dev/gvisor/runsc/console" "gvisor.dev/gvisor/runsc/container" @@ -108,13 +109,13 @@ func (ex *Exec) Execute(_ context.Context, f *flag.FlagSet, args ...interface{}) conf := args[0].(*config.Config) e, id, err := ex.parseArgs(f, conf.EnableRaw) if err != nil { - Fatalf("parsing process spec: %v", err) + util.Fatalf("parsing process spec: %v", err) } waitStatus := args[1].(*unix.WaitStatus) c, err := container.Load(conf.RootDir, container.FullID{ContainerID: id}, container.LoadOpts{}) if err != nil { - Fatalf("loading sandbox: %v", err) + util.Fatalf("loading sandbox: %v", err) } log.Debugf("Exec arguments: %+v", e) @@ -127,14 +128,14 @@ func (ex *Exec) Execute(_ context.Context, f *flag.FlagSet, args ...interface{}) if e.Envv == nil { e.Envv, err = specutils.ResolveEnvs(c.Spec.Process.Env, ex.env) if err != nil { - Fatalf("getting environment variables: %v", err) + util.Fatalf("getting environment variables: %v", err) } } if e.Capabilities == nil { e.Capabilities, err = specutils.Capabilities(conf.EnableRaw, c.Spec.Process.Capabilities) if err != nil { - Fatalf("creating capabilities: %v", err) + util.Fatalf("creating capabilities: %v", err) } log.Infof("Using exec capabilities from container: %+v", e.Capabilities) } @@ -153,7 +154,7 @@ func (ex *Exec) exec(conf *config.Config, c *container.Container, e *control.Exe // Start the new process and get its pid. pid, err := c.Execute(conf, e) if err != nil { - return Errorf("executing processes for container: %v", err) + return util.Errorf("executing processes for container: %v", err) } if e.StdioIsPty { @@ -167,7 +168,7 @@ func (ex *Exec) exec(conf *config.Config, c *container.Container, e *control.Exe if ex.internalPidFile != "" { pidStr := []byte(strconv.Itoa(int(pid))) if err := ioutil.WriteFile(ex.internalPidFile, pidStr, 0644); err != nil { - return Errorf("writing internal pid file %q: %v", ex.internalPidFile, err) + return util.Errorf("writing internal pid file %q: %v", ex.internalPidFile, err) } } @@ -176,14 +177,14 @@ func (ex *Exec) exec(conf *config.Config, c *container.Container, e *control.Exe // `runsc exec -d` returns. if ex.pidFile != "" { if err := ioutil.WriteFile(ex.pidFile, []byte(strconv.Itoa(os.Getpid())), 0644); err != nil { - return Errorf("writing pid file: %v", err) + return util.Errorf("writing pid file: %v", err) } } // Wait for the process to exit. ws, err := c.WaitPID(pid) if err != nil { - return Errorf("waiting on pid %d: %v", pid, err) + return util.Errorf("waiting on pid %d: %v", pid, err) } *waitStatus = ws return subcommands.ExitSuccess @@ -204,7 +205,7 @@ func (ex *Exec) execChildAndWait(waitStatus *unix.WaitStatus) subcommands.ExitSt if pidFile == "" { tmpDir, err := ioutil.TempDir("", "exec-pid-") if err != nil { - Fatalf("creating TempDir: %v", err) + util.Fatalf("creating TempDir: %v", err) } defer os.RemoveAll(tmpDir) pidFile = filepath.Join(tmpDir, "pid") @@ -225,7 +226,7 @@ func (ex *Exec) execChildAndWait(waitStatus *unix.WaitStatus) subcommands.ExitSt // Create a new TTY pair and send the master on the provided socket. tty, err := console.NewWithSocket(ex.consoleSocket) if err != nil { - Fatalf("setting up console with socket %q: %v", ex.consoleSocket, err) + util.Fatalf("setting up console with socket %q: %v", ex.consoleSocket, err) } defer tty.Close() @@ -245,7 +246,7 @@ func (ex *Exec) execChildAndWait(waitStatus *unix.WaitStatus) subcommands.ExitSt } if err := cmd.Start(); err != nil { - Fatalf("failure to start child exec process, err: %v", err) + util.Fatalf("failure to start child exec process, err: %v", err) } log.Infof("Started child (PID: %d) to exec and wait: %s %s", cmd.Process.Pid, specutils.ExePath, args) @@ -307,7 +308,7 @@ func (ex *Exec) argsFromCLI(argv []string, enableRaw bool) (*control.ExecArgs, e for _, s := range ex.extraKGIDs { kgid, err := strconv.Atoi(s) if err != nil { - Fatalf("parsing GID: %s, %v", s, err) + util.Fatalf("parsing GID: %s, %v", s, err) } extraKGIDs = append(extraKGIDs, auth.KGID(kgid)) } diff --git a/runsc/cmd/gofer.go b/runsc/cmd/gofer.go index bec25fb82..4b6c284e4 100644 --- a/runsc/cmd/gofer.go +++ b/runsc/cmd/gofer.go @@ -29,6 +29,7 @@ import ( "gvisor.dev/gvisor/pkg/p9" "gvisor.dev/gvisor/pkg/sync" "gvisor.dev/gvisor/pkg/unet" + "gvisor.dev/gvisor/runsc/cmd/util" "gvisor.dev/gvisor/runsc/config" "gvisor.dev/gvisor/runsc/flag" "gvisor.dev/gvisor/runsc/fsgofer" @@ -105,12 +106,12 @@ func (g *Gofer) Execute(_ context.Context, f *flag.FlagSet, args ...interface{}) defer specFile.Close() spec, err := specutils.ReadSpecFromFile(g.bundleDir, specFile, conf) if err != nil { - Fatalf("reading spec: %v", err) + util.Fatalf("reading spec: %v", err) } if g.setUpRoot { if err := setupRootFS(spec, conf); err != nil { - Fatalf("Error setting up root FS: %v", err) + util.Fatalf("Error setting up root FS: %v", err) } } if g.applyCaps { @@ -118,7 +119,7 @@ func (g *Gofer) Execute(_ context.Context, f *flag.FlagSet, args ...interface{}) // Note: minimal argument handling for the default case to keep it simple. args := os.Args args = append(args, "--apply-caps=false", "--setup-root=false") - Fatalf("setCapsAndCallSelf(%v, %v): %v", args, goferCaps, setCapsAndCallSelf(args, goferCaps)) + util.Fatalf("setCapsAndCallSelf(%v, %v): %v", args, goferCaps, setCapsAndCallSelf(args, goferCaps)) panic("unreachable") } @@ -135,7 +136,7 @@ func (g *Gofer) Execute(_ context.Context, f *flag.FlagSet, args ...interface{}) // setupRootFS(). cleanMounts, err := resolveMounts(conf, spec.Mounts, root) if err != nil { - Fatalf("Failure to resolve mounts: %v", err) + util.Fatalf("Failure to resolve mounts: %v", err) } spec.Mounts = cleanMounts go func() { @@ -151,14 +152,14 @@ func (g *Gofer) Execute(_ context.Context, f *flag.FlagSet, args ...interface{}) unix.Umask(0) if err := fsgofer.OpenProcSelfFD(); err != nil { - Fatalf("failed to open /proc/self/fd: %v", err) + util.Fatalf("failed to open /proc/self/fd: %v", err) } if err := unix.Chroot(root); err != nil { - Fatalf("failed to chroot to %q: %v", root, err) + util.Fatalf("failed to chroot to %q: %v", root, err) } if err := unix.Chdir("/"); err != nil { - Fatalf("changing working dir: %v", err) + util.Fatalf("changing working dir: %v", err) } log.Infof("Process chroot'd to %q", root) @@ -172,7 +173,7 @@ func (g *Gofer) Execute(_ context.Context, f *flag.FlagSet, args ...interface{}) } if err := filter.Install(); err != nil { - Fatalf("installing seccomp filters: %v", err) + util.Fatalf("installing seccomp filters: %v", err) } if conf.Lisafs { @@ -184,7 +185,7 @@ func (g *Gofer) Execute(_ context.Context, f *flag.FlagSet, args ...interface{}) func newSocket(ioFD int) *unet.Socket { socket, err := unet.NewSocket(ioFD) if err != nil { - Fatalf("creating server on FD %d: %v", ioFD, err) + util.Fatalf("creating server on FD %d: %v", ioFD, err) } return socket } @@ -218,10 +219,10 @@ func (g *Gofer) serveLisafs(spec *specs.Spec, conf *config.Config, root string) } if !filepath.IsAbs(m.Destination) { - Fatalf("mount destination must be absolute: %q", m.Destination) + util.Fatalf("mount destination must be absolute: %q", m.Destination) } if mountIdx >= len(g.ioFDs) { - Fatalf("no FD found for mount. Did you forget --io-fd? FDs: %d, Mount: %+v", len(g.ioFDs), m) + util.Fatalf("no FD found for mount. Did you forget --io-fd? FDs: %d, Mount: %+v", len(g.ioFDs), m) } cfgs = append(cfgs, connectionConfig{ @@ -235,14 +236,14 @@ func (g *Gofer) serveLisafs(spec *specs.Spec, conf *config.Config, root string) } if mountIdx != len(g.ioFDs) { - Fatalf("too many FDs passed for mounts. mounts: %d, FDs: %d", mountIdx, len(g.ioFDs)) + util.Fatalf("too many FDs passed for mounts. mounts: %d, FDs: %d", mountIdx, len(g.ioFDs)) } cfgs = cfgs[:mountIdx] for _, cfg := range cfgs { conn, err := server.CreateConnection(cfg.sock, cfg.mountPath, cfg.readonly) if err != nil { - Fatalf("starting connection on FD %d for gofer mount failed: %v", cfg.sock.FD(), err) + util.Fatalf("starting connection on FD %d for gofer mount failed: %v", cfg.sock.FD(), err) } server.StartConnection(conn) } @@ -261,7 +262,7 @@ func (g *Gofer) serve9P(spec *specs.Spec, conf *config.Config, root string) subc EnableVerityXattr: conf.Verity, }) if err != nil { - Fatalf("creating attach point: %v", err) + util.Fatalf("creating attach point: %v", err) } ats = append(ats, ap) log.Infof("Serving %q mapped to %q on FD %d (ro: %t)", "/", root, g.ioFDs[0], spec.Root.Readonly) @@ -276,19 +277,19 @@ func (g *Gofer) serve9P(spec *specs.Spec, conf *config.Config, root string) subc } ap, err := fsgofer.NewAttachPoint(m.Destination, cfg) if err != nil { - Fatalf("creating attach point: %v", err) + util.Fatalf("creating attach point: %v", err) } ats = append(ats, ap) if mountIdx >= len(g.ioFDs) { - Fatalf("no FD found for mount. Did you forget --io-fd? mount: %d, %v", len(g.ioFDs), m) + util.Fatalf("no FD found for mount. Did you forget --io-fd? mount: %d, %v", len(g.ioFDs), m) } log.Infof("Serving %q mapped on FD %d (ro: %t)", m.Destination, g.ioFDs[mountIdx], cfg.ROMount) mountIdx++ } } if mountIdx != len(g.ioFDs) { - Fatalf("too many FDs passed for mounts. mounts: %d, FDs: %d", mountIdx, len(g.ioFDs)) + util.Fatalf("too many FDs passed for mounts. mounts: %d, FDs: %d", mountIdx, len(g.ioFDs)) } // Run the loops and wait for all to exit. @@ -298,11 +299,11 @@ func (g *Gofer) serve9P(spec *specs.Spec, conf *config.Config, root string) subc go func(ioFD int, at p9.Attacher) { socket, err := unet.NewSocket(ioFD) if err != nil { - Fatalf("creating server on FD %d: %v", ioFD, err) + util.Fatalf("creating server on FD %d: %v", ioFD, err) } s := p9.NewServer(at) if err := s.Handle(socket); err != nil { - Fatalf("P9 server returned error. Gofer is shutting down. FD: %d, err: %v", ioFD, err) + util.Fatalf("P9 server returned error. Gofer is shutting down. FD: %d, err: %v", ioFD, err) } wg.Done() }(ioFD, ats[i]) @@ -345,7 +346,7 @@ func setupRootFS(spec *specs.Spec, conf *config.Config) error { // propagated outside of our namespace. procPath := "/proc" if err := specutils.SafeMount("", "/", "", unix.MS_SLAVE|unix.MS_REC, "", procPath); err != nil { - Fatalf("error converting mounts: %v", err) + util.Fatalf("error converting mounts: %v", err) } root := spec.Root.Path @@ -358,23 +359,23 @@ func setupRootFS(spec *specs.Spec, conf *config.Config) error { // runsc can't start without /proc, so we can use it for this. flags := uintptr(unix.MS_NOSUID | unix.MS_NODEV | unix.MS_NOEXEC) if err := specutils.SafeMount("runsc-root", "/proc", "tmpfs", flags, "", procPath); err != nil { - Fatalf("error mounting tmpfs: %v", err) + util.Fatalf("error mounting tmpfs: %v", err) } // Prepare tree structure for pivot_root(2). if err := os.Mkdir("/proc/proc", 0755); err != nil { - Fatalf("error creating /proc/proc: %v", err) + util.Fatalf("error creating /proc/proc: %v", err) } if err := os.Mkdir("/proc/root", 0755); err != nil { - Fatalf("error creating /proc/root: %v", err) + util.Fatalf("error creating /proc/root: %v", err) } if err := os.Mkdir("/proc/etc", 0755); err != nil { - Fatalf("error creating /proc/etc: %v", err) + util.Fatalf("error creating /proc/etc: %v", err) } // This cannot use SafeMount because there's no available procfs. But we // know that /proc is an empty tmpfs mount, so this is safe. if err := unix.Mount("runsc-proc", "/proc/proc", "proc", flags|unix.MS_RDONLY, ""); err != nil { - Fatalf("error mounting proc: %v", err) + util.Fatalf("error mounting proc: %v", err) } if err := copyFile("/proc/etc/localtime", "/etc/localtime"); err != nil { log.Warningf("Failed to copy /etc/localtime: %v. UTC timezone will be used.", err) @@ -398,7 +399,7 @@ func setupRootFS(spec *specs.Spec, conf *config.Config) error { // Replace the current spec, with the clean spec with symlinks resolved. if err := setupMounts(conf, spec.Mounts, root, procPath); err != nil { - Fatalf("error setting up FS: %v", err) + util.Fatalf("error setting up FS: %v", err) } // Create working directory if needed. @@ -426,10 +427,10 @@ func setupRootFS(spec *specs.Spec, conf *config.Config) error { if !conf.TestOnlyAllowRunAsCurrentUserWithoutChroot { if err := pivotRoot("/proc"); err != nil { - Fatalf("failed to change the root file system: %v", err) + util.Fatalf("failed to change the root file system: %v", err) } if err := os.Chdir("/"); err != nil { - Fatalf("failed to change working directory") + util.Fatalf("failed to change working directory") } } return nil diff --git a/runsc/cmd/kill.go b/runsc/cmd/kill.go index 239fc7ac2..5c0c3ef38 100644 --- a/runsc/cmd/kill.go +++ b/runsc/cmd/kill.go @@ -22,6 +22,7 @@ import ( "github.com/google/subcommands" "golang.org/x/sys/unix" + "gvisor.dev/gvisor/runsc/cmd/util" "gvisor.dev/gvisor/runsc/config" "gvisor.dev/gvisor/runsc/container" "gvisor.dev/gvisor/runsc/flag" @@ -65,12 +66,12 @@ func (k *Kill) Execute(_ context.Context, f *flag.FlagSet, args ...interface{}) conf := args[0].(*config.Config) if k.pid != 0 && k.all { - Fatalf("it is invalid to specify both --all and --pid") + util.Fatalf("it is invalid to specify both --all and --pid") } c, err := container.Load(conf.RootDir, container.FullID{ContainerID: id}, container.LoadOpts{}) if err != nil { - Fatalf("loading container: %v", err) + util.Fatalf("loading container: %v", err) } // The OCI command-line spec says that the signal should be specified @@ -83,16 +84,16 @@ func (k *Kill) Execute(_ context.Context, f *flag.FlagSet, args ...interface{}) sig, err := parseSignal(signal) if err != nil { - Fatalf("%v", err) + util.Fatalf("%v", err) } if k.pid != 0 { if err := c.SignalProcess(sig, int32(k.pid)); err != nil { - Fatalf("failed to signal pid %d: %v", k.pid, err) + util.Fatalf("failed to signal pid %d: %v", k.pid, err) } } else { if err := c.SignalContainer(sig, k.all); err != nil { - Fatalf("%v", err) + util.Fatalf("%v", err) } } return subcommands.ExitSuccess diff --git a/runsc/cmd/list.go b/runsc/cmd/list.go index fc13e4a81..38582755f 100644 --- a/runsc/cmd/list.go +++ b/runsc/cmd/list.go @@ -25,6 +25,7 @@ import ( "github.com/google/subcommands" specs "github.com/opencontainers/runtime-spec/specs-go" "gvisor.dev/gvisor/pkg/log" + "gvisor.dev/gvisor/runsc/cmd/util" "gvisor.dev/gvisor/runsc/config" "gvisor.dev/gvisor/runsc/container" "gvisor.dev/gvisor/runsc/flag" @@ -67,7 +68,7 @@ func (l *List) Execute(_ context.Context, f *flag.FlagSet, args ...interface{}) conf := args[0].(*config.Config) ids, err := container.List(conf.RootDir) if err != nil { - Fatalf("%v", err) + util.Fatalf("%v", err) } if l.quiet { @@ -110,10 +111,10 @@ func (l *List) Execute(_ context.Context, f *flag.FlagSet, args ...interface{}) states = append(states, c.State()) } if err := json.NewEncoder(os.Stdout).Encode(states); err != nil { - Fatalf("marshaling container state: %v", err) + util.Fatalf("marshaling container state: %v", err) } default: - Fatalf("unknown list format %q", l.format) + util.Fatalf("unknown list format %q", l.format) } return subcommands.ExitSuccess } diff --git a/runsc/cmd/mitigate.go b/runsc/cmd/mitigate.go index 1aada5968..188abc4e0 100644 --- a/runsc/cmd/mitigate.go +++ b/runsc/cmd/mitigate.go @@ -23,6 +23,7 @@ import ( "github.com/google/subcommands" "gvisor.dev/gvisor/pkg/log" + "gvisor.dev/gvisor/runsc/cmd/util" "gvisor.dev/gvisor/runsc/flag" "gvisor.dev/gvisor/runsc/mitigate" ) @@ -93,22 +94,22 @@ func (m *Mitigate) Execute(_ context.Context, f *flag.FlagSet, args ...interface func (m *Mitigate) execute() subcommands.ExitStatus { beforeSet, err := m.control.getCPUs() if err != nil { - return Errorf("Get before CPUSet failed: %v", err) + return util.Errorf("Get before CPUSet failed: %v", err) } log.Infof("CPUs before: %s", beforeSet.String()) if err := m.doEnableDisable(beforeSet); err != nil { - return Errorf("Enabled/Disable action failed on %q: %v", smtPath, err) + return util.Errorf("Enabled/Disable action failed on %q: %v", smtPath, err) } afterSet, err := m.control.getCPUs() if err != nil { - return Errorf("Get after CPUSet failed: %v", err) + return util.Errorf("Get after CPUSet failed: %v", err) } log.Infof("CPUs after: %s", afterSet.String()) if err = m.postMitigate(afterSet); err != nil { - return Errorf("Post Mitigate failed: %v", err) + return util.Errorf("Post Mitigate failed: %v", err) } return subcommands.ExitSuccess diff --git a/runsc/cmd/mitigate_test.go b/runsc/cmd/mitigate_test.go index 294fc645c..29bc72080 100644 --- a/runsc/cmd/mitigate_test.go +++ b/runsc/cmd/mitigate_test.go @@ -22,6 +22,7 @@ import ( "github.com/google/subcommands" "gvisor.dev/gvisor/pkg/log" + "gvisor.dev/gvisor/runsc/cmd/util" "gvisor.dev/gvisor/runsc/mitigate" ) @@ -99,8 +100,8 @@ func TestExecute(t *testing.T) { { name: "Empty", cpu: mitigate.Empty, - mitigateError: Errorf(`mitigate operation failed: no cpus found for: ""`), - reverseError: Errorf(`mitigate operation failed: no cpus found for: ""`), + mitigateError: util.Errorf(`mitigate operation failed: no cpus found for: ""`), + reverseError: util.Errorf(`mitigate operation failed: no cpus found for: ""`), }, } { t.Run(tc.name, func(t *testing.T) { diff --git a/runsc/cmd/path.go b/runsc/cmd/path.go index 0e9ef7fa5..8822f4692 100644 --- a/runsc/cmd/path.go +++ b/runsc/cmd/path.go @@ -16,13 +16,15 @@ package cmd import ( "os" + + "gvisor.dev/gvisor/runsc/cmd/util" ) // getwdOrDie returns the current working directory and dies if it cannot. func getwdOrDie() string { wd, err := os.Getwd() if err != nil { - Fatalf("getting current working directory: %v", err) + util.Fatalf("getting current working directory: %v", err) } return wd } diff --git a/runsc/cmd/pause.go b/runsc/cmd/pause.go index 9768f1cfb..c37020a5c 100644 --- a/runsc/cmd/pause.go +++ b/runsc/cmd/pause.go @@ -18,6 +18,7 @@ import ( "context" "github.com/google/subcommands" + "gvisor.dev/gvisor/runsc/cmd/util" "gvisor.dev/gvisor/runsc/config" "gvisor.dev/gvisor/runsc/container" "gvisor.dev/gvisor/runsc/flag" @@ -57,11 +58,11 @@ func (*Pause) Execute(_ context.Context, f *flag.FlagSet, args ...interface{}) s cont, err := container.Load(conf.RootDir, container.FullID{ContainerID: id}, container.LoadOpts{}) if err != nil { - Fatalf("loading container: %v", err) + util.Fatalf("loading container: %v", err) } if err := cont.Pause(); err != nil { - Fatalf("pause failed: %v", err) + util.Fatalf("pause failed: %v", err) } return subcommands.ExitSuccess diff --git a/runsc/cmd/ps.go b/runsc/cmd/ps.go index 04e3e0bdd..2900c570e 100644 --- a/runsc/cmd/ps.go +++ b/runsc/cmd/ps.go @@ -20,6 +20,7 @@ import ( "github.com/google/subcommands" "gvisor.dev/gvisor/pkg/sentry/control" + "gvisor.dev/gvisor/runsc/cmd/util" "gvisor.dev/gvisor/runsc/config" "gvisor.dev/gvisor/runsc/container" "gvisor.dev/gvisor/runsc/flag" @@ -62,11 +63,11 @@ func (ps *PS) Execute(ctx context.Context, f *flag.FlagSet, args ...interface{}) c, err := container.Load(conf.RootDir, container.FullID{ContainerID: id}, container.LoadOpts{}) if err != nil { - Fatalf("loading sandbox: %v", err) + util.Fatalf("loading sandbox: %v", err) } pList, err := c.Processes() if err != nil { - Fatalf("getting processes for container: %v", err) + util.Fatalf("getting processes for container: %v", err) } switch ps.format { @@ -75,11 +76,11 @@ func (ps *PS) Execute(ctx context.Context, f *flag.FlagSet, args ...interface{}) case "json": o, err := control.PrintPIDsJSON(pList) if err != nil { - Fatalf("generating JSON: %v", err) + util.Fatalf("generating JSON: %v", err) } fmt.Println(o) default: - Fatalf("unsupported format: %s", ps.format) + util.Fatalf("unsupported format: %s", ps.format) } return subcommands.ExitSuccess diff --git a/runsc/cmd/restore.go b/runsc/cmd/restore.go index b21f05921..2d46c0781 100644 --- a/runsc/cmd/restore.go +++ b/runsc/cmd/restore.go @@ -20,6 +20,7 @@ import ( "github.com/google/subcommands" "golang.org/x/sys/unix" + "gvisor.dev/gvisor/runsc/cmd/util" "gvisor.dev/gvisor/runsc/config" "gvisor.dev/gvisor/runsc/container" "gvisor.dev/gvisor/runsc/flag" @@ -81,7 +82,7 @@ func (r *Restore) Execute(_ context.Context, f *flag.FlagSet, args ...interface{ waitStatus := args[1].(*unix.WaitStatus) if conf.Rootless { - return Errorf("Rootless mode not supported with %q", r.Name()) + return util.Errorf("Rootless mode not supported with %q", r.Name()) } bundleDir := r.bundleDir @@ -90,12 +91,12 @@ func (r *Restore) Execute(_ context.Context, f *flag.FlagSet, args ...interface{ } spec, err := specutils.ReadSpec(bundleDir, conf) if err != nil { - return Errorf("reading spec: %v", err) + return util.Errorf("reading spec: %v", err) } specutils.LogSpec(spec) if r.imagePath == "" { - return Errorf("image-path flag must be provided") + return util.Errorf("image-path flag must be provided") } conf.RestoreFile = filepath.Join(r.imagePath, checkpointFileName) @@ -111,7 +112,7 @@ func (r *Restore) Execute(_ context.Context, f *flag.FlagSet, args ...interface{ } ws, err := container.Run(conf, runArgs) if err != nil { - return Errorf("running container: %v", err) + return util.Errorf("running container: %v", err) } *waitStatus = ws diff --git a/runsc/cmd/resume.go b/runsc/cmd/resume.go index d62e89e80..c466f3776 100644 --- a/runsc/cmd/resume.go +++ b/runsc/cmd/resume.go @@ -18,6 +18,7 @@ import ( "context" "github.com/google/subcommands" + "gvisor.dev/gvisor/runsc/cmd/util" "gvisor.dev/gvisor/runsc/config" "gvisor.dev/gvisor/runsc/container" "gvisor.dev/gvisor/runsc/flag" @@ -58,11 +59,11 @@ func (r *Resume) Execute(_ context.Context, f *flag.FlagSet, args ...interface{} cont, err := container.Load(conf.RootDir, container.FullID{ContainerID: id}, container.LoadOpts{}) if err != nil { - Fatalf("loading container: %v", err) + util.Fatalf("loading container: %v", err) } if err := cont.Resume(); err != nil { - Fatalf("resume failed: %v", err) + util.Fatalf("resume failed: %v", err) } return subcommands.ExitSuccess diff --git a/runsc/cmd/run.go b/runsc/cmd/run.go index da11c9d06..6a361f20d 100644 --- a/runsc/cmd/run.go +++ b/runsc/cmd/run.go @@ -19,6 +19,7 @@ import ( "github.com/google/subcommands" "golang.org/x/sys/unix" + "gvisor.dev/gvisor/runsc/cmd/util" "gvisor.dev/gvisor/runsc/config" "gvisor.dev/gvisor/runsc/container" "gvisor.dev/gvisor/runsc/flag" @@ -69,11 +70,11 @@ func (r *Run) Execute(_ context.Context, f *flag.FlagSet, args ...interface{}) s if conf.Rootless { if conf.Network == config.NetworkSandbox { - return Errorf("sandbox network isn't supported with --rootless, use --network=none or --network=host") + return util.Errorf("sandbox network isn't supported with --rootless, use --network=none or --network=host") } if err := specutils.MaybeRunAsRoot(); err != nil { - return Errorf("Error executing inside namespace: %v", err) + return util.Errorf("Error executing inside namespace: %v", err) } // Execution will continue here if no more capabilities are needed... } @@ -84,7 +85,7 @@ func (r *Run) Execute(_ context.Context, f *flag.FlagSet, args ...interface{}) s } spec, err := specutils.ReadSpec(bundleDir, conf) if err != nil { - return Errorf("reading spec: %v", err) + return util.Errorf("reading spec: %v", err) } specutils.LogSpec(spec) @@ -99,7 +100,7 @@ func (r *Run) Execute(_ context.Context, f *flag.FlagSet, args ...interface{}) s } ws, err := container.Run(conf, runArgs) if err != nil { - return Errorf("running container: %v", err) + return util.Errorf("running container: %v", err) } *waitStatus = ws diff --git a/runsc/cmd/spec.go b/runsc/cmd/spec.go index 3a7f2a2c4..038353f4b 100644 --- a/runsc/cmd/spec.go +++ b/runsc/cmd/spec.go @@ -23,6 +23,7 @@ import ( "github.com/google/subcommands" specs "github.com/opencontainers/runtime-spec/specs-go" + "gvisor.dev/gvisor/runsc/cmd/util" "gvisor.dev/gvisor/runsc/flag" ) @@ -188,17 +189,17 @@ func (s *Spec) Execute(_ context.Context, f *flag.FlagSet, args ...interface{}) confPath := filepath.Join(s.bundle, "config.json") if _, err := os.Stat(confPath); !os.IsNotExist(err) { - Fatalf("file %q already exists", confPath) + util.Fatalf("file %q already exists", confPath) } configFile, err := os.OpenFile(confPath, os.O_WRONLY|os.O_CREATE, 0664) if err != nil { - Fatalf("opening file %q: %v", confPath, err) + util.Fatalf("opening file %q: %v", confPath, err) } err = writeSpec(configFile, s.cwd, s.netns, containerArgs) if err != nil { - Fatalf("writing to %q: %v", confPath, err) + util.Fatalf("writing to %q: %v", confPath, err) } return subcommands.ExitSuccess diff --git a/runsc/cmd/start.go b/runsc/cmd/start.go index 7c395d722..30dcaa0f0 100644 --- a/runsc/cmd/start.go +++ b/runsc/cmd/start.go @@ -18,6 +18,7 @@ import ( "context" "github.com/google/subcommands" + "gvisor.dev/gvisor/runsc/cmd/util" "gvisor.dev/gvisor/runsc/config" "gvisor.dev/gvisor/runsc/container" "gvisor.dev/gvisor/runsc/flag" @@ -57,16 +58,16 @@ func (*Start) Execute(_ context.Context, f *flag.FlagSet, args ...interface{}) s c, err := container.Load(conf.RootDir, container.FullID{ContainerID: id}, container.LoadOpts{}) if err != nil { - Fatalf("loading container: %v", err) + util.Fatalf("loading container: %v", err) } // Read the spec again here to ensure flag annotations from the spec are // applied to "conf". if _, err := specutils.ReadSpec(c.BundleDir, conf); err != nil { - Fatalf("reading spec: %v", err) + util.Fatalf("reading spec: %v", err) } if err := c.Start(conf); err != nil { - Fatalf("starting container: %v", err) + util.Fatalf("starting container: %v", err) } return subcommands.ExitSuccess } diff --git a/runsc/cmd/state.go b/runsc/cmd/state.go index 061003bab..89a739838 100644 --- a/runsc/cmd/state.go +++ b/runsc/cmd/state.go @@ -21,6 +21,7 @@ import ( "github.com/google/subcommands" "gvisor.dev/gvisor/pkg/log" + "gvisor.dev/gvisor/runsc/cmd/util" "gvisor.dev/gvisor/runsc/config" "gvisor.dev/gvisor/runsc/container" "gvisor.dev/gvisor/runsc/flag" @@ -59,7 +60,7 @@ func (*State) Execute(_ context.Context, f *flag.FlagSet, args ...interface{}) s c, err := container.Load(conf.RootDir, container.FullID{ContainerID: id}, container.LoadOpts{}) if err != nil { - Fatalf("loading container: %v", err) + util.Fatalf("loading container: %v", err) } log.Debugf("Returning state for container %+v", c) @@ -69,10 +70,10 @@ func (*State) Execute(_ context.Context, f *flag.FlagSet, args ...interface{}) s // Write json-encoded state directly to stdout. b, err := json.MarshalIndent(state, "", " ") if err != nil { - Fatalf("marshaling container state: %v", err) + util.Fatalf("marshaling container state: %v", err) } if _, err := os.Stdout.Write(b); err != nil { - Fatalf("Error writing to stdout: %v", err) + util.Fatalf("Error writing to stdout: %v", err) } return subcommands.ExitSuccess } diff --git a/runsc/cmd/statefile.go b/runsc/cmd/statefile.go index daed9e728..91a04944c 100644 --- a/runsc/cmd/statefile.go +++ b/runsc/cmd/statefile.go @@ -22,6 +22,7 @@ import ( "github.com/google/subcommands" "gvisor.dev/gvisor/pkg/state/pretty" "gvisor.dev/gvisor/pkg/state/statefile" + "gvisor.dev/gvisor/runsc/cmd/util" "gvisor.dev/gvisor/runsc/flag" ) @@ -62,7 +63,7 @@ func (s *Statefile) SetFlags(f *flag.FlagSet) { func (s *Statefile) Execute(_ context.Context, f *flag.FlagSet, args ...interface{}) subcommands.ExitStatus { // Check arguments. if s.list && s.get != "" { - Fatalf("error: can't specify -list and -get simultaneously.") + util.Fatalf("error: can't specify -list and -get simultaneously.") } // Setup output. @@ -70,11 +71,11 @@ func (s *Statefile) Execute(_ context.Context, f *flag.FlagSet, args ...interfac if s.output != "" { f, err := os.OpenFile(s.output, os.O_WRONLY|os.O_TRUNC|os.O_CREATE, 0644) if err != nil { - Fatalf("error opening output: %v", err) + util.Fatalf("error opening output: %v", err) } defer func() { if err := f.Close(); err != nil { - Fatalf("error flushing output: %v", err) + util.Fatalf("error flushing output: %v", err) } }() output = f @@ -87,7 +88,7 @@ func (s *Statefile) Execute(_ context.Context, f *flag.FlagSet, args ...interfac } input, err := os.Open(f.Arg(0)) if err != nil { - Fatalf("error opening input: %v\n", err) + util.Fatalf("error opening input: %v\n", err) } if s.html { @@ -103,15 +104,15 @@ func (s *Statefile) Execute(_ context.Context, f *flag.FlagSet, args ...interfac } rc, _, err := statefile.NewReader(input, key) if err != nil { - Fatalf("error parsing statefile: %v", err) + util.Fatalf("error parsing statefile: %v", err) } if s.html { if err := pretty.PrintHTML(output, rc); err != nil { - Fatalf("error printing state: %v", err) + util.Fatalf("error printing state: %v", err) } } else { if err := pretty.PrintText(output, rc); err != nil { - Fatalf("error printing state: %v", err) + util.Fatalf("error printing state: %v", err) } } return subcommands.ExitSuccess @@ -120,14 +121,14 @@ func (s *Statefile) Execute(_ context.Context, f *flag.FlagSet, args ...interfac // Load just the metadata. metadata, err := statefile.MetadataUnsafe(input) if err != nil { - Fatalf("error reading metadata: %v", err) + util.Fatalf("error reading metadata: %v", err) } // Is it a single key? if s.get != "" { val, ok := metadata[s.get] if !ok { - Fatalf("metadata key %s: not found", s.get) + util.Fatalf("metadata key %s: not found", s.get) } fmt.Fprintf(output, "%s\n", val) return subcommands.ExitSuccess diff --git a/runsc/cmd/symbolize.go b/runsc/cmd/symbolize.go index 0fa4bfda1..68c4c941f 100644 --- a/runsc/cmd/symbolize.go +++ b/runsc/cmd/symbolize.go @@ -23,6 +23,7 @@ import ( "github.com/google/subcommands" "gvisor.dev/gvisor/pkg/coverage" + "gvisor.dev/gvisor/runsc/cmd/util" "gvisor.dev/gvisor/runsc/flag" ) @@ -66,13 +67,13 @@ func (c *Symbolize) Execute(_ context.Context, f *flag.FlagSet, args ...interfac return subcommands.ExitUsageError } if !coverage.Available() { - return Errorf("symbolize can only be used when coverage is available.") + return util.Errorf("symbolize can only be used when coverage is available.") } coverage.InitCoverageData() if c.dumpAll { if err := coverage.WriteAllBlocks(os.Stdout); err != nil { - return Errorf("Failed to write out blocks: %v", err) + return util.Errorf("Failed to write out blocks: %v", err) } return subcommands.ExitSuccess } @@ -83,10 +84,10 @@ func (c *Symbolize) Execute(_ context.Context, f *flag.FlagSet, args ...interfac str := strings.TrimPrefix(scanner.Text(), "0x") pc, err := strconv.ParseUint(str, 16 /* base */, 64 /* bitSize */) if err != nil { - return Errorf("Failed to symbolize \"%s\": %v", scanner.Text(), err) + return util.Errorf("Failed to symbolize \"%s\": %v", scanner.Text(), err) } if err := coverage.Symbolize(os.Stdout, pc); err != nil { - return Errorf("Failed to symbolize \"%s\": %v", scanner.Text(), err) + return util.Errorf("Failed to symbolize \"%s\": %v", scanner.Text(), err) } } return subcommands.ExitSuccess diff --git a/runsc/cmd/syscalls.go b/runsc/cmd/syscalls.go index 608be9bb4..9596fc561 100644 --- a/runsc/cmd/syscalls.go +++ b/runsc/cmd/syscalls.go @@ -27,6 +27,7 @@ import ( "github.com/google/subcommands" "gvisor.dev/gvisor/pkg/sentry/kernel" + "gvisor.dev/gvisor/runsc/cmd/util" "gvisor.dev/gvisor/runsc/flag" ) @@ -106,7 +107,7 @@ func (s *Syscalls) SetFlags(f *flag.FlagSet) { func (s *Syscalls) Execute(context.Context, *flag.FlagSet, ...interface{}) subcommands.ExitStatus { out, ok := outputMap[s.format] if !ok { - Fatalf("Unsupported output format %q", s.format) + util.Fatalf("Unsupported output format %q", s.format) } // Build map of all supported architectures. @@ -123,18 +124,18 @@ func (s *Syscalls) Execute(context.Context, *flag.FlagSet, ...interface{}) subco // Build a map of the architectures we want to output. info, err := getCompatibilityInfo(s.os, s.arch) if err != nil { - Fatalf("%v", err) + util.Fatalf("%v", err) } w := os.Stdout // Default. if s.filename != "" { w, err = os.OpenFile(s.filename, os.O_CREATE|os.O_TRUNC|os.O_WRONLY, 0644) if err != nil { - Fatalf("Error opening %q: %v", s.filename, err) + util.Fatalf("Error opening %q: %v", s.filename, err) } } if err := out(w, info); err != nil { - Fatalf("Error writing output: %v", err) + util.Fatalf("Error writing output: %v", err) } return subcommands.ExitSuccess diff --git a/runsc/cmd/usage.go b/runsc/cmd/usage.go index d2aeafa28..4ccf87d4e 100644 --- a/runsc/cmd/usage.go +++ b/runsc/cmd/usage.go @@ -21,6 +21,7 @@ import ( "os" "github.com/google/subcommands" + "gvisor.dev/gvisor/runsc/cmd/util" "gvisor.dev/gvisor/runsc/config" "gvisor.dev/gvisor/runsc/container" "gvisor.dev/gvisor/runsc/flag" @@ -65,26 +66,26 @@ func (u *Usage) Execute(_ context.Context, f *flag.FlagSet, args ...interface{}) cont, err := container.Load(conf.RootDir, container.FullID{ContainerID: id}, container.LoadOpts{}) if err != nil { - Fatalf("loading container: %v", err) + util.Fatalf("loading container: %v", err) } if !u.fd { m, err := cont.Usage(u.full) if err != nil { - Fatalf("usage failed: %v", err) + util.Fatalf("usage failed: %v", err) } if err := json.NewEncoder(os.Stdout).Encode(m); err != nil { - Fatalf("Encode MemoryUsage failed: %v", err) + util.Fatalf("Encode MemoryUsage failed: %v", err) } } else { m, err := cont.UsageFD() if err != nil { - Fatalf("usagefd failed: %v", err) + util.Fatalf("usagefd failed: %v", err) } mapped, unknown, total, err := m.Fetch() if err != nil { - Fatalf("Fetch memory usage failed: %v", err) + util.Fatalf("Fetch memory usage failed: %v", err) } fmt.Printf("Mapped %v, Unknown %v, Total %v\n", mapped, unknown, total) diff --git a/runsc/cmd/util/BUILD b/runsc/cmd/util/BUILD new file mode 100644 index 000000000..6a2f1379c --- /dev/null +++ b/runsc/cmd/util/BUILD @@ -0,0 +1,16 @@ +load("//tools:defs.bzl", "go_library") + +package(licenses = ["notice"]) + +go_library( + name = "util", + srcs = ["util.go"], + visibility = [ + "//runsc/cli:__subpackages__", + "//runsc/cmd:__subpackages__", + ], + deps = [ + "//pkg/log", + "@com_github_google_subcommands//:go_default_library", + ], +) diff --git a/runsc/cmd/error.go b/runsc/cmd/util/util.go similarity index 95% rename from runsc/cmd/error.go rename to runsc/cmd/util/util.go index 96c5c1e8d..f7bc438ee 100644 --- a/runsc/cmd/error.go +++ b/runsc/cmd/util/util.go @@ -12,7 +12,8 @@ // See the License for the specific language governing permissions and // limitations under the License. -package cmd +// Package util groups a bunch of common helper functions used by commands. +package util import ( "encoding/json" diff --git a/runsc/cmd/verity_prepare.go b/runsc/cmd/verity_prepare.go index 44c1d05db..80131341a 100644 --- a/runsc/cmd/verity_prepare.go +++ b/runsc/cmd/verity_prepare.go @@ -23,6 +23,7 @@ import ( "github.com/google/subcommands" specs "github.com/opencontainers/runtime-spec/specs-go" "golang.org/x/sys/unix" + "gvisor.dev/gvisor/runsc/cmd/util" "gvisor.dev/gvisor/runsc/config" "gvisor.dev/gvisor/runsc/flag" "gvisor.dev/gvisor/runsc/specutils" @@ -67,13 +68,13 @@ func (c *VerityPrepare) Execute(_ context.Context, f *flag.FlagSet, args ...inte hostname, err := os.Hostname() if err != nil { - return Errorf("Error to retrieve hostname: %v", err) + return util.Errorf("Error to retrieve hostname: %v", err) } // Map the entire host file system. absRoot, err := resolvePath(c.root) if err != nil { - return Errorf("Error resolving root: %v", err) + return util.Errorf("Error resolving root: %v", err) } spec := &specs.Spec{ diff --git a/runsc/cmd/wait.go b/runsc/cmd/wait.go index d7a783b88..23f7ae4af 100644 --- a/runsc/cmd/wait.go +++ b/runsc/cmd/wait.go @@ -21,6 +21,7 @@ import ( "github.com/google/subcommands" "golang.org/x/sys/unix" + "gvisor.dev/gvisor/runsc/cmd/util" "gvisor.dev/gvisor/runsc/config" "gvisor.dev/gvisor/runsc/container" "gvisor.dev/gvisor/runsc/flag" @@ -66,7 +67,7 @@ func (wt *Wait) Execute(_ context.Context, f *flag.FlagSet, args ...interface{}) } // You can't specify both -pid and -rootpid. if wt.rootPID != unsetPID && wt.pid != unsetPID { - Fatalf("only one of -pid and -rootPid can be set") + util.Fatalf("only one of -pid and -rootPid can be set") } id := f.Arg(0) @@ -74,7 +75,7 @@ func (wt *Wait) Execute(_ context.Context, f *flag.FlagSet, args ...interface{}) c, err := container.Load(conf.RootDir, container.FullID{ContainerID: id}, container.LoadOpts{}) if err != nil { - Fatalf("loading container: %v", err) + util.Fatalf("loading container: %v", err) } var waitStatus unix.WaitStatus @@ -83,21 +84,21 @@ func (wt *Wait) Execute(_ context.Context, f *flag.FlagSet, args ...interface{}) case wt.rootPID == unsetPID && wt.pid == unsetPID: ws, err := c.Wait() if err != nil { - Fatalf("waiting on container %q: %v", c.ID, err) + util.Fatalf("waiting on container %q: %v", c.ID, err) } waitStatus = ws // Wait on a PID in the root PID namespace. case wt.rootPID != unsetPID: ws, err := c.WaitRootPID(int32(wt.rootPID)) if err != nil { - Fatalf("waiting on PID in root PID namespace %d in container %q: %v", wt.rootPID, c.ID, err) + util.Fatalf("waiting on PID in root PID namespace %d in container %q: %v", wt.rootPID, c.ID, err) } waitStatus = ws // Wait on a PID in the container's PID namespace. case wt.pid != unsetPID: ws, err := c.WaitPID(int32(wt.pid)) if err != nil { - Fatalf("waiting on PID %d in container %q: %v", wt.pid, c.ID, err) + util.Fatalf("waiting on PID %d in container %q: %v", wt.pid, c.ID, err) } waitStatus = ws } @@ -107,7 +108,7 @@ func (wt *Wait) Execute(_ context.Context, f *flag.FlagSet, args ...interface{}) } // Write json-encoded wait result directly to stdout. if err := json.NewEncoder(os.Stdout).Encode(result); err != nil { - Fatalf("marshaling wait result: %v", err) + util.Fatalf("marshaling wait result: %v", err) } return subcommands.ExitSuccess }