summaryrefslogtreecommitdiffhomepage
path: root/runsc/container/container.go
diff options
context:
space:
mode:
authorKevin Krakauer <krakauer@google.com>2018-06-19 21:42:21 -0700
committerShentubot <shentubot@google.com>2018-06-19 21:44:33 -0700
commit5397963b5d4d57bd3d3668df880b5314ca2fc3d8 (patch)
tree1e56b21b1248c0d74772e7daf368a6ab91e35911 /runsc/container/container.go
parentdb66e383c33228c43efbe16ad3b14ae9833879dc (diff)
runsc: Enable container creation within existing sandboxes.
Containers are created as processes in the sandbox. Of the many things that don't work yet, the biggest issue is that the fsgofer is launched with its root as the sandbox's root directory. Thus, when a container is started and wants to read anything (including the init binary of the container), the gofer tries to serve from sandbox's root (which basically just has pause), not the container's. PiperOrigin-RevId: 201294560 Change-Id: I6423aa8830538959c56ae908ce067e4199d627b1
Diffstat (limited to 'runsc/container/container.go')
-rw-r--r--runsc/container/container.go66
1 files changed, 47 insertions, 19 deletions
diff --git a/runsc/container/container.go b/runsc/container/container.go
index 571784e07..3b7f95af9 100644
--- a/runsc/container/container.go
+++ b/runsc/container/container.go
@@ -214,22 +214,43 @@ func Create(id string, spec *specs.Spec, conf *boot.Config, bundleDir, consoleSo
Owner: os.Getenv("USER"),
}
- // TODO: If the metadata annotations indicate that this
- // container should be started in another sandbox, we must do so. The
- // metadata will indicate the ID of the sandbox, which is the same as
- // the ID of the init container in the sandbox. We can look up that
- // init container by ID to get the sandbox, then we need to expose a
- // way to run a new container in the sandbox.
-
- // Start a new sandbox for this container. Any errors after this point
- // must destroy the container.
- s, err := sandbox.Create(id, spec, conf, bundleDir, consoleSocket)
- if err != nil {
- c.Destroy()
- return nil, err
- }
+ // If the metadata annotations indicate that this container should be
+ // started in an existing sandbox, we must do so. The metadata will
+ // indicate the ID of the sandbox, which is the same as the ID of the
+ // init container in the sandbox.
+ if specutils.ShouldCreateSandbox(spec) {
+ log.Debugf("Creating new sandbox for container %q", id)
+ // Start a new sandbox for this container. Any errors after this point
+ // must destroy the container.
+ s, err := sandbox.Create(id, spec, conf, bundleDir, consoleSocket)
+ if err != nil {
+ c.Destroy()
+ return nil, err
+ }
+ c.Sandbox = s
+ } else {
+ // This is sort of confusing. For a sandbox with a root
+ // container and a child container in it, runsc sees:
+ // * A container struct whose sandbox ID is equal to the
+ // container ID. This is the root container that is tied to
+ // the creation of the sandbox.
+ // * A container struct whose sandbox ID is equal to the above
+ // container/sandbox ID, but that has a different container
+ // ID. This is the child container.
+ sbid, ok := specutils.SandboxID(spec)
+ if !ok {
+ return nil, fmt.Errorf("no sandbox ID found when creating container")
+ }
+ log.Debugf("Creating new container %q in sandbox %q", c.ID, sbid)
- c.Sandbox = s
+ // Find the sandbox associated with this ID.
+ sb, err := Load(conf.RootDir, sbid)
+ if err != nil {
+ c.Destroy()
+ return nil, err
+ }
+ c.Sandbox = sb.Sandbox
+ }
c.Status = Created
// Save the metadata file.
@@ -242,7 +263,7 @@ func Create(id string, spec *specs.Spec, conf *boot.Config, bundleDir, consoleSo
// this file is created, so it must be the last thing we do.
if pidFile != "" {
if err := ioutil.WriteFile(pidFile, []byte(strconv.Itoa(c.Pid())), 0644); err != nil {
- s.Destroy()
+ c.Destroy()
return nil, fmt.Errorf("error writing pid file: %v", err)
}
}
@@ -266,9 +287,16 @@ func (c *Container) Start(conf *boot.Config) error {
}
}
- if err := c.Sandbox.Start(c.ID, c.Spec, conf); err != nil {
- c.Destroy()
- return err
+ if specutils.ShouldCreateSandbox(c.Spec) {
+ if err := c.Sandbox.StartRoot(c.Spec, conf); err != nil {
+ c.Destroy()
+ return err
+ }
+ } else {
+ if err := c.Sandbox.Start(c.Spec, conf); err != nil {
+ c.Destroy()
+ return err
+ }
}
// "If any poststart hook fails, the runtime MUST log a warning, but