Skip to content

[shimV2] adds core pod, container and process controllers#2674

Open
rawahars wants to merge 1 commit intomicrosoft:mainfrom
rawahars:core-ctrls
Open

[shimV2] adds core pod, container and process controllers#2674
rawahars wants to merge 1 commit intomicrosoft:mainfrom
rawahars:core-ctrls

Conversation

@rawahars
Copy link
Copy Markdown
Contributor

Adds the internal/controller package hierarchy with three new sub-packages that provide lifecycle management for Linux Containers on Windows (LCOW):

  • linuxcontainer: manages the full lifecycle of a single LCOW container inside a Utility VM, including host-side resource allocation (SCSI layers, Plan9 shares, vPCI devices), guest-side container creation via the GCS, and state machine transitions.

  • pod: manages a single pod running inside a UVM, owning the network controller and tracking all container controllers belonging to the pod.

  • process: manages individual process (exec) instances within a container, handling IO plumbing, signal delivery, exit status reporting, and a linear state machine.

Each package includes comprehensive unit tests, mock types, and documentation.

Adds the `internal/controller` package hierarchy with three new
sub-packages that provide lifecycle management for Linux Containers on
Windows (LCOW):

- `linuxcontainer`: manages the full lifecycle of a single LCOW
  container inside a Utility VM, including host-side resource allocation (SCSI layers, Plan9 shares, vPCI devices), guest-side container
  creation via the GCS, and state machine transitions.

- `pod`: manages a single pod running inside a UVM, owning the network controller and tracking all container controllers belonging to the pod.

- `process`: manages individual process (exec) instances within a
  container, handling IO plumbing, signal delivery, exit status
  reporting, and a linear state machine.

Each package includes comprehensive unit tests, mock types, and documentation.

Signed-off-by: Harsh Rawat <harshrawat@microsoft.com>
c.mu.Lock()
defer c.mu.Unlock()

switch c.state {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Delete from NotCreated?

if signalOptions != nil {
isDelivered, err = c.process.Signal(ctx, signalOptions)
} else {
// Legacy path: signals are not supported, issue a direct terminate.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do we have a legacy path here? Legacy for who?

// examples:
// - sandbox:///a/dirInUvm destination:/b/dirInContainer
// - sandbox-tmp:///a/dirInUvm destination:/b/dirInContainer
// - uvm:///a/dirInUvm destination:/b/dirInContainer
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How are any of these different lol? The prefix examples all look the same

}

// Map the share into the guest.
guestPath, err := c.plan9.MapToGuest(ctx, reservationID)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Dont you need to immediately store the reservation? So if the Map is an error you can safely always unmap because you have the reservation?

isBlockDev := strings.HasPrefix(mount.Destination, guestpath.BlockDevMountPrefix)

// Reserve the mount.
reservationID, err := c.scsi.Reserve(ctx, diskConfig, scsiMount.Config{
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same here. Store it?

if spec.Root == nil {
spec.Root = &specs.Root{}
}
spec.Root.Path = c.layers.rootfsPath
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm. It seems like we should not apply changes to the original and do this after we have a deep copy right?

pciID, virtualFunctionIndex := vpci.GetDeviceInfoFromPath(device.ID)

// Reserve the device on the host.
vmBusGUID, err := c.vpci.Reserve(ctx, vpci.Device{
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Store it

}

// Parse the runtime options from the request.
shimOpts, err := vmutils.UnmarshalRuntimeOptions(ctx, opts.Options)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this stay in the service layer? I'm wondering if this create call should just take in the OCI spec and deserialized options?

ScratchPath: c.layers.scratch.guestPath,
}); err != nil {
log.G(ctx).WithError(err).Error("failed to remove combined layers from guest")
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you want this retryable you need to unwind the state. so like c.layers.layersCombined is now false if this succeeds so you dont go into here etc.

}

// Unmap additional SCSI mounts.
for _, id := range c.scsiResources {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same here, if you get a success you would remove that one so its continuable

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants