-
Couldn't load subscription status.
- Fork 273
Adding support for WCOW UVM log forward service #2524
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
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -71,6 +71,15 @@ var WindowsGcsHvHostID = guid.GUID{ | |
| Data4: [8]uint8{0x93, 0xfe, 0x42, 0x96, 0x9a, 0xe6, 0xd8, 0xd1}, | ||
| } | ||
|
|
||
| // WindowsLoggingHvsockServiceID is the hvsock service ID that the Windows log forward service | ||
| // will connect to. 172dad59-976d-45f2-8b6c-6d1b13f2ac4d | ||
| var WindowsLoggingHvsockServiceID = guid.GUID{ | ||
| Data1: 0x172dad59, | ||
| Data2: 0x976d, | ||
| Data3: 0x45f2, | ||
| Data4: [8]uint8{0x8b, 0x6c, 0x6d, 0x1b, 0x13, 0xf2, 0xac, 0x4d}, | ||
| } | ||
|
|
||
| type AnyInString struct { | ||
| Value interface{} | ||
| } | ||
|
|
@@ -83,10 +92,17 @@ func (a *AnyInString) UnmarshalText(b []byte) error { | |
| return json.Unmarshal(b, &a.Value) | ||
| } | ||
|
|
||
| const ( | ||
| // Message_Category for the GCS protocol. | ||
| ComputeSystem = 0x00100000 | ||
| ComputeService = 0x00200000 | ||
| ) | ||
|
|
||
| type RPCProc uint32 | ||
|
|
||
| const ( | ||
| RPCCreate RPCProc = (iota+1)<<8 | 1 | ||
| // Compute System RPCs | ||
| RPCCreate RPCProc = ComputeSystem | (iota+1)<<8 | 1 | ||
| RPCStart | ||
| RPCShutdownGraceful | ||
| RPCShutdownForced | ||
|
|
@@ -103,6 +119,26 @@ const ( | |
| RPCLifecycleNotification | ||
| ) | ||
|
|
||
| const ( | ||
| // Compute Service RPCs | ||
| RPCModifyServiceSettings RPCProc = ComputeService | (iota+1)<<8 | 1 | ||
| ) | ||
|
|
||
| type ServiceModifyPropertyType uint32 | ||
|
|
||
| const ( | ||
| LogForwardService ServiceModifyPropertyType = iota | ||
| ) | ||
|
|
||
| func (m ServiceModifyPropertyType) String() string { | ||
| switch m { | ||
| case LogForwardService: | ||
| return "LogForwardService" | ||
| default: | ||
| return fmt.Sprintf("UnknownModifyServiceType(%d)", m) | ||
| } | ||
| } | ||
|
|
||
| func (rpc RPCProc) String() string { | ||
| switch rpc { | ||
| case RPCCreate: | ||
|
|
@@ -135,6 +171,8 @@ func (rpc RPCProc) String() string { | |
| return "UpdateContainer" | ||
| case RPCLifecycleNotification: | ||
| return "LifecycleNotification" | ||
| case RPCModifyServiceSettings: | ||
rawahars marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| return "ModifyServiceSettings" | ||
| default: | ||
| return "0x" + strconv.FormatUint(uint64(rpc), 16) | ||
| } | ||
|
|
@@ -143,10 +181,10 @@ func (rpc RPCProc) String() string { | |
| type MsgType uint32 | ||
|
|
||
| const ( | ||
| MsgTypeRequest MsgType = 0x10100000 | ||
| MsgTypeResponse MsgType = 0x20100000 | ||
| MsgTypeNotify MsgType = 0x30100000 | ||
| MsgTypeMask MsgType = 0xfff00000 | ||
| MsgTypeRequest MsgType = 0x10000000 | ||
| MsgTypeResponse MsgType = 0x20000000 | ||
| MsgTypeNotify MsgType = 0x30000000 | ||
| MsgTypeMask MsgType = 0xf0000000 | ||
|
Comment on lines
+184
to
+187
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Good catch! |
||
|
|
||
| NotifyContainer = 1<<8 | 1 | ||
| ) | ||
|
|
@@ -160,7 +198,7 @@ func (typ MsgType) String() string { | |
| s = "Response(" | ||
| case MsgTypeNotify: | ||
| s = "Notify(" | ||
| switch typ - MsgTypeNotify { | ||
| switch typ - (ComputeSystem | MsgTypeNotify) { | ||
| case NotifyContainer: | ||
| s += "Container" | ||
| default: | ||
|
|
@@ -267,6 +305,12 @@ type ContainerNotification struct { | |
| ResultInfo AnyInString `json:",omitempty"` | ||
| } | ||
|
|
||
| type ServiceModificationRequest struct { | ||
| RequestBase | ||
| PropertyType string // ServiceModifyPropertyType | ||
| Settings interface{} `json:",omitempty"` | ||
| } | ||
|
|
||
| type ContainerExecuteProcess struct { | ||
| RequestBase | ||
| Settings ExecuteProcessSettings | ||
|
|
@@ -345,13 +389,14 @@ type ContainerModifySettings struct { | |
| } | ||
|
|
||
| type GcsCapabilities struct { | ||
| SendHostCreateMessage bool | ||
| SendHostStartMessage bool | ||
| HvSocketConfigOnStartup bool | ||
| SendLifecycleNotifications bool | ||
| SupportedSchemaVersions []hcsschema.Version | ||
| RuntimeOsType string | ||
| GuestDefinedCapabilities json.RawMessage | ||
| SendHostCreateMessage bool | ||
| SendHostStartMessage bool | ||
| HvSocketConfigOnStartup bool | ||
| SendLifecycleNotifications bool | ||
| ModifyServiceSettingsSupported bool | ||
| SupportedSchemaVersions []hcsschema.Version | ||
| RuntimeOsType string | ||
| GuestDefinedCapabilities json.RawMessage | ||
| } | ||
|
|
||
| type ContainerCreateResponse struct { | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -59,6 +59,10 @@ type OptionsWCOW struct { | |
|
|
||
| // AdditionalRegistryKeys are Registry keys and their values to additionally add to the uVM. | ||
| AdditionalRegistryKeys []hcsschema.RegistryValue | ||
|
|
||
| OutputHandlerCreator OutputHandlerCreator // Creates an [OutputHandler] that controls how output received over HVSocket from the UVM is handled. Defaults to parsing output as ETW Log events | ||
| LogSources string // ETW providers to be set for the logging service | ||
| ForwardLogs bool // Whether to forward logs to the host or not | ||
marma-dev marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| } | ||
|
|
||
| func defaultConfidentialWCOWOSBootFilesPath() string { | ||
|
|
@@ -89,6 +93,9 @@ func NewDefaultOptionsWCOW(id, owner string) *OptionsWCOW { | |
| Options: newDefaultOptions(id, owner), | ||
| AdditionalRegistryKeys: []hcsschema.RegistryValue{}, | ||
| ConfidentialWCOWOptions: &ConfidentialWCOWOptions{}, | ||
| OutputHandlerCreator: parseLogrus, | ||
| ForwardLogs: true, // Default to true for WCOW, and set to false for CWCOW in internal/oci/uvm.go SpecToUVMCreateOpts | ||
| LogSources: "", | ||
| } | ||
| } | ||
|
|
||
|
|
@@ -259,6 +266,12 @@ func prepareCommonConfigDoc(ctx context.Context, uvm *UtilityVM, opts *OptionsWC | |
| } | ||
|
|
||
| maps.Copy(doc.VirtualMachine.Devices.HvSocket.HvSocketConfig.ServiceTable, opts.AdditionalHyperVConfig) | ||
| key := prot.WindowsLoggingHvsockServiceID.String() | ||
| doc.VirtualMachine.Devices.HvSocket.HvSocketConfig.ServiceTable[key] = hcsschema.HvSocketServiceConfig{ | ||
| AllowWildcardBinds: true, | ||
| BindSecurityDescriptor: "D:P(A;;FA;;;SY)(A;;FA;;;BA)", | ||
| ConnectSecurityDescriptor: "D:P(A;;FA;;;SY)(A;;FA;;;BA)", | ||
| } | ||
|
Comment on lines
+269
to
+274
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. similar to There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There is a proposal to have option of being able to enable log forwarding by uvm update, but not implemented yet. Keeping that in mind, we would prefer this hvsocket being always there even though initially forwardlogs could be false at the time of creation |
||
|
|
||
| // Handle StorageQoS if set | ||
| if opts.StorageQoSBandwidthMaximum > 0 || opts.StorageQoSIopsMaximum > 0 { | ||
|
|
@@ -507,6 +520,8 @@ func CreateWCOW(ctx context.Context, opts *OptionsWCOW) (_ *UtilityVM, err error | |
| noWritableFileShares: opts.NoWritableFileShares, | ||
| createOpts: *opts, | ||
| blockCIMMounts: make(map[string]*UVMMountedBlockCIMs), | ||
| logSources: opts.LogSources, | ||
| forwardLogs: opts.ForwardLogs, | ||
| } | ||
|
|
||
| defer func() { | ||
|
|
@@ -536,6 +551,15 @@ func CreateWCOW(ctx context.Context, opts *OptionsWCOW) (_ *UtilityVM, err error | |
| return nil, fmt.Errorf("error while creating the compute system: %w", err) | ||
| } | ||
|
|
||
| // Create a socket that the executed program can send to. This is usually | ||
| // used by Log Forward Service to send log data. | ||
| uvm.outputHandler = opts.OutputHandlerCreator(opts.Options) | ||
| uvm.outputProcessingDone = make(chan struct{}) | ||
| uvm.outputListener, err = winio.ListenHvsock(&winio.HvsockAddr{ | ||
| VMID: uvm.RuntimeID(), | ||
| ServiceID: prot.WindowsLoggingHvsockServiceID, | ||
| }) | ||
|
Comment on lines
+556
to
+561
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. can we gate this on There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There is a proposal to have option of being able to enable log forwarding by uvm update, but not implemented yet. Keeping that in mind, we would prefer this outputhandler being always there even though initially forwardlogs could be false at the time of creation as log service could start forwarding logs later on |
||
|
|
||
| gcsServiceID := prot.WindowsGcsHvsockServiceID | ||
| if opts.SecurityPolicyEnabled { | ||
| gcsServiceID = prot.WindowsSidecarGcsHvsockServiceID | ||
|
|
||
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,69 @@ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| //go:build windows | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| package uvm | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import ( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| "context" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| "github.com/Microsoft/hcsshim/internal/gcs" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| "github.com/Microsoft/hcsshim/internal/gcs/prot" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| "github.com/Microsoft/hcsshim/internal/log" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| "github.com/Microsoft/hcsshim/internal/protocol/guestrequest" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| func (uvm *UtilityVM) StartLogForwarding(ctx context.Context) error { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // Implementation for stopping the log forwarder | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if uvm.OS() == "windows" && uvm.gc != nil { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| wcaps := gcs.GetWCOWCapabilities(uvm.gc.Capabilities()) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if wcaps != nil && wcaps.IsLogForwardingSupported() { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| req := guestrequest.LogForwardServiceRPCRequest{ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| RPCType: guestrequest.RPCStartLogForwarding, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Settings: "", | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| err := uvm.gc.ModifyServiceSettings(ctx, prot.LogForwardService, req) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if err != nil { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return err | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } else { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| log.G(ctx).WithField("os", uvm.operatingSystem).Error("Log forwarding not supported for this OS") | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return nil | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+16
to
+31
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| func (uvm *UtilityVM) StopLogForwarding(ctx context.Context) error { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // Implementation for stopping the log forwarder | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if uvm.OS() == "windows" && uvm.gc != nil { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| wcaps := gcs.GetWCOWCapabilities(uvm.gc.Capabilities()) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if wcaps != nil && wcaps.IsLogForwardingSupported() { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| req := guestrequest.LogForwardServiceRPCRequest{ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| RPCType: guestrequest.RPCStopLogForwarding, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Settings: "", | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| err := uvm.gc.ModifyServiceSettings(ctx, prot.LogForwardService, req) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if err != nil { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return err | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return nil | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| func (uvm *UtilityVM) SetLogSources(ctx context.Context) error { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // Implementation for setting the log sources | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if uvm.OS() == "windows" && uvm.logSources != "" && uvm.gc != nil { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| wcaps := gcs.GetWCOWCapabilities(uvm.gc.Capabilities()) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if wcaps != nil && wcaps.IsLogForwardingSupported() { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // Make a call to the GCS to set the ETW providers | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| req := guestrequest.LogForwardServiceRPCRequest{ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| RPCType: guestrequest.RPCModifyServiceSettings, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Settings: uvm.logSources, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| err := uvm.gc.ModifyServiceSettings(ctx, prot.LogForwardService, req) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if err != nil { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return err | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return nil | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we not have
ServiceModifyPropertyTypebe a string, similar to thePropertyTypeandRequestTypeenums, since we don't ever need to use the integer value?\