...

Source file src/github.com/Microsoft/hcsshim/internal/gcs/protocol.go

Documentation: github.com/Microsoft/hcsshim/internal/gcs

     1  //go:build windows
     2  
     3  package gcs
     4  
     5  import (
     6  	"encoding/json"
     7  	"fmt"
     8  	"strconv"
     9  
    10  	"github.com/Microsoft/go-winio/pkg/guid"
    11  	"github.com/Microsoft/hcsshim/internal/hcs/schema1"
    12  	hcsschema "github.com/Microsoft/hcsshim/internal/hcs/schema2"
    13  )
    14  
    15  // LinuxGcsVsockPort is the vsock port number that the Linux GCS will
    16  // connect to.
    17  const LinuxGcsVsockPort = 0x40000000
    18  
    19  // WindowsGcsHvsockServiceID is the hvsock service ID that the Windows GCS
    20  // will connect to.
    21  var WindowsGcsHvsockServiceID = guid.GUID{
    22  	Data1: 0xacef5661,
    23  	Data2: 0x84a1,
    24  	Data3: 0x4e44,
    25  	Data4: [8]uint8{0x85, 0x6b, 0x62, 0x45, 0xe6, 0x9f, 0x46, 0x20},
    26  }
    27  
    28  // WindowsGcsHvHostID is the hvsock address for the parent of the VM running the GCS
    29  var WindowsGcsHvHostID = guid.GUID{
    30  	Data1: 0x894cc2d6,
    31  	Data2: 0x9d79,
    32  	Data3: 0x424f,
    33  	Data4: [8]uint8{0x93, 0xfe, 0x42, 0x96, 0x9a, 0xe6, 0xd8, 0xd1},
    34  }
    35  
    36  type anyInString struct {
    37  	Value interface{}
    38  }
    39  
    40  func (a *anyInString) MarshalText() ([]byte, error) {
    41  	return json.Marshal(a.Value)
    42  }
    43  
    44  func (a *anyInString) UnmarshalText(b []byte) error {
    45  	return json.Unmarshal(b, &a.Value)
    46  }
    47  
    48  type rpcProc uint32
    49  
    50  const (
    51  	rpcCreate rpcProc = (iota+1)<<8 | 1
    52  	rpcStart
    53  	rpcShutdownGraceful
    54  	rpcShutdownForced
    55  	rpcExecuteProcess
    56  	rpcWaitForProcess
    57  	rpcSignalProcess
    58  	rpcResizeConsole
    59  	rpcGetProperties
    60  	rpcModifySettings
    61  	rpcNegotiateProtocol
    62  	rpcDumpStacks
    63  	rpcDeleteContainerState
    64  	rpcUpdateContainer
    65  	rpcLifecycleNotification
    66  )
    67  
    68  func (rpc rpcProc) String() string {
    69  	switch rpc {
    70  	case rpcCreate:
    71  		return "Create"
    72  	case rpcStart:
    73  		return "Start"
    74  	case rpcShutdownGraceful:
    75  		return "ShutdownGraceful"
    76  	case rpcShutdownForced:
    77  		return "ShutdownForced"
    78  	case rpcExecuteProcess:
    79  		return "ExecuteProcess"
    80  	case rpcWaitForProcess:
    81  		return "WaitForProcess"
    82  	case rpcSignalProcess:
    83  		return "SignalProcess"
    84  	case rpcResizeConsole:
    85  		return "ResizeConsole"
    86  	case rpcGetProperties:
    87  		return "GetProperties"
    88  	case rpcModifySettings:
    89  		return "ModifySettings"
    90  	case rpcNegotiateProtocol:
    91  		return "NegotiateProtocol"
    92  	case rpcDumpStacks:
    93  		return "DumpStacks"
    94  	case rpcDeleteContainerState:
    95  		return "DeleteContainerState"
    96  	case rpcUpdateContainer:
    97  		return "UpdateContainer"
    98  	case rpcLifecycleNotification:
    99  		return "LifecycleNotification"
   100  	default:
   101  		return "0x" + strconv.FormatUint(uint64(rpc), 16)
   102  	}
   103  }
   104  
   105  type msgType uint32
   106  
   107  const (
   108  	msgTypeRequest  msgType = 0x10100000
   109  	msgTypeResponse msgType = 0x20100000
   110  	msgTypeNotify   msgType = 0x30100000
   111  	msgTypeMask     msgType = 0xfff00000
   112  
   113  	notifyContainer = 1<<8 | 1
   114  )
   115  
   116  func (typ msgType) String() string {
   117  	var s string
   118  	switch typ & msgTypeMask {
   119  	case msgTypeRequest:
   120  		s = "Request("
   121  	case msgTypeResponse:
   122  		s = "Response("
   123  	case msgTypeNotify:
   124  		s = "Notify("
   125  		switch typ - msgTypeNotify {
   126  		case notifyContainer:
   127  			s += "Container"
   128  		default:
   129  			s += fmt.Sprintf("%#x", uint32(typ))
   130  		}
   131  		return s + ")"
   132  	default:
   133  		return fmt.Sprintf("%#x", uint32(typ))
   134  	}
   135  	s += rpcProc(typ &^ msgTypeMask).String()
   136  	return s + ")"
   137  }
   138  
   139  // ocspancontext is the internal JSON representation of the OpenCensus
   140  // `trace.SpanContext` for fowarding to a GCS that supports it.
   141  type ocspancontext struct {
   142  	// TraceID is the `hex` encoded string of the OpenCensus
   143  	// `SpanContext.TraceID` to propagate to the guest.
   144  	TraceID string `json:",omitempty"`
   145  	// SpanID is the `hex` encoded string of the OpenCensus `SpanContext.SpanID`
   146  	// to propagate to the guest.
   147  	SpanID string `json:",omitempty"`
   148  
   149  	// TraceOptions is the OpenCensus `SpanContext.TraceOptions` passed through
   150  	// to propagate to the guest.
   151  	TraceOptions uint32 `json:",omitempty"`
   152  
   153  	// Tracestate is the `base64` encoded string of marshaling the OpenCensus
   154  	// `SpanContext.TraceState.Entries()` to JSON.
   155  	//
   156  	// If `SpanContext.Tracestate == nil ||
   157  	// len(SpanContext.Tracestate.Entries()) == 0` this will be `""`.
   158  	Tracestate string `json:",omitempty"`
   159  }
   160  
   161  type requestBase struct {
   162  	ContainerID string    `json:"ContainerId"`
   163  	ActivityID  guid.GUID `json:"ActivityId"`
   164  
   165  	// OpenCensusSpanContext is the encoded OpenCensus `trace.SpanContext` if
   166  	// set when making the request.
   167  	//
   168  	// NOTE: This is not a part of the protocol but because its a JSON protocol
   169  	// adding fields is a non-breaking change. If the guest supports it this is
   170  	// just additive context.
   171  	OpenCensusSpanContext *ocspancontext `json:"ocsc,omitempty"`
   172  }
   173  
   174  func (req *requestBase) Base() *requestBase {
   175  	return req
   176  }
   177  
   178  type responseBase struct {
   179  	Result       int32         // HResult
   180  	ErrorMessage string        `json:",omitempty"`
   181  	ActivityID   guid.GUID     `json:"ActivityId,omitempty"`
   182  	ErrorRecords []errorRecord `json:",omitempty"`
   183  }
   184  
   185  type errorRecord struct {
   186  	Result       int32 // HResult
   187  	Message      string
   188  	StackTrace   string `json:",omitempty"`
   189  	ModuleName   string
   190  	FileName     string
   191  	Line         uint32
   192  	FunctionName string `json:",omitempty"`
   193  }
   194  
   195  func (resp *responseBase) Base() *responseBase {
   196  	return resp
   197  }
   198  
   199  type negotiateProtocolRequest struct {
   200  	requestBase
   201  	MinimumVersion uint32
   202  	MaximumVersion uint32
   203  }
   204  
   205  type negotiateProtocolResponse struct {
   206  	responseBase
   207  	Version      uint32          `json:",omitempty"`
   208  	Capabilities gcsCapabilities `json:",omitempty"`
   209  }
   210  
   211  type dumpStacksRequest struct {
   212  	requestBase
   213  }
   214  
   215  type dumpStacksResponse struct {
   216  	responseBase
   217  	GuestStacks string
   218  }
   219  
   220  type deleteContainerStateRequest struct {
   221  	requestBase
   222  }
   223  
   224  type containerCreate struct {
   225  	requestBase
   226  	ContainerConfig anyInString
   227  }
   228  
   229  type uvmConfig struct {
   230  	SystemType          string // must be "Container"
   231  	TimeZoneInformation *hcsschema.TimeZoneInformation
   232  }
   233  
   234  type containerNotification struct {
   235  	requestBase
   236  	Type       string      // Compute.System.NotificationType
   237  	Operation  string      // Compute.System.ActiveOperation
   238  	Result     int32       // HResult
   239  	ResultInfo anyInString `json:",omitempty"`
   240  }
   241  
   242  type containerExecuteProcess struct {
   243  	requestBase
   244  	Settings executeProcessSettings
   245  }
   246  
   247  type executeProcessSettings struct {
   248  	ProcessParameters       anyInString
   249  	StdioRelaySettings      *executeProcessStdioRelaySettings      `json:",omitempty"`
   250  	VsockStdioRelaySettings *executeProcessVsockStdioRelaySettings `json:",omitempty"`
   251  }
   252  
   253  type executeProcessStdioRelaySettings struct {
   254  	StdIn  *guid.GUID `json:",omitempty"`
   255  	StdOut *guid.GUID `json:",omitempty"`
   256  	StdErr *guid.GUID `json:",omitempty"`
   257  }
   258  
   259  type executeProcessVsockStdioRelaySettings struct {
   260  	StdIn  uint32 `json:",omitempty"`
   261  	StdOut uint32 `json:",omitempty"`
   262  	StdErr uint32 `json:",omitempty"`
   263  }
   264  
   265  type containerResizeConsole struct {
   266  	requestBase
   267  	ProcessID uint32 `json:"ProcessId"`
   268  	Height    uint16
   269  	Width     uint16
   270  }
   271  
   272  type containerWaitForProcess struct {
   273  	requestBase
   274  	ProcessID   uint32 `json:"ProcessId"`
   275  	TimeoutInMs uint32
   276  }
   277  
   278  type containerSignalProcess struct {
   279  	requestBase
   280  	ProcessID uint32      `json:"ProcessId"`
   281  	Options   interface{} `json:",omitempty"`
   282  }
   283  
   284  type containerPropertiesQuery schema1.PropertyQuery
   285  
   286  func (q *containerPropertiesQuery) MarshalText() ([]byte, error) {
   287  	return json.Marshal((*schema1.PropertyQuery)(q))
   288  }
   289  
   290  func (q *containerPropertiesQuery) UnmarshalText(b []byte) error {
   291  	return json.Unmarshal(b, (*schema1.PropertyQuery)(q))
   292  }
   293  
   294  type containerPropertiesQueryV2 hcsschema.PropertyQuery
   295  
   296  func (q *containerPropertiesQueryV2) MarshalText() ([]byte, error) {
   297  	return json.Marshal((*hcsschema.PropertyQuery)(q))
   298  }
   299  
   300  func (q *containerPropertiesQueryV2) UnmarshalText(b []byte) error {
   301  	return json.Unmarshal(b, (*hcsschema.PropertyQuery)(q))
   302  }
   303  
   304  type containerGetProperties struct {
   305  	requestBase
   306  	Query containerPropertiesQuery
   307  }
   308  
   309  type containerGetPropertiesV2 struct {
   310  	requestBase
   311  	Query containerPropertiesQueryV2
   312  }
   313  
   314  type containerModifySettings struct {
   315  	requestBase
   316  	Request interface{}
   317  }
   318  
   319  type gcsCapabilities struct {
   320  	SendHostCreateMessage      bool
   321  	SendHostStartMessage       bool
   322  	HvSocketConfigOnStartup    bool
   323  	SendLifecycleNotifications bool
   324  	SupportedSchemaVersions    []hcsschema.Version
   325  	RuntimeOsType              string
   326  	GuestDefinedCapabilities   interface{}
   327  }
   328  
   329  type containerCreateResponse struct {
   330  	responseBase
   331  }
   332  
   333  type containerExecuteProcessResponse struct {
   334  	responseBase
   335  	ProcessID uint32 `json:"ProcessId"`
   336  }
   337  
   338  type containerWaitForProcessResponse struct {
   339  	responseBase
   340  	ExitCode uint32
   341  }
   342  
   343  type containerProperties schema1.ContainerProperties
   344  
   345  func (p *containerProperties) MarshalText() ([]byte, error) {
   346  	return json.Marshal((*schema1.ContainerProperties)(p))
   347  }
   348  
   349  func (p *containerProperties) UnmarshalText(b []byte) error {
   350  	return json.Unmarshal(b, (*schema1.ContainerProperties)(p))
   351  }
   352  
   353  type containerPropertiesV2 hcsschema.Properties
   354  
   355  func (p *containerPropertiesV2) MarshalText() ([]byte, error) {
   356  	return json.Marshal((*hcsschema.Properties)(p))
   357  }
   358  
   359  func (p *containerPropertiesV2) UnmarshalText(b []byte) error {
   360  	return json.Unmarshal(b, (*hcsschema.Properties)(p))
   361  }
   362  
   363  type containerGetPropertiesResponse struct {
   364  	responseBase
   365  	Properties containerProperties
   366  }
   367  
   368  type containerGetPropertiesResponseV2 struct {
   369  	responseBase
   370  	Properties containerPropertiesV2
   371  }
   372  

View as plain text