Skip to content

Commit 76df85b

Browse files
committed
implement guest manager interfaces for VM operations
Signed-off-by: Harsh Rawat <harshrawat@microsoft.com>
1 parent fa457e6 commit 76df85b

13 files changed

Lines changed: 918 additions & 0 deletions

File tree

internal/vm/README.md

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
# VM Package
2+
3+
This directory defines the utility VM (UVM) contracts and separates responsibilities into three layers. The goal is to keep
4+
configuration, host-side management, and guest-side actions distinct so each layer can evolve independently.
5+
6+
1. **Builder**: constructs an HCS compute system configuration used to create a VM.
7+
2. **VM Manager**: manages host-side VM configuration and lifecycle (NICs, SCSI, VPMem, etc.).
8+
3. **Guest Manager**: intended for guest-side actions (for example, mounting a disk).
9+
10+
**Note that** this layer does not store UVM host or guest side state. That will be part of the orchestration layer above it.
11+
12+
## Packages and Responsibilities
13+
14+
- `internal/vm`
15+
- Interface definitions and shared types.
16+
- `UVM` interface exposes APIs for lifecycle, resources, and device management of running VM.
17+
- `Builder` exposes APIs for shaping the configuration used to create a VM.
18+
- `GuestOps` defines guest-side operations executed via the GCS connection.
19+
- `internal/vm/builder`
20+
- Concrete implementation of `Builder` for building `hcsschema.ComputeSystem` documents.
21+
- Provides a fluent API for configuring all aspects of the VM document.
22+
- Presently, this package is tightly coupled with HCS backend.
23+
- `internal/vm/vmmanager`
24+
- Concrete implementation of `UVM` for running and managing a UVM instance.
25+
- Presently, this package is tightly coupled with HCS backend and only runs HCS backed UVMs.
26+
- Owns lifecycle calls (start/terminate/close) and host-side modifications (NICs, SCSI, VPMem, pipes, VSMB, Plan9).
27+
- Allows creation of the UVM using `vmmanager.Create` which takes a `Builder` and produces a running UVM.
28+
- `internal/vm/guestmanager`
29+
- Guest-side actions executed via the GCS connection.
30+
- Implements `vm.GuestOps` which provides APIs for network, storage, devices, security policy, and layers management within guest.
31+
- Translates guest operations into GCS modify requests.
32+
33+
## Typical Flow
34+
35+
1. Build the config using the builder interfaces.
36+
2. Create the VM using the VM manager.
37+
3. Use manager interfaces for lifecycle and host-side changes.
38+
4. Use guest manager interfaces for in-guest actions.
39+
40+
## Example (High Level)
41+
42+
```
43+
builder, _ := builder.New("owner", vm.Linux)
44+
45+
// Configure the VM document.
46+
builder.Memory().SetMemoryLimit(1024)
47+
builder.Processor().SetProcessorConfig(&vm.ProcessorConfig{Count: 2})
48+
// ... other builder configuration
49+
50+
// Create and start the VM.
51+
uvm, _ := vmmanager.Create(ctx, "uvm-id", builder)
52+
_ = uvm.LifetimeManager().Start(ctx)
53+
54+
// Apply host-side updates.
55+
_ = uvm.NetworkManager().AddNIC(ctx, nicID, endpointID, macAddr)
56+
```
57+
58+
## Layer Boundaries (Quick Reference)
59+
60+
- **Builder**: static, pre-create configuration only. No host mutations.
61+
- **VM Manager**: host-side changes and lifecycle operations on an existing UVM.
62+
- **Guest Manager**: guest-side actions, scoped to work that requires in-guest context (GCS-backed).

