Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add containerd-shim plumbing for job containers #1

Merged
merged 1 commit into from
Mar 8, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
164 changes: 100 additions & 64 deletions cmd/containerd-shim-runhcs-v1/options/runhcs.pb.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 4 additions & 0 deletions cmd/containerd-shim-runhcs-v1/options/runhcs.proto
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,10 @@ message Options {
// This currently only affects LCOW. The sandbox containers scratch space is re-used for all
// subsequent containers launched in the pod.
bool share_scratch = 14;

// job_container specifies whether to have the runtime create job containers
// instead of the standard hcs containers.
bool job_container = 15;
}

// ProcessDetails contains additional information about a process. This is the additional
Expand Down
58 changes: 50 additions & 8 deletions cmd/containerd-shim-runhcs-v1/pod.go
Original file line number Diff line number Diff line change
Expand Up @@ -81,10 +81,15 @@ func createPod(ctx context.Context, events publisher, req *task.CreateTaskReques
sid)
}

p := pod{
events: events,
id: req.ID,
}

var parent *uvm.UtilityVM
owner := filepath.Base(os.Args[0])
isWCOW := oci.IsWCOW(s)

var parent *uvm.UtilityVM
if oci.IsIsolated(s) {
// Create the UVM parent
opts, err := oci.SpecToUVMCreateOpts(ctx, s, fmt.Sprintf("%s@vm", req.ID), owner)
Expand Down Expand Up @@ -128,19 +133,37 @@ func createPod(ctx context.Context, events publisher, req *task.CreateTaskReques
}
} else if !isWCOW {
return nil, errors.Wrap(errdefs.ErrFailedPrecondition, "oci spec does not contain WCOW or LCOW spec")
} else if oci.IsJobContainer(s) {
// If privileged was specified just fake a task (i.e reuse the wcowPodSandbox logic)
p.sandboxTask = newWcowPodSandboxTask(ctx, events, req.ID, req.Bundle, parent)
events.publishEvent(
ctx,
runtime.TaskCreateEventTopic,
&eventstypes.TaskCreate{
ContainerID: req.ID,
Bundle: req.Bundle,
Rootfs: req.Rootfs,
IO: &eventstypes.TaskIO{
Stdin: req.Stdin,
Stdout: req.Stdout,
Stderr: req.Stderr,
Terminal: req.Terminal,
},
Checkpoint: "",
Pid: 0,
})
p.jobContainer = true
return &p, nil
}

defer func() {
// clean up the uvm if we fail any further operations
if err != nil && parent != nil {
parent.Close()
}
}()

p := pod{
events: events,
id: req.ID,
host: parent,
}
p.host = parent
// TOOD: JTERRY75 - There is a bug in the compartment activation for Windows
// Process isolated that requires us to create the real pause container to
// hold the network compartment open. This is not required for Windows
Expand Down Expand Up @@ -187,7 +210,7 @@ func createPod(ctx context.Context, events publisher, req *task.CreateTaskReques
}
// LCOW (and WCOW Process Isolated for the time being) requires a real
// task for the sandbox.
lt, err := newHcsTask(ctx, events, parent, true, req, s)
lt, err := newHcsTask(ctx, events, parent, true, req, p.jobContainer, s)
if err != nil {
return nil, err
}
Expand Down Expand Up @@ -217,6 +240,11 @@ type pod struct {
// It MUST be treated as read only in the lifetime of the pod.
host *uvm.UtilityVM

// jobContainer specifies whether this pod is for WCOW job containers only.
//
// It MUST be treated as read only in the lifetime of the pod.
jobContainer bool

// wcl is the worload create mutex. All calls to CreateTask must hold this
// lock while the ID reservation takes place. Once the ID is held it is safe
// to release the lock to allow concurrent creates.
Expand Down Expand Up @@ -259,6 +287,20 @@ func (p *pod) CreateTask(ctx context.Context, req *task.CreateTaskRequest, s *sp
}
}()

if p.jobContainer {
// This is a short circuit to make sure that all containers in a pod will have
// the same IP address/be added to the same compartment.
//
// There is no way to go through the HNS namespace attach flow
// (send an attach request -> compartment created -> add vnic to compartment)
// without supplying a valid container ID to HNS so this is the blocker here.
// When this is supported in the OS this check can be removed and process and
// job containers can be mixed freely.
if !oci.IsJobContainer(s) {
return nil, errors.New("cannot create a normal process isolated container if the pod sandbox is a job container")
}
}

ct, sid, err := oci.GetSandboxTypeAndID(s.Annotations)
if err != nil {
return nil, err
Expand Down Expand Up @@ -289,7 +331,7 @@ func (p *pod) CreateTask(ctx context.Context, req *task.CreateTaskRequest, s *sp
if templateID != "" {
st, err = newClonedHcsTask(ctx, p.events, p.host, false, req, s, templateID)
} else {
st, err = newHcsTask(ctx, p.events, p.host, false, req, s)
st, err = newHcsTask(ctx, p.events, p.host, false, req, p.jobContainer, s)
}
if err != nil {
return nil, err
Expand Down
2 changes: 1 addition & 1 deletion cmd/containerd-shim-runhcs-v1/service_internal.go
Original file line number Diff line number Diff line change
Expand Up @@ -173,7 +173,7 @@ func (s *service) createInternal(ctx context.Context, req *task.CreateTaskReques
resp.Pid = uint32(e.Pid())
s.taskOrPod.Store(pod)
} else {
t, err := newHcsStandaloneTask(ctx, s.events, req, &spec)
t, err := newHcsStandaloneTask(ctx, s.events, req, false, &spec)
if err != nil {
s.cl.Unlock()
return nil, err
Expand Down
Loading