diff --git a/.ko.yaml b/.ko.yaml index 80d54c7973..6465081548 100644 --- a/.ko.yaml +++ b/.ko.yaml @@ -19,6 +19,15 @@ defaultPlatforms: - linux/arm64 baseImageOverrides: + # The actor images built here write at the root of their filesystem and into + # volumes atelet creates as root. A container runs as its image's USER, so + # they stay on the root base. + go.ate.dev/substrate/demos/counter: gcr.io/distroless/static-debian13:latest@sha256:15f8637509792e05b97d83451b0b6ccfa4abd548f997e406ac1e72c87fe1fa78 + go.ate.dev/substrate/demos/egress: gcr.io/distroless/static-debian13:latest@sha256:15f8637509792e05b97d83451b0b6ccfa4abd548f997e406ac1e72c87fe1fa78 + go.ate.dev/substrate/demos/multi-template/fspersist: gcr.io/distroless/static-debian13:latest@sha256:15f8637509792e05b97d83451b0b6ccfa4abd548f997e406ac1e72c87fe1fa78 + go.ate.dev/substrate/internal/e2e/fixtures/probe: gcr.io/distroless/static-debian13:latest@sha256:15f8637509792e05b97d83451b0b6ccfa4abd548f997e406ac1e72c87fe1fa78 + go.ate.dev/substrate/internal/e2e/fixtures/testserver: gcr.io/distroless/static-debian13:latest@sha256:15f8637509792e05b97d83451b0b6ccfa4abd548f997e406ac1e72c87fe1fa78 + go.ate.dev/substrate/cmd/benchmarking/glutton: gcr.io/distroless/static-debian13:latest@sha256:15f8637509792e05b97d83451b0b6ccfa4abd548f997e406ac1e72c87fe1fa78 go.ate.dev/substrate/demos/sandbox: alpine:3.24.3@sha256:be2656061b536c1883c4034790e21d0a09c5aaaf51968b89368a3c0371ea2c9a # atelet needs glibc to run the node's kubelet credential provider, which # some platforms ship dynamically linked (e.g. AKS, GKE Ubuntu). diff --git a/api/ateapi/v1/ateapi.pb.go b/api/ateapi/v1/ateapi.pb.go index 44de8a372c..aadebff8c9 100644 --- a/api/ateapi/v1/ateapi.pb.go +++ b/api/ateapi/v1/ateapi.pb.go @@ -5943,131 +5943,6 @@ func (x *MintActorJwtResponse) GetExpireTime() *timestamppb.Timestamp { return nil } -// Request message for MintActorCertificate. -type MintActorCertificateRequest struct { - state protoimpl.MessageState `protogen:"open.v1"` - // The actor for which the certificate should be issued. - // - // Must be a valid actor that currently exists according to the actor store. - // - // +k8s:required - Actor *ObjectRef `protobuf:"bytes,1,opt,name=actor,proto3" json:"actor,omitempty"` - // The UID of the actor --- used to guard against deletion and recreation of - // an actor with the same name. - // - // +k8s:required - // +k8s:format=k8s-uuid - ActorUid string `protobuf:"bytes,2,opt,name=actor_uid,json=actorUid,proto3" json:"actor_uid,omitempty"` - // Request contains DER encoded bytes of a x509 certificate signing request. - // The signer will ignore the contents of the CSR except to extract the - // subject public key. - // - // +k8s:required - // +k8s:maxBytes=16384 - CertificateSigningRequest []byte `protobuf:"bytes,3,opt,name=certificate_signing_request,json=certificateSigningRequest,proto3" json:"certificate_signing_request,omitempty"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache -} - -func (x *MintActorCertificateRequest) Reset() { - *x = MintActorCertificateRequest{} - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[78] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) -} - -func (x *MintActorCertificateRequest) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*MintActorCertificateRequest) ProtoMessage() {} - -func (x *MintActorCertificateRequest) ProtoReflect() protoreflect.Message { - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[78] - if x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use MintActorCertificateRequest.ProtoReflect.Descriptor instead. -func (*MintActorCertificateRequest) Descriptor() ([]byte, []int) { - return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{78} -} - -func (x *MintActorCertificateRequest) GetActor() *ObjectRef { - if x != nil { - return x.Actor - } - return nil -} - -func (x *MintActorCertificateRequest) GetActorUid() string { - if x != nil { - return x.ActorUid - } - return "" -} - -func (x *MintActorCertificateRequest) GetCertificateSigningRequest() []byte { - if x != nil { - return x.CertificateSigningRequest - } - return nil -} - -// Response message for MintActorCertificate. -type MintActorCertificateResponse struct { - state protoimpl.MessageState `protogen:"open.v1"` - // Response contains a list of DER encoded certificates. The first entry is the - // leaf certificate, and any remaining entries are intermediates in - // leaf-to-root order. - ActorCertificates [][]byte `protobuf:"bytes,1,rep,name=actor_certificates,json=actorCertificates,proto3" json:"actor_certificates,omitempty"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache -} - -func (x *MintActorCertificateResponse) Reset() { - *x = MintActorCertificateResponse{} - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[79] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) -} - -func (x *MintActorCertificateResponse) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*MintActorCertificateResponse) ProtoMessage() {} - -func (x *MintActorCertificateResponse) ProtoReflect() protoreflect.Message { - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[79] - if x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use MintActorCertificateResponse.ProtoReflect.Descriptor instead. -func (*MintActorCertificateResponse) Descriptor() ([]byte, []int) { - return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{79} -} - -func (x *MintActorCertificateResponse) GetActorCertificates() [][]byte { - if x != nil { - return x.ActorCertificates - } - return nil -} - type ListTagsRequest struct { state protoimpl.MessageState `protogen:"open.v1"` // The atespace to list tags from. Empty lists across all atespaces. @@ -6085,7 +5960,7 @@ type ListTagsRequest struct { func (x *ListTagsRequest) Reset() { *x = ListTagsRequest{} - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[80] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[78] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6097,7 +5972,7 @@ func (x *ListTagsRequest) String() string { func (*ListTagsRequest) ProtoMessage() {} func (x *ListTagsRequest) ProtoReflect() protoreflect.Message { - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[80] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[78] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6110,7 +5985,7 @@ func (x *ListTagsRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use ListTagsRequest.ProtoReflect.Descriptor instead. func (*ListTagsRequest) Descriptor() ([]byte, []int) { - return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{80} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{78} } func (x *ListTagsRequest) GetAtespace() string { @@ -6137,7 +6012,7 @@ type ListTagsResponse struct { func (x *ListTagsResponse) Reset() { *x = ListTagsResponse{} - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[81] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[79] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6149,7 +6024,7 @@ func (x *ListTagsResponse) String() string { func (*ListTagsResponse) ProtoMessage() {} func (x *ListTagsResponse) ProtoReflect() protoreflect.Message { - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[81] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[79] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6162,7 +6037,7 @@ func (x *ListTagsResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use ListTagsResponse.ProtoReflect.Descriptor instead. func (*ListTagsResponse) Descriptor() ([]byte, []int) { - return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{81} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{79} } func (x *ListTagsResponse) GetTags() []*Tag { @@ -6207,7 +6082,7 @@ type CreateTagRequest struct { func (x *CreateTagRequest) Reset() { *x = CreateTagRequest{} - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[82] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[80] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6219,7 +6094,7 @@ func (x *CreateTagRequest) String() string { func (*CreateTagRequest) ProtoMessage() {} func (x *CreateTagRequest) ProtoReflect() protoreflect.Message { - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[82] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[80] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6232,7 +6107,7 @@ func (x *CreateTagRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use CreateTagRequest.ProtoReflect.Descriptor instead. func (*CreateTagRequest) Descriptor() ([]byte, []int) { - return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{82} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{80} } func (x *CreateTagRequest) GetTag() *Tag { @@ -6262,7 +6137,7 @@ type UpdateTagRequest struct { func (x *UpdateTagRequest) Reset() { *x = UpdateTagRequest{} - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[83] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[81] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6274,7 +6149,7 @@ func (x *UpdateTagRequest) String() string { func (*UpdateTagRequest) ProtoMessage() {} func (x *UpdateTagRequest) ProtoReflect() protoreflect.Message { - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[83] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[81] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6287,7 +6162,7 @@ func (x *UpdateTagRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use UpdateTagRequest.ProtoReflect.Descriptor instead. func (*UpdateTagRequest) Descriptor() ([]byte, []int) { - return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{83} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{81} } func (x *UpdateTagRequest) GetTag() *Tag { @@ -6312,7 +6187,7 @@ type DeleteTagRequest struct { func (x *DeleteTagRequest) Reset() { *x = DeleteTagRequest{} - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[84] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[82] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6324,7 +6199,7 @@ func (x *DeleteTagRequest) String() string { func (*DeleteTagRequest) ProtoMessage() {} func (x *DeleteTagRequest) ProtoReflect() protoreflect.Message { - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[84] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[82] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6337,7 +6212,7 @@ func (x *DeleteTagRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use DeleteTagRequest.ProtoReflect.Descriptor instead. func (*DeleteTagRequest) Descriptor() ([]byte, []int) { - return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{84} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{82} } func (x *DeleteTagRequest) GetTag() *ObjectRef { @@ -6376,7 +6251,7 @@ type DeleteOptions struct { func (x *DeleteOptions) Reset() { *x = DeleteOptions{} - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[85] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[83] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6388,7 +6263,7 @@ func (x *DeleteOptions) String() string { func (*DeleteOptions) ProtoMessage() {} func (x *DeleteOptions) ProtoReflect() protoreflect.Message { - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[85] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[83] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6401,7 +6276,7 @@ func (x *DeleteOptions) ProtoReflect() protoreflect.Message { // Deprecated: Use DeleteOptions.ProtoReflect.Descriptor instead. func (*DeleteOptions) Descriptor() ([]byte, []int) { - return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{85} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{83} } func (x *DeleteOptions) GetVersion() int64 { @@ -6440,7 +6315,7 @@ type ListOptions struct { func (x *ListOptions) Reset() { *x = ListOptions{} - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[86] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[84] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6452,7 +6327,7 @@ func (x *ListOptions) String() string { func (*ListOptions) ProtoMessage() {} func (x *ListOptions) ProtoReflect() protoreflect.Message { - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[86] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[84] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6465,7 +6340,7 @@ func (x *ListOptions) ProtoReflect() protoreflect.Message { // Deprecated: Use ListOptions.ProtoReflect.Descriptor instead. func (*ListOptions) Descriptor() ([]byte, []int) { - return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{86} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{84} } func (x *ListOptions) GetPageSize() int32 { @@ -6501,7 +6376,7 @@ type ListWorkerActorAssignmentsRequest struct { func (x *ListWorkerActorAssignmentsRequest) Reset() { *x = ListWorkerActorAssignmentsRequest{} - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[87] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[85] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6513,7 +6388,7 @@ func (x *ListWorkerActorAssignmentsRequest) String() string { func (*ListWorkerActorAssignmentsRequest) ProtoMessage() {} func (x *ListWorkerActorAssignmentsRequest) ProtoReflect() protoreflect.Message { - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[87] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[85] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6526,7 +6401,7 @@ func (x *ListWorkerActorAssignmentsRequest) ProtoReflect() protoreflect.Message // Deprecated: Use ListWorkerActorAssignmentsRequest.ProtoReflect.Descriptor instead. func (*ListWorkerActorAssignmentsRequest) Descriptor() ([]byte, []int) { - return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{87} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{85} } func (x *ListWorkerActorAssignmentsRequest) GetWorker() *ObjectRef { @@ -6556,7 +6431,7 @@ type ListWorkerActorAssignmentsResponse struct { func (x *ListWorkerActorAssignmentsResponse) Reset() { *x = ListWorkerActorAssignmentsResponse{} - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[88] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[86] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6568,7 +6443,7 @@ func (x *ListWorkerActorAssignmentsResponse) String() string { func (*ListWorkerActorAssignmentsResponse) ProtoMessage() {} func (x *ListWorkerActorAssignmentsResponse) ProtoReflect() protoreflect.Message { - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[88] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[86] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6581,7 +6456,7 @@ func (x *ListWorkerActorAssignmentsResponse) ProtoReflect() protoreflect.Message // Deprecated: Use ListWorkerActorAssignmentsResponse.ProtoReflect.Descriptor instead. func (*ListWorkerActorAssignmentsResponse) Descriptor() ([]byte, []int) { - return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{88} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{86} } func (x *ListWorkerActorAssignmentsResponse) GetActorAssignments() []*ActorAssignment { @@ -6610,7 +6485,7 @@ type ListWorkersRequest struct { func (x *ListWorkersRequest) Reset() { *x = ListWorkersRequest{} - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[89] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[87] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6622,7 +6497,7 @@ func (x *ListWorkersRequest) String() string { func (*ListWorkersRequest) ProtoMessage() {} func (x *ListWorkersRequest) ProtoReflect() protoreflect.Message { - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[89] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[87] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6635,7 +6510,7 @@ func (x *ListWorkersRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use ListWorkersRequest.ProtoReflect.Descriptor instead. func (*ListWorkersRequest) Descriptor() ([]byte, []int) { - return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{89} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{87} } func (x *ListWorkersRequest) GetOptions() *ListOptions { @@ -6657,7 +6532,7 @@ type ListWorkersResponse struct { func (x *ListWorkersResponse) Reset() { *x = ListWorkersResponse{} - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[90] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[88] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6669,7 +6544,7 @@ func (x *ListWorkersResponse) String() string { func (*ListWorkersResponse) ProtoMessage() {} func (x *ListWorkersResponse) ProtoReflect() protoreflect.Message { - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[90] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[88] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6682,7 +6557,7 @@ func (x *ListWorkersResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use ListWorkersResponse.ProtoReflect.Descriptor instead. func (*ListWorkersResponse) Descriptor() ([]byte, []int) { - return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{90} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{88} } func (x *ListWorkersResponse) GetWorkers() []*Worker { @@ -6712,7 +6587,7 @@ type GetWorkerRequest struct { func (x *GetWorkerRequest) Reset() { *x = GetWorkerRequest{} - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[91] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[89] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6724,7 +6599,7 @@ func (x *GetWorkerRequest) String() string { func (*GetWorkerRequest) ProtoMessage() {} func (x *GetWorkerRequest) ProtoReflect() protoreflect.Message { - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[91] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[89] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6737,7 +6612,7 @@ func (x *GetWorkerRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use GetWorkerRequest.ProtoReflect.Descriptor instead. func (*GetWorkerRequest) Descriptor() ([]byte, []int) { - return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{91} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{89} } func (x *GetWorkerRequest) GetWorker() *ObjectRef { @@ -6759,7 +6634,7 @@ type CreateWorkerRequest struct { func (x *CreateWorkerRequest) Reset() { *x = CreateWorkerRequest{} - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[92] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[90] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6771,7 +6646,7 @@ func (x *CreateWorkerRequest) String() string { func (*CreateWorkerRequest) ProtoMessage() {} func (x *CreateWorkerRequest) ProtoReflect() protoreflect.Message { - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[92] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[90] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6784,7 +6659,7 @@ func (x *CreateWorkerRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use CreateWorkerRequest.ProtoReflect.Descriptor instead. func (*CreateWorkerRequest) Descriptor() ([]byte, []int) { - return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{92} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{90} } func (x *CreateWorkerRequest) GetWorker() *Worker { @@ -6819,7 +6694,7 @@ type UpdateWorkerRequest struct { func (x *UpdateWorkerRequest) Reset() { *x = UpdateWorkerRequest{} - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[93] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[91] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6831,7 +6706,7 @@ func (x *UpdateWorkerRequest) String() string { func (*UpdateWorkerRequest) ProtoMessage() {} func (x *UpdateWorkerRequest) ProtoReflect() protoreflect.Message { - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[93] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[91] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6844,7 +6719,7 @@ func (x *UpdateWorkerRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use UpdateWorkerRequest.ProtoReflect.Descriptor instead. func (*UpdateWorkerRequest) Descriptor() ([]byte, []int) { - return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{93} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{91} } func (x *UpdateWorkerRequest) GetWorker() *Worker { @@ -6871,7 +6746,7 @@ type DeleteWorkerRequest struct { func (x *DeleteWorkerRequest) Reset() { *x = DeleteWorkerRequest{} - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[94] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[92] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6883,7 +6758,7 @@ func (x *DeleteWorkerRequest) String() string { func (*DeleteWorkerRequest) ProtoMessage() {} func (x *DeleteWorkerRequest) ProtoReflect() protoreflect.Message { - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[94] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[92] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6896,7 +6771,7 @@ func (x *DeleteWorkerRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use DeleteWorkerRequest.ProtoReflect.Descriptor instead. func (*DeleteWorkerRequest) Descriptor() ([]byte, []int) { - return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{94} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{92} } func (x *DeleteWorkerRequest) GetWorker() *ObjectRef { @@ -6926,7 +6801,7 @@ type DrainWorkerRequest struct { func (x *DrainWorkerRequest) Reset() { *x = DrainWorkerRequest{} - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[95] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[93] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6938,7 +6813,7 @@ func (x *DrainWorkerRequest) String() string { func (*DrainWorkerRequest) ProtoMessage() {} func (x *DrainWorkerRequest) ProtoReflect() protoreflect.Message { - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[95] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[93] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6951,7 +6826,7 @@ func (x *DrainWorkerRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use DrainWorkerRequest.ProtoReflect.Descriptor instead. func (*DrainWorkerRequest) Descriptor() ([]byte, []int) { - return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{95} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{93} } func (x *DrainWorkerRequest) GetWorker() *ObjectRef { @@ -6972,7 +6847,7 @@ type DrainWorkerResponse struct { func (x *DrainWorkerResponse) Reset() { *x = DrainWorkerResponse{} - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[96] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[94] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6984,7 +6859,7 @@ func (x *DrainWorkerResponse) String() string { func (*DrainWorkerResponse) ProtoMessage() {} func (x *DrainWorkerResponse) ProtoReflect() protoreflect.Message { - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[96] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[94] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6997,7 +6872,7 @@ func (x *DrainWorkerResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use DrainWorkerResponse.ProtoReflect.Descriptor instead. func (*DrainWorkerResponse) Descriptor() ([]byte, []int) { - return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{96} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{94} } func (x *DrainWorkerResponse) GetWorker() *Worker { @@ -7021,7 +6896,7 @@ type MarkWorkerAvailableRequest struct { func (x *MarkWorkerAvailableRequest) Reset() { *x = MarkWorkerAvailableRequest{} - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[97] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[95] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7033,7 +6908,7 @@ func (x *MarkWorkerAvailableRequest) String() string { func (*MarkWorkerAvailableRequest) ProtoMessage() {} func (x *MarkWorkerAvailableRequest) ProtoReflect() protoreflect.Message { - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[97] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[95] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7046,7 +6921,7 @@ func (x *MarkWorkerAvailableRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use MarkWorkerAvailableRequest.ProtoReflect.Descriptor instead. func (*MarkWorkerAvailableRequest) Descriptor() ([]byte, []int) { - return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{97} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{95} } func (x *MarkWorkerAvailableRequest) GetWorker() *ObjectRef { @@ -7067,7 +6942,7 @@ type MarkWorkerAvailableResponse struct { func (x *MarkWorkerAvailableResponse) Reset() { *x = MarkWorkerAvailableResponse{} - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[98] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[96] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7079,7 +6954,7 @@ func (x *MarkWorkerAvailableResponse) String() string { func (*MarkWorkerAvailableResponse) ProtoMessage() {} func (x *MarkWorkerAvailableResponse) ProtoReflect() protoreflect.Message { - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[98] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[96] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7092,7 +6967,7 @@ func (x *MarkWorkerAvailableResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use MarkWorkerAvailableResponse.ProtoReflect.Descriptor instead. func (*MarkWorkerAvailableResponse) Descriptor() ([]byte, []int) { - return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{98} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{96} } func (x *MarkWorkerAvailableResponse) GetWorker() *Worker { @@ -7116,7 +6991,7 @@ type MarkWorkerUnavailableRequest struct { func (x *MarkWorkerUnavailableRequest) Reset() { *x = MarkWorkerUnavailableRequest{} - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[99] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[97] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7128,7 +7003,7 @@ func (x *MarkWorkerUnavailableRequest) String() string { func (*MarkWorkerUnavailableRequest) ProtoMessage() {} func (x *MarkWorkerUnavailableRequest) ProtoReflect() protoreflect.Message { - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[99] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[97] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7141,7 +7016,7 @@ func (x *MarkWorkerUnavailableRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use MarkWorkerUnavailableRequest.ProtoReflect.Descriptor instead. func (*MarkWorkerUnavailableRequest) Descriptor() ([]byte, []int) { - return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{99} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{97} } func (x *MarkWorkerUnavailableRequest) GetWorker() *ObjectRef { @@ -7162,7 +7037,7 @@ type MarkWorkerUnavailableResponse struct { func (x *MarkWorkerUnavailableResponse) Reset() { *x = MarkWorkerUnavailableResponse{} - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[100] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[98] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7174,7 +7049,7 @@ func (x *MarkWorkerUnavailableResponse) String() string { func (*MarkWorkerUnavailableResponse) ProtoMessage() {} func (x *MarkWorkerUnavailableResponse) ProtoReflect() protoreflect.Message { - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[100] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[98] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7187,7 +7062,7 @@ func (x *MarkWorkerUnavailableResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use MarkWorkerUnavailableResponse.ProtoReflect.Descriptor instead. func (*MarkWorkerUnavailableResponse) Descriptor() ([]byte, []int) { - return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{100} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{98} } func (x *MarkWorkerUnavailableResponse) GetWorker() *Worker { @@ -7216,7 +7091,7 @@ type ListActorsRequest struct { func (x *ListActorsRequest) Reset() { *x = ListActorsRequest{} - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[101] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[99] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7228,7 +7103,7 @@ func (x *ListActorsRequest) String() string { func (*ListActorsRequest) ProtoMessage() {} func (x *ListActorsRequest) ProtoReflect() protoreflect.Message { - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[101] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[99] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7241,7 +7116,7 @@ func (x *ListActorsRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use ListActorsRequest.ProtoReflect.Descriptor instead. func (*ListActorsRequest) Descriptor() ([]byte, []int) { - return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{101} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{99} } func (x *ListActorsRequest) GetAtespace() string { @@ -7270,7 +7145,7 @@ type ListActorsResponse struct { func (x *ListActorsResponse) Reset() { *x = ListActorsResponse{} - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[102] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[100] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7282,7 +7157,7 @@ func (x *ListActorsResponse) String() string { func (*ListActorsResponse) ProtoMessage() {} func (x *ListActorsResponse) ProtoReflect() protoreflect.Message { - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[102] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[100] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7295,7 +7170,7 @@ func (x *ListActorsResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use ListActorsResponse.ProtoReflect.Descriptor instead. func (*ListActorsResponse) Descriptor() ([]byte, []int) { - return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{102} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{100} } func (x *ListActorsResponse) GetActors() []*Actor { @@ -7383,7 +7258,7 @@ type Worker struct { func (x *Worker) Reset() { *x = Worker{} - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[103] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[101] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7395,7 +7270,7 @@ func (x *Worker) String() string { func (*Worker) ProtoMessage() {} func (x *Worker) ProtoReflect() protoreflect.Message { - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[103] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[101] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7408,7 +7283,7 @@ func (x *Worker) ProtoReflect() protoreflect.Message { // Deprecated: Use Worker.ProtoReflect.Descriptor instead. func (*Worker) Descriptor() ([]byte, []int) { - return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{103} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{101} } func (x *Worker) GetMetadata() *ResourceMetadata { @@ -7550,7 +7425,7 @@ type WorkerStatus struct { func (x *WorkerStatus) Reset() { *x = WorkerStatus{} - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[104] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[102] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7562,7 +7437,7 @@ func (x *WorkerStatus) String() string { func (*WorkerStatus) ProtoMessage() {} func (x *WorkerStatus) ProtoReflect() protoreflect.Message { - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[104] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[102] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7575,7 +7450,7 @@ func (x *WorkerStatus) ProtoReflect() protoreflect.Message { // Deprecated: Use WorkerStatus.ProtoReflect.Descriptor instead. func (*WorkerStatus) Descriptor() ([]byte, []int) { - return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{104} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{102} } func (x *WorkerStatus) GetState() WorkerState { @@ -7663,7 +7538,7 @@ type WorkerSandboxClass struct { func (x *WorkerSandboxClass) Reset() { *x = WorkerSandboxClass{} - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[105] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[103] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7675,7 +7550,7 @@ func (x *WorkerSandboxClass) String() string { func (*WorkerSandboxClass) ProtoMessage() {} func (x *WorkerSandboxClass) ProtoReflect() protoreflect.Message { - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[105] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[103] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7688,7 +7563,7 @@ func (x *WorkerSandboxClass) ProtoReflect() protoreflect.Message { // Deprecated: Use WorkerSandboxClass.ProtoReflect.Descriptor instead. func (*WorkerSandboxClass) Descriptor() ([]byte, []int) { - return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{105} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{103} } func (x *WorkerSandboxClass) GetSandboxClass() string { @@ -7739,7 +7614,7 @@ type WorkerSandboxRuntime struct { func (x *WorkerSandboxRuntime) Reset() { *x = WorkerSandboxRuntime{} - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[106] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[104] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7751,7 +7626,7 @@ func (x *WorkerSandboxRuntime) String() string { func (*WorkerSandboxRuntime) ProtoMessage() {} func (x *WorkerSandboxRuntime) ProtoReflect() protoreflect.Message { - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[106] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[104] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7764,7 +7639,7 @@ func (x *WorkerSandboxRuntime) ProtoReflect() protoreflect.Message { // Deprecated: Use WorkerSandboxRuntime.ProtoReflect.Descriptor instead. func (*WorkerSandboxRuntime) Descriptor() ([]byte, []int) { - return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{106} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{104} } func (x *WorkerSandboxRuntime) GetVersion() *VersionedSandboxCompat { @@ -7805,7 +7680,7 @@ type RuntimeOverhead struct { func (x *RuntimeOverhead) Reset() { *x = RuntimeOverhead{} - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[107] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[105] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7817,7 +7692,7 @@ func (x *RuntimeOverhead) String() string { func (*RuntimeOverhead) ProtoMessage() {} func (x *RuntimeOverhead) ProtoReflect() protoreflect.Message { - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[107] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[105] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7830,7 +7705,7 @@ func (x *RuntimeOverhead) ProtoReflect() protoreflect.Message { // Deprecated: Use RuntimeOverhead.ProtoReflect.Descriptor instead. func (*RuntimeOverhead) Descriptor() ([]byte, []int) { - return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{107} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{105} } func (x *RuntimeOverhead) GetMemoryBytes() int64 { @@ -7869,7 +7744,7 @@ type ActorSandboxRuntime struct { func (x *ActorSandboxRuntime) Reset() { *x = ActorSandboxRuntime{} - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[108] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[106] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7881,7 +7756,7 @@ func (x *ActorSandboxRuntime) String() string { func (*ActorSandboxRuntime) ProtoMessage() {} func (x *ActorSandboxRuntime) ProtoReflect() protoreflect.Message { - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[108] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[106] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7894,7 +7769,7 @@ func (x *ActorSandboxRuntime) ProtoReflect() protoreflect.Message { // Deprecated: Use ActorSandboxRuntime.ProtoReflect.Descriptor instead. func (*ActorSandboxRuntime) Descriptor() ([]byte, []int) { - return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{108} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{106} } func (x *ActorSandboxRuntime) GetSandboxClass() string { @@ -7945,7 +7820,7 @@ type VersionedSandboxCompat struct { func (x *VersionedSandboxCompat) Reset() { *x = VersionedSandboxCompat{} - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[109] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[107] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7957,7 +7832,7 @@ func (x *VersionedSandboxCompat) String() string { func (*VersionedSandboxCompat) ProtoMessage() {} func (x *VersionedSandboxCompat) ProtoReflect() protoreflect.Message { - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[109] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[107] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7970,7 +7845,7 @@ func (x *VersionedSandboxCompat) ProtoReflect() protoreflect.Message { // Deprecated: Use VersionedSandboxCompat.ProtoReflect.Descriptor instead. func (*VersionedSandboxCompat) Descriptor() ([]byte, []int) { - return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{109} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{107} } func (x *VersionedSandboxCompat) GetSchemaVersion() string { @@ -8006,7 +7881,7 @@ type AttributeEntry struct { func (x *AttributeEntry) Reset() { *x = AttributeEntry{} - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[110] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[108] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -8018,7 +7893,7 @@ func (x *AttributeEntry) String() string { func (*AttributeEntry) ProtoMessage() {} func (x *AttributeEntry) ProtoReflect() protoreflect.Message { - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[110] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[108] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -8031,7 +7906,7 @@ func (x *AttributeEntry) ProtoReflect() protoreflect.Message { // Deprecated: Use AttributeEntry.ProtoReflect.Descriptor instead. func (*AttributeEntry) Descriptor() ([]byte, []int) { - return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{110} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{108} } func (x *AttributeEntry) GetKey() string { @@ -8078,7 +7953,7 @@ type WorkerResources struct { func (x *WorkerResources) Reset() { *x = WorkerResources{} - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[111] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[109] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -8090,7 +7965,7 @@ func (x *WorkerResources) String() string { func (*WorkerResources) ProtoMessage() {} func (x *WorkerResources) ProtoReflect() protoreflect.Message { - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[111] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[109] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -8103,7 +7978,7 @@ func (x *WorkerResources) ProtoReflect() protoreflect.Message { // Deprecated: Use WorkerResources.ProtoReflect.Descriptor instead. func (*WorkerResources) Descriptor() ([]byte, []int) { - return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{111} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{109} } func (x *WorkerResources) GetCpuMillicores() int64 { @@ -8159,7 +8034,7 @@ type ActorAssignment struct { func (x *ActorAssignment) Reset() { *x = ActorAssignment{} - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[112] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[110] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -8171,7 +8046,7 @@ func (x *ActorAssignment) String() string { func (*ActorAssignment) ProtoMessage() {} func (x *ActorAssignment) ProtoReflect() protoreflect.Message { - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[112] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[110] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -8184,7 +8059,7 @@ func (x *ActorAssignment) ProtoReflect() protoreflect.Message { // Deprecated: Use ActorAssignment.ProtoReflect.Descriptor instead. func (*ActorAssignment) Descriptor() ([]byte, []int) { - return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{112} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{110} } func (x *ActorAssignment) GetMetadata() *ResourceMetadata { @@ -8229,7 +8104,7 @@ type AcquireWorkerEpochRequest struct { func (x *AcquireWorkerEpochRequest) Reset() { *x = AcquireWorkerEpochRequest{} - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[113] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[111] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -8241,7 +8116,7 @@ func (x *AcquireWorkerEpochRequest) String() string { func (*AcquireWorkerEpochRequest) ProtoMessage() {} func (x *AcquireWorkerEpochRequest) ProtoReflect() protoreflect.Message { - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[113] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[111] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -8254,7 +8129,7 @@ func (x *AcquireWorkerEpochRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use AcquireWorkerEpochRequest.ProtoReflect.Descriptor instead. func (*AcquireWorkerEpochRequest) Descriptor() ([]byte, []int) { - return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{113} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{111} } func (x *AcquireWorkerEpochRequest) GetWorker() *ObjectRef { @@ -8274,7 +8149,7 @@ type AcquireWorkerEpochResponse struct { func (x *AcquireWorkerEpochResponse) Reset() { *x = AcquireWorkerEpochResponse{} - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[114] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[112] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -8286,7 +8161,7 @@ func (x *AcquireWorkerEpochResponse) String() string { func (*AcquireWorkerEpochResponse) ProtoMessage() {} func (x *AcquireWorkerEpochResponse) ProtoReflect() protoreflect.Message { - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[114] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[112] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -8299,7 +8174,7 @@ func (x *AcquireWorkerEpochResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use AcquireWorkerEpochResponse.ProtoReflect.Descriptor instead. func (*AcquireWorkerEpochResponse) Descriptor() ([]byte, []int) { - return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{114} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{112} } func (x *AcquireWorkerEpochResponse) GetEpoch() int64 { @@ -8342,7 +8217,7 @@ type RegisterWorkerRequest struct { func (x *RegisterWorkerRequest) Reset() { *x = RegisterWorkerRequest{} - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[115] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[113] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -8354,7 +8229,7 @@ func (x *RegisterWorkerRequest) String() string { func (*RegisterWorkerRequest) ProtoMessage() {} func (x *RegisterWorkerRequest) ProtoReflect() protoreflect.Message { - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[115] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[113] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -8367,7 +8242,7 @@ func (x *RegisterWorkerRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use RegisterWorkerRequest.ProtoReflect.Descriptor instead. func (*RegisterWorkerRequest) Descriptor() ([]byte, []int) { - return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{115} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{113} } func (x *RegisterWorkerRequest) GetWorker() *ObjectRef { @@ -8408,7 +8283,7 @@ type RegisterWorkerResponse struct { func (x *RegisterWorkerResponse) Reset() { *x = RegisterWorkerResponse{} - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[116] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[114] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -8420,7 +8295,7 @@ func (x *RegisterWorkerResponse) String() string { func (*RegisterWorkerResponse) ProtoMessage() {} func (x *RegisterWorkerResponse) ProtoReflect() protoreflect.Message { - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[116] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[114] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -8433,7 +8308,7 @@ func (x *RegisterWorkerResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use RegisterWorkerResponse.ProtoReflect.Descriptor instead. func (*RegisterWorkerResponse) Descriptor() ([]byte, []int) { - return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{116} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{114} } func (x *RegisterWorkerResponse) GetWorker() *Worker { @@ -8473,7 +8348,7 @@ type SetWorkerSandboxRuntimesRequest struct { func (x *SetWorkerSandboxRuntimesRequest) Reset() { *x = SetWorkerSandboxRuntimesRequest{} - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[117] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[115] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -8485,7 +8360,7 @@ func (x *SetWorkerSandboxRuntimesRequest) String() string { func (*SetWorkerSandboxRuntimesRequest) ProtoMessage() {} func (x *SetWorkerSandboxRuntimesRequest) ProtoReflect() protoreflect.Message { - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[117] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[115] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -8498,7 +8373,7 @@ func (x *SetWorkerSandboxRuntimesRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use SetWorkerSandboxRuntimesRequest.ProtoReflect.Descriptor instead. func (*SetWorkerSandboxRuntimesRequest) Descriptor() ([]byte, []int) { - return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{117} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{115} } func (x *SetWorkerSandboxRuntimesRequest) GetWorker() *ObjectRef { @@ -8532,7 +8407,7 @@ type SetWorkerSandboxRuntimesResponse struct { func (x *SetWorkerSandboxRuntimesResponse) Reset() { *x = SetWorkerSandboxRuntimesResponse{} - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[118] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[116] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -8544,7 +8419,7 @@ func (x *SetWorkerSandboxRuntimesResponse) String() string { func (*SetWorkerSandboxRuntimesResponse) ProtoMessage() {} func (x *SetWorkerSandboxRuntimesResponse) ProtoReflect() protoreflect.Message { - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[118] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[116] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -8557,7 +8432,7 @@ func (x *SetWorkerSandboxRuntimesResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use SetWorkerSandboxRuntimesResponse.ProtoReflect.Descriptor instead. func (*SetWorkerSandboxRuntimesResponse) Descriptor() ([]byte, []int) { - return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{118} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{116} } func (x *SetWorkerSandboxRuntimesResponse) GetWorker() *Worker { @@ -8604,7 +8479,7 @@ type MintWorkerActorCertificateRequest struct { func (x *MintWorkerActorCertificateRequest) Reset() { *x = MintWorkerActorCertificateRequest{} - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[119] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[117] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -8616,7 +8491,7 @@ func (x *MintWorkerActorCertificateRequest) String() string { func (*MintWorkerActorCertificateRequest) ProtoMessage() {} func (x *MintWorkerActorCertificateRequest) ProtoReflect() protoreflect.Message { - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[119] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[117] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -8629,7 +8504,7 @@ func (x *MintWorkerActorCertificateRequest) ProtoReflect() protoreflect.Message // Deprecated: Use MintWorkerActorCertificateRequest.ProtoReflect.Descriptor instead. func (*MintWorkerActorCertificateRequest) Descriptor() ([]byte, []int) { - return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{119} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{117} } func (x *MintWorkerActorCertificateRequest) GetActor() *ObjectRef { @@ -8673,7 +8548,7 @@ type MintWorkerActorCertificateResponse struct { func (x *MintWorkerActorCertificateResponse) Reset() { *x = MintWorkerActorCertificateResponse{} - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[120] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[118] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -8685,7 +8560,7 @@ func (x *MintWorkerActorCertificateResponse) String() string { func (*MintWorkerActorCertificateResponse) ProtoMessage() {} func (x *MintWorkerActorCertificateResponse) ProtoReflect() protoreflect.Message { - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[120] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[118] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -8698,7 +8573,7 @@ func (x *MintWorkerActorCertificateResponse) ProtoReflect() protoreflect.Message // Deprecated: Use MintWorkerActorCertificateResponse.ProtoReflect.Descriptor instead. func (*MintWorkerActorCertificateResponse) Descriptor() ([]byte, []int) { - return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{120} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{118} } func (x *MintWorkerActorCertificateResponse) GetActorCertificates() [][]byte { @@ -8739,7 +8614,7 @@ type MintWorkerActorJwtRequest struct { func (x *MintWorkerActorJwtRequest) Reset() { *x = MintWorkerActorJwtRequest{} - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[121] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[119] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -8751,7 +8626,7 @@ func (x *MintWorkerActorJwtRequest) String() string { func (*MintWorkerActorJwtRequest) ProtoMessage() {} func (x *MintWorkerActorJwtRequest) ProtoReflect() protoreflect.Message { - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[121] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[119] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -8764,7 +8639,7 @@ func (x *MintWorkerActorJwtRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use MintWorkerActorJwtRequest.ProtoReflect.Descriptor instead. func (*MintWorkerActorJwtRequest) Descriptor() ([]byte, []int) { - return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{121} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{119} } func (x *MintWorkerActorJwtRequest) GetActor() *ObjectRef { @@ -8812,7 +8687,7 @@ type MintWorkerActorJwtResponse struct { func (x *MintWorkerActorJwtResponse) Reset() { *x = MintWorkerActorJwtResponse{} - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[122] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[120] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -8824,7 +8699,7 @@ func (x *MintWorkerActorJwtResponse) String() string { func (*MintWorkerActorJwtResponse) ProtoMessage() {} func (x *MintWorkerActorJwtResponse) ProtoReflect() protoreflect.Message { - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[122] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[120] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -8837,7 +8712,7 @@ func (x *MintWorkerActorJwtResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use MintWorkerActorJwtResponse.ProtoReflect.Descriptor instead. func (*MintWorkerActorJwtResponse) Descriptor() ([]byte, []int) { - return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{122} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{120} } func (x *MintWorkerActorJwtResponse) GetActorJwt() string { @@ -8885,7 +8760,7 @@ type RequestActorSuspendRequest struct { func (x *RequestActorSuspendRequest) Reset() { *x = RequestActorSuspendRequest{} - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[123] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[121] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -8897,7 +8772,7 @@ func (x *RequestActorSuspendRequest) String() string { func (*RequestActorSuspendRequest) ProtoMessage() {} func (x *RequestActorSuspendRequest) ProtoReflect() protoreflect.Message { - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[123] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[121] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -8910,7 +8785,7 @@ func (x *RequestActorSuspendRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use RequestActorSuspendRequest.ProtoReflect.Descriptor instead. func (*RequestActorSuspendRequest) Descriptor() ([]byte, []int) { - return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{123} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{121} } func (x *RequestActorSuspendRequest) GetWorker() *ObjectRef { @@ -8944,7 +8819,7 @@ type RequestActorSuspendResponse struct { func (x *RequestActorSuspendResponse) Reset() { *x = RequestActorSuspendResponse{} - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[124] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[122] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -8956,7 +8831,7 @@ func (x *RequestActorSuspendResponse) String() string { func (*RequestActorSuspendResponse) ProtoMessage() {} func (x *RequestActorSuspendResponse) ProtoReflect() protoreflect.Message { - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[124] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[122] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -8969,7 +8844,7 @@ func (x *RequestActorSuspendResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use RequestActorSuspendResponse.ProtoReflect.Descriptor instead. func (*RequestActorSuspendResponse) Descriptor() ([]byte, []int) { - return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{124} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{122} } func (x *RequestActorSuspendResponse) GetActor() *Actor { @@ -9009,7 +8884,7 @@ type ReportActorCrashedRequest struct { func (x *ReportActorCrashedRequest) Reset() { *x = ReportActorCrashedRequest{} - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[125] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[123] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -9021,7 +8896,7 @@ func (x *ReportActorCrashedRequest) String() string { func (*ReportActorCrashedRequest) ProtoMessage() {} func (x *ReportActorCrashedRequest) ProtoReflect() protoreflect.Message { - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[125] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[123] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -9034,7 +8909,7 @@ func (x *ReportActorCrashedRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use ReportActorCrashedRequest.ProtoReflect.Descriptor instead. func (*ReportActorCrashedRequest) Descriptor() ([]byte, []int) { - return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{125} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{123} } func (x *ReportActorCrashedRequest) GetWorker() *ObjectRef { @@ -9075,7 +8950,7 @@ type ReportActorCrashedResponse struct { func (x *ReportActorCrashedResponse) Reset() { *x = ReportActorCrashedResponse{} - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[126] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[124] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -9087,7 +8962,7 @@ func (x *ReportActorCrashedResponse) String() string { func (*ReportActorCrashedResponse) ProtoMessage() {} func (x *ReportActorCrashedResponse) ProtoReflect() protoreflect.Message { - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[126] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[124] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -9100,7 +8975,7 @@ func (x *ReportActorCrashedResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use ReportActorCrashedResponse.ProtoReflect.Descriptor instead. func (*ReportActorCrashedResponse) Descriptor() ([]byte, []int) { - return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{126} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{124} } func (x *ReportActorCrashedResponse) GetActor() *Actor { @@ -9131,7 +9006,7 @@ type ReportActorSnapshotStateRequest struct { func (x *ReportActorSnapshotStateRequest) Reset() { *x = ReportActorSnapshotStateRequest{} - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[127] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[125] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -9143,7 +9018,7 @@ func (x *ReportActorSnapshotStateRequest) String() string { func (*ReportActorSnapshotStateRequest) ProtoMessage() {} func (x *ReportActorSnapshotStateRequest) ProtoReflect() protoreflect.Message { - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[127] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[125] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -9156,7 +9031,7 @@ func (x *ReportActorSnapshotStateRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use ReportActorSnapshotStateRequest.ProtoReflect.Descriptor instead. func (*ReportActorSnapshotStateRequest) Descriptor() ([]byte, []int) { - return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{127} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{125} } func (x *ReportActorSnapshotStateRequest) GetActor() *ObjectRef { @@ -9188,7 +9063,7 @@ type ReportActorSnapshotStateResponse struct { func (x *ReportActorSnapshotStateResponse) Reset() { *x = ReportActorSnapshotStateResponse{} - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[128] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[126] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -9200,7 +9075,7 @@ func (x *ReportActorSnapshotStateResponse) String() string { func (*ReportActorSnapshotStateResponse) ProtoMessage() {} func (x *ReportActorSnapshotStateResponse) ProtoReflect() protoreflect.Message { - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[128] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[126] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -9213,7 +9088,7 @@ func (x *ReportActorSnapshotStateResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use ReportActorSnapshotStateResponse.ProtoReflect.Descriptor instead. func (*ReportActorSnapshotStateResponse) Descriptor() ([]byte, []int) { - return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{128} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{126} } // ActorSnapshotState is what atelet holds for one Actor on its node. It @@ -9247,7 +9122,7 @@ type ActorSnapshotState struct { func (x *ActorSnapshotState) Reset() { *x = ActorSnapshotState{} - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[129] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[127] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -9259,7 +9134,7 @@ func (x *ActorSnapshotState) String() string { func (*ActorSnapshotState) ProtoMessage() {} func (x *ActorSnapshotState) ProtoReflect() protoreflect.Message { - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[129] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[127] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -9272,7 +9147,7 @@ func (x *ActorSnapshotState) ProtoReflect() protoreflect.Message { // Deprecated: Use ActorSnapshotState.ProtoReflect.Descriptor instead. func (*ActorSnapshotState) Descriptor() ([]byte, []int) { - return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{129} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{127} } func (x *ActorSnapshotState) GetLatestLocal() *SnapshotReport { @@ -9344,7 +9219,7 @@ type SnapshotReport struct { func (x *SnapshotReport) Reset() { *x = SnapshotReport{} - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[130] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[128] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -9356,7 +9231,7 @@ func (x *SnapshotReport) String() string { func (*SnapshotReport) ProtoMessage() {} func (x *SnapshotReport) ProtoReflect() protoreflect.Message { - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[130] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[128] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -9369,7 +9244,7 @@ func (x *SnapshotReport) ProtoReflect() protoreflect.Message { // Deprecated: Use SnapshotReport.ProtoReflect.Descriptor instead. func (*SnapshotReport) Descriptor() ([]byte, []int) { - return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{130} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{128} } func (x *SnapshotReport) GetUuid() string { @@ -9439,7 +9314,7 @@ type AccessPolicy struct { func (x *AccessPolicy) Reset() { *x = AccessPolicy{} - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[131] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[129] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -9451,7 +9326,7 @@ func (x *AccessPolicy) String() string { func (*AccessPolicy) ProtoMessage() {} func (x *AccessPolicy) ProtoReflect() protoreflect.Message { - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[131] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[129] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -9464,7 +9339,7 @@ func (x *AccessPolicy) ProtoReflect() protoreflect.Message { // Deprecated: Use AccessPolicy.ProtoReflect.Descriptor instead. func (*AccessPolicy) Descriptor() ([]byte, []int) { - return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{131} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{129} } func (x *AccessPolicy) GetMetadata() *ResourceMetadata { @@ -9506,7 +9381,7 @@ type Binding struct { func (x *Binding) Reset() { *x = Binding{} - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[132] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[130] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -9518,7 +9393,7 @@ func (x *Binding) String() string { func (*Binding) ProtoMessage() {} func (x *Binding) ProtoReflect() protoreflect.Message { - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[132] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[130] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -9531,7 +9406,7 @@ func (x *Binding) ProtoReflect() protoreflect.Message { // Deprecated: Use Binding.ProtoReflect.Descriptor instead. func (*Binding) Descriptor() ([]byte, []int) { - return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{132} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{130} } func (x *Binding) GetRole() string { @@ -9563,7 +9438,7 @@ type GetGlobalAccessPolicyRequest struct { func (x *GetGlobalAccessPolicyRequest) Reset() { *x = GetGlobalAccessPolicyRequest{} - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[133] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[131] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -9575,7 +9450,7 @@ func (x *GetGlobalAccessPolicyRequest) String() string { func (*GetGlobalAccessPolicyRequest) ProtoMessage() {} func (x *GetGlobalAccessPolicyRequest) ProtoReflect() protoreflect.Message { - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[133] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[131] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -9588,7 +9463,7 @@ func (x *GetGlobalAccessPolicyRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use GetGlobalAccessPolicyRequest.ProtoReflect.Descriptor instead. func (*GetGlobalAccessPolicyRequest) Descriptor() ([]byte, []int) { - return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{133} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{131} } func (x *GetGlobalAccessPolicyRequest) GetName() string { @@ -9612,7 +9487,7 @@ type CreateGlobalAccessPolicyRequest struct { func (x *CreateGlobalAccessPolicyRequest) Reset() { *x = CreateGlobalAccessPolicyRequest{} - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[134] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[132] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -9624,7 +9499,7 @@ func (x *CreateGlobalAccessPolicyRequest) String() string { func (*CreateGlobalAccessPolicyRequest) ProtoMessage() {} func (x *CreateGlobalAccessPolicyRequest) ProtoReflect() protoreflect.Message { - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[134] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[132] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -9637,7 +9512,7 @@ func (x *CreateGlobalAccessPolicyRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use CreateGlobalAccessPolicyRequest.ProtoReflect.Descriptor instead. func (*CreateGlobalAccessPolicyRequest) Descriptor() ([]byte, []int) { - return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{134} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{132} } func (x *CreateGlobalAccessPolicyRequest) GetAccessPolicy() *AccessPolicy { @@ -9661,7 +9536,7 @@ type UpdateGlobalAccessPolicyRequest struct { func (x *UpdateGlobalAccessPolicyRequest) Reset() { *x = UpdateGlobalAccessPolicyRequest{} - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[135] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[133] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -9673,7 +9548,7 @@ func (x *UpdateGlobalAccessPolicyRequest) String() string { func (*UpdateGlobalAccessPolicyRequest) ProtoMessage() {} func (x *UpdateGlobalAccessPolicyRequest) ProtoReflect() protoreflect.Message { - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[135] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[133] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -9686,7 +9561,7 @@ func (x *UpdateGlobalAccessPolicyRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use UpdateGlobalAccessPolicyRequest.ProtoReflect.Descriptor instead. func (*UpdateGlobalAccessPolicyRequest) Descriptor() ([]byte, []int) { - return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{135} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{133} } func (x *UpdateGlobalAccessPolicyRequest) GetAccessPolicy() *AccessPolicy { @@ -9716,7 +9591,7 @@ type GetAtespaceAccessPolicyRequest struct { func (x *GetAtespaceAccessPolicyRequest) Reset() { *x = GetAtespaceAccessPolicyRequest{} - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[136] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[134] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -9728,7 +9603,7 @@ func (x *GetAtespaceAccessPolicyRequest) String() string { func (*GetAtespaceAccessPolicyRequest) ProtoMessage() {} func (x *GetAtespaceAccessPolicyRequest) ProtoReflect() protoreflect.Message { - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[136] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[134] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -9741,7 +9616,7 @@ func (x *GetAtespaceAccessPolicyRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use GetAtespaceAccessPolicyRequest.ProtoReflect.Descriptor instead. func (*GetAtespaceAccessPolicyRequest) Descriptor() ([]byte, []int) { - return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{136} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{134} } func (x *GetAtespaceAccessPolicyRequest) GetAtespace() *ObjectRef { @@ -9777,7 +9652,7 @@ type CreateAtespaceAccessPolicyRequest struct { func (x *CreateAtespaceAccessPolicyRequest) Reset() { *x = CreateAtespaceAccessPolicyRequest{} - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[137] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[135] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -9789,7 +9664,7 @@ func (x *CreateAtespaceAccessPolicyRequest) String() string { func (*CreateAtespaceAccessPolicyRequest) ProtoMessage() {} func (x *CreateAtespaceAccessPolicyRequest) ProtoReflect() protoreflect.Message { - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[137] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[135] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -9802,7 +9677,7 @@ func (x *CreateAtespaceAccessPolicyRequest) ProtoReflect() protoreflect.Message // Deprecated: Use CreateAtespaceAccessPolicyRequest.ProtoReflect.Descriptor instead. func (*CreateAtespaceAccessPolicyRequest) Descriptor() ([]byte, []int) { - return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{137} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{135} } func (x *CreateAtespaceAccessPolicyRequest) GetAtespace() *ObjectRef { @@ -9838,7 +9713,7 @@ type UpdateAtespaceAccessPolicyRequest struct { func (x *UpdateAtespaceAccessPolicyRequest) Reset() { *x = UpdateAtespaceAccessPolicyRequest{} - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[138] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[136] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -9850,7 +9725,7 @@ func (x *UpdateAtespaceAccessPolicyRequest) String() string { func (*UpdateAtespaceAccessPolicyRequest) ProtoMessage() {} func (x *UpdateAtespaceAccessPolicyRequest) ProtoReflect() protoreflect.Message { - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[138] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[136] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -9863,7 +9738,7 @@ func (x *UpdateAtespaceAccessPolicyRequest) ProtoReflect() protoreflect.Message // Deprecated: Use UpdateAtespaceAccessPolicyRequest.ProtoReflect.Descriptor instead. func (*UpdateAtespaceAccessPolicyRequest) Descriptor() ([]byte, []int) { - return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{138} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{136} } func (x *UpdateAtespaceAccessPolicyRequest) GetAtespace() *ObjectRef { @@ -9904,7 +9779,7 @@ type DeleteAtespaceAccessPolicyRequest struct { func (x *DeleteAtespaceAccessPolicyRequest) Reset() { *x = DeleteAtespaceAccessPolicyRequest{} - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[139] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[137] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -9916,7 +9791,7 @@ func (x *DeleteAtespaceAccessPolicyRequest) String() string { func (*DeleteAtespaceAccessPolicyRequest) ProtoMessage() {} func (x *DeleteAtespaceAccessPolicyRequest) ProtoReflect() protoreflect.Message { - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[139] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[137] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -9929,7 +9804,7 @@ func (x *DeleteAtespaceAccessPolicyRequest) ProtoReflect() protoreflect.Message // Deprecated: Use DeleteAtespaceAccessPolicyRequest.ProtoReflect.Descriptor instead. func (*DeleteAtespaceAccessPolicyRequest) Descriptor() ([]byte, []int) { - return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{139} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{137} } func (x *DeleteAtespaceAccessPolicyRequest) GetAtespace() *ObjectRef { @@ -9975,7 +9850,7 @@ type ResourceAnnotation struct { func (x *ResourceAnnotation) Reset() { *x = ResourceAnnotation{} - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[140] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[138] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -9987,7 +9862,7 @@ func (x *ResourceAnnotation) String() string { func (*ResourceAnnotation) ProtoMessage() {} func (x *ResourceAnnotation) ProtoReflect() protoreflect.Message { - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[140] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[138] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -10000,7 +9875,7 @@ func (x *ResourceAnnotation) ProtoReflect() protoreflect.Message { // Deprecated: Use ResourceAnnotation.ProtoReflect.Descriptor instead. func (*ResourceAnnotation) Descriptor() ([]byte, []int) { - return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{140} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{138} } func (x *ResourceAnnotation) GetParents() []string { @@ -10043,7 +9918,7 @@ type MethodAnnotation struct { func (x *MethodAnnotation) Reset() { *x = MethodAnnotation{} - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[141] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[139] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -10055,7 +9930,7 @@ func (x *MethodAnnotation) String() string { func (*MethodAnnotation) ProtoMessage() {} func (x *MethodAnnotation) ProtoReflect() protoreflect.Message { - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[141] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[139] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -10068,7 +9943,7 @@ func (x *MethodAnnotation) ProtoReflect() protoreflect.Message { // Deprecated: Use MethodAnnotation.ProtoReflect.Descriptor instead. func (*MethodAnnotation) Descriptor() ([]byte, []int) { - return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{141} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{139} } func (x *MethodAnnotation) GetResource() string { @@ -10400,13 +10275,7 @@ const file_api_ateapi_v1_ateapi_proto_rawDesc = "" + "\x14MintActorJwtResponse\x12 \n" + "\tactor_jwt\x18\x01 \x01(\tB\x03\x80\x01\x01R\bactorJwt\x12;\n" + "\vexpire_time\x18\x02 \x01(\v2\x1a.google.protobuf.TimestampR\n" + - "expireTime\"\xb0\x01\n" + - "\x1bMintActorCertificateRequest\x124\n" + - "\x05actor\x18\x01 \x01(\v2\x1e.substrate.ateapi.v1.ObjectRefR\x05actor\x12\x1b\n" + - "\tactor_uid\x18\x02 \x01(\tR\bactorUid\x12>\n" + - "\x1bcertificate_signing_request\x18\x03 \x01(\fR\x19certificateSigningRequest\"M\n" + - "\x1cMintActorCertificateResponse\x12-\n" + - "\x12actor_certificates\x18\x01 \x03(\fR\x11actorCertificates\"i\n" + + "expireTime\"i\n" + "\x0fListTagsRequest\x12\x1a\n" + "\batespace\x18\x01 \x01(\tR\batespace\x12:\n" + "\aoptions\x18\x02 \x01(\v2 .substrate.ateapi.v1.ListOptionsR\aoptions\"h\n" + @@ -10666,7 +10535,7 @@ const file_api_ateapi_v1_ateapi_proto_rawDesc = "" + "\x05Scope\x12\x15\n" + "\x11SCOPE_UNSPECIFIED\x10\x00\x12\x12\n" + "\x0eSCOPE_ATESPACE\x10\x01\x12\x10\n" + - "\fSCOPE_GLOBAL\x10\x022\xd5'\n" + + "\fSCOPE_GLOBAL\x10\x022\xca&\n" + "\aControl\x12Y\n" + "\bGetActor\x12$.substrate.ateapi.v1.GetActorRequest\x1a\x1a.substrate.ateapi.v1.Actor\"\v\x82\xb5\x18\a\n" + "\x05Actor\x12_\n" + @@ -10691,8 +10560,6 @@ const file_api_ateapi_v1_ateapi_proto_rawDesc = "" + "\x17DeleteActorEgressPolicy\x123.substrate.ateapi.v1.DeleteActorEgressPolicyRequest\x1a!.substrate.ateapi.v1.EgressPolicy\"\x12\x82\xb5\x18\x0e\n" + "\fEgressPolicy\x12p\n" + "\fMintActorJwt\x12(.substrate.ateapi.v1.MintActorJwtRequest\x1a).substrate.ateapi.v1.MintActorJwtResponse\"\v\x82\xb5\x18\a\n" + - "\x05Actor\x12\x88\x01\n" + - "\x14MintActorCertificate\x120.substrate.ateapi.v1.MintActorCertificateRequest\x1a1.substrate.ateapi.v1.MintActorCertificateResponse\"\v\x82\xb5\x18\a\n" + "\x05Actor\x12W\n" + "\tCreateTag\x12%.substrate.ateapi.v1.CreateTagRequest\x1a\x18.substrate.ateapi.v1.Tag\"\t\x82\xb5\x18\x05\n" + "\x03Tag\x12Q\n" + @@ -10784,7 +10651,7 @@ func file_api_ateapi_v1_ateapi_proto_rawDescGZIP() []byte { } var file_api_ateapi_v1_ateapi_proto_enumTypes = make([]protoimpl.EnumInfo, 10) -var file_api_ateapi_v1_ateapi_proto_msgTypes = make([]protoimpl.MessageInfo, 145) +var file_api_ateapi_v1_ateapi_proto_msgTypes = make([]protoimpl.MessageInfo, 143) var file_api_ateapi_v1_ateapi_proto_goTypes = []any{ (SnapshotOwner)(0), // 0: substrate.ateapi.v1.SnapshotOwner (SnapshotStorageState)(0), // 1: substrate.ateapi.v1.SnapshotStorageState @@ -10874,76 +10741,74 @@ var file_api_ateapi_v1_ateapi_proto_goTypes = []any{ (*GetTagRequest)(nil), // 85: substrate.ateapi.v1.GetTagRequest (*MintActorJwtRequest)(nil), // 86: substrate.ateapi.v1.MintActorJwtRequest (*MintActorJwtResponse)(nil), // 87: substrate.ateapi.v1.MintActorJwtResponse - (*MintActorCertificateRequest)(nil), // 88: substrate.ateapi.v1.MintActorCertificateRequest - (*MintActorCertificateResponse)(nil), // 89: substrate.ateapi.v1.MintActorCertificateResponse - (*ListTagsRequest)(nil), // 90: substrate.ateapi.v1.ListTagsRequest - (*ListTagsResponse)(nil), // 91: substrate.ateapi.v1.ListTagsResponse - (*CreateTagRequest)(nil), // 92: substrate.ateapi.v1.CreateTagRequest - (*UpdateTagRequest)(nil), // 93: substrate.ateapi.v1.UpdateTagRequest - (*DeleteTagRequest)(nil), // 94: substrate.ateapi.v1.DeleteTagRequest - (*DeleteOptions)(nil), // 95: substrate.ateapi.v1.DeleteOptions - (*ListOptions)(nil), // 96: substrate.ateapi.v1.ListOptions - (*ListWorkerActorAssignmentsRequest)(nil), // 97: substrate.ateapi.v1.ListWorkerActorAssignmentsRequest - (*ListWorkerActorAssignmentsResponse)(nil), // 98: substrate.ateapi.v1.ListWorkerActorAssignmentsResponse - (*ListWorkersRequest)(nil), // 99: substrate.ateapi.v1.ListWorkersRequest - (*ListWorkersResponse)(nil), // 100: substrate.ateapi.v1.ListWorkersResponse - (*GetWorkerRequest)(nil), // 101: substrate.ateapi.v1.GetWorkerRequest - (*CreateWorkerRequest)(nil), // 102: substrate.ateapi.v1.CreateWorkerRequest - (*UpdateWorkerRequest)(nil), // 103: substrate.ateapi.v1.UpdateWorkerRequest - (*DeleteWorkerRequest)(nil), // 104: substrate.ateapi.v1.DeleteWorkerRequest - (*DrainWorkerRequest)(nil), // 105: substrate.ateapi.v1.DrainWorkerRequest - (*DrainWorkerResponse)(nil), // 106: substrate.ateapi.v1.DrainWorkerResponse - (*MarkWorkerAvailableRequest)(nil), // 107: substrate.ateapi.v1.MarkWorkerAvailableRequest - (*MarkWorkerAvailableResponse)(nil), // 108: substrate.ateapi.v1.MarkWorkerAvailableResponse - (*MarkWorkerUnavailableRequest)(nil), // 109: substrate.ateapi.v1.MarkWorkerUnavailableRequest - (*MarkWorkerUnavailableResponse)(nil), // 110: substrate.ateapi.v1.MarkWorkerUnavailableResponse - (*ListActorsRequest)(nil), // 111: substrate.ateapi.v1.ListActorsRequest - (*ListActorsResponse)(nil), // 112: substrate.ateapi.v1.ListActorsResponse - (*Worker)(nil), // 113: substrate.ateapi.v1.Worker - (*WorkerStatus)(nil), // 114: substrate.ateapi.v1.WorkerStatus - (*WorkerSandboxClass)(nil), // 115: substrate.ateapi.v1.WorkerSandboxClass - (*WorkerSandboxRuntime)(nil), // 116: substrate.ateapi.v1.WorkerSandboxRuntime - (*RuntimeOverhead)(nil), // 117: substrate.ateapi.v1.RuntimeOverhead - (*ActorSandboxRuntime)(nil), // 118: substrate.ateapi.v1.ActorSandboxRuntime - (*VersionedSandboxCompat)(nil), // 119: substrate.ateapi.v1.VersionedSandboxCompat - (*AttributeEntry)(nil), // 120: substrate.ateapi.v1.AttributeEntry - (*WorkerResources)(nil), // 121: substrate.ateapi.v1.WorkerResources - (*ActorAssignment)(nil), // 122: substrate.ateapi.v1.ActorAssignment - (*AcquireWorkerEpochRequest)(nil), // 123: substrate.ateapi.v1.AcquireWorkerEpochRequest - (*AcquireWorkerEpochResponse)(nil), // 124: substrate.ateapi.v1.AcquireWorkerEpochResponse - (*RegisterWorkerRequest)(nil), // 125: substrate.ateapi.v1.RegisterWorkerRequest - (*RegisterWorkerResponse)(nil), // 126: substrate.ateapi.v1.RegisterWorkerResponse - (*SetWorkerSandboxRuntimesRequest)(nil), // 127: substrate.ateapi.v1.SetWorkerSandboxRuntimesRequest - (*SetWorkerSandboxRuntimesResponse)(nil), // 128: substrate.ateapi.v1.SetWorkerSandboxRuntimesResponse - (*MintWorkerActorCertificateRequest)(nil), // 129: substrate.ateapi.v1.MintWorkerActorCertificateRequest - (*MintWorkerActorCertificateResponse)(nil), // 130: substrate.ateapi.v1.MintWorkerActorCertificateResponse - (*MintWorkerActorJwtRequest)(nil), // 131: substrate.ateapi.v1.MintWorkerActorJwtRequest - (*MintWorkerActorJwtResponse)(nil), // 132: substrate.ateapi.v1.MintWorkerActorJwtResponse - (*RequestActorSuspendRequest)(nil), // 133: substrate.ateapi.v1.RequestActorSuspendRequest - (*RequestActorSuspendResponse)(nil), // 134: substrate.ateapi.v1.RequestActorSuspendResponse - (*ReportActorCrashedRequest)(nil), // 135: substrate.ateapi.v1.ReportActorCrashedRequest - (*ReportActorCrashedResponse)(nil), // 136: substrate.ateapi.v1.ReportActorCrashedResponse - (*ReportActorSnapshotStateRequest)(nil), // 137: substrate.ateapi.v1.ReportActorSnapshotStateRequest - (*ReportActorSnapshotStateResponse)(nil), // 138: substrate.ateapi.v1.ReportActorSnapshotStateResponse - (*ActorSnapshotState)(nil), // 139: substrate.ateapi.v1.ActorSnapshotState - (*SnapshotReport)(nil), // 140: substrate.ateapi.v1.SnapshotReport - (*AccessPolicy)(nil), // 141: substrate.ateapi.v1.AccessPolicy - (*Binding)(nil), // 142: substrate.ateapi.v1.Binding - (*GetGlobalAccessPolicyRequest)(nil), // 143: substrate.ateapi.v1.GetGlobalAccessPolicyRequest - (*CreateGlobalAccessPolicyRequest)(nil), // 144: substrate.ateapi.v1.CreateGlobalAccessPolicyRequest - (*UpdateGlobalAccessPolicyRequest)(nil), // 145: substrate.ateapi.v1.UpdateGlobalAccessPolicyRequest - (*GetAtespaceAccessPolicyRequest)(nil), // 146: substrate.ateapi.v1.GetAtespaceAccessPolicyRequest - (*CreateAtespaceAccessPolicyRequest)(nil), // 147: substrate.ateapi.v1.CreateAtespaceAccessPolicyRequest - (*UpdateAtespaceAccessPolicyRequest)(nil), // 148: substrate.ateapi.v1.UpdateAtespaceAccessPolicyRequest - (*DeleteAtespaceAccessPolicyRequest)(nil), // 149: substrate.ateapi.v1.DeleteAtespaceAccessPolicyRequest - (*ResourceAnnotation)(nil), // 150: substrate.ateapi.v1.ResourceAnnotation - (*MethodAnnotation)(nil), // 151: substrate.ateapi.v1.MethodAnnotation - nil, // 152: substrate.ateapi.v1.Selector.MatchLabelsEntry - nil, // 153: substrate.ateapi.v1.ExternalVolumeStatus.VolumeContextEntry - nil, // 154: substrate.ateapi.v1.Worker.LabelsEntry - (*timestamppb.Timestamp)(nil), // 155: google.protobuf.Timestamp - (*descriptorpb.MessageOptions)(nil), // 156: google.protobuf.MessageOptions - (*descriptorpb.MethodOptions)(nil), // 157: google.protobuf.MethodOptions + (*ListTagsRequest)(nil), // 88: substrate.ateapi.v1.ListTagsRequest + (*ListTagsResponse)(nil), // 89: substrate.ateapi.v1.ListTagsResponse + (*CreateTagRequest)(nil), // 90: substrate.ateapi.v1.CreateTagRequest + (*UpdateTagRequest)(nil), // 91: substrate.ateapi.v1.UpdateTagRequest + (*DeleteTagRequest)(nil), // 92: substrate.ateapi.v1.DeleteTagRequest + (*DeleteOptions)(nil), // 93: substrate.ateapi.v1.DeleteOptions + (*ListOptions)(nil), // 94: substrate.ateapi.v1.ListOptions + (*ListWorkerActorAssignmentsRequest)(nil), // 95: substrate.ateapi.v1.ListWorkerActorAssignmentsRequest + (*ListWorkerActorAssignmentsResponse)(nil), // 96: substrate.ateapi.v1.ListWorkerActorAssignmentsResponse + (*ListWorkersRequest)(nil), // 97: substrate.ateapi.v1.ListWorkersRequest + (*ListWorkersResponse)(nil), // 98: substrate.ateapi.v1.ListWorkersResponse + (*GetWorkerRequest)(nil), // 99: substrate.ateapi.v1.GetWorkerRequest + (*CreateWorkerRequest)(nil), // 100: substrate.ateapi.v1.CreateWorkerRequest + (*UpdateWorkerRequest)(nil), // 101: substrate.ateapi.v1.UpdateWorkerRequest + (*DeleteWorkerRequest)(nil), // 102: substrate.ateapi.v1.DeleteWorkerRequest + (*DrainWorkerRequest)(nil), // 103: substrate.ateapi.v1.DrainWorkerRequest + (*DrainWorkerResponse)(nil), // 104: substrate.ateapi.v1.DrainWorkerResponse + (*MarkWorkerAvailableRequest)(nil), // 105: substrate.ateapi.v1.MarkWorkerAvailableRequest + (*MarkWorkerAvailableResponse)(nil), // 106: substrate.ateapi.v1.MarkWorkerAvailableResponse + (*MarkWorkerUnavailableRequest)(nil), // 107: substrate.ateapi.v1.MarkWorkerUnavailableRequest + (*MarkWorkerUnavailableResponse)(nil), // 108: substrate.ateapi.v1.MarkWorkerUnavailableResponse + (*ListActorsRequest)(nil), // 109: substrate.ateapi.v1.ListActorsRequest + (*ListActorsResponse)(nil), // 110: substrate.ateapi.v1.ListActorsResponse + (*Worker)(nil), // 111: substrate.ateapi.v1.Worker + (*WorkerStatus)(nil), // 112: substrate.ateapi.v1.WorkerStatus + (*WorkerSandboxClass)(nil), // 113: substrate.ateapi.v1.WorkerSandboxClass + (*WorkerSandboxRuntime)(nil), // 114: substrate.ateapi.v1.WorkerSandboxRuntime + (*RuntimeOverhead)(nil), // 115: substrate.ateapi.v1.RuntimeOverhead + (*ActorSandboxRuntime)(nil), // 116: substrate.ateapi.v1.ActorSandboxRuntime + (*VersionedSandboxCompat)(nil), // 117: substrate.ateapi.v1.VersionedSandboxCompat + (*AttributeEntry)(nil), // 118: substrate.ateapi.v1.AttributeEntry + (*WorkerResources)(nil), // 119: substrate.ateapi.v1.WorkerResources + (*ActorAssignment)(nil), // 120: substrate.ateapi.v1.ActorAssignment + (*AcquireWorkerEpochRequest)(nil), // 121: substrate.ateapi.v1.AcquireWorkerEpochRequest + (*AcquireWorkerEpochResponse)(nil), // 122: substrate.ateapi.v1.AcquireWorkerEpochResponse + (*RegisterWorkerRequest)(nil), // 123: substrate.ateapi.v1.RegisterWorkerRequest + (*RegisterWorkerResponse)(nil), // 124: substrate.ateapi.v1.RegisterWorkerResponse + (*SetWorkerSandboxRuntimesRequest)(nil), // 125: substrate.ateapi.v1.SetWorkerSandboxRuntimesRequest + (*SetWorkerSandboxRuntimesResponse)(nil), // 126: substrate.ateapi.v1.SetWorkerSandboxRuntimesResponse + (*MintWorkerActorCertificateRequest)(nil), // 127: substrate.ateapi.v1.MintWorkerActorCertificateRequest + (*MintWorkerActorCertificateResponse)(nil), // 128: substrate.ateapi.v1.MintWorkerActorCertificateResponse + (*MintWorkerActorJwtRequest)(nil), // 129: substrate.ateapi.v1.MintWorkerActorJwtRequest + (*MintWorkerActorJwtResponse)(nil), // 130: substrate.ateapi.v1.MintWorkerActorJwtResponse + (*RequestActorSuspendRequest)(nil), // 131: substrate.ateapi.v1.RequestActorSuspendRequest + (*RequestActorSuspendResponse)(nil), // 132: substrate.ateapi.v1.RequestActorSuspendResponse + (*ReportActorCrashedRequest)(nil), // 133: substrate.ateapi.v1.ReportActorCrashedRequest + (*ReportActorCrashedResponse)(nil), // 134: substrate.ateapi.v1.ReportActorCrashedResponse + (*ReportActorSnapshotStateRequest)(nil), // 135: substrate.ateapi.v1.ReportActorSnapshotStateRequest + (*ReportActorSnapshotStateResponse)(nil), // 136: substrate.ateapi.v1.ReportActorSnapshotStateResponse + (*ActorSnapshotState)(nil), // 137: substrate.ateapi.v1.ActorSnapshotState + (*SnapshotReport)(nil), // 138: substrate.ateapi.v1.SnapshotReport + (*AccessPolicy)(nil), // 139: substrate.ateapi.v1.AccessPolicy + (*Binding)(nil), // 140: substrate.ateapi.v1.Binding + (*GetGlobalAccessPolicyRequest)(nil), // 141: substrate.ateapi.v1.GetGlobalAccessPolicyRequest + (*CreateGlobalAccessPolicyRequest)(nil), // 142: substrate.ateapi.v1.CreateGlobalAccessPolicyRequest + (*UpdateGlobalAccessPolicyRequest)(nil), // 143: substrate.ateapi.v1.UpdateGlobalAccessPolicyRequest + (*GetAtespaceAccessPolicyRequest)(nil), // 144: substrate.ateapi.v1.GetAtespaceAccessPolicyRequest + (*CreateAtespaceAccessPolicyRequest)(nil), // 145: substrate.ateapi.v1.CreateAtespaceAccessPolicyRequest + (*UpdateAtespaceAccessPolicyRequest)(nil), // 146: substrate.ateapi.v1.UpdateAtespaceAccessPolicyRequest + (*DeleteAtespaceAccessPolicyRequest)(nil), // 147: substrate.ateapi.v1.DeleteAtespaceAccessPolicyRequest + (*ResourceAnnotation)(nil), // 148: substrate.ateapi.v1.ResourceAnnotation + (*MethodAnnotation)(nil), // 149: substrate.ateapi.v1.MethodAnnotation + nil, // 150: substrate.ateapi.v1.Selector.MatchLabelsEntry + nil, // 151: substrate.ateapi.v1.ExternalVolumeStatus.VolumeContextEntry + nil, // 152: substrate.ateapi.v1.Worker.LabelsEntry + (*timestamppb.Timestamp)(nil), // 153: google.protobuf.Timestamp + (*descriptorpb.MessageOptions)(nil), // 154: google.protobuf.MessageOptions + (*descriptorpb.MethodOptions)(nil), // 155: google.protobuf.MethodOptions } var file_api_ateapi_v1_ateapi_proto_depIdxs = []int32{ 1, // 0: substrate.ateapi.v1.SnapshotStorage.state:type_name -> substrate.ateapi.v1.SnapshotStorageState @@ -10951,13 +10816,13 @@ var file_api_ateapi_v1_ateapi_proto_depIdxs = []int32{ 0, // 2: substrate.ateapi.v1.Snapshot.owner:type_name -> substrate.ateapi.v1.SnapshotOwner 2, // 3: substrate.ateapi.v1.Snapshot.fidelity:type_name -> substrate.ateapi.v1.SnapshotFidelity 11, // 4: substrate.ateapi.v1.Snapshot.durable_snapshot:type_name -> substrate.ateapi.v1.SnapshotStorage - 118, // 5: substrate.ateapi.v1.Snapshot.sandbox_runtime:type_name -> substrate.ateapi.v1.ActorSandboxRuntime - 152, // 6: substrate.ateapi.v1.Selector.match_labels:type_name -> substrate.ateapi.v1.Selector.MatchLabelsEntry - 155, // 7: substrate.ateapi.v1.ResourceMetadata.create_time:type_name -> google.protobuf.Timestamp - 155, // 8: substrate.ateapi.v1.ResourceMetadata.update_time:type_name -> google.protobuf.Timestamp - 155, // 9: substrate.ateapi.v1.ResourceMetadata.delete_time:type_name -> google.protobuf.Timestamp + 116, // 5: substrate.ateapi.v1.Snapshot.sandbox_runtime:type_name -> substrate.ateapi.v1.ActorSandboxRuntime + 150, // 6: substrate.ateapi.v1.Selector.match_labels:type_name -> substrate.ateapi.v1.Selector.MatchLabelsEntry + 153, // 7: substrate.ateapi.v1.ResourceMetadata.create_time:type_name -> google.protobuf.Timestamp + 153, // 8: substrate.ateapi.v1.ResourceMetadata.update_time:type_name -> google.protobuf.Timestamp + 153, // 9: substrate.ateapi.v1.ResourceMetadata.delete_time:type_name -> google.protobuf.Timestamp 16, // 10: substrate.ateapi.v1.ExternalVolumes.volumes:type_name -> substrate.ateapi.v1.ExternalVolumeStatus - 153, // 11: substrate.ateapi.v1.ExternalVolumeStatus.volume_context:type_name -> substrate.ateapi.v1.ExternalVolumeStatus.VolumeContextEntry + 151, // 11: substrate.ateapi.v1.ExternalVolumeStatus.volume_context:type_name -> substrate.ateapi.v1.ExternalVolumeStatus.VolumeContextEntry 14, // 12: substrate.ateapi.v1.Actor.metadata:type_name -> substrate.ateapi.v1.ResourceMetadata 35, // 13: substrate.ateapi.v1.Actor.actor_template:type_name -> substrate.ateapi.v1.ObjectRef 13, // 14: substrate.ateapi.v1.Actor.worker_selector:type_name -> substrate.ateapi.v1.Selector @@ -10982,9 +10847,9 @@ var file_api_ateapi_v1_ateapi_proto_depIdxs = []int32{ 15, // 33: substrate.ateapi.v1.ActorStatus.external_volumes:type_name -> substrate.ateapi.v1.ExternalVolumes 30, // 34: substrate.ateapi.v1.ActorStatus.crash:type_name -> substrate.ateapi.v1.ActorCrash 12, // 35: substrate.ateapi.v1.ActorStatus.snapshots:type_name -> substrate.ateapi.v1.Snapshot - 155, // 36: substrate.ateapi.v1.ActorCrash.crash_time:type_name -> google.protobuf.Timestamp + 153, // 36: substrate.ateapi.v1.ActorCrash.crash_time:type_name -> google.protobuf.Timestamp 35, // 37: substrate.ateapi.v1.WorkerAssignment.worker:type_name -> substrate.ateapi.v1.ObjectRef - 118, // 38: substrate.ateapi.v1.WorkerAssignment.sandbox_runtime:type_name -> substrate.ateapi.v1.ActorSandboxRuntime + 116, // 38: substrate.ateapi.v1.WorkerAssignment.sandbox_runtime:type_name -> substrate.ateapi.v1.ActorSandboxRuntime 12, // 39: substrate.ateapi.v1.TagStatus.snapshot:type_name -> substrate.ateapi.v1.Snapshot 14, // 40: substrate.ateapi.v1.Tag.metadata:type_name -> substrate.ateapi.v1.ResourceMetadata 32, // 41: substrate.ateapi.v1.Tag.status:type_name -> substrate.ateapi.v1.TagStatus @@ -11001,7 +10866,7 @@ var file_api_ateapi_v1_ateapi_proto_depIdxs = []int32{ 40, // 52: substrate.ateapi.v1.ActorTemplate.status:type_name -> substrate.ateapi.v1.ActorTemplateStatus 38, // 53: substrate.ateapi.v1.ResourceRequirements.limits:type_name -> substrate.ateapi.v1.Resources 35, // 54: substrate.ateapi.v1.GoldenSnapshotStatus.golden_tag:type_name -> substrate.ateapi.v1.ObjectRef - 155, // 55: substrate.ateapi.v1.GoldenSnapshotStatus.snapshot_time:type_name -> google.protobuf.Timestamp + 153, // 55: substrate.ateapi.v1.GoldenSnapshotStatus.snapshot_time:type_name -> google.protobuf.Timestamp 39, // 56: substrate.ateapi.v1.ActorTemplateStatus.golden_snapshot_status:type_name -> substrate.ateapi.v1.GoldenSnapshotStatus 2, // 57: substrate.ateapi.v1.SnapshotConfig.preferred_fidelity:type_name -> substrate.ateapi.v1.SnapshotFidelity 42, // 58: substrate.ateapi.v1.SnapshotConfig.golden_snapshot_config:type_name -> substrate.ateapi.v1.GoldenSnapshotConfig @@ -11025,16 +10890,16 @@ var file_api_ateapi_v1_ateapi_proto_depIdxs = []int32{ 6, // 76: substrate.ateapi.v1.ActorMetadataItem.field:type_name -> substrate.ateapi.v1.ActorMetadataField 34, // 77: substrate.ateapi.v1.CreateAtespaceRequest.atespace:type_name -> substrate.ateapi.v1.Atespace 35, // 78: substrate.ateapi.v1.GetAtespaceRequest.atespace:type_name -> substrate.ateapi.v1.ObjectRef - 96, // 79: substrate.ateapi.v1.ListAtespacesRequest.options:type_name -> substrate.ateapi.v1.ListOptions + 94, // 79: substrate.ateapi.v1.ListAtespacesRequest.options:type_name -> substrate.ateapi.v1.ListOptions 34, // 80: substrate.ateapi.v1.ListAtespacesResponse.atespaces:type_name -> substrate.ateapi.v1.Atespace 35, // 81: substrate.ateapi.v1.DeleteAtespaceRequest.atespace:type_name -> substrate.ateapi.v1.ObjectRef - 95, // 82: substrate.ateapi.v1.DeleteAtespaceRequest.options:type_name -> substrate.ateapi.v1.DeleteOptions + 93, // 82: substrate.ateapi.v1.DeleteAtespaceRequest.options:type_name -> substrate.ateapi.v1.DeleteOptions 36, // 83: substrate.ateapi.v1.CreateActorTemplateRequest.actor_template:type_name -> substrate.ateapi.v1.ActorTemplate 35, // 84: substrate.ateapi.v1.GetActorTemplateRequest.actor_template:type_name -> substrate.ateapi.v1.ObjectRef - 96, // 85: substrate.ateapi.v1.ListActorTemplatesRequest.options:type_name -> substrate.ateapi.v1.ListOptions + 94, // 85: substrate.ateapi.v1.ListActorTemplatesRequest.options:type_name -> substrate.ateapi.v1.ListOptions 36, // 86: substrate.ateapi.v1.ListActorTemplatesResponse.actor_templates:type_name -> substrate.ateapi.v1.ActorTemplate 35, // 87: substrate.ateapi.v1.DeleteActorTemplateRequest.actor_template:type_name -> substrate.ateapi.v1.ObjectRef - 95, // 88: substrate.ateapi.v1.DeleteActorTemplateRequest.options:type_name -> substrate.ateapi.v1.DeleteOptions + 93, // 88: substrate.ateapi.v1.DeleteActorTemplateRequest.options:type_name -> substrate.ateapi.v1.DeleteOptions 35, // 89: substrate.ateapi.v1.GetActorRequest.actor:type_name -> substrate.ateapi.v1.ObjectRef 17, // 90: substrate.ateapi.v1.CreateActorRequest.actor:type_name -> substrate.ateapi.v1.Actor 17, // 91: substrate.ateapi.v1.UpdateActorRequest.actor:type_name -> substrate.ateapi.v1.Actor @@ -11047,208 +10912,205 @@ var file_api_ateapi_v1_ateapi_proto_depIdxs = []int32{ 35, // 98: substrate.ateapi.v1.RevertActorRequest.actor:type_name -> substrate.ateapi.v1.ObjectRef 17, // 99: substrate.ateapi.v1.RevertActorResponse.actor:type_name -> substrate.ateapi.v1.Actor 35, // 100: substrate.ateapi.v1.DeleteActorRequest.actor:type_name -> substrate.ateapi.v1.ObjectRef - 95, // 101: substrate.ateapi.v1.DeleteActorRequest.options:type_name -> substrate.ateapi.v1.DeleteOptions + 93, // 101: substrate.ateapi.v1.DeleteActorRequest.options:type_name -> substrate.ateapi.v1.DeleteOptions 35, // 102: substrate.ateapi.v1.GetActorEgressPolicyRequest.actor:type_name -> substrate.ateapi.v1.ObjectRef 35, // 103: substrate.ateapi.v1.CreateActorEgressPolicyRequest.actor:type_name -> substrate.ateapi.v1.ObjectRef 18, // 104: substrate.ateapi.v1.CreateActorEgressPolicyRequest.egress_policy:type_name -> substrate.ateapi.v1.EgressPolicy 35, // 105: substrate.ateapi.v1.UpdateActorEgressPolicyRequest.actor:type_name -> substrate.ateapi.v1.ObjectRef 18, // 106: substrate.ateapi.v1.UpdateActorEgressPolicyRequest.egress_policy:type_name -> substrate.ateapi.v1.EgressPolicy 35, // 107: substrate.ateapi.v1.DeleteActorEgressPolicyRequest.actor:type_name -> substrate.ateapi.v1.ObjectRef - 95, // 108: substrate.ateapi.v1.DeleteActorEgressPolicyRequest.options:type_name -> substrate.ateapi.v1.DeleteOptions + 93, // 108: substrate.ateapi.v1.DeleteActorEgressPolicyRequest.options:type_name -> substrate.ateapi.v1.DeleteOptions 35, // 109: substrate.ateapi.v1.GetTagRequest.tag:type_name -> substrate.ateapi.v1.ObjectRef 35, // 110: substrate.ateapi.v1.MintActorJwtRequest.actor:type_name -> substrate.ateapi.v1.ObjectRef - 155, // 111: substrate.ateapi.v1.MintActorJwtResponse.expire_time:type_name -> google.protobuf.Timestamp - 35, // 112: substrate.ateapi.v1.MintActorCertificateRequest.actor:type_name -> substrate.ateapi.v1.ObjectRef - 96, // 113: substrate.ateapi.v1.ListTagsRequest.options:type_name -> substrate.ateapi.v1.ListOptions - 33, // 114: substrate.ateapi.v1.ListTagsResponse.tags:type_name -> substrate.ateapi.v1.Tag - 33, // 115: substrate.ateapi.v1.CreateTagRequest.tag:type_name -> substrate.ateapi.v1.Tag - 33, // 116: substrate.ateapi.v1.UpdateTagRequest.tag:type_name -> substrate.ateapi.v1.Tag - 35, // 117: substrate.ateapi.v1.DeleteTagRequest.tag:type_name -> substrate.ateapi.v1.ObjectRef - 95, // 118: substrate.ateapi.v1.DeleteTagRequest.options:type_name -> substrate.ateapi.v1.DeleteOptions - 35, // 119: substrate.ateapi.v1.ListWorkerActorAssignmentsRequest.worker:type_name -> substrate.ateapi.v1.ObjectRef - 96, // 120: substrate.ateapi.v1.ListWorkerActorAssignmentsRequest.options:type_name -> substrate.ateapi.v1.ListOptions - 122, // 121: substrate.ateapi.v1.ListWorkerActorAssignmentsResponse.actor_assignments:type_name -> substrate.ateapi.v1.ActorAssignment - 96, // 122: substrate.ateapi.v1.ListWorkersRequest.options:type_name -> substrate.ateapi.v1.ListOptions - 113, // 123: substrate.ateapi.v1.ListWorkersResponse.workers:type_name -> substrate.ateapi.v1.Worker - 35, // 124: substrate.ateapi.v1.GetWorkerRequest.worker:type_name -> substrate.ateapi.v1.ObjectRef - 113, // 125: substrate.ateapi.v1.CreateWorkerRequest.worker:type_name -> substrate.ateapi.v1.Worker - 113, // 126: substrate.ateapi.v1.UpdateWorkerRequest.worker:type_name -> substrate.ateapi.v1.Worker - 35, // 127: substrate.ateapi.v1.DeleteWorkerRequest.worker:type_name -> substrate.ateapi.v1.ObjectRef - 95, // 128: substrate.ateapi.v1.DeleteWorkerRequest.options:type_name -> substrate.ateapi.v1.DeleteOptions - 35, // 129: substrate.ateapi.v1.DrainWorkerRequest.worker:type_name -> substrate.ateapi.v1.ObjectRef - 113, // 130: substrate.ateapi.v1.DrainWorkerResponse.worker:type_name -> substrate.ateapi.v1.Worker - 35, // 131: substrate.ateapi.v1.MarkWorkerAvailableRequest.worker:type_name -> substrate.ateapi.v1.ObjectRef - 113, // 132: substrate.ateapi.v1.MarkWorkerAvailableResponse.worker:type_name -> substrate.ateapi.v1.Worker - 35, // 133: substrate.ateapi.v1.MarkWorkerUnavailableRequest.worker:type_name -> substrate.ateapi.v1.ObjectRef - 113, // 134: substrate.ateapi.v1.MarkWorkerUnavailableResponse.worker:type_name -> substrate.ateapi.v1.Worker - 96, // 135: substrate.ateapi.v1.ListActorsRequest.options:type_name -> substrate.ateapi.v1.ListOptions - 17, // 136: substrate.ateapi.v1.ListActorsResponse.actors:type_name -> substrate.ateapi.v1.Actor - 14, // 137: substrate.ateapi.v1.Worker.metadata:type_name -> substrate.ateapi.v1.ResourceMetadata - 154, // 138: substrate.ateapi.v1.Worker.labels:type_name -> substrate.ateapi.v1.Worker.LabelsEntry - 114, // 139: substrate.ateapi.v1.Worker.status:type_name -> substrate.ateapi.v1.WorkerStatus - 8, // 140: substrate.ateapi.v1.WorkerStatus.state:type_name -> substrate.ateapi.v1.WorkerState - 121, // 141: substrate.ateapi.v1.WorkerStatus.capacity:type_name -> substrate.ateapi.v1.WorkerResources - 121, // 142: substrate.ateapi.v1.WorkerStatus.allocated:type_name -> substrate.ateapi.v1.WorkerResources - 115, // 143: substrate.ateapi.v1.WorkerStatus.sandbox_classes:type_name -> substrate.ateapi.v1.WorkerSandboxClass - 116, // 144: substrate.ateapi.v1.WorkerSandboxClass.default_runtime:type_name -> substrate.ateapi.v1.WorkerSandboxRuntime - 116, // 145: substrate.ateapi.v1.WorkerSandboxClass.restorable_runtimes:type_name -> substrate.ateapi.v1.WorkerSandboxRuntime - 119, // 146: substrate.ateapi.v1.WorkerSandboxRuntime.version:type_name -> substrate.ateapi.v1.VersionedSandboxCompat - 117, // 147: substrate.ateapi.v1.WorkerSandboxRuntime.actor_overhead:type_name -> substrate.ateapi.v1.RuntimeOverhead - 119, // 148: substrate.ateapi.v1.ActorSandboxRuntime.version:type_name -> substrate.ateapi.v1.VersionedSandboxCompat - 120, // 149: substrate.ateapi.v1.VersionedSandboxCompat.attributes:type_name -> substrate.ateapi.v1.AttributeEntry - 14, // 150: substrate.ateapi.v1.ActorAssignment.metadata:type_name -> substrate.ateapi.v1.ResourceMetadata - 35, // 151: substrate.ateapi.v1.ActorAssignment.actor:type_name -> substrate.ateapi.v1.ObjectRef - 38, // 152: substrate.ateapi.v1.ActorAssignment.resources:type_name -> substrate.ateapi.v1.Resources - 35, // 153: substrate.ateapi.v1.AcquireWorkerEpochRequest.worker:type_name -> substrate.ateapi.v1.ObjectRef - 35, // 154: substrate.ateapi.v1.RegisterWorkerRequest.worker:type_name -> substrate.ateapi.v1.ObjectRef - 121, // 155: substrate.ateapi.v1.RegisterWorkerRequest.capacity:type_name -> substrate.ateapi.v1.WorkerResources - 113, // 156: substrate.ateapi.v1.RegisterWorkerResponse.worker:type_name -> substrate.ateapi.v1.Worker - 35, // 157: substrate.ateapi.v1.SetWorkerSandboxRuntimesRequest.worker:type_name -> substrate.ateapi.v1.ObjectRef - 115, // 158: substrate.ateapi.v1.SetWorkerSandboxRuntimesRequest.sandbox_classes:type_name -> substrate.ateapi.v1.WorkerSandboxClass - 113, // 159: substrate.ateapi.v1.SetWorkerSandboxRuntimesResponse.worker:type_name -> substrate.ateapi.v1.Worker - 35, // 160: substrate.ateapi.v1.MintWorkerActorCertificateRequest.actor:type_name -> substrate.ateapi.v1.ObjectRef - 35, // 161: substrate.ateapi.v1.MintWorkerActorCertificateRequest.worker:type_name -> substrate.ateapi.v1.ObjectRef - 35, // 162: substrate.ateapi.v1.MintWorkerActorJwtRequest.actor:type_name -> substrate.ateapi.v1.ObjectRef - 155, // 163: substrate.ateapi.v1.MintWorkerActorJwtResponse.expire_time:type_name -> google.protobuf.Timestamp - 35, // 164: substrate.ateapi.v1.RequestActorSuspendRequest.worker:type_name -> substrate.ateapi.v1.ObjectRef - 35, // 165: substrate.ateapi.v1.RequestActorSuspendRequest.actor:type_name -> substrate.ateapi.v1.ObjectRef - 17, // 166: substrate.ateapi.v1.RequestActorSuspendResponse.actor:type_name -> substrate.ateapi.v1.Actor - 35, // 167: substrate.ateapi.v1.ReportActorCrashedRequest.worker:type_name -> substrate.ateapi.v1.ObjectRef - 35, // 168: substrate.ateapi.v1.ReportActorCrashedRequest.actor:type_name -> substrate.ateapi.v1.ObjectRef - 17, // 169: substrate.ateapi.v1.ReportActorCrashedResponse.actor:type_name -> substrate.ateapi.v1.Actor - 35, // 170: substrate.ateapi.v1.ReportActorSnapshotStateRequest.actor:type_name -> substrate.ateapi.v1.ObjectRef - 139, // 171: substrate.ateapi.v1.ReportActorSnapshotStateRequest.state:type_name -> substrate.ateapi.v1.ActorSnapshotState - 140, // 172: substrate.ateapi.v1.ActorSnapshotState.latest_local:type_name -> substrate.ateapi.v1.SnapshotReport - 140, // 173: substrate.ateapi.v1.ActorSnapshotState.uploading:type_name -> substrate.ateapi.v1.SnapshotReport - 140, // 174: substrate.ateapi.v1.ActorSnapshotState.latest_durable:type_name -> substrate.ateapi.v1.SnapshotReport - 155, // 175: substrate.ateapi.v1.ActorSnapshotState.upload_due_time:type_name -> google.protobuf.Timestamp - 2, // 176: substrate.ateapi.v1.SnapshotReport.fidelity:type_name -> substrate.ateapi.v1.SnapshotFidelity - 10, // 177: substrate.ateapi.v1.SnapshotReport.object:type_name -> substrate.ateapi.v1.ObjectSnapshot - 155, // 178: substrate.ateapi.v1.SnapshotReport.local_commit_time:type_name -> google.protobuf.Timestamp - 155, // 179: substrate.ateapi.v1.SnapshotReport.durable_complete_time:type_name -> google.protobuf.Timestamp - 14, // 180: substrate.ateapi.v1.AccessPolicy.metadata:type_name -> substrate.ateapi.v1.ResourceMetadata - 142, // 181: substrate.ateapi.v1.AccessPolicy.bindings:type_name -> substrate.ateapi.v1.Binding - 141, // 182: substrate.ateapi.v1.CreateGlobalAccessPolicyRequest.access_policy:type_name -> substrate.ateapi.v1.AccessPolicy - 141, // 183: substrate.ateapi.v1.UpdateGlobalAccessPolicyRequest.access_policy:type_name -> substrate.ateapi.v1.AccessPolicy - 35, // 184: substrate.ateapi.v1.GetAtespaceAccessPolicyRequest.atespace:type_name -> substrate.ateapi.v1.ObjectRef - 35, // 185: substrate.ateapi.v1.CreateAtespaceAccessPolicyRequest.atespace:type_name -> substrate.ateapi.v1.ObjectRef - 141, // 186: substrate.ateapi.v1.CreateAtespaceAccessPolicyRequest.access_policy:type_name -> substrate.ateapi.v1.AccessPolicy - 35, // 187: substrate.ateapi.v1.UpdateAtespaceAccessPolicyRequest.atespace:type_name -> substrate.ateapi.v1.ObjectRef - 141, // 188: substrate.ateapi.v1.UpdateAtespaceAccessPolicyRequest.access_policy:type_name -> substrate.ateapi.v1.AccessPolicy - 35, // 189: substrate.ateapi.v1.DeleteAtespaceAccessPolicyRequest.atespace:type_name -> substrate.ateapi.v1.ObjectRef - 95, // 190: substrate.ateapi.v1.DeleteAtespaceAccessPolicyRequest.options:type_name -> substrate.ateapi.v1.DeleteOptions - 9, // 191: substrate.ateapi.v1.ResourceAnnotation.scope:type_name -> substrate.ateapi.v1.Scope - 156, // 192: substrate.ateapi.v1.resource:extendee -> google.protobuf.MessageOptions - 157, // 193: substrate.ateapi.v1.method:extendee -> google.protobuf.MethodOptions - 150, // 194: substrate.ateapi.v1.resource:type_name -> substrate.ateapi.v1.ResourceAnnotation - 151, // 195: substrate.ateapi.v1.method:type_name -> substrate.ateapi.v1.MethodAnnotation - 70, // 196: substrate.ateapi.v1.Control.GetActor:input_type -> substrate.ateapi.v1.GetActorRequest - 71, // 197: substrate.ateapi.v1.Control.CreateActor:input_type -> substrate.ateapi.v1.CreateActorRequest - 72, // 198: substrate.ateapi.v1.Control.UpdateActor:input_type -> substrate.ateapi.v1.UpdateActorRequest - 73, // 199: substrate.ateapi.v1.Control.SuspendActor:input_type -> substrate.ateapi.v1.SuspendActorRequest - 76, // 200: substrate.ateapi.v1.Control.ResumeActor:input_type -> substrate.ateapi.v1.ResumeActorRequest - 78, // 201: substrate.ateapi.v1.Control.RevertActor:input_type -> substrate.ateapi.v1.RevertActorRequest - 80, // 202: substrate.ateapi.v1.Control.DeleteActor:input_type -> substrate.ateapi.v1.DeleteActorRequest - 81, // 203: substrate.ateapi.v1.Control.GetActorEgressPolicy:input_type -> substrate.ateapi.v1.GetActorEgressPolicyRequest - 82, // 204: substrate.ateapi.v1.Control.CreateActorEgressPolicy:input_type -> substrate.ateapi.v1.CreateActorEgressPolicyRequest - 83, // 205: substrate.ateapi.v1.Control.UpdateActorEgressPolicy:input_type -> substrate.ateapi.v1.UpdateActorEgressPolicyRequest - 84, // 206: substrate.ateapi.v1.Control.DeleteActorEgressPolicy:input_type -> substrate.ateapi.v1.DeleteActorEgressPolicyRequest - 86, // 207: substrate.ateapi.v1.Control.MintActorJwt:input_type -> substrate.ateapi.v1.MintActorJwtRequest - 88, // 208: substrate.ateapi.v1.Control.MintActorCertificate:input_type -> substrate.ateapi.v1.MintActorCertificateRequest - 92, // 209: substrate.ateapi.v1.Control.CreateTag:input_type -> substrate.ateapi.v1.CreateTagRequest - 85, // 210: substrate.ateapi.v1.Control.GetTag:input_type -> substrate.ateapi.v1.GetTagRequest - 90, // 211: substrate.ateapi.v1.Control.ListTags:input_type -> substrate.ateapi.v1.ListTagsRequest - 93, // 212: substrate.ateapi.v1.Control.UpdateTag:input_type -> substrate.ateapi.v1.UpdateTagRequest - 94, // 213: substrate.ateapi.v1.Control.DeleteTag:input_type -> substrate.ateapi.v1.DeleteTagRequest - 99, // 214: substrate.ateapi.v1.Control.ListWorkers:input_type -> substrate.ateapi.v1.ListWorkersRequest - 101, // 215: substrate.ateapi.v1.Control.GetWorker:input_type -> substrate.ateapi.v1.GetWorkerRequest - 102, // 216: substrate.ateapi.v1.Control.CreateWorker:input_type -> substrate.ateapi.v1.CreateWorkerRequest - 103, // 217: substrate.ateapi.v1.Control.UpdateWorker:input_type -> substrate.ateapi.v1.UpdateWorkerRequest - 104, // 218: substrate.ateapi.v1.Control.DeleteWorker:input_type -> substrate.ateapi.v1.DeleteWorkerRequest - 105, // 219: substrate.ateapi.v1.Control.DrainWorker:input_type -> substrate.ateapi.v1.DrainWorkerRequest - 107, // 220: substrate.ateapi.v1.Control.MarkWorkerAvailable:input_type -> substrate.ateapi.v1.MarkWorkerAvailableRequest - 109, // 221: substrate.ateapi.v1.Control.MarkWorkerUnavailable:input_type -> substrate.ateapi.v1.MarkWorkerUnavailableRequest - 97, // 222: substrate.ateapi.v1.Control.ListWorkerActorAssignments:input_type -> substrate.ateapi.v1.ListWorkerActorAssignmentsRequest - 111, // 223: substrate.ateapi.v1.Control.ListActors:input_type -> substrate.ateapi.v1.ListActorsRequest - 60, // 224: substrate.ateapi.v1.Control.CreateAtespace:input_type -> substrate.ateapi.v1.CreateAtespaceRequest - 61, // 225: substrate.ateapi.v1.Control.GetAtespace:input_type -> substrate.ateapi.v1.GetAtespaceRequest - 62, // 226: substrate.ateapi.v1.Control.ListAtespaces:input_type -> substrate.ateapi.v1.ListAtespacesRequest - 64, // 227: substrate.ateapi.v1.Control.DeleteAtespace:input_type -> substrate.ateapi.v1.DeleteAtespaceRequest - 65, // 228: substrate.ateapi.v1.Control.CreateActorTemplate:input_type -> substrate.ateapi.v1.CreateActorTemplateRequest - 66, // 229: substrate.ateapi.v1.Control.GetActorTemplate:input_type -> substrate.ateapi.v1.GetActorTemplateRequest - 67, // 230: substrate.ateapi.v1.Control.ListActorTemplates:input_type -> substrate.ateapi.v1.ListActorTemplatesRequest - 69, // 231: substrate.ateapi.v1.Control.DeleteActorTemplate:input_type -> substrate.ateapi.v1.DeleteActorTemplateRequest - 143, // 232: substrate.ateapi.v1.Control.GetGlobalAccessPolicy:input_type -> substrate.ateapi.v1.GetGlobalAccessPolicyRequest - 144, // 233: substrate.ateapi.v1.Control.CreateGlobalAccessPolicy:input_type -> substrate.ateapi.v1.CreateGlobalAccessPolicyRequest - 145, // 234: substrate.ateapi.v1.Control.UpdateGlobalAccessPolicy:input_type -> substrate.ateapi.v1.UpdateGlobalAccessPolicyRequest - 146, // 235: substrate.ateapi.v1.Control.GetAtespaceAccessPolicy:input_type -> substrate.ateapi.v1.GetAtespaceAccessPolicyRequest - 147, // 236: substrate.ateapi.v1.Control.CreateAtespaceAccessPolicy:input_type -> substrate.ateapi.v1.CreateAtespaceAccessPolicyRequest - 148, // 237: substrate.ateapi.v1.Control.UpdateAtespaceAccessPolicy:input_type -> substrate.ateapi.v1.UpdateAtespaceAccessPolicyRequest - 149, // 238: substrate.ateapi.v1.Control.DeleteAtespaceAccessPolicy:input_type -> substrate.ateapi.v1.DeleteAtespaceAccessPolicyRequest - 123, // 239: substrate.ateapi.v1.WorkerService.AcquireWorkerEpoch:input_type -> substrate.ateapi.v1.AcquireWorkerEpochRequest - 125, // 240: substrate.ateapi.v1.WorkerService.RegisterWorker:input_type -> substrate.ateapi.v1.RegisterWorkerRequest - 127, // 241: substrate.ateapi.v1.WorkerService.SetWorkerSandboxRuntimes:input_type -> substrate.ateapi.v1.SetWorkerSandboxRuntimesRequest - 129, // 242: substrate.ateapi.v1.WorkerService.MintWorkerActorCertificate:input_type -> substrate.ateapi.v1.MintWorkerActorCertificateRequest - 131, // 243: substrate.ateapi.v1.WorkerService.MintWorkerActorJwt:input_type -> substrate.ateapi.v1.MintWorkerActorJwtRequest - 133, // 244: substrate.ateapi.v1.WorkerService.RequestActorSuspend:input_type -> substrate.ateapi.v1.RequestActorSuspendRequest - 137, // 245: substrate.ateapi.v1.WorkerService.ReportActorSnapshotState:input_type -> substrate.ateapi.v1.ReportActorSnapshotStateRequest - 135, // 246: substrate.ateapi.v1.WorkerService.ReportActorCrashed:input_type -> substrate.ateapi.v1.ReportActorCrashedRequest - 17, // 247: substrate.ateapi.v1.Control.GetActor:output_type -> substrate.ateapi.v1.Actor - 17, // 248: substrate.ateapi.v1.Control.CreateActor:output_type -> substrate.ateapi.v1.Actor - 17, // 249: substrate.ateapi.v1.Control.UpdateActor:output_type -> substrate.ateapi.v1.Actor - 74, // 250: substrate.ateapi.v1.Control.SuspendActor:output_type -> substrate.ateapi.v1.SuspendActorResponse - 77, // 251: substrate.ateapi.v1.Control.ResumeActor:output_type -> substrate.ateapi.v1.ResumeActorResponse - 79, // 252: substrate.ateapi.v1.Control.RevertActor:output_type -> substrate.ateapi.v1.RevertActorResponse - 17, // 253: substrate.ateapi.v1.Control.DeleteActor:output_type -> substrate.ateapi.v1.Actor - 18, // 254: substrate.ateapi.v1.Control.GetActorEgressPolicy:output_type -> substrate.ateapi.v1.EgressPolicy - 18, // 255: substrate.ateapi.v1.Control.CreateActorEgressPolicy:output_type -> substrate.ateapi.v1.EgressPolicy - 18, // 256: substrate.ateapi.v1.Control.UpdateActorEgressPolicy:output_type -> substrate.ateapi.v1.EgressPolicy - 18, // 257: substrate.ateapi.v1.Control.DeleteActorEgressPolicy:output_type -> substrate.ateapi.v1.EgressPolicy - 87, // 258: substrate.ateapi.v1.Control.MintActorJwt:output_type -> substrate.ateapi.v1.MintActorJwtResponse - 89, // 259: substrate.ateapi.v1.Control.MintActorCertificate:output_type -> substrate.ateapi.v1.MintActorCertificateResponse - 33, // 260: substrate.ateapi.v1.Control.CreateTag:output_type -> substrate.ateapi.v1.Tag - 33, // 261: substrate.ateapi.v1.Control.GetTag:output_type -> substrate.ateapi.v1.Tag - 91, // 262: substrate.ateapi.v1.Control.ListTags:output_type -> substrate.ateapi.v1.ListTagsResponse - 33, // 263: substrate.ateapi.v1.Control.UpdateTag:output_type -> substrate.ateapi.v1.Tag - 33, // 264: substrate.ateapi.v1.Control.DeleteTag:output_type -> substrate.ateapi.v1.Tag - 100, // 265: substrate.ateapi.v1.Control.ListWorkers:output_type -> substrate.ateapi.v1.ListWorkersResponse - 113, // 266: substrate.ateapi.v1.Control.GetWorker:output_type -> substrate.ateapi.v1.Worker - 113, // 267: substrate.ateapi.v1.Control.CreateWorker:output_type -> substrate.ateapi.v1.Worker - 113, // 268: substrate.ateapi.v1.Control.UpdateWorker:output_type -> substrate.ateapi.v1.Worker - 113, // 269: substrate.ateapi.v1.Control.DeleteWorker:output_type -> substrate.ateapi.v1.Worker - 106, // 270: substrate.ateapi.v1.Control.DrainWorker:output_type -> substrate.ateapi.v1.DrainWorkerResponse - 108, // 271: substrate.ateapi.v1.Control.MarkWorkerAvailable:output_type -> substrate.ateapi.v1.MarkWorkerAvailableResponse - 110, // 272: substrate.ateapi.v1.Control.MarkWorkerUnavailable:output_type -> substrate.ateapi.v1.MarkWorkerUnavailableResponse - 98, // 273: substrate.ateapi.v1.Control.ListWorkerActorAssignments:output_type -> substrate.ateapi.v1.ListWorkerActorAssignmentsResponse - 112, // 274: substrate.ateapi.v1.Control.ListActors:output_type -> substrate.ateapi.v1.ListActorsResponse - 34, // 275: substrate.ateapi.v1.Control.CreateAtespace:output_type -> substrate.ateapi.v1.Atespace - 34, // 276: substrate.ateapi.v1.Control.GetAtespace:output_type -> substrate.ateapi.v1.Atespace - 63, // 277: substrate.ateapi.v1.Control.ListAtespaces:output_type -> substrate.ateapi.v1.ListAtespacesResponse - 34, // 278: substrate.ateapi.v1.Control.DeleteAtespace:output_type -> substrate.ateapi.v1.Atespace - 36, // 279: substrate.ateapi.v1.Control.CreateActorTemplate:output_type -> substrate.ateapi.v1.ActorTemplate - 36, // 280: substrate.ateapi.v1.Control.GetActorTemplate:output_type -> substrate.ateapi.v1.ActorTemplate - 68, // 281: substrate.ateapi.v1.Control.ListActorTemplates:output_type -> substrate.ateapi.v1.ListActorTemplatesResponse - 36, // 282: substrate.ateapi.v1.Control.DeleteActorTemplate:output_type -> substrate.ateapi.v1.ActorTemplate - 141, // 283: substrate.ateapi.v1.Control.GetGlobalAccessPolicy:output_type -> substrate.ateapi.v1.AccessPolicy - 141, // 284: substrate.ateapi.v1.Control.CreateGlobalAccessPolicy:output_type -> substrate.ateapi.v1.AccessPolicy - 141, // 285: substrate.ateapi.v1.Control.UpdateGlobalAccessPolicy:output_type -> substrate.ateapi.v1.AccessPolicy - 141, // 286: substrate.ateapi.v1.Control.GetAtespaceAccessPolicy:output_type -> substrate.ateapi.v1.AccessPolicy - 141, // 287: substrate.ateapi.v1.Control.CreateAtespaceAccessPolicy:output_type -> substrate.ateapi.v1.AccessPolicy - 141, // 288: substrate.ateapi.v1.Control.UpdateAtespaceAccessPolicy:output_type -> substrate.ateapi.v1.AccessPolicy - 141, // 289: substrate.ateapi.v1.Control.DeleteAtespaceAccessPolicy:output_type -> substrate.ateapi.v1.AccessPolicy - 124, // 290: substrate.ateapi.v1.WorkerService.AcquireWorkerEpoch:output_type -> substrate.ateapi.v1.AcquireWorkerEpochResponse - 126, // 291: substrate.ateapi.v1.WorkerService.RegisterWorker:output_type -> substrate.ateapi.v1.RegisterWorkerResponse - 128, // 292: substrate.ateapi.v1.WorkerService.SetWorkerSandboxRuntimes:output_type -> substrate.ateapi.v1.SetWorkerSandboxRuntimesResponse - 130, // 293: substrate.ateapi.v1.WorkerService.MintWorkerActorCertificate:output_type -> substrate.ateapi.v1.MintWorkerActorCertificateResponse - 132, // 294: substrate.ateapi.v1.WorkerService.MintWorkerActorJwt:output_type -> substrate.ateapi.v1.MintWorkerActorJwtResponse - 134, // 295: substrate.ateapi.v1.WorkerService.RequestActorSuspend:output_type -> substrate.ateapi.v1.RequestActorSuspendResponse - 138, // 296: substrate.ateapi.v1.WorkerService.ReportActorSnapshotState:output_type -> substrate.ateapi.v1.ReportActorSnapshotStateResponse - 136, // 297: substrate.ateapi.v1.WorkerService.ReportActorCrashed:output_type -> substrate.ateapi.v1.ReportActorCrashedResponse - 247, // [247:298] is the sub-list for method output_type - 196, // [196:247] is the sub-list for method input_type - 194, // [194:196] is the sub-list for extension type_name - 192, // [192:194] is the sub-list for extension extendee - 0, // [0:192] is the sub-list for field type_name + 153, // 111: substrate.ateapi.v1.MintActorJwtResponse.expire_time:type_name -> google.protobuf.Timestamp + 94, // 112: substrate.ateapi.v1.ListTagsRequest.options:type_name -> substrate.ateapi.v1.ListOptions + 33, // 113: substrate.ateapi.v1.ListTagsResponse.tags:type_name -> substrate.ateapi.v1.Tag + 33, // 114: substrate.ateapi.v1.CreateTagRequest.tag:type_name -> substrate.ateapi.v1.Tag + 33, // 115: substrate.ateapi.v1.UpdateTagRequest.tag:type_name -> substrate.ateapi.v1.Tag + 35, // 116: substrate.ateapi.v1.DeleteTagRequest.tag:type_name -> substrate.ateapi.v1.ObjectRef + 93, // 117: substrate.ateapi.v1.DeleteTagRequest.options:type_name -> substrate.ateapi.v1.DeleteOptions + 35, // 118: substrate.ateapi.v1.ListWorkerActorAssignmentsRequest.worker:type_name -> substrate.ateapi.v1.ObjectRef + 94, // 119: substrate.ateapi.v1.ListWorkerActorAssignmentsRequest.options:type_name -> substrate.ateapi.v1.ListOptions + 120, // 120: substrate.ateapi.v1.ListWorkerActorAssignmentsResponse.actor_assignments:type_name -> substrate.ateapi.v1.ActorAssignment + 94, // 121: substrate.ateapi.v1.ListWorkersRequest.options:type_name -> substrate.ateapi.v1.ListOptions + 111, // 122: substrate.ateapi.v1.ListWorkersResponse.workers:type_name -> substrate.ateapi.v1.Worker + 35, // 123: substrate.ateapi.v1.GetWorkerRequest.worker:type_name -> substrate.ateapi.v1.ObjectRef + 111, // 124: substrate.ateapi.v1.CreateWorkerRequest.worker:type_name -> substrate.ateapi.v1.Worker + 111, // 125: substrate.ateapi.v1.UpdateWorkerRequest.worker:type_name -> substrate.ateapi.v1.Worker + 35, // 126: substrate.ateapi.v1.DeleteWorkerRequest.worker:type_name -> substrate.ateapi.v1.ObjectRef + 93, // 127: substrate.ateapi.v1.DeleteWorkerRequest.options:type_name -> substrate.ateapi.v1.DeleteOptions + 35, // 128: substrate.ateapi.v1.DrainWorkerRequest.worker:type_name -> substrate.ateapi.v1.ObjectRef + 111, // 129: substrate.ateapi.v1.DrainWorkerResponse.worker:type_name -> substrate.ateapi.v1.Worker + 35, // 130: substrate.ateapi.v1.MarkWorkerAvailableRequest.worker:type_name -> substrate.ateapi.v1.ObjectRef + 111, // 131: substrate.ateapi.v1.MarkWorkerAvailableResponse.worker:type_name -> substrate.ateapi.v1.Worker + 35, // 132: substrate.ateapi.v1.MarkWorkerUnavailableRequest.worker:type_name -> substrate.ateapi.v1.ObjectRef + 111, // 133: substrate.ateapi.v1.MarkWorkerUnavailableResponse.worker:type_name -> substrate.ateapi.v1.Worker + 94, // 134: substrate.ateapi.v1.ListActorsRequest.options:type_name -> substrate.ateapi.v1.ListOptions + 17, // 135: substrate.ateapi.v1.ListActorsResponse.actors:type_name -> substrate.ateapi.v1.Actor + 14, // 136: substrate.ateapi.v1.Worker.metadata:type_name -> substrate.ateapi.v1.ResourceMetadata + 152, // 137: substrate.ateapi.v1.Worker.labels:type_name -> substrate.ateapi.v1.Worker.LabelsEntry + 112, // 138: substrate.ateapi.v1.Worker.status:type_name -> substrate.ateapi.v1.WorkerStatus + 8, // 139: substrate.ateapi.v1.WorkerStatus.state:type_name -> substrate.ateapi.v1.WorkerState + 119, // 140: substrate.ateapi.v1.WorkerStatus.capacity:type_name -> substrate.ateapi.v1.WorkerResources + 119, // 141: substrate.ateapi.v1.WorkerStatus.allocated:type_name -> substrate.ateapi.v1.WorkerResources + 113, // 142: substrate.ateapi.v1.WorkerStatus.sandbox_classes:type_name -> substrate.ateapi.v1.WorkerSandboxClass + 114, // 143: substrate.ateapi.v1.WorkerSandboxClass.default_runtime:type_name -> substrate.ateapi.v1.WorkerSandboxRuntime + 114, // 144: substrate.ateapi.v1.WorkerSandboxClass.restorable_runtimes:type_name -> substrate.ateapi.v1.WorkerSandboxRuntime + 117, // 145: substrate.ateapi.v1.WorkerSandboxRuntime.version:type_name -> substrate.ateapi.v1.VersionedSandboxCompat + 115, // 146: substrate.ateapi.v1.WorkerSandboxRuntime.actor_overhead:type_name -> substrate.ateapi.v1.RuntimeOverhead + 117, // 147: substrate.ateapi.v1.ActorSandboxRuntime.version:type_name -> substrate.ateapi.v1.VersionedSandboxCompat + 118, // 148: substrate.ateapi.v1.VersionedSandboxCompat.attributes:type_name -> substrate.ateapi.v1.AttributeEntry + 14, // 149: substrate.ateapi.v1.ActorAssignment.metadata:type_name -> substrate.ateapi.v1.ResourceMetadata + 35, // 150: substrate.ateapi.v1.ActorAssignment.actor:type_name -> substrate.ateapi.v1.ObjectRef + 38, // 151: substrate.ateapi.v1.ActorAssignment.resources:type_name -> substrate.ateapi.v1.Resources + 35, // 152: substrate.ateapi.v1.AcquireWorkerEpochRequest.worker:type_name -> substrate.ateapi.v1.ObjectRef + 35, // 153: substrate.ateapi.v1.RegisterWorkerRequest.worker:type_name -> substrate.ateapi.v1.ObjectRef + 119, // 154: substrate.ateapi.v1.RegisterWorkerRequest.capacity:type_name -> substrate.ateapi.v1.WorkerResources + 111, // 155: substrate.ateapi.v1.RegisterWorkerResponse.worker:type_name -> substrate.ateapi.v1.Worker + 35, // 156: substrate.ateapi.v1.SetWorkerSandboxRuntimesRequest.worker:type_name -> substrate.ateapi.v1.ObjectRef + 113, // 157: substrate.ateapi.v1.SetWorkerSandboxRuntimesRequest.sandbox_classes:type_name -> substrate.ateapi.v1.WorkerSandboxClass + 111, // 158: substrate.ateapi.v1.SetWorkerSandboxRuntimesResponse.worker:type_name -> substrate.ateapi.v1.Worker + 35, // 159: substrate.ateapi.v1.MintWorkerActorCertificateRequest.actor:type_name -> substrate.ateapi.v1.ObjectRef + 35, // 160: substrate.ateapi.v1.MintWorkerActorCertificateRequest.worker:type_name -> substrate.ateapi.v1.ObjectRef + 35, // 161: substrate.ateapi.v1.MintWorkerActorJwtRequest.actor:type_name -> substrate.ateapi.v1.ObjectRef + 153, // 162: substrate.ateapi.v1.MintWorkerActorJwtResponse.expire_time:type_name -> google.protobuf.Timestamp + 35, // 163: substrate.ateapi.v1.RequestActorSuspendRequest.worker:type_name -> substrate.ateapi.v1.ObjectRef + 35, // 164: substrate.ateapi.v1.RequestActorSuspendRequest.actor:type_name -> substrate.ateapi.v1.ObjectRef + 17, // 165: substrate.ateapi.v1.RequestActorSuspendResponse.actor:type_name -> substrate.ateapi.v1.Actor + 35, // 166: substrate.ateapi.v1.ReportActorCrashedRequest.worker:type_name -> substrate.ateapi.v1.ObjectRef + 35, // 167: substrate.ateapi.v1.ReportActorCrashedRequest.actor:type_name -> substrate.ateapi.v1.ObjectRef + 17, // 168: substrate.ateapi.v1.ReportActorCrashedResponse.actor:type_name -> substrate.ateapi.v1.Actor + 35, // 169: substrate.ateapi.v1.ReportActorSnapshotStateRequest.actor:type_name -> substrate.ateapi.v1.ObjectRef + 137, // 170: substrate.ateapi.v1.ReportActorSnapshotStateRequest.state:type_name -> substrate.ateapi.v1.ActorSnapshotState + 138, // 171: substrate.ateapi.v1.ActorSnapshotState.latest_local:type_name -> substrate.ateapi.v1.SnapshotReport + 138, // 172: substrate.ateapi.v1.ActorSnapshotState.uploading:type_name -> substrate.ateapi.v1.SnapshotReport + 138, // 173: substrate.ateapi.v1.ActorSnapshotState.latest_durable:type_name -> substrate.ateapi.v1.SnapshotReport + 153, // 174: substrate.ateapi.v1.ActorSnapshotState.upload_due_time:type_name -> google.protobuf.Timestamp + 2, // 175: substrate.ateapi.v1.SnapshotReport.fidelity:type_name -> substrate.ateapi.v1.SnapshotFidelity + 10, // 176: substrate.ateapi.v1.SnapshotReport.object:type_name -> substrate.ateapi.v1.ObjectSnapshot + 153, // 177: substrate.ateapi.v1.SnapshotReport.local_commit_time:type_name -> google.protobuf.Timestamp + 153, // 178: substrate.ateapi.v1.SnapshotReport.durable_complete_time:type_name -> google.protobuf.Timestamp + 14, // 179: substrate.ateapi.v1.AccessPolicy.metadata:type_name -> substrate.ateapi.v1.ResourceMetadata + 140, // 180: substrate.ateapi.v1.AccessPolicy.bindings:type_name -> substrate.ateapi.v1.Binding + 139, // 181: substrate.ateapi.v1.CreateGlobalAccessPolicyRequest.access_policy:type_name -> substrate.ateapi.v1.AccessPolicy + 139, // 182: substrate.ateapi.v1.UpdateGlobalAccessPolicyRequest.access_policy:type_name -> substrate.ateapi.v1.AccessPolicy + 35, // 183: substrate.ateapi.v1.GetAtespaceAccessPolicyRequest.atespace:type_name -> substrate.ateapi.v1.ObjectRef + 35, // 184: substrate.ateapi.v1.CreateAtespaceAccessPolicyRequest.atespace:type_name -> substrate.ateapi.v1.ObjectRef + 139, // 185: substrate.ateapi.v1.CreateAtespaceAccessPolicyRequest.access_policy:type_name -> substrate.ateapi.v1.AccessPolicy + 35, // 186: substrate.ateapi.v1.UpdateAtespaceAccessPolicyRequest.atespace:type_name -> substrate.ateapi.v1.ObjectRef + 139, // 187: substrate.ateapi.v1.UpdateAtespaceAccessPolicyRequest.access_policy:type_name -> substrate.ateapi.v1.AccessPolicy + 35, // 188: substrate.ateapi.v1.DeleteAtespaceAccessPolicyRequest.atespace:type_name -> substrate.ateapi.v1.ObjectRef + 93, // 189: substrate.ateapi.v1.DeleteAtespaceAccessPolicyRequest.options:type_name -> substrate.ateapi.v1.DeleteOptions + 9, // 190: substrate.ateapi.v1.ResourceAnnotation.scope:type_name -> substrate.ateapi.v1.Scope + 154, // 191: substrate.ateapi.v1.resource:extendee -> google.protobuf.MessageOptions + 155, // 192: substrate.ateapi.v1.method:extendee -> google.protobuf.MethodOptions + 148, // 193: substrate.ateapi.v1.resource:type_name -> substrate.ateapi.v1.ResourceAnnotation + 149, // 194: substrate.ateapi.v1.method:type_name -> substrate.ateapi.v1.MethodAnnotation + 70, // 195: substrate.ateapi.v1.Control.GetActor:input_type -> substrate.ateapi.v1.GetActorRequest + 71, // 196: substrate.ateapi.v1.Control.CreateActor:input_type -> substrate.ateapi.v1.CreateActorRequest + 72, // 197: substrate.ateapi.v1.Control.UpdateActor:input_type -> substrate.ateapi.v1.UpdateActorRequest + 73, // 198: substrate.ateapi.v1.Control.SuspendActor:input_type -> substrate.ateapi.v1.SuspendActorRequest + 76, // 199: substrate.ateapi.v1.Control.ResumeActor:input_type -> substrate.ateapi.v1.ResumeActorRequest + 78, // 200: substrate.ateapi.v1.Control.RevertActor:input_type -> substrate.ateapi.v1.RevertActorRequest + 80, // 201: substrate.ateapi.v1.Control.DeleteActor:input_type -> substrate.ateapi.v1.DeleteActorRequest + 81, // 202: substrate.ateapi.v1.Control.GetActorEgressPolicy:input_type -> substrate.ateapi.v1.GetActorEgressPolicyRequest + 82, // 203: substrate.ateapi.v1.Control.CreateActorEgressPolicy:input_type -> substrate.ateapi.v1.CreateActorEgressPolicyRequest + 83, // 204: substrate.ateapi.v1.Control.UpdateActorEgressPolicy:input_type -> substrate.ateapi.v1.UpdateActorEgressPolicyRequest + 84, // 205: substrate.ateapi.v1.Control.DeleteActorEgressPolicy:input_type -> substrate.ateapi.v1.DeleteActorEgressPolicyRequest + 86, // 206: substrate.ateapi.v1.Control.MintActorJwt:input_type -> substrate.ateapi.v1.MintActorJwtRequest + 90, // 207: substrate.ateapi.v1.Control.CreateTag:input_type -> substrate.ateapi.v1.CreateTagRequest + 85, // 208: substrate.ateapi.v1.Control.GetTag:input_type -> substrate.ateapi.v1.GetTagRequest + 88, // 209: substrate.ateapi.v1.Control.ListTags:input_type -> substrate.ateapi.v1.ListTagsRequest + 91, // 210: substrate.ateapi.v1.Control.UpdateTag:input_type -> substrate.ateapi.v1.UpdateTagRequest + 92, // 211: substrate.ateapi.v1.Control.DeleteTag:input_type -> substrate.ateapi.v1.DeleteTagRequest + 97, // 212: substrate.ateapi.v1.Control.ListWorkers:input_type -> substrate.ateapi.v1.ListWorkersRequest + 99, // 213: substrate.ateapi.v1.Control.GetWorker:input_type -> substrate.ateapi.v1.GetWorkerRequest + 100, // 214: substrate.ateapi.v1.Control.CreateWorker:input_type -> substrate.ateapi.v1.CreateWorkerRequest + 101, // 215: substrate.ateapi.v1.Control.UpdateWorker:input_type -> substrate.ateapi.v1.UpdateWorkerRequest + 102, // 216: substrate.ateapi.v1.Control.DeleteWorker:input_type -> substrate.ateapi.v1.DeleteWorkerRequest + 103, // 217: substrate.ateapi.v1.Control.DrainWorker:input_type -> substrate.ateapi.v1.DrainWorkerRequest + 105, // 218: substrate.ateapi.v1.Control.MarkWorkerAvailable:input_type -> substrate.ateapi.v1.MarkWorkerAvailableRequest + 107, // 219: substrate.ateapi.v1.Control.MarkWorkerUnavailable:input_type -> substrate.ateapi.v1.MarkWorkerUnavailableRequest + 95, // 220: substrate.ateapi.v1.Control.ListWorkerActorAssignments:input_type -> substrate.ateapi.v1.ListWorkerActorAssignmentsRequest + 109, // 221: substrate.ateapi.v1.Control.ListActors:input_type -> substrate.ateapi.v1.ListActorsRequest + 60, // 222: substrate.ateapi.v1.Control.CreateAtespace:input_type -> substrate.ateapi.v1.CreateAtespaceRequest + 61, // 223: substrate.ateapi.v1.Control.GetAtespace:input_type -> substrate.ateapi.v1.GetAtespaceRequest + 62, // 224: substrate.ateapi.v1.Control.ListAtespaces:input_type -> substrate.ateapi.v1.ListAtespacesRequest + 64, // 225: substrate.ateapi.v1.Control.DeleteAtespace:input_type -> substrate.ateapi.v1.DeleteAtespaceRequest + 65, // 226: substrate.ateapi.v1.Control.CreateActorTemplate:input_type -> substrate.ateapi.v1.CreateActorTemplateRequest + 66, // 227: substrate.ateapi.v1.Control.GetActorTemplate:input_type -> substrate.ateapi.v1.GetActorTemplateRequest + 67, // 228: substrate.ateapi.v1.Control.ListActorTemplates:input_type -> substrate.ateapi.v1.ListActorTemplatesRequest + 69, // 229: substrate.ateapi.v1.Control.DeleteActorTemplate:input_type -> substrate.ateapi.v1.DeleteActorTemplateRequest + 141, // 230: substrate.ateapi.v1.Control.GetGlobalAccessPolicy:input_type -> substrate.ateapi.v1.GetGlobalAccessPolicyRequest + 142, // 231: substrate.ateapi.v1.Control.CreateGlobalAccessPolicy:input_type -> substrate.ateapi.v1.CreateGlobalAccessPolicyRequest + 143, // 232: substrate.ateapi.v1.Control.UpdateGlobalAccessPolicy:input_type -> substrate.ateapi.v1.UpdateGlobalAccessPolicyRequest + 144, // 233: substrate.ateapi.v1.Control.GetAtespaceAccessPolicy:input_type -> substrate.ateapi.v1.GetAtespaceAccessPolicyRequest + 145, // 234: substrate.ateapi.v1.Control.CreateAtespaceAccessPolicy:input_type -> substrate.ateapi.v1.CreateAtespaceAccessPolicyRequest + 146, // 235: substrate.ateapi.v1.Control.UpdateAtespaceAccessPolicy:input_type -> substrate.ateapi.v1.UpdateAtespaceAccessPolicyRequest + 147, // 236: substrate.ateapi.v1.Control.DeleteAtespaceAccessPolicy:input_type -> substrate.ateapi.v1.DeleteAtespaceAccessPolicyRequest + 121, // 237: substrate.ateapi.v1.WorkerService.AcquireWorkerEpoch:input_type -> substrate.ateapi.v1.AcquireWorkerEpochRequest + 123, // 238: substrate.ateapi.v1.WorkerService.RegisterWorker:input_type -> substrate.ateapi.v1.RegisterWorkerRequest + 125, // 239: substrate.ateapi.v1.WorkerService.SetWorkerSandboxRuntimes:input_type -> substrate.ateapi.v1.SetWorkerSandboxRuntimesRequest + 127, // 240: substrate.ateapi.v1.WorkerService.MintWorkerActorCertificate:input_type -> substrate.ateapi.v1.MintWorkerActorCertificateRequest + 129, // 241: substrate.ateapi.v1.WorkerService.MintWorkerActorJwt:input_type -> substrate.ateapi.v1.MintWorkerActorJwtRequest + 131, // 242: substrate.ateapi.v1.WorkerService.RequestActorSuspend:input_type -> substrate.ateapi.v1.RequestActorSuspendRequest + 135, // 243: substrate.ateapi.v1.WorkerService.ReportActorSnapshotState:input_type -> substrate.ateapi.v1.ReportActorSnapshotStateRequest + 133, // 244: substrate.ateapi.v1.WorkerService.ReportActorCrashed:input_type -> substrate.ateapi.v1.ReportActorCrashedRequest + 17, // 245: substrate.ateapi.v1.Control.GetActor:output_type -> substrate.ateapi.v1.Actor + 17, // 246: substrate.ateapi.v1.Control.CreateActor:output_type -> substrate.ateapi.v1.Actor + 17, // 247: substrate.ateapi.v1.Control.UpdateActor:output_type -> substrate.ateapi.v1.Actor + 74, // 248: substrate.ateapi.v1.Control.SuspendActor:output_type -> substrate.ateapi.v1.SuspendActorResponse + 77, // 249: substrate.ateapi.v1.Control.ResumeActor:output_type -> substrate.ateapi.v1.ResumeActorResponse + 79, // 250: substrate.ateapi.v1.Control.RevertActor:output_type -> substrate.ateapi.v1.RevertActorResponse + 17, // 251: substrate.ateapi.v1.Control.DeleteActor:output_type -> substrate.ateapi.v1.Actor + 18, // 252: substrate.ateapi.v1.Control.GetActorEgressPolicy:output_type -> substrate.ateapi.v1.EgressPolicy + 18, // 253: substrate.ateapi.v1.Control.CreateActorEgressPolicy:output_type -> substrate.ateapi.v1.EgressPolicy + 18, // 254: substrate.ateapi.v1.Control.UpdateActorEgressPolicy:output_type -> substrate.ateapi.v1.EgressPolicy + 18, // 255: substrate.ateapi.v1.Control.DeleteActorEgressPolicy:output_type -> substrate.ateapi.v1.EgressPolicy + 87, // 256: substrate.ateapi.v1.Control.MintActorJwt:output_type -> substrate.ateapi.v1.MintActorJwtResponse + 33, // 257: substrate.ateapi.v1.Control.CreateTag:output_type -> substrate.ateapi.v1.Tag + 33, // 258: substrate.ateapi.v1.Control.GetTag:output_type -> substrate.ateapi.v1.Tag + 89, // 259: substrate.ateapi.v1.Control.ListTags:output_type -> substrate.ateapi.v1.ListTagsResponse + 33, // 260: substrate.ateapi.v1.Control.UpdateTag:output_type -> substrate.ateapi.v1.Tag + 33, // 261: substrate.ateapi.v1.Control.DeleteTag:output_type -> substrate.ateapi.v1.Tag + 98, // 262: substrate.ateapi.v1.Control.ListWorkers:output_type -> substrate.ateapi.v1.ListWorkersResponse + 111, // 263: substrate.ateapi.v1.Control.GetWorker:output_type -> substrate.ateapi.v1.Worker + 111, // 264: substrate.ateapi.v1.Control.CreateWorker:output_type -> substrate.ateapi.v1.Worker + 111, // 265: substrate.ateapi.v1.Control.UpdateWorker:output_type -> substrate.ateapi.v1.Worker + 111, // 266: substrate.ateapi.v1.Control.DeleteWorker:output_type -> substrate.ateapi.v1.Worker + 104, // 267: substrate.ateapi.v1.Control.DrainWorker:output_type -> substrate.ateapi.v1.DrainWorkerResponse + 106, // 268: substrate.ateapi.v1.Control.MarkWorkerAvailable:output_type -> substrate.ateapi.v1.MarkWorkerAvailableResponse + 108, // 269: substrate.ateapi.v1.Control.MarkWorkerUnavailable:output_type -> substrate.ateapi.v1.MarkWorkerUnavailableResponse + 96, // 270: substrate.ateapi.v1.Control.ListWorkerActorAssignments:output_type -> substrate.ateapi.v1.ListWorkerActorAssignmentsResponse + 110, // 271: substrate.ateapi.v1.Control.ListActors:output_type -> substrate.ateapi.v1.ListActorsResponse + 34, // 272: substrate.ateapi.v1.Control.CreateAtespace:output_type -> substrate.ateapi.v1.Atespace + 34, // 273: substrate.ateapi.v1.Control.GetAtespace:output_type -> substrate.ateapi.v1.Atespace + 63, // 274: substrate.ateapi.v1.Control.ListAtespaces:output_type -> substrate.ateapi.v1.ListAtespacesResponse + 34, // 275: substrate.ateapi.v1.Control.DeleteAtespace:output_type -> substrate.ateapi.v1.Atespace + 36, // 276: substrate.ateapi.v1.Control.CreateActorTemplate:output_type -> substrate.ateapi.v1.ActorTemplate + 36, // 277: substrate.ateapi.v1.Control.GetActorTemplate:output_type -> substrate.ateapi.v1.ActorTemplate + 68, // 278: substrate.ateapi.v1.Control.ListActorTemplates:output_type -> substrate.ateapi.v1.ListActorTemplatesResponse + 36, // 279: substrate.ateapi.v1.Control.DeleteActorTemplate:output_type -> substrate.ateapi.v1.ActorTemplate + 139, // 280: substrate.ateapi.v1.Control.GetGlobalAccessPolicy:output_type -> substrate.ateapi.v1.AccessPolicy + 139, // 281: substrate.ateapi.v1.Control.CreateGlobalAccessPolicy:output_type -> substrate.ateapi.v1.AccessPolicy + 139, // 282: substrate.ateapi.v1.Control.UpdateGlobalAccessPolicy:output_type -> substrate.ateapi.v1.AccessPolicy + 139, // 283: substrate.ateapi.v1.Control.GetAtespaceAccessPolicy:output_type -> substrate.ateapi.v1.AccessPolicy + 139, // 284: substrate.ateapi.v1.Control.CreateAtespaceAccessPolicy:output_type -> substrate.ateapi.v1.AccessPolicy + 139, // 285: substrate.ateapi.v1.Control.UpdateAtespaceAccessPolicy:output_type -> substrate.ateapi.v1.AccessPolicy + 139, // 286: substrate.ateapi.v1.Control.DeleteAtespaceAccessPolicy:output_type -> substrate.ateapi.v1.AccessPolicy + 122, // 287: substrate.ateapi.v1.WorkerService.AcquireWorkerEpoch:output_type -> substrate.ateapi.v1.AcquireWorkerEpochResponse + 124, // 288: substrate.ateapi.v1.WorkerService.RegisterWorker:output_type -> substrate.ateapi.v1.RegisterWorkerResponse + 126, // 289: substrate.ateapi.v1.WorkerService.SetWorkerSandboxRuntimes:output_type -> substrate.ateapi.v1.SetWorkerSandboxRuntimesResponse + 128, // 290: substrate.ateapi.v1.WorkerService.MintWorkerActorCertificate:output_type -> substrate.ateapi.v1.MintWorkerActorCertificateResponse + 130, // 291: substrate.ateapi.v1.WorkerService.MintWorkerActorJwt:output_type -> substrate.ateapi.v1.MintWorkerActorJwtResponse + 132, // 292: substrate.ateapi.v1.WorkerService.RequestActorSuspend:output_type -> substrate.ateapi.v1.RequestActorSuspendResponse + 136, // 293: substrate.ateapi.v1.WorkerService.ReportActorSnapshotState:output_type -> substrate.ateapi.v1.ReportActorSnapshotStateResponse + 134, // 294: substrate.ateapi.v1.WorkerService.ReportActorCrashed:output_type -> substrate.ateapi.v1.ReportActorCrashedResponse + 245, // [245:295] is the sub-list for method output_type + 195, // [195:245] is the sub-list for method input_type + 193, // [193:195] is the sub-list for extension type_name + 191, // [191:193] is the sub-list for extension extendee + 0, // [0:191] is the sub-list for field type_name } func init() { file_api_ateapi_v1_ateapi_proto_init() } @@ -11262,7 +11124,7 @@ func file_api_ateapi_v1_ateapi_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: unsafe.Slice(unsafe.StringData(file_api_ateapi_v1_ateapi_proto_rawDesc), len(file_api_ateapi_v1_ateapi_proto_rawDesc)), NumEnums: 10, - NumMessages: 145, + NumMessages: 143, NumExtensions: 2, NumServices: 2, }, diff --git a/api/ateapi/v1/ateapi.proto b/api/ateapi/v1/ateapi.proto index 7a59f6a098..d997c8d365 100644 --- a/api/ateapi/v1/ateapi.proto +++ b/api/ateapi/v1/ateapi.proto @@ -90,16 +90,6 @@ service Control { option (method).resource = "Actor"; } - // Create a Substrate-issued SPIFFE certificate asserting the actor identity. - // - // SPIFFE URI: spiffe://${trustdomain}/actor/${atespace}/${actor} - // - // * Called by the egress gateway when actor client certificate injection is - // configured for outbound requests. - rpc MintActorCertificate(MintActorCertificateRequest) returns (MintActorCertificateResponse) { - option (method).resource = "Actor"; - } - // Tag the external snapshot a suspended Actor holds. The tag gets its own // copy of that snapshot, so suspending or deleting the Actor afterwards // cannot collect it. When the Actor's latest snapshot is not uploaded yet, @@ -2013,39 +2003,6 @@ message MintActorJwtResponse { google.protobuf.Timestamp expire_time = 2; } -// Request message for MintActorCertificate. -message MintActorCertificateRequest { - // The actor for which the certificate should be issued. - // - // Must be a valid actor that currently exists according to the actor store. - // - // +k8s:required - ObjectRef actor = 1; - - // The UID of the actor --- used to guard against deletion and recreation of - // an actor with the same name. - // - // +k8s:required - // +k8s:format=k8s-uuid - string actor_uid = 2; - - // Request contains DER encoded bytes of a x509 certificate signing request. - // The signer will ignore the contents of the CSR except to extract the - // subject public key. - // - // +k8s:required - // +k8s:maxBytes=16384 - bytes certificate_signing_request = 3; -} - -// Response message for MintActorCertificate. -message MintActorCertificateResponse { - // Response contains a list of DER encoded certificates. The first entry is the - // leaf certificate, and any remaining entries are intermediates in - // leaf-to-root order. - repeated bytes actor_certificates = 1; -} - message ListTagsRequest { // The atespace to list tags from. Empty lists across all atespaces. // diff --git a/api/ateapi/v1/ateapi_grpc.pb.go b/api/ateapi/v1/ateapi_grpc.pb.go index 4c2cadb5d9..50f21cc0c4 100644 --- a/api/ateapi/v1/ateapi_grpc.pb.go +++ b/api/ateapi/v1/ateapi_grpc.pb.go @@ -45,7 +45,6 @@ const ( Control_UpdateActorEgressPolicy_FullMethodName = "/substrate.ateapi.v1.Control/UpdateActorEgressPolicy" Control_DeleteActorEgressPolicy_FullMethodName = "/substrate.ateapi.v1.Control/DeleteActorEgressPolicy" Control_MintActorJwt_FullMethodName = "/substrate.ateapi.v1.Control/MintActorJwt" - Control_MintActorCertificate_FullMethodName = "/substrate.ateapi.v1.Control/MintActorCertificate" Control_CreateTag_FullMethodName = "/substrate.ateapi.v1.Control/CreateTag" Control_GetTag_FullMethodName = "/substrate.ateapi.v1.Control/GetTag" Control_ListTags_FullMethodName = "/substrate.ateapi.v1.Control/ListTags" @@ -115,13 +114,6 @@ type ControlClient interface { // // * Called by the egress gateway when actor JWT injection is configured for outbound requests. MintActorJwt(ctx context.Context, in *MintActorJwtRequest, opts ...grpc.CallOption) (*MintActorJwtResponse, error) - // Create a Substrate-issued SPIFFE certificate asserting the actor identity. - // - // SPIFFE URI: spiffe://${trustdomain}/actor/${atespace}/${actor} - // - // * Called by the egress gateway when actor client certificate injection is - // configured for outbound requests. - MintActorCertificate(ctx context.Context, in *MintActorCertificateRequest, opts ...grpc.CallOption) (*MintActorCertificateResponse, error) // Tag the external snapshot a suspended Actor holds. The tag gets its own // copy of that snapshot, so suspending or deleting the Actor afterwards // cannot collect it. When the Actor's latest snapshot is not uploaded yet, @@ -333,16 +325,6 @@ func (c *controlClient) MintActorJwt(ctx context.Context, in *MintActorJwtReques return out, nil } -func (c *controlClient) MintActorCertificate(ctx context.Context, in *MintActorCertificateRequest, opts ...grpc.CallOption) (*MintActorCertificateResponse, error) { - cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) - out := new(MintActorCertificateResponse) - err := c.cc.Invoke(ctx, Control_MintActorCertificate_FullMethodName, in, out, cOpts...) - if err != nil { - return nil, err - } - return out, nil -} - func (c *controlClient) CreateTag(ctx context.Context, in *CreateTagRequest, opts ...grpc.CallOption) (*Tag, error) { cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) out := new(Tag) @@ -680,13 +662,6 @@ type ControlServer interface { // // * Called by the egress gateway when actor JWT injection is configured for outbound requests. MintActorJwt(context.Context, *MintActorJwtRequest) (*MintActorJwtResponse, error) - // Create a Substrate-issued SPIFFE certificate asserting the actor identity. - // - // SPIFFE URI: spiffe://${trustdomain}/actor/${atespace}/${actor} - // - // * Called by the egress gateway when actor client certificate injection is - // configured for outbound requests. - MintActorCertificate(context.Context, *MintActorCertificateRequest) (*MintActorCertificateResponse, error) // Tag the external snapshot a suspended Actor holds. The tag gets its own // copy of that snapshot, so suspending or deleting the Actor afterwards // cannot collect it. When the Actor's latest snapshot is not uploaded yet, @@ -814,9 +789,6 @@ func (UnimplementedControlServer) DeleteActorEgressPolicy(context.Context, *Dele func (UnimplementedControlServer) MintActorJwt(context.Context, *MintActorJwtRequest) (*MintActorJwtResponse, error) { return nil, status.Error(codes.Unimplemented, "method MintActorJwt not implemented") } -func (UnimplementedControlServer) MintActorCertificate(context.Context, *MintActorCertificateRequest) (*MintActorCertificateResponse, error) { - return nil, status.Error(codes.Unimplemented, "method MintActorCertificate not implemented") -} func (UnimplementedControlServer) CreateTag(context.Context, *CreateTagRequest) (*Tag, error) { return nil, status.Error(codes.Unimplemented, "method CreateTag not implemented") } @@ -1144,24 +1116,6 @@ func _Control_MintActorJwt_Handler(srv interface{}, ctx context.Context, dec fun return interceptor(ctx, in, info, handler) } -func _Control_MintActorCertificate_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(MintActorCertificateRequest) - if err := dec(in); err != nil { - return nil, err - } - if interceptor == nil { - return srv.(ControlServer).MintActorCertificate(ctx, in) - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: Control_MintActorCertificate_FullMethodName, - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(ControlServer).MintActorCertificate(ctx, req.(*MintActorCertificateRequest)) - } - return interceptor(ctx, in, info, handler) -} - func _Control_CreateTag_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(CreateTagRequest) if err := dec(in); err != nil { @@ -1757,10 +1711,6 @@ var Control_ServiceDesc = grpc.ServiceDesc{ MethodName: "MintActorJwt", Handler: _Control_MintActorJwt_Handler, }, - { - MethodName: "MintActorCertificate", - Handler: _Control_MintActorCertificate_Handler, - }, { MethodName: "CreateTag", Handler: _Control_CreateTag_Handler, diff --git a/charts/substrate/templates/atelet.yaml b/charts/substrate/templates/atelet.yaml index d5a846760d..5abad9d1c5 100644 --- a/charts/substrate/templates/atelet.yaml +++ b/charts/substrate/templates/atelet.yaml @@ -215,7 +215,10 @@ spec: drop: - ALL add: + - CHOWN - DAC_OVERRIDE + - FOWNER + - FSETID resources: {{ toYaml .Values.atelet.resources | indent 10 }} env: diff --git a/charts/substrate/tests/control_plane_test.yaml b/charts/substrate/tests/control_plane_test.yaml index 2f9955400f..de9b50b2fe 100644 --- a/charts/substrate/tests/control_plane_test.yaml +++ b/charts/substrate/tests/control_plane_test.yaml @@ -114,6 +114,21 @@ tests: key: cloud.google.com/compute-class operator: Exists effect: NoSchedule +- it: lets atelet preserve image ownership and permissions + template: atelet.yaml + documentSelector: + path: kind + value: DaemonSet + asserts: + - equal: + path: spec.template.spec.containers[0].securityContext + value: + allowPrivilegeEscalation: false + runAsUser: 0 + runAsGroup: 0 + capabilities: + drop: [ALL] + add: [CHOWN, DAC_OVERRIDE, FOWNER, FSETID] - it: probes the credential provider on its health listener template: k8s-credential-provider.yaml documentSelector: diff --git a/cmd/ate-setup/internal/ko/ko.go b/cmd/ate-setup/internal/ko/ko.go index 139fa6bd63..c2b719c5c3 100644 --- a/cmd/ate-setup/internal/ko/ko.go +++ b/cmd/ate-setup/internal/ko/ko.go @@ -33,6 +33,9 @@ import ( "strings" "time" + "k8s.io/apimachinery/pkg/util/wait" + "k8s.io/client-go/util/retry" + "go.ate.dev/substrate/cmd/ate-setup/internal/log" ) @@ -162,6 +165,37 @@ func (r *Runner) BuildTagged(ctx context.Context, tag string, labels []string, i return refs, nil } +// buildBackoff paces the retries of an image that fails to build or push: 3 +// attempts, 10s then 20s apart. ghcr.io can briefly deny pushes to a package it +// has just created. +var buildBackoff = wait.Backoff{Steps: 3, Duration: 10 * time.Second, Factor: 2} + +// BuildEach runs BuildTagged once per import path, retrying each failure per +// buildBackoff. It returns the refs in importPaths order. +func (r *Runner) BuildEach(ctx context.Context, tag string, labels []string, importPaths ...string) ([]string, error) { + refs := make([]string, 0, len(importPaths)) + for _, path := range importPaths { + var ref string + logAndRetry := func(err error) bool { + log.Warnf("%s: %v", path, err) + return true + } + err := retry.OnError(buildBackoff, logAndRetry, func() error { + built, err := r.BuildTagged(ctx, tag, labels, path) + if err != nil { + return err + } + ref = built[0] + return nil + }) + if err != nil { + return nil, err + } + refs = append(refs, ref) + } + return refs, nil +} + // ResolveBytes resolves an in-memory manifest, such as kustomize output. func (r *Runner) ResolveBytes(ctx context.Context, manifest []byte) ([]byte, error) { return r.Resolve(ctx, "-", manifest) diff --git a/cmd/ate-setup/internal/ko/ko_test.go b/cmd/ate-setup/internal/ko/ko_test.go index 8c5377a60b..415676b4be 100644 --- a/cmd/ate-setup/internal/ko/ko_test.go +++ b/cmd/ate-setup/internal/ko/ko_test.go @@ -15,12 +15,17 @@ package ko import ( + "errors" "os" "os/exec" "path/filepath" "slices" + "strconv" "strings" "testing" + "time" + + "k8s.io/apimachinery/pkg/util/wait" ) // Without --base-import-paths ko publishes cmd/atelet as "atelet-", and @@ -174,3 +179,80 @@ func TestBuildTaggedRejectsMissingRefs(t *testing.T) { t.Error("BuildTagged() error = nil, want one for 1 ref from 2 packages") } } + +// flakyKo writes a ko stand-in that fails the first failures builds of each +// package, printing stderr, then prints a ref for it. It returns the +// directory where it counts builds per package. +func flakyKo(t *testing.T, failures int, stderr string) (binary, dir string) { + t.Helper() + dir = t.TempDir() + binary = filepath.Join(dir, "ko") + script := "#!/bin/sh\n" + + "pkg=$(basename \"$2\")\n" + + "echo run >> " + dir + "/runs-$pkg\n" + + "if [ $(wc -l < " + dir + "/runs-$pkg) -le " + strconv.Itoa(failures) + " ]; then echo '" + stderr + "' >&2; exit 1; fi\n" + + "echo repo/$pkg:v1@sha256:a\n" + if err := os.WriteFile(binary, []byte(script), 0o755); err != nil { + t.Fatal(err) + } + return binary, dir +} + +// koRuns returns how many times flakyKo built pkg. +func koRuns(t *testing.T, dir, pkg string) int { + t.Helper() + raw, err := os.ReadFile(filepath.Join(dir, "runs-"+pkg)) + if errors.Is(err, os.ErrNotExist) { + return 0 + } + if err != nil { + t.Fatal(err) + } + return strings.Count(string(raw), "run") +} + +// fastBackoff shortens buildBackoff for the test. +func fastBackoff(t *testing.T) { + t.Helper() + original := buildBackoff + buildBackoff = wait.Backoff{Steps: original.Steps, Duration: time.Millisecond, Factor: 1} + t.Cleanup(func() { buildBackoff = original }) +} + +const deniedStderr = "PATCH https://ghcr.io/v2/agent-substrate/substrate/ateapi/blobs/upload/1: DENIED: permission_denied: write_package" + +func TestBuildEachRetriesEachImage(t *testing.T) { + fastBackoff(t) + binary, dir := flakyKo(t, 2, deniedStderr) + r := &Runner{Root: t.TempDir(), binary: binary} + + refs, err := r.BuildEach(t.Context(), "v1", nil, "./cmd/ateapi", "./cmd/atelet") + if err != nil { + t.Fatalf("BuildEach() error = %v", err) + } + if want := []string{"repo/ateapi:v1@sha256:a", "repo/atelet:v1@sha256:a"}; !slices.Equal(refs, want) { + t.Errorf("BuildEach() = %q, want %q", refs, want) + } + for _, pkg := range []string{"ateapi", "atelet"} { + if got := koRuns(t, dir, pkg); got != 3 { + t.Errorf("ko built %s %d times, want 3", pkg, got) + } + } +} + +func TestBuildEachStopsAfterAttempts(t *testing.T) { + fastBackoff(t) + binary, dir := flakyKo(t, 100, deniedStderr) + r := &Runner{Root: t.TempDir(), binary: binary} + + _, err := r.BuildEach(t.Context(), "v1", nil, "./cmd/ateapi", "./cmd/atelet") + if err == nil { + t.Error("BuildEach() error = nil, want one after 3 failed attempts") + } + if got := koRuns(t, dir, "ateapi"); got != 3 { + t.Errorf("ko built ateapi %d times, want 3", got) + } + if got := koRuns(t, dir, "atelet"); got != 0 { + t.Errorf("ko built atelet %d times, want 0", got) + } +} diff --git a/cmd/ate-setup/internal/steps/publish.go b/cmd/ate-setup/internal/steps/publish.go index f98326e733..cbeac86ad0 100644 --- a/cmd/ate-setup/internal/steps/publish.go +++ b/cmd/ate-setup/internal/steps/publish.go @@ -254,7 +254,7 @@ func (e *Env) PublishReleaseImages(ctx context.Context, w io.Writer, opts Publis } refs = append(refs, ref) } - koRefs, err := runner.BuildTagged(ctx, tag, labels, pkgs...) + koRefs, err := runner.BuildEach(ctx, tag, labels, pkgs...) if err != nil { return err } diff --git a/cmd/ateapi/internal/apivalidation/actor.go b/cmd/ateapi/internal/apivalidation/actor.go index 138e4f5e4a..81cb30fc7f 100644 --- a/cmd/ateapi/internal/apivalidation/actor.go +++ b/cmd/ateapi/internal/apivalidation/actor.go @@ -82,12 +82,6 @@ func ValidateMintActorJWTRequest(ctx context.Context, req *ateapi.MintActorJwtRe return Validate_MintActorJwtRequest(ctx, op, nil, req, nil) } -func ValidateMintActorCertificateRequest(ctx context.Context, req *ateapi.MintActorCertificateRequest) field.ErrorList { - // Call the generated validation. - op := MakeCreateOp(ctx) - return Validate_MintActorCertificateRequest(ctx, op, nil, req, nil) -} - func ValidateMintWorkerActorCertificateRequest(ctx context.Context, req *ateapi.MintWorkerActorCertificateRequest) field.ErrorList { op := MakeCreateOp(ctx) return Validate_MintWorkerActorCertificateRequest(ctx, op, nil, req, nil) diff --git a/cmd/ateapi/internal/apivalidation/actor_test.go b/cmd/ateapi/internal/apivalidation/actor_test.go index 272ba567cc..750439ec1e 100644 --- a/cmd/ateapi/internal/apivalidation/actor_test.go +++ b/cmd/ateapi/internal/apivalidation/actor_test.go @@ -1032,49 +1032,6 @@ func TestValidateSuspendActorRequest(t *testing.T) { } } -func TestValidateMintActorCertificateRequest(t *testing.T) { - validUID := "3b9f1e77-2c4d-4a80-91be-6d5c8f0a7e21" - tests := []struct { - name string - req *ateapi.MintActorCertificateRequest - want field.ErrorList - }{{ - "valid", - &ateapi.MintActorCertificateRequest{ - Actor: &ateapi.ObjectRef{Atespace: "ns1", Name: "id1"}, - ActorUid: validUID, - CertificateSigningRequest: []byte("csr"), - }, - nil, - }, { - "missing actor", - &ateapi.MintActorCertificateRequest{ - ActorUid: validUID, - CertificateSigningRequest: []byte("csr"), - }, - field.ErrorList{field.Required(field.NewPath("actor"), "")}, - }, { - "missing actor_uid", - &ateapi.MintActorCertificateRequest{ - Actor: &ateapi.ObjectRef{Atespace: "ns1", Name: "id1"}, - CertificateSigningRequest: []byte("csr"), - }, - field.ErrorList{field.Required(field.NewPath("actor_uid"), "")}, - }, { - "missing csr", - &ateapi.MintActorCertificateRequest{ - Actor: &ateapi.ObjectRef{Atespace: "ns1", Name: "id1"}, - ActorUid: validUID, - }, - field.ErrorList{field.Required(field.NewPath("certificate_signing_request"), "")}, - }} - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - assertValidateErr(t, ValidateMintActorCertificateRequest(context.Background(), tt.req), tt.want) - }) - } -} - // validActor returns a minimal Actor which should pass input validation. func validActor(mods ...func(*ateapi.Actor)) *ateapi.Actor { a := &ateapi.Actor{ diff --git a/cmd/ateapi/internal/apivalidation/zz_generated.validation.go b/cmd/ateapi/internal/apivalidation/zz_generated.validation.go index bfe1672f01..9d177ca23f 100644 --- a/cmd/ateapi/internal/apivalidation/zz_generated.validation.go +++ b/cmd/ateapi/internal/apivalidation/zz_generated.validation.go @@ -5878,110 +5878,6 @@ func Validate_MarkWorkerUnavailableRequest( return errs } -// Validate_MintActorCertificateRequest validates an instance of MintActorCertificateRequest according -// to declarative validation rules in the API schema. -func Validate_MintActorCertificateRequest( - ctx context.Context, op operation.Operation, fldPath *field.Path, - obj, oldObj *v1.MintActorCertificateRequest) (errs field.ErrorList) { - - { // field v1.MintActorCertificateRequest.Actor - fn := func( - fldPath *field.Path, - obj, oldObj *v1.ObjectRef, - oldValueCorrelated bool) (errs field.ErrorList) { - // don't revalidate unchanged data - if oldValueCorrelated && op.Type == operation.Update { - if ateDeepEqual(obj, oldObj) { - return nil - } - } - // call field-attached validations - earlyReturn := false - if e := validate.RequiredPointer(ctx, op, fldPath, obj, oldObj).MarkShortCircuit(); len(e) != 0 { - errs = append(errs, e...) - earlyReturn = true - } - if earlyReturn { - return // do not proceed - } - // call the type's validation function - errs = append(errs, Validate_ObjectRef(ctx, op, fldPath, obj, oldObj)...) - return - } - oldVal := safe.Field(oldObj, - func(oldObj *v1.MintActorCertificateRequest) *v1.ObjectRef { - return oldObj.Actor - }) - errs = append(errs, fn(fldPath.Child("actor"), obj.Actor, oldVal, oldObj != nil)...) - } - - { // field v1.MintActorCertificateRequest.ActorUid - fn := func( - fldPath *field.Path, - obj, oldObj *string, - oldValueCorrelated bool) (errs field.ErrorList) { - // don't revalidate unchanged data - if oldValueCorrelated && op.Type == operation.Update { - if obj == oldObj || (obj != nil && oldObj != nil && *obj == *oldObj) { - return nil - } - } - // call field-attached validations - earlyReturn := false - if e := validate.RequiredValue(ctx, op, fldPath, obj, oldObj).MarkShortCircuit(); len(e) != 0 { - errs = append(errs, e...) - earlyReturn = true - } - if earlyReturn { - return // do not proceed - } - if e := validate.UUID(ctx, op, fldPath, obj, oldObj); len(e) != 0 { - errs = append(errs, e...) - } - return - } - oldVal := safe.Field(oldObj, - func(oldObj *v1.MintActorCertificateRequest) *string { - return &oldObj.ActorUid - }) - errs = append(errs, fn(fldPath.Child("actor_uid"), &obj.ActorUid, oldVal, oldObj != nil)...) - } - - { // field v1.MintActorCertificateRequest.CertificateSigningRequest - fn := func( - fldPath *field.Path, - obj, oldObj []byte, - oldValueCorrelated bool) (errs field.ErrorList) { - // don't revalidate unchanged data - if oldValueCorrelated && op.Type == operation.Update { - if ateDeepEqual(obj, oldObj) { - return nil - } - } - // call field-attached validations - earlyReturn := false - if e := validate.RequiredSlice(ctx, op, fldPath, obj, oldObj).MarkShortCircuit(); len(e) != 0 { - errs = append(errs, e...) - earlyReturn = true - } - if earlyReturn { - return // do not proceed - } - if e := validate.MaxBytesSlice(ctx, op, fldPath, obj, oldObj, 16384); len(e) != 0 { - errs = append(errs, e...) - } - return - } - oldVal := safe.Field(oldObj, - func(oldObj *v1.MintActorCertificateRequest) []byte { - return oldObj.CertificateSigningRequest - }) - errs = append(errs, fn(fldPath.Child("certificate_signing_request"), obj.CertificateSigningRequest, oldVal, oldObj != nil)...) - } - - return errs -} - // Validate_MintActorJwtRequest validates an instance of MintActorJwtRequest according // to declarative validation rules in the API schema. func Validate_MintActorJwtRequest( diff --git a/cmd/ateapi/internal/authz/authz_util.go b/cmd/ateapi/internal/authz/authz_util.go index 1e1734d6cd..45b52375c5 100644 --- a/cmd/ateapi/internal/authz/authz_util.go +++ b/cmd/ateapi/internal/authz/authz_util.go @@ -79,7 +79,6 @@ const ( RelationCanListTags = "can_list_tags" RelationCanUseTag = "can_use_tag" RelationCanMintActorJWT = "can_mint_actor_jwt" - RelationCanMintActorCertificate = "can_mint_actor_certificate" // maxTuplesPerWrite is OpenFGA's default maximum number of tuples allowed in a single Write request. maxTuplesPerWrite = 100 diff --git a/cmd/ateapi/internal/authz/interceptor_test.go b/cmd/ateapi/internal/authz/interceptor_test.go index b20bd6a7a6..ea6d6dece8 100644 --- a/cmd/ateapi/internal/authz/interceptor_test.go +++ b/cmd/ateapi/internal/authz/interceptor_test.go @@ -484,7 +484,6 @@ func TestUnaryServerInterceptor_LifecycleEgressWorkerAndTagChecks(t *testing.T) }}} deleteTag := rpcCall{ateapi.Control_DeleteTag_FullMethodName, &ateapi.DeleteTagRequest{Tag: tag}} mintJWT := rpcCall{ateapi.Control_MintActorJwt_FullMethodName, &ateapi.MintActorJwtRequest{Actor: actor}} - mintCert := rpcCall{ateapi.Control_MintActorCertificate_FullMethodName, &ateapi.MintActorCertificateRequest{Actor: actor}} // cloneTag creates an actor in atespace from team-a's tag v1, with a // template in that same atespace so only the tag check can differ. cloneTag := func(atespace string, sourceTag *ateapi.ObjectRef) rpcCall { @@ -586,7 +585,7 @@ func TestUnaryServerInterceptor_LifecycleEgressWorkerAndTagChecks(t *testing.T) // Only the egress gateway mints actor credentials; not even owners. {"editor cannot mint actor JWT", "editor", mintJWT, codes.PermissionDenied}, {"global owner cannot mint actor JWT", "global-owner", mintJWT, codes.PermissionDenied}, - {"bootstrap owner cannot mint actor certificate", "bootstrap-owner", mintCert, codes.PermissionDenied}, + {"bootstrap owner cannot mint actor JWT", "bootstrap-owner", mintJWT, codes.PermissionDenied}, } interceptor := UnaryServerInterceptor(authorizer) @@ -661,7 +660,6 @@ func TestUnaryServerInterceptor_SystemPrincipals(t *testing.T) { markUnavailable := rpcCall{ateapi.Control_MarkWorkerUnavailable_FullMethodName, &ateapi.MarkWorkerUnavailableRequest{Worker: worker}} listAssignments := rpcCall{ateapi.Control_ListWorkerActorAssignments_FullMethodName, &ateapi.ListWorkerActorAssignmentsRequest{Worker: worker}} mintJWT := rpcCall{ateapi.Control_MintActorJwt_FullMethodName, &ateapi.MintActorJwtRequest{Actor: actor}} - mintCert := rpcCall{ateapi.Control_MintActorCertificate_FullMethodName, &ateapi.MintActorCertificateRequest{Actor: actor}} mtls := func(id string) principal.PrincipalInfo { return principal.PrincipalInfo{ID: id, Kind: principal.KindMTLS} @@ -699,7 +697,6 @@ func TestUnaryServerInterceptor_SystemPrincipals(t *testing.T) { {"egress gateway lists actors", mtls(egressID), listAllActors, codes.OK}, {"egress gateway cannot get worker", mtls(egressID), getWorker, codes.PermissionDenied}, {"egress gateway mints actor JWT", mtls(egressID), mintJWT, codes.OK}, - {"egress gateway mints actor certificate", mtls(egressID), mintCert, codes.OK}, // atenet-router resumes actors. Both it and atenet-egress list actors // as their ateapi health check. @@ -711,7 +708,7 @@ func TestUnaryServerInterceptor_SystemPrincipals(t *testing.T) { {"ingress router cannot get egress policy", mtls(routerID), getEgress, codes.PermissionDenied}, {"ingress router cannot create worker", mtls(routerID), createWorker, codes.PermissionDenied}, {"ingress router cannot mint actor JWT", mtls(routerID), mintJWT, codes.PermissionDenied}, - {"controller cannot mint actor certificate", mtls(controllerID), mintCert, codes.PermissionDenied}, + {"controller cannot mint actor JWT", mtls(controllerID), mintJWT, codes.PermissionDenied}, // atelet reads egress policies for the worker that enforces them, and // nothing else. diff --git a/cmd/ateapi/internal/authz/model.fga b/cmd/ateapi/internal/authz/model.fga index 1d42a82e3e..5f71197ffe 100644 --- a/cmd/ateapi/internal/authz/model.fga +++ b/cmd/ateapi/internal/authz/model.fga @@ -169,7 +169,6 @@ type actor # Credentials asserting the actor's own identity. Only the egress gateway # mints them; an editor holding one could impersonate the actor. define can_mint_actor_jwt: egress_gateway from parent_atespace - define can_mint_actor_certificate: egress_gateway from parent_atespace # Data Plane Ingress: Routers (or editors) can resume define can_resume: [user] or editor from parent_atespace or ingress_router from parent_atespace diff --git a/cmd/ateapi/internal/authz/model_test.fga.yaml b/cmd/ateapi/internal/authz/model_test.fga.yaml index 02741ca1db..3962a8072b 100644 --- a/cmd/ateapi/internal/authz/model_test.fga.yaml +++ b/cmd/ateapi/internal/authz/model_test.fga.yaml @@ -401,7 +401,6 @@ tests: can_get: true can_get_egress_policy: true can_mint_actor_jwt: true - can_mint_actor_certificate: true can_update: false can_delete: false can_create_egress_policy: false @@ -430,7 +429,6 @@ tests: can_update_egress_policy: false can_delete_egress_policy: false can_mint_actor_jwt: false - can_mint_actor_certificate: false can_resume: false can_suspend: false - user: user:sys-atelet @@ -456,7 +454,6 @@ tests: can_resume: false can_suspend: false can_mint_actor_jwt: false - can_mint_actor_certificate: false - user: user:sys-api-server-sidecar object: atespace:space-1 assertions: @@ -567,14 +564,11 @@ tests: object: actor:runner-1 assertions: can_mint_actor_jwt: false - can_mint_actor_certificate: false - user: user:bob # Atespace editor object: actor:runner-1 assertions: can_mint_actor_jwt: false - can_mint_actor_certificate: false - user: user:sys-router object: actor:runner-1 assertions: can_mint_actor_jwt: false - can_mint_actor_certificate: false diff --git a/cmd/ateapi/internal/authz/registry.go b/cmd/ateapi/internal/authz/registry.go index 741e716bbd..951a27480b 100644 --- a/cmd/ateapi/internal/authz/registry.go +++ b/cmd/ateapi/internal/authz/registry.go @@ -298,9 +298,6 @@ var defaultRPCPermissions = map[string]rpcRule{ ateapi.Control_MintActorJwt_FullMethodName: rule(checksOf(func(r *ateapi.MintActorJwtRequest) ([]check, field.ErrorList) { return onActor(RelationCanMintActorJWT, r.GetActor(), field.NewPath("actor")) })), - ateapi.Control_MintActorCertificate_FullMethodName: rule(checksOf(func(r *ateapi.MintActorCertificateRequest) ([]check, field.ErrorList) { - return onActor(RelationCanMintActorCertificate, r.GetActor(), field.NewPath("actor")) - })), // Tags. CreateTag stores the tag in its source actor's atespace, so that is // the atespace checked. Validation also requires metadata.atespace to diff --git a/cmd/ateapi/internal/authz/registry_test.go b/cmd/ateapi/internal/authz/registry_test.go index 57d2b6bc77..51ada93341 100644 --- a/cmd/ateapi/internal/authz/registry_test.go +++ b/cmd/ateapi/internal/authz/registry_test.go @@ -281,12 +281,6 @@ func TestDefaultRPCPermissions(t *testing.T) { req: &ateapi.MintActorJwtRequest{Actor: actorRef}, want: []check{{RelationCanMintActorJWT, "actor:team-a/runner"}}, }, - { - name: "MintActorCertificate", - fullMethod: ateapi.Control_MintActorCertificate_FullMethodName, - req: &ateapi.MintActorCertificateRequest{Actor: actorRef}, - want: []check{{RelationCanMintActorCertificate, "actor:team-a/runner"}}, - }, // Tags. { @@ -603,12 +597,6 @@ func TestDefaultRPCPermissions_MalformedIdentifierFailsClosed(t *testing.T) { req: &ateapi.MintActorJwtRequest{}, wantField: "actor.atespace", }, - { - name: "MintActorCertificate with an invalid name", - fullMethod: ateapi.Control_MintActorCertificate_FullMethodName, - req: &ateapi.MintActorCertificateRequest{Actor: &ateapi.ObjectRef{Atespace: "team-a", Name: "a/b"}}, - wantField: "actor.name", - }, { name: "CreateTag without a source actor", fullMethod: ateapi.Control_CreateTag_FullMethodName, diff --git a/cmd/ateapi/internal/controlapi/access_policy_test.go b/cmd/ateapi/internal/controlapi/access_policy_test.go index b612ce8ab3..a76facb096 100644 --- a/cmd/ateapi/internal/controlapi/access_policy_test.go +++ b/cmd/ateapi/internal/controlapi/access_policy_test.go @@ -48,7 +48,7 @@ func TestAccessPolicy_GlobalAndAtespaceGovernance(t *testing.T) { } persistence.SetPolicyManager(policyManager) - svc := NewRPCService(persistence, nil, nil, nil, nil, nil, "", 0, nil, nil, "", nil, nil, "") + svc := NewRPCService(persistence, nil, nil, nil, nil, nil, "", 0, nil, nil, "", nil, "") interceptor := authz.UnaryServerInterceptor(authorizer) userCtx := func(id string) context.Context { diff --git a/cmd/ateapi/internal/controlapi/actor.go b/cmd/ateapi/internal/controlapi/actor.go index bd092788e0..8cac775de9 100644 --- a/cmd/ateapi/internal/controlapi/actor.go +++ b/cmd/ateapi/internal/controlapi/actor.go @@ -17,11 +17,8 @@ package controlapi import ( "context" "crypto/rand" - "crypto/x509" "errors" "fmt" - "log/slog" - "net/url" "slices" "time" @@ -34,10 +31,7 @@ import ( "go.ate.dev/substrate/internal/ateattr" "go.ate.dev/substrate/internal/preview" "go.ate.dev/substrate/internal/resources" - "go.ate.dev/substrate/internal/substratex509" "go.opentelemetry.io/otel/attribute" - "google.golang.org/grpc/credentials" - "google.golang.org/grpc/peer" "google.golang.org/protobuf/proto" "google.golang.org/protobuf/types/known/timestamppb" "k8s.io/apimachinery/pkg/util/validation/field" @@ -608,87 +602,3 @@ func (s *RPCService) MintActorJwt(ctx context.Context, req *ateapi.MintActorJwtR ExpireTime: timestamppb.New(expiresAt), }, nil } - -func (s *RPCService) MintActorCertificate(ctx context.Context, req *ateapi.MintActorCertificateRequest) (*ateapi.MintActorCertificateResponse, error) { - if errs := apivalidation.ValidateMintActorCertificateRequest(ctx, req); len(errs) > 0 { - return nil, resources.ToAPIError(errs) - } - - // With authz enforced, the interceptor requires can_mint_actor_certificate - // on the actor, which only the egress gateway holds. - - // Check that the caller authenticated with a client certificate --- we - // should not allow bootstrapping a proof-of-possession credential from a - // bearer credential. Note, we don't care that it was a certificate issued - // by Substrate, or something else. - // - // TODO(authz): Perhaps this can be handled with an OpenFGA condition. - p, ok := peer.FromContext(ctx) - if !ok { - return nil, apierror.Unauthenticated("no peer transport information found") - } - tlsInfo, ok := p.AuthInfo.(credentials.TLSInfo) - if !ok { - return nil, apierror.Unauthenticated("unexpected peer transport credentials") - } - if len(tlsInfo.State.PeerCertificates) == 0 { - return nil, apierror.Unauthenticated("could not verify peer certificate") - } - - // Verify that this actor exists in the store. It doesn't need to be - // running, since we may need to issue certificates during actor boot / resume. - dbActor, err := s.impl.GetActor(ctx, resources.ActorRefFromObjectRef(req.GetActor())) - if errors.Is(err, store.ErrNotFound) { - return nil, apierror.NotFound("actor not found") - } else if err != nil { - return nil, fmt.Errorf("while retrieving actor: %w", err) - } - if dbActor.GetMetadata().GetUid() != req.GetActorUid() { - return nil, apierror.Aborted("conflict; actor has been deleted and recreated") - } - - // Parse the CSR - csr, err := x509.ParseCertificateRequest(req.GetCertificateSigningRequest()) - if err != nil { - return nil, fmt.Errorf("while parsing CSR: %w", err) - } - if err := csr.CheckSignature(); err != nil { - slog.ErrorContext(ctx, "Failed to verify CSR signature", slog.Any("err", err)) - return nil, apierror.InvalidArgument("Failed to verify CSR signature") - } - - template := &x509.Certificate{ - URIs: []*url.URL{resources.ActorSPIFFEID(resources.ActorRef{ - Atespace: dbActor.GetMetadata().GetAtespace(), - Name: dbActor.GetMetadata().GetName(), - })}, - NotBefore: time.Now().Add(-5 * time.Minute), - NotAfter: time.Now().Add(time.Hour), - KeyUsage: x509.KeyUsageDigitalSignature, - ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageClientAuth, x509.ExtKeyUsageServerAuth}, - BasicConstraintsValid: true, - IsCA: false, - } - - err = substratex509.AddActorIdentityToCertificate( - &substratex509.ActorIdentity{ - Atespace: dbActor.GetMetadata().GetAtespace(), - ActorName: dbActor.GetMetadata().GetName(), - ActorUid: dbActor.GetMetadata().GetUid(), - }, - template, - ) - if err != nil { - return nil, fmt.Errorf("while adding Substrate extension: %w", err) - } - - // Sign and return the actor cert. - chain, err := s.actorIDCAPool.CreateCertificate(template, csr.PublicKey) - if err != nil { - return nil, fmt.Errorf("while signing certificate: %w", err) - } - - return &ateapi.MintActorCertificateResponse{ - ActorCertificates: chain, - }, nil -} diff --git a/cmd/ateapi/internal/controlapi/actor_test.go b/cmd/ateapi/internal/controlapi/actor_test.go index f1c3b5fd96..1c8ea23255 100644 --- a/cmd/ateapi/internal/controlapi/actor_test.go +++ b/cmd/ateapi/internal/controlapi/actor_test.go @@ -16,16 +16,10 @@ package controlapi import ( "context" - "crypto/ecdsa" - "crypto/elliptic" - "crypto/rand" - "crypto/tls" - "crypto/x509" "errors" "fmt" "strings" "testing" - "time" "github.com/google/go-cmp/cmp" "go.ate.dev/substrate/api/ateapi/v1" @@ -34,13 +28,9 @@ import ( "go.ate.dev/substrate/cmd/ateapi/internal/store/storetest" "go.ate.dev/substrate/internal/apierror" "go.ate.dev/substrate/internal/ateattr" - "go.ate.dev/substrate/internal/localca" "go.ate.dev/substrate/internal/preview" "go.ate.dev/substrate/internal/resources" - "go.ate.dev/substrate/internal/substratex509" "google.golang.org/grpc/codes" - "google.golang.org/grpc/credentials" - "google.golang.org/grpc/peer" "google.golang.org/protobuf/proto" "google.golang.org/protobuf/testing/protocmp" "google.golang.org/protobuf/types/known/timestamppb" @@ -1069,101 +1059,3 @@ func TestCreateActor_GoldenTagDefault(t *testing.T) { }) } } - -type fakeActorServiceStore struct { - serviceStore - actors map[resources.ActorRef]*ateapi.Actor -} - -func (f *fakeActorServiceStore) GetActor(_ context.Context, actorRef resources.ActorRef) (*ateapi.Actor, error) { - a, ok := f.actors[actorRef] - if !ok { - return nil, store.ErrNotFound - } - return a, nil -} - -func TestMintActorCertificate(t *testing.T) { - ctx := peer.NewContext(context.Background(), &peer.Peer{ - AuthInfo: credentials.TLSInfo{ - State: tls.ConnectionState{ - PeerCertificates: []*x509.Certificate{{}}, - }, - }, - }) - - actorUID := "3b9f1e77-2c4d-4a80-91be-6d5c8f0a7e21" - created := &ateapi.Actor{ - Metadata: &ateapi.ResourceMetadata{Atespace: testAtespace, Name: testActorID, Uid: actorUID}, - ActorTemplate: &ateapi.ObjectRef{Atespace: testAtespace, Name: "tmpl-1"}, - Status: &ateapi.ActorStatus{State: ateapi.ActorState_ACTOR_STATE_RUNNING}, - } - fakeStore := &fakeActorServiceStore{ - actors: map[resources.ActorRef]*ateapi.Actor{ - {Atespace: testAtespace, Name: testActorID}: created, - }, - } - - ca, err := localca.GenerateCA("1", localca.KeyTypeECDSAP256, 24*time.Hour) - if err != nil { - t.Fatalf("GenerateCA: %v", err) - } - caPool := &localca.ConcretePool{ - CAs: []*localca.CA{ca}, - ActiveForSigning: "1", - } - - svc := &RPCService{ - impl: fakeStore, - actorIDCAPool: caPool, - } - - key, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader) - if err != nil { - t.Fatalf("GenerateKey: %v", err) - } - csr, err := x509.CreateCertificateRequest(rand.Reader, &x509.CertificateRequest{}, key) - if err != nil { - t.Fatalf("CreateCertificateRequest: %v", err) - } - - resp, err := svc.MintActorCertificate(ctx, &ateapi.MintActorCertificateRequest{ - Actor: &ateapi.ObjectRef{Atespace: testAtespace, Name: testActorID}, - ActorUid: created.GetMetadata().GetUid(), - CertificateSigningRequest: csr, - }) - if err != nil { - t.Fatalf("MintActorCertificate() failed: %v", err) - } - - chain := resp.GetActorCertificates() - if len(chain) == 0 { - t.Fatal("MintActorCertificate() returned empty chain") - } - - leaf, err := x509.ParseCertificate(chain[0]) - if err != nil { - t.Fatalf("ParseCertificate: %v", err) - } - if !key.PublicKey.Equal(leaf.PublicKey) { - t.Error("leaf public key does not match CSR key") - } - - wantURI := fmt.Sprintf("spiffe://substrate-actor.local/actor/%s/%s", testAtespace, testActorID) - if len(leaf.URIs) != 1 || leaf.URIs[0].String() != wantURI { - t.Errorf("leaf URIs = %v, want [%s]", leaf.URIs, wantURI) - } - - identity, err := substratex509.ActorIdentityFromCertificate(leaf) - if err != nil { - t.Fatalf("ActorIdentityFromCertificate: %v", err) - } - wantIdentity := &substratex509.ActorIdentity{ - Atespace: testAtespace, - ActorName: testActorID, - ActorUid: created.GetMetadata().GetUid(), - } - if diff := cmp.Diff(wantIdentity, identity); diff != "" { - t.Errorf("ActorIdentity mismatch (-want +got):\n%s", diff) - } -} diff --git a/cmd/ateapi/internal/controlapi/functionaltest/common_test.go b/cmd/ateapi/internal/controlapi/functionaltest/common_test.go index e628c0145e..7a34330bcb 100644 --- a/cmd/ateapi/internal/controlapi/functionaltest/common_test.go +++ b/cmd/ateapi/internal/controlapi/functionaltest/common_test.go @@ -30,7 +30,6 @@ import ( "go.ate.dev/substrate/cmd/ateapi/internal/workercache" "go.ate.dev/substrate/internal/ateinterceptors" "go.ate.dev/substrate/internal/installdefaults" - "go.ate.dev/substrate/internal/localca" "go.ate.dev/substrate/internal/localjwtauthority" "go.ate.dev/substrate/internal/objectstore/objectstoretest" "go.ate.dev/substrate/internal/objectstoreplugin/objectstoreplugintest" @@ -217,18 +216,6 @@ func setupTestWithOptions(t *testing.T, ns string, options testOptions) *testCon ActiveForSigning: "1", } - actorCA, err := localca.GenerateCA("1", localca.KeyTypeECDSAP256, 365*24*time.Hour) - if err != nil { - t.Fatalf("Error generating actor CA: %v", err) - } - - actorCAPool := &localca.ConcretePool{ - CAs: []*localca.CA{ - actorCA, - }, - ActiveForSigning: "1", - } - objectStore := objectstoretest.New() service := controlapi.NewRPCService( @@ -244,7 +231,6 @@ func setupTestWithOptions(t *testing.T, ns string, options testOptions) *testCon objectstoreplugintest.ControlClient(objectStore), testActorJWTIssuer, actorJWTAuthorityPool, - actorCAPool, testStorageLocation, ) diff --git a/cmd/ateapi/internal/controlapi/service.go b/cmd/ateapi/internal/controlapi/service.go index 65a2fc9d53..9144beaa93 100644 --- a/cmd/ateapi/internal/controlapi/service.go +++ b/cmd/ateapi/internal/controlapi/service.go @@ -23,7 +23,6 @@ import ( "go.ate.dev/substrate/api/objectstore/v1" "go.ate.dev/substrate/cmd/ateapi/internal/store" "go.ate.dev/substrate/cmd/ateapi/internal/workercache" - "go.ate.dev/substrate/internal/localca" "go.ate.dev/substrate/internal/localjwtauthority" "go.ate.dev/substrate/internal/resources" "go.ate.dev/substrate/internal/volume" @@ -53,7 +52,6 @@ type RPCService struct { actorJWTIssuer string actorIDJWTPool localjwtauthority.Pool - actorIDCAPool localca.Pool } var _ ateapi.ControlServer = (*RPCService)(nil) @@ -90,7 +88,6 @@ func NewRPCService( objectStorePlugin objectstore.ControlProviderClient, actorJWTIssuer string, actorIDJWTPool localjwtauthority.Pool, - actorIDCAPool localca.Pool, snapshotLocation string, ) *RPCService { impl := newServiceImpl(persistence, storageClassLister) @@ -106,7 +103,6 @@ func NewRPCService( objectStorePlugin: objectStorePlugin, actorJWTIssuer: actorJWTIssuer, actorIDJWTPool: actorIDJWTPool, - actorIDCAPool: actorIDCAPool, } s.actorWorkflow = NewActorWorkflow(impl, workerCache, dialer, storageClassLister, instruments, egressGatewayAddress, s, actorWorkflowDeadline, objectStorePlugin) s.actorWorkflow.clusterSnapshotLocation = snapshotLocation diff --git a/cmd/ateapi/main.go b/cmd/ateapi/main.go index 2bf57909b2..acc4fa1e82 100644 --- a/cmd/ateapi/main.go +++ b/cmd/ateapi/main.go @@ -363,7 +363,6 @@ func main() { objectstore.NewControlProviderClient(objectStorePluginConn), *actorJWTIssuer, actorIDJWTAuthorityPool, - actorIDCAPool, *snapshotLocation, ) diff --git a/cmd/atelet/imagevolume_test.go b/cmd/atelet/imagevolume_test.go index 387688a823..c5a2bd17cb 100644 --- a/cmd/atelet/imagevolume_test.go +++ b/cmd/atelet/imagevolume_test.go @@ -75,11 +75,26 @@ func singleFileLayer(t *testing.T, path, body string) v1.Layer { // pushTestImage pushes the image and returns its digest-pinned reference, // which is what validated workload specs carry. func pushTestImage(t *testing.T, ref string, layers ...v1.Layer) string { + t.Helper() + return pushTestImageWithConfig(t, ref, v1.Config{}, layers...) +} + +// pushTestImageWithConfig is pushTestImage with the image config set. +func pushTestImageWithConfig(t *testing.T, ref string, cfg v1.Config, layers ...v1.Layer) string { t.Helper() img, err := mutate.AppendLayers(empty.Image, layers...) if err != nil { t.Fatalf("mutate.AppendLayers: %v", err) } + cf, err := img.ConfigFile() + if err != nil { + t.Fatalf("img.ConfigFile: %v", err) + } + cf = cf.DeepCopy() + cf.Config = cfg + if img, err = mutate.ConfigFile(img, cf); err != nil { + t.Fatalf("mutate.ConfigFile: %v", err) + } tag, err := name.ParseReference(ref, name.Insecure) if err != nil { t.Fatalf("name.ParseReference(%q): %v", ref, err) diff --git a/cmd/atelet/main.go b/cmd/atelet/main.go index 1987f2bae9..0f822093e5 100644 --- a/cmd/atelet/main.go +++ b/cmd/atelet/main.go @@ -236,7 +236,10 @@ func main() { }() } - startDevicePlugins(ctx) + // stopped on SIGTERM because the replacement pod starts while we drain and + // registers the same socket, and kubelet can wedge the resource when two + // registrations for one socket overlap + startDevicePlugins(shutdownCtx) workerDialer := newWorkerDialer(256) @@ -2278,19 +2281,25 @@ func (s *Atelet) prepareOCIBundles( envs = append(envs, fmt.Sprintf("%s=%s", env.GetName(), env.GetValue())) } g.Go(func() error { - imageConfig, err := prepareOCIDirectory(gCtx, s.imageCache, actorUID, ctr.GetName(), ctr.GetImage(), spec.GetVolumes(), ctr.GetVolumeMounts()) + img, cwd, err := prepareOCIDirectory(gCtx, s.imageCache, actorUID, ctr.GetName(), ctr.GetImage(), spec.GetVolumes(), ctr.GetVolumeMounts()) if err != nil { return wrapFileSystemErr(fmt.Sprintf("while creating %q OCI bundle", ctr.GetName()), err) } - args, err := resolveProcessArgs(imageConfig, ctr.GetCommand(), ctr.GetArgs()) + args, err := resolveProcessArgs(&img.Config, ctr.GetCommand(), ctr.GetArgs()) if err != nil { return fmt.Errorf("while resolving process args for container %q: %w", ctr.GetName(), err) } + user, err := resolveImageUser(img) + if err != nil { + return fmt.Errorf("while resolving user for container %q: %w", ctr.GetName(), err) + } containerSpecs[i] = &ateworkerpb.ContainerSpec{ Args: args, - Env: resolveActorEnv(imageConfig, envs), + Env: resolveActorEnv(&img.Config, envs), Capabilities: resolveCapabilities(ctr.GetSecurityContext().GetCapabilities()), Resources: toAteworkerResources(ctr.GetResources()), + User: user, + Cwd: cwd, } return nil }) diff --git a/cmd/atelet/main_test.go b/cmd/atelet/main_test.go index d3daf4e277..162d1fba5b 100644 --- a/cmd/atelet/main_test.go +++ b/cmd/atelet/main_test.go @@ -34,6 +34,7 @@ import ( "time" "github.com/google/go-cmp/cmp" + v1 "github.com/google/go-containerregistry/pkg/v1" "github.com/spf13/pflag" "go.ate.dev/substrate/cmd/atelet/internal/actordirs" "go.ate.dev/substrate/cmd/atelet/internal/ateletpath" @@ -42,6 +43,7 @@ import ( "go.ate.dev/substrate/internal/ateattr" "go.ate.dev/substrate/internal/ateinterceptors" "go.ate.dev/substrate/internal/atelet" + "go.ate.dev/substrate/internal/imagecache" "go.ate.dev/substrate/internal/proto/ateletpb" "go.ate.dev/substrate/internal/proto/ateworkerpb" "go.ate.dev/substrate/internal/resources" @@ -265,12 +267,69 @@ func TestPrepareOCIBundlesFillsContainerSpec(t *testing.T) { Env: []string{"GREETING=hello", "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"}, Capabilities: []string{"CAP_AUDIT_WRITE", "CAP_NET_ADMIN", "CAP_NET_BIND_SERVICE"}, Resources: &ateworkerpb.ResourceRequirements{Limits: &ateworkerpb.Resources{MemoryBytes: 1 << 30, CpuMillicores: 500}}, + Cwd: "/", }} if diff := cmp.Diff(want, got, protocmp.Transform()); diff != "" { t.Errorf("prepareOCIBundles container specs mismatch (-want +got):\n%s", diff) } } +// TestPrepareOCIBundlesResolvesUsers pins that a container runs as its image's +// USER, resolved against the image's own passwd and group files; a USER the +// image cannot resolve fails the run. +func TestPrepareOCIBundlesResolvesUsers(t *testing.T) { + useTempNodeDirs(t) + host := imageVolumeTestRegistry(t) + etc := []v1.Layer{ + singleFileLayer(t, "etc/passwd", "root:x:0:0:root:/root:/bin/sh\nnonroot:x:65532:65532::/home/nonroot:/sbin/nologin\n"), + singleFileLayer(t, "etc/group", "root:x:0:\nnonroot:x:65532:\nvideo:x:44:nonroot\n"), + } + app := pushTestImageWithConfig(t, host+"/app:v1", v1.Config{User: "nonroot", Cmd: []string{"/bin/app"}}, etc...) + s := &Atelet{imageCache: newImageVolumeStore(t)} + + spec := &ateletpb.WorkloadSpec{Containers: []*ateletpb.Container{{Name: "app", Image: app}}} + got, err := s.prepareOCIBundles(t.Context(), "actor-uid-1", resources.ActorRef{}, spec) + if err != nil { + t.Fatalf("prepareOCIBundles: %v", err) + } + want := &ateworkerpb.ProcessUser{Uid: 65532, Gid: 65532, AdditionalGids: []uint32{44}} + if diff := cmp.Diff(want, got[0].GetUser(), protocmp.Transform()); diff != "" { + t.Errorf("app user mismatch (-want +got):\n%s", diff) + } + + unresolvable := pushTestImageWithConfig(t, host+"/nobody:v1", v1.Config{User: "nobody", Cmd: []string{"/bin/app"}}) + spec = &ateletpb.WorkloadSpec{Containers: []*ateletpb.Container{{Name: "app", Image: unresolvable}}} + if _, err := s.prepareOCIBundles(t.Context(), "actor-uid-2", resources.ActorRef{}, spec); err == nil { + t.Error("prepareOCIBundles succeeded with a USER the image has no passwd entry for, want an error") + } +} + +// TestPrepareOCIBundlesStartsInTheImageWorkdir pins that a container starts in +// its image's WORKDIR, created through the overlay when the image lacks it. +func TestPrepareOCIBundlesStartsInTheImageWorkdir(t *testing.T) { + useTempNodeDirs(t) + host := imageVolumeTestRegistry(t) + image := pushTestImageWithConfig(t, host+"/app:v1", v1.Config{Cmd: []string{"/bin/app"}, WorkingDir: "/home/nonroot"}) + spec := &ateletpb.WorkloadSpec{Containers: []*ateletpb.Container{{Name: "app", Image: image}}} + + const actorUID = "actor-uid-1" + s := &Atelet{imageCache: newImageVolumeStore(t)} + got, err := s.prepareOCIBundles(t.Context(), actorUID, resources.ActorRef{}, spec) + if err != nil { + t.Fatalf("prepareOCIBundles: %v", err) + } + if cwd := got[0].GetCwd(); cwd != "/home/nonroot" { + t.Errorf("Cwd = %q, want /home/nonroot", cwd) + } + overlay, err := imagecache.ReadSpec(ateletpath.OCIBundlePath(actorUID, "app")) + if err != nil { + t.Fatalf("imagecache.ReadSpec: %v", err) + } + if !slices.Contains(overlay.ExtraDirs, "/home/nonroot") { + t.Errorf("ExtraDirs = %v, want the working directory", overlay.ExtraDirs) + } +} + func TestSnapshotManifestRejectsNonLocalFile(t *testing.T) { manifest, err := json.Marshal(sandboxAssetsRecord{ SandboxClass: "gvisor", diff --git a/cmd/atelet/oci.go b/cmd/atelet/oci.go index 3f72633d5b..1cf5a1a9ca 100644 --- a/cmd/atelet/oci.go +++ b/cmd/atelet/oci.go @@ -15,17 +15,23 @@ package main import ( + "bytes" "context" + "errors" "fmt" + "io" + "io/fs" "os" "path" "sort" "strings" v1 "github.com/google/go-containerregistry/pkg/v1" + "github.com/moby/sys/user" "go.ate.dev/substrate/cmd/atelet/internal/ateletpath" "go.ate.dev/substrate/internal/imagecache" "go.ate.dev/substrate/internal/proto/ateletpb" + "go.ate.dev/substrate/internal/proto/ateworkerpb" "go.opentelemetry.io/otel" "go.opentelemetry.io/otel/attribute" "golang.org/x/sync/errgroup" @@ -74,7 +80,10 @@ func resolveCapabilities(caps *ateletpb.Capabilities) []string { return out } -func prepareOCIDirectory(ctx context.Context, imageCache *imagecache.Store, actorUID, containerName, ref string, volumes []*ateletpb.Volume, volumeMounts []*ateletpb.VolumeMount) (*v1.Config, error) { +// prepareOCIDirectory pulls the container's image and writes the overlay spec +// the worker composes its rootfs from. It returns the image and the process's +// working directory, which the worker creates through the overlay. +func prepareOCIDirectory(ctx context.Context, imageCache *imagecache.Store, actorUID, containerName, ref string, volumes []*ateletpb.Volume, volumeMounts []*ateletpb.VolumeMount) (*imagecache.Image, string, error) { tracer := otel.Tracer("prepareOCIDirectory") ctx, span := tracer.Start(ctx, "prepareOCIDirectory") @@ -87,18 +96,18 @@ func prepareOCIDirectory(ctx context.Context, imageCache *imagecache.Store, acto // actordirs.ResetActorDirs already wiped the bundle dir on the Run/Restore // path). if err := imagecache.RemoveAllWritable(bundlePath); err != nil { - return nil, fmt.Errorf("while clearing bundle %q: %w", bundlePath, err) + return nil, "", fmt.Errorf("while clearing bundle %q: %w", bundlePath, err) } // The bundle's rootfs is composed by worker as an overlay mount just before // the workload runs: the cached image layers are the read-only lowerdirs, // and the bundle-local upper/work hold this actor's private writes (wiped // between runs, preserving the pristine-rootfs-per-run contract the old - // full re-untar provided). atelet only prepares the (empty) directories — - // it deliberately runs with no capabilities, so it cannot mount. + // full re-untar provided). atelet only prepares the (empty) directories: + // it has no CAP_SYS_ADMIN, so it cannot mount. for _, d := range []string{"rootfs", "upper", "work"} { if err := os.MkdirAll(path.Join(bundlePath, d), 0o700); err != nil { - return nil, fmt.Errorf("in os.MkdirAll for container bundle dir: %w", err) + return nil, "", fmt.Errorf("in os.MkdirAll for container bundle dir: %w", err) } } @@ -120,26 +129,45 @@ func prepareOCIDirectory(ctx context.Context, imageCache *imagecache.Store, acto return err }) if err := g.Wait(); err != nil { - return nil, err + return nil, "", err + } + cwd, err := resolveCwd(&img.Config) + if err != nil { + return nil, "", fmt.Errorf("while resolving the working directory of container %q: %w", containerName, err) } - // Every bind target must exist in the rootfs for the mount to attach; - // worker creates them through the mounted overlay (they land in the - // actor's upper). + // Every bind target must exist in the rootfs for the mount to attach, and + // the working directory for the process to start; worker creates them + // through the mounted overlay (they land in the actor's upper). var extraDirs []string for _, vm := range volumeMounts { extraDirs = append(extraDirs, vm.GetMountPath()) } + if cwd != "/" { + extraDirs = append(extraDirs, cwd) + } if err := imagecache.WriteSpec(bundlePath, &imagecache.OverlaySpec{ ImageDigest: img.Digest.String(), Layers: img.LayerDirs, ExtraDirs: extraDirs, ImageVolumes: imageVolumes, }); err != nil { - return nil, fmt.Errorf("while writing overlay spec: %w", err) + return nil, "", fmt.Errorf("while writing overlay spec: %w", err) } - return &img.Config, nil + return img, cwd, nil +} + +// resolveCwd reads the image's WORKDIR; none means "/". The OCI spec requires +// an absolute path. +func resolveCwd(imageCfg *v1.Config) (string, error) { + if imageCfg == nil || imageCfg.WorkingDir == "" { + return "/", nil + } + if !path.IsAbs(imageCfg.WorkingDir) { + return "", fmt.Errorf("image WorkingDir %q is not absolute", imageCfg.WorkingDir) + } + return path.Clean(imageCfg.WorkingDir), nil } // resolveImageVolumes pulls the image behind every image-typed volume this @@ -241,3 +269,52 @@ func resolveProcessArgs(imageCfg *v1.Config, command, args []string) ([]string, } return argv, nil } + +// resolveImageUser resolves the image's USER against the image's own +// /etc/passwd and /etc/group, either of which may be absent. No USER is root, +// reported as nil. +func resolveImageUser(img *imagecache.Image) (*ateworkerpb.ProcessUser, error) { + if img.Config.User == "" { + return nil, nil + } + passwd, err := readOptionalImageFile(img, "etc/passwd") + if err != nil { + return nil, err + } + group, err := readOptionalImageFile(img, "etc/group") + if err != nil { + return nil, err + } + return resolveUser(img.Config.User, passwd, group) +} + +// readOptionalImageFile returns a nil reader for a file the image lacks. +func readOptionalImageFile(img *imagecache.Image, name string) (io.Reader, error) { + b, err := img.ReadFile(name) + if errors.Is(err, fs.ErrNotExist) { + return nil, nil + } + if err != nil { + return nil, err + } + return bytes.NewReader(b), nil +} + +// resolveUser follows Docker's rules for USER "user[:group]": numeric ids as +// is, a bare uid with its login group from passwd (gid 0 without an entry), +// names looked up or an error, group memberships as supplementary groups. +// Ids are bounded to int32. A nil reader means the image lacks the file. +func resolveUser(userSpec string, passwd, group io.Reader) (*ateworkerpb.ProcessUser, error) { + if strings.Count(userSpec, ":") > 1 { + return nil, fmt.Errorf("image User %q: want user[:group]", userSpec) + } + u, err := user.GetExecUser(userSpec, nil, passwd, group) + if err != nil { + return nil, fmt.Errorf("image User %q: %w", userSpec, err) + } + identity := &ateworkerpb.ProcessUser{Uid: uint32(u.Uid), Gid: uint32(u.Gid)} + for _, gid := range u.Sgids { + identity.AdditionalGids = append(identity.AdditionalGids, uint32(gid)) + } + return identity, nil +} diff --git a/cmd/atelet/oci_test.go b/cmd/atelet/oci_test.go index c76d2d0d03..1eed244303 100644 --- a/cmd/atelet/oci_test.go +++ b/cmd/atelet/oci_test.go @@ -15,11 +15,16 @@ package main import ( + "io" "slices" + "strings" "testing" + "github.com/google/go-cmp/cmp" v1 "github.com/google/go-containerregistry/pkg/v1" "go.ate.dev/substrate/internal/proto/ateletpb" + "go.ate.dev/substrate/internal/proto/ateworkerpb" + "google.golang.org/protobuf/testing/protocmp" ) func TestResolveActorEnv(t *testing.T) { @@ -176,6 +181,72 @@ func withCaps(in []string, add ...string) []string { return out } +func TestResolveUser(t *testing.T) { + const passwd = "root:x:0:0:root:/root:/bin/sh\n" + + "jovyan:x:1000:100::/home/jovyan:/bin/bash\n" + + "nonroot:x:65532:65532::/home/nonroot:/sbin/nologin\n" + const group = "root:x:0:\n" + + "users:x:100:\n" + + "nonroot:x:65532:\n" + + "video:x:44:nonroot,jovyan\n" + + "audio:x:29:nonroot\n" + tests := []struct { + name string + user string + passwd, group string // empty: the image lacks the file + want *ateworkerpb.ProcessUser + wantErr bool + }{ + {name: "bare uid, no passwd", user: "1000", want: &ateworkerpb.ProcessUser{Uid: 1000}}, + {name: "bare uid takes its login group and memberships", user: "1000", passwd: passwd, group: group, want: &ateworkerpb.ProcessUser{Uid: 1000, Gid: 100, AdditionalGids: []uint32{44}}}, + {name: "bare uid without a passwd entry", user: "1001", passwd: passwd, group: group, want: &ateworkerpb.ProcessUser{Uid: 1001}}, + {name: "uid:gid passes through", user: "1000:2000", passwd: passwd, group: group, want: &ateworkerpb.ProcessUser{Uid: 1000, Gid: 2000}}, + {name: "named user", user: "nonroot", passwd: passwd, group: group, want: &ateworkerpb.ProcessUser{Uid: 65532, Gid: 65532, AdditionalGids: []uint32{44, 29}}}, + {name: "named user and group", user: "jovyan:video", passwd: passwd, group: group, want: &ateworkerpb.ProcessUser{Uid: 1000, Gid: 44}}, + {name: "named user missing from passwd", user: "nobody", passwd: passwd, wantErr: true}, + {name: "named group missing from group", user: "1000:staff", passwd: passwd, group: group, wantErr: true}, + {name: "above int32", user: "2147483648", wantErr: true}, + {name: "third field", user: "1000:1000:1", wantErr: true}, + } + for _, tc := range tests { + t.Run(tc.name, func(t *testing.T) { + var passwdR, groupR io.Reader + if tc.passwd != "" { + passwdR = strings.NewReader(tc.passwd) + } + if tc.group != "" { + groupR = strings.NewReader(tc.group) + } + got, err := resolveUser(tc.user, passwdR, groupR) + if (err != nil) != tc.wantErr { + t.Fatalf("resolveUser(%q) = %v, %v; wantErr %v", tc.user, got, err, tc.wantErr) + } + if diff := cmp.Diff(tc.want, got, protocmp.Transform()); err == nil && diff != "" { + t.Errorf("resolveUser(%q) mismatch (-want +got):\n%s", tc.user, diff) + } + }) + } +} + +func TestResolveCwd(t *testing.T) { + for _, tc := range []struct { + image *v1.Config + want string + wantErr bool + }{ + {image: nil, want: "/"}, + {image: &v1.Config{}, want: "/"}, + {image: &v1.Config{WorkingDir: "/home/jovyan"}, want: "/home/jovyan"}, + {image: &v1.Config{WorkingDir: "/app/"}, want: "/app"}, + {image: &v1.Config{WorkingDir: "app"}, wantErr: true}, + } { + got, err := resolveCwd(tc.image) + if (err != nil) != tc.wantErr || got != tc.want { + t.Errorf("resolveCwd(%+v) = %q, %v; want %q, wantErr %v", tc.image, got, err, tc.want, tc.wantErr) + } + } +} + func TestResolveCapabilities(t *testing.T) { tests := []struct { name string diff --git a/cmd/ateworker-microvm/internal/kata/specconv_linux_test.go b/cmd/ateworker-microvm/internal/kata/specconv_linux_test.go index 4b7d3afdc7..b211346f9f 100644 --- a/cmd/ateworker-microvm/internal/kata/specconv_linux_test.go +++ b/cmd/ateworker-microvm/internal/kata/specconv_linux_test.go @@ -17,6 +17,7 @@ package kata import ( + "slices" "testing" specs "github.com/opencontainers/runtime-spec/specs-go" @@ -174,3 +175,22 @@ func TestSpecToAgentPB_ForwardsSysctl(t *testing.T) { t.Fatalf("Linux.Sysctl = %v, want %s=0 carried through", got.GetLinux().GetSysctl(), key) } } + +// The agent starts the process as the user it is sent; a dropped identity +// would run the workload as root in the guest. +func TestSpecToAgentPB_ForwardsProcessUser(t *testing.T) { + got := SpecToAgentPB(&specs.Spec{ + Process: &specs.Process{User: specs.User{UID: 65532, GID: 65534, AdditionalGids: []uint32{44}}}, + }) + u := got.GetProcess().GetUser() + if u == nil || u.UID != 65532 || u.GID != 65534 || !slices.Equal(u.AdditionalGids, []uint32{44}) { + t.Fatalf("Process.User = %v, want 65532:65534 +44", u) + } +} + +func TestSpecToAgentPB_ForwardsCwd(t *testing.T) { + got := SpecToAgentPB(&specs.Spec{Process: &specs.Process{Cwd: "/work"}}) + if got.GetProcess().GetCwd() != "/work" { + t.Fatalf("Process.Cwd = %q, want /work", got.GetProcess().GetCwd()) + } +} diff --git a/demos/jupyter/jupyter-template.yaml.tmpl b/demos/jupyter/jupyter-template.yaml.tmpl index df8cd69396..1877a397a1 100644 --- a/demos/jupyter/jupyter-template.yaml.tmpl +++ b/demos/jupyter/jupyter-template.yaml.tmpl @@ -28,7 +28,6 @@ containers: command: - jupyter - lab - - "--allow-root" - "--ServerApp.token=''" - "--ServerApp.password=''" - "--ServerApp.allow_origin='*'" diff --git a/docs/guides/authorization.md b/docs/guides/authorization.md index 62fde72a62..fa726e2f7c 100644 --- a/docs/guides/authorization.md +++ b/docs/guides/authorization.md @@ -143,7 +143,7 @@ through their pod certificates. `ate-api-server`'s `--controller-spiffe-id`, | Role | Held by | Allows | |---|---|---| | `controller` | `ate-controller` | Create, get, list, update, delete and drain workers | -| `egress_gateway` | `atenet-egress`, and any other SPIFFE IDs passed with `--egress-gateway-spiffe-id`, which ate-setup sets from `ATE_EGRESS_GATEWAY_EXTRA_SPIFFE_IDS` | Get actors and their egress policies; list actors across all atespaces; mint actor JWTs and certificates | +| `egress_gateway` | `atenet-egress`, and any other SPIFFE IDs passed with `--egress-gateway-spiffe-id`, which ate-setup sets from `ATE_EGRESS_GATEWAY_EXTRA_SPIFFE_IDS` | Get actors and their egress policies; list actors across all atespaces; mint actor JWTs | | `ingress_router` | `atenet-router` | Resume actors; list actors across all atespaces | | `atelet` | `atelet` | Get actors' egress policies, for the worker that enforces them | | `api_server_sidecar` | the `ate-api-server` pod identity, which its sidecars share, today the objectstore control plugin | Get actors, to derive the snapshot prefixes a per-actor storage credential may cover | @@ -192,7 +192,7 @@ viewer, and a global role holds the same role in every atespace. So | `ResumeActor` | `can_resume`, the actor | Editor of its atespace; `atenet-router` | | `GetActorEgressPolicy` | `can_get_egress_policy`, the actor | Viewer of its atespace; `atenet-egress`; `atelet` | | `CreateActorEgressPolicy`, `UpdateActorEgressPolicy`, `DeleteActorEgressPolicy` | `can_create_egress_policy` / `can_update_egress_policy` / `can_delete_egress_policy`, the actor | Editor of its atespace | -| `MintActorJwt`, `MintActorCertificate` | `can_mint_actor_jwt` / `can_mint_actor_certificate`, the actor | `atenet-egress` only | +| `MintActorJwt` | `can_mint_actor_jwt`, the actor | `atenet-egress` only | ### Tags diff --git a/docs/reference/api-guide.md b/docs/reference/api-guide.md index e22e77f2c5..9a26af21d4 100644 --- a/docs/reference/api-guide.md +++ b/docs/reference/api-guide.md @@ -309,10 +309,16 @@ Each entry in `containers` describes one process to run in the actor's sandbox. `command` and `args` resolve against the container image's `ENTRYPOINT`/`CMD` the same way [Kubernetes Pod `command`/`args`](https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/) resolve against `ENTRYPOINT`/`CMD`. If the resolved argv is empty — the image sets neither `ENTRYPOINT` nor `CMD`, and the container sets neither `command` nor `args` — `Run`/`Restore` fails. +The process runs as the image's `USER`, resolved as Docker does against the image's own `/etc/passwd` and `/etc/group`: a numeric `uid:gid` as is; a bare uid with its login group, or gid 0 when it has no entry; a name must have an entry or `Run`/`Restore` fails. Group memberships become supplementary groups. Ids are at most 2147483647. No `USER` means root. There is no `runAsUser` field. + +The process starts in the image's `WORKDIR`, or in `/` when the image sets none. A `WORKDIR` the image lacks is created in the actor's writable layer. There is no `workingDir` field. + ### Container Capabilities (`securityContext.capabilities`) Each container runs with a default set of Linux capabilities — `AUDIT_WRITE`, `KILL` and `NET_BIND_SERVICE`. `securityContext.capabilities` adjusts that set, mirroring `securityContext.capabilities` on a Kubernetes Pod container. +A container running as root has that set as its effective capabilities. A container whose image `USER` is not root starts with no effective capabilities, as under Kubernetes, because ambient capabilities are not supported. Its set then only limits what a setuid-root program can gain. + | Field | Type | Description | | :--- | :--- | :--- | | `securityContext.capabilities.add` | `[]string` | Optional. Capabilities to grant on top of the default set. `ALL` is **not** accepted here. | @@ -333,6 +339,7 @@ Each container runs with a default set of Linux capabilities — `AUDIT_WRITE`, - **Ambient capabilities are not supported** ([gvisor#3166](https://github.com/google/gvisor/issues/3166)). - **Low ports.** A container may bind a port below 1024 without `NET_BIND_SERVICE` on both runtimes: gVisor's network stack has no privileged-port limit, and the micro-VM guest sets `net.ipv4.ip_unprivileged_port_start=0` to match. - **Setuid binaries work.** Neither runtime sets `no_new_privileges`, as for a Kubernetes container with `allowPrivilegeEscalation: true`; gVisor runs with `--allow-suid`. +- **Image files owned by other users.** Image files keep the owner their image's layers record, as under containerd. A container running as its image's `USER` can use what the image gave that user, for example after `RUN chown -R app:app /app` and `USER app`. A container running as root, because its image sets no `USER` or `USER root`, has no `DAC_OVERRIDE` or `DAC_READ_SEARCH` by default. On a file or directory another user owns, it gets only what the permission bits grant to others. Add `DAC_OVERRIDE` if it writes to such files, or `DAC_READ_SEARCH` if it only reads them. The sandbox — gVisor or microVM — remains the isolation boundary; capabilities constrain the workload *inside* it. @@ -756,7 +763,7 @@ Query the physical resource pool. ate-api-server mints credentials that identify an actor to services outside Substrate. They name the logical actor, so they stay the same as the actor moves between workers. This is distinct from the `actorMetadata` data source described under [SystemInfo Volumes](#systeminfo-volumes), which only tells an actor its own identity fields (name, atespace, uid). -Both RPCs are on `substrate.ateapi.v1.Control`. Only the egress gateway may call them; see [authorization.md](../guides/authorization.md). It calls `MintActorJwt` when an egress policy injects an actor JWT into a request. +`MintActorJwt` is on `substrate.ateapi.v1.Control`. Only the egress gateway may call it; see [authorization.md](../guides/authorization.md). It calls this RPC when an egress policy injects an actor JWT into a request. ### `MintActorJwt` @@ -774,13 +781,6 @@ The token's header carries `typ: JWT`, the algorithm of the pool's active signin Relying parties find the signing keys through OpenID Connect Discovery at `/.well-known/openid-configuration`, which ate-idp-server serves in every install. -### `MintActorCertificate` - -* **Request:** `actor`; `actor_uid`, which must match the actor's current UID, so that a deleted and recreated actor isn't mistaken for the old one (`ABORTED` otherwise); and `certificate_signing_request`, a DER-encoded CSR. The signer checks the CSR's signature and uses only its public key. -* **Response:** `actor_certificates`, DER certificates with the leaf first, followed by any intermediates. - -The caller must connect with a client certificate; a bearer token is not enough. The leaf is valid for one hour, allows client and server authentication, carries the SPIFFE URI `spiffe://substrate-actor.local/actor//`, and has the `ActorIdentity` X.509 extension with the actor's atespace, name, and UID. - --- ## 8. Framework & Ecosystem Integration diff --git a/docs/security/security.md b/docs/security/security.md index 8d871097ee..92860e4aa2 100644 --- a/docs/security/security.md +++ b/docs/security/security.md @@ -8,7 +8,7 @@ description: > # Substrate Security -Substrate delivers zero trust for agents. Every agent has an identity, but no credentials, no open network, and no way out of the sandbox. +Substrate delivers zero trust for agents. Every agent has an identity, but no credentials, no open network, and no escape from the sandbox. Agent Substrate executes untrusted actors at scale in a multi-tenant environment where workloads are dynamic and memory states migrate continuously across physical infrastructure. All security controls operate within Substrate's cold-start and resume latency budget. This document defines the high-level security principles. For identity and credential configuration, see the [Authentication Guide](../guides/authentication.md). Detailed threat scenarios and mitigating invariants are documented [in the threat model](threat-model.md). diff --git a/go.mod b/go.mod index 8368991eca..31106cd7b8 100644 --- a/go.mod +++ b/go.mod @@ -34,6 +34,7 @@ require ( github.com/gorilla/websocket v1.5.4-0.20250319132907-e064f32e3674 github.com/jackc/pgx/v5 v5.10.0 github.com/klauspost/compress v1.19.1 + github.com/moby/sys/user v0.4.1 github.com/myzhan/boomer v1.6.1-0.20250711115830-8a2c7ce4c7b1 github.com/opencontainers/runtime-spec v1.3.0 github.com/openfga/api/proto v0.0.0-20260319214821-f153694bfc20 @@ -192,7 +193,6 @@ require ( github.com/moby/patternmatcher v0.6.1 // indirect github.com/moby/spdystream v0.5.1 // indirect github.com/moby/sys/sequential v0.7.0 // indirect - github.com/moby/sys/user v0.4.1 // indirect github.com/moby/sys/userns v0.1.0 // indirect github.com/moby/term v0.5.2 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect diff --git a/internal/ateworkervalidation/zz_generated.validation.go b/internal/ateworkervalidation/zz_generated.validation.go index eb633428cf..fc44c8eeed 100644 --- a/internal/ateworkervalidation/zz_generated.validation.go +++ b/internal/ateworkervalidation/zz_generated.validation.go @@ -922,6 +922,8 @@ func Validate_ContainerSpec( errs = append(errs, fn(fldPath.Child("resources"), obj.Resources, oldVal, oldObj != nil)...) } + // field ateworkerpb.ContainerSpec.User has no validation + // field ateworkerpb.ContainerSpec.Cwd has no validation return errs } diff --git a/internal/deviceplugin/deviceplugin.go b/internal/deviceplugin/deviceplugin.go index d834975b87..f64e0b69f7 100644 --- a/internal/deviceplugin/deviceplugin.go +++ b/internal/deviceplugin/deviceplugin.go @@ -165,7 +165,10 @@ func (p *Plugin) Run(ctx context.Context) error { slog.InfoContext(ctx, "Device plugin registered", slog.String("resource", p.dev.ResourceName), slog.String("device", p.dev.Path)) - p.waitForKubeletRestart(ctx, watcher) + // stat after registering, so a Create already queued for this same + // socket (say, kubelet came up while we slept on a retry) is ignored + registered, _ := os.Stat(pluginapi.KubeletSocket) + p.waitForKubeletRestart(ctx, watcher, registered) srv.Stop() } return ctx.Err() @@ -223,8 +226,9 @@ func (p *Plugin) register(ctx context.Context) error { } // waitForKubeletRestart blocks until kubelet recreates its socket (meaning it -// restarted and dropped our registration) or ctx is cancelled. -func (p *Plugin) waitForKubeletRestart(ctx context.Context, watcher *fsnotify.Watcher) { +// restarted and dropped our registration) or ctx is cancelled. registered is +// the kubelet socket we registered with, nil if it could not be stat'd. +func (p *Plugin) waitForKubeletRestart(ctx context.Context, watcher *fsnotify.Watcher, registered os.FileInfo) { for { select { case <-ctx.Done(): @@ -233,7 +237,7 @@ func (p *Plugin) waitForKubeletRestart(ctx context.Context, watcher *fsnotify.Wa if !ok { return } - if event.Name == pluginapi.KubeletSocket && event.Has(fsnotify.Create) { + if kubeletRestarted(event, pluginapi.KubeletSocket, registered) { slog.InfoContext(ctx, "Kubelet restarted; re-registering device plugin", slog.String("resource", p.dev.ResourceName)) return @@ -248,6 +252,22 @@ func (p *Plugin) waitForKubeletRestart(ctx context.Context, watcher *fsnotify.Wa } } +// kubeletRestarted reports whether event is kubelet recreating socket since we +// stat'd it as registered. Re-registering on a stale event can wedge the +// resource in kubelet as "already connected", if the second Register for our +// socket arrives while kubelet is still closing the first stream. +func kubeletRestarted(event fsnotify.Event, socket string, registered os.FileInfo) bool { + if event.Name != socket || !event.Has(fsnotify.Create) { + return false + } + if registered == nil { + return true + } + // mtime too, as a just freed inode can be reused for the new socket + fi, err := os.Stat(socket) + return err != nil || !os.SameFile(fi, registered) || !fi.ModTime().Equal(registered.ModTime()) +} + // GetDevicePluginOptions implements the device plugin API; the defaults are // correct here. func (p *Plugin) GetDevicePluginOptions(context.Context, *pluginapi.Empty) (*pluginapi.DevicePluginOptions, error) { diff --git a/internal/deviceplugin/deviceplugin_test.go b/internal/deviceplugin/deviceplugin_test.go index a67c1c839d..a66f5e76e0 100644 --- a/internal/deviceplugin/deviceplugin_test.go +++ b/internal/deviceplugin/deviceplugin_test.go @@ -19,7 +19,9 @@ import ( "os" "path/filepath" "testing" + "time" + "github.com/fsnotify/fsnotify" "google.golang.org/grpc" pluginapi "k8s.io/kubelet/pkg/apis/deviceplugin/v1beta1" ) @@ -158,6 +160,53 @@ func TestListAndWatchSendsDevicesThenBlocks(t *testing.T) { } } +// Only a Create for a kubelet socket other than the one we registered with +// is a restart; one already queued for that same socket is stale. +func TestKubeletRestartedIgnoresStaleCreate(t *testing.T) { + dir := t.TempDir() + socket := filepath.Join(dir, "kubelet.sock") + if err := os.WriteFile(socket, nil, 0o600); err != nil { + t.Fatal(err) + } + registered, err := os.Stat(socket) + if err != nil { + t.Fatal(err) + } + create := fsnotify.Event{Name: socket, Op: fsnotify.Create} + + if kubeletRestarted(create, socket, registered) { + t.Error("kubeletRestarted() = true for a Create of the registered socket") + } + if kubeletRestarted(fsnotify.Event{Name: filepath.Join(dir, "other.sock"), Op: fsnotify.Create}, socket, registered) { + t.Error("kubeletRestarted() = true for another socket") + } + if kubeletRestarted(fsnotify.Event{Name: socket, Op: fsnotify.Write}, socket, registered) { + t.Error("kubeletRestarted() = true for a Write") + } + if !kubeletRestarted(create, socket, nil) { + t.Error("kubeletRestarted() = false with no registered socket") + } + + // kubelet restarting unlinks and recreates its socket + if err := os.Remove(socket); err != nil { + t.Fatal(err) + } + if !kubeletRestarted(create, socket, registered) { + t.Error("kubeletRestarted() = false with the socket gone") + } + if err := os.WriteFile(socket, nil, 0o600); err != nil { + t.Fatal(err) + } + // the inode may be reused, so only mtime tells them apart + later := registered.ModTime().Add(time.Second) + if err := os.Chtimes(socket, later, later); err != nil { + t.Fatal(err) + } + if !kubeletRestarted(create, socket, registered) { + t.Error("kubeletRestarted() = false for a recreated socket") + } +} + type fakeListAndWatchStream struct { grpc.ServerStream ctx context.Context diff --git a/internal/e2e/fixture.go b/internal/e2e/fixture.go index e4c1d384f1..4abc935240 100644 --- a/internal/e2e/fixture.go +++ b/internal/e2e/fixture.go @@ -92,6 +92,7 @@ type FixtureOption func(*fixtureConfig) type fixtureConfig struct { templateValues map[string]string + imageUser string } // WithTemplateValue replaces the inline placeholder ${name} in the fixture's @@ -105,6 +106,12 @@ func WithTemplateValue(name, value string) FixtureOption { } } +// WithImageUser sets user as the USER of the images ko builds for the +// fixture's ActorTemplates, as a Dockerfile USER line would. +func WithImageUser(user string) FixtureOption { + return func(c *fixtureConfig) { c.imageUser = user } +} + // SubstrateFixtureManifests names the two manifest templates a substrate // fixture is built from (both repo-relative, under internal/e2e/fixtures). type SubstrateFixtureManifests struct { @@ -157,7 +164,11 @@ func DeploySubstrateFixture(t *testing.T, ctx context.Context, clients *Clients, tmplInline, tmplBlocks := substrateTemplateSubstitutions(name, trustBundles) maps.Copy(tmplInline, cfg.templateValues) - rendered := koResolve(t, renderManifest(t, manifests.Template, tmplInline, tmplBlocks)) + var resolveArgs []string + if cfg.imageUser != "" { + resolveArgs = append(resolveArgs, "--image-user", cfg.imageUser) + } + rendered := koResolve(t, renderManifest(t, manifests.Template, tmplInline, tmplBlocks), resolveArgs...) templates := decodeSubstrateTemplates(t, rendered) atespace := templates[0].GetMetadata().GetAtespace() diff --git a/internal/e2e/fixtures/probe/main.go b/internal/e2e/fixtures/probe/main.go index 5dedcb1005..80a68179db 100644 --- a/internal/e2e/fixtures/probe/main.go +++ b/internal/e2e/fixtures/probe/main.go @@ -223,6 +223,36 @@ func readfile(w http.ResponseWriter, r *http.Request) { writeJSON(w, resp) } +// statResponse is the /stat payload: path's numeric owner and mode as the +// actor sees them, without following a final-component symlink. +type statResponse struct { + Path string `json:"path"` + UID uint32 `json:"uid"` + GID uint32 `json:"gid"` + // Mode is the os.FileMode string, e.g. "drwx------". + Mode string `json:"mode"` + Error string `json:"error,omitempty"` +} + +// stat reports a path's owner and mode inside the actor, so a test can assert +// on the ownership the image's layers gave it. +func stat(w http.ResponseWriter, r *http.Request) { + resp := statResponse{Path: r.URL.Query().Get("path")} + fi, err := os.Lstat(resp.Path) + if err != nil { + resp.Error = err.Error() + writeJSON(w, resp) + return + } + resp.Mode = fi.Mode().String() + if st, ok := fi.Sys().(*syscall.Stat_t); ok { + resp.UID, resp.GID = st.Uid, st.Gid + } else { + resp.Error = "no owner information for " + resp.Path + } + writeJSON(w, resp) +} + func writefile(w http.ResponseWriter, r *http.Request) { path := r.URL.Query().Get("path") resp := map[string]string{"path": path} @@ -629,6 +659,7 @@ func main() { mux.HandleFunc("/readfile", readfile) mux.HandleFunc("/writefile", writefile) mux.HandleFunc("/lookup", lookup) + mux.HandleFunc("/stat", stat) mux.HandleFunc("/resources", resources) mux.HandleFunc("/capabilities", capabilities) mux.HandleFunc("/healthz", healthz) diff --git a/internal/e2e/fixtures/probe/main_test.go b/internal/e2e/fixtures/probe/main_test.go index 7d26c6a151..e7ec377308 100644 --- a/internal/e2e/fixtures/probe/main_test.go +++ b/internal/e2e/fixtures/probe/main_test.go @@ -515,3 +515,48 @@ func TestRestoreFetchRetriesOnNextProbe(t *testing.T) { time.Sleep(50 * time.Millisecond) } } + +func doStat(t *testing.T, path string) statResponse { + t.Helper() + req := httptest.NewRequest(http.MethodGet, "/stat?"+url.Values{"path": {path}}.Encode(), nil) + rec := httptest.NewRecorder() + stat(rec, req) + var resp statResponse + if err := json.Unmarshal(rec.Body.Bytes(), &resp); err != nil { + t.Fatalf("decoding /stat response %q: %v", rec.Body.String(), err) + } + return resp +} + +// The imagefs e2e suite asserts on /stat's owner and mode, so this pins both +// against files whose owner and mode the test sets itself. +func TestStatReportsOwnerAndMode(t *testing.T) { + dir := t.TempDir() + priv := filepath.Join(dir, "private") + if err := os.Mkdir(priv, 0o700); err != nil { + t.Fatal(err) + } + // Mkdir's mode is clipped by the umask; set it exactly. + if err := os.Chmod(priv, 0o700); err != nil { + t.Fatal(err) + } + link := filepath.Join(dir, "link") + if err := os.Symlink("private", link); err != nil { + t.Fatal(err) + } + + got := doStat(t, priv) + want := statResponse{Path: priv, UID: uint32(os.Getuid()), GID: got.GID, Mode: "drwx------"} + if diff := cmp.Diff(want, got); diff != "" { + t.Errorf("/stat %s mismatch (-want +got):\n%s", priv, diff) + } + + // The symlink itself, not its target. + if got := doStat(t, link); !strings.HasPrefix(got.Mode, "L") || got.Error != "" { + t.Errorf("/stat %s = %+v, want the symlink's own mode", link, got) + } + + if got := doStat(t, filepath.Join(dir, "missing")); got.Error == "" { + t.Errorf("/stat of a missing path reported no error: %+v", got) + } +} diff --git a/internal/e2e/fixtures/probe/nonroot/main.go b/internal/e2e/fixtures/probe/nonroot/main.go new file mode 100644 index 0000000000..587b69f283 --- /dev/null +++ b/internal/e2e/fixtures/probe/nonroot/main.go @@ -0,0 +1,91 @@ +// Copyright 2026 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// Command nonroot is the probe for an image with a non-root USER and a +// WORKDIR that user owns. It reports the identity, effective capabilities and +// working directory the actor's process runs with. +// +// It is a separate binary from the probe because ko picks the base image per +// import path. The probe stays on the root base, and this one builds on the +// default nonroot distroless base, whose WORKDIR is /home/nonroot. +package main + +import ( + "encoding/json" + "log" + "net/http" + "os" + "strings" +) + +// identityResponse is the /identity payload. +type identityResponse struct { + UID int `json:"uid"` + GID int `json:"gid"` + Groups []int `json:"groups"` + Cwd string `json:"cwd"` + // CapEff is the CapEff mask from /proc/self/status, in hex. + CapEff string `json:"capEff"` + // WriteError is why creating a file in the working directory failed. + WriteError string `json:"writeError,omitempty"` + Error string `json:"error,omitempty"` +} + +func identity(w http.ResponseWriter, _ *http.Request) { + resp := identityResponse{UID: os.Getuid(), GID: os.Getgid(), Groups: []int{}} + if groups, err := os.Getgroups(); err == nil { + resp.Groups = append(resp.Groups, groups...) + } else { + resp.Error += "getgroups: " + err.Error() + "; " + } + if cwd, err := os.Getwd(); err == nil { + resp.Cwd = cwd + } else { + resp.Error += "getwd: " + err.Error() + "; " + } + if status, err := os.ReadFile("/proc/self/status"); err == nil { + for line := range strings.Lines(string(status)) { + if v, ok := strings.CutPrefix(line, "CapEff:"); ok { + resp.CapEff = strings.TrimSpace(v) + } + } + } else { + resp.Error += "reading /proc/self/status: " + err.Error() + "; " + } + if f, err := os.CreateTemp(".", "write-check-"); err == nil { + _ = f.Close() + if err := os.Remove(f.Name()); err != nil { + resp.WriteError = err.Error() + } + } else { + resp.WriteError = err.Error() + } + + w.Header().Set("Content-Type", "application/json") + if err := json.NewEncoder(w).Encode(resp); err != nil { + log.Printf("nonroot probe: writing response: %v", err) + } +} + +func main() { + mux := http.NewServeMux() + mux.HandleFunc("/identity", identity) + mux.HandleFunc("/healthz", func(w http.ResponseWriter, _ *http.Request) { w.WriteHeader(http.StatusOK) }) + + const addr = ":80" + log.Printf("nonroot probe listening on %s", addr) + if err := http.ListenAndServe(addr, mux); err != nil { + log.Fatalf("nonroot probe server: %v", err) + } +} diff --git a/internal/e2e/fixtures/probe/probe-nonroot-template.yaml.tmpl b/internal/e2e/fixtures/probe/probe-nonroot-template.yaml.tmpl new file mode 100644 index 0000000000..6ada59c5b1 --- /dev/null +++ b/internal/e2e/fixtures/probe/probe-nonroot-template.yaml.tmpl @@ -0,0 +1,38 @@ +# Copyright 2026 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# An ActorTemplate on the probe pool (probe.yaml.tmpl) whose image runs as a +# named non-root USER in a WORKDIR that user owns. The imagefs suite resolves +# it with `ko resolve --image-user nonroot:nonroot` (e2e.WithImageUser); the +# nonroot distroless base sets WORKDIR /home/nonroot. + +metadata: + atespace: ate-e2e-probe${FIXTURE_SUFFIX} + name: probe-nonroot +workerSelector: + matchLabels: + workload: probe${FIXTURE_SUFFIX} +containers: +- name: probe + image: ko://go.ate.dev/substrate/internal/e2e/fixtures/probe/nonroot + command: ["/ko-app/nonroot"] + wakeupProbe: + httpGet: + path: /healthz + port: 80 + timeoutSeconds: 60 +resources: + limits: + cpuMillicores: 1000 + memoryBytes: 536870912 # 512Mi diff --git a/internal/e2e/manifest.go b/internal/e2e/manifest.go index 5714973ba6..b7623cd2ea 100644 --- a/internal/e2e/manifest.go +++ b/internal/e2e/manifest.go @@ -120,12 +120,14 @@ func koApply(t *testing.T, manifest string) { // the manifest with those references replaced by pushed digests. Same pinned // ko and KO_CONFIG_PATH rules as koApply; resolve is how a manifest that is // not destined for kubectl (a protojson ActorTemplate document) still gets -// its image built. -func koResolve(t *testing.T, manifest string) []byte { +// its image built. args go to ko resolve before the manifest. +func koResolve(t *testing.T, manifest string, args ...string) []byte { t.Helper() root, err := FindRepoRoot() if err != nil { t.Fatalf("FindRepoRoot: %v", err) } - return RunCmdOutput(t, []string{"KO_CONFIG_PATH=" + root}, filepath.Join(root, "hack/run-tool.sh"), "ko", "resolve", "-f", manifest) + resolveArgs := append([]string{"ko", "resolve"}, args...) + resolveArgs = append(resolveArgs, "-f", manifest) + return RunCmdOutput(t, []string{"KO_CONFIG_PATH=" + root}, filepath.Join(root, "hack/run-tool.sh"), resolveArgs...) } diff --git a/internal/e2e/sandbox_test.go b/internal/e2e/sandbox_test.go index 427bb5d823..d60ce2aec0 100644 --- a/internal/e2e/sandbox_test.go +++ b/internal/e2e/sandbox_test.go @@ -40,6 +40,10 @@ var substrateFixtures = []struct { Pool: "internal/e2e/fixtures/probe/probe.yaml.tmpl", Template: "internal/e2e/fixtures/probe/probe-template.yaml.tmpl", }, 1, nil}, + {SubstrateFixtureManifests{ + Pool: "internal/e2e/fixtures/probe/probe.yaml.tmpl", + Template: "internal/e2e/fixtures/probe/probe-nonroot-template.yaml.tmpl", + }, 1, nil}, {SubstrateFixtureManifests{ Pool: "internal/e2e/fixtures/probe/probe.yaml.tmpl", Template: "internal/e2e/fixtures/probe/probe-bootfetch-template.yaml.tmpl", diff --git a/internal/e2e/suites/imagefs/imagefs_test.go b/internal/e2e/suites/imagefs/imagefs_test.go new file mode 100644 index 0000000000..e354d420f8 --- /dev/null +++ b/internal/e2e/suites/imagefs/imagefs_test.go @@ -0,0 +1,243 @@ +// Copyright 2026 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// Package imagefs checks the actor's view of its image's filesystem and +// process identity against what the image records. +package imagefs + +import ( + "context" + "encoding/json" + "io" + "net/http" + "net/url" + "strconv" + "testing" + + "go.ate.dev/substrate/api/ateapi/v1" + "go.ate.dev/substrate/internal/e2e" + "go.ate.dev/substrate/internal/resources" +) + +// statResponse mirrors the probe's /stat payload. +type statResponse struct { + Path string `json:"path"` + UID uint32 `json:"uid"` + GID uint32 `json:"gid"` + Mode string `json:"mode"` + Error string `json:"error"` +} + +// layerOwners are paths whose owner and mode the probe image's layers record. +// .ko.yaml builds the probe on the root distroless static base, whose base +// layer has /home/nonroot as drwx------ owned by 65532:65532 (distroless's +// nonroot user), /var/tmp as root-owned 1777, and root-owned system files. +// /var/tmp, not /tmp, checks the sticky bit: gVisor mounts its own 1777 tmpfs +// over an empty /tmp. +var layerOwners = []statResponse{ + {Path: "/home/nonroot", UID: 65532, GID: 65532, Mode: "drwx------"}, + {Path: "/var/tmp", UID: 0, GID: 0, Mode: "dtrwxrwxrwx"}, + {Path: "/etc/passwd", UID: 0, GID: 0, Mode: "-rw-r--r--"}, + {Path: "/home", UID: 0, GID: 0, Mode: "drwxr-xr-x"}, +} + +// TestImageLayerOwnership asserts that files keep the owners the image's +// layer tars record, as they do under containerd: a private home directory +// given to a non-root user must not show up as root-owned inside the actor. +// It checks once on the first start and again after a suspend and resume, +// which restores the actor over the same cached layers. +// +// It runs against whichever sandbox class E2E_SANDBOX_CLASS selects, so CI +// covers both gVisor and microVM from one suite. +func TestImageLayerOwnership(t *testing.T) { + if _, err := e2e.CheckEnv("KO_DOCKER_REPO"); err != nil { + t.Fatalf("CheckEnv failed: %v", err) + } + ctx := context.Background() + clients := e2e.GetClients() + + atespace, tmpl := e2e.DeployProbe(t, "imagefs") + ref := &ateapi.ObjectRef{Atespace: atespace, Name: "imagefs-actor"} + if _, err := clients.SubstrateAPI.CreateActor(ctx, &ateapi.CreateActorRequest{Actor: &ateapi.Actor{ + Metadata: &ateapi.ResourceMetadata{Atespace: ref.Atespace, Name: ref.Name}, + ActorTemplate: &ateapi.ObjectRef{Atespace: atespace, Name: tmpl.GetMetadata().GetName()}, + }}); err != nil { + t.Fatalf("CreateActor %q: %v", ref.Name, err) + } + t.Cleanup(func() { + _, _ = clients.SubstrateAPI.DeleteActor(ctx, &ateapi.DeleteActorRequest{Actor: ref}) + }) + + rc, err := e2e.NewRouterClient(t, ctx) + if err != nil { + t.Fatalf("NewRouterClient: %v", err) + } + defer rc.Close() + + if _, err := e2e.ResumeActorAwaitCapacity(t, ctx, clients, &ateapi.ResumeActorRequest{Actor: ref}); err != nil { + t.Fatalf("ResumeActor %q: %v", ref.Name, err) + } + t.Run("first start", func(t *testing.T) { checkOwners(t, ctx, rc, ref) }) + + suspended, err := clients.SubstrateAPI.SuspendActor(ctx, &ateapi.SuspendActorRequest{Actor: ref}) + if err != nil { + t.Fatalf("SuspendActor %q: %v", ref.Name, err) + } + if got := suspended.GetActor().GetStatus().GetState(); got != ateapi.ActorState_ACTOR_STATE_SUSPENDED { + t.Fatalf("SuspendActor %q: state %v, want %v", ref.Name, got, ateapi.ActorState_ACTOR_STATE_SUSPENDED) + } + if _, err := e2e.ResumeActorAwaitCapacity(t, ctx, clients, &ateapi.ResumeActorRequest{Actor: ref}); err != nil { + t.Fatalf("ResumeActor %q after suspend: %v", ref.Name, err) + } + t.Run("after suspend and resume", func(t *testing.T) { checkOwners(t, ctx, rc, ref) }) +} + +// identityResponse mirrors the nonroot probe's /identity payload. +type identityResponse struct { + UID int `json:"uid"` + GID int `json:"gid"` + Groups []int `json:"groups"` + Cwd string `json:"cwd"` + CapEff string `json:"capEff"` + WriteError string `json:"writeError"` + Error string `json:"error"` +} + +// The nonroot probe image's USER is nonroot:nonroot. The distroless base's +// /etc/passwd and /etc/group give that user and group id 65532 and list the +// user in no other group. Its WORKDIR, /home/nonroot, is 65532:65532 and +// drwx------. +const ( + nonrootID = 65532 + nonrootWorkdir = "/home/nonroot" +) + +// TestImageUserAndWorkdir asserts that the actor's process runs as its image's +// USER, resolved by name against the image's own /etc/passwd and /etc/group, +// with no effective capabilities, and starts in the image's WORKDIR, where +// that user can create files. The WORKDIR is private to the user, so the +// write also needs the layer owners TestImageLayerOwnership checks. +// +// The golden bake runs the probe as that user and binds :80, and the actor +// resumes from that golden snapshot. It runs against whichever sandbox class +// E2E_SANDBOX_CLASS selects, so CI covers both gVisor and microVM. +func TestImageUserAndWorkdir(t *testing.T) { + if _, err := e2e.CheckEnv("KO_DOCKER_REPO"); err != nil { + t.Fatalf("CheckEnv failed: %v", err) + } + ctx := context.Background() + clients := e2e.GetClients() + + atespace, templates := e2e.DeploySubstrateFixture(t, ctx, clients, e2e.SubstrateFixtureManifests{ + Pool: "internal/e2e/fixtures/probe/probe.yaml.tmpl", + Template: "internal/e2e/fixtures/probe/probe-nonroot-template.yaml.tmpl", + }, "imagefs-user", nil, e2e.WithImageUser("nonroot:nonroot")) + ref := &ateapi.ObjectRef{Atespace: atespace, Name: "imagefs-user-actor"} + if _, err := clients.SubstrateAPI.CreateActor(ctx, &ateapi.CreateActorRequest{Actor: &ateapi.Actor{ + Metadata: &ateapi.ResourceMetadata{Atespace: ref.Atespace, Name: ref.Name}, + ActorTemplate: &ateapi.ObjectRef{Atespace: atespace, Name: templates[0].GetMetadata().GetName()}, + }}); err != nil { + t.Fatalf("CreateActor %q: %v", ref.Name, err) + } + t.Cleanup(func() { + _, _ = clients.SubstrateAPI.DeleteActor(ctx, &ateapi.DeleteActorRequest{Actor: ref}) + }) + + rc, err := e2e.NewRouterClient(t, ctx) + if err != nil { + t.Fatalf("NewRouterClient: %v", err) + } + defer rc.Close() + + if _, err := e2e.ResumeActorAwaitCapacity(t, ctx, clients, &ateapi.ResumeActorRequest{Actor: ref}); err != nil { + t.Fatalf("ResumeActor %q: %v", ref.Name, err) + } + + got := probeIdentity(t, ctx, rc, ref) + if got.Error != "" { + t.Errorf("probe reported an error reading its identity: %s", got.Error) + } + if got.UID != nonrootID || got.GID != nonrootID { + t.Errorf("process runs as %d:%d, want %d:%d from the image's USER nonroot:nonroot", got.UID, got.GID, nonrootID, nonrootID) + } + // Linux may list the primary group among the supplementary ones. Any + // other group, such as root's 0, was not granted by the image. + for _, g := range got.Groups { + if g != nonrootID { + t.Errorf("supplementary groups = %v, want none besides %d", got.Groups, nonrootID) + break + } + } + // Without ambient capabilities, a non-root process has none effective. + if capEff, err := strconv.ParseUint(got.CapEff, 16, 64); err != nil || capEff != 0 { + t.Errorf("CapEff = %q, want no effective capabilities for a non-root USER", got.CapEff) + } + if got.Cwd != nonrootWorkdir { + t.Errorf("working directory = %q, want the image's WORKDIR %q", got.Cwd, nonrootWorkdir) + } + if got.WriteError != "" { + t.Errorf("creating a file in the WORKDIR as the image's USER: %s", got.WriteError) + } +} + +func probeIdentity(t *testing.T, ctx context.Context, rc *e2e.RouterClient, ref *ateapi.ObjectRef) identityResponse { + t.Helper() + resp, err := rc.Get(ctx, resources.ActorRef{Atespace: ref.Atespace, Name: ref.Name}, "/identity") + if err != nil { + t.Fatalf("GET /identity: %v", err) + } + defer resp.Body.Close() + if resp.StatusCode != http.StatusOK { + body, _ := io.ReadAll(resp.Body) + t.Fatalf("GET /identity: status %d, body %q", resp.StatusCode, body) + } + var out identityResponse + if err := json.NewDecoder(resp.Body).Decode(&out); err != nil { + t.Fatalf("decoding /identity: %v", err) + } + return out +} + +func checkOwners(t *testing.T, ctx context.Context, rc *e2e.RouterClient, ref *ateapi.ObjectRef) { + t.Helper() + for _, want := range layerOwners { + got := probeStat(t, ctx, rc, ref, want.Path) + if got.Error != "" { + t.Errorf("stat %s inside the actor: %s", want.Path, got.Error) + continue + } + if got.UID != want.UID || got.GID != want.GID || got.Mode != want.Mode { + t.Errorf("%s inside the actor is %s %d:%d, want %s %d:%d as the image's layer records it", + want.Path, got.Mode, got.UID, got.GID, want.Mode, want.UID, want.GID) + } + } +} + +func probeStat(t *testing.T, ctx context.Context, rc *e2e.RouterClient, ref *ateapi.ObjectRef, path string) statResponse { + t.Helper() + resp, err := rc.Get(ctx, resources.ActorRef{Atespace: ref.Atespace, Name: ref.Name}, "/stat?"+url.Values{"path": {path}}.Encode()) + if err != nil { + t.Fatalf("GET /stat %s: %v", path, err) + } + defer resp.Body.Close() + if resp.StatusCode != http.StatusOK { + body, _ := io.ReadAll(resp.Body) + t.Fatalf("GET /stat %s: status %d, body %q", path, resp.StatusCode, body) + } + var out statResponse + if err := json.NewDecoder(resp.Body).Decode(&out); err != nil { + t.Fatalf("decoding /stat %s: %v", path, err) + } + return out +} diff --git a/internal/e2e/suites/imagefs/testmain_test.go b/internal/e2e/suites/imagefs/testmain_test.go new file mode 100644 index 0000000000..e22b83e12d --- /dev/null +++ b/internal/e2e/suites/imagefs/testmain_test.go @@ -0,0 +1,24 @@ +// Copyright 2026 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package imagefs + +import ( + "os" + "testing" + + "go.ate.dev/substrate/internal/e2e" +) + +func TestMain(m *testing.M) { os.Exit(e2e.RunTestMain(m)) } diff --git a/internal/imagecache/README.md b/internal/imagecache/README.md index db37c4c2e3..126a00deec 100644 --- a/internal/imagecache/README.md +++ b/internal/imagecache/README.md @@ -37,13 +37,15 @@ What it buys, concretely: ## The privilege split The design is shaped by an existing substrate boundary: **atelet runs as -plain root with every Linux capability dropped** ("atelet does no mounts" — -see `manifests/ate-install/atelet.yaml`), while the **worker pods are -privileged** and own all mounts on the node. The module is split accordingly: +root with every Linux capability dropped but a few for files other users +own** ("atelet does no mounts" — see +[`manifests/ate-install/atelet.yaml`](../../manifests/ate-install/atelet.yaml), +which gives the reason for each), while the **worker pods hold the mount +capabilities** and own all mounts on the node. The module is split accordingly: | Half | Runs in | Files | Needs | |---|---|---|---| -| Store: pull, parse, unpack, record | atelet | `imagecache.go`, `unpack.go`, `spec.go` (portable) | nothing but file I/O | +| Store: pull, parse, unpack, record | atelet | `imagecache.go`, `unpack.go`, `spec.go` (portable) | file I/O; `CAP_CHOWN`, `CAP_DAC_OVERRIDE`, `CAP_FOWNER`, `CAP_FSETID` | | Consumer: finalize, mount, unmount | ateworker-gvisor / ateworker-microvm | `bundle_linux.go` (`//go:build linux`) | `CAP_MKNOD`, `CAP_SYS_ADMIN` | The two halves communicate through the filesystem only: the shared cache @@ -59,7 +61,7 @@ anywhere. ``` / default: /var/lib/ate/image-cache - version layout version marker ("2") + version layout version marker ("3") layers/sha256// fs/ the unpacked layer tree (an overlay lowerdir) whiteouts.json whiteout state recorded at unpack time @@ -101,12 +103,18 @@ layer diffIDs in order — layers shared by N images exist once. confinement (path traversal and symlink/hardlink escapes are refused), "later entry wins" within a layer, read-only-dir handling that works without `CAP_DAC_OVERRIDE`, and creation of parent directories that the - layer tar omits (they may exist only in lower layers). Character and - block device nodes are skipped (atelet runs without `CAP_MKNOD` and the - runtime mounts `/dev`). Whiteout entries (`.wh.*`) are **not** written - into the tree — overlayfs whiteouts are char devices atelet cannot - create — they are recorded in `whiteouts.json` for the consumer to - materialize. + layer tar omits (they may exist only in lower layers). Every entry keeps + the numeric owner and the exact mode its tar header records, setuid, + setgid and sticky bits included, as containerd and moby apply them + (see `unpackLayer` for how a failed chown or chmod is handled). A root + atelet inside a user namespace (rootless or userns-remapped nodes) can + only give files to uids and gids the namespace maps, so a layer with an + owner outside that range fails to unpack, as it does under rootless + Docker. Character and block device nodes are skipped (atelet runs + without `CAP_MKNOD` and the runtime mounts `/dev`). Whiteout entries + (`.wh.*`) are **not** written into the tree — overlayfs whiteouts are + char devices atelet cannot create — they are recorded in + `whiteouts.json` for the consumer to materialize. 5. **Verify** before the layer enters the pool. Images share layers by diffID, but each image's author chooses the diffIDs in its config. So the uncompressed stream is hashed as it unpacks and must match the @@ -117,7 +125,8 @@ layer diffIDs in order — layers shared by N images exist once. A layer already in the pool is reused without re-hashing, because it was checked when it was written. The reusing image's own blob is never downloaded, so it is never checked. atelet refuses a layout version 1 - pool, whose layers may not have been checked. + pool, whose layers may not have been checked, and a version 2 pool, + whose layers are root-owned without setuid, setgid or sticky bits. 6. **Record**: the image config + diffID list is written under the requested digest (and the per-platform child digest for multi-arch refs). diff --git a/internal/imagecache/ateletcaps_test.go b/internal/imagecache/ateletcaps_test.go new file mode 100644 index 0000000000..26894ef135 --- /dev/null +++ b/internal/imagecache/ateletcaps_test.go @@ -0,0 +1,199 @@ +// Copyright 2026 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package imagecache + +import ( + "bytes" + "os" + "os/exec" + "regexp" + "runtime" + "slices" + "strconv" + "strings" + "testing" + "time" + + appsv1 "k8s.io/api/apps/v1" + corev1 "k8s.io/api/core/v1" + "sigs.k8s.io/yaml" +) + +// Capability bits, from linux/capability.h. +const ( + capChown = 0 + capDacOverride = 1 + capFowner = 3 + capFsetid = 4 + capSysAdmin = 21 + capMknod = 27 +) + +// capSet is a capability set a root-gated test runs under, as root with +// every other capability dropped. +type capSet struct { + // bounding is the set in setpriv(1)'s --bounding-set syntax. + bounding string + // eff is the effective set the child process must report. + eff uint64 +} + +var ( + // ateletCaps is the set manifests/ate-install/atelet.yaml grants atelet. + ateletCaps = capSet{ + bounding: "-all,+chown,+dac_override,+fowner,+fsetid", + eff: 1<