diff --git a/docs/openapi/gateway.swagger.json b/docs/openapi/gateway.swagger.json index 9f554995d..5b4c1c6dc 100644 --- a/docs/openapi/gateway.swagger.json +++ b/docs/openapi/gateway.swagger.json @@ -996,29 +996,6 @@ } } }, - "gatewayAttachToContainerRequest": { - "type": "object", - "properties": { - "containerId": { - "type": "string" - } - } - }, - "gatewayAttachToContainerResponse": { - "type": "object", - "properties": { - "output": { - "type": "string" - }, - "done": { - "type": "boolean" - }, - "exitCode": { - "type": "integer", - "format": "int32" - } - } - }, "gatewayAuthorizeResponse": { "type": "object", "properties": { @@ -1056,20 +1033,6 @@ } } }, - "gatewayCheckpointContainerResponse": { - "type": "object", - "properties": { - "ok": { - "type": "boolean" - }, - "checkpointId": { - "type": "string" - }, - "errorMsg": { - "type": "string" - } - } - }, "gatewayCordonWorkerResponse": { "type": "object", "properties": { @@ -1837,20 +1800,6 @@ } } }, - "gatewayPutObjectResponse": { - "type": "object", - "properties": { - "ok": { - "type": "boolean" - }, - "objectId": { - "type": "string" - }, - "errorMsg": { - "type": "string" - } - } - }, "gatewayScaleDeploymentResponse": { "type": "object", "properties": { @@ -2005,39 +1954,6 @@ } } }, - "gatewaySyncContainerWorkspaceOperation": { - "type": "string", - "enum": [ - "WRITE", - "DELETE", - "MOVED" - ], - "default": "WRITE" - }, - "gatewaySyncContainerWorkspaceRequest": { - "type": "object", - "properties": { - "containerId": { - "type": "string" - }, - "path": { - "type": "string" - }, - "newPath": { - "type": "string" - }, - "isDir": { - "type": "boolean" - }, - "data": { - "type": "string", - "format": "byte" - }, - "op": { - "$ref": "#/definitions/gatewaySyncContainerWorkspaceOperation" - } - } - }, "gatewayTask": { "type": "object", "properties": { diff --git a/docs/openapi/pod.swagger.json b/docs/openapi/pod.swagger.json index 0fea5bbf7..5f0d1812e 100644 --- a/docs/openapi/pod.swagger.json +++ b/docs/openapi/pod.swagger.json @@ -857,6 +857,46 @@ "PodService" ] } + }, + "/pods/{stubId}/events": { + "get": { + "operationId": "PodService_SandboxListEvents", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/podPodSandboxListEventsResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/rpcStatus" + } + } + }, + "parameters": [ + { + "name": "stubId", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "searchAfter", + "in": "query", + "required": false, + "type": "array", + "items": { + "type": "string" + }, + "collectionFormat": "multi" + } + ], + "tags": [ + "PodService" + ] + } } }, "definitions": { @@ -1103,6 +1143,36 @@ } } }, + "podPodSandboxEvent": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "time": { + "type": "string" + }, + "type": { + "type": "string" + }, + "status": { + "type": "string" + }, + "containerId": { + "type": "string" + }, + "workerId": { + "type": "string" + }, + "stubId": { + "type": "string" + }, + "exitCode": { + "type": "integer", + "format": "int32" + } + } + }, "podPodSandboxExecResponse": { "type": "object", "properties": { @@ -1194,6 +1264,30 @@ } } }, + "podPodSandboxListEventsResponse": { + "type": "object", + "properties": { + "ok": { + "type": "boolean" + }, + "errorMsg": { + "type": "string" + }, + "events": { + "type": "array", + "items": { + "type": "object", + "$ref": "#/definitions/podPodSandboxEvent" + } + }, + "nextCursor": { + "type": "array", + "items": { + "type": "string" + } + } + } + }, "podPodSandboxListFilesResponse": { "type": "object", "properties": { diff --git a/manifests/kustomize/components/monitoring/victoria-metrics.yaml b/manifests/kustomize/components/monitoring/victoria-metrics.yaml index 79d277ef0..21952436e 100644 --- a/manifests/kustomize/components/monitoring/victoria-metrics.yaml +++ b/manifests/kustomize/components/monitoring/victoria-metrics.yaml @@ -46,7 +46,7 @@ valuesInline: regex: true - source_labels: [__meta_kubernetes_pod_container_port_number] action: keep - regex: 9090 + regex: (9090|8112) --- apiVersion: builtin kind: HelmChartInflationGenerator diff --git a/pkg/abstractions/pod/pod.proto b/pkg/abstractions/pod/pod.proto index cfdf451a0..0df569d72 100644 --- a/pkg/abstractions/pod/pod.proto +++ b/pkg/abstractions/pod/pod.proto @@ -157,6 +157,12 @@ service PodService { get : "/pods/{container_id}/urls" }; } + rpc SandboxListEvents(PodSandboxListEventsRequest) + returns (PodSandboxListEventsResponse) { + option (google.api.http) = { + get : "/pods/{stub_id}/events" + }; + } } message CreatePodRequest { @@ -418,4 +424,27 @@ message PodSandboxListUrlsResponse { bool ok = 1; map urls = 2; string error_msg = 3; +} + +message PodSandboxListEventsRequest { + string stub_id = 1; + repeated string search_after = 2; +} + +message PodSandboxListEventsResponse { + bool ok = 1; + string error_msg = 2; + repeated PodSandboxEvent events = 3; + repeated string next_cursor = 4; +} + +message PodSandboxEvent { + string id = 1; + string time = 2; + string type = 3; + string status = 4; + string container_id = 5; + string worker_id = 6; + string stub_id = 7; + int32 exit_code = 8; } \ No newline at end of file diff --git a/pkg/abstractions/pod/sandbox.go b/pkg/abstractions/pod/sandbox.go index 492e3efe7..b3dc6da19 100644 --- a/pkg/abstractions/pod/sandbox.go +++ b/pkg/abstractions/pod/sandbox.go @@ -1,9 +1,13 @@ package pod import ( + "bytes" "context" + "encoding/json" "errors" "fmt" + "io" + "net/http" "time" "github.com/beam-cloud/beta9/pkg/auth" @@ -739,3 +743,167 @@ func (s *GenericPodService) SandboxListProcesses(ctx context.Context, in *pb.Pod Processes: resp.Processes, }, nil } + +func (s *GenericPodService) SandboxListEvents(ctx context.Context, in *pb.PodSandboxListEventsRequest) (*pb.PodSandboxListEventsResponse, error) { + authInfo, _ := auth.AuthInfoFromContext(ctx) + + // Validate stub ownership + stub, err := s.backendRepo.GetStubByExternalId(ctx, in.StubId, types.QueryFilter{ + Field: "workspace_id", + Value: authInfo.Workspace.ExternalId, + }) + if err != nil || stub == nil { + return &pb.PodSandboxListEventsResponse{ + Ok: false, + ErrorMsg: "Stub not found", + }, nil + } + + esConfig := s.config.Agent.ElasticSearch + if esConfig.Host == "" { + return &pb.PodSandboxListEventsResponse{ + Ok: false, + ErrorMsg: "Elasticsearch not configured", + }, nil + } + + // Build ES query + query := map[string]interface{}{ + "size": 25, + "query": map[string]interface{}{ + "bool": map[string]interface{}{ + "must": []map[string]interface{}{ + {"term": map[string]interface{}{"type.keyword": "container.lifecycle"}}, + }, + "should": []map[string]interface{}{ + {"term": map[string]interface{}{"data.stub_id.keyword": in.StubId}}, + {"term": map[string]interface{}{"data.request.stub_id.keyword": in.StubId}}, + }, + "minimum_should_match": 1, + }, + }, + "sort": []map[string]interface{}{ + {"@timestamp": map[string]string{"order": "desc"}}, + {"id.keyword": map[string]string{"order": "desc"}}, + }, + } + + if len(in.SearchAfter) > 0 { + query["search_after"] = in.SearchAfter + } + + queryBytes, err := json.Marshal(query) + if err != nil { + return &pb.PodSandboxListEventsResponse{ + Ok: false, + ErrorMsg: "Failed to build query", + }, nil + } + + esURL := fmt.Sprintf("http://%s:%s/events-*/_search", esConfig.Host, esConfig.Port) + req, err := http.NewRequestWithContext(ctx, http.MethodPost, esURL, bytes.NewReader(queryBytes)) + if err != nil { + return &pb.PodSandboxListEventsResponse{ + Ok: false, + ErrorMsg: "Failed to create request", + }, nil + } + req.Header.Set("Content-Type", "application/json") + if esConfig.HttpUser != "" { + req.SetBasicAuth(esConfig.HttpUser, esConfig.HttpPasswd) + } + + resp, err := http.DefaultClient.Do(req) + if err != nil { + return &pb.PodSandboxListEventsResponse{ + Ok: false, + ErrorMsg: "Failed to query Elasticsearch", + }, nil + } + defer resp.Body.Close() + + body, err := io.ReadAll(resp.Body) + if err != nil { + return &pb.PodSandboxListEventsResponse{ + Ok: false, + ErrorMsg: "Failed to read Elasticsearch response", + }, nil + } + + var esResp esSearchResponse + if err := json.Unmarshal(body, &esResp); err != nil { + return &pb.PodSandboxListEventsResponse{ + Ok: false, + ErrorMsg: "Failed to parse Elasticsearch response", + }, nil + } + + events := make([]*pb.PodSandboxEvent, 0, len(esResp.Hits.Hits)) + var lastSort []interface{} + + for _, hit := range esResp.Hits.Hits { + event := &pb.PodSandboxEvent{ + Id: hit.Source.ID, + Time: hit.Source.Time, + Type: hit.Source.Type, + Status: hit.Source.Data.Status, + ContainerId: hit.Source.Data.ContainerID, + WorkerId: hit.Source.Data.WorkerID, + StubId: hit.Source.Data.StubID, + ExitCode: hit.Source.Data.ExitCode, + } + + // Fall back to request-level stub_id if top-level is empty + if event.StubId == "" && hit.Source.Data.Request != nil { + event.StubId = hit.Source.Data.Request.StubID + } + + events = append(events, event) + lastSort = hit.Sort + } + + var nextCursor []string + if len(lastSort) > 0 { + for _, v := range lastSort { + nextCursor = append(nextCursor, fmt.Sprintf("%v", v)) + } + } + + return &pb.PodSandboxListEventsResponse{ + Ok: true, + Events: events, + NextCursor: nextCursor, + }, nil +} + +// Elasticsearch response types for SandboxListEvents +type esSearchResponse struct { + Hits struct { + Hits []esHit `json:"hits"` + } `json:"hits"` +} + +type esHit struct { + Source esEventSource `json:"_source"` + Sort []interface{} `json:"sort"` +} + +type esEventSource struct { + ID string `json:"id"` + Time string `json:"time"` + Type string `json:"type"` + Data esEventData `json:"data"` +} + +type esEventData struct { + Status string `json:"status"` + ContainerID string `json:"container_id"` + WorkerID string `json:"worker_id"` + StubID string `json:"stub_id"` + ExitCode int32 `json:"exit_code"` + Request *esEventRequest `json:"request,omitempty"` +} + +type esEventRequest struct { + StubID string `json:"stub_id"` +} diff --git a/proto/pod.pb.go b/proto/pod.pb.go index 3a6465353..8d3bffb86 100644 --- a/proto/pod.pb.go +++ b/proto/pod.pb.go @@ -2862,6 +2862,235 @@ func (x *PodSandboxListUrlsResponse) GetErrorMsg() string { return "" } +type PodSandboxListEventsRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + StubId string `protobuf:"bytes,1,opt,name=stub_id,json=stubId,proto3" json:"stub_id,omitempty"` + SearchAfter []string `protobuf:"bytes,2,rep,name=search_after,json=searchAfter,proto3" json:"search_after,omitempty"` +} + +func (x *PodSandboxListEventsRequest) Reset() { + *x = PodSandboxListEventsRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_pod_proto_msgTypes[47] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *PodSandboxListEventsRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*PodSandboxListEventsRequest) ProtoMessage() {} + +func (x *PodSandboxListEventsRequest) ProtoReflect() protoreflect.Message { + mi := &file_pod_proto_msgTypes[47] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use PodSandboxListEventsRequest.ProtoReflect.Descriptor instead. +func (*PodSandboxListEventsRequest) Descriptor() ([]byte, []int) { + return file_pod_proto_rawDescGZIP(), []int{47} +} + +func (x *PodSandboxListEventsRequest) GetStubId() string { + if x != nil { + return x.StubId + } + return "" +} + +func (x *PodSandboxListEventsRequest) GetSearchAfter() []string { + if x != nil { + return x.SearchAfter + } + return nil +} + +type PodSandboxListEventsResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Ok bool `protobuf:"varint,1,opt,name=ok,proto3" json:"ok,omitempty"` + ErrorMsg string `protobuf:"bytes,2,opt,name=error_msg,json=errorMsg,proto3" json:"error_msg,omitempty"` + Events []*PodSandboxEvent `protobuf:"bytes,3,rep,name=events,proto3" json:"events,omitempty"` + NextCursor []string `protobuf:"bytes,4,rep,name=next_cursor,json=nextCursor,proto3" json:"next_cursor,omitempty"` +} + +func (x *PodSandboxListEventsResponse) Reset() { + *x = PodSandboxListEventsResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_pod_proto_msgTypes[48] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *PodSandboxListEventsResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*PodSandboxListEventsResponse) ProtoMessage() {} + +func (x *PodSandboxListEventsResponse) ProtoReflect() protoreflect.Message { + mi := &file_pod_proto_msgTypes[48] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use PodSandboxListEventsResponse.ProtoReflect.Descriptor instead. +func (*PodSandboxListEventsResponse) Descriptor() ([]byte, []int) { + return file_pod_proto_rawDescGZIP(), []int{48} +} + +func (x *PodSandboxListEventsResponse) GetOk() bool { + if x != nil { + return x.Ok + } + return false +} + +func (x *PodSandboxListEventsResponse) GetErrorMsg() string { + if x != nil { + return x.ErrorMsg + } + return "" +} + +func (x *PodSandboxListEventsResponse) GetEvents() []*PodSandboxEvent { + if x != nil { + return x.Events + } + return nil +} + +func (x *PodSandboxListEventsResponse) GetNextCursor() []string { + if x != nil { + return x.NextCursor + } + return nil +} + +type PodSandboxEvent struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` + Time string `protobuf:"bytes,2,opt,name=time,proto3" json:"time,omitempty"` + Type string `protobuf:"bytes,3,opt,name=type,proto3" json:"type,omitempty"` + Status string `protobuf:"bytes,4,opt,name=status,proto3" json:"status,omitempty"` + ContainerId string `protobuf:"bytes,5,opt,name=container_id,json=containerId,proto3" json:"container_id,omitempty"` + WorkerId string `protobuf:"bytes,6,opt,name=worker_id,json=workerId,proto3" json:"worker_id,omitempty"` + StubId string `protobuf:"bytes,7,opt,name=stub_id,json=stubId,proto3" json:"stub_id,omitempty"` + ExitCode int32 `protobuf:"varint,8,opt,name=exit_code,json=exitCode,proto3" json:"exit_code,omitempty"` +} + +func (x *PodSandboxEvent) Reset() { + *x = PodSandboxEvent{} + if protoimpl.UnsafeEnabled { + mi := &file_pod_proto_msgTypes[49] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *PodSandboxEvent) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*PodSandboxEvent) ProtoMessage() {} + +func (x *PodSandboxEvent) ProtoReflect() protoreflect.Message { + mi := &file_pod_proto_msgTypes[49] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use PodSandboxEvent.ProtoReflect.Descriptor instead. +func (*PodSandboxEvent) Descriptor() ([]byte, []int) { + return file_pod_proto_rawDescGZIP(), []int{49} +} + +func (x *PodSandboxEvent) GetId() string { + if x != nil { + return x.Id + } + return "" +} + +func (x *PodSandboxEvent) GetTime() string { + if x != nil { + return x.Time + } + return "" +} + +func (x *PodSandboxEvent) GetType() string { + if x != nil { + return x.Type + } + return "" +} + +func (x *PodSandboxEvent) GetStatus() string { + if x != nil { + return x.Status + } + return "" +} + +func (x *PodSandboxEvent) GetContainerId() string { + if x != nil { + return x.ContainerId + } + return "" +} + +func (x *PodSandboxEvent) GetWorkerId() string { + if x != nil { + return x.WorkerId + } + return "" +} + +func (x *PodSandboxEvent) GetStubId() string { + if x != nil { + return x.StubId + } + return "" +} + +func (x *PodSandboxEvent) GetExitCode() int32 { + if x != nil { + return x.ExitCode + } + return 0 +} + var File_pod_proto protoreflect.FileDescriptor var file_pod_proto_rawDesc = []byte{ @@ -3192,205 +3421,242 @@ var file_pod_proto_rawDesc = []byte{ 0x72, 0x6c, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, - 0x3a, 0x02, 0x38, 0x01, 0x32, 0xb9, 0x18, 0x0a, 0x0a, 0x50, 0x6f, 0x64, 0x53, 0x65, 0x72, 0x76, - 0x69, 0x63, 0x65, 0x12, 0x4c, 0x0a, 0x09, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x50, 0x6f, 0x64, - 0x12, 0x15, 0x2e, 0x70, 0x6f, 0x64, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x50, 0x6f, 0x64, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x70, 0x6f, 0x64, 0x2e, 0x43, 0x72, - 0x65, 0x61, 0x74, 0x65, 0x50, 0x6f, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, - 0x10, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x0a, 0x3a, 0x01, 0x2a, 0x22, 0x05, 0x2f, 0x70, 0x6f, 0x64, - 0x73, 0x12, 0x6c, 0x0a, 0x0b, 0x53, 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x45, 0x78, 0x65, 0x63, - 0x12, 0x1a, 0x2e, 0x70, 0x6f, 0x64, 0x2e, 0x50, 0x6f, 0x64, 0x53, 0x61, 0x6e, 0x64, 0x62, 0x6f, - 0x78, 0x45, 0x78, 0x65, 0x63, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1b, 0x2e, 0x70, - 0x6f, 0x64, 0x2e, 0x50, 0x6f, 0x64, 0x53, 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x45, 0x78, 0x65, - 0x63, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x24, 0x82, 0xd3, 0xe4, 0x93, 0x02, - 0x1e, 0x3a, 0x01, 0x2a, 0x22, 0x19, 0x2f, 0x70, 0x6f, 0x64, 0x73, 0x2f, 0x7b, 0x63, 0x6f, 0x6e, - 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x65, 0x78, 0x65, 0x63, 0x12, - 0x71, 0x0a, 0x0d, 0x53, 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, - 0x12, 0x1c, 0x2e, 0x70, 0x6f, 0x64, 0x2e, 0x50, 0x6f, 0x64, 0x53, 0x61, 0x6e, 0x64, 0x62, 0x6f, - 0x78, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1d, - 0x2e, 0x70, 0x6f, 0x64, 0x2e, 0x50, 0x6f, 0x64, 0x53, 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x53, - 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x23, 0x82, - 0xd3, 0xe4, 0x93, 0x02, 0x1d, 0x12, 0x1b, 0x2f, 0x70, 0x6f, 0x64, 0x73, 0x2f, 0x7b, 0x63, 0x6f, - 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x73, 0x74, 0x61, 0x74, - 0x75, 0x73, 0x12, 0x71, 0x0a, 0x0d, 0x53, 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x53, 0x74, 0x64, - 0x6f, 0x75, 0x74, 0x12, 0x1c, 0x2e, 0x70, 0x6f, 0x64, 0x2e, 0x50, 0x6f, 0x64, 0x53, 0x61, 0x6e, - 0x64, 0x62, 0x6f, 0x78, 0x53, 0x74, 0x64, 0x6f, 0x75, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x1a, 0x1d, 0x2e, 0x70, 0x6f, 0x64, 0x2e, 0x50, 0x6f, 0x64, 0x53, 0x61, 0x6e, 0x64, 0x62, - 0x6f, 0x78, 0x53, 0x74, 0x64, 0x6f, 0x75, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x22, 0x23, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1d, 0x12, 0x1b, 0x2f, 0x70, 0x6f, 0x64, 0x73, 0x2f, - 0x7b, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x73, - 0x74, 0x64, 0x6f, 0x75, 0x74, 0x12, 0x71, 0x0a, 0x0d, 0x53, 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, - 0x53, 0x74, 0x64, 0x65, 0x72, 0x72, 0x12, 0x1c, 0x2e, 0x70, 0x6f, 0x64, 0x2e, 0x50, 0x6f, 0x64, - 0x53, 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x53, 0x74, 0x64, 0x65, 0x72, 0x72, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1d, 0x2e, 0x70, 0x6f, 0x64, 0x2e, 0x50, 0x6f, 0x64, 0x53, 0x61, - 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x53, 0x74, 0x64, 0x65, 0x72, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x22, 0x23, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1d, 0x12, 0x1b, 0x2f, 0x70, 0x6f, + 0x3a, 0x02, 0x38, 0x01, 0x22, 0x59, 0x0a, 0x1b, 0x50, 0x6f, 0x64, 0x53, 0x61, 0x6e, 0x64, 0x62, + 0x6f, 0x78, 0x4c, 0x69, 0x73, 0x74, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x12, 0x17, 0x0a, 0x07, 0x73, 0x74, 0x75, 0x62, 0x5f, 0x69, 0x64, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x73, 0x74, 0x75, 0x62, 0x49, 0x64, 0x12, 0x21, 0x0a, 0x0c, + 0x73, 0x65, 0x61, 0x72, 0x63, 0x68, 0x5f, 0x61, 0x66, 0x74, 0x65, 0x72, 0x18, 0x02, 0x20, 0x03, + 0x28, 0x09, 0x52, 0x0b, 0x73, 0x65, 0x61, 0x72, 0x63, 0x68, 0x41, 0x66, 0x74, 0x65, 0x72, 0x22, + 0x9a, 0x01, 0x0a, 0x1c, 0x50, 0x6f, 0x64, 0x53, 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x4c, 0x69, + 0x73, 0x74, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x12, 0x0e, 0x0a, 0x02, 0x6f, 0x6b, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x02, 0x6f, 0x6b, + 0x12, 0x1b, 0x0a, 0x09, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x5f, 0x6d, 0x73, 0x67, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x08, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x4d, 0x73, 0x67, 0x12, 0x2c, 0x0a, + 0x06, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x14, 0x2e, + 0x70, 0x6f, 0x64, 0x2e, 0x50, 0x6f, 0x64, 0x53, 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x45, 0x76, + 0x65, 0x6e, 0x74, 0x52, 0x06, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x12, 0x1f, 0x0a, 0x0b, 0x6e, + 0x65, 0x78, 0x74, 0x5f, 0x63, 0x75, 0x72, 0x73, 0x6f, 0x72, 0x18, 0x04, 0x20, 0x03, 0x28, 0x09, + 0x52, 0x0a, 0x6e, 0x65, 0x78, 0x74, 0x43, 0x75, 0x72, 0x73, 0x6f, 0x72, 0x22, 0xd7, 0x01, 0x0a, + 0x0f, 0x50, 0x6f, 0x64, 0x53, 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x45, 0x76, 0x65, 0x6e, 0x74, + 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, + 0x12, 0x12, 0x0a, 0x04, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, + 0x74, 0x69, 0x6d, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x03, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, + 0x75, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, + 0x12, 0x21, 0x0a, 0x0c, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x5f, 0x69, 0x64, + 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, + 0x72, 0x49, 0x64, 0x12, 0x1b, 0x0a, 0x09, 0x77, 0x6f, 0x72, 0x6b, 0x65, 0x72, 0x5f, 0x69, 0x64, + 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x77, 0x6f, 0x72, 0x6b, 0x65, 0x72, 0x49, 0x64, + 0x12, 0x17, 0x0a, 0x07, 0x73, 0x74, 0x75, 0x62, 0x5f, 0x69, 0x64, 0x18, 0x07, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x06, 0x73, 0x74, 0x75, 0x62, 0x49, 0x64, 0x12, 0x1b, 0x0a, 0x09, 0x65, 0x78, 0x69, + 0x74, 0x5f, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x08, 0x20, 0x01, 0x28, 0x05, 0x52, 0x08, 0x65, 0x78, + 0x69, 0x74, 0x43, 0x6f, 0x64, 0x65, 0x32, 0xb3, 0x19, 0x0a, 0x0a, 0x50, 0x6f, 0x64, 0x53, 0x65, + 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x4c, 0x0a, 0x09, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x50, + 0x6f, 0x64, 0x12, 0x15, 0x2e, 0x70, 0x6f, 0x64, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x50, + 0x6f, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x70, 0x6f, 0x64, 0x2e, + 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x50, 0x6f, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x22, 0x10, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x0a, 0x3a, 0x01, 0x2a, 0x22, 0x05, 0x2f, 0x70, + 0x6f, 0x64, 0x73, 0x12, 0x6c, 0x0a, 0x0b, 0x53, 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x45, 0x78, + 0x65, 0x63, 0x12, 0x1a, 0x2e, 0x70, 0x6f, 0x64, 0x2e, 0x50, 0x6f, 0x64, 0x53, 0x61, 0x6e, 0x64, + 0x62, 0x6f, 0x78, 0x45, 0x78, 0x65, 0x63, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1b, + 0x2e, 0x70, 0x6f, 0x64, 0x2e, 0x50, 0x6f, 0x64, 0x53, 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x45, + 0x78, 0x65, 0x63, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x24, 0x82, 0xd3, 0xe4, + 0x93, 0x02, 0x1e, 0x3a, 0x01, 0x2a, 0x22, 0x19, 0x2f, 0x70, 0x6f, 0x64, 0x73, 0x2f, 0x7b, 0x63, + 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x65, 0x78, 0x65, + 0x63, 0x12, 0x71, 0x0a, 0x0d, 0x53, 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x53, 0x74, 0x61, 0x74, + 0x75, 0x73, 0x12, 0x1c, 0x2e, 0x70, 0x6f, 0x64, 0x2e, 0x50, 0x6f, 0x64, 0x53, 0x61, 0x6e, 0x64, + 0x62, 0x6f, 0x78, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x1a, 0x1d, 0x2e, 0x70, 0x6f, 0x64, 0x2e, 0x50, 0x6f, 0x64, 0x53, 0x61, 0x6e, 0x64, 0x62, 0x6f, + 0x78, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, + 0x23, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1d, 0x12, 0x1b, 0x2f, 0x70, 0x6f, 0x64, 0x73, 0x2f, 0x7b, + 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x73, 0x74, + 0x61, 0x74, 0x75, 0x73, 0x12, 0x71, 0x0a, 0x0d, 0x53, 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x53, + 0x74, 0x64, 0x6f, 0x75, 0x74, 0x12, 0x1c, 0x2e, 0x70, 0x6f, 0x64, 0x2e, 0x50, 0x6f, 0x64, 0x53, + 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x53, 0x74, 0x64, 0x6f, 0x75, 0x74, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x1a, 0x1d, 0x2e, 0x70, 0x6f, 0x64, 0x2e, 0x50, 0x6f, 0x64, 0x53, 0x61, 0x6e, + 0x64, 0x62, 0x6f, 0x78, 0x53, 0x74, 0x64, 0x6f, 0x75, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x22, 0x23, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1d, 0x12, 0x1b, 0x2f, 0x70, 0x6f, 0x64, + 0x73, 0x2f, 0x7b, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x7d, + 0x2f, 0x73, 0x74, 0x64, 0x6f, 0x75, 0x74, 0x12, 0x71, 0x0a, 0x0d, 0x53, 0x61, 0x6e, 0x64, 0x62, + 0x6f, 0x78, 0x53, 0x74, 0x64, 0x65, 0x72, 0x72, 0x12, 0x1c, 0x2e, 0x70, 0x6f, 0x64, 0x2e, 0x50, + 0x6f, 0x64, 0x53, 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x53, 0x74, 0x64, 0x65, 0x72, 0x72, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1d, 0x2e, 0x70, 0x6f, 0x64, 0x2e, 0x50, 0x6f, 0x64, + 0x53, 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x53, 0x74, 0x64, 0x65, 0x72, 0x72, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x23, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1d, 0x12, 0x1b, 0x2f, + 0x70, 0x6f, 0x64, 0x73, 0x2f, 0x7b, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x5f, + 0x69, 0x64, 0x7d, 0x2f, 0x73, 0x74, 0x64, 0x65, 0x72, 0x72, 0x12, 0x6c, 0x0a, 0x0b, 0x53, 0x61, + 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x4b, 0x69, 0x6c, 0x6c, 0x12, 0x1a, 0x2e, 0x70, 0x6f, 0x64, 0x2e, + 0x50, 0x6f, 0x64, 0x53, 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x4b, 0x69, 0x6c, 0x6c, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1b, 0x2e, 0x70, 0x6f, 0x64, 0x2e, 0x50, 0x6f, 0x64, 0x53, + 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x4b, 0x69, 0x6c, 0x6c, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x22, 0x24, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1e, 0x3a, 0x01, 0x2a, 0x22, 0x19, 0x2f, + 0x70, 0x6f, 0x64, 0x73, 0x2f, 0x7b, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x5f, + 0x69, 0x64, 0x7d, 0x2f, 0x6b, 0x69, 0x6c, 0x6c, 0x12, 0x89, 0x01, 0x0a, 0x14, 0x53, 0x61, 0x6e, + 0x64, 0x62, 0x6f, 0x78, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x65, + 0x73, 0x12, 0x23, 0x2e, 0x70, 0x6f, 0x64, 0x2e, 0x50, 0x6f, 0x64, 0x53, 0x61, 0x6e, 0x64, 0x62, + 0x6f, 0x78, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x65, 0x73, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x24, 0x2e, 0x70, 0x6f, 0x64, 0x2e, 0x50, 0x6f, 0x64, + 0x53, 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x72, 0x6f, 0x63, 0x65, + 0x73, 0x73, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x26, 0x82, 0xd3, + 0xe4, 0x93, 0x02, 0x20, 0x12, 0x1e, 0x2f, 0x70, 0x6f, 0x64, 0x73, 0x2f, 0x7b, 0x63, 0x6f, 0x6e, + 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x70, 0x72, 0x6f, 0x63, 0x65, + 0x73, 0x73, 0x65, 0x73, 0x12, 0x86, 0x01, 0x0a, 0x11, 0x53, 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, + 0x55, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x46, 0x69, 0x6c, 0x65, 0x12, 0x20, 0x2e, 0x70, 0x6f, 0x64, + 0x2e, 0x50, 0x6f, 0x64, 0x53, 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x55, 0x70, 0x6c, 0x6f, 0x61, + 0x64, 0x46, 0x69, 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x21, 0x2e, 0x70, + 0x6f, 0x64, 0x2e, 0x50, 0x6f, 0x64, 0x53, 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x55, 0x70, 0x6c, + 0x6f, 0x61, 0x64, 0x46, 0x69, 0x6c, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, + 0x2c, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x26, 0x3a, 0x01, 0x2a, 0x22, 0x21, 0x2f, 0x70, 0x6f, 0x64, + 0x73, 0x2f, 0x7b, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x7d, + 0x2f, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x2f, 0x75, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x12, 0x9f, 0x01, + 0x0a, 0x13, 0x53, 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x44, 0x6f, 0x77, 0x6e, 0x6c, 0x6f, 0x61, + 0x64, 0x46, 0x69, 0x6c, 0x65, 0x12, 0x22, 0x2e, 0x70, 0x6f, 0x64, 0x2e, 0x50, 0x6f, 0x64, 0x53, + 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x44, 0x6f, 0x77, 0x6e, 0x6c, 0x6f, 0x61, 0x64, 0x46, 0x69, + 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x23, 0x2e, 0x70, 0x6f, 0x64, 0x2e, + 0x50, 0x6f, 0x64, 0x53, 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x44, 0x6f, 0x77, 0x6e, 0x6c, 0x6f, + 0x61, 0x64, 0x46, 0x69, 0x6c, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x3f, + 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x39, 0x12, 0x37, 0x2f, 0x70, 0x6f, 0x64, 0x73, 0x2f, 0x7b, 0x63, + 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x66, 0x69, 0x6c, + 0x65, 0x73, 0x2f, 0x64, 0x6f, 0x77, 0x6e, 0x6c, 0x6f, 0x61, 0x64, 0x2f, 0x7b, 0x63, 0x6f, 0x6e, + 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x5f, 0x70, 0x61, 0x74, 0x68, 0x3d, 0x2a, 0x2a, 0x7d, 0x12, + 0x7b, 0x0a, 0x0f, 0x53, 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x53, 0x74, 0x61, 0x74, 0x46, 0x69, + 0x6c, 0x65, 0x12, 0x1e, 0x2e, 0x70, 0x6f, 0x64, 0x2e, 0x50, 0x6f, 0x64, 0x53, 0x61, 0x6e, 0x64, + 0x62, 0x6f, 0x78, 0x53, 0x74, 0x61, 0x74, 0x46, 0x69, 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x1a, 0x1f, 0x2e, 0x70, 0x6f, 0x64, 0x2e, 0x50, 0x6f, 0x64, 0x53, 0x61, 0x6e, 0x64, + 0x62, 0x6f, 0x78, 0x53, 0x74, 0x61, 0x74, 0x46, 0x69, 0x6c, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x22, 0x27, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x21, 0x12, 0x1f, 0x2f, 0x70, 0x6f, 0x64, 0x73, 0x2f, 0x7b, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x5f, 0x69, 0x64, - 0x7d, 0x2f, 0x73, 0x74, 0x64, 0x65, 0x72, 0x72, 0x12, 0x6c, 0x0a, 0x0b, 0x53, 0x61, 0x6e, 0x64, - 0x62, 0x6f, 0x78, 0x4b, 0x69, 0x6c, 0x6c, 0x12, 0x1a, 0x2e, 0x70, 0x6f, 0x64, 0x2e, 0x50, 0x6f, - 0x64, 0x53, 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x4b, 0x69, 0x6c, 0x6c, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x1a, 0x1b, 0x2e, 0x70, 0x6f, 0x64, 0x2e, 0x50, 0x6f, 0x64, 0x53, 0x61, 0x6e, - 0x64, 0x62, 0x6f, 0x78, 0x4b, 0x69, 0x6c, 0x6c, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x22, 0x24, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1e, 0x3a, 0x01, 0x2a, 0x22, 0x19, 0x2f, 0x70, 0x6f, + 0x7d, 0x2f, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x2f, 0x73, 0x74, 0x61, 0x74, 0x12, 0x79, 0x0a, 0x10, + 0x53, 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x4c, 0x69, 0x73, 0x74, 0x46, 0x69, 0x6c, 0x65, 0x73, + 0x12, 0x1f, 0x2e, 0x70, 0x6f, 0x64, 0x2e, 0x50, 0x6f, 0x64, 0x53, 0x61, 0x6e, 0x64, 0x62, 0x6f, + 0x78, 0x4c, 0x69, 0x73, 0x74, 0x46, 0x69, 0x6c, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x1a, 0x20, 0x2e, 0x70, 0x6f, 0x64, 0x2e, 0x50, 0x6f, 0x64, 0x53, 0x61, 0x6e, 0x64, 0x62, + 0x6f, 0x78, 0x4c, 0x69, 0x73, 0x74, 0x46, 0x69, 0x6c, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x22, 0x22, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1c, 0x12, 0x1a, 0x2f, 0x70, 0x6f, 0x64, 0x73, 0x2f, 0x7b, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x5f, 0x69, 0x64, - 0x7d, 0x2f, 0x6b, 0x69, 0x6c, 0x6c, 0x12, 0x89, 0x01, 0x0a, 0x14, 0x53, 0x61, 0x6e, 0x64, 0x62, - 0x6f, 0x78, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x65, 0x73, 0x12, - 0x23, 0x2e, 0x70, 0x6f, 0x64, 0x2e, 0x50, 0x6f, 0x64, 0x53, 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, - 0x4c, 0x69, 0x73, 0x74, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x65, 0x73, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x1a, 0x24, 0x2e, 0x70, 0x6f, 0x64, 0x2e, 0x50, 0x6f, 0x64, 0x53, 0x61, - 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, - 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x26, 0x82, 0xd3, 0xe4, 0x93, - 0x02, 0x20, 0x12, 0x1e, 0x2f, 0x70, 0x6f, 0x64, 0x73, 0x2f, 0x7b, 0x63, 0x6f, 0x6e, 0x74, 0x61, - 0x69, 0x6e, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, - 0x65, 0x73, 0x12, 0x86, 0x01, 0x0a, 0x11, 0x53, 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x55, 0x70, - 0x6c, 0x6f, 0x61, 0x64, 0x46, 0x69, 0x6c, 0x65, 0x12, 0x20, 0x2e, 0x70, 0x6f, 0x64, 0x2e, 0x50, - 0x6f, 0x64, 0x53, 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x55, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x46, - 0x69, 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x21, 0x2e, 0x70, 0x6f, 0x64, - 0x2e, 0x50, 0x6f, 0x64, 0x53, 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x55, 0x70, 0x6c, 0x6f, 0x61, - 0x64, 0x46, 0x69, 0x6c, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x2c, 0x82, - 0xd3, 0xe4, 0x93, 0x02, 0x26, 0x3a, 0x01, 0x2a, 0x22, 0x21, 0x2f, 0x70, 0x6f, 0x64, 0x73, 0x2f, - 0x7b, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x66, - 0x69, 0x6c, 0x65, 0x73, 0x2f, 0x75, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x12, 0x9f, 0x01, 0x0a, 0x13, - 0x53, 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x44, 0x6f, 0x77, 0x6e, 0x6c, 0x6f, 0x61, 0x64, 0x46, - 0x69, 0x6c, 0x65, 0x12, 0x22, 0x2e, 0x70, 0x6f, 0x64, 0x2e, 0x50, 0x6f, 0x64, 0x53, 0x61, 0x6e, - 0x64, 0x62, 0x6f, 0x78, 0x44, 0x6f, 0x77, 0x6e, 0x6c, 0x6f, 0x61, 0x64, 0x46, 0x69, 0x6c, 0x65, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x23, 0x2e, 0x70, 0x6f, 0x64, 0x2e, 0x50, 0x6f, - 0x64, 0x53, 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x44, 0x6f, 0x77, 0x6e, 0x6c, 0x6f, 0x61, 0x64, - 0x46, 0x69, 0x6c, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x3f, 0x82, 0xd3, - 0xe4, 0x93, 0x02, 0x39, 0x12, 0x37, 0x2f, 0x70, 0x6f, 0x64, 0x73, 0x2f, 0x7b, 0x63, 0x6f, 0x6e, - 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x66, 0x69, 0x6c, 0x65, 0x73, - 0x2f, 0x64, 0x6f, 0x77, 0x6e, 0x6c, 0x6f, 0x61, 0x64, 0x2f, 0x7b, 0x63, 0x6f, 0x6e, 0x74, 0x61, - 0x69, 0x6e, 0x65, 0x72, 0x5f, 0x70, 0x61, 0x74, 0x68, 0x3d, 0x2a, 0x2a, 0x7d, 0x12, 0x7b, 0x0a, - 0x0f, 0x53, 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x53, 0x74, 0x61, 0x74, 0x46, 0x69, 0x6c, 0x65, - 0x12, 0x1e, 0x2e, 0x70, 0x6f, 0x64, 0x2e, 0x50, 0x6f, 0x64, 0x53, 0x61, 0x6e, 0x64, 0x62, 0x6f, - 0x78, 0x53, 0x74, 0x61, 0x74, 0x46, 0x69, 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x1a, 0x1f, 0x2e, 0x70, 0x6f, 0x64, 0x2e, 0x50, 0x6f, 0x64, 0x53, 0x61, 0x6e, 0x64, 0x62, 0x6f, - 0x78, 0x53, 0x74, 0x61, 0x74, 0x46, 0x69, 0x6c, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x22, 0x27, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x21, 0x12, 0x1f, 0x2f, 0x70, 0x6f, 0x64, 0x73, - 0x2f, 0x7b, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x7d, 0x2f, - 0x66, 0x69, 0x6c, 0x65, 0x73, 0x2f, 0x73, 0x74, 0x61, 0x74, 0x12, 0x79, 0x0a, 0x10, 0x53, 0x61, - 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x4c, 0x69, 0x73, 0x74, 0x46, 0x69, 0x6c, 0x65, 0x73, 0x12, 0x1f, - 0x2e, 0x70, 0x6f, 0x64, 0x2e, 0x50, 0x6f, 0x64, 0x53, 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x4c, - 0x69, 0x73, 0x74, 0x46, 0x69, 0x6c, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, - 0x20, 0x2e, 0x70, 0x6f, 0x64, 0x2e, 0x50, 0x6f, 0x64, 0x53, 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, - 0x4c, 0x69, 0x73, 0x74, 0x46, 0x69, 0x6c, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x22, 0x22, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1c, 0x12, 0x1a, 0x2f, 0x70, 0x6f, 0x64, 0x73, - 0x2f, 0x7b, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x7d, 0x2f, - 0x66, 0x69, 0x6c, 0x65, 0x73, 0x12, 0x90, 0x01, 0x0a, 0x11, 0x53, 0x61, 0x6e, 0x64, 0x62, 0x6f, - 0x78, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x46, 0x69, 0x6c, 0x65, 0x12, 0x20, 0x2e, 0x70, 0x6f, - 0x64, 0x2e, 0x50, 0x6f, 0x64, 0x53, 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x44, 0x65, 0x6c, 0x65, - 0x74, 0x65, 0x46, 0x69, 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x21, 0x2e, + 0x7d, 0x2f, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x12, 0x90, 0x01, 0x0a, 0x11, 0x53, 0x61, 0x6e, 0x64, + 0x62, 0x6f, 0x78, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x46, 0x69, 0x6c, 0x65, 0x12, 0x20, 0x2e, 0x70, 0x6f, 0x64, 0x2e, 0x50, 0x6f, 0x64, 0x53, 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x44, 0x65, - 0x6c, 0x65, 0x74, 0x65, 0x46, 0x69, 0x6c, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x22, 0x36, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x30, 0x2a, 0x2e, 0x2f, 0x70, 0x6f, 0x64, 0x73, 0x2f, - 0x7b, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x66, - 0x69, 0x6c, 0x65, 0x73, 0x2f, 0x7b, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x5f, - 0x70, 0x61, 0x74, 0x68, 0x3d, 0x2a, 0x2a, 0x7d, 0x12, 0x94, 0x01, 0x0a, 0x16, 0x53, 0x61, 0x6e, - 0x64, 0x62, 0x6f, 0x78, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x44, 0x69, 0x72, 0x65, 0x63, 0x74, - 0x6f, 0x72, 0x79, 0x12, 0x25, 0x2e, 0x70, 0x6f, 0x64, 0x2e, 0x50, 0x6f, 0x64, 0x53, 0x61, 0x6e, - 0x64, 0x62, 0x6f, 0x78, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x44, 0x69, 0x72, 0x65, 0x63, 0x74, - 0x6f, 0x72, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x26, 0x2e, 0x70, 0x6f, 0x64, - 0x2e, 0x50, 0x6f, 0x64, 0x53, 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x43, 0x72, 0x65, 0x61, 0x74, - 0x65, 0x44, 0x69, 0x72, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x22, 0x2b, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x25, 0x3a, 0x01, 0x2a, 0x22, 0x20, 0x2f, - 0x70, 0x6f, 0x64, 0x73, 0x2f, 0x7b, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x5f, - 0x69, 0x64, 0x7d, 0x2f, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x69, 0x65, 0x73, 0x12, - 0xa5, 0x01, 0x0a, 0x16, 0x53, 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x44, 0x65, 0x6c, 0x65, 0x74, - 0x65, 0x44, 0x69, 0x72, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x79, 0x12, 0x25, 0x2e, 0x70, 0x6f, 0x64, - 0x2e, 0x50, 0x6f, 0x64, 0x53, 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x44, 0x65, 0x6c, 0x65, 0x74, - 0x65, 0x44, 0x69, 0x72, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x1a, 0x26, 0x2e, 0x70, 0x6f, 0x64, 0x2e, 0x50, 0x6f, 0x64, 0x53, 0x61, 0x6e, 0x64, 0x62, - 0x6f, 0x78, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x44, 0x69, 0x72, 0x65, 0x63, 0x74, 0x6f, 0x72, - 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x3c, 0x82, 0xd3, 0xe4, 0x93, 0x02, - 0x36, 0x2a, 0x34, 0x2f, 0x70, 0x6f, 0x64, 0x73, 0x2f, 0x7b, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, - 0x6e, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x6f, 0x72, - 0x69, 0x65, 0x73, 0x2f, 0x7b, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x5f, 0x70, - 0x61, 0x74, 0x68, 0x3d, 0x2a, 0x2a, 0x7d, 0x12, 0x86, 0x01, 0x0a, 0x11, 0x53, 0x61, 0x6e, 0x64, - 0x62, 0x6f, 0x78, 0x45, 0x78, 0x70, 0x6f, 0x73, 0x65, 0x50, 0x6f, 0x72, 0x74, 0x12, 0x20, 0x2e, - 0x70, 0x6f, 0x64, 0x2e, 0x50, 0x6f, 0x64, 0x53, 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x45, 0x78, - 0x70, 0x6f, 0x73, 0x65, 0x50, 0x6f, 0x72, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, + 0x6c, 0x65, 0x74, 0x65, 0x46, 0x69, 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x21, 0x2e, 0x70, 0x6f, 0x64, 0x2e, 0x50, 0x6f, 0x64, 0x53, 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, - 0x45, 0x78, 0x70, 0x6f, 0x73, 0x65, 0x50, 0x6f, 0x72, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x22, 0x2c, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x26, 0x3a, 0x01, 0x2a, 0x22, 0x21, 0x2f, - 0x70, 0x6f, 0x64, 0x73, 0x2f, 0x7b, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x5f, - 0x69, 0x64, 0x7d, 0x2f, 0x70, 0x6f, 0x72, 0x74, 0x73, 0x2f, 0x65, 0x78, 0x70, 0x6f, 0x73, 0x65, - 0x12, 0xb2, 0x01, 0x0a, 0x1f, 0x53, 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x55, 0x70, 0x64, 0x61, - 0x74, 0x65, 0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, - 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x2e, 0x2e, 0x70, 0x6f, 0x64, 0x2e, 0x50, 0x6f, 0x64, 0x53, 0x61, - 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4e, 0x65, 0x74, 0x77, 0x6f, - 0x72, 0x6b, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2f, 0x2e, 0x70, 0x6f, 0x64, 0x2e, 0x50, 0x6f, 0x64, 0x53, 0x61, - 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4e, 0x65, 0x74, 0x77, 0x6f, - 0x72, 0x6b, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x2e, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x28, 0x3a, 0x01, 0x2a, - 0x22, 0x23, 0x2f, 0x70, 0x6f, 0x64, 0x73, 0x2f, 0x7b, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, - 0x65, 0x72, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x2f, 0x75, - 0x70, 0x64, 0x61, 0x74, 0x65, 0x12, 0x93, 0x01, 0x0a, 0x15, 0x53, 0x61, 0x6e, 0x64, 0x62, 0x6f, - 0x78, 0x52, 0x65, 0x70, 0x6c, 0x61, 0x63, 0x65, 0x49, 0x6e, 0x46, 0x69, 0x6c, 0x65, 0x73, 0x12, - 0x24, 0x2e, 0x70, 0x6f, 0x64, 0x2e, 0x50, 0x6f, 0x64, 0x53, 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, - 0x52, 0x65, 0x70, 0x6c, 0x61, 0x63, 0x65, 0x49, 0x6e, 0x46, 0x69, 0x6c, 0x65, 0x73, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x25, 0x2e, 0x70, 0x6f, 0x64, 0x2e, 0x50, 0x6f, 0x64, 0x53, - 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x52, 0x65, 0x70, 0x6c, 0x61, 0x63, 0x65, 0x49, 0x6e, 0x46, - 0x69, 0x6c, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x2d, 0x82, 0xd3, - 0xe4, 0x93, 0x02, 0x27, 0x3a, 0x01, 0x2a, 0x22, 0x22, 0x2f, 0x70, 0x6f, 0x64, 0x73, 0x2f, 0x7b, - 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x66, 0x69, - 0x6c, 0x65, 0x73, 0x2f, 0x72, 0x65, 0x70, 0x6c, 0x61, 0x63, 0x65, 0x12, 0x87, 0x01, 0x0a, 0x12, - 0x53, 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x46, 0x69, 0x6e, 0x64, 0x49, 0x6e, 0x46, 0x69, 0x6c, - 0x65, 0x73, 0x12, 0x21, 0x2e, 0x70, 0x6f, 0x64, 0x2e, 0x50, 0x6f, 0x64, 0x53, 0x61, 0x6e, 0x64, - 0x62, 0x6f, 0x78, 0x46, 0x69, 0x6e, 0x64, 0x49, 0x6e, 0x46, 0x69, 0x6c, 0x65, 0x73, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x22, 0x2e, 0x70, 0x6f, 0x64, 0x2e, 0x50, 0x6f, 0x64, 0x53, - 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x46, 0x69, 0x6e, 0x64, 0x49, 0x6e, 0x46, 0x69, 0x6c, 0x65, - 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x2a, 0x82, 0xd3, 0xe4, 0x93, 0x02, - 0x24, 0x3a, 0x01, 0x2a, 0x22, 0x1f, 0x2f, 0x70, 0x6f, 0x64, 0x73, 0x2f, 0x7b, 0x63, 0x6f, 0x6e, - 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x66, 0x69, 0x6c, 0x65, 0x73, - 0x2f, 0x66, 0x69, 0x6e, 0x64, 0x12, 0x78, 0x0a, 0x0e, 0x53, 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, - 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x12, 0x1d, 0x2e, 0x70, 0x6f, 0x64, 0x2e, 0x50, 0x6f, - 0x64, 0x53, 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x52, - 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1e, 0x2e, 0x70, 0x6f, 0x64, 0x2e, 0x50, 0x6f, 0x64, - 0x53, 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x27, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x21, 0x3a, 0x01, - 0x2a, 0x22, 0x1c, 0x2f, 0x70, 0x6f, 0x64, 0x73, 0x2f, 0x7b, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, - 0x6e, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x12, - 0x7a, 0x0a, 0x10, 0x53, 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, - 0x54, 0x54, 0x4c, 0x12, 0x1f, 0x2e, 0x70, 0x6f, 0x64, 0x2e, 0x50, 0x6f, 0x64, 0x53, 0x61, 0x6e, - 0x64, 0x62, 0x6f, 0x78, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x54, 0x54, 0x4c, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x1a, 0x20, 0x2e, 0x70, 0x6f, 0x64, 0x2e, 0x50, 0x6f, 0x64, 0x53, 0x61, - 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x54, 0x54, 0x4c, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x23, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1d, 0x3a, 0x01, - 0x2a, 0x22, 0x18, 0x2f, 0x70, 0x6f, 0x64, 0x73, 0x2f, 0x7b, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, - 0x6e, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x74, 0x74, 0x6c, 0x12, 0xc3, 0x01, 0x0a, 0x20, - 0x53, 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x49, 0x6d, 0x61, - 0x67, 0x65, 0x46, 0x72, 0x6f, 0x6d, 0x46, 0x69, 0x6c, 0x65, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, - 0x12, 0x2f, 0x2e, 0x70, 0x6f, 0x64, 0x2e, 0x50, 0x6f, 0x64, 0x53, 0x61, 0x6e, 0x64, 0x62, 0x6f, - 0x78, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x49, 0x6d, 0x61, 0x67, 0x65, 0x46, 0x72, 0x6f, 0x6d, - 0x46, 0x69, 0x6c, 0x65, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x1a, 0x30, 0x2e, 0x70, 0x6f, 0x64, 0x2e, 0x50, 0x6f, 0x64, 0x53, 0x61, 0x6e, 0x64, 0x62, - 0x6f, 0x78, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x49, 0x6d, 0x61, 0x67, 0x65, 0x46, 0x72, 0x6f, - 0x6d, 0x46, 0x69, 0x6c, 0x65, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x22, 0x3c, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x36, 0x3a, 0x01, 0x2a, 0x22, 0x31, - 0x2f, 0x70, 0x6f, 0x64, 0x73, 0x2f, 0x7b, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, - 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x2d, 0x69, 0x6d, 0x61, 0x67, - 0x65, 0x2d, 0x66, 0x72, 0x6f, 0x6d, 0x2d, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x79, 0x73, 0x74, 0x65, - 0x6d, 0x12, 0x95, 0x01, 0x0a, 0x15, 0x53, 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x53, 0x6e, 0x61, - 0x70, 0x73, 0x68, 0x6f, 0x74, 0x4d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x12, 0x24, 0x2e, 0x70, 0x6f, - 0x64, 0x2e, 0x50, 0x6f, 0x64, 0x53, 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x53, 0x6e, 0x61, 0x70, - 0x73, 0x68, 0x6f, 0x74, 0x4d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x1a, 0x25, 0x2e, 0x70, 0x6f, 0x64, 0x2e, 0x50, 0x6f, 0x64, 0x53, 0x61, 0x6e, 0x64, 0x62, - 0x6f, 0x78, 0x53, 0x6e, 0x61, 0x70, 0x73, 0x68, 0x6f, 0x74, 0x4d, 0x65, 0x6d, 0x6f, 0x72, 0x79, - 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x2f, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x29, - 0x3a, 0x01, 0x2a, 0x22, 0x24, 0x2f, 0x70, 0x6f, 0x64, 0x73, 0x2f, 0x7b, 0x63, 0x6f, 0x6e, 0x74, - 0x61, 0x69, 0x6e, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x73, 0x6e, 0x61, 0x70, 0x73, 0x68, - 0x6f, 0x74, 0x2d, 0x6d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x12, 0x75, 0x0a, 0x0f, 0x53, 0x61, 0x6e, - 0x64, 0x62, 0x6f, 0x78, 0x4c, 0x69, 0x73, 0x74, 0x55, 0x72, 0x6c, 0x73, 0x12, 0x1e, 0x2e, 0x70, - 0x6f, 0x64, 0x2e, 0x50, 0x6f, 0x64, 0x53, 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x4c, 0x69, 0x73, - 0x74, 0x55, 0x72, 0x6c, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1f, 0x2e, 0x70, - 0x6f, 0x64, 0x2e, 0x50, 0x6f, 0x64, 0x53, 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x4c, 0x69, 0x73, - 0x74, 0x55, 0x72, 0x6c, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x21, 0x82, - 0xd3, 0xe4, 0x93, 0x02, 0x1b, 0x12, 0x19, 0x2f, 0x70, 0x6f, 0x64, 0x73, 0x2f, 0x7b, 0x63, 0x6f, - 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x75, 0x72, 0x6c, 0x73, - 0x42, 0x23, 0x5a, 0x21, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x62, - 0x65, 0x61, 0x6d, 0x2d, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2f, 0x62, 0x65, 0x74, 0x61, 0x39, 0x2f, - 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x46, 0x69, 0x6c, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x22, 0x36, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x30, 0x2a, 0x2e, 0x2f, 0x70, 0x6f, 0x64, + 0x73, 0x2f, 0x7b, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x7d, + 0x2f, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x2f, 0x7b, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, + 0x72, 0x5f, 0x70, 0x61, 0x74, 0x68, 0x3d, 0x2a, 0x2a, 0x7d, 0x12, 0x94, 0x01, 0x0a, 0x16, 0x53, + 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x44, 0x69, 0x72, 0x65, + 0x63, 0x74, 0x6f, 0x72, 0x79, 0x12, 0x25, 0x2e, 0x70, 0x6f, 0x64, 0x2e, 0x50, 0x6f, 0x64, 0x53, + 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x44, 0x69, 0x72, 0x65, + 0x63, 0x74, 0x6f, 0x72, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x26, 0x2e, 0x70, + 0x6f, 0x64, 0x2e, 0x50, 0x6f, 0x64, 0x53, 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x43, 0x72, 0x65, + 0x61, 0x74, 0x65, 0x44, 0x69, 0x72, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x79, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x2b, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x25, 0x3a, 0x01, 0x2a, 0x22, + 0x20, 0x2f, 0x70, 0x6f, 0x64, 0x73, 0x2f, 0x7b, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, + 0x72, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x69, 0x65, + 0x73, 0x12, 0xa5, 0x01, 0x0a, 0x16, 0x53, 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x44, 0x65, 0x6c, + 0x65, 0x74, 0x65, 0x44, 0x69, 0x72, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x79, 0x12, 0x25, 0x2e, 0x70, + 0x6f, 0x64, 0x2e, 0x50, 0x6f, 0x64, 0x53, 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x44, 0x65, 0x6c, + 0x65, 0x74, 0x65, 0x44, 0x69, 0x72, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x79, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x1a, 0x26, 0x2e, 0x70, 0x6f, 0x64, 0x2e, 0x50, 0x6f, 0x64, 0x53, 0x61, 0x6e, + 0x64, 0x62, 0x6f, 0x78, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x44, 0x69, 0x72, 0x65, 0x63, 0x74, + 0x6f, 0x72, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x3c, 0x82, 0xd3, 0xe4, + 0x93, 0x02, 0x36, 0x2a, 0x34, 0x2f, 0x70, 0x6f, 0x64, 0x73, 0x2f, 0x7b, 0x63, 0x6f, 0x6e, 0x74, + 0x61, 0x69, 0x6e, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, + 0x6f, 0x72, 0x69, 0x65, 0x73, 0x2f, 0x7b, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, + 0x5f, 0x70, 0x61, 0x74, 0x68, 0x3d, 0x2a, 0x2a, 0x7d, 0x12, 0x86, 0x01, 0x0a, 0x11, 0x53, 0x61, + 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x45, 0x78, 0x70, 0x6f, 0x73, 0x65, 0x50, 0x6f, 0x72, 0x74, 0x12, + 0x20, 0x2e, 0x70, 0x6f, 0x64, 0x2e, 0x50, 0x6f, 0x64, 0x53, 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, + 0x45, 0x78, 0x70, 0x6f, 0x73, 0x65, 0x50, 0x6f, 0x72, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x1a, 0x21, 0x2e, 0x70, 0x6f, 0x64, 0x2e, 0x50, 0x6f, 0x64, 0x53, 0x61, 0x6e, 0x64, 0x62, + 0x6f, 0x78, 0x45, 0x78, 0x70, 0x6f, 0x73, 0x65, 0x50, 0x6f, 0x72, 0x74, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x2c, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x26, 0x3a, 0x01, 0x2a, 0x22, + 0x21, 0x2f, 0x70, 0x6f, 0x64, 0x73, 0x2f, 0x7b, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, + 0x72, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x70, 0x6f, 0x72, 0x74, 0x73, 0x2f, 0x65, 0x78, 0x70, 0x6f, + 0x73, 0x65, 0x12, 0xb2, 0x01, 0x0a, 0x1f, 0x53, 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x55, 0x70, + 0x64, 0x61, 0x74, 0x65, 0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x50, 0x65, 0x72, 0x6d, 0x69, + 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x2e, 0x2e, 0x70, 0x6f, 0x64, 0x2e, 0x50, 0x6f, 0x64, + 0x53, 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4e, 0x65, 0x74, + 0x77, 0x6f, 0x72, 0x6b, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2f, 0x2e, 0x70, 0x6f, 0x64, 0x2e, 0x50, 0x6f, 0x64, + 0x53, 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4e, 0x65, 0x74, + 0x77, 0x6f, 0x72, 0x6b, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x2e, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x28, 0x3a, + 0x01, 0x2a, 0x22, 0x23, 0x2f, 0x70, 0x6f, 0x64, 0x73, 0x2f, 0x7b, 0x63, 0x6f, 0x6e, 0x74, 0x61, + 0x69, 0x6e, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, + 0x2f, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x12, 0x93, 0x01, 0x0a, 0x15, 0x53, 0x61, 0x6e, 0x64, + 0x62, 0x6f, 0x78, 0x52, 0x65, 0x70, 0x6c, 0x61, 0x63, 0x65, 0x49, 0x6e, 0x46, 0x69, 0x6c, 0x65, + 0x73, 0x12, 0x24, 0x2e, 0x70, 0x6f, 0x64, 0x2e, 0x50, 0x6f, 0x64, 0x53, 0x61, 0x6e, 0x64, 0x62, + 0x6f, 0x78, 0x52, 0x65, 0x70, 0x6c, 0x61, 0x63, 0x65, 0x49, 0x6e, 0x46, 0x69, 0x6c, 0x65, 0x73, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x25, 0x2e, 0x70, 0x6f, 0x64, 0x2e, 0x50, 0x6f, + 0x64, 0x53, 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x52, 0x65, 0x70, 0x6c, 0x61, 0x63, 0x65, 0x49, + 0x6e, 0x46, 0x69, 0x6c, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x2d, + 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x27, 0x3a, 0x01, 0x2a, 0x22, 0x22, 0x2f, 0x70, 0x6f, 0x64, 0x73, + 0x2f, 0x7b, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x7d, 0x2f, + 0x66, 0x69, 0x6c, 0x65, 0x73, 0x2f, 0x72, 0x65, 0x70, 0x6c, 0x61, 0x63, 0x65, 0x12, 0x87, 0x01, + 0x0a, 0x12, 0x53, 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x46, 0x69, 0x6e, 0x64, 0x49, 0x6e, 0x46, + 0x69, 0x6c, 0x65, 0x73, 0x12, 0x21, 0x2e, 0x70, 0x6f, 0x64, 0x2e, 0x50, 0x6f, 0x64, 0x53, 0x61, + 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x46, 0x69, 0x6e, 0x64, 0x49, 0x6e, 0x46, 0x69, 0x6c, 0x65, 0x73, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x22, 0x2e, 0x70, 0x6f, 0x64, 0x2e, 0x50, 0x6f, + 0x64, 0x53, 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x46, 0x69, 0x6e, 0x64, 0x49, 0x6e, 0x46, 0x69, + 0x6c, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x2a, 0x82, 0xd3, 0xe4, + 0x93, 0x02, 0x24, 0x3a, 0x01, 0x2a, 0x22, 0x1f, 0x2f, 0x70, 0x6f, 0x64, 0x73, 0x2f, 0x7b, 0x63, + 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x66, 0x69, 0x6c, + 0x65, 0x73, 0x2f, 0x66, 0x69, 0x6e, 0x64, 0x12, 0x78, 0x0a, 0x0e, 0x53, 0x61, 0x6e, 0x64, 0x62, + 0x6f, 0x78, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x12, 0x1d, 0x2e, 0x70, 0x6f, 0x64, 0x2e, + 0x50, 0x6f, 0x64, 0x53, 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, + 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1e, 0x2e, 0x70, 0x6f, 0x64, 0x2e, 0x50, + 0x6f, 0x64, 0x53, 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x27, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x21, + 0x3a, 0x01, 0x2a, 0x22, 0x1c, 0x2f, 0x70, 0x6f, 0x64, 0x73, 0x2f, 0x7b, 0x63, 0x6f, 0x6e, 0x74, + 0x61, 0x69, 0x6e, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, + 0x74, 0x12, 0x7a, 0x0a, 0x10, 0x53, 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x55, 0x70, 0x64, 0x61, + 0x74, 0x65, 0x54, 0x54, 0x4c, 0x12, 0x1f, 0x2e, 0x70, 0x6f, 0x64, 0x2e, 0x50, 0x6f, 0x64, 0x53, + 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x54, 0x54, 0x4c, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x20, 0x2e, 0x70, 0x6f, 0x64, 0x2e, 0x50, 0x6f, 0x64, + 0x53, 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x54, 0x54, 0x4c, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x23, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1d, + 0x3a, 0x01, 0x2a, 0x22, 0x18, 0x2f, 0x70, 0x6f, 0x64, 0x73, 0x2f, 0x7b, 0x63, 0x6f, 0x6e, 0x74, + 0x61, 0x69, 0x6e, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x74, 0x74, 0x6c, 0x12, 0xc3, 0x01, + 0x0a, 0x20, 0x53, 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x49, + 0x6d, 0x61, 0x67, 0x65, 0x46, 0x72, 0x6f, 0x6d, 0x46, 0x69, 0x6c, 0x65, 0x73, 0x79, 0x73, 0x74, + 0x65, 0x6d, 0x12, 0x2f, 0x2e, 0x70, 0x6f, 0x64, 0x2e, 0x50, 0x6f, 0x64, 0x53, 0x61, 0x6e, 0x64, + 0x62, 0x6f, 0x78, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x49, 0x6d, 0x61, 0x67, 0x65, 0x46, 0x72, + 0x6f, 0x6d, 0x46, 0x69, 0x6c, 0x65, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x1a, 0x30, 0x2e, 0x70, 0x6f, 0x64, 0x2e, 0x50, 0x6f, 0x64, 0x53, 0x61, 0x6e, + 0x64, 0x62, 0x6f, 0x78, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x49, 0x6d, 0x61, 0x67, 0x65, 0x46, + 0x72, 0x6f, 0x6d, 0x46, 0x69, 0x6c, 0x65, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x3c, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x36, 0x3a, 0x01, 0x2a, + 0x22, 0x31, 0x2f, 0x70, 0x6f, 0x64, 0x73, 0x2f, 0x7b, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, + 0x65, 0x72, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x2d, 0x69, 0x6d, + 0x61, 0x67, 0x65, 0x2d, 0x66, 0x72, 0x6f, 0x6d, 0x2d, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x79, 0x73, + 0x74, 0x65, 0x6d, 0x12, 0x95, 0x01, 0x0a, 0x15, 0x53, 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x53, + 0x6e, 0x61, 0x70, 0x73, 0x68, 0x6f, 0x74, 0x4d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x12, 0x24, 0x2e, + 0x70, 0x6f, 0x64, 0x2e, 0x50, 0x6f, 0x64, 0x53, 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x53, 0x6e, + 0x61, 0x70, 0x73, 0x68, 0x6f, 0x74, 0x4d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x1a, 0x25, 0x2e, 0x70, 0x6f, 0x64, 0x2e, 0x50, 0x6f, 0x64, 0x53, 0x61, 0x6e, + 0x64, 0x62, 0x6f, 0x78, 0x53, 0x6e, 0x61, 0x70, 0x73, 0x68, 0x6f, 0x74, 0x4d, 0x65, 0x6d, 0x6f, + 0x72, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x2f, 0x82, 0xd3, 0xe4, 0x93, + 0x02, 0x29, 0x3a, 0x01, 0x2a, 0x22, 0x24, 0x2f, 0x70, 0x6f, 0x64, 0x73, 0x2f, 0x7b, 0x63, 0x6f, + 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x73, 0x6e, 0x61, 0x70, + 0x73, 0x68, 0x6f, 0x74, 0x2d, 0x6d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x12, 0x75, 0x0a, 0x0f, 0x53, + 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x4c, 0x69, 0x73, 0x74, 0x55, 0x72, 0x6c, 0x73, 0x12, 0x1e, + 0x2e, 0x70, 0x6f, 0x64, 0x2e, 0x50, 0x6f, 0x64, 0x53, 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x4c, + 0x69, 0x73, 0x74, 0x55, 0x72, 0x6c, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1f, + 0x2e, 0x70, 0x6f, 0x64, 0x2e, 0x50, 0x6f, 0x64, 0x53, 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x4c, + 0x69, 0x73, 0x74, 0x55, 0x72, 0x6c, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, + 0x21, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1b, 0x12, 0x19, 0x2f, 0x70, 0x6f, 0x64, 0x73, 0x2f, 0x7b, + 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x75, 0x72, + 0x6c, 0x73, 0x12, 0x78, 0x0a, 0x11, 0x53, 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x4c, 0x69, 0x73, + 0x74, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x12, 0x20, 0x2e, 0x70, 0x6f, 0x64, 0x2e, 0x50, 0x6f, + 0x64, 0x53, 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x4c, 0x69, 0x73, 0x74, 0x45, 0x76, 0x65, 0x6e, + 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x21, 0x2e, 0x70, 0x6f, 0x64, 0x2e, + 0x50, 0x6f, 0x64, 0x53, 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x4c, 0x69, 0x73, 0x74, 0x45, 0x76, + 0x65, 0x6e, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x1e, 0x82, 0xd3, + 0xe4, 0x93, 0x02, 0x18, 0x12, 0x16, 0x2f, 0x70, 0x6f, 0x64, 0x73, 0x2f, 0x7b, 0x73, 0x74, 0x75, + 0x62, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x42, 0x23, 0x5a, 0x21, + 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x62, 0x65, 0x61, 0x6d, 0x2d, + 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2f, 0x62, 0x65, 0x74, 0x61, 0x39, 0x2f, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -3405,7 +3671,7 @@ func file_pod_proto_rawDescGZIP() []byte { return file_pod_proto_rawDescData } -var file_pod_proto_msgTypes = make([]protoimpl.MessageInfo, 49) +var file_pod_proto_msgTypes = make([]protoimpl.MessageInfo, 52) var file_pod_proto_goTypes = []interface{}{ (*CreatePodRequest)(nil), // 0: pod.CreatePodRequest (*CreatePodResponse)(nil), // 1: pod.CreatePodResponse @@ -3454,69 +3720,75 @@ var file_pod_proto_goTypes = []interface{}{ (*PodSandboxListProcessesResponse)(nil), // 44: pod.PodSandboxListProcessesResponse (*PodSandboxListUrlsRequest)(nil), // 45: pod.PodSandboxListUrlsRequest (*PodSandboxListUrlsResponse)(nil), // 46: pod.PodSandboxListUrlsResponse - nil, // 47: pod.PodSandboxExecRequest.EnvEntry - nil, // 48: pod.PodSandboxListUrlsResponse.UrlsEntry - (*FileSearchResult)(nil), // 49: types.FileSearchResult - (*ProcessInfo)(nil), // 50: types.ProcessInfo + (*PodSandboxListEventsRequest)(nil), // 47: pod.PodSandboxListEventsRequest + (*PodSandboxListEventsResponse)(nil), // 48: pod.PodSandboxListEventsResponse + (*PodSandboxEvent)(nil), // 49: pod.PodSandboxEvent + nil, // 50: pod.PodSandboxExecRequest.EnvEntry + nil, // 51: pod.PodSandboxListUrlsResponse.UrlsEntry + (*FileSearchResult)(nil), // 52: types.FileSearchResult + (*ProcessInfo)(nil), // 53: types.ProcessInfo } var file_pod_proto_depIdxs = []int32{ - 47, // 0: pod.PodSandboxExecRequest.env:type_name -> pod.PodSandboxExecRequest.EnvEntry + 50, // 0: pod.PodSandboxExecRequest.env:type_name -> pod.PodSandboxExecRequest.EnvEntry 26, // 1: pod.PodSandboxListFilesResponse.files:type_name -> pod.PodSandboxFileInfo 26, // 2: pod.PodSandboxStatFileResponse.file_info:type_name -> pod.PodSandboxFileInfo - 49, // 3: pod.PodSandboxFindInFilesResponse.results:type_name -> types.FileSearchResult - 50, // 4: pod.PodSandboxListProcessesResponse.processes:type_name -> types.ProcessInfo - 48, // 5: pod.PodSandboxListUrlsResponse.urls:type_name -> pod.PodSandboxListUrlsResponse.UrlsEntry - 0, // 6: pod.PodService.CreatePod:input_type -> pod.CreatePodRequest - 2, // 7: pod.PodService.SandboxExec:input_type -> pod.PodSandboxExecRequest - 4, // 8: pod.PodService.SandboxStatus:input_type -> pod.PodSandboxStatusRequest - 6, // 9: pod.PodService.SandboxStdout:input_type -> pod.PodSandboxStdoutRequest - 8, // 10: pod.PodService.SandboxStderr:input_type -> pod.PodSandboxStderrRequest - 10, // 11: pod.PodService.SandboxKill:input_type -> pod.PodSandboxKillRequest - 43, // 12: pod.PodService.SandboxListProcesses:input_type -> pod.PodSandboxListProcessesRequest - 12, // 13: pod.PodService.SandboxUploadFile:input_type -> pod.PodSandboxUploadFileRequest - 14, // 14: pod.PodService.SandboxDownloadFile:input_type -> pod.PodSandboxDownloadFileRequest - 24, // 15: pod.PodService.SandboxStatFile:input_type -> pod.PodSandboxStatFileRequest - 16, // 16: pod.PodService.SandboxListFiles:input_type -> pod.PodSandboxListFilesRequest - 18, // 17: pod.PodService.SandboxDeleteFile:input_type -> pod.PodSandboxDeleteFileRequest - 20, // 18: pod.PodService.SandboxCreateDirectory:input_type -> pod.PodSandboxCreateDirectoryRequest - 22, // 19: pod.PodService.SandboxDeleteDirectory:input_type -> pod.PodSandboxDeleteDirectoryRequest - 29, // 20: pod.PodService.SandboxExposePort:input_type -> pod.PodSandboxExposePortRequest - 31, // 21: pod.PodService.SandboxUpdateNetworkPermissions:input_type -> pod.PodSandboxUpdateNetworkPermissionsRequest - 27, // 22: pod.PodService.SandboxReplaceInFiles:input_type -> pod.PodSandboxReplaceInFilesRequest - 33, // 23: pod.PodService.SandboxFindInFiles:input_type -> pod.PodSandboxFindInFilesRequest - 35, // 24: pod.PodService.SandboxConnect:input_type -> pod.PodSandboxConnectRequest - 37, // 25: pod.PodService.SandboxUpdateTTL:input_type -> pod.PodSandboxUpdateTTLRequest - 39, // 26: pod.PodService.SandboxCreateImageFromFilesystem:input_type -> pod.PodSandboxCreateImageFromFilesystemRequest - 41, // 27: pod.PodService.SandboxSnapshotMemory:input_type -> pod.PodSandboxSnapshotMemoryRequest - 45, // 28: pod.PodService.SandboxListUrls:input_type -> pod.PodSandboxListUrlsRequest - 1, // 29: pod.PodService.CreatePod:output_type -> pod.CreatePodResponse - 3, // 30: pod.PodService.SandboxExec:output_type -> pod.PodSandboxExecResponse - 5, // 31: pod.PodService.SandboxStatus:output_type -> pod.PodSandboxStatusResponse - 7, // 32: pod.PodService.SandboxStdout:output_type -> pod.PodSandboxStdoutResponse - 9, // 33: pod.PodService.SandboxStderr:output_type -> pod.PodSandboxStderrResponse - 11, // 34: pod.PodService.SandboxKill:output_type -> pod.PodSandboxKillResponse - 44, // 35: pod.PodService.SandboxListProcesses:output_type -> pod.PodSandboxListProcessesResponse - 13, // 36: pod.PodService.SandboxUploadFile:output_type -> pod.PodSandboxUploadFileResponse - 15, // 37: pod.PodService.SandboxDownloadFile:output_type -> pod.PodSandboxDownloadFileResponse - 25, // 38: pod.PodService.SandboxStatFile:output_type -> pod.PodSandboxStatFileResponse - 17, // 39: pod.PodService.SandboxListFiles:output_type -> pod.PodSandboxListFilesResponse - 19, // 40: pod.PodService.SandboxDeleteFile:output_type -> pod.PodSandboxDeleteFileResponse - 21, // 41: pod.PodService.SandboxCreateDirectory:output_type -> pod.PodSandboxCreateDirectoryResponse - 23, // 42: pod.PodService.SandboxDeleteDirectory:output_type -> pod.PodSandboxDeleteDirectoryResponse - 30, // 43: pod.PodService.SandboxExposePort:output_type -> pod.PodSandboxExposePortResponse - 32, // 44: pod.PodService.SandboxUpdateNetworkPermissions:output_type -> pod.PodSandboxUpdateNetworkPermissionsResponse - 28, // 45: pod.PodService.SandboxReplaceInFiles:output_type -> pod.PodSandboxReplaceInFilesResponse - 34, // 46: pod.PodService.SandboxFindInFiles:output_type -> pod.PodSandboxFindInFilesResponse - 36, // 47: pod.PodService.SandboxConnect:output_type -> pod.PodSandboxConnectResponse - 38, // 48: pod.PodService.SandboxUpdateTTL:output_type -> pod.PodSandboxUpdateTTLResponse - 40, // 49: pod.PodService.SandboxCreateImageFromFilesystem:output_type -> pod.PodSandboxCreateImageFromFilesystemResponse - 42, // 50: pod.PodService.SandboxSnapshotMemory:output_type -> pod.PodSandboxSnapshotMemoryResponse - 46, // 51: pod.PodService.SandboxListUrls:output_type -> pod.PodSandboxListUrlsResponse - 29, // [29:52] is the sub-list for method output_type - 6, // [6:29] is the sub-list for method input_type - 6, // [6:6] is the sub-list for extension type_name - 6, // [6:6] is the sub-list for extension extendee - 0, // [0:6] is the sub-list for field type_name + 52, // 3: pod.PodSandboxFindInFilesResponse.results:type_name -> types.FileSearchResult + 53, // 4: pod.PodSandboxListProcessesResponse.processes:type_name -> types.ProcessInfo + 51, // 5: pod.PodSandboxListUrlsResponse.urls:type_name -> pod.PodSandboxListUrlsResponse.UrlsEntry + 49, // 6: pod.PodSandboxListEventsResponse.events:type_name -> pod.PodSandboxEvent + 0, // 7: pod.PodService.CreatePod:input_type -> pod.CreatePodRequest + 2, // 8: pod.PodService.SandboxExec:input_type -> pod.PodSandboxExecRequest + 4, // 9: pod.PodService.SandboxStatus:input_type -> pod.PodSandboxStatusRequest + 6, // 10: pod.PodService.SandboxStdout:input_type -> pod.PodSandboxStdoutRequest + 8, // 11: pod.PodService.SandboxStderr:input_type -> pod.PodSandboxStderrRequest + 10, // 12: pod.PodService.SandboxKill:input_type -> pod.PodSandboxKillRequest + 43, // 13: pod.PodService.SandboxListProcesses:input_type -> pod.PodSandboxListProcessesRequest + 12, // 14: pod.PodService.SandboxUploadFile:input_type -> pod.PodSandboxUploadFileRequest + 14, // 15: pod.PodService.SandboxDownloadFile:input_type -> pod.PodSandboxDownloadFileRequest + 24, // 16: pod.PodService.SandboxStatFile:input_type -> pod.PodSandboxStatFileRequest + 16, // 17: pod.PodService.SandboxListFiles:input_type -> pod.PodSandboxListFilesRequest + 18, // 18: pod.PodService.SandboxDeleteFile:input_type -> pod.PodSandboxDeleteFileRequest + 20, // 19: pod.PodService.SandboxCreateDirectory:input_type -> pod.PodSandboxCreateDirectoryRequest + 22, // 20: pod.PodService.SandboxDeleteDirectory:input_type -> pod.PodSandboxDeleteDirectoryRequest + 29, // 21: pod.PodService.SandboxExposePort:input_type -> pod.PodSandboxExposePortRequest + 31, // 22: pod.PodService.SandboxUpdateNetworkPermissions:input_type -> pod.PodSandboxUpdateNetworkPermissionsRequest + 27, // 23: pod.PodService.SandboxReplaceInFiles:input_type -> pod.PodSandboxReplaceInFilesRequest + 33, // 24: pod.PodService.SandboxFindInFiles:input_type -> pod.PodSandboxFindInFilesRequest + 35, // 25: pod.PodService.SandboxConnect:input_type -> pod.PodSandboxConnectRequest + 37, // 26: pod.PodService.SandboxUpdateTTL:input_type -> pod.PodSandboxUpdateTTLRequest + 39, // 27: pod.PodService.SandboxCreateImageFromFilesystem:input_type -> pod.PodSandboxCreateImageFromFilesystemRequest + 41, // 28: pod.PodService.SandboxSnapshotMemory:input_type -> pod.PodSandboxSnapshotMemoryRequest + 45, // 29: pod.PodService.SandboxListUrls:input_type -> pod.PodSandboxListUrlsRequest + 47, // 30: pod.PodService.SandboxListEvents:input_type -> pod.PodSandboxListEventsRequest + 1, // 31: pod.PodService.CreatePod:output_type -> pod.CreatePodResponse + 3, // 32: pod.PodService.SandboxExec:output_type -> pod.PodSandboxExecResponse + 5, // 33: pod.PodService.SandboxStatus:output_type -> pod.PodSandboxStatusResponse + 7, // 34: pod.PodService.SandboxStdout:output_type -> pod.PodSandboxStdoutResponse + 9, // 35: pod.PodService.SandboxStderr:output_type -> pod.PodSandboxStderrResponse + 11, // 36: pod.PodService.SandboxKill:output_type -> pod.PodSandboxKillResponse + 44, // 37: pod.PodService.SandboxListProcesses:output_type -> pod.PodSandboxListProcessesResponse + 13, // 38: pod.PodService.SandboxUploadFile:output_type -> pod.PodSandboxUploadFileResponse + 15, // 39: pod.PodService.SandboxDownloadFile:output_type -> pod.PodSandboxDownloadFileResponse + 25, // 40: pod.PodService.SandboxStatFile:output_type -> pod.PodSandboxStatFileResponse + 17, // 41: pod.PodService.SandboxListFiles:output_type -> pod.PodSandboxListFilesResponse + 19, // 42: pod.PodService.SandboxDeleteFile:output_type -> pod.PodSandboxDeleteFileResponse + 21, // 43: pod.PodService.SandboxCreateDirectory:output_type -> pod.PodSandboxCreateDirectoryResponse + 23, // 44: pod.PodService.SandboxDeleteDirectory:output_type -> pod.PodSandboxDeleteDirectoryResponse + 30, // 45: pod.PodService.SandboxExposePort:output_type -> pod.PodSandboxExposePortResponse + 32, // 46: pod.PodService.SandboxUpdateNetworkPermissions:output_type -> pod.PodSandboxUpdateNetworkPermissionsResponse + 28, // 47: pod.PodService.SandboxReplaceInFiles:output_type -> pod.PodSandboxReplaceInFilesResponse + 34, // 48: pod.PodService.SandboxFindInFiles:output_type -> pod.PodSandboxFindInFilesResponse + 36, // 49: pod.PodService.SandboxConnect:output_type -> pod.PodSandboxConnectResponse + 38, // 50: pod.PodService.SandboxUpdateTTL:output_type -> pod.PodSandboxUpdateTTLResponse + 40, // 51: pod.PodService.SandboxCreateImageFromFilesystem:output_type -> pod.PodSandboxCreateImageFromFilesystemResponse + 42, // 52: pod.PodService.SandboxSnapshotMemory:output_type -> pod.PodSandboxSnapshotMemoryResponse + 46, // 53: pod.PodService.SandboxListUrls:output_type -> pod.PodSandboxListUrlsResponse + 48, // 54: pod.PodService.SandboxListEvents:output_type -> pod.PodSandboxListEventsResponse + 31, // [31:55] is the sub-list for method output_type + 7, // [7:31] is the sub-list for method input_type + 7, // [7:7] is the sub-list for extension type_name + 7, // [7:7] is the sub-list for extension extendee + 0, // [0:7] is the sub-list for field type_name } func init() { file_pod_proto_init() } @@ -4090,6 +4362,42 @@ func file_pod_proto_init() { return nil } } + file_pod_proto_msgTypes[47].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*PodSandboxListEventsRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_pod_proto_msgTypes[48].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*PodSandboxListEventsResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_pod_proto_msgTypes[49].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*PodSandboxEvent); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } } file_pod_proto_msgTypes[0].OneofWrappers = []interface{}{} type x struct{} @@ -4098,7 +4406,7 @@ func file_pod_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_pod_proto_rawDesc, NumEnums: 0, - NumMessages: 49, + NumMessages: 52, NumExtensions: 0, NumServices: 1, }, diff --git a/proto/pod.pb.gw.go b/proto/pod.pb.gw.go index aafa5ad52..58ccdff2c 100644 --- a/proto/pod.pb.gw.go +++ b/proto/pod.pb.gw.go @@ -1110,6 +1110,59 @@ func local_request_PodService_SandboxListUrls_0(ctx context.Context, marshaler r return msg, metadata, err } +var filter_PodService_SandboxListEvents_0 = &utilities.DoubleArray{Encoding: map[string]int{"stub_id": 0}, Base: []int{1, 1, 0}, Check: []int{0, 1, 2}} + +func request_PodService_SandboxListEvents_0(ctx context.Context, marshaler runtime.Marshaler, client PodServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var ( + protoReq PodSandboxListEventsRequest + metadata runtime.ServerMetadata + err error + ) + if req.Body != nil { + _, _ = io.Copy(io.Discard, req.Body) + } + val, ok := pathParams["stub_id"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "stub_id") + } + protoReq.StubId, err = runtime.String(val) + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "stub_id", err) + } + if err := req.ParseForm(); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_PodService_SandboxListEvents_0); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + msg, err := client.SandboxListEvents(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err +} + +func local_request_PodService_SandboxListEvents_0(ctx context.Context, marshaler runtime.Marshaler, server PodServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var ( + protoReq PodSandboxListEventsRequest + metadata runtime.ServerMetadata + err error + ) + val, ok := pathParams["stub_id"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "stub_id") + } + protoReq.StubId, err = runtime.String(val) + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "stub_id", err) + } + if err := req.ParseForm(); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_PodService_SandboxListEvents_0); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + msg, err := server.SandboxListEvents(ctx, &protoReq) + return msg, metadata, err +} + // RegisterPodServiceHandlerServer registers the http handlers for service PodService to "mux". // UnaryRPC :call PodServiceServer directly. // StreamingRPC :currently unsupported pending https://github.com/grpc/grpc-go/issues/906. @@ -1576,6 +1629,26 @@ func RegisterPodServiceHandlerServer(ctx context.Context, mux *runtime.ServeMux, } forward_PodService_SandboxListUrls_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) }) + mux.Handle(http.MethodGet, pattern_PodService_SandboxListEvents_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + var stream runtime.ServerTransportStream + ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + annotatedContext, err := runtime.AnnotateIncomingContext(ctx, mux, req, "/pod.PodService/SandboxListEvents", runtime.WithHTTPPathPattern("/pods/{stub_id}/events")) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := local_request_PodService_SandboxListEvents_0(annotatedContext, inboundMarshaler, server, req, pathParams) + md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) + if err != nil { + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) + return + } + forward_PodService_SandboxListEvents_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + }) return nil } @@ -2007,6 +2080,23 @@ func RegisterPodServiceHandlerClient(ctx context.Context, mux *runtime.ServeMux, } forward_PodService_SandboxListUrls_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) }) + mux.Handle(http.MethodGet, pattern_PodService_SandboxListEvents_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + annotatedContext, err := runtime.AnnotateContext(ctx, mux, req, "/pod.PodService/SandboxListEvents", runtime.WithHTTPPathPattern("/pods/{stub_id}/events")) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_PodService_SandboxListEvents_0(annotatedContext, inboundMarshaler, client, req, pathParams) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) + if err != nil { + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) + return + } + forward_PodService_SandboxListEvents_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + }) return nil } @@ -2034,6 +2124,7 @@ var ( pattern_PodService_SandboxCreateImageFromFilesystem_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 1, 0, 4, 1, 5, 1, 2, 2}, []string{"pods", "container_id", "create-image-from-filesystem"}, "")) pattern_PodService_SandboxSnapshotMemory_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 1, 0, 4, 1, 5, 1, 2, 2}, []string{"pods", "container_id", "snapshot-memory"}, "")) pattern_PodService_SandboxListUrls_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 1, 0, 4, 1, 5, 1, 2, 2}, []string{"pods", "container_id", "urls"}, "")) + pattern_PodService_SandboxListEvents_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 1, 0, 4, 1, 5, 1, 2, 2}, []string{"pods", "stub_id", "events"}, "")) ) var ( @@ -2060,4 +2151,5 @@ var ( forward_PodService_SandboxCreateImageFromFilesystem_0 = runtime.ForwardResponseMessage forward_PodService_SandboxSnapshotMemory_0 = runtime.ForwardResponseMessage forward_PodService_SandboxListUrls_0 = runtime.ForwardResponseMessage + forward_PodService_SandboxListEvents_0 = runtime.ForwardResponseMessage ) diff --git a/proto/pod_grpc.pb.go b/proto/pod_grpc.pb.go index c44ee2ace..dcdf012da 100644 --- a/proto/pod_grpc.pb.go +++ b/proto/pod_grpc.pb.go @@ -42,6 +42,7 @@ const ( PodService_SandboxCreateImageFromFilesystem_FullMethodName = "/pod.PodService/SandboxCreateImageFromFilesystem" PodService_SandboxSnapshotMemory_FullMethodName = "/pod.PodService/SandboxSnapshotMemory" PodService_SandboxListUrls_FullMethodName = "/pod.PodService/SandboxListUrls" + PodService_SandboxListEvents_FullMethodName = "/pod.PodService/SandboxListEvents" ) // PodServiceClient is the client API for PodService service. @@ -71,6 +72,7 @@ type PodServiceClient interface { SandboxCreateImageFromFilesystem(ctx context.Context, in *PodSandboxCreateImageFromFilesystemRequest, opts ...grpc.CallOption) (*PodSandboxCreateImageFromFilesystemResponse, error) SandboxSnapshotMemory(ctx context.Context, in *PodSandboxSnapshotMemoryRequest, opts ...grpc.CallOption) (*PodSandboxSnapshotMemoryResponse, error) SandboxListUrls(ctx context.Context, in *PodSandboxListUrlsRequest, opts ...grpc.CallOption) (*PodSandboxListUrlsResponse, error) + SandboxListEvents(ctx context.Context, in *PodSandboxListEventsRequest, opts ...grpc.CallOption) (*PodSandboxListEventsResponse, error) } type podServiceClient struct { @@ -288,6 +290,15 @@ func (c *podServiceClient) SandboxListUrls(ctx context.Context, in *PodSandboxLi return out, nil } +func (c *podServiceClient) SandboxListEvents(ctx context.Context, in *PodSandboxListEventsRequest, opts ...grpc.CallOption) (*PodSandboxListEventsResponse, error) { + out := new(PodSandboxListEventsResponse) + err := c.cc.Invoke(ctx, PodService_SandboxListEvents_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + // PodServiceServer is the server API for PodService service. // All implementations must embed UnimplementedPodServiceServer // for forward compatibility @@ -315,6 +326,7 @@ type PodServiceServer interface { SandboxCreateImageFromFilesystem(context.Context, *PodSandboxCreateImageFromFilesystemRequest) (*PodSandboxCreateImageFromFilesystemResponse, error) SandboxSnapshotMemory(context.Context, *PodSandboxSnapshotMemoryRequest) (*PodSandboxSnapshotMemoryResponse, error) SandboxListUrls(context.Context, *PodSandboxListUrlsRequest) (*PodSandboxListUrlsResponse, error) + SandboxListEvents(context.Context, *PodSandboxListEventsRequest) (*PodSandboxListEventsResponse, error) mustEmbedUnimplementedPodServiceServer() } @@ -391,6 +403,9 @@ func (UnimplementedPodServiceServer) SandboxSnapshotMemory(context.Context, *Pod func (UnimplementedPodServiceServer) SandboxListUrls(context.Context, *PodSandboxListUrlsRequest) (*PodSandboxListUrlsResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method SandboxListUrls not implemented") } +func (UnimplementedPodServiceServer) SandboxListEvents(context.Context, *PodSandboxListEventsRequest) (*PodSandboxListEventsResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method SandboxListEvents not implemented") +} func (UnimplementedPodServiceServer) mustEmbedUnimplementedPodServiceServer() {} // UnsafePodServiceServer may be embedded to opt out of forward compatibility for this service. @@ -818,6 +833,24 @@ func _PodService_SandboxListUrls_Handler(srv interface{}, ctx context.Context, d return interceptor(ctx, in, info, handler) } +func _PodService_SandboxListEvents_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(PodSandboxListEventsRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(PodServiceServer).SandboxListEvents(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: PodService_SandboxListEvents_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(PodServiceServer).SandboxListEvents(ctx, req.(*PodSandboxListEventsRequest)) + } + return interceptor(ctx, in, info, handler) +} + // PodService_ServiceDesc is the grpc.ServiceDesc for PodService service. // It's only intended for direct use with grpc.RegisterService, // and not to be introspected or modified (even as a copy) @@ -917,6 +950,10 @@ var PodService_ServiceDesc = grpc.ServiceDesc{ MethodName: "SandboxListUrls", Handler: _PodService_SandboxListUrls_Handler, }, + { + MethodName: "SandboxListEvents", + Handler: _PodService_SandboxListEvents_Handler, + }, }, Streams: []grpc.StreamDesc{}, Metadata: "pod.proto", diff --git a/sdk/src/beta9/abstractions/sandbox.py b/sdk/src/beta9/abstractions/sandbox.py index 17002186e..5880382cc 100644 --- a/sdk/src/beta9/abstractions/sandbox.py +++ b/sdk/src/beta9/abstractions/sandbox.py @@ -32,6 +32,8 @@ PodSandboxExposePortResponse, PodSandboxFindInFilesRequest, PodSandboxKillRequest, + PodSandboxListEventsRequest, + PodSandboxListEventsResponse, PodSandboxListFilesRequest, PodSandboxListProcessesRequest, PodSandboxListProcessesResponse, @@ -654,6 +656,59 @@ def list_urls(self) -> Dict[int, str]: return res.urls + def list_events( + self, cursor: Optional[List[str]] = None + ) -> Tuple[List["SandboxEvent"], Optional[List[str]]]: + """ + List container lifecycle events for this sandbox. + + Returns events in reverse chronological order (newest first), with pagination support. + + Parameters: + cursor (Optional[List[str]]): Pagination cursor from a previous call. + + Returns: + Tuple[List[SandboxEvent], Optional[List[str]]]: A tuple of (events, next_cursor). + next_cursor is None if there are no more results. + + Raises: + SandboxConnectionError: If listing events fails. + + Example: + ```python + events, cursor = instance.list_events() + for e in events: + print(f"{e.time}: {e.status} ({e.container_id})") + + # Paginate + if cursor: + more_events, next_cursor = instance.list_events(cursor=cursor) + ``` + """ + res: "PodSandboxListEventsResponse" = self.stub.sandbox_list_events( + PodSandboxListEventsRequest( + stub_id=self.stub_id, + search_after=cursor or [], + ) + ) + if not res.ok: + raise SandboxConnectionError(res.error_msg) + + events = [ + SandboxEvent( + id=e.id, + time=e.time, + status=e.status, + container_id=e.container_id, + worker_id=e.worker_id, + stub_id=e.stub_id, + exit_code=e.exit_code, + ) + for e in res.events + ] + next_cursor = list(res.next_cursor) if res.next_cursor else None + return events, next_cursor + @property def aio(self) -> "AsyncSandboxInstance": """ @@ -1428,6 +1483,30 @@ def __setstate__(self, state): self.__dict__.update(state) +@dataclass +class SandboxEvent: + """ + A container lifecycle event from the sandbox. + + Attributes: + id (str): The unique event ID. + time (str): The timestamp of the event. + status (str): The event status (e.g. requested, scheduled, started, stopped, oom, failed). + container_id (str): The container ID associated with the event. + worker_id (str): The worker ID that handled the event. + stub_id (str): The stub ID associated with the event. + exit_code (int): The exit code of the container, if applicable. + """ + + id: str + time: str + status: str + container_id: str + worker_id: str + stub_id: str + exit_code: int + + @dataclass class SandboxFileInfo: """ @@ -3934,4 +4013,21 @@ async def list_urls(self) -> Dict[int, str]: Raises: SandboxConnectionError: If listing URLs fails. """ - return await asyncio.to_thread(self._sync.list_urls) \ No newline at end of file + return await asyncio.to_thread(self._sync.list_urls) + + async def list_events( + self, cursor: Optional[List[str]] = None + ) -> Tuple[List["SandboxEvent"], Optional[List[str]]]: + """ + List container lifecycle events for this sandbox asynchronously. + + Parameters: + cursor (Optional[List[str]]): Pagination cursor from a previous call. + + Returns: + Tuple[List[SandboxEvent], Optional[List[str]]]: A tuple of (events, next_cursor). + + Raises: + SandboxConnectionError: If listing events fails. + """ + return await asyncio.to_thread(self._sync.list_events, cursor) \ No newline at end of file diff --git a/sdk/src/beta9/clients/pod/__init__.py b/sdk/src/beta9/clients/pod/__init__.py index 8740aa660..73825cf64 100644 --- a/sdk/src/beta9/clients/pod/__init__.py +++ b/sdk/src/beta9/clients/pod/__init__.py @@ -343,6 +343,32 @@ class PodSandboxListUrlsResponse(betterproto.Message): error_msg: str = betterproto.string_field(3) +@dataclass(eq=False, repr=False) +class PodSandboxListEventsRequest(betterproto.Message): + stub_id: str = betterproto.string_field(1) + search_after: List[str] = betterproto.string_field(2) + + +@dataclass(eq=False, repr=False) +class PodSandboxListEventsResponse(betterproto.Message): + ok: bool = betterproto.bool_field(1) + error_msg: str = betterproto.string_field(2) + events: List["PodSandboxEvent"] = betterproto.message_field(3) + next_cursor: List[str] = betterproto.string_field(4) + + +@dataclass(eq=False, repr=False) +class PodSandboxEvent(betterproto.Message): + id: str = betterproto.string_field(1) + time: str = betterproto.string_field(2) + type: str = betterproto.string_field(3) + status: str = betterproto.string_field(4) + container_id: str = betterproto.string_field(5) + worker_id: str = betterproto.string_field(6) + stub_id: str = betterproto.string_field(7) + exit_code: int = betterproto.int32_field(8) + + class PodServiceStub(SyncServiceStub): def create_pod(self, create_pod_request: "CreatePodRequest") -> "CreatePodResponse": return self._unary_unary( @@ -550,3 +576,12 @@ def sandbox_list_urls( PodSandboxListUrlsRequest, PodSandboxListUrlsResponse, )(pod_sandbox_list_urls_request) + + def sandbox_list_events( + self, pod_sandbox_list_events_request: "PodSandboxListEventsRequest" + ) -> "PodSandboxListEventsResponse": + return self._unary_unary( + "/pod.PodService/SandboxListEvents", + PodSandboxListEventsRequest, + PodSandboxListEventsResponse, + )(pod_sandbox_list_events_request)