diff --git a/containers/containers.go b/containers/containers.go index c343a64a9..9aa0ba0d4 100644 --- a/containers/containers.go +++ b/containers/containers.go @@ -78,6 +78,8 @@ type Container struct { Extensions map[string]typeurl.Any // SandboxID is an identifier of sandbox this container belongs to. + // + // This property is optional, but can't be changed after creation. SandboxID string } diff --git a/runtime/runtime.go b/runtime/runtime.go index 1ca22ee2b..65c276c80 100644 --- a/runtime/runtime.go +++ b/runtime/runtime.go @@ -49,6 +49,8 @@ type CreateOpts struct { // Runtime name to use (e.g. `io.containerd.NAME.VERSION`). // As an alternative full abs path to binary may be specified instead. Runtime string + // SandboxID is an optional ID of sandbox this container belongs to + SandboxID string } // Exit information for a process diff --git a/runtime/v2/manager.go b/runtime/v2/manager.go index e98027551..51c6df616 100644 --- a/runtime/v2/manager.go +++ b/runtime/v2/manager.go @@ -373,9 +373,22 @@ func (m *TaskManager) ID() string { // Create launches new shim instance and creates new task func (m *TaskManager) Create(ctx context.Context, taskID string, opts runtime.CreateOpts) (runtime.Task, error) { - process, err := m.manager.Start(ctx, taskID, opts) - if err != nil { - return nil, fmt.Errorf("failed to start shim: %w", err) + var ( + process ShimProcess + err error + ) + + if opts.SandboxID != "" { + // This container belongs to sandbox which supposed to be already started via sandbox API. + process, err = m.manager.Get(ctx, opts.SandboxID) + if err != nil { + return nil, fmt.Errorf("can't find sandbox %s", opts.SandboxID) + } + } else { + process, err = m.manager.Start(ctx, taskID, opts) + if err != nil { + return nil, fmt.Errorf("failed to start shim: %w", err) + } } // Cast to shim task and call task service to create a new container task instance. diff --git a/sandbox/controller.go b/sandbox/controller.go index 3bf77d154..b0c24953f 100644 --- a/sandbox/controller.go +++ b/sandbox/controller.go @@ -22,22 +22,22 @@ import ( "github.com/gogo/protobuf/types" ) -// Controller is an interface to manage a runtime sandbox instance (runtimes's SandboxManager) -// SandboxRuntime is responsible for the sandbox instances lifecycle management. +// Controller is an interface to manage sandboxes at runtime. // When running the traditional containerd shim, the workflow looks as follows: // For each new task we're about to run: -// 1. Invoke `shim_binary --start` to obtain `TaskService` address (printed in stdout) -// 2. Call TaskService.RunContainer(id=1) -// 3. Exec `shim_binary --delete` to stop shim -// 4. Exec `shim_binary --start` again to obtain another `TaskService` address -// 5. TaskService.RunContainer(id=2) -// 6. Exec `shim_binary --delete` to stop shim +// 1. Invoke `shim_binary --start` to obtain `TaskService` address (printed in stdout) +// 2. Call TaskService.RunContainer(id=1) +// 3. Exec `shim_binary --delete` to stop shim +// 4. Exec `shim_binary --start` again to obtain another `TaskService` address +// 5. TaskService.RunContainer(id=2) +// 6. Exec `shim_binary --delete` to stop shim // -// When running in sandbox mode, shim must implement `SandboxService`. In sandbox mode shim lifetimes are managed manually. -// 1. Client calls `client.Controller.Start()` to launch new shim and create sandbox process -// 2. Run containers with `shim.TaskService.RunContainer(id=1)` and another one `shim.TaskService.RunContainer(id=2)` -// 3. ... usual container lifecycle calls to `shim.TaskService` -// 4. Client calls shim to stop the sandbox with `client.SandboxService.Shutdown()` +// When running in sandbox mode, shim must implement `SandboxService`. +// In sandbox mode shim lifetimes are managed manually via sandbox API. +// 1. Client calls `client.SandboxController.Start()` to launch new shim and create sandbox process +// 2. Run containers with `shim.TaskService.RunContainer(id=1)` and another one `shim.TaskService.RunContainer(id=2)` +// 3. ... usual container lifecycle calls to `shim.TaskService` +// 4. Client calls shim to stop the sandbox with `client.SandboxService.Shutdown()` // 5. Shim implementation will perform cleanup similar to regular task service (e.g. shutdown, clean, and `shim_binary --delete`) type Controller interface { // Start will start new sandbox instance. diff --git a/services/tasks/local.go b/services/tasks/local.go index f57748ff5..8e7ac4933 100644 --- a/services/tasks/local.go +++ b/services/tasks/local.go @@ -200,6 +200,7 @@ func (l *local) Create(ctx context.Context, r *api.CreateTaskRequest, _ ...grpc. Runtime: container.Runtime.Name, RuntimeOptions: container.Runtime.Options, TaskOptions: r.Options, + SandboxID: container.SandboxID, } if r.RuntimePath != "" { opts.Runtime = r.RuntimePath