internal/vm/guest.go

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
package vm
2+
3+
import (
4+
"context"
5+
6+
"github.com/Microsoft/hcsshim/internal/gcs"
7+
hcsschema "github.com/Microsoft/hcsshim/internal/hcs/schema2"
8+
"github.com/Microsoft/hcsshim/internal/protocol/guestrequest"
9+
"github.com/Microsoft/hcsshim/internal/protocol/guestresource"
10+
)
11+
12+
// ConfigOption defines a function that modifies the GCS connection config.
13+
type ConfigOption func(*gcs.GuestConnectionConfig) error
14+
15+
// GuestOps is an interface to interact with
16+
type GuestOps interface {
17+
// CreateConnection creates a connection to the guest.
18+
CreateConnection(ctx context.Context, opts ...ConfigOption) error
19+
// CloseConnection closes the connection to the guest.
20+
CloseConnection() error
21+
// Capabilities returns the guest's declared capabilities.
22+
Capabilities() gcs.GuestDefinedCapabilities
23+
// LayersManager returns an interface to manage combined layers in the guest.
24+
LayersManager() LayersManager
25+
// GuestNetworkManager returns an interface to manage networking in the guest.
26+
GuestNetworkManager() GuestNetworkManager
27+
// DirectoryManager returns an interface to manage mapped directories in the guest.
28+
DirectoryManager() DirectoryManager
29+
// SecurityPolicyManager returns an interface to manage guest security policy operations.
30+
SecurityPolicyManager() SecurityPolicyManager
31+
// GuestDeviceManager returns an interface to manage device operations in the guest.
32+
GuestDeviceManager() GuestDeviceManager
33+
// BlockCIMsManager returns an interface to manage WCOW block CIMs in the guest.
34+
BlockCIMsManager() BlockCIMsManager
35+
// ScsiManager returns an interface to manage SCSI-related operations in the guest.
36+
ScsiManager() ScsiManager
37+
}
38+
39+
// LayersManager exposes combined layer operations in the guest.
40+
type LayersManager interface {
41+
AddCombinedLayers(ctx context.Context, settings interface{}) error
42+
AddCWCOWCombinedLayers(ctx context.Context, settings interface{}) error
43+
RemoveCombinedLayers(ctx context.Context, settings interface{}) error
44+
RemoveCWCOWCombinedLayers(ctx context.Context, settings interface{}) error
45+
}
46+
47+
// GuestNetworkManager exposes guest network operations.
48+
type GuestNetworkManager interface {
49+
AddNetworkNamespace(ctx context.Context, settings interface{}) error
50+
RemoveNetworkNamespace(ctx context.Context, settings interface{}) error
51+
AddNetworkInterface(ctx context.Context, adapterID string, requestType guestrequest.RequestType, settings interface{}) error
52+
AddNetworkInterfaceLCOW(ctx context.Context, settings *guestresource.LCOWNetworkAdapter) error
53+
RemoveNetworkInterface(ctx context.Context, adapterID string, requestType guestrequest.RequestType, settings interface{}) error
54+
RemoveNetworkInterfaceLCOW(ctx context.Context, settings *guestresource.LCOWNetworkAdapter) error
55+
}
56+
57+
// DirectoryManager exposes mapped directory operations in the guest.
58+
type DirectoryManager interface {
59+
AddMappedDirectory(ctx context.Context, settings *hcsschema.MappedDirectory) error
60+
AddMappedDirectoryLCOW(ctx context.Context, settings guestresource.LCOWMappedDirectory) error
61+
RemoveMappedDirectoryLCOW(ctx context.Context, settings guestresource.LCOWMappedDirectory) error
62+
}
63+
64+
// SecurityPolicyManager exposes guest security policy operations.
65+
type SecurityPolicyManager interface {
66+
AddSecurityPolicy(ctx context.Context, settings interface{}) error
67+
InjectPolicyFragment(ctx context.Context, settings guestresource.SecurityPolicyFragment) error
68+
}
69+
70+
// GuestDeviceManager exposes guest device operations.
71+
type GuestDeviceManager interface {
72+
AddVPCIDevice(ctx context.Context, vmBusGUID string) error
73+
AddVPMemDevice(ctx context.Context, settings guestresource.LCOWMappedVPMemDevice) error
74+
RemoveVPMemDevice(ctx context.Context, settings guestresource.LCOWMappedVPMemDevice) error
75+
}
76+
77+
// BlockCIMsManager exposes guest WCOW block CIM operations.
78+
type BlockCIMsManager interface {
79+
AddWCOWBlockCIMs(ctx context.Context, settings *guestresource.CWCOWBlockCIMMounts) error
80+
RemoveWCOWBlockCIMs(ctx context.Context, settings *guestresource.CWCOWBlockCIMMounts) error
81+
}
82+
83+
// ScsiManager exposes guest SCSI operations.
84+
type ScsiManager interface {
85+
AddMappedVirtualDisk(ctx context.Context, settings interface{}) error
86+
AddMappedVirtualDiskForContainerScratch(ctx context.Context, settings interface{}) error
87+
RemoveMappedVirtualDisk(ctx context.Context, settings interface{}) error
88+
RemoveSCSIDevice(ctx context.Context, settings guestresource.SCSIDevice) error
89+
}
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
//go:build windows
2+
3+
package guestmanager
4+
5+
import (
6+
"context"
7+
8+
hcsschema "github.com/Microsoft/hcsshim/internal/hcs/schema2"
9+
"github.com/Microsoft/hcsshim/internal/protocol/guestrequest"
10+
"github.com/Microsoft/hcsshim/internal/protocol/guestresource"
11+
"github.com/Microsoft/hcsshim/internal/vm"
12+
"github.com/pkg/errors"
13+
)
14+
15+
// BlockCIMsManager returns the guest block CIMs manager.
16+
func (gm *guestManager) BlockCIMsManager() vm.BlockCIMsManager {
17+
return gm
18+
}
19+
20+
// AddWCOWBlockCIMs adds WCOW block CIM mounts in the guest.
21+
func (gm *guestManager) AddWCOWBlockCIMs(ctx context.Context, settings *guestresource.CWCOWBlockCIMMounts) error {
22+
request := &hcsschema.ModifySettingRequest{
23+
GuestRequest: guestrequest.ModificationRequest{
24+
ResourceType: guestresource.ResourceTypeWCOWBlockCims,
25+
RequestType: guestrequest.RequestTypeAdd,
26+
Settings: settings,
27+
},
28+
}
29+
30+
err := gm.modify(ctx, request.GuestRequest)
31+
if err != nil {
32+
return errors.Wrap(err, "failed to add WCOW block CIMs")
33+
}
34+
35+
return nil
36+
}
37+
38+
// RemoveWCOWBlockCIMs removes WCOW block CIM mounts in the guest.
39+
func (gm *guestManager) RemoveWCOWBlockCIMs(ctx context.Context, settings *guestresource.CWCOWBlockCIMMounts) error {
40+
request := &hcsschema.ModifySettingRequest{
41+
GuestRequest: guestrequest.ModificationRequest{
42+
ResourceType: guestresource.ResourceTypeWCOWBlockCims,
43+
RequestType: guestrequest.RequestTypeRemove,
44+
Settings: settings,
45+
},
46+
}
47+
48+
err := gm.modify(ctx, request.GuestRequest)
49+
if err != nil {
50+
return errors.Wrap(err, "failed to remove WCOW block CIMs")
51+
}
52+
53+
return nil
54+
}
Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
//go:build windows
2+
3+
package guestmanager
4+
5+
import (
6+
"context"
7+
8+
hcsschema "github.com/Microsoft/hcsshim/internal/hcs/schema2"
9+
"github.com/Microsoft/hcsshim/internal/protocol/guestrequest"
10+
"github.com/Microsoft/hcsshim/internal/protocol/guestresource"
11+
"github.com/Microsoft/hcsshim/internal/vm"
12+
13+
"github.com/pkg/errors"
14+
)
15+
16+
// LayersManager returns the guest layers manager.
17+
func (gm *guestManager) LayersManager() vm.LayersManager {
18+
return gm
19+
}
20+
21+
// AddCombinedLayers adds combined layers in the guest.
22+
func (gm *guestManager) AddCombinedLayers(ctx context.Context, settings interface{}) error {
23+
modifyRequest := &hcsschema.ModifySettingRequest{
24+
GuestRequest: guestrequest.ModificationRequest{
25+
ResourceType: guestresource.ResourceTypeCombinedLayers,
26+
RequestType: guestrequest.RequestTypeAdd,
27+
Settings: settings,
28+
},
29+
}
30+
31+
err := gm.modify(ctx, modifyRequest.GuestRequest)
32+
if err != nil {
33+
return errors.Wrap(err, "AddCombinedLayers failed")
34+
}
35+
return nil
36+
}
37+
38+
// AddCWCOWCombinedLayers adds combined layers in CWCOW guest.
39+
func (gm *guestManager) AddCWCOWCombinedLayers(ctx context.Context, settings interface{}) error {
40+
modifyRequest := &hcsschema.ModifySettingRequest{
41+
GuestRequest: guestrequest.ModificationRequest{
42+
ResourceType: guestresource.ResourceTypeCWCOWCombinedLayers,
43+
RequestType: guestrequest.RequestTypeAdd,
44+
Settings: settings,
45+
},
46+
}
47+
48+
err := gm.modify(ctx, modifyRequest.GuestRequest)
49+
if err != nil {
50+
return errors.Wrap(err, "AddCWCOWCombinedLayers failed")
51+
}
52+
return nil
53+
}
54+
55+
// RemoveCombinedLayers removes combined layers in the guest.
56+
func (gm *guestManager) RemoveCombinedLayers(ctx context.Context, settings interface{}) error {
57+
modifyRequest := &hcsschema.ModifySettingRequest{
58+
GuestRequest: guestrequest.ModificationRequest{
59+
ResourceType: guestresource.ResourceTypeCombinedLayers,
60+
RequestType: guestrequest.RequestTypeRemove,
61+
Settings: settings,
62+
},
63+
}
64+
65+
err := gm.modify(ctx, modifyRequest.GuestRequest)
66+
if err != nil {
67+
return errors.Wrap(err, "RemoveCombinedLayers failed")
68+
}
69+
return nil
70+
}
71+
72+
// RemoveCWCOWCombinedLayers removes combined layers in CWCOW guest.
73+
func (gm *guestManager) RemoveCWCOWCombinedLayers(ctx context.Context, settings interface{}) error {
74+
modifyRequest := &hcsschema.ModifySettingRequest{
75+
GuestRequest: guestrequest.ModificationRequest{
76+
ResourceType: guestresource.ResourceTypeCWCOWCombinedLayers,
77+
RequestType: guestrequest.RequestTypeRemove,
78+
Settings: settings,
79+
},
80+
}
81+
82+
err := gm.modify(ctx, modifyRequest.GuestRequest)
83+
if err != nil {
84+
return errors.Wrap(err, "RemoveCWCOWCombinedLayers failed")
85+
}
86+
return nil
87+
}

