From 205f1027e6beb84101439172b3c776c2671b5be8 Mon Sep 17 00:00:00 2001 From: Nicolas Lacasse Date: Tue, 15 May 2018 10:17:19 -0700 Subject: Refactor the Sandbox package into Sandbox + Container. This is a necessary prerequisite for supporting multiple containers in a single sandbox. All the commands (in cmd package) now call operations on Containers (container package). When a Container first starts, it will create a Sandbox with the same ID. The Sandbox class is now simpler, as it only knows how to create boot/gofer processes, and how to forward commands into the running boot process. There are TODOs sprinkled around for additional support for multiple containers. Most notably, we need to detect when a container is intended to run in an existing sandbox (by reading the metadata), and then have some way to signal to the sandbox to start a new container. Other urpc calls into the sandbox need to pass the container ID, so the sandbox can run the operation on the given container. These are only half-plummed through right now. PiperOrigin-RevId: 196688269 Change-Id: I1ecf4abbb9dd8987a53ae509df19341aaf42b5b0 --- runsc/cmd/BUILD | 2 +- runsc/cmd/cmd.go | 11 ----------- runsc/cmd/create.go | 17 +++++++++-------- runsc/cmd/delete.go | 18 +++++++++--------- runsc/cmd/events.go | 8 ++++---- runsc/cmd/exec.go | 20 ++++++++++---------- runsc/cmd/kill.go | 10 +++++----- runsc/cmd/list.go | 34 +++++++++++++++++----------------- runsc/cmd/ps.go | 8 ++++---- runsc/cmd/run.go | 6 +++--- runsc/cmd/start.go | 10 +++++----- runsc/cmd/state.go | 16 ++++++++-------- 12 files changed, 75 insertions(+), 85 deletions(-) (limited to 'runsc/cmd') diff --git a/runsc/cmd/BUILD b/runsc/cmd/BUILD index 128c8f7e6..08aaee996 100644 --- a/runsc/cmd/BUILD +++ b/runsc/cmd/BUILD @@ -32,8 +32,8 @@ go_library( "//pkg/unet", "//pkg/urpc", "//runsc/boot", + "//runsc/container", "//runsc/fsgofer", - "//runsc/sandbox", "//runsc/specutils", "@com_github_google_subcommands//:go_default_library", "@com_github_opencontainers_runtime-spec//specs-go:go_default_library", diff --git a/runsc/cmd/cmd.go b/runsc/cmd/cmd.go index d4b834213..9f7fd6e25 100644 --- a/runsc/cmd/cmd.go +++ b/runsc/cmd/cmd.go @@ -20,7 +20,6 @@ import ( "os" "strconv" - "flag" "gvisor.googlesource.com/gvisor/pkg/log" ) @@ -35,16 +34,6 @@ func Fatalf(s string, args ...interface{}) { os.Exit(128) } -// commandLineFlags returns a slice of all top-level command line flags that -// have been set. -func commandLineFlags() []string { - var args []string - flag.CommandLine.Visit(func(f *flag.Flag) { - args = append(args, fmt.Sprintf("--%s=%s", f.Name, f.Value.String())) - }) - return args -} - // intFlags can be used with int flags that appear multiple times. type intFlags []int diff --git a/runsc/cmd/create.go b/runsc/cmd/create.go index 83cb09eb0..94a889077 100644 --- a/runsc/cmd/create.go +++ b/runsc/cmd/create.go @@ -19,7 +19,7 @@ import ( "flag" "github.com/google/subcommands" "gvisor.googlesource.com/gvisor/runsc/boot" - "gvisor.googlesource.com/gvisor/runsc/sandbox" + "gvisor.googlesource.com/gvisor/runsc/container" "gvisor.googlesource.com/gvisor/runsc/specutils" ) @@ -30,8 +30,8 @@ type Create struct { bundleDir string // pidFile is the filename that the sandbox pid will be written to. - // This file should only be created once the sandbox process is ready - // to use (i.e. control server has started and is listening). + // This file should only be created once the container process inside + // the sandbox is ready to use. pidFile string // consoleSocket is the path to an AF_UNIX socket which will receive a @@ -61,7 +61,7 @@ func (*Create) Usage() string { func (c *Create) SetFlags(f *flag.FlagSet) { f.StringVar(&c.bundleDir, "bundle", "", "path to the root of the bundle directory, defaults to the current directory") f.StringVar(&c.consoleSocket, "console-socket", "", "path to an AF_UNIX socket which will receive a file descriptor referencing the master end of the console's pseudoterminal") - f.StringVar(&c.pidFile, "pid-file", "", "filename that the sandbox pid will be written to") + f.StringVar(&c.pidFile, "pid-file", "", "filename that the container pid will be written to") } // Execute implements subcommands.Command.Execute. @@ -84,10 +84,11 @@ func (c *Create) Execute(_ context.Context, f *flag.FlagSet, args ...interface{} } specutils.LogSpec(spec) - // Create the sandbox process, passing additional command line - // arguments to the sandbox process. - if _, err := sandbox.Create(id, spec, conf, bundleDir, c.consoleSocket, c.pidFile, commandLineFlags()); err != nil { - Fatalf("error creating sandbox: %v", err) + // 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); err != nil { + Fatalf("error creating container: %v", err) } return subcommands.ExitSuccess } diff --git a/runsc/cmd/delete.go b/runsc/cmd/delete.go index a497c034d..769a11c45 100644 --- a/runsc/cmd/delete.go +++ b/runsc/cmd/delete.go @@ -19,12 +19,12 @@ import ( "flag" "github.com/google/subcommands" "gvisor.googlesource.com/gvisor/runsc/boot" - "gvisor.googlesource.com/gvisor/runsc/sandbox" + "gvisor.googlesource.com/gvisor/runsc/container" ) // Delete implements subcommands.Command for the "delete" command. type Delete struct { - // force indicates that the sandbox should be terminated if running. + // force indicates that the container should be terminated if running. force bool } @@ -45,7 +45,7 @@ func (*Delete) Usage() string { // SetFlags implements subcommands.Command.SetFlags. func (d *Delete) SetFlags(f *flag.FlagSet) { - f.BoolVar(&d.force, "force", false, "terminate sandbox if running") + f.BoolVar(&d.force, "force", false, "terminate container if running") } // Execute implements subcommands.Command.Execute. @@ -59,15 +59,15 @@ func (d *Delete) Execute(_ context.Context, f *flag.FlagSet, args ...interface{} for i := 0; i < f.NArg(); i++ { id := f.Arg(i) - s, err := sandbox.Load(conf.RootDir, id) + c, err := container.Load(conf.RootDir, id) if err != nil { - Fatalf("error loading sandbox %q: %v", id, err) + Fatalf("error loading container %q: %v", id, err) } - if !d.force && (s.Status == sandbox.Running) { - Fatalf("cannot stop running sandbox without --force flag") + if !d.force && (c.Status == container.Running) { + Fatalf("cannot stop running container without --force flag") } - if err := s.Destroy(); err != nil { - Fatalf("error destroying sandbox: %v", err) + if err := c.Destroy(); err != nil { + Fatalf("error destroying container: %v", err) } } return subcommands.ExitSuccess diff --git a/runsc/cmd/events.go b/runsc/cmd/events.go index afd42c2f2..f221ad3ae 100644 --- a/runsc/cmd/events.go +++ b/runsc/cmd/events.go @@ -24,7 +24,7 @@ import ( "github.com/google/subcommands" "gvisor.googlesource.com/gvisor/pkg/log" "gvisor.googlesource.com/gvisor/runsc/boot" - "gvisor.googlesource.com/gvisor/runsc/sandbox" + "gvisor.googlesource.com/gvisor/runsc/container" ) // Events implements subcommands.Command for the "events" command. @@ -74,7 +74,7 @@ func (evs *Events) Execute(ctx context.Context, f *flag.FlagSet, args ...interfa id := f.Arg(0) conf := args[0].(*boot.Config) - s, err := sandbox.Load(conf.RootDir, id) + c, err := container.Load(conf.RootDir, id) if err != nil { Fatalf("error loading sandox: %v", err) } @@ -82,9 +82,9 @@ func (evs *Events) Execute(ctx context.Context, f *flag.FlagSet, args ...interfa // Repeatedly get stats from the container. for { // Get the event and print it as JSON. - ev, err := s.Event() + ev, err := c.Event() if err != nil { - log.Warningf("error getting events for sandbox: %v", err) + log.Warningf("error getting events for container: %v", err) } // err must be preserved because it is used below when breaking // out of the loop. diff --git a/runsc/cmd/exec.go b/runsc/cmd/exec.go index 052e00316..235ed9bc6 100644 --- a/runsc/cmd/exec.go +++ b/runsc/cmd/exec.go @@ -34,7 +34,7 @@ import ( "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/sandbox" + "gvisor.googlesource.com/gvisor/runsc/container" "gvisor.googlesource.com/gvisor/runsc/specutils" ) @@ -89,11 +89,11 @@ func (ex *Exec) SetFlags(f *flag.FlagSet) { f.Var(&ex.caps, "cap", "add a capability to the bounding set for the process") f.BoolVar(&ex.detach, "detach", false, "detach from the container's process") f.StringVar(&ex.processPath, "process", "", "path to the process.json") - f.StringVar(&ex.pidFile, "pid-file", "", "filename that the sandbox pid will be written to") + f.StringVar(&ex.pidFile, "pid-file", "", "filename that the container pid will be written to") } // Execute implements subcommands.Command.Execute. It starts a process in an -// already created sandbox. +// already created container. func (ex *Exec) Execute(_ context.Context, f *flag.FlagSet, args ...interface{}) subcommands.ExitStatus { e, id, err := ex.parseArgs(f) if err != nil { @@ -102,17 +102,17 @@ func (ex *Exec) Execute(_ context.Context, f *flag.FlagSet, args ...interface{}) conf := args[0].(*boot.Config) waitStatus := args[1].(*syscall.WaitStatus) - s, err := sandbox.Load(conf.RootDir, id) + c, err := container.Load(conf.RootDir, id) if err != nil { Fatalf("error loading sandox: %v", err) } if e.WorkingDirectory == "" { - e.WorkingDirectory = s.Spec.Process.Cwd + e.WorkingDirectory = c.Spec.Process.Cwd } if e.Envv == nil { - e.Envv, err = resolveEnvs(s.Spec.Process.Env, ex.env) + e.Envv, err = resolveEnvs(c.Spec.Process.Env, ex.env) if err != nil { Fatalf("error getting environment variables: %v", err) } @@ -136,15 +136,15 @@ func (ex *Exec) Execute(_ context.Context, f *flag.FlagSet, args ...interface{}) // inspect the environment PATH which is relative to the root path. // If the user is overriding environment variables, PATH may have been // overwritten. - rootPath := s.Spec.Root.Path + rootPath := c.Spec.Root.Path e.Filename, err = specutils.GetExecutablePath(e.Argv[0], rootPath, e.Envv) if err != nil { Fatalf("error getting executable path: %v", err) } - ws, err := s.Execute(e) + ws, err := c.Execute(e) if err != nil { - Fatalf("error getting processes for sandbox: %v", err) + Fatalf("error getting processes for container: %v", err) } *waitStatus = ws return subcommands.ExitSuccess @@ -196,7 +196,7 @@ func (ex *Exec) execAndWait(waitStatus *syscall.WaitStatus) subcommands.ExitStat // parseArgs parses exec information from the command line or a JSON file // depending on whether the --process flag was used. Returns an ExecArgs and -// the ID of the sandbox to be used. +// the ID of the container to be used. func (ex *Exec) parseArgs(f *flag.FlagSet) (*control.ExecArgs, string, error) { if ex.processPath == "" { // Requires at least a container ID and command. diff --git a/runsc/cmd/kill.go b/runsc/cmd/kill.go index f89e0077e..97a505fac 100644 --- a/runsc/cmd/kill.go +++ b/runsc/cmd/kill.go @@ -25,7 +25,7 @@ import ( "github.com/google/subcommands" "golang.org/x/sys/unix" "gvisor.googlesource.com/gvisor/runsc/boot" - "gvisor.googlesource.com/gvisor/runsc/sandbox" + "gvisor.googlesource.com/gvisor/runsc/container" ) // Kill implements subcommands.Command for the "kill" command. @@ -38,7 +38,7 @@ func (*Kill) Name() string { // Synopsis implements subcommands.Command.Synopsis. func (*Kill) Synopsis() string { - return "sends a signal to the sandbox" + return "sends a signal to the container" } // Usage implements subcommands.Command.Usage. @@ -64,9 +64,9 @@ func (*Kill) Execute(_ context.Context, f *flag.FlagSet, args ...interface{}) su id := f.Arg(0) conf := args[0].(*boot.Config) - s, err := sandbox.Load(conf.RootDir, id) + c, err := container.Load(conf.RootDir, id) if err != nil { - Fatalf("error loading sandbox: %v", err) + Fatalf("error loading container: %v", err) } // The OCI command-line spec says that the signal should be specified @@ -81,7 +81,7 @@ func (*Kill) Execute(_ context.Context, f *flag.FlagSet, args ...interface{}) su if err != nil { Fatalf("%v", err) } - if err := s.Signal(sig); err != nil { + if err := c.Signal(sig); err != nil { Fatalf("%v", err) } return subcommands.ExitSuccess diff --git a/runsc/cmd/list.go b/runsc/cmd/list.go index bf7cb41bb..d554bf7cf 100644 --- a/runsc/cmd/list.go +++ b/runsc/cmd/list.go @@ -26,7 +26,7 @@ import ( "github.com/google/subcommands" specs "github.com/opencontainers/runtime-spec/specs-go" "gvisor.googlesource.com/gvisor/runsc/boot" - "gvisor.googlesource.com/gvisor/runsc/sandbox" + "gvisor.googlesource.com/gvisor/runsc/container" ) // List implements subcommands.Command for the "list" command for the "list" command. @@ -64,7 +64,7 @@ func (l *List) Execute(_ context.Context, f *flag.FlagSet, args ...interface{}) } conf := args[0].(*boot.Config) - ids, err := sandbox.List(conf.RootDir) + ids, err := container.List(conf.RootDir) if err != nil { Fatalf("%v", err) } @@ -76,14 +76,14 @@ func (l *List) Execute(_ context.Context, f *flag.FlagSet, args ...interface{}) return subcommands.ExitSuccess } - // Collect the sandboxes. - var sandboxes []*sandbox.Sandbox + // Collect the containers. + var containers []*container.Container for _, id := range ids { - s, err := sandbox.Load(conf.RootDir, id) + c, err := container.Load(conf.RootDir, id) if err != nil { - Fatalf("error loading sandbox %q: %v", id, err) + Fatalf("error loading container %q: %v", id, err) } - sandboxes = append(sandboxes, s) + containers = append(containers, c) } switch l.format { @@ -91,24 +91,24 @@ func (l *List) Execute(_ context.Context, f *flag.FlagSet, args ...interface{}) // Print a nice table. w := tabwriter.NewWriter(os.Stdout, 12, 1, 3, ' ', 0) fmt.Fprint(w, "ID\tPID\tSTATUS\tBUNDLE\tCREATED\tOWNER\n") - for _, s := range sandboxes { + for _, c := range containers { fmt.Fprintf(w, "%s\t%d\t%s\t%s\t%s\t%s\n", - s.ID, - s.Pid, - s.Status, - s.BundleDir, - s.CreatedAt.Format(time.RFC3339Nano), - s.Owner) + c.ID, + c.Pid(), + c.Status, + c.BundleDir, + c.CreatedAt.Format(time.RFC3339Nano), + c.Owner) } w.Flush() case "json": // Print just the states. var states []specs.State - for _, s := range sandboxes { - states = append(states, s.State()) + for _, c := range containers { + states = append(states, c.State()) } if err := json.NewEncoder(os.Stdout).Encode(states); err != nil { - Fatalf("error marshaling sandbox state: %v", err) + Fatalf("error marshaling container state: %v", err) } default: Fatalf("unknown list format %q", l.format) diff --git a/runsc/cmd/ps.go b/runsc/cmd/ps.go index a667ec04c..9f9f4d15e 100644 --- a/runsc/cmd/ps.go +++ b/runsc/cmd/ps.go @@ -22,7 +22,7 @@ import ( "github.com/google/subcommands" "gvisor.googlesource.com/gvisor/pkg/sentry/control" "gvisor.googlesource.com/gvisor/runsc/boot" - "gvisor.googlesource.com/gvisor/runsc/sandbox" + "gvisor.googlesource.com/gvisor/runsc/container" ) // PS implements subcommands.Command for the "ps" command. @@ -60,13 +60,13 @@ func (ps *PS) Execute(ctx context.Context, f *flag.FlagSet, args ...interface{}) id := f.Arg(0) conf := args[0].(*boot.Config) - s, err := sandbox.Load(conf.RootDir, id) + c, err := container.Load(conf.RootDir, id) if err != nil { Fatalf("error loading sandox: %v", err) } - pList, err := s.Processes() + pList, err := c.Processes() if err != nil { - Fatalf("error getting processes for sandbox: %v", err) + Fatalf("error getting processes for container: %v", err) } switch ps.format { diff --git a/runsc/cmd/run.go b/runsc/cmd/run.go index a61a6c73e..681112f30 100644 --- a/runsc/cmd/run.go +++ b/runsc/cmd/run.go @@ -21,7 +21,7 @@ import ( "flag" "github.com/google/subcommands" "gvisor.googlesource.com/gvisor/runsc/boot" - "gvisor.googlesource.com/gvisor/runsc/sandbox" + "gvisor.googlesource.com/gvisor/runsc/container" "gvisor.googlesource.com/gvisor/runsc/specutils" ) @@ -72,9 +72,9 @@ func (r *Run) Execute(_ context.Context, f *flag.FlagSet, args ...interface{}) s Fatalf("error reading spec: %v", err) } - ws, err := sandbox.Run(id, spec, conf, bundleDir, r.consoleSocket, r.pidFile, commandLineFlags()) + ws, err := container.Run(id, spec, conf, bundleDir, r.consoleSocket, r.pidFile) if err != nil { - Fatalf("error running sandbox: %v", err) + Fatalf("error running container: %v", err) } *waitStatus = ws diff --git a/runsc/cmd/start.go b/runsc/cmd/start.go index a8e132497..97ea91fff 100644 --- a/runsc/cmd/start.go +++ b/runsc/cmd/start.go @@ -19,7 +19,7 @@ import ( "flag" "github.com/google/subcommands" "gvisor.googlesource.com/gvisor/runsc/boot" - "gvisor.googlesource.com/gvisor/runsc/sandbox" + "gvisor.googlesource.com/gvisor/runsc/container" ) // Start implements subcommands.Command for the "start" command. @@ -53,12 +53,12 @@ func (*Start) Execute(_ context.Context, f *flag.FlagSet, args ...interface{}) s id := f.Arg(0) conf := args[0].(*boot.Config) - s, err := sandbox.Load(conf.RootDir, id) + c, err := container.Load(conf.RootDir, id) if err != nil { - Fatalf("error loading sandbox: %v", err) + Fatalf("error loading container: %v", err) } - if err := s.Start(conf); err != nil { - Fatalf("error starting sandbox: %v", err) + if err := c.Start(conf); err != nil { + Fatalf("error starting container: %v", err) } return subcommands.ExitSuccess } diff --git a/runsc/cmd/state.go b/runsc/cmd/state.go index 0b47f290a..28752d95e 100644 --- a/runsc/cmd/state.go +++ b/runsc/cmd/state.go @@ -23,7 +23,7 @@ import ( "github.com/google/subcommands" "gvisor.googlesource.com/gvisor/pkg/log" "gvisor.googlesource.com/gvisor/runsc/boot" - "gvisor.googlesource.com/gvisor/runsc/sandbox" + "gvisor.googlesource.com/gvisor/runsc/container" ) // State implements subcommands.Command for the "state" command. @@ -36,12 +36,12 @@ func (*State) Name() string { // Synopsis implements subcommands.Command.Synopsis. func (*State) Synopsis() string { - return "get the state of a sandbox" + return "get the state of a container" } // Usage implements subcommands.Command.Usage. func (*State) Usage() string { - return `state [flags] - get the state of a sandbox` + return `state [flags] - get the state of a container` } // SetFlags implements subcommands.Command.SetFlags. @@ -57,16 +57,16 @@ func (*State) Execute(_ context.Context, f *flag.FlagSet, args ...interface{}) s id := f.Arg(0) conf := args[0].(*boot.Config) - s, err := sandbox.Load(conf.RootDir, id) + c, err := container.Load(conf.RootDir, id) if err != nil { - Fatalf("error loading sandbox: %v", err) + Fatalf("error loading container: %v", err) } - log.Debugf("Returning state %+v", s) + log.Debugf("Returning state for container %+v", c) // Write json-encoded state directly to stdout. - b, err := json.MarshalIndent(s.State(), "", " ") + b, err := json.MarshalIndent(c.State(), "", " ") if err != nil { - Fatalf("error marshaling sandbox state: %v", err) + Fatalf("error marshaling container state: %v", err) } os.Stdout.Write(b) return subcommands.ExitSuccess -- cgit v1.2.3