1
2
3
4 package prot
5
6 import (
7 "encoding/json"
8 "strconv"
9
10 v1 "github.com/containerd/cgroups/stats/v1"
11 oci "github.com/opencontainers/runtime-spec/specs-go"
12 "github.com/pkg/errors"
13
14 "github.com/Microsoft/hcsshim/internal/guest/commonutils"
15 hcsschema "github.com/Microsoft/hcsshim/internal/hcs/schema2"
16 "github.com/Microsoft/hcsshim/internal/protocol/guestrequest"
17 "github.com/Microsoft/hcsshim/internal/protocol/guestresource"
18 )
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33 const (
34 messageTypeMask = 0xF0000000
35 messageCategoryMask = 0x0FF00000
36 messageIDMask = 0x000FFF00
37 messageVersionMask = 0x000000FF
38 messageIDShift = 8
39 messageVersionShift = 0
40 )
41
42
43 type MessageType uint32
44
45 const (
46
47 MtNone = 0
48
49 MtRequest = 0x10000000
50
51 MtResponse = 0x20000000
52
53
54 MtNotification = 0x30000000
55 )
56
57
58
59 type MessageCategory uint32
60
61 const (
62
63 McNone = 0
64
65
66 McComputeSystem = 0x00100000
67 )
68
69
70
71
72 func GetResponseIdentifier(identifier MessageIdentifier) MessageIdentifier {
73 return MessageIdentifier(MtResponse | (uint32(identifier) & ^uint32(messageTypeMask)))
74 }
75
76
77 type MessageIdentifier uint32
78
79 const (
80
81 MiNone = 0
82
83
84 ComputeSystemCreateV1 = 0x10100101
85
86 ComputeSystemStartV1 = 0x10100201
87
88
89 ComputeSystemShutdownGracefulV1 = 0x10100301
90
91 ComputeSystemShutdownForcedV1 = 0x10100401
92
93 ComputeSystemExecuteProcessV1 = 0x10100501
94
95 ComputeSystemWaitForProcessV1 = 0x10100601
96
97 ComputeSystemSignalProcessV1 = 0x10100701
98
99 ComputeSystemResizeConsoleV1 = 0x10100801
100
101 ComputeSystemGetPropertiesV1 = 0x10100901
102
103 ComputeSystemModifySettingsV1 = 0x10100a01
104
105 ComputeSystemNegotiateProtocolV1 = 0x10100b01
106
107 ComputeSystemDumpStacksV1 = 0x10100c01
108
109 ComputeSystemDeleteContainerStateV1 = 0x10100d01
110
111
112 ComputeSystemResponseCreateV1 = 0x20100101
113
114 ComputeSystemResponseStartV1 = 0x20100201
115
116
117 ComputeSystemResponseShutdownGracefulV1 = 0x20100301
118
119
120 ComputeSystemResponseShutdownForcedV1 = 0x20100401
121
122 ComputeSystemResponseExecuteProcessV1 = 0x20100501
123
124
125 ComputeSystemResponseWaitForProcessV1 = 0x20100601
126
127 ComputeSystemResponseSignalProcessV1 = 0x20100701
128
129 ComputeSystemResponseResizeConsoleV1 = 0x20100801
130
131
132 ComputeSystemResponseGetPropertiesV1 = 0x20100901
133
134 ComputeSystemResponseModifySettingsV1 = 0x20100a01
135
136
137 ComputeSystemResponseNegotiateProtocolV1 = 0x20100b01
138
139 ComputeSystemResponseDumpStacksV1 = 0x20100c01
140
141
142 ComputeSystemNotificationV1 = 0x30100101
143 )
144
145
146 func (mi MessageIdentifier) String() string {
147 switch mi {
148 case MiNone:
149 return "None"
150 case ComputeSystemCreateV1:
151 return "ComputeSystemCreateV1"
152 case ComputeSystemStartV1:
153 return "ComputeSystemStartV1"
154 case ComputeSystemShutdownGracefulV1:
155 return "ComputeSystemShutdownGracefulV1"
156 case ComputeSystemShutdownForcedV1:
157 return "ComputeSystemShutdownForcedV1"
158 case ComputeSystemExecuteProcessV1:
159 return "ComputeSystemExecuteProcessV1"
160 case ComputeSystemWaitForProcessV1:
161 return "ComputeSystemWaitForProcessV1"
162 case ComputeSystemSignalProcessV1:
163 return "ComputeSystemSignalProcessV1"
164 case ComputeSystemResizeConsoleV1:
165 return "ComputeSystemResizeConsoleV1"
166 case ComputeSystemGetPropertiesV1:
167 return "ComputeSystemGetPropertiesV1"
168 case ComputeSystemModifySettingsV1:
169 return "ComputeSystemModifySettingsV1"
170 case ComputeSystemNegotiateProtocolV1:
171 return "ComputeSystemNegotiateProtocolV1"
172 case ComputeSystemDumpStacksV1:
173 return "ComputeSystemDumpStacksV1"
174 case ComputeSystemDeleteContainerStateV1:
175 return "ComputeSystemDeleteContainerStateV1"
176 case ComputeSystemResponseCreateV1:
177 return "ComputeSystemResponseCreateV1"
178 case ComputeSystemResponseStartV1:
179 return "ComputeSystemResponseStartV1"
180 case ComputeSystemResponseShutdownGracefulV1:
181 return "ComputeSystemResponseShutdownGracefulV1"
182 case ComputeSystemResponseShutdownForcedV1:
183 return "ComputeSystemResponseShutdownForcedV1"
184 case ComputeSystemResponseExecuteProcessV1:
185 return "ComputeSystemResponseExecuteProcessV1"
186 case ComputeSystemResponseWaitForProcessV1:
187 return "ComputeSystemResponseWaitForProcessV1"
188 case ComputeSystemResponseSignalProcessV1:
189 return "ComputeSystemResponseSignalProcessV1"
190 case ComputeSystemResponseResizeConsoleV1:
191 return "ComputeSystemResponseResizeConsoleV1"
192 case ComputeSystemResponseGetPropertiesV1:
193 return "ComputeSystemResponseGetPropertiesV1"
194 case ComputeSystemResponseModifySettingsV1:
195 return "ComputeSystemResponseModifySettingsV1"
196 case ComputeSystemResponseNegotiateProtocolV1:
197 return "ComputeSystemResponseNegotiateProtocolV1"
198 case ComputeSystemResponseDumpStacksV1:
199 return "ComputeSystemResponseDumpStacksV1"
200 case ComputeSystemNotificationV1:
201 return "ComputeSystemNotificationV1"
202 default:
203 return strconv.FormatUint(uint64(mi), 10)
204 }
205 }
206
207
208 type SequenceID uint64
209
210
211 type MessageHeader struct {
212 Type MessageIdentifier
213 Size uint32
214 ID SequenceID
215 }
216
217
218 const MessageHeaderSize = 16
219
220
221
222
223
224 type ProtocolVersion uint32
225
226
227 const (
228 PvInvalid ProtocolVersion = 0
229 PvV4 ProtocolVersion = 4
230 PvMax ProtocolVersion = PvV4
231 )
232
233
234
235 type ProtocolSupport struct {
236 MinimumVersion string `json:",omitempty"`
237 MaximumVersion string `json:",omitempty"`
238 MinimumProtocolVersion uint32
239 MaximumProtocolVersion uint32
240 }
241
242
243
244 type OsType string
245
246
247 const OsTypeLinux OsType = "Linux"
248
249
250 type GcsCapabilities struct {
251
252 SendHostCreateMessage bool `json:",omitempty"`
253
254
255 SendHostStartMessage bool `json:",omitempty"`
256
257
258
259
260
261 HVSocketConfigOnStartup bool `json:"HvSocketConfigOnStartup,omitempty"`
262 SupportedSchemaVersions []SchemaVersion `json:",omitempty"`
263 RuntimeOsType OsType `json:",omitempty"`
264
265
266
267 GuestDefinedCapabilities GcsGuestCapabilities `json:",omitempty"`
268 }
269
270
271
272 type GcsGuestCapabilities struct {
273 NamespaceAddRequestSupported bool `json:",omitempty"`
274 SignalProcessSupported bool `json:",omitempty"`
275 DumpStacksSupported bool `json:",omitempty"`
276 DeleteContainerStateSupported bool `json:",omitempty"`
277 }
278
279
280
281 type ocspancontext struct {
282
283
284 TraceID string `json:",omitempty"`
285
286
287 SpanID string `json:",omitempty"`
288
289
290
291 TraceOptions uint32 `json:",omitempty"`
292
293
294
295
296
297
298 Tracestate string `json:",omitempty"`
299 }
300
301
302
303 type MessageBase struct {
304 ContainerID string `json:"ContainerId"`
305 ActivityID string `json:"ActivityId"`
306
307
308
309
310
311
312
313 OpenCensusSpanContext *ocspancontext `json:"ocsc,omitempty"`
314 }
315
316
317
318 type NegotiateProtocol struct {
319 MessageBase
320 MinimumVersion uint32
321 MaximumVersion uint32
322 }
323
324
325
326
327
328 type ContainerCreate struct {
329 MessageBase
330 ContainerConfig string
331 SupportedVersions ProtocolSupport `json:",omitempty"`
332 }
333
334
335 type NotificationType string
336
337 const (
338
339 NtNone = NotificationType("None")
340
341
342 NtGracefulExit = NotificationType("GracefulExit")
343
344
345 NtForcedExit = NotificationType("ForcedExit")
346
347
348 NtUnexpectedExit = NotificationType("UnexpectedExit")
349
350 NtReboot = NotificationType("Reboot")
351
352
353 NtConstructed = NotificationType("Constructed")
354
355 NtStarted = NotificationType("Started")
356
357 NtPaused = NotificationType("Paused")
358
359 NtUnknown = NotificationType("Unknown")
360 )
361
362
363
364 type ActiveOperation string
365
366 const (
367
368 AoNone = ActiveOperation("None")
369
370 AoConstruct = ActiveOperation("Construct")
371
372 AoStart = ActiveOperation("Start")
373
374 AoPause = ActiveOperation("Pause")
375
376 AoResume = ActiveOperation("Resume")
377
378 AoShutdown = ActiveOperation("Shutdown")
379
380 AoTerminate = ActiveOperation("Terminate")
381 )
382
383
384
385
386 type ContainerNotification struct {
387 MessageBase
388 Type NotificationType
389 Operation ActiveOperation
390 Result int32
391 ResultInfo string `json:",omitempty"`
392 }
393
394
395
396 type ExecuteProcessVsockStdioRelaySettings struct {
397 StdIn uint32 `json:",omitempty"`
398 StdOut uint32 `json:",omitempty"`
399 StdErr uint32 `json:",omitempty"`
400 }
401
402
403
404 type ExecuteProcessSettings struct {
405 ProcessParameters string
406 VsockStdioRelaySettings ExecuteProcessVsockStdioRelaySettings
407 }
408
409
410
411 type ContainerExecuteProcess struct {
412 MessageBase
413 Settings ExecuteProcessSettings
414 }
415
416
417
418 type ContainerResizeConsole struct {
419 MessageBase
420 ProcessID uint32 `json:"ProcessId"`
421 Height uint16
422 Width uint16
423 }
424
425
426
427
428 type ContainerWaitForProcess struct {
429 MessageBase
430 ProcessID uint32 `json:"ProcessId"`
431 TimeoutInMs uint32
432 }
433
434
435
436 const InfiniteWaitTimeout = 0xffffffff
437
438
439
440 type ContainerSignalProcess struct {
441 MessageBase
442 ProcessID uint32 `json:"ProcessId"`
443 Options SignalProcessOptions `json:",omitempty"`
444 }
445
446
447
448 type ContainerGetProperties struct {
449 MessageBase
450 Query string
451 }
452
453
454
455 type PropertyType string
456
457 const (
458
459 PtMemory = PropertyType("Memory")
460
461 PtCPUGroup = PropertyType("CpuGroup")
462
463 PtStatistics = PropertyType("Statistics")
464
465 PtProcessList = PropertyType("ProcessList")
466
467
468 PtPendingUpdates = PropertyType("PendingUpdates")
469
470
471 PtTerminateOnLastHandleClosed = PropertyType("TerminateOnLastHandleClosed")
472
473 PtMappedDirectory = PropertyType("MappedDirectory")
474
475 PtSystemGUID = PropertyType("SystemGUID")
476
477 PtNetwork = PropertyType("Network")
478
479 PtMappedPipe = PropertyType("MappedPipe")
480
481 PtMappedVirtualDisk = PropertyType("MappedVirtualDisk")
482 )
483
484
485 type RequestType string
486
487 const (
488
489 RtAdd = RequestType("Add")
490
491 RtRemove = RequestType("Remove")
492
493 RtUpdate = RequestType("Update")
494 )
495
496
497
498 type ResourceModificationRequestResponse struct {
499 ResourceType PropertyType
500 RequestType RequestType `json:",omitempty"`
501 Settings interface{} `json:",omitempty"`
502 }
503
504
505
506 type ContainerModifySettings struct {
507 MessageBase
508 Request interface{}
509 }
510
511
512
513
514
515 func UnmarshalContainerModifySettings(b []byte) (*ContainerModifySettings, error) {
516
517 var request ContainerModifySettings
518 var requestRawSettings json.RawMessage
519 request.Request = &requestRawSettings
520 if err := commonutils.UnmarshalJSONWithHresult(b, &request); err != nil {
521 return nil, errors.Wrap(err, "failed to unmarshal ContainerModifySettings")
522 }
523
524 var msr guestrequest.ModificationRequest
525 var msrRawSettings json.RawMessage
526 msr.Settings = &msrRawSettings
527 if err := commonutils.UnmarshalJSONWithHresult(requestRawSettings, &msr); err != nil {
528 return &request, errors.Wrap(err, "failed to unmarshal request.Settings as ModifySettingRequest")
529 }
530
531 if msr.RequestType == "" {
532 msr.RequestType = guestrequest.RequestTypeAdd
533 }
534
535
536 switch msr.ResourceType {
537 case guestresource.ResourceTypeSCSIDevice:
538 msd := &guestresource.SCSIDevice{}
539 if err := commonutils.UnmarshalJSONWithHresult(msrRawSettings, msd); err != nil {
540 return &request, errors.Wrap(err, "failed to unmarshal settings as SCSIDevice")
541 }
542 msr.Settings = msd
543 case guestresource.ResourceTypeMappedVirtualDisk:
544 mvd := &guestresource.LCOWMappedVirtualDisk{}
545 if err := commonutils.UnmarshalJSONWithHresult(msrRawSettings, mvd); err != nil {
546 return &request, errors.Wrap(err, "failed to unmarshal settings as MappedVirtualDiskV2")
547 }
548 msr.Settings = mvd
549 case guestresource.ResourceTypeMappedDirectory:
550 md := &guestresource.LCOWMappedDirectory{}
551 if err := commonutils.UnmarshalJSONWithHresult(msrRawSettings, md); err != nil {
552 return &request, errors.Wrap(err, "failed to unmarshal settings as MappedDirectoryV2")
553 }
554 msr.Settings = md
555 case guestresource.ResourceTypeVPMemDevice:
556 vpd := &guestresource.LCOWMappedVPMemDevice{}
557 if err := commonutils.UnmarshalJSONWithHresult(msrRawSettings, vpd); err != nil {
558 return &request, errors.Wrap(err, "failed to unmarshal hosted settings as MappedVPMemDeviceV2")
559 }
560 msr.Settings = vpd
561 case guestresource.ResourceTypeCombinedLayers:
562 cl := &guestresource.LCOWCombinedLayers{}
563 if err := commonutils.UnmarshalJSONWithHresult(msrRawSettings, cl); err != nil {
564 return &request, errors.Wrap(err, "failed to unmarshal settings as CombinedLayersV2")
565 }
566 msr.Settings = cl
567 case guestresource.ResourceTypeNetwork:
568 na := &guestresource.LCOWNetworkAdapter{}
569 if err := commonutils.UnmarshalJSONWithHresult(msrRawSettings, na); err != nil {
570 return &request, errors.Wrap(err, "failed to unmarshal settings as NetworkAdapterV2")
571 }
572 msr.Settings = na
573 case guestresource.ResourceTypeVPCIDevice:
574 vd := &guestresource.LCOWMappedVPCIDevice{}
575 if err := commonutils.UnmarshalJSONWithHresult(msrRawSettings, vd); err != nil {
576 return &request, errors.Wrap(err, "failed to unmarshal settings as MappedVPCIDeviceV2")
577 }
578 msr.Settings = vd
579 case guestresource.ResourceTypeContainerConstraints:
580 cc := &guestresource.LCOWContainerConstraints{}
581 if err := commonutils.UnmarshalJSONWithHresult(msrRawSettings, cc); err != nil {
582 return &request, errors.Wrap(err, "failed to unmarshal settings as ContainerConstraintsV2")
583 }
584 msr.Settings = cc
585 case guestresource.ResourceTypeSecurityPolicy:
586 enforcer := &guestresource.LCOWConfidentialOptions{}
587 if err := commonutils.UnmarshalJSONWithHresult(msrRawSettings, enforcer); err != nil {
588 return &request, errors.Wrap(err, "failed to unmarshal settings as LCOWConfidentialOptions")
589 }
590 msr.Settings = enforcer
591 case guestresource.ResourceTypePolicyFragment:
592 fragment := &guestresource.LCOWSecurityPolicyFragment{}
593 if err := commonutils.UnmarshalJSONWithHresult(msrRawSettings, fragment); err != nil {
594 return &request, errors.Wrap(err, "failed to unmarshal settings as LCOWSecurityPolicyFragment")
595 }
596 msr.Settings = fragment
597 default:
598 return &request, errors.Errorf("invalid ResourceType '%s'", msr.ResourceType)
599 }
600 request.Request = &msr
601 return &request, nil
602 }
603
604
605
606
607 type ErrorRecord struct {
608 Result int32
609 Message string
610 StackTrace string `json:",omitempty"`
611 ModuleName string
612 FileName string
613 Line uint32
614 FunctionName string `json:",omitempty"`
615 }
616
617
618
619 type MessageResponseBase struct {
620 Result int32
621 ActivityID string `json:"ActivityId,omitempty"`
622 ErrorMessage string `json:",omitempty"`
623 ErrorRecords []ErrorRecord `json:",omitempty"`
624 }
625
626
627 func (mrp *MessageResponseBase) Base() *MessageResponseBase {
628 return mrp
629 }
630
631
632
633
634 type NegotiateProtocolResponse struct {
635 MessageResponseBase
636 Version uint32
637 Capabilities GcsCapabilities
638 }
639
640 type DumpStacksResponse struct {
641 MessageResponseBase
642 GuestStacks string
643 }
644
645
646
647
648
649 type ContainerCreateResponse struct {
650 MessageResponseBase
651 SelectedVersion string `json:",omitempty"`
652 SelectedProtocolVersion uint32
653 }
654
655
656
657 type ContainerExecuteProcessResponse struct {
658 MessageResponseBase
659 ProcessID uint32 `json:"ProcessId"`
660 }
661
662
663
664 type ContainerWaitForProcessResponse struct {
665 MessageResponseBase
666 ExitCode uint32
667 }
668
669
670
671
672 type ContainerGetPropertiesResponse struct {
673 MessageResponseBase
674 Properties string
675 }
676
677
678
679
680
681 type NetworkAdapter struct {
682 AdapterInstanceID string `json:"AdapterInstanceId"`
683 FirewallEnabled bool
684 NatEnabled bool
685 MacAddress string `json:",omitempty"`
686 AllocatedIPAddress string `json:"AllocatedIpAddress,omitempty"`
687 HostIPAddress string `json:"HostIpAddress,omitempty"`
688 HostIPPrefixLength uint8 `json:"HostIpPrefixLength,omitempty"`
689 AllocatedIPv6Address string `json:"AllocatedIpv6Address,omitempty"`
690 HostIPv6Address string `json:"HostIpv6Address,omitempty"`
691 HostIPv6PrefixLength uint8 `json:"HostIpv6PrefixLength,omitempty"`
692 HostDNSServerList string `json:"HostDnsServerList,omitempty"`
693 HostDNSSuffix string `json:"HostDnsSuffix,omitempty"`
694 EnableLowMetric bool `json:",omitempty"`
695 EncapOverhead uint16 `json:",omitempty"`
696 }
697
698
699
700 type MappedVirtualDisk struct {
701 ContainerPath string
702 Lun uint8 `json:",omitempty"`
703 CreateInUtilityVM bool `json:",omitempty"`
704 ReadOnly bool `json:",omitempty"`
705 AttachOnly bool `json:",omitempty"`
706 }
707
708
709
710 type MappedDirectory struct {
711 ContainerPath string
712 CreateInUtilityVM bool `json:",omitempty"`
713 ReadOnly bool `json:",omitempty"`
714 Port uint32 `json:",omitempty"`
715 }
716
717
718
719 type VMHostedContainerSettings struct {
720 Layers []hcsschema.Layer
721
722
723 SandboxDataPath string
724 MappedVirtualDisks []MappedVirtualDisk
725 MappedDirectories []MappedDirectory
726 NetworkAdapters []NetworkAdapter `json:",omitempty"`
727 }
728
729
730 type SchemaVersion struct {
731 Major uint32 `json:",omitempty"`
732 Minor uint32 `json:",omitempty"`
733 }
734
735
736
737
738
739
740 func (s *SchemaVersion) Cmp(v SchemaVersion) int {
741 if s.Major == v.Major {
742 if s.Minor == v.Minor {
743 return 0
744 } else if s.Minor < v.Minor {
745 return -1
746 }
747 return 1
748 } else if s.Major < v.Major {
749 return -1
750 }
751 return 1
752 }
753
754
755
756
757
758 type VMHostedContainerSettingsV2 struct {
759 SchemaVersion SchemaVersion
760 OCIBundlePath string `json:"OciBundlePath,omitempty"`
761 OCISpecification *oci.Spec `json:"OciSpecification,omitempty"`
762
763
764
765
766 ScratchDirPath string
767 }
768
769
770
771
772
773
774
775
776
777
778
779 type ProcessParameters struct {
780
781
782
783 CommandLine string `json:",omitempty"`
784
785
786
787 CommandArgs []string `json:",omitempty"`
788 WorkingDirectory string `json:",omitempty"`
789 Environment map[string]string `json:",omitempty"`
790 EmulateConsole bool `json:",omitempty"`
791 CreateStdInPipe bool `json:",omitempty"`
792 CreateStdOutPipe bool `json:",omitempty"`
793 CreateStdErrPipe bool `json:",omitempty"`
794
795
796
797
798 IsExternal bool `json:"CreateInUtilityVM,omitempty"`
799
800
801
802 OCISpecification *oci.Spec `json:"OciSpecification,omitempty"`
803
804 OCIProcess *oci.Process `json:"OciProcess,omitempty"`
805 }
806
807
808 type SignalProcessOptions struct {
809 Signal int32
810 }
811
812
813 type ProcessDetails struct {
814 ProcessID uint32 `json:"ProcessId"`
815 }
816
817
818 type PropertyQuery struct {
819 PropertyTypes []PropertyType `json:",omitempty"`
820 }
821
822
823 type Properties struct {
824 ProcessList []ProcessDetails `json:",omitempty"`
825 }
826
827 type PropertiesV2 struct {
828 ProcessList []ProcessDetails `json:"ProcessList,omitempty"`
829 Metrics *v1.Metrics `json:"LCOWMetrics,omitempty"`
830 }
831
View as plain text