internal/vm/guestmanager/device.go

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
//go:build windows
2+
3+
package guestmanager
4+
5+
import (
6+
"context"
7+
8+
hcsschema "github.com/Microsoft/hcsshim/internal/hcs/schema2"
9+
"github.com/Microsoft/hcsshim/internal/protocol/guestrequest"
10+
"github.com/Microsoft/hcsshim/internal/protocol/guestresource"
11+
"github.com/Microsoft/hcsshim/internal/vm"
12+
"github.com/pkg/errors"
13+
)
14+
15+
// GuestDeviceManager returns the guest device manager.
16+
func (gm *guestManager) GuestDeviceManager() vm.GuestDeviceManager {
17+
return gm
18+
}
19+
20+
// AddVPCIDevice adds a VPCI device in the guest.
21+
func (gm *guestManager) AddVPCIDevice(ctx context.Context, vmBusGUID string) error {
22+
request := &hcsschema.ModifySettingRequest{
23+
GuestRequest: guestrequest.ModificationRequest{
24+
ResourceType: guestresource.ResourceTypeVPCIDevice,
25+
RequestType: guestrequest.RequestTypeAdd,
26+
Settings: guestresource.LCOWMappedVPCIDevice{
27+
VMBusGUID: vmBusGUID,
28+
},
29+
},
30+
}
31+
32+
err := gm.modify(ctx, request.GuestRequest)
33+
if err != nil {
34+
return errors.Wrap(err, "failed to add VPCI device")
35+
}
36+
return nil
37+
}
38+
39+
// AddVPMemDevice adds a VPMem device in the guest.
40+
func (gm *guestManager) AddVPMemDevice(ctx context.Context, settings guestresource.LCOWMappedVPMemDevice) error {
41+
request := &hcsschema.ModifySettingRequest{
42+
GuestRequest: guestrequest.ModificationRequest{
43+
ResourceType: guestresource.ResourceTypeVPMemDevice,
44+
RequestType: guestrequest.RequestTypeAdd,
45+
Settings: settings,
46+
},
47+
}
48+
49+
err := gm.modify(ctx, request.GuestRequest)
50+
if err != nil {
51+
return errors.Wrap(err, "failed to add VPMem device")
52+
}
53+
return nil
54+
}
55+
56+
// RemoveVPMemDevice removes a VPMem device in the guest.
57+
func (gm *guestManager) RemoveVPMemDevice(ctx context.Context, settings guestresource.LCOWMappedVPMemDevice) error {
58+
request := &hcsschema.ModifySettingRequest{
59+
GuestRequest: guestrequest.ModificationRequest{
60+
ResourceType: guestresource.ResourceTypeVPMemDevice,
61+
RequestType: guestrequest.RequestTypeRemove,
62+
Settings: settings,
63+
},
64+
}
65+
66+
err := gm.modify(ctx, request.GuestRequest)
67+
if err != nil {
68+
return errors.Wrap(err, "failed to remove VPMem device")
69+
}
70+
return nil
71+
}

0 commit comments

Comments
 (0)