From 7cd29c5a516b7d030387655579e43565cdc8bd3d Mon Sep 17 00:00:00 2001 From: Elijah Rodriguez Date: Fri, 25 Sep 2026 09:34:36 -0700 Subject: [PATCH 1/3] atelet: add the empty_dir volume source An EmptyDirVolume is an empty host directory at the same path an external volume would be published to, mounted into the sandbox the same way. It lets a golden actor warm up against a placeholder for an external volume it must not mount, so the snapshot's mount table matches the real actor's on both gVisor and microVM. Co-Authored-By: Claude Fable 5.1 --- cmd/atelet/main.go | 2 +- cmd/atelet/main_test.go | 3 + cmd/atelet/volumes.go | 18 +- cmd/atelet/volumes_test.go | 20 ++ internal/proto/ateletpb/atelet.pb.go | 408 +++++++++++++++------------ internal/proto/ateletpb/atelet.proto | 5 + 6 files changed, 279 insertions(+), 177 deletions(-) diff --git a/cmd/atelet/main.go b/cmd/atelet/main.go index 085ad698ce..4f06b2e978 100644 --- a/cmd/atelet/main.go +++ b/cmd/atelet/main.go @@ -1573,7 +1573,7 @@ func buildAteomWorkloadSpec(spec *ateletpb.WorkloadSpec, containerSpecs []*ateom VolumeName: volName, MountPath: vm.GetMountPath(), }) - case *ateletpb.Volume_External: + case *ateletpb.Volume_External, *ateletpb.Volume_EmptyDir: csiMounts = append(csiMounts, &ateompb.VolumeMount{ VolumeName: volName, MountPath: vm.GetMountPath(), diff --git a/cmd/atelet/main_test.go b/cmd/atelet/main_test.go index 14f6f39b26..18c443727f 100644 --- a/cmd/atelet/main_test.go +++ b/cmd/atelet/main_test.go @@ -1022,6 +1022,7 @@ func TestBuildAteomWorkloadSpecForwardsDurableDirMounts(t *testing.T) { {Name: "data", Source: &ateletpb.Volume_DurableDir{DurableDir: &ateletpb.DurableDirVolume{}}}, {Name: "cache", Source: &ateletpb.Volume_DurableDir{DurableDir: &ateletpb.DurableDirVolume{}}}, {Name: "scratch", Source: &ateletpb.Volume_External{External: &ateletpb.ExternalVolumeSource{}}}, + {Name: "empty", Source: &ateletpb.Volume_EmptyDir{EmptyDir: &ateletpb.EmptyDirVolume{}}}, {Name: "system-info", Source: &ateletpb.Volume_SystemInfo{SystemInfo: &ateletpb.SystemInfoVolume{}}}, }, Containers: []*ateletpb.Container{ @@ -1031,6 +1032,7 @@ func TestBuildAteomWorkloadSpecForwardsDurableDirMounts(t *testing.T) { {Name: "data", MountPath: "/home/counter"}, {Name: "cache", MountPath: "/var/cache"}, {Name: "scratch", MountPath: "/scratch"}, + {Name: "empty", MountPath: "/empty"}, {Name: "system-info", MountPath: "/run/ate"}, }, }, @@ -1055,6 +1057,7 @@ func TestBuildAteomWorkloadSpecForwardsDurableDirMounts(t *testing.T) { }, CsiVolumeMounts: []*ateompb.VolumeMount{ {VolumeName: "scratch", MountPath: "/scratch"}, + {VolumeName: "empty", MountPath: "/empty"}, }, SystemInfoVolumeMounts: []*ateompb.SystemInfoVolumeMount{ {VolumeName: "system-info", MountPath: "/run/ate"}, diff --git a/cmd/atelet/volumes.go b/cmd/atelet/volumes.go index 2cc0ee6810..b114905242 100644 --- a/cmd/atelet/volumes.go +++ b/cmd/atelet/volumes.go @@ -31,11 +31,17 @@ import ( func (s *AteomHerder) mountExternalVolumes(ctx context.Context, actorUID string, volumes []*ateletpb.Volume) error { for _, vol := range volumes { + hostPath := ateletpath.VolumeHostPath(actorUID, vol.GetName()) + if vol.GetEmptyDir() != nil { + if err := resetEmptyDir(hostPath); err != nil { + return err + } + continue + } ext := vol.GetExternal() if ext == nil { continue } - hostPath := ateletpath.VolumeHostPath(actorUID, vol.GetName()) if err := os.MkdirAll(hostPath, 0o750); err != nil { return fmt.Errorf("failed to create mount point %q: %w", hostPath, err) } @@ -56,6 +62,16 @@ func (s *AteomHerder) mountExternalVolumes(ctx context.Context, actorUID string, return nil } +func resetEmptyDir(hostPath string) error { + if err := os.RemoveAll(hostPath); err != nil { + return fmt.Errorf("failed to clear empty dir %q: %w", hostPath, err) + } + if err := os.MkdirAll(hostPath, 0o750); err != nil { + return fmt.Errorf("failed to create empty dir %q: %w", hostPath, err) + } + return nil +} + func (s *AteomHerder) unmountExternalVolumes(ctx context.Context, actorUID string, volumes []*ateletpb.Volume) error { var errs []error for _, vol := range volumes { diff --git a/cmd/atelet/volumes_test.go b/cmd/atelet/volumes_test.go index e3b13ac9b3..afa29ff40f 100644 --- a/cmd/atelet/volumes_test.go +++ b/cmd/atelet/volumes_test.go @@ -570,3 +570,23 @@ func TestDirectCSIDriverConfigGetter(t *testing.T) { t.Fatalf("expected error for missing driver, got nil") } } + +func TestResetEmptyDirClearsPreviousContents(t *testing.T) { + dir := filepath.Join(t.TempDir(), "volumes", "shared") + if err := os.MkdirAll(dir, 0o750); err != nil { + t.Fatal(err) + } + if err := os.WriteFile(filepath.Join(dir, "stale"), []byte("x"), 0o600); err != nil { + t.Fatal(err) + } + if err := resetEmptyDir(dir); err != nil { + t.Fatalf("resetEmptyDir: %v", err) + } + entries, err := os.ReadDir(dir) + if err != nil { + t.Fatalf("ReadDir: %v", err) + } + if len(entries) != 0 { + t.Fatalf("dir still has %d entries after reset", len(entries)) + } +} diff --git a/internal/proto/ateletpb/atelet.pb.go b/internal/proto/ateletpb/atelet.pb.go index 90b451c20d..ab16f0bf85 100644 --- a/internal/proto/ateletpb/atelet.pb.go +++ b/internal/proto/ateletpb/atelet.pb.go @@ -1332,6 +1332,43 @@ func (*DurableDirVolume) Descriptor() ([]byte, []int) { return file_atelet_proto_rawDescGZIP(), []int{18} } +// EmptyDirVolume is an empty host directory at the external volume path. +type EmptyDirVolume struct { + state protoimpl.MessageState `protogen:"open.v1"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *EmptyDirVolume) Reset() { + *x = EmptyDirVolume{} + mi := &file_atelet_proto_msgTypes[19] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *EmptyDirVolume) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*EmptyDirVolume) ProtoMessage() {} + +func (x *EmptyDirVolume) ProtoReflect() protoreflect.Message { + mi := &file_atelet_proto_msgTypes[19] + 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 EmptyDirVolume.ProtoReflect.Descriptor instead. +func (*EmptyDirVolume) Descriptor() ([]byte, []int) { + return file_atelet_proto_rawDescGZIP(), []int{19} +} + type ExternalVolumeSource struct { state protoimpl.MessageState `protogen:"open.v1"` StorageVolumeId string `protobuf:"bytes,1,opt,name=storage_volume_id,json=storageVolumeId,proto3" json:"storage_volume_id,omitempty"` @@ -1346,7 +1383,7 @@ type ExternalVolumeSource struct { func (x *ExternalVolumeSource) Reset() { *x = ExternalVolumeSource{} - mi := &file_atelet_proto_msgTypes[19] + mi := &file_atelet_proto_msgTypes[20] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1358,7 +1395,7 @@ func (x *ExternalVolumeSource) String() string { func (*ExternalVolumeSource) ProtoMessage() {} func (x *ExternalVolumeSource) ProtoReflect() protoreflect.Message { - mi := &file_atelet_proto_msgTypes[19] + mi := &file_atelet_proto_msgTypes[20] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1371,7 +1408,7 @@ func (x *ExternalVolumeSource) ProtoReflect() protoreflect.Message { // Deprecated: Use ExternalVolumeSource.ProtoReflect.Descriptor instead. func (*ExternalVolumeSource) Descriptor() ([]byte, []int) { - return file_atelet_proto_rawDescGZIP(), []int{19} + return file_atelet_proto_rawDescGZIP(), []int{20} } func (x *ExternalVolumeSource) GetStorageVolumeId() string { @@ -1411,7 +1448,7 @@ type ImageVolumeSource struct { func (x *ImageVolumeSource) Reset() { *x = ImageVolumeSource{} - mi := &file_atelet_proto_msgTypes[20] + mi := &file_atelet_proto_msgTypes[21] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1423,7 +1460,7 @@ func (x *ImageVolumeSource) String() string { func (*ImageVolumeSource) ProtoMessage() {} func (x *ImageVolumeSource) ProtoReflect() protoreflect.Message { - mi := &file_atelet_proto_msgTypes[20] + mi := &file_atelet_proto_msgTypes[21] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1436,7 +1473,7 @@ func (x *ImageVolumeSource) ProtoReflect() protoreflect.Message { // Deprecated: Use ImageVolumeSource.ProtoReflect.Descriptor instead. func (*ImageVolumeSource) Descriptor() ([]byte, []int) { - return file_atelet_proto_rawDescGZIP(), []int{20} + return file_atelet_proto_rawDescGZIP(), []int{21} } func (x *ImageVolumeSource) GetReference() string { @@ -1458,7 +1495,7 @@ type ActorMetadataItem struct { func (x *ActorMetadataItem) Reset() { *x = ActorMetadataItem{} - mi := &file_atelet_proto_msgTypes[21] + mi := &file_atelet_proto_msgTypes[22] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1470,7 +1507,7 @@ func (x *ActorMetadataItem) String() string { func (*ActorMetadataItem) ProtoMessage() {} func (x *ActorMetadataItem) ProtoReflect() protoreflect.Message { - mi := &file_atelet_proto_msgTypes[21] + mi := &file_atelet_proto_msgTypes[22] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1483,7 +1520,7 @@ func (x *ActorMetadataItem) ProtoReflect() protoreflect.Message { // Deprecated: Use ActorMetadataItem.ProtoReflect.Descriptor instead. func (*ActorMetadataItem) Descriptor() ([]byte, []int) { - return file_atelet_proto_rawDescGZIP(), []int{21} + return file_atelet_proto_rawDescGZIP(), []int{22} } func (x *ActorMetadataItem) GetField() ActorMetadataField { @@ -1511,7 +1548,7 @@ type ActorMetadataDataSource struct { func (x *ActorMetadataDataSource) Reset() { *x = ActorMetadataDataSource{} - mi := &file_atelet_proto_msgTypes[22] + mi := &file_atelet_proto_msgTypes[23] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1523,7 +1560,7 @@ func (x *ActorMetadataDataSource) String() string { func (*ActorMetadataDataSource) ProtoMessage() {} func (x *ActorMetadataDataSource) ProtoReflect() protoreflect.Message { - mi := &file_atelet_proto_msgTypes[22] + mi := &file_atelet_proto_msgTypes[23] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1536,7 +1573,7 @@ func (x *ActorMetadataDataSource) ProtoReflect() protoreflect.Message { // Deprecated: Use ActorMetadataDataSource.ProtoReflect.Descriptor instead. func (*ActorMetadataDataSource) Descriptor() ([]byte, []int) { - return file_atelet_proto_rawDescGZIP(), []int{22} + return file_atelet_proto_rawDescGZIP(), []int{23} } func (x *ActorMetadataDataSource) GetItems() []*ActorMetadataItem { @@ -1557,7 +1594,7 @@ type TrustBundleDataSource struct { func (x *TrustBundleDataSource) Reset() { *x = TrustBundleDataSource{} - mi := &file_atelet_proto_msgTypes[23] + mi := &file_atelet_proto_msgTypes[24] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1569,7 +1606,7 @@ func (x *TrustBundleDataSource) String() string { func (*TrustBundleDataSource) ProtoMessage() {} func (x *TrustBundleDataSource) ProtoReflect() protoreflect.Message { - mi := &file_atelet_proto_msgTypes[23] + mi := &file_atelet_proto_msgTypes[24] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1582,7 +1619,7 @@ func (x *TrustBundleDataSource) ProtoReflect() protoreflect.Message { // Deprecated: Use TrustBundleDataSource.ProtoReflect.Descriptor instead. func (*TrustBundleDataSource) Descriptor() ([]byte, []int) { - return file_atelet_proto_rawDescGZIP(), []int{23} + return file_atelet_proto_rawDescGZIP(), []int{24} } func (x *TrustBundleDataSource) GetPath() string { @@ -1612,7 +1649,7 @@ type SystemInfoDataSource struct { func (x *SystemInfoDataSource) Reset() { *x = SystemInfoDataSource{} - mi := &file_atelet_proto_msgTypes[24] + mi := &file_atelet_proto_msgTypes[25] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1624,7 +1661,7 @@ func (x *SystemInfoDataSource) String() string { func (*SystemInfoDataSource) ProtoMessage() {} func (x *SystemInfoDataSource) ProtoReflect() protoreflect.Message { - mi := &file_atelet_proto_msgTypes[24] + mi := &file_atelet_proto_msgTypes[25] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1637,7 +1674,7 @@ func (x *SystemInfoDataSource) ProtoReflect() protoreflect.Message { // Deprecated: Use SystemInfoDataSource.ProtoReflect.Descriptor instead. func (*SystemInfoDataSource) Descriptor() ([]byte, []int) { - return file_atelet_proto_rawDescGZIP(), []int{24} + return file_atelet_proto_rawDescGZIP(), []int{25} } func (x *SystemInfoDataSource) GetDataSource() isSystemInfoDataSource_DataSource { @@ -1693,7 +1730,7 @@ type SystemInfoVolume struct { func (x *SystemInfoVolume) Reset() { *x = SystemInfoVolume{} - mi := &file_atelet_proto_msgTypes[25] + mi := &file_atelet_proto_msgTypes[26] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1705,7 +1742,7 @@ func (x *SystemInfoVolume) String() string { func (*SystemInfoVolume) ProtoMessage() {} func (x *SystemInfoVolume) ProtoReflect() protoreflect.Message { - mi := &file_atelet_proto_msgTypes[25] + mi := &file_atelet_proto_msgTypes[26] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1718,7 +1755,7 @@ func (x *SystemInfoVolume) ProtoReflect() protoreflect.Message { // Deprecated: Use SystemInfoVolume.ProtoReflect.Descriptor instead. func (*SystemInfoVolume) Descriptor() ([]byte, []int) { - return file_atelet_proto_rawDescGZIP(), []int{25} + return file_atelet_proto_rawDescGZIP(), []int{26} } func (x *SystemInfoVolume) GetDataSources() []*SystemInfoDataSource { @@ -1737,6 +1774,7 @@ type Volume struct { // *Volume_External // *Volume_SystemInfo // *Volume_Image + // *Volume_EmptyDir Source isVolume_Source `protobuf_oneof:"source"` unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache @@ -1744,7 +1782,7 @@ type Volume struct { func (x *Volume) Reset() { *x = Volume{} - mi := &file_atelet_proto_msgTypes[26] + mi := &file_atelet_proto_msgTypes[27] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1756,7 +1794,7 @@ func (x *Volume) String() string { func (*Volume) ProtoMessage() {} func (x *Volume) ProtoReflect() protoreflect.Message { - mi := &file_atelet_proto_msgTypes[26] + mi := &file_atelet_proto_msgTypes[27] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1769,7 +1807,7 @@ func (x *Volume) ProtoReflect() protoreflect.Message { // Deprecated: Use Volume.ProtoReflect.Descriptor instead. func (*Volume) Descriptor() ([]byte, []int) { - return file_atelet_proto_rawDescGZIP(), []int{26} + return file_atelet_proto_rawDescGZIP(), []int{27} } func (x *Volume) GetName() string { @@ -1822,6 +1860,15 @@ func (x *Volume) GetImage() *ImageVolumeSource { return nil } +func (x *Volume) GetEmptyDir() *EmptyDirVolume { + if x != nil { + if x, ok := x.Source.(*Volume_EmptyDir); ok { + return x.EmptyDir + } + } + return nil +} + type isVolume_Source interface { isVolume_Source() } @@ -1842,6 +1889,10 @@ type Volume_Image struct { Image *ImageVolumeSource `protobuf:"bytes,5,opt,name=image,proto3,oneof"` } +type Volume_EmptyDir struct { + EmptyDir *EmptyDirVolume `protobuf:"bytes,6,opt,name=empty_dir,json=emptyDir,proto3,oneof"` +} + func (*Volume_DurableDir) isVolume_Source() {} func (*Volume_External) isVolume_Source() {} @@ -1850,6 +1901,8 @@ func (*Volume_SystemInfo) isVolume_Source() {} func (*Volume_Image) isVolume_Source() {} +func (*Volume_EmptyDir) isVolume_Source() {} + type VolumeMount struct { state protoimpl.MessageState `protogen:"open.v1"` Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` @@ -1860,7 +1913,7 @@ type VolumeMount struct { func (x *VolumeMount) Reset() { *x = VolumeMount{} - mi := &file_atelet_proto_msgTypes[27] + mi := &file_atelet_proto_msgTypes[28] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1872,7 +1925,7 @@ func (x *VolumeMount) String() string { func (*VolumeMount) ProtoMessage() {} func (x *VolumeMount) ProtoReflect() protoreflect.Message { - mi := &file_atelet_proto_msgTypes[27] + mi := &file_atelet_proto_msgTypes[28] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1885,7 +1938,7 @@ func (x *VolumeMount) ProtoReflect() protoreflect.Message { // Deprecated: Use VolumeMount.ProtoReflect.Descriptor instead. func (*VolumeMount) Descriptor() ([]byte, []int) { - return file_atelet_proto_rawDescGZIP(), []int{27} + return file_atelet_proto_rawDescGZIP(), []int{28} } func (x *VolumeMount) GetName() string { @@ -1921,7 +1974,7 @@ type Container struct { func (x *Container) Reset() { *x = Container{} - mi := &file_atelet_proto_msgTypes[28] + mi := &file_atelet_proto_msgTypes[29] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1933,7 +1986,7 @@ func (x *Container) String() string { func (*Container) ProtoMessage() {} func (x *Container) ProtoReflect() protoreflect.Message { - mi := &file_atelet_proto_msgTypes[28] + mi := &file_atelet_proto_msgTypes[29] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1946,7 +1999,7 @@ func (x *Container) ProtoReflect() protoreflect.Message { // Deprecated: Use Container.ProtoReflect.Descriptor instead. func (*Container) Descriptor() ([]byte, []int) { - return file_atelet_proto_rawDescGZIP(), []int{28} + return file_atelet_proto_rawDescGZIP(), []int{29} } func (x *Container) GetName() string { @@ -2022,7 +2075,7 @@ type SecurityContext struct { func (x *SecurityContext) Reset() { *x = SecurityContext{} - mi := &file_atelet_proto_msgTypes[29] + mi := &file_atelet_proto_msgTypes[30] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2034,7 +2087,7 @@ func (x *SecurityContext) String() string { func (*SecurityContext) ProtoMessage() {} func (x *SecurityContext) ProtoReflect() protoreflect.Message { - mi := &file_atelet_proto_msgTypes[29] + mi := &file_atelet_proto_msgTypes[30] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2047,7 +2100,7 @@ func (x *SecurityContext) ProtoReflect() protoreflect.Message { // Deprecated: Use SecurityContext.ProtoReflect.Descriptor instead. func (*SecurityContext) Descriptor() ([]byte, []int) { - return file_atelet_proto_rawDescGZIP(), []int{29} + return file_atelet_proto_rawDescGZIP(), []int{30} } func (x *SecurityContext) GetCapabilities() *Capabilities { @@ -2069,7 +2122,7 @@ type Capabilities struct { func (x *Capabilities) Reset() { *x = Capabilities{} - mi := &file_atelet_proto_msgTypes[30] + mi := &file_atelet_proto_msgTypes[31] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2081,7 +2134,7 @@ func (x *Capabilities) String() string { func (*Capabilities) ProtoMessage() {} func (x *Capabilities) ProtoReflect() protoreflect.Message { - mi := &file_atelet_proto_msgTypes[30] + mi := &file_atelet_proto_msgTypes[31] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2094,7 +2147,7 @@ func (x *Capabilities) ProtoReflect() protoreflect.Message { // Deprecated: Use Capabilities.ProtoReflect.Descriptor instead. func (*Capabilities) Descriptor() ([]byte, []int) { - return file_atelet_proto_rawDescGZIP(), []int{30} + return file_atelet_proto_rawDescGZIP(), []int{31} } func (x *Capabilities) GetAdd() []string { @@ -2125,7 +2178,7 @@ type ResourceLimits struct { func (x *ResourceLimits) Reset() { *x = ResourceLimits{} - mi := &file_atelet_proto_msgTypes[31] + mi := &file_atelet_proto_msgTypes[32] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2137,7 +2190,7 @@ func (x *ResourceLimits) String() string { func (*ResourceLimits) ProtoMessage() {} func (x *ResourceLimits) ProtoReflect() protoreflect.Message { - mi := &file_atelet_proto_msgTypes[31] + mi := &file_atelet_proto_msgTypes[32] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2150,7 +2203,7 @@ func (x *ResourceLimits) ProtoReflect() protoreflect.Message { // Deprecated: Use ResourceLimits.ProtoReflect.Descriptor instead. func (*ResourceLimits) Descriptor() ([]byte, []int) { - return file_atelet_proto_rawDescGZIP(), []int{31} + return file_atelet_proto_rawDescGZIP(), []int{32} } func (x *ResourceLimits) GetMemoryBytes() int64 { @@ -2177,7 +2230,7 @@ type EnvEntry struct { func (x *EnvEntry) Reset() { *x = EnvEntry{} - mi := &file_atelet_proto_msgTypes[32] + mi := &file_atelet_proto_msgTypes[33] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2189,7 +2242,7 @@ func (x *EnvEntry) String() string { func (*EnvEntry) ProtoMessage() {} func (x *EnvEntry) ProtoReflect() protoreflect.Message { - mi := &file_atelet_proto_msgTypes[32] + mi := &file_atelet_proto_msgTypes[33] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2202,7 +2255,7 @@ func (x *EnvEntry) ProtoReflect() protoreflect.Message { // Deprecated: Use EnvEntry.ProtoReflect.Descriptor instead. func (*EnvEntry) Descriptor() ([]byte, []int) { - return file_atelet_proto_rawDescGZIP(), []int{32} + return file_atelet_proto_rawDescGZIP(), []int{33} } func (x *EnvEntry) GetName() string { @@ -2232,7 +2285,7 @@ type WakeupProbe struct { func (x *WakeupProbe) Reset() { *x = WakeupProbe{} - mi := &file_atelet_proto_msgTypes[33] + mi := &file_atelet_proto_msgTypes[34] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2244,7 +2297,7 @@ func (x *WakeupProbe) String() string { func (*WakeupProbe) ProtoMessage() {} func (x *WakeupProbe) ProtoReflect() protoreflect.Message { - mi := &file_atelet_proto_msgTypes[33] + mi := &file_atelet_proto_msgTypes[34] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2257,7 +2310,7 @@ func (x *WakeupProbe) ProtoReflect() protoreflect.Message { // Deprecated: Use WakeupProbe.ProtoReflect.Descriptor instead. func (*WakeupProbe) Descriptor() ([]byte, []int) { - return file_atelet_proto_rawDescGZIP(), []int{33} + return file_atelet_proto_rawDescGZIP(), []int{34} } func (x *WakeupProbe) GetHttpGet() *HTTPGetAction { @@ -2287,7 +2340,7 @@ type HTTPGetAction struct { func (x *HTTPGetAction) Reset() { *x = HTTPGetAction{} - mi := &file_atelet_proto_msgTypes[34] + mi := &file_atelet_proto_msgTypes[35] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2299,7 +2352,7 @@ func (x *HTTPGetAction) String() string { func (*HTTPGetAction) ProtoMessage() {} func (x *HTTPGetAction) ProtoReflect() protoreflect.Message { - mi := &file_atelet_proto_msgTypes[34] + mi := &file_atelet_proto_msgTypes[35] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2312,7 +2365,7 @@ func (x *HTTPGetAction) ProtoReflect() protoreflect.Message { // Deprecated: Use HTTPGetAction.ProtoReflect.Descriptor instead. func (*HTTPGetAction) Descriptor() ([]byte, []int) { - return file_atelet_proto_rawDescGZIP(), []int{34} + return file_atelet_proto_rawDescGZIP(), []int{35} } func (x *HTTPGetAction) GetPath() string { @@ -2337,7 +2390,7 @@ type RunResponse struct { func (x *RunResponse) Reset() { *x = RunResponse{} - mi := &file_atelet_proto_msgTypes[35] + mi := &file_atelet_proto_msgTypes[36] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2349,7 +2402,7 @@ func (x *RunResponse) String() string { func (*RunResponse) ProtoMessage() {} func (x *RunResponse) ProtoReflect() protoreflect.Message { - mi := &file_atelet_proto_msgTypes[35] + mi := &file_atelet_proto_msgTypes[36] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2362,7 +2415,7 @@ func (x *RunResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use RunResponse.ProtoReflect.Descriptor instead. func (*RunResponse) Descriptor() ([]byte, []int) { - return file_atelet_proto_rawDescGZIP(), []int{35} + return file_atelet_proto_rawDescGZIP(), []int{36} } type LocalCheckpointConfiguration struct { @@ -2378,7 +2431,7 @@ type LocalCheckpointConfiguration struct { func (x *LocalCheckpointConfiguration) Reset() { *x = LocalCheckpointConfiguration{} - mi := &file_atelet_proto_msgTypes[36] + mi := &file_atelet_proto_msgTypes[37] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2390,7 +2443,7 @@ func (x *LocalCheckpointConfiguration) String() string { func (*LocalCheckpointConfiguration) ProtoMessage() {} func (x *LocalCheckpointConfiguration) ProtoReflect() protoreflect.Message { - mi := &file_atelet_proto_msgTypes[36] + mi := &file_atelet_proto_msgTypes[37] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2403,7 +2456,7 @@ func (x *LocalCheckpointConfiguration) ProtoReflect() protoreflect.Message { // Deprecated: Use LocalCheckpointConfiguration.ProtoReflect.Descriptor instead. func (*LocalCheckpointConfiguration) Descriptor() ([]byte, []int) { - return file_atelet_proto_rawDescGZIP(), []int{36} + return file_atelet_proto_rawDescGZIP(), []int{37} } func (x *LocalCheckpointConfiguration) GetSnapshotName() string { @@ -2424,7 +2477,7 @@ type ExternalCheckpointConfiguration struct { func (x *ExternalCheckpointConfiguration) Reset() { *x = ExternalCheckpointConfiguration{} - mi := &file_atelet_proto_msgTypes[37] + mi := &file_atelet_proto_msgTypes[38] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2436,7 +2489,7 @@ func (x *ExternalCheckpointConfiguration) String() string { func (*ExternalCheckpointConfiguration) ProtoMessage() {} func (x *ExternalCheckpointConfiguration) ProtoReflect() protoreflect.Message { - mi := &file_atelet_proto_msgTypes[37] + mi := &file_atelet_proto_msgTypes[38] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2449,7 +2502,7 @@ func (x *ExternalCheckpointConfiguration) ProtoReflect() protoreflect.Message { // Deprecated: Use ExternalCheckpointConfiguration.ProtoReflect.Descriptor instead. func (*ExternalCheckpointConfiguration) Descriptor() ([]byte, []int) { - return file_atelet_proto_rawDescGZIP(), []int{37} + return file_atelet_proto_rawDescGZIP(), []int{38} } func (x *ExternalCheckpointConfiguration) GetSnapshotUri() string { @@ -2474,7 +2527,7 @@ type ExternalRestoreConfiguration struct { func (x *ExternalRestoreConfiguration) Reset() { *x = ExternalRestoreConfiguration{} - mi := &file_atelet_proto_msgTypes[38] + mi := &file_atelet_proto_msgTypes[39] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2486,7 +2539,7 @@ func (x *ExternalRestoreConfiguration) String() string { func (*ExternalRestoreConfiguration) ProtoMessage() {} func (x *ExternalRestoreConfiguration) ProtoReflect() protoreflect.Message { - mi := &file_atelet_proto_msgTypes[38] + mi := &file_atelet_proto_msgTypes[39] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2499,7 +2552,7 @@ func (x *ExternalRestoreConfiguration) ProtoReflect() protoreflect.Message { // Deprecated: Use ExternalRestoreConfiguration.ProtoReflect.Descriptor instead. func (*ExternalRestoreConfiguration) Descriptor() ([]byte, []int) { - return file_atelet_proto_rawDescGZIP(), []int{38} + return file_atelet_proto_rawDescGZIP(), []int{39} } func (x *ExternalRestoreConfiguration) GetSnapshotUri() string { @@ -2537,7 +2590,7 @@ type CheckpointRequest struct { func (x *CheckpointRequest) Reset() { *x = CheckpointRequest{} - mi := &file_atelet_proto_msgTypes[39] + mi := &file_atelet_proto_msgTypes[40] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2549,7 +2602,7 @@ func (x *CheckpointRequest) String() string { func (*CheckpointRequest) ProtoMessage() {} func (x *CheckpointRequest) ProtoReflect() protoreflect.Message { - mi := &file_atelet_proto_msgTypes[39] + mi := &file_atelet_proto_msgTypes[40] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2562,7 +2615,7 @@ func (x *CheckpointRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use CheckpointRequest.ProtoReflect.Descriptor instead. func (*CheckpointRequest) Descriptor() ([]byte, []int) { - return file_atelet_proto_rawDescGZIP(), []int{39} + return file_atelet_proto_rawDescGZIP(), []int{40} } func (x *CheckpointRequest) GetTargetAteomUid() string { @@ -2677,7 +2730,7 @@ type CheckpointResponse struct { func (x *CheckpointResponse) Reset() { *x = CheckpointResponse{} - mi := &file_atelet_proto_msgTypes[40] + mi := &file_atelet_proto_msgTypes[41] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2689,7 +2742,7 @@ func (x *CheckpointResponse) String() string { func (*CheckpointResponse) ProtoMessage() {} func (x *CheckpointResponse) ProtoReflect() protoreflect.Message { - mi := &file_atelet_proto_msgTypes[40] + mi := &file_atelet_proto_msgTypes[41] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2702,7 +2755,7 @@ func (x *CheckpointResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use CheckpointResponse.ProtoReflect.Descriptor instead. func (*CheckpointResponse) Descriptor() ([]byte, []int) { - return file_atelet_proto_rawDescGZIP(), []int{40} + return file_atelet_proto_rawDescGZIP(), []int{41} } type UploadPausedCheckpointRequest struct { @@ -2730,7 +2783,7 @@ type UploadPausedCheckpointRequest struct { func (x *UploadPausedCheckpointRequest) Reset() { *x = UploadPausedCheckpointRequest{} - mi := &file_atelet_proto_msgTypes[41] + mi := &file_atelet_proto_msgTypes[42] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2742,7 +2795,7 @@ func (x *UploadPausedCheckpointRequest) String() string { func (*UploadPausedCheckpointRequest) ProtoMessage() {} func (x *UploadPausedCheckpointRequest) ProtoReflect() protoreflect.Message { - mi := &file_atelet_proto_msgTypes[41] + mi := &file_atelet_proto_msgTypes[42] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2755,7 +2808,7 @@ func (x *UploadPausedCheckpointRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use UploadPausedCheckpointRequest.ProtoReflect.Descriptor instead. func (*UploadPausedCheckpointRequest) Descriptor() ([]byte, []int) { - return file_atelet_proto_rawDescGZIP(), []int{41} + return file_atelet_proto_rawDescGZIP(), []int{42} } func (x *UploadPausedCheckpointRequest) GetAtespace() string { @@ -2822,7 +2875,7 @@ type UploadPausedCheckpointResponse struct { func (x *UploadPausedCheckpointResponse) Reset() { *x = UploadPausedCheckpointResponse{} - mi := &file_atelet_proto_msgTypes[42] + mi := &file_atelet_proto_msgTypes[43] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2834,7 +2887,7 @@ func (x *UploadPausedCheckpointResponse) String() string { func (*UploadPausedCheckpointResponse) ProtoMessage() {} func (x *UploadPausedCheckpointResponse) ProtoReflect() protoreflect.Message { - mi := &file_atelet_proto_msgTypes[42] + mi := &file_atelet_proto_msgTypes[43] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2847,7 +2900,7 @@ func (x *UploadPausedCheckpointResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use UploadPausedCheckpointResponse.ProtoReflect.Descriptor instead. func (*UploadPausedCheckpointResponse) Descriptor() ([]byte, []int) { - return file_atelet_proto_rawDescGZIP(), []int{42} + return file_atelet_proto_rawDescGZIP(), []int{43} } type RestoreRequest struct { @@ -2886,7 +2939,7 @@ type RestoreRequest struct { func (x *RestoreRequest) Reset() { *x = RestoreRequest{} - mi := &file_atelet_proto_msgTypes[43] + mi := &file_atelet_proto_msgTypes[44] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2898,7 +2951,7 @@ func (x *RestoreRequest) String() string { func (*RestoreRequest) ProtoMessage() {} func (x *RestoreRequest) ProtoReflect() protoreflect.Message { - mi := &file_atelet_proto_msgTypes[43] + mi := &file_atelet_proto_msgTypes[44] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2911,7 +2964,7 @@ func (x *RestoreRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use RestoreRequest.ProtoReflect.Descriptor instead. func (*RestoreRequest) Descriptor() ([]byte, []int) { - return file_atelet_proto_rawDescGZIP(), []int{43} + return file_atelet_proto_rawDescGZIP(), []int{44} } func (x *RestoreRequest) GetTargetAteomUid() string { @@ -3054,7 +3107,7 @@ type RestoreResponse struct { func (x *RestoreResponse) Reset() { *x = RestoreResponse{} - mi := &file_atelet_proto_msgTypes[44] + mi := &file_atelet_proto_msgTypes[45] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3066,7 +3119,7 @@ func (x *RestoreResponse) String() string { func (*RestoreResponse) ProtoMessage() {} func (x *RestoreResponse) ProtoReflect() protoreflect.Message { - mi := &file_atelet_proto_msgTypes[44] + mi := &file_atelet_proto_msgTypes[45] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3079,7 +3132,7 @@ func (x *RestoreResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use RestoreResponse.ProtoReflect.Descriptor instead. func (*RestoreResponse) Descriptor() ([]byte, []int) { - return file_atelet_proto_rawDescGZIP(), []int{44} + return file_atelet_proto_rawDescGZIP(), []int{45} } var File_atelet_proto protoreflect.FileDescriptor @@ -3171,7 +3224,8 @@ const file_atelet_proto_rawDesc = "" + "containers\x18\x01 \x03(\v2\x11.atelet.ContainerR\n" + "containers\x12(\n" + "\avolumes\x18\x02 \x03(\v2\x0e.atelet.VolumeR\avolumes\"\x12\n" + - "\x10DurableDirVolume\"\x9b\x03\n" + + "\x10DurableDirVolume\"\x10\n" + + "\x0eEmptyDirVolume\"\x9b\x03\n" + "\x14ExternalVolumeSource\x12*\n" + "\x11storage_volume_id\x18\x01 \x01(\tR\x0fstorageVolumeId\x12\x1f\n" + "\vvolume_type\x18\x02 \x01(\tR\n" + @@ -3199,7 +3253,7 @@ const file_atelet_proto_rawDesc = "" + "\ftrust_bundle\x18\x02 \x01(\v2\x1d.atelet.TrustBundleDataSourceH\x00R\vtrustBundleB\r\n" + "\vdata_source\"S\n" + "\x10SystemInfoVolume\x12?\n" + - "\fdata_sources\x18\x01 \x03(\v2\x1c.atelet.SystemInfoDataSourceR\vdataSources\"\x8f\x02\n" + + "\fdata_sources\x18\x01 \x03(\v2\x1c.atelet.SystemInfoDataSourceR\vdataSources\"\xc6\x02\n" + "\x06Volume\x12\x12\n" + "\x04name\x18\x01 \x01(\tR\x04name\x12;\n" + "\vdurable_dir\x18\x02 \x01(\v2\x18.atelet.DurableDirVolumeH\x00R\n" + @@ -3207,7 +3261,8 @@ const file_atelet_proto_rawDesc = "" + "\bexternal\x18\x03 \x01(\v2\x1c.atelet.ExternalVolumeSourceH\x00R\bexternal\x12;\n" + "\vsystem_info\x18\x04 \x01(\v2\x18.atelet.SystemInfoVolumeH\x00R\n" + "systemInfo\x121\n" + - "\x05image\x18\x05 \x01(\v2\x19.atelet.ImageVolumeSourceH\x00R\x05imageB\b\n" + + "\x05image\x18\x05 \x01(\v2\x19.atelet.ImageVolumeSourceH\x00R\x05image\x125\n" + + "\tempty_dir\x18\x06 \x01(\v2\x16.atelet.EmptyDirVolumeH\x00R\bemptyDirB\b\n" + "\x06source\"@\n" + "\vVolumeMount\x12\x12\n" + "\x04name\x18\x01 \x01(\tR\x04name\x12\x1d\n" + @@ -3335,7 +3390,7 @@ func file_atelet_proto_rawDescGZIP() []byte { } var file_atelet_proto_enumTypes = make([]protoimpl.EnumInfo, 3) -var file_atelet_proto_msgTypes = make([]protoimpl.MessageInfo, 50) +var file_atelet_proto_msgTypes = make([]protoimpl.MessageInfo, 51) var file_atelet_proto_goTypes = []any{ (ActorMetadataField)(0), // 0: atelet.ActorMetadataField (CheckpointType)(0), // 1: atelet.CheckpointType @@ -3359,106 +3414,108 @@ var file_atelet_proto_goTypes = []any{ (*SandboxAssets)(nil), // 19: atelet.SandboxAssets (*WorkloadSpec)(nil), // 20: atelet.WorkloadSpec (*DurableDirVolume)(nil), // 21: atelet.DurableDirVolume - (*ExternalVolumeSource)(nil), // 22: atelet.ExternalVolumeSource - (*ImageVolumeSource)(nil), // 23: atelet.ImageVolumeSource - (*ActorMetadataItem)(nil), // 24: atelet.ActorMetadataItem - (*ActorMetadataDataSource)(nil), // 25: atelet.ActorMetadataDataSource - (*TrustBundleDataSource)(nil), // 26: atelet.TrustBundleDataSource - (*SystemInfoDataSource)(nil), // 27: atelet.SystemInfoDataSource - (*SystemInfoVolume)(nil), // 28: atelet.SystemInfoVolume - (*Volume)(nil), // 29: atelet.Volume - (*VolumeMount)(nil), // 30: atelet.VolumeMount - (*Container)(nil), // 31: atelet.Container - (*SecurityContext)(nil), // 32: atelet.SecurityContext - (*Capabilities)(nil), // 33: atelet.Capabilities - (*ResourceLimits)(nil), // 34: atelet.ResourceLimits - (*EnvEntry)(nil), // 35: atelet.EnvEntry - (*WakeupProbe)(nil), // 36: atelet.WakeupProbe - (*HTTPGetAction)(nil), // 37: atelet.HTTPGetAction - (*RunResponse)(nil), // 38: atelet.RunResponse - (*LocalCheckpointConfiguration)(nil), // 39: atelet.LocalCheckpointConfiguration - (*ExternalCheckpointConfiguration)(nil), // 40: atelet.ExternalCheckpointConfiguration - (*ExternalRestoreConfiguration)(nil), // 41: atelet.ExternalRestoreConfiguration - (*CheckpointRequest)(nil), // 42: atelet.CheckpointRequest - (*CheckpointResponse)(nil), // 43: atelet.CheckpointResponse - (*UploadPausedCheckpointRequest)(nil), // 44: atelet.UploadPausedCheckpointRequest - (*UploadPausedCheckpointResponse)(nil), // 45: atelet.UploadPausedCheckpointResponse - (*RestoreRequest)(nil), // 46: atelet.RestoreRequest - (*RestoreResponse)(nil), // 47: atelet.RestoreResponse - nil, // 48: atelet.HardwareIdentity.AttributesEntry - nil, // 49: atelet.ArchAssets.FilesEntry - nil, // 50: atelet.SandboxAssets.AssetsEntry - nil, // 51: atelet.ExternalVolumeSource.VolumeContextEntry - nil, // 52: atelet.ExternalVolumeSource.PublishContextEntry + (*EmptyDirVolume)(nil), // 22: atelet.EmptyDirVolume + (*ExternalVolumeSource)(nil), // 23: atelet.ExternalVolumeSource + (*ImageVolumeSource)(nil), // 24: atelet.ImageVolumeSource + (*ActorMetadataItem)(nil), // 25: atelet.ActorMetadataItem + (*ActorMetadataDataSource)(nil), // 26: atelet.ActorMetadataDataSource + (*TrustBundleDataSource)(nil), // 27: atelet.TrustBundleDataSource + (*SystemInfoDataSource)(nil), // 28: atelet.SystemInfoDataSource + (*SystemInfoVolume)(nil), // 29: atelet.SystemInfoVolume + (*Volume)(nil), // 30: atelet.Volume + (*VolumeMount)(nil), // 31: atelet.VolumeMount + (*Container)(nil), // 32: atelet.Container + (*SecurityContext)(nil), // 33: atelet.SecurityContext + (*Capabilities)(nil), // 34: atelet.Capabilities + (*ResourceLimits)(nil), // 35: atelet.ResourceLimits + (*EnvEntry)(nil), // 36: atelet.EnvEntry + (*WakeupProbe)(nil), // 37: atelet.WakeupProbe + (*HTTPGetAction)(nil), // 38: atelet.HTTPGetAction + (*RunResponse)(nil), // 39: atelet.RunResponse + (*LocalCheckpointConfiguration)(nil), // 40: atelet.LocalCheckpointConfiguration + (*ExternalCheckpointConfiguration)(nil), // 41: atelet.ExternalCheckpointConfiguration + (*ExternalRestoreConfiguration)(nil), // 42: atelet.ExternalRestoreConfiguration + (*CheckpointRequest)(nil), // 43: atelet.CheckpointRequest + (*CheckpointResponse)(nil), // 44: atelet.CheckpointResponse + (*UploadPausedCheckpointRequest)(nil), // 45: atelet.UploadPausedCheckpointRequest + (*UploadPausedCheckpointResponse)(nil), // 46: atelet.UploadPausedCheckpointResponse + (*RestoreRequest)(nil), // 47: atelet.RestoreRequest + (*RestoreResponse)(nil), // 48: atelet.RestoreResponse + nil, // 49: atelet.HardwareIdentity.AttributesEntry + nil, // 50: atelet.ArchAssets.FilesEntry + nil, // 51: atelet.SandboxAssets.AssetsEntry + nil, // 52: atelet.ExternalVolumeSource.VolumeContextEntry + nil, // 53: atelet.ExternalVolumeSource.PublishContextEntry } var file_atelet_proto_depIdxs = []int32{ 5, // 0: atelet.RegisterWorkerRequest.capacity:type_name -> atelet.WorkerResources 4, // 1: atelet.RegisterWorkerRequest.hardware:type_name -> atelet.HardwareIdentity - 48, // 2: atelet.HardwareIdentity.attributes:type_name -> atelet.HardwareIdentity.AttributesEntry + 49, // 2: atelet.HardwareIdentity.attributes:type_name -> atelet.HardwareIdentity.AttributesEntry 6, // 3: atelet.WorkerResources.resources:type_name -> atelet.Resources 7, // 4: atelet.Resources.limits:type_name -> atelet.Limits 20, // 5: atelet.TerminateRequest.spec:type_name -> atelet.WorkloadSpec 20, // 6: atelet.RunRequest.spec:type_name -> atelet.WorkloadSpec 19, // 7: atelet.RunRequest.sandbox_assets:type_name -> atelet.SandboxAssets 16, // 8: atelet.RunRequest.egress_gateway:type_name -> atelet.EgressGateway - 49, // 9: atelet.ArchAssets.files:type_name -> atelet.ArchAssets.FilesEntry - 50, // 10: atelet.SandboxAssets.assets:type_name -> atelet.SandboxAssets.AssetsEntry - 31, // 11: atelet.WorkloadSpec.containers:type_name -> atelet.Container - 29, // 12: atelet.WorkloadSpec.volumes:type_name -> atelet.Volume - 51, // 13: atelet.ExternalVolumeSource.volume_context:type_name -> atelet.ExternalVolumeSource.VolumeContextEntry - 52, // 14: atelet.ExternalVolumeSource.publish_context:type_name -> atelet.ExternalVolumeSource.PublishContextEntry + 50, // 9: atelet.ArchAssets.files:type_name -> atelet.ArchAssets.FilesEntry + 51, // 10: atelet.SandboxAssets.assets:type_name -> atelet.SandboxAssets.AssetsEntry + 32, // 11: atelet.WorkloadSpec.containers:type_name -> atelet.Container + 30, // 12: atelet.WorkloadSpec.volumes:type_name -> atelet.Volume + 52, // 13: atelet.ExternalVolumeSource.volume_context:type_name -> atelet.ExternalVolumeSource.VolumeContextEntry + 53, // 14: atelet.ExternalVolumeSource.publish_context:type_name -> atelet.ExternalVolumeSource.PublishContextEntry 0, // 15: atelet.ActorMetadataItem.field:type_name -> atelet.ActorMetadataField - 24, // 16: atelet.ActorMetadataDataSource.items:type_name -> atelet.ActorMetadataItem - 25, // 17: atelet.SystemInfoDataSource.actor_metadata:type_name -> atelet.ActorMetadataDataSource - 26, // 18: atelet.SystemInfoDataSource.trust_bundle:type_name -> atelet.TrustBundleDataSource - 27, // 19: atelet.SystemInfoVolume.data_sources:type_name -> atelet.SystemInfoDataSource + 25, // 16: atelet.ActorMetadataDataSource.items:type_name -> atelet.ActorMetadataItem + 26, // 17: atelet.SystemInfoDataSource.actor_metadata:type_name -> atelet.ActorMetadataDataSource + 27, // 18: atelet.SystemInfoDataSource.trust_bundle:type_name -> atelet.TrustBundleDataSource + 28, // 19: atelet.SystemInfoVolume.data_sources:type_name -> atelet.SystemInfoDataSource 21, // 20: atelet.Volume.durable_dir:type_name -> atelet.DurableDirVolume - 22, // 21: atelet.Volume.external:type_name -> atelet.ExternalVolumeSource - 28, // 22: atelet.Volume.system_info:type_name -> atelet.SystemInfoVolume - 23, // 23: atelet.Volume.image:type_name -> atelet.ImageVolumeSource - 35, // 24: atelet.Container.env:type_name -> atelet.EnvEntry - 36, // 25: atelet.Container.wakeup_probe:type_name -> atelet.WakeupProbe - 30, // 26: atelet.Container.volume_mounts:type_name -> atelet.VolumeMount - 32, // 27: atelet.Container.security_context:type_name -> atelet.SecurityContext - 34, // 28: atelet.Container.resources:type_name -> atelet.ResourceLimits - 33, // 29: atelet.SecurityContext.capabilities:type_name -> atelet.Capabilities - 37, // 30: atelet.WakeupProbe.http_get:type_name -> atelet.HTTPGetAction - 20, // 31: atelet.CheckpointRequest.spec:type_name -> atelet.WorkloadSpec - 1, // 32: atelet.CheckpointRequest.type:type_name -> atelet.CheckpointType - 39, // 33: atelet.CheckpointRequest.local_config:type_name -> atelet.LocalCheckpointConfiguration - 40, // 34: atelet.CheckpointRequest.external_config:type_name -> atelet.ExternalCheckpointConfiguration - 2, // 35: atelet.CheckpointRequest.fidelity:type_name -> atelet.SnapshotFidelity - 2, // 36: atelet.UploadPausedCheckpointRequest.desired_fidelity:type_name -> atelet.SnapshotFidelity - 20, // 37: atelet.RestoreRequest.spec:type_name -> atelet.WorkloadSpec - 1, // 38: atelet.RestoreRequest.type:type_name -> atelet.CheckpointType - 39, // 39: atelet.RestoreRequest.local_config:type_name -> atelet.LocalCheckpointConfiguration - 41, // 40: atelet.RestoreRequest.external_config:type_name -> atelet.ExternalRestoreConfiguration - 2, // 41: atelet.RestoreRequest.fidelity:type_name -> atelet.SnapshotFidelity - 16, // 42: atelet.RestoreRequest.egress_gateway:type_name -> atelet.EgressGateway - 19, // 43: atelet.RestoreRequest.sandbox_assets:type_name -> atelet.SandboxAssets - 17, // 44: atelet.ArchAssets.FilesEntry.value:type_name -> atelet.AssetFile - 18, // 45: atelet.SandboxAssets.AssetsEntry.value:type_name -> atelet.ArchAssets - 11, // 46: atelet.AteomSupport.MintActorCertificate:input_type -> atelet.MintActorCertificateRequest - 3, // 47: atelet.AteomSupport.RegisterWorker:input_type -> atelet.RegisterWorkerRequest - 9, // 48: atelet.AteomSupport.RequestActorSuspend:input_type -> atelet.RequestActorSuspendRequest - 15, // 49: atelet.AteomHerder.Run:input_type -> atelet.RunRequest - 42, // 50: atelet.AteomHerder.Checkpoint:input_type -> atelet.CheckpointRequest - 46, // 51: atelet.AteomHerder.Restore:input_type -> atelet.RestoreRequest - 44, // 52: atelet.AteomHerder.UploadPausedCheckpoint:input_type -> atelet.UploadPausedCheckpointRequest - 13, // 53: atelet.AteomHerder.Terminate:input_type -> atelet.TerminateRequest - 12, // 54: atelet.AteomSupport.MintActorCertificate:output_type -> atelet.MintActorCertificateResponse - 8, // 55: atelet.AteomSupport.RegisterWorker:output_type -> atelet.RegisterWorkerResponse - 10, // 56: atelet.AteomSupport.RequestActorSuspend:output_type -> atelet.RequestActorSuspendResponse - 38, // 57: atelet.AteomHerder.Run:output_type -> atelet.RunResponse - 43, // 58: atelet.AteomHerder.Checkpoint:output_type -> atelet.CheckpointResponse - 47, // 59: atelet.AteomHerder.Restore:output_type -> atelet.RestoreResponse - 45, // 60: atelet.AteomHerder.UploadPausedCheckpoint:output_type -> atelet.UploadPausedCheckpointResponse - 14, // 61: atelet.AteomHerder.Terminate:output_type -> atelet.TerminateResponse - 54, // [54:62] is the sub-list for method output_type - 46, // [46:54] is the sub-list for method input_type - 46, // [46:46] is the sub-list for extension type_name - 46, // [46:46] is the sub-list for extension extendee - 0, // [0:46] is the sub-list for field type_name + 23, // 21: atelet.Volume.external:type_name -> atelet.ExternalVolumeSource + 29, // 22: atelet.Volume.system_info:type_name -> atelet.SystemInfoVolume + 24, // 23: atelet.Volume.image:type_name -> atelet.ImageVolumeSource + 22, // 24: atelet.Volume.empty_dir:type_name -> atelet.EmptyDirVolume + 36, // 25: atelet.Container.env:type_name -> atelet.EnvEntry + 37, // 26: atelet.Container.wakeup_probe:type_name -> atelet.WakeupProbe + 31, // 27: atelet.Container.volume_mounts:type_name -> atelet.VolumeMount + 33, // 28: atelet.Container.security_context:type_name -> atelet.SecurityContext + 35, // 29: atelet.Container.resources:type_name -> atelet.ResourceLimits + 34, // 30: atelet.SecurityContext.capabilities:type_name -> atelet.Capabilities + 38, // 31: atelet.WakeupProbe.http_get:type_name -> atelet.HTTPGetAction + 20, // 32: atelet.CheckpointRequest.spec:type_name -> atelet.WorkloadSpec + 1, // 33: atelet.CheckpointRequest.type:type_name -> atelet.CheckpointType + 40, // 34: atelet.CheckpointRequest.local_config:type_name -> atelet.LocalCheckpointConfiguration + 41, // 35: atelet.CheckpointRequest.external_config:type_name -> atelet.ExternalCheckpointConfiguration + 2, // 36: atelet.CheckpointRequest.fidelity:type_name -> atelet.SnapshotFidelity + 2, // 37: atelet.UploadPausedCheckpointRequest.desired_fidelity:type_name -> atelet.SnapshotFidelity + 20, // 38: atelet.RestoreRequest.spec:type_name -> atelet.WorkloadSpec + 1, // 39: atelet.RestoreRequest.type:type_name -> atelet.CheckpointType + 40, // 40: atelet.RestoreRequest.local_config:type_name -> atelet.LocalCheckpointConfiguration + 42, // 41: atelet.RestoreRequest.external_config:type_name -> atelet.ExternalRestoreConfiguration + 2, // 42: atelet.RestoreRequest.fidelity:type_name -> atelet.SnapshotFidelity + 16, // 43: atelet.RestoreRequest.egress_gateway:type_name -> atelet.EgressGateway + 19, // 44: atelet.RestoreRequest.sandbox_assets:type_name -> atelet.SandboxAssets + 17, // 45: atelet.ArchAssets.FilesEntry.value:type_name -> atelet.AssetFile + 18, // 46: atelet.SandboxAssets.AssetsEntry.value:type_name -> atelet.ArchAssets + 11, // 47: atelet.AteomSupport.MintActorCertificate:input_type -> atelet.MintActorCertificateRequest + 3, // 48: atelet.AteomSupport.RegisterWorker:input_type -> atelet.RegisterWorkerRequest + 9, // 49: atelet.AteomSupport.RequestActorSuspend:input_type -> atelet.RequestActorSuspendRequest + 15, // 50: atelet.AteomHerder.Run:input_type -> atelet.RunRequest + 43, // 51: atelet.AteomHerder.Checkpoint:input_type -> atelet.CheckpointRequest + 47, // 52: atelet.AteomHerder.Restore:input_type -> atelet.RestoreRequest + 45, // 53: atelet.AteomHerder.UploadPausedCheckpoint:input_type -> atelet.UploadPausedCheckpointRequest + 13, // 54: atelet.AteomHerder.Terminate:input_type -> atelet.TerminateRequest + 12, // 55: atelet.AteomSupport.MintActorCertificate:output_type -> atelet.MintActorCertificateResponse + 8, // 56: atelet.AteomSupport.RegisterWorker:output_type -> atelet.RegisterWorkerResponse + 10, // 57: atelet.AteomSupport.RequestActorSuspend:output_type -> atelet.RequestActorSuspendResponse + 39, // 58: atelet.AteomHerder.Run:output_type -> atelet.RunResponse + 44, // 59: atelet.AteomHerder.Checkpoint:output_type -> atelet.CheckpointResponse + 48, // 60: atelet.AteomHerder.Restore:output_type -> atelet.RestoreResponse + 46, // 61: atelet.AteomHerder.UploadPausedCheckpoint:output_type -> atelet.UploadPausedCheckpointResponse + 14, // 62: atelet.AteomHerder.Terminate:output_type -> atelet.TerminateResponse + 55, // [55:63] is the sub-list for method output_type + 47, // [47:55] is the sub-list for method input_type + 47, // [47:47] is the sub-list for extension type_name + 47, // [47:47] is the sub-list for extension extendee + 0, // [0:47] is the sub-list for field type_name } func init() { file_atelet_proto_init() } @@ -3467,21 +3524,22 @@ func file_atelet_proto_init() { return } file_atelet_proto_msgTypes[12].OneofWrappers = []any{} - file_atelet_proto_msgTypes[24].OneofWrappers = []any{ + file_atelet_proto_msgTypes[25].OneofWrappers = []any{ (*SystemInfoDataSource_ActorMetadata)(nil), (*SystemInfoDataSource_TrustBundle)(nil), } - file_atelet_proto_msgTypes[26].OneofWrappers = []any{ + file_atelet_proto_msgTypes[27].OneofWrappers = []any{ (*Volume_DurableDir)(nil), (*Volume_External)(nil), (*Volume_SystemInfo)(nil), (*Volume_Image)(nil), + (*Volume_EmptyDir)(nil), } - file_atelet_proto_msgTypes[39].OneofWrappers = []any{ + file_atelet_proto_msgTypes[40].OneofWrappers = []any{ (*CheckpointRequest_LocalConfig)(nil), (*CheckpointRequest_ExternalConfig)(nil), } - file_atelet_proto_msgTypes[43].OneofWrappers = []any{ + file_atelet_proto_msgTypes[44].OneofWrappers = []any{ (*RestoreRequest_LocalConfig)(nil), (*RestoreRequest_ExternalConfig)(nil), } @@ -3491,7 +3549,7 @@ func file_atelet_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: unsafe.Slice(unsafe.StringData(file_atelet_proto_rawDesc), len(file_atelet_proto_rawDesc)), NumEnums: 3, - NumMessages: 50, + NumMessages: 51, NumExtensions: 0, NumServices: 2, }, diff --git a/internal/proto/ateletpb/atelet.proto b/internal/proto/ateletpb/atelet.proto index 5f6f644848..283d526d84 100644 --- a/internal/proto/ateletpb/atelet.proto +++ b/internal/proto/ateletpb/atelet.proto @@ -293,6 +293,10 @@ message WorkloadSpec { message DurableDirVolume { } +// EmptyDirVolume is an empty host directory at the external volume path. +message EmptyDirVolume { +} + message ExternalVolumeSource { string storage_volume_id = 1; string volume_type = 2; @@ -358,6 +362,7 @@ message Volume { ExternalVolumeSource external = 3; SystemInfoVolume system_info = 4; ImageVolumeSource image = 5; + EmptyDirVolume empty_dir = 6; } } From 4732991e3291da4de0cbef7e36acf3be209259b0 Mon Sep 17 00:00:00 2001 From: Elijah Rodriguez Date: Fri, 25 Sep 2026 10:16:06 -0700 Subject: [PATCH 2/3] ateapi: let actors reference ExternalVolumes A template volume with external_volume_ref mounts an ExternalVolume instead of provisioning one per actor. The ref names the volume, or leaves the name empty so each actor binds it at creation through Actor.external_volume_bindings. Every actor referencing a volume is recorded in the volume's refs, with active set while the actor is resumed. Resume refuses a READ_WRITE_ONCE volume another actor holds active, pause and suspend mark the reference inactive, crash leaves it as is, and delete removes it and deletes a LAST_ACTOR volume that no actor references any more. Golden actors never reference a volume; they warm up against an empty directory at the same mount path. Depends on the empty_dir volume source and the ExternalVolume resource. Co-Authored-By: Claude Fable 5.1 --- .../apivalidation/zz_generated.validation.go | 156 +- cmd/ateapi/internal/controlapi/actor.go | 16 + .../controlapi/external_volume_refs.go | 255 ++++ .../controlapi/external_volume_refs_test.go | 294 ++++ .../functionaltest/external_volume_test.go | 226 +++ cmd/ateapi/internal/controlapi/service.go | 4 +- cmd/ateapi/internal/controlapi/volumes.go | 10 +- .../internal/controlapi/volumes_test.go | 40 + cmd/ateapi/internal/controlapi/workflow.go | 4 + .../internal/controlapi/workflow_delete.go | 13 + .../controlapi/workflow_delete_test.go | 4 +- .../internal/controlapi/workflow_resume.go | 12 +- .../internal/controlapi/workflow_suspend.go | 12 +- .../controlapi/workflow_testutil_test.go | 2 +- .../internal/controlapi/workload_spec.go | 26 +- .../internal/controlapi/workload_spec_test.go | 94 +- cmd/kubectl-ate/internal/cmd/actor.go | 9 +- cmd/kubectl-ate/internal/cmd/actor_test.go | 13 +- docs/csi-volumes.md | 41 + .../combinedvolumes/combinedvolumes_test.go | 177 +++ pkg/proto/ateapipb/ateapi.pb.go | 1307 +++++++++-------- pkg/proto/ateapipb/ateapi.proto | 41 +- 22 files changed, 2128 insertions(+), 628 deletions(-) create mode 100644 cmd/ateapi/internal/controlapi/external_volume_refs.go create mode 100644 cmd/ateapi/internal/controlapi/external_volume_refs_test.go diff --git a/cmd/ateapi/internal/apivalidation/zz_generated.validation.go b/cmd/ateapi/internal/apivalidation/zz_generated.validation.go index 1ce71bcaa1..e6471f3ed5 100644 --- a/cmd/ateapi/internal/apivalidation/zz_generated.validation.go +++ b/cmd/ateapi/internal/apivalidation/zz_generated.validation.go @@ -325,6 +325,48 @@ func Validate_Actor( errs = append(errs, fn(fldPath.Child("status"), obj.Status, oldVal, oldObj != nil)...) } + { // field ateapipb.Actor.ExternalVolumeBindings + fn := func( + fldPath *field.Path, + obj, oldObj map[string]string, + 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.Immutable(ctx, op, fldPath, obj, oldObj).MarkShortCircuit(); len(e) != 0 { + errs = append(errs, e...) + earlyReturn = true + } + if e := validate.MaxProperties(ctx, op, fldPath, obj, oldObj, 32).MarkShortCircuit(); len(e) != 0 { + errs = append(errs, e...) + earlyReturn = true + } + if e := validate.OptionalMap(ctx, op, fldPath, obj, oldObj).MarkShortCircuit(); len(e) != 0 { + earlyReturn = true + } + if earlyReturn { + return // do not proceed + } + if e := validate.EachMapKey(ctx, op, fldPath, obj, oldObj, validate.ShortName); len(e) != 0 { + errs = append(errs, e...) + } + if e := validate.EachMapVal(ctx, op, fldPath, obj, oldObj, validate.DirectEqual, validate.ShortName); len(e) != 0 { + errs = append(errs, e...) + } + return + } + oldVal := safe.Field(oldObj, + func(oldObj *ateapipb.Actor) map[string]string { + return oldObj.ExternalVolumeBindings + }) + errs = append(errs, fn(fldPath.Child("external_volume_bindings"), obj.ExternalVolumeBindings, oldVal, oldObj != nil)...) + } + return errs } @@ -1547,6 +1589,42 @@ func Validate_ActorVolumeStatus( errs = append(errs, fn(fldPath.Child("volume_context"), obj.VolumeContext, oldVal, oldObj != nil)...) } + { // field ateapipb.ActorVolumeStatus.ExternalVolumeName + 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.OptionalValue(ctx, op, fldPath, obj, oldObj).MarkShortCircuit(); len(e) != 0 { + earlyReturn = true + } + if e := validate.UpdateValue(ctx, op, fldPath, obj, oldObj, + func(a string, b string) bool { return a == b }, validate.NoUnset, validate.NoModify).MarkShortCircuit(); len(e) != 0 { + errs = append(errs, e...) + earlyReturn = true + } + if earlyReturn { + return // do not proceed + } + if e := validate.ShortName(ctx, op, fldPath, obj, oldObj); len(e) != 0 { + errs = append(errs, e...) + } + return + } + oldVal := safe.Field(oldObj, + func(oldObj *ateapipb.ActorVolumeStatus) *string { + return &oldObj.ExternalVolumeName + }) + errs = append(errs, fn(fldPath.Child("external_volume_name"), &obj.ExternalVolumeName, oldVal, oldObj != nil)...) + } + return errs } @@ -4348,6 +4426,46 @@ func Validate_ExternalVolume( return errs } +// Validate_ExternalVolumeRef validates an instance of ExternalVolumeRef according +// to declarative validation rules in the API schema. +func Validate_ExternalVolumeRef( + ctx context.Context, op operation.Operation, fldPath *field.Path, + obj, oldObj *ateapipb.ExternalVolumeRef) (errs field.ErrorList) { + + { // field ateapipb.ExternalVolumeRef.Name + 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.OptionalValue(ctx, op, fldPath, obj, oldObj).MarkShortCircuit(); len(e) != 0 { + earlyReturn = true + } + if earlyReturn { + return // do not proceed + } + if e := validate.ShortName(ctx, op, fldPath, obj, oldObj); len(e) != 0 { + errs = append(errs, e...) + } + return + } + oldVal := safe.Field(oldObj, + func(oldObj *ateapipb.ExternalVolumeRef) *string { + return &oldObj.Name + }) + errs = append(errs, fn(fldPath.Child("name"), &obj.Name, oldVal, oldObj != nil)...) + } + + return errs +} + // Validate_ExternalVolumeStatus validates an instance of ExternalVolumeStatus according // to declarative validation rules in the API schema. func Validate_ExternalVolumeStatus( @@ -9251,7 +9369,7 @@ func Validate_UpdateWorkerRequest( return errs } -var unionMembershipFor_github_com_agent_substrate_substrate_pkg_proto_ateapipb_Volume_ = validate.NewUnionMembership(validate.NewUnionMember("durable_dir"), validate.NewUnionMember("external_volume_template"), validate.NewUnionMember("system_info"), validate.NewUnionMember("image")) +var unionMembershipFor_github_com_agent_substrate_substrate_pkg_proto_ateapipb_Volume_ = validate.NewUnionMembership(validate.NewUnionMember("durable_dir"), validate.NewUnionMember("external_volume_template"), validate.NewUnionMember("external_volume_ref"), validate.NewUnionMember("system_info"), validate.NewUnionMember("image")) // Validate_Volume validates an instance of Volume according // to declarative validation rules in the API schema. @@ -9272,6 +9390,12 @@ func Validate_Volume( } return obj.ExternalVolumeTemplate != nil }, + func(obj *ateapipb.Volume) bool { + if obj == nil { + return false + } + return obj.ExternalVolumeRef != nil + }, func(obj *ateapipb.Volume) bool { if obj == nil { return false @@ -9377,6 +9501,36 @@ func Validate_Volume( errs = append(errs, fn(fldPath.Child("external_volume_template"), obj.ExternalVolumeTemplate, oldVal, oldObj != nil)...) } + { // field ateapipb.Volume.ExternalVolumeRef + fn := func( + fldPath *field.Path, + obj, oldObj *ateapipb.ExternalVolumeRef, + 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.OptionalPointer(ctx, op, fldPath, obj, oldObj).MarkShortCircuit(); len(e) != 0 { + earlyReturn = true + } + if earlyReturn { + return // do not proceed + } + // call the type's validation function + errs = append(errs, Validate_ExternalVolumeRef(ctx, op, fldPath, obj, oldObj)...) + return + } + oldVal := safe.Field(oldObj, + func(oldObj *ateapipb.Volume) *ateapipb.ExternalVolumeRef { + return oldObj.ExternalVolumeRef + }) + errs = append(errs, fn(fldPath.Child("external_volume_ref"), obj.ExternalVolumeRef, oldVal, oldObj != nil)...) + } + { // field ateapipb.Volume.SystemInfo fn := func( fldPath *field.Path, diff --git a/cmd/ateapi/internal/controlapi/actor.go b/cmd/ateapi/internal/controlapi/actor.go index 8ced1cb406..481ac02595 100644 --- a/cmd/ateapi/internal/controlapi/actor.go +++ b/cmd/ateapi/internal/controlapi/actor.go @@ -120,6 +120,13 @@ func (s *ServiceImpl) CreateActor(ctx context.Context, inActor *ateapipb.Actor) if err != nil { return nil, err } + if !isGoldenActor(inActor) { + refVols, err := resolveExternalVolumeRefs(ctx, s.store, inActor, template) + if err != nil { + return nil, err + } + initVols = append(initVols, refVols...) + } // Verify that the result is properly valid before storing it. outActor := proto.CloneOf(inActor) @@ -158,6 +165,11 @@ func (s *ServiceImpl) CreateActor(ctx context.Context, inActor *ateapipb.Actor) return nil, fmt.Errorf("while recording actor: %w", err) } + // Resume re-takes any reference missed here, so this does not fail the create. + if err := bindExternalVolumes(ctx, s.store, stored); err != nil { + slog.WarnContext(ctx, "Failed to bind external volumes to new actor", slog.Any("actor", resources.ActorRefFromActor(stored)), slog.Any("err", err)) + } + // Without this an actor that is created and never resumed has no record at // all, at any retention. logActorStateChanged(ctx, stored, ateattr.OperationCreate) @@ -165,6 +177,10 @@ func (s *ServiceImpl) CreateActor(ctx context.Context, inActor *ateapipb.Actor) return stored, nil } +func isGoldenActor(actor *ateapipb.Actor) bool { + return actor.GetMetadata().GetAtespace() == resources.GoldenActorAtespace +} + // resolveTagSource resolves a CreateActor request's source tag // and checks that the tag is usable for creating an Actor in actorAtespace // from template. diff --git a/cmd/ateapi/internal/controlapi/external_volume_refs.go b/cmd/ateapi/internal/controlapi/external_volume_refs.go new file mode 100644 index 0000000000..d8833c0b70 --- /dev/null +++ b/cmd/ateapi/internal/controlapi/external_volume_refs.go @@ -0,0 +1,255 @@ +// 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 controlapi + +import ( + "context" + "errors" + "fmt" + "slices" + + "github.com/agent-substrate/substrate/cmd/ateapi/internal/store" + "github.com/agent-substrate/substrate/internal/apierror" + "github.com/agent-substrate/substrate/internal/resources" + "github.com/agent-substrate/substrate/pkg/proto/ateapipb" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/status" +) + +type externalVolumeRefStore interface { + GetExternalVolume(ctx context.Context, volumeRef resources.ExternalVolumeRef) (*ateapipb.ExternalVolume, error) + UpdateExternalVolume(ctx context.Context, volumeRef resources.ExternalVolumeRef, precondition store.Precondition, mutate func(toUpdate *ateapipb.ExternalVolume) error) (*ateapipb.ExternalVolume, error) +} + +type externalVolumeDeleter interface { + DeleteExternalVolume(ctx context.Context, volumeRef resources.ExternalVolumeRef, precondition store.DeletePreconditions) (*ateapipb.ExternalVolume, error) +} + +// resolveExternalVolumeRefs checks the actor's bindings against the template +// and returns a mount for every ExternalVolume the actor references. +func resolveExternalVolumeRefs(ctx context.Context, st externalVolumeRefStore, actor *ateapipb.Actor, template *ateapipb.ActorTemplate) ([]*ateapipb.ActorVolumeStatus, error) { + bindings := actor.GetExternalVolumeBindings() + unnamed := make(map[string]bool) + for _, vol := range template.GetVolumes() { + if vol.GetExternalVolumeRef() != nil && vol.GetExternalVolumeRef().GetName() == "" { + unnamed[vol.GetName()] = true + } + } + for slot := range bindings { + if !unnamed[slot] { + return nil, apierror.InvalidArgument("external_volume_bindings[%q] does not name an unnamed external_volume_ref in the template", slot) + } + } + + var mounts []*ateapipb.ActorVolumeStatus + for _, vol := range template.GetVolumes() { + ref := vol.GetExternalVolumeRef() + if ref == nil { + continue + } + name := ref.GetName() + if name == "" { + if name = bindings[vol.GetName()]; name == "" { + return nil, apierror.InvalidArgument("external_volume_bindings must bind volume %q", vol.GetName()) + } + } + volume, err := getReadyExternalVolume(ctx, st, resources.ExternalVolumeRef{Atespace: actor.GetMetadata().GetAtespace(), Name: name}) + if err != nil { + return nil, err + } + mounts = append(mounts, externalVolumeMount(vol.GetName(), volume)) + } + return mounts, nil +} + +func getReadyExternalVolume(ctx context.Context, st externalVolumeRefStore, volumeRef resources.ExternalVolumeRef) (*ateapipb.ExternalVolume, error) { + volume, err := st.GetExternalVolume(ctx, volumeRef) + if err != nil { + if errors.Is(err, store.ErrNotFound) { + return nil, apierror.FailedPrecondition("ExternalVolume %s not found", volumeRef) + } + return nil, fmt.Errorf("while getting external volume %s: %w", volumeRef, err) + } + if state := volume.GetStatus().GetState(); state != ateapipb.ExternalVolumeState_EXTERNAL_VOLUME_STATE_READY { + return nil, apierror.FailedPrecondition("ExternalVolume %s is not ready (state %s)", volumeRef, state) + } + return volume, nil +} + +func externalVolumeMount(templateVolumeName string, volume *ateapipb.ExternalVolume) *ateapipb.ActorVolumeStatus { + return &ateapipb.ActorVolumeStatus{ + Name: templateVolumeName, + ExternalVolumeName: volume.GetMetadata().GetName(), + StorageVolumeId: volume.GetVolumeId(), + VolumeType: volume.GetVolumeType(), + VolumeContext: volume.GetVolumeContext(), + Status: ateapipb.ActorVolumeStatus_STATUS_CREATED, + } +} + +func borrowedVolumeRefs(actor *ateapipb.Actor) []resources.ExternalVolumeRef { + var refs []resources.ExternalVolumeRef + for _, vol := range actor.GetStatus().GetExternalVolumes() { + if vol.GetExternalVolumeName() != "" { + refs = append(refs, resources.ExternalVolumeRef{Atespace: actor.GetMetadata().GetAtespace(), Name: vol.GetExternalVolumeName()}) + } + } + return refs +} + +func actorRefOf(actor *ateapipb.Actor, active bool) *ateapipb.ActorRef { + return &ateapipb.ActorRef{ + ActorUid: actor.GetMetadata().GetUid(), + ActorName: actor.GetMetadata().GetName(), + Active: active, + } +} + +func findActorRef(volume *ateapipb.ExternalVolume, actorUID string) *ateapipb.ActorRef { + for _, ref := range volume.GetStatus().GetRefs() { + if ref.GetActorUid() == actorUID { + return ref + } + } + return nil +} + +func setActorRef(volume *ateapipb.ExternalVolume, ref *ateapipb.ActorRef) { + if existing := findActorRef(volume, ref.GetActorUid()); existing != nil { + existing.ActorName, existing.Active = ref.GetActorName(), ref.GetActive() + return + } + if volume.Status == nil { + volume.Status = &ateapipb.ExternalVolumeStatus{} + } + volume.Status.Refs = append(volume.Status.Refs, ref) +} + +// updateExternalVolumeRefs applies mutate under the volume's version guard. +// TODO: move references to their own table so claims do not contend on one row. +func updateExternalVolumeRefs(ctx context.Context, st externalVolumeRefStore, volumeRef resources.ExternalVolumeRef, mutate func(*ateapipb.ExternalVolume) error) (*ateapipb.ExternalVolume, error) { + volume, err := st.GetExternalVolume(ctx, volumeRef) + if err != nil { + return nil, err + } + return st.UpdateExternalVolume(ctx, volumeRef, store.PreconditionFrom(volume), mutate) +} + +// bindExternalVolumes records an inactive reference for every ExternalVolume +// the actor mounts. +func bindExternalVolumes(ctx context.Context, st externalVolumeRefStore, actor *ateapipb.Actor) error { + var errs []error + for _, volumeRef := range borrowedVolumeRefs(actor) { + _, err := updateExternalVolumeRefs(ctx, st, volumeRef, func(toUpdate *ateapipb.ExternalVolume) error { + if findActorRef(toUpdate, actor.GetMetadata().GetUid()) == nil { + setActorRef(toUpdate, actorRefOf(actor, false)) + } + return nil + }) + if err != nil { + errs = append(errs, fmt.Errorf("while binding external volume %s: %w", volumeRef, err)) + } + } + return errors.Join(errs...) +} + +var errExternalVolumeHeld = errors.New("external volume is held by another actor") + +// claimExternalVolumes marks the actor's references active and refreshes the +// recorded mounts. A READ_WRITE_ONCE volume another actor holds is refused. +// TODO: let READ_WRITE_MANY volumes carry several active references. +func claimExternalVolumes(ctx context.Context, st externalVolumeRefStore, actor *ateapipb.Actor) ([]*ateapipb.ActorVolumeStatus, error) { + volumes := slices.Clone(actor.GetStatus().GetExternalVolumes()) + actorUID := actor.GetMetadata().GetUid() + for i, mount := range volumes { + if mount.GetExternalVolumeName() == "" { + continue + } + volumeRef := resources.ExternalVolumeRef{Atespace: actor.GetMetadata().GetAtespace(), Name: mount.GetExternalVolumeName()} + var holder string + claimed, err := updateExternalVolumeRefs(ctx, st, volumeRef, func(toUpdate *ateapipb.ExternalVolume) error { + if toUpdate.GetStatus().GetState() != ateapipb.ExternalVolumeState_EXTERNAL_VOLUME_STATE_READY { + return fmt.Errorf("external volume is not ready (state %s)", toUpdate.GetStatus().GetState()) + } + for _, ref := range toUpdate.GetStatus().GetRefs() { + if ref.GetActive() && ref.GetActorUid() != actorUID { + holder = ref.GetActorName() + return errExternalVolumeHeld + } + } + setActorRef(toUpdate, actorRefOf(actor, true)) + return nil + }) + switch { + case err == nil: + case errors.Is(err, errExternalVolumeHeld): + return nil, apierror.FailedPrecondition("ExternalVolume %s is already held by actor %q; pause or suspend it before resuming another actor", volumeRef, holder) + case errors.Is(err, store.ErrNotFound): + return nil, apierror.FailedPrecondition("ExternalVolume %s not found", volumeRef) + case errors.Is(err, store.ErrVersionConflict), errors.Is(err, store.ErrUIDConflict): + return nil, apierror.Aborted("concurrent update conflict, please retry") + default: + return nil, apierror.FailedPrecondition("ExternalVolume %s: %v", volumeRef, err) + } + volumes[i] = externalVolumeMount(mount.GetName(), claimed) + } + return volumes, nil +} + +// deactivateExternalVolumes marks the actor's references inactive. +func deactivateExternalVolumes(ctx context.Context, st externalVolumeRefStore, actor *ateapipb.Actor) error { + var errs []error + for _, volumeRef := range borrowedVolumeRefs(actor) { + _, err := updateExternalVolumeRefs(ctx, st, volumeRef, func(toUpdate *ateapipb.ExternalVolume) error { + if ref := findActorRef(toUpdate, actor.GetMetadata().GetUid()); ref != nil { + ref.Active = false + } + return nil + }) + if err != nil && !errors.Is(err, store.ErrNotFound) { + errs = append(errs, fmt.Errorf("while deactivating external volume %s: %w", volumeRef, err)) + } + } + return errors.Join(errs...) +} + +// releaseExternalVolumes drops the actor's references and deletes each volume +// left without references whose delete trigger is LAST_ACTOR. +func releaseExternalVolumes(ctx context.Context, st externalVolumeRefStore, deleter externalVolumeDeleter, actor *ateapipb.Actor) error { + var errs []error + for _, volumeRef := range borrowedVolumeRefs(actor) { + released, err := updateExternalVolumeRefs(ctx, st, volumeRef, func(toUpdate *ateapipb.ExternalVolume) error { + toUpdate.Status.Refs = slices.DeleteFunc(toUpdate.GetStatus().GetRefs(), func(ref *ateapipb.ActorRef) bool { + return ref.GetActorUid() == actor.GetMetadata().GetUid() + }) + return nil + }) + if errors.Is(err, store.ErrNotFound) { + continue + } + if err != nil { + errs = append(errs, fmt.Errorf("while releasing external volume %s: %w", volumeRef, err)) + continue + } + if released.GetDeleteTrigger() != ateapipb.DeleteTrigger_DELETE_TRIGGER_LAST_ACTOR || len(released.GetStatus().GetRefs()) > 0 { + continue + } + _, err = deleter.DeleteExternalVolume(ctx, volumeRef, store.DeletePreconditions{UID: released.GetMetadata().GetUid()}) + if code := status.Code(err); err != nil && code != codes.NotFound && code != codes.FailedPrecondition { + errs = append(errs, fmt.Errorf("while deleting external volume %s: %w", volumeRef, err)) + } + } + return errors.Join(errs...) +} diff --git a/cmd/ateapi/internal/controlapi/external_volume_refs_test.go b/cmd/ateapi/internal/controlapi/external_volume_refs_test.go new file mode 100644 index 0000000000..57a8488b67 --- /dev/null +++ b/cmd/ateapi/internal/controlapi/external_volume_refs_test.go @@ -0,0 +1,294 @@ +// 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 controlapi + +import ( + "context" + "strings" + "testing" + + "github.com/agent-substrate/substrate/cmd/ateapi/internal/store" + "github.com/agent-substrate/substrate/cmd/ateapi/internal/store/storetest" + "github.com/agent-substrate/substrate/internal/apierror" + "github.com/agent-substrate/substrate/internal/resources" + "github.com/agent-substrate/substrate/pkg/proto/ateapipb" + "github.com/google/go-cmp/cmp" + "google.golang.org/grpc/codes" + "google.golang.org/protobuf/testing/protocmp" +) + +const ( + refTestAtespace = "team-refs" + refTestActorUID = "11111111-1111-1111-1111-111111111111" + refTestOtherUID = "22222222-2222-2222-2222-222222222222" +) + +func refTestTemplate(volumes ...*ateapipb.Volume) *ateapipb.ActorTemplate { + return &ateapipb.ActorTemplate{ + Metadata: &ateapipb.ResourceMetadata{Atespace: refTestAtespace, Name: "tmpl"}, + Volumes: volumes, + } +} + +func refTestActor(volumes ...*ateapipb.ActorVolumeStatus) *ateapipb.Actor { + return &ateapipb.Actor{ + Metadata: &ateapipb.ResourceMetadata{Atespace: refTestAtespace, Name: "consumer", Uid: refTestActorUID}, + Status: &ateapipb.ActorStatus{ExternalVolumes: volumes}, + } +} + +func borrowedMount(volumeName string) *ateapipb.ActorVolumeStatus { + return &ateapipb.ActorVolumeStatus{ + Name: "shared-data", + ExternalVolumeName: volumeName, + StorageVolumeId: "disk/" + volumeName, + VolumeType: "mock", + VolumeContext: map[string]string{"type": "pd-ssd"}, + Status: ateapipb.ActorVolumeStatus_STATUS_CREATED, + } +} + +func mustStoreReadyVolume(t *testing.T, ctx context.Context, st store.Interface, name string, trigger ateapipb.DeleteTrigger, refs ...*ateapipb.ActorRef) *ateapipb.ExternalVolume { + t.Helper() + return storetest.MustCreateExternalVolume(t, ctx, st, &ateapipb.ExternalVolume{ + Metadata: &ateapipb.ResourceMetadata{Atespace: refTestAtespace, Name: name}, + DeleteTrigger: trigger, + AccessMode: ateapipb.AccessMode_ACCESS_MODE_READ_WRITE_ONCE, + VolumeId: "disk/" + name, + VolumeType: "mock", + VolumeContext: map[string]string{"type": "pd-ssd"}, + Status: &ateapipb.ExternalVolumeStatus{ + State: ateapipb.ExternalVolumeState_EXTERNAL_VOLUME_STATE_READY, + Refs: refs, + }, + }) +} + +func mustGetVolume(t *testing.T, ctx context.Context, st store.Interface, name string) *ateapipb.ExternalVolume { + t.Helper() + got, err := st.GetExternalVolume(ctx, resources.ExternalVolumeRef{Atespace: refTestAtespace, Name: name}) + if err != nil { + t.Fatalf("GetExternalVolume(%q): %v", name, err) + } + return got +} + +// refStates maps each referencing actor's UID to whether its reference is active. +func refStates(volume *ateapipb.ExternalVolume) map[string]bool { + states := make(map[string]bool, len(volume.GetStatus().GetRefs())) + for _, ref := range volume.GetStatus().GetRefs() { + states[ref.GetActorUid()] = ref.GetActive() + } + return states +} + +func TestResolveExternalVolumeRefs(t *testing.T) { + ctx := context.Background() + st := newTestPersistence(t) + mustStoreReadyVolume(t, ctx, st, "shared", ateapipb.DeleteTrigger_DELETE_TRIGGER_MANUAL) + mustStoreReadyVolume(t, ctx, st, "bound", ateapipb.DeleteTrigger_DELETE_TRIGGER_MANUAL) + storetest.MustCreateExternalVolume(t, ctx, st, &ateapipb.ExternalVolume{ + Metadata: &ateapipb.ResourceMetadata{Atespace: refTestAtespace, Name: "pending"}, + StorageClassName: "standard", + Status: &ateapipb.ExternalVolumeStatus{State: ateapipb.ExternalVolumeState_EXTERNAL_VOLUME_STATE_PENDING}, + }) + named := &ateapipb.Volume{Name: "shared-data", ExternalVolumeRef: &ateapipb.ExternalVolumeRef{Name: "shared"}} + unnamed := &ateapipb.Volume{Name: "slot", ExternalVolumeRef: &ateapipb.ExternalVolumeRef{}} + + tests := []struct { + name string + template *ateapipb.ActorTemplate + bindings map[string]string + want []string + wantCode codes.Code + }{ + {name: "named ref", template: refTestTemplate(named), want: []string{"shared"}}, + {name: "bound slot", template: refTestTemplate(named, unnamed), bindings: map[string]string{"slot": "bound"}, want: []string{"shared", "bound"}}, + {name: "unbound slot", template: refTestTemplate(unnamed), wantCode: codes.InvalidArgument}, + {name: "binding for a named ref", template: refTestTemplate(named), bindings: map[string]string{"shared-data": "bound"}, wantCode: codes.InvalidArgument}, + {name: "binding for an unknown volume", template: refTestTemplate(unnamed), bindings: map[string]string{"slot": "bound", "other": "bound"}, wantCode: codes.InvalidArgument}, + {name: "missing volume", template: refTestTemplate(unnamed), bindings: map[string]string{"slot": "absent"}, wantCode: codes.FailedPrecondition}, + {name: "pending volume", template: refTestTemplate(unnamed), bindings: map[string]string{"slot": "pending"}, wantCode: codes.FailedPrecondition}, + } + for _, tc := range tests { + t.Run(tc.name, func(t *testing.T) { + actor := refTestActor() + actor.ExternalVolumeBindings = tc.bindings + mounts, err := resolveExternalVolumeRefs(ctx, st, actor, tc.template) + if apierror.Code(err) != tc.wantCode { + t.Fatalf("resolveExternalVolumeRefs() error = %v, want code %v", err, tc.wantCode) + } + var got []string + for _, mount := range mounts { + if mount.GetStorageVolumeId() != "disk/"+mount.GetExternalVolumeName() || mount.GetStatus() != ateapipb.ActorVolumeStatus_STATUS_CREATED { + t.Errorf("mount %v does not carry the volume's handle", mount) + } + got = append(got, mount.GetExternalVolumeName()) + } + if diff := cmp.Diff(tc.want, got); diff != "" { + t.Errorf("resolved volumes mismatch (-want +got):\n%s", diff) + } + }) + } +} + +func TestBindClaimDeactivateRelease(t *testing.T) { + ctx := context.Background() + st := newTestPersistence(t) + mustStoreReadyVolume(t, ctx, st, "shared", ateapipb.DeleteTrigger_DELETE_TRIGGER_MANUAL) + actor := refTestActor(borrowedMount("shared")) + volumeRef := resources.ExternalVolumeRef{Atespace: refTestAtespace, Name: "shared"} + + if err := bindExternalVolumes(ctx, st, actor); err != nil { + t.Fatalf("bindExternalVolumes: %v", err) + } + if diff := cmp.Diff(map[string]bool{refTestActorUID: false}, refStates(mustGetVolume(t, ctx, st, "shared"))); diff != "" { + t.Errorf("refs after bind mismatch (-want +got):\n%s", diff) + } + + claimed, err := claimExternalVolumes(ctx, st, actor) + if err != nil { + t.Fatalf("claimExternalVolumes: %v", err) + } + if diff := cmp.Diff(actor.GetStatus().GetExternalVolumes(), claimed, protocmp.Transform()); diff != "" { + t.Errorf("claimed mounts mismatch (-want +got):\n%s", diff) + } + if diff := cmp.Diff(map[string]bool{refTestActorUID: true}, refStates(mustGetVolume(t, ctx, st, "shared"))); diff != "" { + t.Errorf("refs after claim mismatch (-want +got):\n%s", diff) + } + if _, err := claimExternalVolumes(ctx, st, actor); err != nil { + t.Fatalf("second claimExternalVolumes: %v", err) + } + + if err := deactivateExternalVolumes(ctx, st, actor); err != nil { + t.Fatalf("deactivateExternalVolumes: %v", err) + } + if diff := cmp.Diff(map[string]bool{refTestActorUID: false}, refStates(mustGetVolume(t, ctx, st, "shared"))); diff != "" { + t.Errorf("refs after deactivate mismatch (-want +got):\n%s", diff) + } + + deleter := &recordingExternalVolumeDeleter{} + if err := releaseExternalVolumes(ctx, st, deleter, actor); err != nil { + t.Fatalf("releaseExternalVolumes: %v", err) + } + if got := refStates(mustGetVolume(t, ctx, st, "shared")); len(got) != 0 { + t.Errorf("refs after release = %v, want none", got) + } + if len(deleter.deleted) != 0 { + t.Errorf("deleted %v, want a MANUAL volume left in place", deleter.deleted) + } + if err := releaseExternalVolumes(ctx, st, deleter, actor); err != nil { + t.Fatalf("second releaseExternalVolumes: %v", err) + } + if _, err := st.GetExternalVolume(ctx, volumeRef); err != nil { + t.Errorf("GetExternalVolume after release: %v", err) + } +} + +func TestClaimExternalVolumes_Exclusion(t *testing.T) { + ctx := context.Background() + other := &ateapipb.ActorRef{ActorUid: refTestOtherUID, ActorName: "producer"} + + t.Run("active holder blocks", func(t *testing.T) { + st := newTestPersistence(t) + other := &ateapipb.ActorRef{ActorUid: other.ActorUid, ActorName: other.ActorName, Active: true} + mustStoreReadyVolume(t, ctx, st, "shared", ateapipb.DeleteTrigger_DELETE_TRIGGER_MANUAL, other) + + _, err := claimExternalVolumes(ctx, st, refTestActor(borrowedMount("shared"))) + if apierror.Code(err) != codes.FailedPrecondition || !strings.Contains(err.Error(), "producer") { + t.Fatalf("claimExternalVolumes() = %v, want FailedPrecondition naming the holder", err) + } + if diff := cmp.Diff(map[string]bool{refTestOtherUID: true}, refStates(mustGetVolume(t, ctx, st, "shared"))); diff != "" { + t.Errorf("refs after refused claim mismatch (-want +got):\n%s", diff) + } + }) + + t.Run("inactive holder does not block", func(t *testing.T) { + st := newTestPersistence(t) + mustStoreReadyVolume(t, ctx, st, "shared", ateapipb.DeleteTrigger_DELETE_TRIGGER_MANUAL, other) + + if _, err := claimExternalVolumes(ctx, st, refTestActor(borrowedMount("shared"))); err != nil { + t.Fatalf("claimExternalVolumes: %v", err) + } + if diff := cmp.Diff(map[string]bool{refTestOtherUID: false, refTestActorUID: true}, refStates(mustGetVolume(t, ctx, st, "shared"))); diff != "" { + t.Errorf("refs mismatch (-want +got):\n%s", diff) + } + }) + + t.Run("missing volume", func(t *testing.T) { + st := newTestPersistence(t) + storetest.MustCreateAtespace(t, ctx, st, refTestAtespace) + + _, err := claimExternalVolumes(ctx, st, refTestActor(borrowedMount("absent"))) + if apierror.Code(err) != codes.FailedPrecondition { + t.Fatalf("claimExternalVolumes() = %v, want FailedPrecondition", err) + } + }) +} + +func TestReleaseExternalVolumes_LastActorDeletes(t *testing.T) { + ctx := context.Background() + st := newTestPersistence(t) + other := &ateapipb.ActorRef{ActorUid: refTestOtherUID, ActorName: "other"} + mustStoreReadyVolume(t, ctx, st, "shared", ateapipb.DeleteTrigger_DELETE_TRIGGER_LAST_ACTOR, + &ateapipb.ActorRef{ActorUid: refTestActorUID, ActorName: "consumer"}, other) + actor := refTestActor(borrowedMount("shared")) + deleter := &recordingExternalVolumeDeleter{} + + if err := releaseExternalVolumes(ctx, st, deleter, actor); err != nil { + t.Fatalf("releaseExternalVolumes: %v", err) + } + if len(deleter.deleted) != 0 { + t.Fatalf("deleted %v while another actor still references the volume", deleter.deleted) + } + + otherActor := refTestActor(borrowedMount("shared")) + otherActor.Metadata.Uid = refTestOtherUID + if err := releaseExternalVolumes(ctx, st, deleter, otherActor); err != nil { + t.Fatalf("releaseExternalVolumes(other): %v", err) + } + if diff := cmp.Diff([]string{refTestAtespace + "/shared"}, deleter.deleted); diff != "" { + t.Errorf("deleted volumes mismatch (-want +got):\n%s", diff) + } +} + +func TestCrashActorKeepsExternalVolumeRefs(t *testing.T) { + ctx := context.Background() + st := newTestPersistence(t) + + created := storetest.MustCreateActor(t, ctx, st, refTestActor()) + mustStoreReadyVolume(t, ctx, st, "shared", ateapipb.DeleteTrigger_DELETE_TRIGGER_MANUAL, + &ateapipb.ActorRef{ActorUid: created.GetMetadata().GetUid(), ActorName: "consumer", Active: true}) + mustUpdateActorStatus(t, ctx, st, created, func(s *ateapipb.ActorStatus) { + s.State = ateapipb.ActorState_ACTOR_STATE_RUNNING + s.ExternalVolumes = []*ateapipb.ActorVolumeStatus{borrowedMount("shared")} + }) + + if err := crashActor(ctx, st, resources.ActorRef{Atespace: refTestAtespace, Name: "consumer"}, "resume", "worker lost"); err != nil { + t.Fatalf("crashActor: %v", err) + } + if diff := cmp.Diff(map[string]bool{created.GetMetadata().GetUid(): true}, refStates(mustGetVolume(t, ctx, st, "shared"))); diff != "" { + t.Errorf("refs after crash mismatch (-want +got):\n%s", diff) + } +} + +type recordingExternalVolumeDeleter struct { + deleted []string +} + +func (d *recordingExternalVolumeDeleter) DeleteExternalVolume(_ context.Context, volumeRef resources.ExternalVolumeRef, _ store.DeletePreconditions) (*ateapipb.ExternalVolume, error) { + d.deleted = append(d.deleted, volumeRef.String()) + return nil, nil +} diff --git a/cmd/ateapi/internal/controlapi/functionaltest/external_volume_test.go b/cmd/ateapi/internal/controlapi/functionaltest/external_volume_test.go index 27e30a6fe6..e50e653bb4 100644 --- a/cmd/ateapi/internal/controlapi/functionaltest/external_volume_test.go +++ b/cmd/ateapi/internal/controlapi/functionaltest/external_volume_test.go @@ -269,3 +269,229 @@ func TestDeleteExternalVolume(t *testing.T) { _, err = tc.client.DeleteExternalVolume(context.Background(), &ateapipb.DeleteExternalVolumeRequest{ExternalVolume: ref}) assertGrpcError(t, err, codes.NotFound, fmt.Sprintf("ExternalVolume %s/shared not found", testAtespace)) } + +// refStates maps each actor referencing volumeName to whether its reference is active. +func refStates(t *testing.T, tc *testContext, volumeName string) map[string]bool { + t.Helper() + states := make(map[string]bool) + for _, ref := range getExternalVolume(t, tc, volumeName).GetStatus().GetRefs() { + states[ref.GetActorName()] = ref.GetActive() + } + return states +} + +func borrowedMount(t *testing.T, tc *testContext, actorName, volumeName string) *ateapipb.ActorVolumeStatus { + t.Helper() + actor, err := tc.client.GetActor(context.Background(), &ateapipb.GetActorRequest{ + Actor: &ateapipb.ObjectRef{Atespace: testAtespace, Name: actorName}, + }) + if err != nil { + t.Fatalf("GetActor(%s) failed: %v", actorName, err) + } + for _, vol := range actor.GetStatus().GetExternalVolumes() { + if vol.GetName() == volumeName { + return vol + } + } + return nil +} + +func createBorrowingActor(t *testing.T, tc *testContext, name string, bindings map[string]string) { + t.Helper() + if _, err := tc.client.CreateActor(context.Background(), &ateapipb.CreateActorRequest{Actor: &ateapipb.Actor{ + Metadata: &ateapipb.ResourceMetadata{Atespace: testAtespace, Name: name}, + ActorTemplate: &ateapipb.ObjectRef{Atespace: testAtespace, Name: "tmpl1"}, + ExternalVolumeBindings: bindings, + }}); err != nil { + t.Fatalf("CreateActor(%s) failed: %v", name, err) + } +} + +func actorState(t *testing.T, tc *testContext, name string) ateapipb.ActorState { + t.Helper() + actor, err := tc.client.GetActor(context.Background(), &ateapipb.GetActorRequest{ + Actor: &ateapipb.ObjectRef{Atespace: testAtespace, Name: name}, + }) + if err != nil { + t.Fatalf("GetActor(%s) failed: %v", name, err) + } + return actor.GetStatus().GetState() +} + +func TestExternalVolume_SequentialHandoff(t *testing.T) { + ns := namespaceForTest("ns-extvol-handoff") + tc, plugin := setupExternalVolumeTest(t, ns) + defer tc.cleanup() + + shared := createExternalVolume(t, tc, "handoff", ateapipb.DeleteTrigger_DELETE_TRIGGER_LAST_ACTOR) + createTemplateWithVolumes(t, tc, ns, + []*ateapipb.Volume{{Name: "work", ExternalVolumeRef: &ateapipb.ExternalVolumeRef{Name: "handoff"}}}, + []*ateapipb.VolumeMount{{Name: "work", MountPath: "/mnt/work"}}) + workerName := createWorkerPod(t, tc, ns, "worker-1", "node1", "pool1") + ctx := context.Background() + + createBorrowingActor(t, tc, "producer", nil) + createBorrowingActor(t, tc, "consumer", nil) + if diff := cmp.Diff(map[string]bool{"producer": false, "consumer": false}, refStates(t, tc, "handoff")); diff != "" { + t.Errorf("refs after create mismatch (-want +got):\n%s", diff) + } + + waitForWorkerAvailable(t, tc, workerName) + if _, err := tc.client.ResumeActor(ctx, &ateapipb.ResumeActorRequest{Actor: &ateapipb.ObjectRef{Atespace: testAtespace, Name: "producer"}}); err != nil { + t.Fatalf("ResumeActor(producer) failed: %v", err) + } + if diff := cmp.Diff(map[string]bool{"producer": true, "consumer": false}, refStates(t, tc, "handoff")); diff != "" { + t.Errorf("refs while the producer runs mismatch (-want +got):\n%s", diff) + } + if _, err := tc.client.SuspendActor(ctx, &ateapipb.SuspendActorRequest{Actor: &ateapipb.ObjectRef{Atespace: testAtespace, Name: "producer"}}); err != nil { + t.Fatalf("SuspendActor(producer) failed: %v", err) + } + if diff := cmp.Diff(map[string]bool{"producer": false, "consumer": false}, refStates(t, tc, "handoff")); diff != "" { + t.Errorf("refs after the producer stops mismatch (-want +got):\n%s", diff) + } + + waitForWorkerAvailable(t, tc, workerName) + if _, err := tc.client.ResumeActor(ctx, &ateapipb.ResumeActorRequest{Actor: &ateapipb.ObjectRef{Atespace: testAtespace, Name: "consumer"}}); err != nil { + t.Fatalf("ResumeActor(consumer) failed: %v", err) + } + if diff := cmp.Diff(map[string]bool{"producer": false, "consumer": true}, refStates(t, tc, "handoff")); diff != "" { + t.Errorf("refs while the consumer runs mismatch (-want +got):\n%s", diff) + } + for _, name := range []string{"producer", "consumer"} { + if got, want := borrowedMount(t, tc, name, "work").GetStorageVolumeId(), shared.GetVolumeId(); got != want { + t.Errorf("actor %s mounted %q, want the shared volume %q", name, got, want) + } + } + created, deleted, attached, detached := plugin.snapshot() + if diff := cmp.Diff([]string{shared.GetVolumeId() + "@node1", shared.GetVolumeId() + "@node1"}, attached); diff != "" { + t.Errorf("attached volumes mismatch (-want +got):\n%s", diff) + } + if diff := cmp.Diff([]string{shared.GetVolumeId() + "@node1"}, detached); diff != "" { + t.Errorf("detached volumes mismatch (-want +got):\n%s", diff) + } + if len(created) != 1 || len(deleted) != 0 { + t.Errorf("created %v deleted %v, want one provisioning and no deletion", created, deleted) + } + + if _, err := tc.client.SuspendActor(ctx, &ateapipb.SuspendActorRequest{Actor: &ateapipb.ObjectRef{Atespace: testAtespace, Name: "consumer"}}); err != nil { + t.Fatalf("SuspendActor(consumer) failed: %v", err) + } + for _, name := range []string{"producer", "consumer"} { + if _, err := tc.client.DeleteActor(ctx, &ateapipb.DeleteActorRequest{Actor: &ateapipb.ObjectRef{Atespace: testAtespace, Name: name}}); err != nil { + t.Fatalf("DeleteActor(%s) failed: %v", name, err) + } + } + _, err := tc.client.GetExternalVolume(ctx, &ateapipb.GetExternalVolumeRequest{ExternalVolume: &ateapipb.ObjectRef{Atespace: testAtespace, Name: "handoff"}}) + assertGrpcError(t, err, codes.NotFound, fmt.Sprintf("ExternalVolume %s/handoff not found", testAtespace)) + if _, deleted, _, _ := plugin.snapshot(); !cmp.Equal([]string{shared.GetVolumeId()}, deleted) { + t.Errorf("deleted volumes = %v, want the LAST_ACTOR trigger to delete %q", deleted, shared.GetVolumeId()) + } +} + +func TestExternalVolume_HeldByAnotherActor(t *testing.T) { + ns := namespaceForTest("ns-extvol-held") + tc, plugin := setupExternalVolumeTest(t, ns) + defer tc.cleanup() + + shared := createExternalVolume(t, tc, "held", ateapipb.DeleteTrigger_DELETE_TRIGGER_MANUAL) + createTemplateWithVolumes(t, tc, ns, + []*ateapipb.Volume{{Name: "work", ExternalVolumeRef: &ateapipb.ExternalVolumeRef{Name: "held"}}}, + []*ateapipb.VolumeMount{{Name: "work", MountPath: "/mnt/work"}}) + firstWorker := createWorkerPod(t, tc, ns, "worker-1", "node1", "pool1") + ctx := context.Background() + + createBorrowingActor(t, tc, "producer", nil) + createBorrowingActor(t, tc, "consumer", nil) + waitForWorkerAvailable(t, tc, firstWorker) + if _, err := tc.client.ResumeActor(ctx, &ateapipb.ResumeActorRequest{Actor: &ateapipb.ObjectRef{Atespace: testAtespace, Name: "producer"}}); err != nil { + t.Fatalf("ResumeActor(producer) failed: %v", err) + } + + secondWorker := createWorkerPod(t, tc, ns, "worker-2", "node1", "pool1") + waitForWorkerAvailable(t, tc, secondWorker) + _, err := tc.client.ResumeActor(ctx, &ateapipb.ResumeActorRequest{Actor: &ateapipb.ObjectRef{Atespace: testAtespace, Name: "consumer"}}) + assertGrpcErrorRegex(t, err, codes.FailedPrecondition, `ExternalVolume .*held is already held by actor "producer"`) + if diff := cmp.Diff(map[string]bool{"producer": true, "consumer": false}, refStates(t, tc, "held")); diff != "" { + t.Errorf("refs after the refused resume mismatch (-want +got):\n%s", diff) + } + if got := actorState(t, tc, "consumer"); got != ateapipb.ActorState_ACTOR_STATE_SUSPENDED { + t.Errorf("consumer is in %v, want it left SUSPENDED", got) + } + if _, _, attached, _ := plugin.snapshot(); !cmp.Equal([]string{shared.GetVolumeId() + "@node1"}, attached) { + t.Errorf("attached volumes = %v, want only the producer's attach", attached) + } + + if _, err := tc.client.PauseActor(ctx, &ateapipb.PauseActorRequest{Actor: &ateapipb.ObjectRef{Atespace: testAtespace, Name: "producer"}}); err != nil { + t.Fatalf("PauseActor(producer) failed: %v", err) + } + if _, err := tc.client.ResumeActor(ctx, &ateapipb.ResumeActorRequest{Actor: &ateapipb.ObjectRef{Atespace: testAtespace, Name: "consumer"}}); err != nil { + t.Fatalf("ResumeActor(consumer) after the handoff failed: %v", err) + } + if diff := cmp.Diff(map[string]bool{"producer": false, "consumer": true}, refStates(t, tc, "held")); diff != "" { + t.Errorf("refs after the handoff mismatch (-want +got):\n%s", diff) + } +} + +func TestDeleteExternalVolume_Referenced(t *testing.T) { + ns := namespaceForTest("ns-extvol-referenced") + tc, plugin := setupExternalVolumeTest(t, ns) + defer tc.cleanup() + + createExternalVolume(t, tc, "shared", ateapipb.DeleteTrigger_DELETE_TRIGGER_MANUAL) + createTemplateWithVolumes(t, tc, ns, + []*ateapipb.Volume{{Name: "work", ExternalVolumeRef: &ateapipb.ExternalVolumeRef{Name: "shared"}}}, + []*ateapipb.VolumeMount{{Name: "work", MountPath: "/mnt/work"}}) + ctx := context.Background() + ref := &ateapipb.ObjectRef{Atespace: testAtespace, Name: "shared"} + + createBorrowingActor(t, tc, "borrower", nil) + _, err := tc.client.DeleteExternalVolume(ctx, &ateapipb.DeleteExternalVolumeRequest{ExternalVolume: ref}) + assertGrpcErrorRegex(t, err, codes.FailedPrecondition, `ExternalVolume .*shared is still referenced by 1 actor\(s\), starting with "borrower"`) + + if _, err := tc.client.DeleteActor(ctx, &ateapipb.DeleteActorRequest{Actor: &ateapipb.ObjectRef{Atespace: testAtespace, Name: "borrower"}}); err != nil { + t.Fatalf("DeleteActor failed: %v", err) + } + if got := refStates(t, tc, "shared"); len(got) != 0 { + t.Errorf("refs after the actor is deleted = %v, want none", got) + } + if _, deleted, _, _ := plugin.snapshot(); len(deleted) != 0 { + t.Errorf("deleted %v, want a MANUAL volume left in place", deleted) + } + if _, err := tc.client.DeleteExternalVolume(ctx, &ateapipb.DeleteExternalVolumeRequest{ExternalVolume: ref}); err != nil { + t.Fatalf("DeleteExternalVolume failed: %v", err) + } +} + +func TestCreateActor_ExternalVolumeBindings(t *testing.T) { + ns := namespaceForTest("ns-extvol-bindings") + tc, _ := setupExternalVolumeTest(t, ns) + defer tc.cleanup() + + shared := createExternalVolume(t, tc, "ctx-42", ateapipb.DeleteTrigger_DELETE_TRIGGER_MANUAL) + createTemplateWithVolumes(t, tc, ns, + []*ateapipb.Volume{{Name: "work", ExternalVolumeRef: &ateapipb.ExternalVolumeRef{}}}, + []*ateapipb.VolumeMount{{Name: "work", MountPath: "/mnt/work"}}) + ctx := context.Background() + create := func(name string, bindings map[string]string) error { + _, err := tc.client.CreateActor(ctx, &ateapipb.CreateActorRequest{Actor: &ateapipb.Actor{ + Metadata: &ateapipb.ResourceMetadata{Atespace: testAtespace, Name: name}, + ActorTemplate: &ateapipb.ObjectRef{Atespace: testAtespace, Name: "tmpl1"}, + ExternalVolumeBindings: bindings, + }}) + return err + } + + assertGrpcErrorRegex(t, create("unbound", nil), codes.InvalidArgument, `external_volume_bindings must bind volume "work"`) + assertGrpcErrorRegex(t, create("stray", map[string]string{"work": "ctx-42", "other": "ctx-42"}), codes.InvalidArgument, `external_volume_bindings\["other"\]`) + assertGrpcErrorRegex(t, create("missing", map[string]string{"work": "ctx-41"}), codes.FailedPrecondition, fmt.Sprintf("ExternalVolume %s/ctx-41 not found", testAtespace)) + + if err := create("bound", map[string]string{"work": "ctx-42"}); err != nil { + t.Fatalf("CreateActor(bound) failed: %v", err) + } + if got, want := borrowedMount(t, tc, "bound", "work").GetStorageVolumeId(), shared.GetVolumeId(); got != want { + t.Errorf("bound actor mounts %q, want %q", got, want) + } + if diff := cmp.Diff(map[string]bool{"bound": false}, refStates(t, tc, "ctx-42")); diff != "" { + t.Errorf("refs mismatch (-want +got):\n%s", diff) + } +} diff --git a/cmd/ateapi/internal/controlapi/service.go b/cmd/ateapi/internal/controlapi/service.go index 7b0b526768..74b1aa10a7 100644 --- a/cmd/ateapi/internal/controlapi/service.go +++ b/cmd/ateapi/internal/controlapi/service.go @@ -104,9 +104,9 @@ func NewRPCService( actorIDJWTPool: actorIDJWTPool, actorIDCAPool: actorIDCAPool, } - s.actorWorkflow = NewActorWorkflow(impl, workerCache, dialer, sandboxConfigLister, storageClassLister, instruments, egressGatewayAddress, s, snapshotPlugin) - s.workerWorkflow = NewWorkerWorkflow(impl) s.externalVolumeWorkflow = NewExternalVolumeWorkflow(impl, storageClassLister, s) + s.actorWorkflow = NewActorWorkflow(impl, workerCache, dialer, sandboxConfigLister, storageClassLister, instruments, egressGatewayAddress, s, snapshotPlugin, s.externalVolumeWorkflow) + s.workerWorkflow = NewWorkerWorkflow(impl) return s } diff --git a/cmd/ateapi/internal/controlapi/volumes.go b/cmd/ateapi/internal/controlapi/volumes.go index 2460b522b3..329eb8690d 100644 --- a/cmd/ateapi/internal/controlapi/volumes.go +++ b/cmd/ateapi/internal/controlapi/volumes.go @@ -74,6 +74,11 @@ func createActorVolumes(ctx context.Context, registry VolumePluginRegistry, scLi for idx, vol := range volumesToCreate { currentIdx = idx + if vol.GetExternalVolumeName() != "" { + resultVolumes = append(resultVolumes, vol) + continue + } + var specVol *ateapipb.Volume volName := vol.GetName() for _, tVol := range template.GetVolumes() { @@ -138,13 +143,16 @@ func createActorVolumes(ctx context.Context, registry VolumePluginRegistry, scLi return resultVolumes, nil } -// deleteActorVolumes deletes all external volumes in the list. +// deleteActorVolumes deletes the external volumes the actor owns. func deleteActorVolumes(ctx context.Context, registry VolumePluginRegistry, actorUID string, volumes []*ateapipb.ActorVolumeStatus) error { if actorUID == "" { return errors.New("actorUID is required") } var errs []error for _, vol := range volumes { + if vol.GetExternalVolumeName() != "" { + continue + } volID := vol.GetStorageVolumeId() if volID == "" { // If the volume hasn't been successfully created yet, it's possible diff --git a/cmd/ateapi/internal/controlapi/volumes_test.go b/cmd/ateapi/internal/controlapi/volumes_test.go index 52d8eb6fb5..853a6afaf7 100644 --- a/cmd/ateapi/internal/controlapi/volumes_test.go +++ b/cmd/ateapi/internal/controlapi/volumes_test.go @@ -698,3 +698,43 @@ func TestDetachActorVolumes(t *testing.T) { }) } } + +func TestBorrowedVolumesAreNotProvisionedOrDeleted(t *testing.T) { + ctx := context.Background() + template := &ateapipb.ActorTemplate{ + Volumes: []*ateapipb.Volume{{Name: "shared-data", ExternalVolumeRef: &ateapipb.ExternalVolumeRef{Name: "shared"}}}, + } + scLister := &fakeStorageClassLister{storageClasses: map[string]*storagev1.StorageClass{}} + + initial, err := initialActorVolumes(ctx, scLister, template) + if err != nil { + t.Fatalf("initialActorVolumes: %v", err) + } + if len(initial) != 0 { + t.Errorf("initialActorVolumes() = %v, want no entry for a borrowed volume", initial) + } + + borrowed := []*ateapipb.ActorVolumeStatus{{ + Name: "shared-data", + ExternalVolumeName: "shared", + StorageVolumeId: "disk/shared", + VolumeType: "mock", + Status: ateapipb.ActorVolumeStatus_STATUS_CREATED, + }} + plugin := &trackingVolumePlugin{} + registry := &mockPluginRegistry{plugins: map[string]volume.VolumePluginControlPlane{"mock": plugin}} + + got, err := createActorVolumes(ctx, registry, scLister, "actor-uid-123", template, borrowed) + if err != nil { + t.Fatalf("createActorVolumes: %v", err) + } + if diff := cmp.Diff(borrowed, got, protocmp.Transform()); diff != "" { + t.Errorf("createActorVolumes() mismatch (-want +got):\n%s", diff) + } + if err := deleteActorVolumes(ctx, registry, "actor-uid-123", borrowed); err != nil { + t.Fatalf("deleteActorVolumes: %v", err) + } + if len(plugin.deletedIDs) != 0 { + t.Errorf("deleted %v, want the borrowed volume left alone", plugin.deletedIDs) + } +} diff --git a/cmd/ateapi/internal/controlapi/workflow.go b/cmd/ateapi/internal/controlapi/workflow.go index d830f8804d..2b3fbe7e01 100644 --- a/cmd/ateapi/internal/controlapi/workflow.go +++ b/cmd/ateapi/internal/controlapi/workflow.go @@ -102,6 +102,7 @@ func logActorState(ctx context.Context, actor *ateapipb.Actor, opName, state str // ActorWorkflow handles the workflows for actor's resume / suspend operations. type ActorWorkflow struct { store actorWorkflowStore + externalVolumes externalVolumeDeleter workerCache *workercache.Cache scheduler scheduling.Scheduler dialer *AteletDialer @@ -128,9 +129,11 @@ func NewActorWorkflow( egressGatewayAddress string, pluginRegistry VolumePluginRegistry, snapshotPlugin objectstoresnapshotv1.ControlProviderClient, + externalVolumes externalVolumeDeleter, ) *ActorWorkflow { return &ActorWorkflow{ store: store, + externalVolumes: externalVolumes, workerCache: workerCache, scheduler: scheduling.New(workerCache), dialer: dialer, @@ -179,6 +182,7 @@ type actorWorkflowStore interface { GetActorTemplate(ctx context.Context, templateRef resources.ActorTemplateRef) (*ateapipb.ActorTemplate, error) DeleteActorTemplate(ctx context.Context, templateRef resources.ActorTemplateRef, precondition store.DeletePreconditions) (*ateapipb.ActorTemplate, error) AcquireLease(ctx context.Context, key string) (*store.Lease, error) + externalVolumeRefStore } // WorkerWorkflow handles the multi-step operations on a Worker. diff --git a/cmd/ateapi/internal/controlapi/workflow_delete.go b/cmd/ateapi/internal/controlapi/workflow_delete.go index ea98140354..554e29bfdd 100644 --- a/cmd/ateapi/internal/controlapi/workflow_delete.go +++ b/cmd/ateapi/internal/controlapi/workflow_delete.go @@ -95,6 +95,10 @@ func (w *ActorWorkflow) DeleteActor(ctx context.Context, actorRef resources.Acto errs = append(errs, fmt.Errorf("while deleting volumes: %w", err)) } + if err := w.ensureExternalVolumeRefsReleased(ctx, actor); err != nil { + errs = append(errs, fmt.Errorf("while releasing external volume references: %w", err)) + } + if err := w.ensureExternalSnapshotsReleased(ctx, actor); err != nil { errs = append(errs, fmt.Errorf("while releasing external snapshots: %w", err)) } @@ -365,6 +369,15 @@ func (w *ActorWorkflow) ensureVolumesDeleted(ctx context.Context, actor *ateapip return nil } +// ensureExternalVolumeRefsReleased drops the actor's ExternalVolume references +// and deletes any volume that reached its LAST_ACTOR trigger. +func (w *ActorWorkflow) ensureExternalVolumeRefsReleased(ctx context.Context, actor *ateapipb.Actor) (err error) { + ctx, done := stepSpan(ctx, "ReleaseExternalVolumeRefs") + defer func() { err = done(err) }() + + return releaseExternalVolumes(ctx, w.store, w.externalVolumes, actor) +} + // ensureExternalSnapshotsReleased collects everything the actor wrote to // object storage, by deleting its own prefix. It runs before the actor is // removed, so a failed attempt is still rediscoverable on the retry. diff --git a/cmd/ateapi/internal/controlapi/workflow_delete_test.go b/cmd/ateapi/internal/controlapi/workflow_delete_test.go index 214f0b3965..a9a5d87f9e 100644 --- a/cmd/ateapi/internal/controlapi/workflow_delete_test.go +++ b/cmd/ateapi/internal/controlapi/workflow_delete_test.go @@ -347,7 +347,7 @@ func TestDeleteActor_CollectsInFlightSnapshotWithoutTemplate(t *testing.T) { ctx := context.Background() persistence := newTestPersistence(t) objects := objectstoretest.New() - w := NewActorWorkflow(persistence, nil, nil, nil, nil, nil, "", nil, objectstoreplugintest.ControlClient(objects)) + w := NewActorWorkflow(persistence, nil, nil, nil, nil, nil, "", nil, objectstoreplugintest.ControlClient(objects), nil) actorRef := resources.ActorRef{Atespace: "team-a", Name: "actor-1"} actor := storetest.MustCreateActor(t, ctx, persistence, &ateapipb.Actor{ @@ -500,7 +500,7 @@ func TestDeleteActor_CollectsSnapshotsAfterWorkerDelete(t *testing.T) { }) } - actorWorkflow := NewActorWorkflow(persistence, nil, nil, nil, nil, nil, "", nil, objectstoreplugintest.ControlClient(objects)) + actorWorkflow := NewActorWorkflow(persistence, nil, nil, nil, nil, nil, "", nil, objectstoreplugintest.ControlClient(objects), nil) // Suspend the actor as far as it gets: MarkSuspending mints the // in-progress URI, and the checkpoint writes under it actor, err := actorWorkflow.ensureMarkedSuspending(ctx, actorRef, actor, template) diff --git a/cmd/ateapi/internal/controlapi/workflow_resume.go b/cmd/ateapi/internal/controlapi/workflow_resume.go index 2a8e649ddf..6b5339bdce 100644 --- a/cmd/ateapi/internal/controlapi/workflow_resume.go +++ b/cmd/ateapi/internal/controlapi/workflow_resume.go @@ -199,12 +199,20 @@ func (w *ActorWorkflow) ensureVolumesCreated(ctx context.Context, actorRef resou break } } - if !pending { + borrows := len(borrowedVolumeRefs(actor)) > 0 + if !pending && !borrows { markSkipped(ctx, "no volumes awaiting creation") return actor, nil } - volumes, createErr := createActorVolumes(ctx, w.pluginRegistry, w.storageClassLister, actor.GetMetadata().GetUid(), actorTemplate, actor.GetStatus().GetExternalVolumes()) + volumes := actor.GetStatus().GetExternalVolumes() + if borrows { + var err error + if volumes, err = claimExternalVolumes(ctx, w.store, actor); err != nil { + return nil, err + } + } + volumes, createErr := createActorVolumes(ctx, w.pluginRegistry, w.storageClassLister, actor.GetMetadata().GetUid(), actorTemplate, volumes) // createActorVolumes reports the state it got to even when it fails, so both // paths persist the same field. updatePrecondition := store.PreconditionFrom(actor) diff --git a/cmd/ateapi/internal/controlapi/workflow_suspend.go b/cmd/ateapi/internal/controlapi/workflow_suspend.go index e6d462ddbb..39698594d6 100644 --- a/cmd/ateapi/internal/controlapi/workflow_suspend.go +++ b/cmd/ateapi/internal/controlapi/workflow_suspend.go @@ -340,16 +340,18 @@ func newInProgressSnapshotURI(actorTemplate *ateapipb.ActorTemplate, actor *atea return uri, nil } -// ensureVolumesDetached detaches the actor's mounted external volumes from -// its worker node. Detachment is idempotent, so a re-entered workflow safely -// runs it again. spanName distinguishes the suspend and pause steps in -// traces; op labels the volume metrics. +// ensureVolumesDetached detaches the actor's mounted external volumes from its +// worker node and marks its ExternalVolume references inactive. Both steps are +// idempotent; spanName distinguishes suspend from pause and op labels metrics. // TODO replace re-execution with a proper check on the volumes' attach state. func (w *ActorWorkflow) ensureVolumesDetached(ctx context.Context, actor *ateapipb.Actor, actorTemplate *ateapipb.ActorTemplate, spanName, op string) (err error) { ctx, done := stepSpan(ctx, spanName) defer func() { err = done(err) }() - return detachActorVolumes(ctx, w.pluginRegistry, actor, actorTemplate, op) + if err := detachActorVolumes(ctx, w.pluginRegistry, actor, actorTemplate, op); err != nil { + return err + } + return deactivateExternalVolumes(ctx, w.store, actor) } // ensureSuspendedFinalized releases the actor's worker (only when it is still diff --git a/cmd/ateapi/internal/controlapi/workflow_testutil_test.go b/cmd/ateapi/internal/controlapi/workflow_testutil_test.go index d2e78bd3cb..2920ea15e5 100644 --- a/cmd/ateapi/internal/controlapi/workflow_testutil_test.go +++ b/cmd/ateapi/internal/controlapi/workflow_testutil_test.go @@ -58,7 +58,7 @@ func newTestActorWorkflow(t *testing.T, st store.Interface, tmplAtespace, tmplNa }); err != nil && !errors.Is(err, store.ErrAlreadyExists) { t.Fatalf("create test ActorTemplate: %v", err) } - return NewActorWorkflow(st, nil, nil, nil, nil, nil, "", nil, objectstoreplugintest.ControlClient(objectstoretest.New())) + return NewActorWorkflow(st, nil, nil, nil, nil, nil, "", nil, objectstoreplugintest.ControlClient(objectstoretest.New()), nil) } // newFinalizeWorkflow builds an ActorWorkflow over persistence with an diff --git a/cmd/ateapi/internal/controlapi/workload_spec.go b/cmd/ateapi/internal/controlapi/workload_spec.go index 2c666994bf..a069d14762 100644 --- a/cmd/ateapi/internal/controlapi/workload_spec.go +++ b/cmd/ateapi/internal/controlapi/workload_spec.go @@ -55,6 +55,12 @@ func workloadSpecFromActorTemplate(actorTemplate *ateapipb.ActorTemplate, actor // already ensured that only one source is set. for _, vol := range actorTemplate.GetVolumes() { switch { + case vol.GetExternalVolumeRef() != nil && isGoldenActor(actor): + workloadSpec.Volumes = append(workloadSpec.Volumes, &ateletpb.Volume{ + Name: vol.GetName(), + Source: &ateletpb.Volume_EmptyDir{EmptyDir: &ateletpb.EmptyDirVolume{}}, + }) + case vol.GetDurableDir() != nil: workloadSpec.Volumes = append(workloadSpec.Volumes, &ateletpb.Volume{ Name: vol.GetName(), @@ -112,8 +118,11 @@ func workloadSpecFromActorTemplate(actorTemplate *ateapipb.ActorTemplate, actor }, }) + case vol.GetExternalVolumeTemplate() != nil, vol.GetExternalVolumeRef() != nil: + continue // appended by appendExternalVolumes from the actor's status + default: - continue // Drop unrecognized volumes. + return nil, fmt.Errorf("volume %q has no supported source", vol.GetName()) } } @@ -155,21 +164,24 @@ func workloadSpecFromActorTemplate(actorTemplate *ateapipb.ActorTemplate, actor return workloadSpec, nil } -// appendExternalVolumes maps template external volumes to resolved actor volumes -// and appends them to workloadSpec if they are referenced in container -// volumeMounts. volumePublishContexts carries the attachment metadata of the current -// resume by volume name; it is nil on paths that do not mount. +// appendExternalVolumes maps mounted external volumes, owned or referenced, to +// the handles recorded on the actor and appends them to workloadSpec. +// volumePublishContexts carries the attachment metadata of the current resume +// by volume name; it is nil on paths that do not mount. func appendExternalVolumes(workloadSpec *ateletpb.WorkloadSpec, template *ateapipb.ActorTemplate, actor *ateapipb.Actor, volumePublishContexts map[string]map[string]string) error { if template == nil { return nil } for _, vol := range template.GetVolumes() { - if vol.GetExternalVolumeTemplate() != nil { + if vol.GetExternalVolumeTemplate() != nil || vol.GetExternalVolumeRef() != nil { if !isVolumeMounted(vol.GetName(), template) { continue } + if vol.GetExternalVolumeRef() != nil && isGoldenActor(actor) { + continue + } if actor == nil { - return fmt.Errorf("actor is required when externalVolumeTemplate is present") + return fmt.Errorf("actor is required when an external volume is present") } var storageVolID string diff --git a/cmd/ateapi/internal/controlapi/workload_spec_test.go b/cmd/ateapi/internal/controlapi/workload_spec_test.go index 66cc175771..0095133079 100644 --- a/cmd/ateapi/internal/controlapi/workload_spec_test.go +++ b/cmd/ateapi/internal/controlapi/workload_spec_test.go @@ -15,9 +15,11 @@ package controlapi import ( + "strings" "testing" "github.com/agent-substrate/substrate/internal/proto/ateletpb" + "github.com/agent-substrate/substrate/internal/resources" "github.com/agent-substrate/substrate/pkg/proto/ateapipb" "github.com/google/go-cmp/cmp" "google.golang.org/protobuf/testing/protocmp" @@ -223,11 +225,12 @@ func TestWorkloadSpecFromActorTemplate(t *testing.T) { }, }, { - name: "skips non-DurableDir volumes", + name: "leaves unmounted external volumes out", template: &ateapipb.ActorTemplate{ Metadata: &ateapipb.ResourceMetadata{Atespace: "agent-ns", Name: "tmpl1"}, Volumes: []*ateapipb.Volume{ - {Name: "unsupported"}, + {Name: "borrowed", ExternalVolumeRef: &ateapipb.ExternalVolumeRef{Name: "shared"}}, + {Name: "owned", ExternalVolumeTemplate: &ateapipb.ExternalVolumeTemplate{StorageClassName: "standard"}}, {Name: "home", DurableDir: &ateapipb.DurableDirVolumeSource{}}, }, Containers: []*ateapipb.Container{ @@ -652,3 +655,90 @@ func TestWorkloadSpecFromActorTemplatePropagatesResources(t *testing.T) { t.Errorf("unlimited container Resources = %v, want nil", r) } } + +func TestWorkloadSpecFromActorTemplateRejectsUnknownVolumeSource(t *testing.T) { + _, err := workloadSpecFromActorTemplate(&ateapipb.ActorTemplate{ + Metadata: &ateapipb.ResourceMetadata{Atespace: "agent-ns", Name: "tmpl-unknown"}, + Volumes: []*ateapipb.Volume{{Name: "unsupported"}}, + }, nil, nil) + if err == nil || !strings.Contains(err.Error(), "unsupported") { + t.Fatalf("workloadSpecFromActorTemplate() error = %v, want one naming the volume", err) + } +} + +func TestWorkloadSpecBorrowedVolume(t *testing.T) { + template := &ateapipb.ActorTemplate{ + Metadata: &ateapipb.ResourceMetadata{Atespace: "space-abc", Name: "tmpl1"}, + Volumes: []*ateapipb.Volume{ + {Name: "borrowed", ExternalVolumeRef: &ateapipb.ExternalVolumeRef{}}, + {Name: "owned", ExternalVolumeTemplate: &ateapipb.ExternalVolumeTemplate{StorageClassName: "standard"}}, + }, + Containers: []*ateapipb.Container{{ + Name: "main", + VolumeMounts: []*ateapipb.VolumeMount{ + {Name: "borrowed", MountPath: "/mnt/shared"}, + {Name: "owned", MountPath: "/mnt/owned"}, + }, + }}, + } + owned := &ateletpb.Volume{ + Name: "owned", + Source: &ateletpb.Volume_External{External: &ateletpb.ExternalVolumeSource{ + StorageVolumeId: "disk-1", + VolumeType: "pd.csi.storage.gke.io", + }}, + } + + tests := []struct { + name string + actor *ateapipb.Actor + want []*ateletpb.Volume + }{ + { + name: "golden actor gets an empty dir in place of the shared volume", + actor: &ateapipb.Actor{ + Metadata: &ateapipb.ResourceMetadata{Atespace: resources.GoldenActorAtespace, Name: "tmpl1-uid"}, + Status: &ateapipb.ActorStatus{ExternalVolumes: []*ateapipb.ActorVolumeStatus{ + {Name: "owned", StorageVolumeId: "disk-1", VolumeType: "pd.csi.storage.gke.io"}, + }}, + }, + want: []*ateletpb.Volume{ + {Name: "borrowed", Source: &ateletpb.Volume_EmptyDir{EmptyDir: &ateletpb.EmptyDirVolume{}}}, + owned, + }, + }, + { + name: "user actor mounts the shared volume's handle", + actor: &ateapipb.Actor{ + Metadata: &ateapipb.ResourceMetadata{Atespace: "space-abc", Name: "consumer"}, + ExternalVolumeBindings: map[string]string{"borrowed": "shared"}, + Status: &ateapipb.ActorStatus{ExternalVolumes: []*ateapipb.ActorVolumeStatus{ + {Name: "borrowed", ExternalVolumeName: "shared", StorageVolumeId: "disk-shared", VolumeType: "nfs.csi.k8s.io", VolumeContext: map[string]string{"server": "10.0.0.2"}}, + {Name: "owned", StorageVolumeId: "disk-1", VolumeType: "pd.csi.storage.gke.io"}, + }}, + }, + want: []*ateletpb.Volume{ + { + Name: "borrowed", + Source: &ateletpb.Volume_External{External: &ateletpb.ExternalVolumeSource{ + StorageVolumeId: "disk-shared", + VolumeType: "nfs.csi.k8s.io", + VolumeContext: map[string]string{"server": "10.0.0.2"}, + }}, + }, + owned, + }, + }, + } + for _, tc := range tests { + t.Run(tc.name, func(t *testing.T) { + got, err := workloadSpecFromActorTemplate(template, tc.actor, nil) + if err != nil { + t.Fatalf("workloadSpecFromActorTemplate: %v", err) + } + if diff := cmp.Diff(tc.want, got.GetVolumes(), protocmp.Transform()); diff != "" { + t.Errorf("volumes mismatch (-want +got):\n%s", diff) + } + }) + } +} diff --git a/cmd/kubectl-ate/internal/cmd/actor.go b/cmd/kubectl-ate/internal/cmd/actor.go index ea74e334f6..e7c3791013 100644 --- a/cmd/kubectl-ate/internal/cmd/actor.go +++ b/cmd/kubectl-ate/internal/cmd/actor.go @@ -47,6 +47,7 @@ var ( createActorAtespaceFlag string createActorTemplateFlag string createActorTagFlag string + createActorVolumeFlag map[string]string deleteActorAtespaceFlag string deleteActorAnyStateFlag bool pauseActorAtespaceFlag string @@ -133,7 +134,7 @@ var createActorCmd = &cobra.Command{ Short: "Create an actor", Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { - request, err := buildCreateActorRequest(args[0], createActorAtespaceFlag, createActorTemplateFlag, createActorTagFlag) + request, err := buildCreateActorRequest(args[0], createActorAtespaceFlag, createActorTemplateFlag, createActorTagFlag, createActorVolumeFlag) if err != nil { return err } @@ -260,7 +261,7 @@ var logsActorsCmd = &cobra.Command{ RunE: runLogsActor, } -func buildCreateActorRequest(actorName, atespace, template, tag string) (*ateapipb.CreateActorRequest, error) { +func buildCreateActorRequest(actorName, atespace, template, tag string, volumes map[string]string) (*ateapipb.CreateActorRequest, error) { templateRef, err := parseAtespacedName(template, atespace) if err != nil { return nil, err @@ -272,6 +273,9 @@ func buildCreateActorRequest(actorName, atespace, template, tag string) (*ateapi }, ActorTemplate: templateRef, } + if len(volumes) > 0 { + actor.ExternalVolumeBindings = volumes + } if tag != "" { ref, err := parseAtespacedName(tag, atespace) @@ -735,6 +739,7 @@ func init() { createActorCmd.Flags().StringVarP(&createActorAtespaceFlag, "atespace", "a", "", "Atespace to create the actor in") _ = createActorCmd.MarkFlagRequired("atespace") createActorCmd.Flags().StringVar(&createActorTagFlag, "tag", "", "The name of a Tag to initialize the actor from, as /, or just to use the actor's own atespace (--atespace)") + createActorCmd.Flags().StringToStringVar(&createActorVolumeFlag, "volume", nil, "Bind an unnamed externalVolumeRef in the template to an ExternalVolume, as =; repeatable") createCmd.AddCommand(createActorCmd) deleteActorCmd.Flags().StringVarP(&deleteActorAtespaceFlag, "atespace", "a", "", "Atespace the actor lives in") diff --git a/cmd/kubectl-ate/internal/cmd/actor_test.go b/cmd/kubectl-ate/internal/cmd/actor_test.go index 2c3f36cf4a..a6cf7fb7b8 100644 --- a/cmd/kubectl-ate/internal/cmd/actor_test.go +++ b/cmd/kubectl-ate/internal/cmd/actor_test.go @@ -48,6 +48,7 @@ func TestBuildCreateActorRequest(t *testing.T) { name string templateRef string tag string + volumes map[string]string want *ateapipb.Actor wantErr bool }{ @@ -87,13 +88,23 @@ func TestBuildCreateActorRequest(t *testing.T) { ActorTemplate: &ateapipb.ObjectRef{Atespace: "shared-templates", Name: "counter"}, }, }, + { + name: "volume bindings", + templateRef: "counter", + volumes: map[string]string{"shared": "ctx-42"}, + want: &ateapipb.Actor{ + Metadata: &ateapipb.ResourceMetadata{Atespace: "demo", Name: "my-counter"}, + ActorTemplate: &ateapipb.ObjectRef{Atespace: "demo", Name: "counter"}, + ExternalVolumeBindings: map[string]string{"shared": "ctx-42"}, + }, + }, {name: "malformed template ref", templateRef: "a/b/c", wantErr: true}, {name: "malformed tag", templateRef: "counter", tag: "a/b/c", wantErr: true}, } for _, test := range tests { t.Run(test.name, func(t *testing.T) { - got, err := buildCreateActorRequest("my-counter", "demo", test.templateRef, test.tag) + got, err := buildCreateActorRequest("my-counter", "demo", test.templateRef, test.tag, test.volumes) if (err != nil) != test.wantErr { t.Fatalf("buildCreateActorRequest error = %v, wantErr %t", err, test.wantErr) } diff --git a/docs/csi-volumes.md b/docs/csi-volumes.md index ae170b3f25..7242bda436 100644 --- a/docs/csi-volumes.md +++ b/docs/csi-volumes.md @@ -190,3 +190,44 @@ volumes: capacity: 5Gi storageClassName: csi-nfs-sc ``` + +## 5. Shared External Volumes + +An `ExternalVolume` is an atespace-scoped CSI volume whose lifetime is +independent of any actor, so several actors can mount the same storage in turn. +Create one from a StorageClass, or register a volume that already exists: + +```bash +kubectl ate create externalvolume ctx-42 -a demo --storage-class csi-nfs-sc --capacity 10Gi +kubectl ate create externalvolume imported -a demo --volume-id --volume-type nfs.csi.k8s.io +``` + +Each volume records: + +- `accessMode`: fixed at create. Only `READ_WRITE_ONCE` is accepted today, so + at most one resumed actor holds the volume; a resume that would take a held + volume fails and names the holder. +- `deleteTrigger`: `MANUAL` removes the volume only on an explicit delete; + `LAST_ACTOR` removes it when the last actor referencing it is deleted. + Provisioned volumes default to `LAST_ACTOR`, registered ones to `MANUAL`. + Deleting the volume also deletes the storage. +- `status.refs`: every actor referencing the volume, with `active` set while + the actor is resumed. A referenced volume cannot be deleted. + +A template mounts an `ExternalVolume` with `externalVolumeRef`. Name the volume +in the template, or leave the name empty and bind it per actor at creation: + +```yaml +volumes: +- name: shared + externalVolumeRef: {} +``` + +```bash +kubectl ate create actor producer-42 -a demo --template producer --volume shared=ctx-42 +kubectl ate create actor consumer-42 -a demo --template consumer --volume shared=ctx-42 +``` + +Bindings are validated and recorded when the actor is created and cannot change +afterwards. Golden actors never reference a shared volume; they warm up against +an empty directory at the same mount path. diff --git a/internal/e2e/suites/combinedvolumes/combinedvolumes_test.go b/internal/e2e/suites/combinedvolumes/combinedvolumes_test.go index 70e6b5b823..d4c5104b5b 100644 --- a/internal/e2e/suites/combinedvolumes/combinedvolumes_test.go +++ b/internal/e2e/suites/combinedvolumes/combinedvolumes_test.go @@ -40,6 +40,8 @@ import ( "github.com/google/go-containerregistry/pkg/v1/mutate" "github.com/google/go-containerregistry/pkg/v1/remote" "github.com/google/go-containerregistry/pkg/v1/tarball" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/status" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) @@ -68,6 +70,10 @@ const ( // probeWrittenContent is the fixed string the probe's /writefile writes. probeWrittenContent = "written by probe" + sharedVolume = "shared" + sharedPath = "/mnt/ate-shared" + sharedFile = "handoff.txt" + payloadName = "payload.txt" payloadContent = "delivered by an image volume" // shadowedName is written by two layers; the upper one must win. @@ -461,3 +467,174 @@ func TestCombinedVolumes(t *testing.T) { }) }) } + +// createHandoffTemplate builds a probe ActorTemplate that references the +// ExternalVolume named volumeName. +func createHandoffTemplate(ctx context.Context, t *testing.T, clients *e2e.Clients, ns *e2e.Namespace, volumeName string) *ateapipb.ActorTemplate { + t.Helper() + + env, err := e2e.CheckEnv("BUCKET_NAME") + if err != nil { + t.Fatalf("CheckEnv: %v", err) + } + probeAtespace, _ := e2e.DeployProbe(t, env["BUCKET_NAME"], "combinedvolumes") + src := e2e.SubstrateFixture{ + Atespace: probeAtespace, + Name: probeName, + PoolNamespace: probeAtespace, + PoolName: probeName, + DeployWith: "the combinedvolumes suite's own DeployProbe", + } + return e2e.CreateSubstrateTemplateFrom(ctx, t, clients, ns.Name, src, e2e.SubstrateTemplateOptions{ + Atespace: atespace, + Name: "handoff-" + ns.Name, + PoolName: probeName, + PoolReplicas: 2, + Labels: map[string]string{"combinedvolumes": ns.Name}, + SnapshotConfig: &ateapipb.SnapshotConfig{ + StorageLocation: fmt.Sprintf("gs://%s/%s/", env["BUCKET_NAME"], ns.Name), + }, + Modify: func(tmpl *ateapipb.ActorTemplate) { + tmpl.Containers[0].VolumeMounts = append(tmpl.Containers[0].VolumeMounts, + &ateapipb.VolumeMount{Name: sharedVolume, MountPath: sharedPath}) + tmpl.Volumes = append(tmpl.Volumes, &ateapipb.Volume{ + Name: sharedVolume, + ExternalVolumeRef: &ateapipb.ExternalVolumeRef{Name: volumeName}, + }) + }, + }) +} + +// createHandoffActor creates a suspended actor from tmpl and registers its +// teardown, which must run before the shared volume's. +func createHandoffActor(ctx context.Context, t *testing.T, clients *e2e.Clients, tmpl *ateapipb.ActorTemplate, name string) resources.ActorRef { + t.Helper() + + actorRef := resources.ActorRef{Atespace: atespace, Name: name} + if _, err := clients.SubstrateAPI.CreateActor(ctx, &ateapipb.CreateActorRequest{ + Actor: &ateapipb.Actor{ + Metadata: &ateapipb.ResourceMetadata{Atespace: actorRef.Atespace, Name: actorRef.Name}, + ActorTemplate: e2e.TemplateRef(tmpl), + }, + }); err != nil { + t.Fatalf("CreateActor(%s): %v", name, err) + } + t.Cleanup(func() { + cleanupCtx := context.Background() + _, _ = clients.SubstrateAPI.SuspendActor(cleanupCtx, &ateapipb.SuspendActorRequest{Actor: actorRef.ToObjectRef()}) + _, _ = clients.SubstrateAPI.DeleteActor(cleanupCtx, &ateapipb.DeleteActorRequest{Actor: actorRef.ToObjectRef()}) + }) + return actorRef +} + +func TestSharedExternalVolumeHandoff(t *testing.T) { + ctx := context.Background() + clients := e2e.GetClients() + ns := e2e.CreateNamespace(t) + + if storageClassOrEmpty(ctx, t, clients) == "" { + t.Skipf("StorageClass %q is not installed", e2e.StorageClass) + } + + volumeName := "shared-" + ns.Name + // The template is created first because it creates the suite's atespace. + tmpl := createHandoffTemplate(ctx, t, clients, ns, volumeName) + + volumeRef := &ateapipb.ObjectRef{Atespace: atespace, Name: volumeName} + if _, err := clients.SubstrateAPI.CreateExternalVolume(ctx, &ateapipb.CreateExternalVolumeRequest{ + ExternalVolume: &ateapipb.ExternalVolume{ + Metadata: &ateapipb.ResourceMetadata{Atespace: atespace, Name: volumeName}, + StorageClassName: e2e.StorageClass, + Capacity: extCapacity, + DeleteTrigger: ateapipb.DeleteTrigger_DELETE_TRIGGER_MANUAL, + }, + }); err != nil { + t.Fatalf("CreateExternalVolume: %v", err) + } + t.Cleanup(func() { + if _, err := clients.SubstrateAPI.DeleteExternalVolume(context.Background(), &ateapipb.DeleteExternalVolumeRequest{ExternalVolume: volumeRef}); err != nil { + t.Errorf("DeleteExternalVolume: %v", err) + } + }) + + producer := createHandoffActor(ctx, t, clients, tmpl, "producer-"+ns.Name) + consumer := createHandoffActor(ctx, t, clients, tmpl, "consumer-"+ns.Name) + + router, err := e2e.NewRouterClient(ctx) + if err != nil { + t.Fatalf("NewRouterClient: %v", err) + } + defer router.Close() + + handoffFile := sharedPath + "/" + sharedFile + if _, err := e2e.ResumeActorAwaitCapacity(t, ctx, clients, &ateapipb.ResumeActorRequest{Actor: producer.ToObjectRef()}); err != nil { + t.Fatalf("ResumeActor(producer): %v", err) + } + requireUnreadable(ctx, t, router, producer, handoffFile) + if got := probeJSON(ctx, t, router, producer, "/writefile?path="+handoffFile); got["error"] != "" { + t.Fatalf("writing %s: %s", handoffFile, got["error"]) + } + requireContent(ctx, t, router, producer, handoffFile, probeWrittenContent) + + _, err = e2e.ResumeActorAwaitCapacity(t, ctx, clients, &ateapipb.ResumeActorRequest{Actor: consumer.ToObjectRef()}) + if status.Code(err) != codes.FailedPrecondition || !strings.Contains(err.Error(), producer.Name) { + t.Fatalf("ResumeActor(consumer) while the producer holds the volume = %v, want FailedPrecondition naming %q", err, producer.Name) + } + blocked, err := clients.SubstrateAPI.GetActor(ctx, &ateapipb.GetActorRequest{Actor: consumer.ToObjectRef()}) + if err != nil { + t.Fatalf("GetActor(consumer): %v", err) + } + if got := blocked.GetStatus().GetState(); got != ateapipb.ActorState_ACTOR_STATE_SUSPENDED { + t.Errorf("consumer state after a refused claim = %s, want ACTOR_STATE_SUSPENDED", got) + } + + if _, err := clients.SubstrateAPI.SuspendActor(ctx, &ateapipb.SuspendActorRequest{Actor: producer.ToObjectRef()}); err != nil { + t.Fatalf("SuspendActor(producer): %v", err) + } + if _, err := e2e.ResumeActorAwaitCapacity(t, ctx, clients, &ateapipb.ResumeActorRequest{Actor: consumer.ToObjectRef()}); err != nil { + t.Fatalf("ResumeActor(consumer): %v", err) + } + requireContent(ctx, t, router, consumer, handoffFile, probeWrittenContent) + + if _, err := clients.SubstrateAPI.DeleteExternalVolume(ctx, &ateapipb.DeleteExternalVolumeRequest{ExternalVolume: volumeRef}); status.Code(err) != codes.FailedPrecondition { + t.Errorf("DeleteExternalVolume while referenced = %v, want FailedPrecondition", err) + } + stored, err := clients.SubstrateAPI.GetExternalVolume(ctx, &ateapipb.GetExternalVolumeRequest{ExternalVolume: volumeRef}) + if err != nil { + t.Fatalf("GetExternalVolume: %v", err) + } + actor, err := clients.SubstrateAPI.GetActor(ctx, &ateapipb.GetActorRequest{Actor: consumer.ToObjectRef()}) + if err != nil { + t.Fatalf("GetActor(consumer): %v", err) + } + var mounted string + for _, vol := range actor.GetStatus().GetExternalVolumes() { + if vol.GetName() == sharedVolume { + mounted = vol.GetStorageVolumeId() + } + } + if mounted != stored.GetVolumeId() { + t.Errorf("the consumer mounted %q, want the shared volume %q", mounted, stored.GetVolumeId()) + } +} + +func TestSharedExternalVolumeMissing(t *testing.T) { + ctx := context.Background() + clients := e2e.GetClients() + ns := e2e.CreateNamespace(t) + + if storageClassOrEmpty(ctx, t, clients) == "" { + t.Skipf("StorageClass %q is not installed", e2e.StorageClass) + } + + tmpl := createHandoffTemplate(ctx, t, clients, ns, "absent-"+ns.Name) + _, err := clients.SubstrateAPI.CreateActor(ctx, &ateapipb.CreateActorRequest{ + Actor: &ateapipb.Actor{ + Metadata: &ateapipb.ResourceMetadata{Atespace: atespace, Name: "orphan-" + ns.Name}, + ActorTemplate: e2e.TemplateRef(tmpl), + }, + }) + if status.Code(err) != codes.FailedPrecondition { + t.Fatalf("CreateActor with an unresolvable volume reference = %v, want FailedPrecondition", err) + } +} diff --git a/pkg/proto/ateapipb/ateapi.pb.go b/pkg/proto/ateapipb/ateapi.pb.go index f253e89184..dc906583ed 100644 --- a/pkg/proto/ateapipb/ateapi.pb.go +++ b/pkg/proto/ateapipb/ateapi.pb.go @@ -1277,8 +1277,16 @@ type ActorVolumeStatus struct { // +k8s:eachKey=+k8s:maxLength=128 // +k8s:eachVal=+k8s:maxLength=256 VolumeContext map[string]string `protobuf:"bytes,5,rep,name=volume_context,json=volumeContext,proto3" json:"volume_context,omitempty" protobuf_key:"bytes,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache + // external_volume_name names the ExternalVolume this mount references, in the + // actor's atespace. Empty when the actor owns the volume itself. + // + // +k8s:optional + // +k8s:format=k8s-short-name + // +k8s:update=NoModify + // +k8s:update=NoUnset + ExternalVolumeName string `protobuf:"bytes,6,opt,name=external_volume_name,json=externalVolumeName,proto3" json:"external_volume_name,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache } func (x *ActorVolumeStatus) Reset() { @@ -1346,6 +1354,13 @@ func (x *ActorVolumeStatus) GetVolumeContext() map[string]string { return nil } +func (x *ActorVolumeStatus) GetExternalVolumeName() string { + if x != nil { + return x.ExternalVolumeName + } + return "" +} + type Actor struct { state protoimpl.MessageState `protogen:"open.v1"` // Common resource metadata: atespace, name, uid, version, timestamps. @@ -1377,9 +1392,19 @@ type Actor struct { // server and ignored on input. It is always present in output. // // +k8s:optional - Status *ActorStatus `protobuf:"bytes,7,opt,name=status,proto3" json:"status,omitempty"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache + Status *ActorStatus `protobuf:"bytes,7,opt,name=status,proto3" json:"status,omitempty"` + // external_volume_bindings maps each unnamed external_volume_ref in the + // template, by volume name, to the ExternalVolume this actor mounts. Every + // unnamed ref must be bound; a named ref cannot be rebound. Set at creation. + // + // +k8s:optional + // +k8s:maxProperties=32 + // +k8s:eachKey=+k8s:format=k8s-short-name + // +k8s:eachVal=+k8s:format=k8s-short-name + // +k8s:immutable + ExternalVolumeBindings map[string]string `protobuf:"bytes,8,rep,name=external_volume_bindings,json=externalVolumeBindings,proto3" json:"external_volume_bindings,omitempty" protobuf_key:"bytes,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache } func (x *Actor) Reset() { @@ -1447,6 +1472,13 @@ func (x *Actor) GetStatus() *ActorStatus { return nil } +func (x *Actor) GetExternalVolumeBindings() map[string]string { + if x != nil { + return x.ExternalVolumeBindings + } + return nil +} + // EgressPolicy is an egress policy resource nested under an Actor. An Actor has // at most one egress policy resource, named "default". type EgressPolicy struct { @@ -4086,8 +4118,8 @@ type Volume struct { // +k8s:required // +k8s:format=k8s-short-name Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` - // Exactly one of durable_dir / external_volume_template / image / - // system_info must be set. + // Exactly one of durable_dir / external_volume_template / + // external_volume_ref / image / system_info must be set. // // +k8s:optional // +k8s:unionMember @@ -4095,6 +4127,11 @@ type Volume struct { // +k8s:optional // +k8s:unionMember ExternalVolumeTemplate *ExternalVolumeTemplate `protobuf:"bytes,3,opt,name=external_volume_template,json=externalVolumeTemplate,proto3" json:"external_volume_template,omitempty"` + // external_volume_ref mounts an ExternalVolume that already exists. + // + // +k8s:optional + // +k8s:unionMember + ExternalVolumeRef *ExternalVolumeRef `protobuf:"bytes,4,opt,name=external_volume_ref,json=externalVolumeRef,proto3" json:"external_volume_ref,omitempty"` // +k8s:optional // +k8s:unionMember SystemInfo *SystemInfoVolumeSource `protobuf:"bytes,5,opt,name=system_info,json=systemInfo,proto3" json:"system_info,omitempty"` @@ -4158,6 +4195,13 @@ func (x *Volume) GetExternalVolumeTemplate() *ExternalVolumeTemplate { return nil } +func (x *Volume) GetExternalVolumeRef() *ExternalVolumeRef { + if x != nil { + return x.ExternalVolumeRef + } + return nil +} + func (x *Volume) GetSystemInfo() *SystemInfoVolumeSource { if x != nil { return x.SystemInfo @@ -4328,6 +4372,57 @@ func (x *ExternalVolumeTemplate) GetStorageClassName() string { return "" } +// ExternalVolumeRef mounts an ExternalVolume in the actor's atespace. The +// volume outlives the actor, so several actors can mount it in turn. +type ExternalVolumeRef struct { + state protoimpl.MessageState `protogen:"open.v1"` + // name of the ExternalVolume. Left empty, the actor names it at creation in + // Actor.external_volume_bindings. + // + // +k8s:optional + // +k8s:format=k8s-short-name + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *ExternalVolumeRef) Reset() { + *x = ExternalVolumeRef{} + mi := &file_ateapi_proto_msgTypes[45] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ExternalVolumeRef) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ExternalVolumeRef) ProtoMessage() {} + +func (x *ExternalVolumeRef) ProtoReflect() protoreflect.Message { + mi := &file_ateapi_proto_msgTypes[45] + 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 ExternalVolumeRef.ProtoReflect.Descriptor instead. +func (*ExternalVolumeRef) Descriptor() ([]byte, []int) { + return file_ateapi_proto_rawDescGZIP(), []int{45} +} + +func (x *ExternalVolumeRef) GetName() string { + if x != nil { + return x.Name + } + return "" +} + // SystemInfoVolumeSource is a read-only volume of substrate-generated // per-actor files (identity fields, projected trust bundles), regenerated by // atelet on every Run/Restore. @@ -4348,7 +4443,7 @@ type SystemInfoVolumeSource struct { func (x *SystemInfoVolumeSource) Reset() { *x = SystemInfoVolumeSource{} - mi := &file_ateapi_proto_msgTypes[45] + mi := &file_ateapi_proto_msgTypes[46] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4360,7 +4455,7 @@ func (x *SystemInfoVolumeSource) String() string { func (*SystemInfoVolumeSource) ProtoMessage() {} func (x *SystemInfoVolumeSource) ProtoReflect() protoreflect.Message { - mi := &file_ateapi_proto_msgTypes[45] + mi := &file_ateapi_proto_msgTypes[46] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4373,7 +4468,7 @@ func (x *SystemInfoVolumeSource) ProtoReflect() protoreflect.Message { // Deprecated: Use SystemInfoVolumeSource.ProtoReflect.Descriptor instead. func (*SystemInfoVolumeSource) Descriptor() ([]byte, []int) { - return file_ateapi_proto_rawDescGZIP(), []int{45} + return file_ateapi_proto_rawDescGZIP(), []int{46} } func (x *SystemInfoVolumeSource) GetDataSources() []*SystemInfoDataSource { @@ -4399,7 +4494,7 @@ type SystemInfoDataSource struct { func (x *SystemInfoDataSource) Reset() { *x = SystemInfoDataSource{} - mi := &file_ateapi_proto_msgTypes[46] + mi := &file_ateapi_proto_msgTypes[47] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4411,7 +4506,7 @@ func (x *SystemInfoDataSource) String() string { func (*SystemInfoDataSource) ProtoMessage() {} func (x *SystemInfoDataSource) ProtoReflect() protoreflect.Message { - mi := &file_ateapi_proto_msgTypes[46] + mi := &file_ateapi_proto_msgTypes[47] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4424,7 +4519,7 @@ func (x *SystemInfoDataSource) ProtoReflect() protoreflect.Message { // Deprecated: Use SystemInfoDataSource.ProtoReflect.Descriptor instead. func (*SystemInfoDataSource) Descriptor() ([]byte, []int) { - return file_ateapi_proto_rawDescGZIP(), []int{46} + return file_ateapi_proto_rawDescGZIP(), []int{47} } func (x *SystemInfoDataSource) GetActorMetadata() *ActorMetadataDataSource { @@ -4461,7 +4556,7 @@ type ActorMetadataDataSource struct { func (x *ActorMetadataDataSource) Reset() { *x = ActorMetadataDataSource{} - mi := &file_ateapi_proto_msgTypes[47] + mi := &file_ateapi_proto_msgTypes[48] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4473,7 +4568,7 @@ func (x *ActorMetadataDataSource) String() string { func (*ActorMetadataDataSource) ProtoMessage() {} func (x *ActorMetadataDataSource) ProtoReflect() protoreflect.Message { - mi := &file_ateapi_proto_msgTypes[47] + mi := &file_ateapi_proto_msgTypes[48] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4486,7 +4581,7 @@ func (x *ActorMetadataDataSource) ProtoReflect() protoreflect.Message { // Deprecated: Use ActorMetadataDataSource.ProtoReflect.Descriptor instead. func (*ActorMetadataDataSource) Descriptor() ([]byte, []int) { - return file_ateapi_proto_rawDescGZIP(), []int{47} + return file_ateapi_proto_rawDescGZIP(), []int{48} } func (x *ActorMetadataDataSource) GetItems() []*ActorMetadataItem { @@ -4518,7 +4613,7 @@ type ActorMetadataItem struct { func (x *ActorMetadataItem) Reset() { *x = ActorMetadataItem{} - mi := &file_ateapi_proto_msgTypes[48] + mi := &file_ateapi_proto_msgTypes[49] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4530,7 +4625,7 @@ func (x *ActorMetadataItem) String() string { func (*ActorMetadataItem) ProtoMessage() {} func (x *ActorMetadataItem) ProtoReflect() protoreflect.Message { - mi := &file_ateapi_proto_msgTypes[48] + mi := &file_ateapi_proto_msgTypes[49] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4543,7 +4638,7 @@ func (x *ActorMetadataItem) ProtoReflect() protoreflect.Message { // Deprecated: Use ActorMetadataItem.ProtoReflect.Descriptor instead. func (*ActorMetadataItem) Descriptor() ([]byte, []int) { - return file_ateapi_proto_rawDescGZIP(), []int{48} + return file_ateapi_proto_rawDescGZIP(), []int{49} } func (x *ActorMetadataItem) GetField() ActorMetadataField { @@ -4595,7 +4690,7 @@ type TrustBundleDataSource struct { func (x *TrustBundleDataSource) Reset() { *x = TrustBundleDataSource{} - mi := &file_ateapi_proto_msgTypes[49] + mi := &file_ateapi_proto_msgTypes[50] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4607,7 +4702,7 @@ func (x *TrustBundleDataSource) String() string { func (*TrustBundleDataSource) ProtoMessage() {} func (x *TrustBundleDataSource) ProtoReflect() protoreflect.Message { - mi := &file_ateapi_proto_msgTypes[49] + mi := &file_ateapi_proto_msgTypes[50] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4620,7 +4715,7 @@ func (x *TrustBundleDataSource) ProtoReflect() protoreflect.Message { // Deprecated: Use TrustBundleDataSource.ProtoReflect.Descriptor instead. func (*TrustBundleDataSource) Descriptor() ([]byte, []int) { - return file_ateapi_proto_rawDescGZIP(), []int{49} + return file_ateapi_proto_rawDescGZIP(), []int{50} } func (x *TrustBundleDataSource) GetNames() []string { @@ -4659,7 +4754,7 @@ type VolumeMount struct { func (x *VolumeMount) Reset() { *x = VolumeMount{} - mi := &file_ateapi_proto_msgTypes[50] + mi := &file_ateapi_proto_msgTypes[51] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4671,7 +4766,7 @@ func (x *VolumeMount) String() string { func (*VolumeMount) ProtoMessage() {} func (x *VolumeMount) ProtoReflect() protoreflect.Message { - mi := &file_ateapi_proto_msgTypes[50] + mi := &file_ateapi_proto_msgTypes[51] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4684,7 +4779,7 @@ func (x *VolumeMount) ProtoReflect() protoreflect.Message { // Deprecated: Use VolumeMount.ProtoReflect.Descriptor instead. func (*VolumeMount) Descriptor() ([]byte, []int) { - return file_ateapi_proto_rawDescGZIP(), []int{50} + return file_ateapi_proto_rawDescGZIP(), []int{51} } func (x *VolumeMount) GetName() string { @@ -4713,7 +4808,7 @@ type CreateAtespaceRequest struct { func (x *CreateAtespaceRequest) Reset() { *x = CreateAtespaceRequest{} - mi := &file_ateapi_proto_msgTypes[51] + mi := &file_ateapi_proto_msgTypes[52] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4725,7 +4820,7 @@ func (x *CreateAtespaceRequest) String() string { func (*CreateAtespaceRequest) ProtoMessage() {} func (x *CreateAtespaceRequest) ProtoReflect() protoreflect.Message { - mi := &file_ateapi_proto_msgTypes[51] + mi := &file_ateapi_proto_msgTypes[52] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4738,7 +4833,7 @@ func (x *CreateAtespaceRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use CreateAtespaceRequest.ProtoReflect.Descriptor instead. func (*CreateAtespaceRequest) Descriptor() ([]byte, []int) { - return file_ateapi_proto_rawDescGZIP(), []int{51} + return file_ateapi_proto_rawDescGZIP(), []int{52} } func (x *CreateAtespaceRequest) GetAtespace() *Atespace { @@ -4759,7 +4854,7 @@ type GetAtespaceRequest struct { func (x *GetAtespaceRequest) Reset() { *x = GetAtespaceRequest{} - mi := &file_ateapi_proto_msgTypes[52] + mi := &file_ateapi_proto_msgTypes[53] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4771,7 +4866,7 @@ func (x *GetAtespaceRequest) String() string { func (*GetAtespaceRequest) ProtoMessage() {} func (x *GetAtespaceRequest) ProtoReflect() protoreflect.Message { - mi := &file_ateapi_proto_msgTypes[52] + mi := &file_ateapi_proto_msgTypes[53] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4784,7 +4879,7 @@ func (x *GetAtespaceRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use GetAtespaceRequest.ProtoReflect.Descriptor instead. func (*GetAtespaceRequest) Descriptor() ([]byte, []int) { - return file_ateapi_proto_rawDescGZIP(), []int{52} + return file_ateapi_proto_rawDescGZIP(), []int{53} } func (x *GetAtespaceRequest) GetAtespace() *ObjectRef { @@ -4815,7 +4910,7 @@ type ListAtespacesRequest struct { func (x *ListAtespacesRequest) Reset() { *x = ListAtespacesRequest{} - mi := &file_ateapi_proto_msgTypes[53] + mi := &file_ateapi_proto_msgTypes[54] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4827,7 +4922,7 @@ func (x *ListAtespacesRequest) String() string { func (*ListAtespacesRequest) ProtoMessage() {} func (x *ListAtespacesRequest) ProtoReflect() protoreflect.Message { - mi := &file_ateapi_proto_msgTypes[53] + mi := &file_ateapi_proto_msgTypes[54] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4840,7 +4935,7 @@ func (x *ListAtespacesRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use ListAtespacesRequest.ProtoReflect.Descriptor instead. func (*ListAtespacesRequest) Descriptor() ([]byte, []int) { - return file_ateapi_proto_rawDescGZIP(), []int{53} + return file_ateapi_proto_rawDescGZIP(), []int{54} } func (x *ListAtespacesRequest) GetPageSize() int32 { @@ -4869,7 +4964,7 @@ type ListAtespacesResponse struct { func (x *ListAtespacesResponse) Reset() { *x = ListAtespacesResponse{} - mi := &file_ateapi_proto_msgTypes[54] + mi := &file_ateapi_proto_msgTypes[55] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4881,7 +4976,7 @@ func (x *ListAtespacesResponse) String() string { func (*ListAtespacesResponse) ProtoMessage() {} func (x *ListAtespacesResponse) ProtoReflect() protoreflect.Message { - mi := &file_ateapi_proto_msgTypes[54] + mi := &file_ateapi_proto_msgTypes[55] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4894,7 +4989,7 @@ func (x *ListAtespacesResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use ListAtespacesResponse.ProtoReflect.Descriptor instead. func (*ListAtespacesResponse) Descriptor() ([]byte, []int) { - return file_ateapi_proto_rawDescGZIP(), []int{54} + return file_ateapi_proto_rawDescGZIP(), []int{55} } func (x *ListAtespacesResponse) GetAtespaces() []*Atespace { @@ -4926,7 +5021,7 @@ type DeleteAtespaceRequest struct { func (x *DeleteAtespaceRequest) Reset() { *x = DeleteAtespaceRequest{} - mi := &file_ateapi_proto_msgTypes[55] + mi := &file_ateapi_proto_msgTypes[56] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4938,7 +5033,7 @@ func (x *DeleteAtespaceRequest) String() string { func (*DeleteAtespaceRequest) ProtoMessage() {} func (x *DeleteAtespaceRequest) ProtoReflect() protoreflect.Message { - mi := &file_ateapi_proto_msgTypes[55] + mi := &file_ateapi_proto_msgTypes[56] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4951,7 +5046,7 @@ func (x *DeleteAtespaceRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use DeleteAtespaceRequest.ProtoReflect.Descriptor instead. func (*DeleteAtespaceRequest) Descriptor() ([]byte, []int) { - return file_ateapi_proto_rawDescGZIP(), []int{55} + return file_ateapi_proto_rawDescGZIP(), []int{56} } func (x *DeleteAtespaceRequest) GetAtespace() *ObjectRef { @@ -4982,7 +5077,7 @@ type CreateActorTemplateRequest struct { func (x *CreateActorTemplateRequest) Reset() { *x = CreateActorTemplateRequest{} - mi := &file_ateapi_proto_msgTypes[56] + mi := &file_ateapi_proto_msgTypes[57] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4994,7 +5089,7 @@ func (x *CreateActorTemplateRequest) String() string { func (*CreateActorTemplateRequest) ProtoMessage() {} func (x *CreateActorTemplateRequest) ProtoReflect() protoreflect.Message { - mi := &file_ateapi_proto_msgTypes[56] + mi := &file_ateapi_proto_msgTypes[57] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5007,7 +5102,7 @@ func (x *CreateActorTemplateRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use CreateActorTemplateRequest.ProtoReflect.Descriptor instead. func (*CreateActorTemplateRequest) Descriptor() ([]byte, []int) { - return file_ateapi_proto_rawDescGZIP(), []int{56} + return file_ateapi_proto_rawDescGZIP(), []int{57} } func (x *CreateActorTemplateRequest) GetActorTemplate() *ActorTemplate { @@ -5028,7 +5123,7 @@ type GetActorTemplateRequest struct { func (x *GetActorTemplateRequest) Reset() { *x = GetActorTemplateRequest{} - mi := &file_ateapi_proto_msgTypes[57] + mi := &file_ateapi_proto_msgTypes[58] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5040,7 +5135,7 @@ func (x *GetActorTemplateRequest) String() string { func (*GetActorTemplateRequest) ProtoMessage() {} func (x *GetActorTemplateRequest) ProtoReflect() protoreflect.Message { - mi := &file_ateapi_proto_msgTypes[57] + mi := &file_ateapi_proto_msgTypes[58] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5053,7 +5148,7 @@ func (x *GetActorTemplateRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use GetActorTemplateRequest.ProtoReflect.Descriptor instead. func (*GetActorTemplateRequest) Descriptor() ([]byte, []int) { - return file_ateapi_proto_rawDescGZIP(), []int{57} + return file_ateapi_proto_rawDescGZIP(), []int{58} } func (x *GetActorTemplateRequest) GetActorTemplate() *ObjectRef { @@ -5090,7 +5185,7 @@ type ListActorTemplatesRequest struct { func (x *ListActorTemplatesRequest) Reset() { *x = ListActorTemplatesRequest{} - mi := &file_ateapi_proto_msgTypes[58] + mi := &file_ateapi_proto_msgTypes[59] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5102,7 +5197,7 @@ func (x *ListActorTemplatesRequest) String() string { func (*ListActorTemplatesRequest) ProtoMessage() {} func (x *ListActorTemplatesRequest) ProtoReflect() protoreflect.Message { - mi := &file_ateapi_proto_msgTypes[58] + mi := &file_ateapi_proto_msgTypes[59] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5115,7 +5210,7 @@ func (x *ListActorTemplatesRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use ListActorTemplatesRequest.ProtoReflect.Descriptor instead. func (*ListActorTemplatesRequest) Descriptor() ([]byte, []int) { - return file_ateapi_proto_rawDescGZIP(), []int{58} + return file_ateapi_proto_rawDescGZIP(), []int{59} } func (x *ListActorTemplatesRequest) GetAtespace() string { @@ -5152,7 +5247,7 @@ type ListActorTemplatesResponse struct { func (x *ListActorTemplatesResponse) Reset() { *x = ListActorTemplatesResponse{} - mi := &file_ateapi_proto_msgTypes[59] + mi := &file_ateapi_proto_msgTypes[60] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5164,7 +5259,7 @@ func (x *ListActorTemplatesResponse) String() string { func (*ListActorTemplatesResponse) ProtoMessage() {} func (x *ListActorTemplatesResponse) ProtoReflect() protoreflect.Message { - mi := &file_ateapi_proto_msgTypes[59] + mi := &file_ateapi_proto_msgTypes[60] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5177,7 +5272,7 @@ func (x *ListActorTemplatesResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use ListActorTemplatesResponse.ProtoReflect.Descriptor instead. func (*ListActorTemplatesResponse) Descriptor() ([]byte, []int) { - return file_ateapi_proto_rawDescGZIP(), []int{59} + return file_ateapi_proto_rawDescGZIP(), []int{60} } func (x *ListActorTemplatesResponse) GetActorTemplates() []*ActorTemplate { @@ -5209,7 +5304,7 @@ type DeleteActorTemplateRequest struct { func (x *DeleteActorTemplateRequest) Reset() { *x = DeleteActorTemplateRequest{} - mi := &file_ateapi_proto_msgTypes[60] + mi := &file_ateapi_proto_msgTypes[61] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5221,7 +5316,7 @@ func (x *DeleteActorTemplateRequest) String() string { func (*DeleteActorTemplateRequest) ProtoMessage() {} func (x *DeleteActorTemplateRequest) ProtoReflect() protoreflect.Message { - mi := &file_ateapi_proto_msgTypes[60] + mi := &file_ateapi_proto_msgTypes[61] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5234,7 +5329,7 @@ func (x *DeleteActorTemplateRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use DeleteActorTemplateRequest.ProtoReflect.Descriptor instead. func (*DeleteActorTemplateRequest) Descriptor() ([]byte, []int) { - return file_ateapi_proto_rawDescGZIP(), []int{60} + return file_ateapi_proto_rawDescGZIP(), []int{61} } func (x *DeleteActorTemplateRequest) GetActorTemplate() *ObjectRef { @@ -5262,7 +5357,7 @@ type GetActorRequest struct { func (x *GetActorRequest) Reset() { *x = GetActorRequest{} - mi := &file_ateapi_proto_msgTypes[61] + mi := &file_ateapi_proto_msgTypes[62] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5274,7 +5369,7 @@ func (x *GetActorRequest) String() string { func (*GetActorRequest) ProtoMessage() {} func (x *GetActorRequest) ProtoReflect() protoreflect.Message { - mi := &file_ateapi_proto_msgTypes[61] + mi := &file_ateapi_proto_msgTypes[62] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5287,7 +5382,7 @@ func (x *GetActorRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use GetActorRequest.ProtoReflect.Descriptor instead. func (*GetActorRequest) Descriptor() ([]byte, []int) { - return file_ateapi_proto_rawDescGZIP(), []int{61} + return file_ateapi_proto_rawDescGZIP(), []int{62} } func (x *GetActorRequest) GetActor() *ObjectRef { @@ -5310,7 +5405,7 @@ type CreateActorRequest struct { func (x *CreateActorRequest) Reset() { *x = CreateActorRequest{} - mi := &file_ateapi_proto_msgTypes[62] + mi := &file_ateapi_proto_msgTypes[63] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5322,7 +5417,7 @@ func (x *CreateActorRequest) String() string { func (*CreateActorRequest) ProtoMessage() {} func (x *CreateActorRequest) ProtoReflect() protoreflect.Message { - mi := &file_ateapi_proto_msgTypes[62] + mi := &file_ateapi_proto_msgTypes[63] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5335,7 +5430,7 @@ func (x *CreateActorRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use CreateActorRequest.ProtoReflect.Descriptor instead. func (*CreateActorRequest) Descriptor() ([]byte, []int) { - return file_ateapi_proto_rawDescGZIP(), []int{62} + return file_ateapi_proto_rawDescGZIP(), []int{63} } func (x *CreateActorRequest) GetActor() *Actor { @@ -5366,7 +5461,7 @@ type UpdateActorRequest struct { func (x *UpdateActorRequest) Reset() { *x = UpdateActorRequest{} - mi := &file_ateapi_proto_msgTypes[63] + mi := &file_ateapi_proto_msgTypes[64] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5378,7 +5473,7 @@ func (x *UpdateActorRequest) String() string { func (*UpdateActorRequest) ProtoMessage() {} func (x *UpdateActorRequest) ProtoReflect() protoreflect.Message { - mi := &file_ateapi_proto_msgTypes[63] + mi := &file_ateapi_proto_msgTypes[64] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5391,7 +5486,7 @@ func (x *UpdateActorRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use UpdateActorRequest.ProtoReflect.Descriptor instead. func (*UpdateActorRequest) Descriptor() ([]byte, []int) { - return file_ateapi_proto_rawDescGZIP(), []int{63} + return file_ateapi_proto_rawDescGZIP(), []int{64} } func (x *UpdateActorRequest) GetActor() *Actor { @@ -5412,7 +5507,7 @@ type SuspendActorRequest struct { func (x *SuspendActorRequest) Reset() { *x = SuspendActorRequest{} - mi := &file_ateapi_proto_msgTypes[64] + mi := &file_ateapi_proto_msgTypes[65] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5424,7 +5519,7 @@ func (x *SuspendActorRequest) String() string { func (*SuspendActorRequest) ProtoMessage() {} func (x *SuspendActorRequest) ProtoReflect() protoreflect.Message { - mi := &file_ateapi_proto_msgTypes[64] + mi := &file_ateapi_proto_msgTypes[65] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5437,7 +5532,7 @@ func (x *SuspendActorRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use SuspendActorRequest.ProtoReflect.Descriptor instead. func (*SuspendActorRequest) Descriptor() ([]byte, []int) { - return file_ateapi_proto_rawDescGZIP(), []int{64} + return file_ateapi_proto_rawDescGZIP(), []int{65} } func (x *SuspendActorRequest) GetActor() *ObjectRef { @@ -5456,7 +5551,7 @@ type SuspendActorResponse struct { func (x *SuspendActorResponse) Reset() { *x = SuspendActorResponse{} - mi := &file_ateapi_proto_msgTypes[65] + mi := &file_ateapi_proto_msgTypes[66] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5468,7 +5563,7 @@ func (x *SuspendActorResponse) String() string { func (*SuspendActorResponse) ProtoMessage() {} func (x *SuspendActorResponse) ProtoReflect() protoreflect.Message { - mi := &file_ateapi_proto_msgTypes[65] + mi := &file_ateapi_proto_msgTypes[66] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5481,7 +5576,7 @@ func (x *SuspendActorResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use SuspendActorResponse.ProtoReflect.Descriptor instead. func (*SuspendActorResponse) Descriptor() ([]byte, []int) { - return file_ateapi_proto_rawDescGZIP(), []int{65} + return file_ateapi_proto_rawDescGZIP(), []int{66} } func (x *SuspendActorResponse) GetActor() *Actor { @@ -5502,7 +5597,7 @@ type PauseActorRequest struct { func (x *PauseActorRequest) Reset() { *x = PauseActorRequest{} - mi := &file_ateapi_proto_msgTypes[66] + mi := &file_ateapi_proto_msgTypes[67] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5514,7 +5609,7 @@ func (x *PauseActorRequest) String() string { func (*PauseActorRequest) ProtoMessage() {} func (x *PauseActorRequest) ProtoReflect() protoreflect.Message { - mi := &file_ateapi_proto_msgTypes[66] + mi := &file_ateapi_proto_msgTypes[67] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5527,7 +5622,7 @@ func (x *PauseActorRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use PauseActorRequest.ProtoReflect.Descriptor instead. func (*PauseActorRequest) Descriptor() ([]byte, []int) { - return file_ateapi_proto_rawDescGZIP(), []int{66} + return file_ateapi_proto_rawDescGZIP(), []int{67} } func (x *PauseActorRequest) GetActor() *ObjectRef { @@ -5546,7 +5641,7 @@ type PauseActorResponse struct { func (x *PauseActorResponse) Reset() { *x = PauseActorResponse{} - mi := &file_ateapi_proto_msgTypes[67] + mi := &file_ateapi_proto_msgTypes[68] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5558,7 +5653,7 @@ func (x *PauseActorResponse) String() string { func (*PauseActorResponse) ProtoMessage() {} func (x *PauseActorResponse) ProtoReflect() protoreflect.Message { - mi := &file_ateapi_proto_msgTypes[67] + mi := &file_ateapi_proto_msgTypes[68] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5571,7 +5666,7 @@ func (x *PauseActorResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use PauseActorResponse.ProtoReflect.Descriptor instead. func (*PauseActorResponse) Descriptor() ([]byte, []int) { - return file_ateapi_proto_rawDescGZIP(), []int{67} + return file_ateapi_proto_rawDescGZIP(), []int{68} } func (x *PauseActorResponse) GetActor() *Actor { @@ -5592,7 +5687,7 @@ type ResumeActorRequest struct { func (x *ResumeActorRequest) Reset() { *x = ResumeActorRequest{} - mi := &file_ateapi_proto_msgTypes[68] + mi := &file_ateapi_proto_msgTypes[69] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5604,7 +5699,7 @@ func (x *ResumeActorRequest) String() string { func (*ResumeActorRequest) ProtoMessage() {} func (x *ResumeActorRequest) ProtoReflect() protoreflect.Message { - mi := &file_ateapi_proto_msgTypes[68] + mi := &file_ateapi_proto_msgTypes[69] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5617,7 +5712,7 @@ func (x *ResumeActorRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use ResumeActorRequest.ProtoReflect.Descriptor instead. func (*ResumeActorRequest) Descriptor() ([]byte, []int) { - return file_ateapi_proto_rawDescGZIP(), []int{68} + return file_ateapi_proto_rawDescGZIP(), []int{69} } func (x *ResumeActorRequest) GetActor() *ObjectRef { @@ -5639,7 +5734,7 @@ type ResumeActorResponse struct { func (x *ResumeActorResponse) Reset() { *x = ResumeActorResponse{} - mi := &file_ateapi_proto_msgTypes[69] + mi := &file_ateapi_proto_msgTypes[70] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5651,7 +5746,7 @@ func (x *ResumeActorResponse) String() string { func (*ResumeActorResponse) ProtoMessage() {} func (x *ResumeActorResponse) ProtoReflect() protoreflect.Message { - mi := &file_ateapi_proto_msgTypes[69] + mi := &file_ateapi_proto_msgTypes[70] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5664,7 +5759,7 @@ func (x *ResumeActorResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use ResumeActorResponse.ProtoReflect.Descriptor instead. func (*ResumeActorResponse) Descriptor() ([]byte, []int) { - return file_ateapi_proto_rawDescGZIP(), []int{69} + return file_ateapi_proto_rawDescGZIP(), []int{70} } func (x *ResumeActorResponse) GetActor() *Actor { @@ -5694,7 +5789,7 @@ type RevertActorRequest struct { func (x *RevertActorRequest) Reset() { *x = RevertActorRequest{} - mi := &file_ateapi_proto_msgTypes[70] + mi := &file_ateapi_proto_msgTypes[71] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5706,7 +5801,7 @@ func (x *RevertActorRequest) String() string { func (*RevertActorRequest) ProtoMessage() {} func (x *RevertActorRequest) ProtoReflect() protoreflect.Message { - mi := &file_ateapi_proto_msgTypes[70] + mi := &file_ateapi_proto_msgTypes[71] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5719,7 +5814,7 @@ func (x *RevertActorRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use RevertActorRequest.ProtoReflect.Descriptor instead. func (*RevertActorRequest) Descriptor() ([]byte, []int) { - return file_ateapi_proto_rawDescGZIP(), []int{70} + return file_ateapi_proto_rawDescGZIP(), []int{71} } func (x *RevertActorRequest) GetActor() *ObjectRef { @@ -5741,7 +5836,7 @@ type RevertActorResponse struct { func (x *RevertActorResponse) Reset() { *x = RevertActorResponse{} - mi := &file_ateapi_proto_msgTypes[71] + mi := &file_ateapi_proto_msgTypes[72] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5753,7 +5848,7 @@ func (x *RevertActorResponse) String() string { func (*RevertActorResponse) ProtoMessage() {} func (x *RevertActorResponse) ProtoReflect() protoreflect.Message { - mi := &file_ateapi_proto_msgTypes[71] + mi := &file_ateapi_proto_msgTypes[72] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5766,7 +5861,7 @@ func (x *RevertActorResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use RevertActorResponse.ProtoReflect.Descriptor instead. func (*RevertActorResponse) Descriptor() ([]byte, []int) { - return file_ateapi_proto_rawDescGZIP(), []int{71} + return file_ateapi_proto_rawDescGZIP(), []int{72} } func (x *RevertActorResponse) GetActor() *Actor { @@ -5795,7 +5890,7 @@ type DeleteActorRequest struct { func (x *DeleteActorRequest) Reset() { *x = DeleteActorRequest{} - mi := &file_ateapi_proto_msgTypes[72] + mi := &file_ateapi_proto_msgTypes[73] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5807,7 +5902,7 @@ func (x *DeleteActorRequest) String() string { func (*DeleteActorRequest) ProtoMessage() {} func (x *DeleteActorRequest) ProtoReflect() protoreflect.Message { - mi := &file_ateapi_proto_msgTypes[72] + mi := &file_ateapi_proto_msgTypes[73] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5820,7 +5915,7 @@ func (x *DeleteActorRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use DeleteActorRequest.ProtoReflect.Descriptor instead. func (*DeleteActorRequest) Descriptor() ([]byte, []int) { - return file_ateapi_proto_rawDescGZIP(), []int{72} + return file_ateapi_proto_rawDescGZIP(), []int{73} } func (x *DeleteActorRequest) GetActor() *ObjectRef { @@ -5858,7 +5953,7 @@ type GetActorEgressPolicyRequest struct { func (x *GetActorEgressPolicyRequest) Reset() { *x = GetActorEgressPolicyRequest{} - mi := &file_ateapi_proto_msgTypes[73] + mi := &file_ateapi_proto_msgTypes[74] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5870,7 +5965,7 @@ func (x *GetActorEgressPolicyRequest) String() string { func (*GetActorEgressPolicyRequest) ProtoMessage() {} func (x *GetActorEgressPolicyRequest) ProtoReflect() protoreflect.Message { - mi := &file_ateapi_proto_msgTypes[73] + mi := &file_ateapi_proto_msgTypes[74] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5883,7 +5978,7 @@ func (x *GetActorEgressPolicyRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use GetActorEgressPolicyRequest.ProtoReflect.Descriptor instead. func (*GetActorEgressPolicyRequest) Descriptor() ([]byte, []int) { - return file_ateapi_proto_rawDescGZIP(), []int{73} + return file_ateapi_proto_rawDescGZIP(), []int{74} } func (x *GetActorEgressPolicyRequest) GetActor() *ObjectRef { @@ -5914,7 +6009,7 @@ type CreateActorEgressPolicyRequest struct { func (x *CreateActorEgressPolicyRequest) Reset() { *x = CreateActorEgressPolicyRequest{} - mi := &file_ateapi_proto_msgTypes[74] + mi := &file_ateapi_proto_msgTypes[75] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5926,7 +6021,7 @@ func (x *CreateActorEgressPolicyRequest) String() string { func (*CreateActorEgressPolicyRequest) ProtoMessage() {} func (x *CreateActorEgressPolicyRequest) ProtoReflect() protoreflect.Message { - mi := &file_ateapi_proto_msgTypes[74] + mi := &file_ateapi_proto_msgTypes[75] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5939,7 +6034,7 @@ func (x *CreateActorEgressPolicyRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use CreateActorEgressPolicyRequest.ProtoReflect.Descriptor instead. func (*CreateActorEgressPolicyRequest) Descriptor() ([]byte, []int) { - return file_ateapi_proto_rawDescGZIP(), []int{74} + return file_ateapi_proto_rawDescGZIP(), []int{75} } func (x *CreateActorEgressPolicyRequest) GetActor() *ObjectRef { @@ -5977,7 +6072,7 @@ type UpdateActorEgressPolicyRequest struct { func (x *UpdateActorEgressPolicyRequest) Reset() { *x = UpdateActorEgressPolicyRequest{} - mi := &file_ateapi_proto_msgTypes[75] + mi := &file_ateapi_proto_msgTypes[76] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5989,7 +6084,7 @@ func (x *UpdateActorEgressPolicyRequest) String() string { func (*UpdateActorEgressPolicyRequest) ProtoMessage() {} func (x *UpdateActorEgressPolicyRequest) ProtoReflect() protoreflect.Message { - mi := &file_ateapi_proto_msgTypes[75] + mi := &file_ateapi_proto_msgTypes[76] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6002,7 +6097,7 @@ func (x *UpdateActorEgressPolicyRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use UpdateActorEgressPolicyRequest.ProtoReflect.Descriptor instead. func (*UpdateActorEgressPolicyRequest) Descriptor() ([]byte, []int) { - return file_ateapi_proto_rawDescGZIP(), []int{75} + return file_ateapi_proto_rawDescGZIP(), []int{76} } func (x *UpdateActorEgressPolicyRequest) GetActor() *ObjectRef { @@ -6037,7 +6132,7 @@ type DeleteActorEgressPolicyRequest struct { func (x *DeleteActorEgressPolicyRequest) Reset() { *x = DeleteActorEgressPolicyRequest{} - mi := &file_ateapi_proto_msgTypes[76] + mi := &file_ateapi_proto_msgTypes[77] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6049,7 +6144,7 @@ func (x *DeleteActorEgressPolicyRequest) String() string { func (*DeleteActorEgressPolicyRequest) ProtoMessage() {} func (x *DeleteActorEgressPolicyRequest) ProtoReflect() protoreflect.Message { - mi := &file_ateapi_proto_msgTypes[76] + mi := &file_ateapi_proto_msgTypes[77] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6062,7 +6157,7 @@ func (x *DeleteActorEgressPolicyRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use DeleteActorEgressPolicyRequest.ProtoReflect.Descriptor instead. func (*DeleteActorEgressPolicyRequest) Descriptor() ([]byte, []int) { - return file_ateapi_proto_rawDescGZIP(), []int{76} + return file_ateapi_proto_rawDescGZIP(), []int{77} } func (x *DeleteActorEgressPolicyRequest) GetActor() *ObjectRef { @@ -6090,7 +6185,7 @@ type GetTagRequest struct { func (x *GetTagRequest) Reset() { *x = GetTagRequest{} - mi := &file_ateapi_proto_msgTypes[77] + mi := &file_ateapi_proto_msgTypes[78] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6102,7 +6197,7 @@ func (x *GetTagRequest) String() string { func (*GetTagRequest) ProtoMessage() {} func (x *GetTagRequest) ProtoReflect() protoreflect.Message { - mi := &file_ateapi_proto_msgTypes[77] + mi := &file_ateapi_proto_msgTypes[78] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6115,7 +6210,7 @@ func (x *GetTagRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use GetTagRequest.ProtoReflect.Descriptor instead. func (*GetTagRequest) Descriptor() ([]byte, []int) { - return file_ateapi_proto_rawDescGZIP(), []int{77} + return file_ateapi_proto_rawDescGZIP(), []int{78} } func (x *GetTagRequest) GetTag() *ObjectRef { @@ -6154,7 +6249,7 @@ type MintActorJWTRequest struct { func (x *MintActorJWTRequest) Reset() { *x = MintActorJWTRequest{} - mi := &file_ateapi_proto_msgTypes[78] + mi := &file_ateapi_proto_msgTypes[79] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6166,7 +6261,7 @@ func (x *MintActorJWTRequest) String() string { func (*MintActorJWTRequest) ProtoMessage() {} func (x *MintActorJWTRequest) ProtoReflect() protoreflect.Message { - mi := &file_ateapi_proto_msgTypes[78] + mi := &file_ateapi_proto_msgTypes[79] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6179,7 +6274,7 @@ func (x *MintActorJWTRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use MintActorJWTRequest.ProtoReflect.Descriptor instead. func (*MintActorJWTRequest) Descriptor() ([]byte, []int) { - return file_ateapi_proto_rawDescGZIP(), []int{78} + return file_ateapi_proto_rawDescGZIP(), []int{79} } func (x *MintActorJWTRequest) GetActor() *ObjectRef { @@ -6229,7 +6324,7 @@ type MintActorJWTResponse struct { func (x *MintActorJWTResponse) Reset() { *x = MintActorJWTResponse{} - mi := &file_ateapi_proto_msgTypes[79] + mi := &file_ateapi_proto_msgTypes[80] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6241,7 +6336,7 @@ func (x *MintActorJWTResponse) String() string { func (*MintActorJWTResponse) ProtoMessage() {} func (x *MintActorJWTResponse) ProtoReflect() protoreflect.Message { - mi := &file_ateapi_proto_msgTypes[79] + mi := &file_ateapi_proto_msgTypes[80] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6254,7 +6349,7 @@ func (x *MintActorJWTResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use MintActorJWTResponse.ProtoReflect.Descriptor instead. func (*MintActorJWTResponse) Descriptor() ([]byte, []int) { - return file_ateapi_proto_rawDescGZIP(), []int{79} + return file_ateapi_proto_rawDescGZIP(), []int{80} } func (x *MintActorJWTResponse) GetActorJwt() string { @@ -6299,7 +6394,7 @@ type MintActorCertificateRequest struct { func (x *MintActorCertificateRequest) Reset() { *x = MintActorCertificateRequest{} - mi := &file_ateapi_proto_msgTypes[80] + mi := &file_ateapi_proto_msgTypes[81] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6311,7 +6406,7 @@ func (x *MintActorCertificateRequest) String() string { func (*MintActorCertificateRequest) ProtoMessage() {} func (x *MintActorCertificateRequest) ProtoReflect() protoreflect.Message { - mi := &file_ateapi_proto_msgTypes[80] + mi := &file_ateapi_proto_msgTypes[81] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6324,7 +6419,7 @@ func (x *MintActorCertificateRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use MintActorCertificateRequest.ProtoReflect.Descriptor instead. func (*MintActorCertificateRequest) Descriptor() ([]byte, []int) { - return file_ateapi_proto_rawDescGZIP(), []int{80} + return file_ateapi_proto_rawDescGZIP(), []int{81} } func (x *MintActorCertificateRequest) GetActor() *ObjectRef { @@ -6361,7 +6456,7 @@ type MintActorCertificateResponse struct { func (x *MintActorCertificateResponse) Reset() { *x = MintActorCertificateResponse{} - mi := &file_ateapi_proto_msgTypes[81] + mi := &file_ateapi_proto_msgTypes[82] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6373,7 +6468,7 @@ func (x *MintActorCertificateResponse) String() string { func (*MintActorCertificateResponse) ProtoMessage() {} func (x *MintActorCertificateResponse) ProtoReflect() protoreflect.Message { - mi := &file_ateapi_proto_msgTypes[81] + mi := &file_ateapi_proto_msgTypes[82] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6386,7 +6481,7 @@ func (x *MintActorCertificateResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use MintActorCertificateResponse.ProtoReflect.Descriptor instead. func (*MintActorCertificateResponse) Descriptor() ([]byte, []int) { - return file_ateapi_proto_rawDescGZIP(), []int{81} + return file_ateapi_proto_rawDescGZIP(), []int{82} } func (x *MintActorCertificateResponse) GetActorCertificates() [][]byte { @@ -6422,7 +6517,7 @@ type ListTagsRequest struct { func (x *ListTagsRequest) Reset() { *x = ListTagsRequest{} - mi := &file_ateapi_proto_msgTypes[82] + mi := &file_ateapi_proto_msgTypes[83] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6434,7 +6529,7 @@ func (x *ListTagsRequest) String() string { func (*ListTagsRequest) ProtoMessage() {} func (x *ListTagsRequest) ProtoReflect() protoreflect.Message { - mi := &file_ateapi_proto_msgTypes[82] + mi := &file_ateapi_proto_msgTypes[83] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6447,7 +6542,7 @@ func (x *ListTagsRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use ListTagsRequest.ProtoReflect.Descriptor instead. func (*ListTagsRequest) Descriptor() ([]byte, []int) { - return file_ateapi_proto_rawDescGZIP(), []int{82} + return file_ateapi_proto_rawDescGZIP(), []int{83} } func (x *ListTagsRequest) GetAtespace() string { @@ -6481,7 +6576,7 @@ type ListTagsResponse struct { func (x *ListTagsResponse) Reset() { *x = ListTagsResponse{} - mi := &file_ateapi_proto_msgTypes[83] + mi := &file_ateapi_proto_msgTypes[84] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6493,7 +6588,7 @@ func (x *ListTagsResponse) String() string { func (*ListTagsResponse) ProtoMessage() {} func (x *ListTagsResponse) ProtoReflect() protoreflect.Message { - mi := &file_ateapi_proto_msgTypes[83] + mi := &file_ateapi_proto_msgTypes[84] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6506,7 +6601,7 @@ func (x *ListTagsResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use ListTagsResponse.ProtoReflect.Descriptor instead. func (*ListTagsResponse) Descriptor() ([]byte, []int) { - return file_ateapi_proto_rawDescGZIP(), []int{83} + return file_ateapi_proto_rawDescGZIP(), []int{84} } func (x *ListTagsResponse) GetTags() []*Tag { @@ -6551,7 +6646,7 @@ type CreateTagRequest struct { func (x *CreateTagRequest) Reset() { *x = CreateTagRequest{} - mi := &file_ateapi_proto_msgTypes[84] + mi := &file_ateapi_proto_msgTypes[85] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6563,7 +6658,7 @@ func (x *CreateTagRequest) String() string { func (*CreateTagRequest) ProtoMessage() {} func (x *CreateTagRequest) ProtoReflect() protoreflect.Message { - mi := &file_ateapi_proto_msgTypes[84] + mi := &file_ateapi_proto_msgTypes[85] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6576,7 +6671,7 @@ func (x *CreateTagRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use CreateTagRequest.ProtoReflect.Descriptor instead. func (*CreateTagRequest) Descriptor() ([]byte, []int) { - return file_ateapi_proto_rawDescGZIP(), []int{84} + return file_ateapi_proto_rawDescGZIP(), []int{85} } func (x *CreateTagRequest) GetTag() *Tag { @@ -6606,7 +6701,7 @@ type UpdateTagRequest struct { func (x *UpdateTagRequest) Reset() { *x = UpdateTagRequest{} - mi := &file_ateapi_proto_msgTypes[85] + mi := &file_ateapi_proto_msgTypes[86] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6618,7 +6713,7 @@ func (x *UpdateTagRequest) String() string { func (*UpdateTagRequest) ProtoMessage() {} func (x *UpdateTagRequest) ProtoReflect() protoreflect.Message { - mi := &file_ateapi_proto_msgTypes[85] + mi := &file_ateapi_proto_msgTypes[86] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6631,7 +6726,7 @@ func (x *UpdateTagRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use UpdateTagRequest.ProtoReflect.Descriptor instead. func (*UpdateTagRequest) Descriptor() ([]byte, []int) { - return file_ateapi_proto_rawDescGZIP(), []int{85} + return file_ateapi_proto_rawDescGZIP(), []int{86} } func (x *UpdateTagRequest) GetTag() *Tag { @@ -6656,7 +6751,7 @@ type DeleteTagRequest struct { func (x *DeleteTagRequest) Reset() { *x = DeleteTagRequest{} - mi := &file_ateapi_proto_msgTypes[86] + mi := &file_ateapi_proto_msgTypes[87] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6668,7 +6763,7 @@ func (x *DeleteTagRequest) String() string { func (*DeleteTagRequest) ProtoMessage() {} func (x *DeleteTagRequest) ProtoReflect() protoreflect.Message { - mi := &file_ateapi_proto_msgTypes[86] + mi := &file_ateapi_proto_msgTypes[87] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6681,7 +6776,7 @@ func (x *DeleteTagRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use DeleteTagRequest.ProtoReflect.Descriptor instead. func (*DeleteTagRequest) Descriptor() ([]byte, []int) { - return file_ateapi_proto_rawDescGZIP(), []int{86} + return file_ateapi_proto_rawDescGZIP(), []int{87} } func (x *DeleteTagRequest) GetTag() *ObjectRef { @@ -6714,7 +6809,7 @@ type CreateExternalVolumeRequest struct { func (x *CreateExternalVolumeRequest) Reset() { *x = CreateExternalVolumeRequest{} - mi := &file_ateapi_proto_msgTypes[87] + mi := &file_ateapi_proto_msgTypes[88] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6726,7 +6821,7 @@ func (x *CreateExternalVolumeRequest) String() string { func (*CreateExternalVolumeRequest) ProtoMessage() {} func (x *CreateExternalVolumeRequest) ProtoReflect() protoreflect.Message { - mi := &file_ateapi_proto_msgTypes[87] + mi := &file_ateapi_proto_msgTypes[88] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6739,7 +6834,7 @@ func (x *CreateExternalVolumeRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use CreateExternalVolumeRequest.ProtoReflect.Descriptor instead. func (*CreateExternalVolumeRequest) Descriptor() ([]byte, []int) { - return file_ateapi_proto_rawDescGZIP(), []int{87} + return file_ateapi_proto_rawDescGZIP(), []int{88} } func (x *CreateExternalVolumeRequest) GetExternalVolume() *ExternalVolume { @@ -6763,7 +6858,7 @@ type GetExternalVolumeRequest struct { func (x *GetExternalVolumeRequest) Reset() { *x = GetExternalVolumeRequest{} - mi := &file_ateapi_proto_msgTypes[88] + mi := &file_ateapi_proto_msgTypes[89] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6775,7 +6870,7 @@ func (x *GetExternalVolumeRequest) String() string { func (*GetExternalVolumeRequest) ProtoMessage() {} func (x *GetExternalVolumeRequest) ProtoReflect() protoreflect.Message { - mi := &file_ateapi_proto_msgTypes[88] + mi := &file_ateapi_proto_msgTypes[89] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6788,7 +6883,7 @@ func (x *GetExternalVolumeRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use GetExternalVolumeRequest.ProtoReflect.Descriptor instead. func (*GetExternalVolumeRequest) Descriptor() ([]byte, []int) { - return file_ateapi_proto_rawDescGZIP(), []int{88} + return file_ateapi_proto_rawDescGZIP(), []int{89} } func (x *GetExternalVolumeRequest) GetExternalVolume() *ObjectRef { @@ -6822,7 +6917,7 @@ type ListExternalVolumesRequest struct { func (x *ListExternalVolumesRequest) Reset() { *x = ListExternalVolumesRequest{} - mi := &file_ateapi_proto_msgTypes[89] + mi := &file_ateapi_proto_msgTypes[90] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6834,7 +6929,7 @@ func (x *ListExternalVolumesRequest) String() string { func (*ListExternalVolumesRequest) ProtoMessage() {} func (x *ListExternalVolumesRequest) ProtoReflect() protoreflect.Message { - mi := &file_ateapi_proto_msgTypes[89] + mi := &file_ateapi_proto_msgTypes[90] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6847,7 +6942,7 @@ func (x *ListExternalVolumesRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use ListExternalVolumesRequest.ProtoReflect.Descriptor instead. func (*ListExternalVolumesRequest) Descriptor() ([]byte, []int) { - return file_ateapi_proto_rawDescGZIP(), []int{89} + return file_ateapi_proto_rawDescGZIP(), []int{90} } func (x *ListExternalVolumesRequest) GetAtespace() string { @@ -6884,7 +6979,7 @@ type ListExternalVolumesResponse struct { func (x *ListExternalVolumesResponse) Reset() { *x = ListExternalVolumesResponse{} - mi := &file_ateapi_proto_msgTypes[90] + mi := &file_ateapi_proto_msgTypes[91] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6896,7 +6991,7 @@ func (x *ListExternalVolumesResponse) String() string { func (*ListExternalVolumesResponse) ProtoMessage() {} func (x *ListExternalVolumesResponse) ProtoReflect() protoreflect.Message { - mi := &file_ateapi_proto_msgTypes[90] + mi := &file_ateapi_proto_msgTypes[91] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6909,7 +7004,7 @@ func (x *ListExternalVolumesResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use ListExternalVolumesResponse.ProtoReflect.Descriptor instead. func (*ListExternalVolumesResponse) Descriptor() ([]byte, []int) { - return file_ateapi_proto_rawDescGZIP(), []int{90} + return file_ateapi_proto_rawDescGZIP(), []int{91} } func (x *ListExternalVolumesResponse) GetExternalVolumes() []*ExternalVolume { @@ -6943,7 +7038,7 @@ type UpdateExternalVolumeRequest struct { func (x *UpdateExternalVolumeRequest) Reset() { *x = UpdateExternalVolumeRequest{} - mi := &file_ateapi_proto_msgTypes[91] + mi := &file_ateapi_proto_msgTypes[92] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6955,7 +7050,7 @@ func (x *UpdateExternalVolumeRequest) String() string { func (*UpdateExternalVolumeRequest) ProtoMessage() {} func (x *UpdateExternalVolumeRequest) ProtoReflect() protoreflect.Message { - mi := &file_ateapi_proto_msgTypes[91] + mi := &file_ateapi_proto_msgTypes[92] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6968,7 +7063,7 @@ func (x *UpdateExternalVolumeRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use UpdateExternalVolumeRequest.ProtoReflect.Descriptor instead. func (*UpdateExternalVolumeRequest) Descriptor() ([]byte, []int) { - return file_ateapi_proto_rawDescGZIP(), []int{91} + return file_ateapi_proto_rawDescGZIP(), []int{92} } func (x *UpdateExternalVolumeRequest) GetExternalVolume() *ExternalVolume { @@ -6996,7 +7091,7 @@ type DeleteExternalVolumeRequest struct { func (x *DeleteExternalVolumeRequest) Reset() { *x = DeleteExternalVolumeRequest{} - mi := &file_ateapi_proto_msgTypes[92] + mi := &file_ateapi_proto_msgTypes[93] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7008,7 +7103,7 @@ func (x *DeleteExternalVolumeRequest) String() string { func (*DeleteExternalVolumeRequest) ProtoMessage() {} func (x *DeleteExternalVolumeRequest) ProtoReflect() protoreflect.Message { - mi := &file_ateapi_proto_msgTypes[92] + mi := &file_ateapi_proto_msgTypes[93] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7021,7 +7116,7 @@ func (x *DeleteExternalVolumeRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use DeleteExternalVolumeRequest.ProtoReflect.Descriptor instead. func (*DeleteExternalVolumeRequest) Descriptor() ([]byte, []int) { - return file_ateapi_proto_rawDescGZIP(), []int{92} + return file_ateapi_proto_rawDescGZIP(), []int{93} } func (x *DeleteExternalVolumeRequest) GetExternalVolume() *ObjectRef { @@ -7060,7 +7155,7 @@ type DeleteOptions struct { func (x *DeleteOptions) Reset() { *x = DeleteOptions{} - mi := &file_ateapi_proto_msgTypes[93] + mi := &file_ateapi_proto_msgTypes[94] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7072,7 +7167,7 @@ func (x *DeleteOptions) String() string { func (*DeleteOptions) ProtoMessage() {} func (x *DeleteOptions) ProtoReflect() protoreflect.Message { - mi := &file_ateapi_proto_msgTypes[93] + mi := &file_ateapi_proto_msgTypes[94] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7085,7 +7180,7 @@ func (x *DeleteOptions) ProtoReflect() protoreflect.Message { // Deprecated: Use DeleteOptions.ProtoReflect.Descriptor instead. func (*DeleteOptions) Descriptor() ([]byte, []int) { - return file_ateapi_proto_rawDescGZIP(), []int{93} + return file_ateapi_proto_rawDescGZIP(), []int{94} } func (x *DeleteOptions) GetVersion() int64 { @@ -7129,7 +7224,7 @@ type ListWorkerActorAssignmentsRequest struct { func (x *ListWorkerActorAssignmentsRequest) Reset() { *x = ListWorkerActorAssignmentsRequest{} - mi := &file_ateapi_proto_msgTypes[94] + mi := &file_ateapi_proto_msgTypes[95] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7141,7 +7236,7 @@ func (x *ListWorkerActorAssignmentsRequest) String() string { func (*ListWorkerActorAssignmentsRequest) ProtoMessage() {} func (x *ListWorkerActorAssignmentsRequest) ProtoReflect() protoreflect.Message { - mi := &file_ateapi_proto_msgTypes[94] + mi := &file_ateapi_proto_msgTypes[95] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7154,7 +7249,7 @@ func (x *ListWorkerActorAssignmentsRequest) ProtoReflect() protoreflect.Message // Deprecated: Use ListWorkerActorAssignmentsRequest.ProtoReflect.Descriptor instead. func (*ListWorkerActorAssignmentsRequest) Descriptor() ([]byte, []int) { - return file_ateapi_proto_rawDescGZIP(), []int{94} + return file_ateapi_proto_rawDescGZIP(), []int{95} } func (x *ListWorkerActorAssignmentsRequest) GetWorker() *ObjectRef { @@ -7191,7 +7286,7 @@ type ListWorkerActorAssignmentsResponse struct { func (x *ListWorkerActorAssignmentsResponse) Reset() { *x = ListWorkerActorAssignmentsResponse{} - mi := &file_ateapi_proto_msgTypes[95] + mi := &file_ateapi_proto_msgTypes[96] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7203,7 +7298,7 @@ func (x *ListWorkerActorAssignmentsResponse) String() string { func (*ListWorkerActorAssignmentsResponse) ProtoMessage() {} func (x *ListWorkerActorAssignmentsResponse) ProtoReflect() protoreflect.Message { - mi := &file_ateapi_proto_msgTypes[95] + mi := &file_ateapi_proto_msgTypes[96] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7216,7 +7311,7 @@ func (x *ListWorkerActorAssignmentsResponse) ProtoReflect() protoreflect.Message // Deprecated: Use ListWorkerActorAssignmentsResponse.ProtoReflect.Descriptor instead. func (*ListWorkerActorAssignmentsResponse) Descriptor() ([]byte, []int) { - return file_ateapi_proto_rawDescGZIP(), []int{95} + return file_ateapi_proto_rawDescGZIP(), []int{96} } func (x *ListWorkerActorAssignmentsResponse) GetActorAssignments() []*ActorAssignment { @@ -7254,7 +7349,7 @@ type ListWorkersRequest struct { func (x *ListWorkersRequest) Reset() { *x = ListWorkersRequest{} - mi := &file_ateapi_proto_msgTypes[96] + mi := &file_ateapi_proto_msgTypes[97] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7266,7 +7361,7 @@ func (x *ListWorkersRequest) String() string { func (*ListWorkersRequest) ProtoMessage() {} func (x *ListWorkersRequest) ProtoReflect() protoreflect.Message { - mi := &file_ateapi_proto_msgTypes[96] + mi := &file_ateapi_proto_msgTypes[97] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7279,7 +7374,7 @@ func (x *ListWorkersRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use ListWorkersRequest.ProtoReflect.Descriptor instead. func (*ListWorkersRequest) Descriptor() ([]byte, []int) { - return file_ateapi_proto_rawDescGZIP(), []int{96} + return file_ateapi_proto_rawDescGZIP(), []int{97} } func (x *ListWorkersRequest) GetPageSize() int32 { @@ -7308,7 +7403,7 @@ type ListWorkersResponse struct { func (x *ListWorkersResponse) Reset() { *x = ListWorkersResponse{} - mi := &file_ateapi_proto_msgTypes[97] + mi := &file_ateapi_proto_msgTypes[98] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7320,7 +7415,7 @@ func (x *ListWorkersResponse) String() string { func (*ListWorkersResponse) ProtoMessage() {} func (x *ListWorkersResponse) ProtoReflect() protoreflect.Message { - mi := &file_ateapi_proto_msgTypes[97] + mi := &file_ateapi_proto_msgTypes[98] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7333,7 +7428,7 @@ func (x *ListWorkersResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use ListWorkersResponse.ProtoReflect.Descriptor instead. func (*ListWorkersResponse) Descriptor() ([]byte, []int) { - return file_ateapi_proto_rawDescGZIP(), []int{97} + return file_ateapi_proto_rawDescGZIP(), []int{98} } func (x *ListWorkersResponse) GetWorkers() []*Worker { @@ -7363,7 +7458,7 @@ type GetWorkerRequest struct { func (x *GetWorkerRequest) Reset() { *x = GetWorkerRequest{} - mi := &file_ateapi_proto_msgTypes[98] + mi := &file_ateapi_proto_msgTypes[99] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7375,7 +7470,7 @@ func (x *GetWorkerRequest) String() string { func (*GetWorkerRequest) ProtoMessage() {} func (x *GetWorkerRequest) ProtoReflect() protoreflect.Message { - mi := &file_ateapi_proto_msgTypes[98] + mi := &file_ateapi_proto_msgTypes[99] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7388,7 +7483,7 @@ func (x *GetWorkerRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use GetWorkerRequest.ProtoReflect.Descriptor instead. func (*GetWorkerRequest) Descriptor() ([]byte, []int) { - return file_ateapi_proto_rawDescGZIP(), []int{98} + return file_ateapi_proto_rawDescGZIP(), []int{99} } func (x *GetWorkerRequest) GetWorker() *ObjectRef { @@ -7410,7 +7505,7 @@ type CreateWorkerRequest struct { func (x *CreateWorkerRequest) Reset() { *x = CreateWorkerRequest{} - mi := &file_ateapi_proto_msgTypes[99] + mi := &file_ateapi_proto_msgTypes[100] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7422,7 +7517,7 @@ func (x *CreateWorkerRequest) String() string { func (*CreateWorkerRequest) ProtoMessage() {} func (x *CreateWorkerRequest) ProtoReflect() protoreflect.Message { - mi := &file_ateapi_proto_msgTypes[99] + mi := &file_ateapi_proto_msgTypes[100] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7435,7 +7530,7 @@ func (x *CreateWorkerRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use CreateWorkerRequest.ProtoReflect.Descriptor instead. func (*CreateWorkerRequest) Descriptor() ([]byte, []int) { - return file_ateapi_proto_rawDescGZIP(), []int{99} + return file_ateapi_proto_rawDescGZIP(), []int{100} } func (x *CreateWorkerRequest) GetWorker() *Worker { @@ -7470,7 +7565,7 @@ type UpdateWorkerRequest struct { func (x *UpdateWorkerRequest) Reset() { *x = UpdateWorkerRequest{} - mi := &file_ateapi_proto_msgTypes[100] + mi := &file_ateapi_proto_msgTypes[101] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7482,7 +7577,7 @@ func (x *UpdateWorkerRequest) String() string { func (*UpdateWorkerRequest) ProtoMessage() {} func (x *UpdateWorkerRequest) ProtoReflect() protoreflect.Message { - mi := &file_ateapi_proto_msgTypes[100] + mi := &file_ateapi_proto_msgTypes[101] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7495,7 +7590,7 @@ func (x *UpdateWorkerRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use UpdateWorkerRequest.ProtoReflect.Descriptor instead. func (*UpdateWorkerRequest) Descriptor() ([]byte, []int) { - return file_ateapi_proto_rawDescGZIP(), []int{100} + return file_ateapi_proto_rawDescGZIP(), []int{101} } func (x *UpdateWorkerRequest) GetWorker() *Worker { @@ -7522,7 +7617,7 @@ type DeleteWorkerRequest struct { func (x *DeleteWorkerRequest) Reset() { *x = DeleteWorkerRequest{} - mi := &file_ateapi_proto_msgTypes[101] + mi := &file_ateapi_proto_msgTypes[102] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7534,7 +7629,7 @@ func (x *DeleteWorkerRequest) String() string { func (*DeleteWorkerRequest) ProtoMessage() {} func (x *DeleteWorkerRequest) ProtoReflect() protoreflect.Message { - mi := &file_ateapi_proto_msgTypes[101] + mi := &file_ateapi_proto_msgTypes[102] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7547,7 +7642,7 @@ func (x *DeleteWorkerRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use DeleteWorkerRequest.ProtoReflect.Descriptor instead. func (*DeleteWorkerRequest) Descriptor() ([]byte, []int) { - return file_ateapi_proto_rawDescGZIP(), []int{101} + return file_ateapi_proto_rawDescGZIP(), []int{102} } func (x *DeleteWorkerRequest) GetWorker() *ObjectRef { @@ -7577,7 +7672,7 @@ type DrainWorkerRequest struct { func (x *DrainWorkerRequest) Reset() { *x = DrainWorkerRequest{} - mi := &file_ateapi_proto_msgTypes[102] + mi := &file_ateapi_proto_msgTypes[103] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7589,7 +7684,7 @@ func (x *DrainWorkerRequest) String() string { func (*DrainWorkerRequest) ProtoMessage() {} func (x *DrainWorkerRequest) ProtoReflect() protoreflect.Message { - mi := &file_ateapi_proto_msgTypes[102] + mi := &file_ateapi_proto_msgTypes[103] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7602,7 +7697,7 @@ func (x *DrainWorkerRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use DrainWorkerRequest.ProtoReflect.Descriptor instead. func (*DrainWorkerRequest) Descriptor() ([]byte, []int) { - return file_ateapi_proto_rawDescGZIP(), []int{102} + return file_ateapi_proto_rawDescGZIP(), []int{103} } func (x *DrainWorkerRequest) GetWorker() *ObjectRef { @@ -7640,7 +7735,7 @@ type ListActorsRequest struct { func (x *ListActorsRequest) Reset() { *x = ListActorsRequest{} - mi := &file_ateapi_proto_msgTypes[103] + mi := &file_ateapi_proto_msgTypes[104] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7652,7 +7747,7 @@ func (x *ListActorsRequest) String() string { func (*ListActorsRequest) ProtoMessage() {} func (x *ListActorsRequest) ProtoReflect() protoreflect.Message { - mi := &file_ateapi_proto_msgTypes[103] + mi := &file_ateapi_proto_msgTypes[104] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7665,7 +7760,7 @@ func (x *ListActorsRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use ListActorsRequest.ProtoReflect.Descriptor instead. func (*ListActorsRequest) Descriptor() ([]byte, []int) { - return file_ateapi_proto_rawDescGZIP(), []int{103} + return file_ateapi_proto_rawDescGZIP(), []int{104} } func (x *ListActorsRequest) GetAtespace() string { @@ -7701,7 +7796,7 @@ type ListActorsResponse struct { func (x *ListActorsResponse) Reset() { *x = ListActorsResponse{} - mi := &file_ateapi_proto_msgTypes[104] + mi := &file_ateapi_proto_msgTypes[105] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7713,7 +7808,7 @@ func (x *ListActorsResponse) String() string { func (*ListActorsResponse) ProtoMessage() {} func (x *ListActorsResponse) ProtoReflect() protoreflect.Message { - mi := &file_ateapi_proto_msgTypes[104] + mi := &file_ateapi_proto_msgTypes[105] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7726,7 +7821,7 @@ func (x *ListActorsResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use ListActorsResponse.ProtoReflect.Descriptor instead. func (*ListActorsResponse) Descriptor() ([]byte, []int) { - return file_ateapi_proto_rawDescGZIP(), []int{104} + return file_ateapi_proto_rawDescGZIP(), []int{105} } func (x *ListActorsResponse) GetActors() []*Actor { @@ -7833,7 +7928,7 @@ type Worker struct { func (x *Worker) Reset() { *x = Worker{} - mi := &file_ateapi_proto_msgTypes[105] + mi := &file_ateapi_proto_msgTypes[106] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7845,7 +7940,7 @@ func (x *Worker) String() string { func (*Worker) ProtoMessage() {} func (x *Worker) ProtoReflect() protoreflect.Message { - mi := &file_ateapi_proto_msgTypes[105] + mi := &file_ateapi_proto_msgTypes[106] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7858,7 +7953,7 @@ func (x *Worker) ProtoReflect() protoreflect.Message { // Deprecated: Use Worker.ProtoReflect.Descriptor instead. func (*Worker) Descriptor() ([]byte, []int) { - return file_ateapi_proto_rawDescGZIP(), []int{105} + return file_ateapi_proto_rawDescGZIP(), []int{106} } func (x *Worker) GetMetadata() *ResourceMetadata { @@ -7978,7 +8073,7 @@ type WorkerStatus struct { func (x *WorkerStatus) Reset() { *x = WorkerStatus{} - mi := &file_ateapi_proto_msgTypes[106] + mi := &file_ateapi_proto_msgTypes[107] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7990,7 +8085,7 @@ func (x *WorkerStatus) String() string { func (*WorkerStatus) ProtoMessage() {} func (x *WorkerStatus) ProtoReflect() protoreflect.Message { - mi := &file_ateapi_proto_msgTypes[106] + mi := &file_ateapi_proto_msgTypes[107] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -8003,7 +8098,7 @@ func (x *WorkerStatus) ProtoReflect() protoreflect.Message { // Deprecated: Use WorkerStatus.ProtoReflect.Descriptor instead. func (*WorkerStatus) Descriptor() ([]byte, []int) { - return file_ateapi_proto_rawDescGZIP(), []int{106} + return file_ateapi_proto_rawDescGZIP(), []int{107} } func (x *WorkerStatus) GetState() WorkerState { @@ -8059,7 +8154,7 @@ type HardwareIdentity struct { func (x *HardwareIdentity) Reset() { *x = HardwareIdentity{} - mi := &file_ateapi_proto_msgTypes[107] + mi := &file_ateapi_proto_msgTypes[108] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -8071,7 +8166,7 @@ func (x *HardwareIdentity) String() string { func (*HardwareIdentity) ProtoMessage() {} func (x *HardwareIdentity) ProtoReflect() protoreflect.Message { - mi := &file_ateapi_proto_msgTypes[107] + mi := &file_ateapi_proto_msgTypes[108] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -8084,7 +8179,7 @@ func (x *HardwareIdentity) ProtoReflect() protoreflect.Message { // Deprecated: Use HardwareIdentity.ProtoReflect.Descriptor instead. func (*HardwareIdentity) Descriptor() ([]byte, []int) { - return file_ateapi_proto_rawDescGZIP(), []int{107} + return file_ateapi_proto_rawDescGZIP(), []int{108} } func (x *HardwareIdentity) GetAttributes() map[string]string { @@ -8116,7 +8211,7 @@ type WorkerResources struct { func (x *WorkerResources) Reset() { *x = WorkerResources{} - mi := &file_ateapi_proto_msgTypes[108] + mi := &file_ateapi_proto_msgTypes[109] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -8128,7 +8223,7 @@ func (x *WorkerResources) String() string { func (*WorkerResources) ProtoMessage() {} func (x *WorkerResources) ProtoReflect() protoreflect.Message { - mi := &file_ateapi_proto_msgTypes[108] + mi := &file_ateapi_proto_msgTypes[109] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -8141,7 +8236,7 @@ func (x *WorkerResources) ProtoReflect() protoreflect.Message { // Deprecated: Use WorkerResources.ProtoReflect.Descriptor instead. func (*WorkerResources) Descriptor() ([]byte, []int) { - return file_ateapi_proto_rawDescGZIP(), []int{108} + return file_ateapi_proto_rawDescGZIP(), []int{109} } func (x *WorkerResources) GetResources() *Resources { @@ -8194,7 +8289,7 @@ type ActorAssignment struct { func (x *ActorAssignment) Reset() { *x = ActorAssignment{} - mi := &file_ateapi_proto_msgTypes[109] + mi := &file_ateapi_proto_msgTypes[110] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -8206,7 +8301,7 @@ func (x *ActorAssignment) String() string { func (*ActorAssignment) ProtoMessage() {} func (x *ActorAssignment) ProtoReflect() protoreflect.Message { - mi := &file_ateapi_proto_msgTypes[109] + mi := &file_ateapi_proto_msgTypes[110] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -8219,7 +8314,7 @@ func (x *ActorAssignment) ProtoReflect() protoreflect.Message { // Deprecated: Use ActorAssignment.ProtoReflect.Descriptor instead. func (*ActorAssignment) Descriptor() ([]byte, []int) { - return file_ateapi_proto_rawDescGZIP(), []int{109} + return file_ateapi_proto_rawDescGZIP(), []int{110} } func (x *ActorAssignment) GetMetadata() *ResourceMetadata { @@ -8282,7 +8377,7 @@ type RegisterWorkerRequest struct { func (x *RegisterWorkerRequest) Reset() { *x = RegisterWorkerRequest{} - mi := &file_ateapi_proto_msgTypes[110] + mi := &file_ateapi_proto_msgTypes[111] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -8294,7 +8389,7 @@ func (x *RegisterWorkerRequest) String() string { func (*RegisterWorkerRequest) ProtoMessage() {} func (x *RegisterWorkerRequest) ProtoReflect() protoreflect.Message { - mi := &file_ateapi_proto_msgTypes[110] + mi := &file_ateapi_proto_msgTypes[111] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -8307,7 +8402,7 @@ func (x *RegisterWorkerRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use RegisterWorkerRequest.ProtoReflect.Descriptor instead. func (*RegisterWorkerRequest) Descriptor() ([]byte, []int) { - return file_ateapi_proto_rawDescGZIP(), []int{110} + return file_ateapi_proto_rawDescGZIP(), []int{111} } func (x *RegisterWorkerRequest) GetWorker() *ObjectRef { @@ -8341,7 +8436,7 @@ type RegisterWorkerResponse struct { func (x *RegisterWorkerResponse) Reset() { *x = RegisterWorkerResponse{} - mi := &file_ateapi_proto_msgTypes[111] + mi := &file_ateapi_proto_msgTypes[112] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -8353,7 +8448,7 @@ func (x *RegisterWorkerResponse) String() string { func (*RegisterWorkerResponse) ProtoMessage() {} func (x *RegisterWorkerResponse) ProtoReflect() protoreflect.Message { - mi := &file_ateapi_proto_msgTypes[111] + mi := &file_ateapi_proto_msgTypes[112] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -8366,7 +8461,7 @@ func (x *RegisterWorkerResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use RegisterWorkerResponse.ProtoReflect.Descriptor instead. func (*RegisterWorkerResponse) Descriptor() ([]byte, []int) { - return file_ateapi_proto_rawDescGZIP(), []int{111} + return file_ateapi_proto_rawDescGZIP(), []int{112} } func (x *RegisterWorkerResponse) GetWorker() *Worker { @@ -8405,7 +8500,7 @@ type MintAteomActorCertificateRequest struct { func (x *MintAteomActorCertificateRequest) Reset() { *x = MintAteomActorCertificateRequest{} - mi := &file_ateapi_proto_msgTypes[112] + mi := &file_ateapi_proto_msgTypes[113] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -8417,7 +8512,7 @@ func (x *MintAteomActorCertificateRequest) String() string { func (*MintAteomActorCertificateRequest) ProtoMessage() {} func (x *MintAteomActorCertificateRequest) ProtoReflect() protoreflect.Message { - mi := &file_ateapi_proto_msgTypes[112] + mi := &file_ateapi_proto_msgTypes[113] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -8430,7 +8525,7 @@ func (x *MintAteomActorCertificateRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use MintAteomActorCertificateRequest.ProtoReflect.Descriptor instead. func (*MintAteomActorCertificateRequest) Descriptor() ([]byte, []int) { - return file_ateapi_proto_rawDescGZIP(), []int{112} + return file_ateapi_proto_rawDescGZIP(), []int{113} } func (x *MintAteomActorCertificateRequest) GetActor() *ObjectRef { @@ -8467,7 +8562,7 @@ type MintAteomActorCertificateResponse struct { func (x *MintAteomActorCertificateResponse) Reset() { *x = MintAteomActorCertificateResponse{} - mi := &file_ateapi_proto_msgTypes[113] + mi := &file_ateapi_proto_msgTypes[114] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -8479,7 +8574,7 @@ func (x *MintAteomActorCertificateResponse) String() string { func (*MintAteomActorCertificateResponse) ProtoMessage() {} func (x *MintAteomActorCertificateResponse) ProtoReflect() protoreflect.Message { - mi := &file_ateapi_proto_msgTypes[113] + mi := &file_ateapi_proto_msgTypes[114] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -8492,7 +8587,7 @@ func (x *MintAteomActorCertificateResponse) ProtoReflect() protoreflect.Message // Deprecated: Use MintAteomActorCertificateResponse.ProtoReflect.Descriptor instead. func (*MintAteomActorCertificateResponse) Descriptor() ([]byte, []int) { - return file_ateapi_proto_rawDescGZIP(), []int{113} + return file_ateapi_proto_rawDescGZIP(), []int{114} } func (x *MintAteomActorCertificateResponse) GetActorCertificates() [][]byte { @@ -8530,7 +8625,7 @@ type RequestActorSuspendRequest struct { func (x *RequestActorSuspendRequest) Reset() { *x = RequestActorSuspendRequest{} - mi := &file_ateapi_proto_msgTypes[114] + mi := &file_ateapi_proto_msgTypes[115] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -8542,7 +8637,7 @@ func (x *RequestActorSuspendRequest) String() string { func (*RequestActorSuspendRequest) ProtoMessage() {} func (x *RequestActorSuspendRequest) ProtoReflect() protoreflect.Message { - mi := &file_ateapi_proto_msgTypes[114] + mi := &file_ateapi_proto_msgTypes[115] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -8555,7 +8650,7 @@ func (x *RequestActorSuspendRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use RequestActorSuspendRequest.ProtoReflect.Descriptor instead. func (*RequestActorSuspendRequest) Descriptor() ([]byte, []int) { - return file_ateapi_proto_rawDescGZIP(), []int{114} + return file_ateapi_proto_rawDescGZIP(), []int{115} } func (x *RequestActorSuspendRequest) GetWorker() *ObjectRef { @@ -8589,7 +8684,7 @@ type RequestActorSuspendResponse struct { func (x *RequestActorSuspendResponse) Reset() { *x = RequestActorSuspendResponse{} - mi := &file_ateapi_proto_msgTypes[115] + mi := &file_ateapi_proto_msgTypes[116] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -8601,7 +8696,7 @@ func (x *RequestActorSuspendResponse) String() string { func (*RequestActorSuspendResponse) ProtoMessage() {} func (x *RequestActorSuspendResponse) ProtoReflect() protoreflect.Message { - mi := &file_ateapi_proto_msgTypes[115] + mi := &file_ateapi_proto_msgTypes[116] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -8614,7 +8709,7 @@ func (x *RequestActorSuspendResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use RequestActorSuspendResponse.ProtoReflect.Descriptor instead. func (*RequestActorSuspendResponse) Descriptor() ([]byte, []int) { - return file_ateapi_proto_rawDescGZIP(), []int{115} + return file_ateapi_proto_rawDescGZIP(), []int{116} } func (x *RequestActorSuspendResponse) GetActor() *Actor { @@ -8649,7 +8744,7 @@ type AccessPolicy struct { func (x *AccessPolicy) Reset() { *x = AccessPolicy{} - mi := &file_ateapi_proto_msgTypes[116] + mi := &file_ateapi_proto_msgTypes[117] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -8661,7 +8756,7 @@ func (x *AccessPolicy) String() string { func (*AccessPolicy) ProtoMessage() {} func (x *AccessPolicy) ProtoReflect() protoreflect.Message { - mi := &file_ateapi_proto_msgTypes[116] + mi := &file_ateapi_proto_msgTypes[117] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -8674,7 +8769,7 @@ func (x *AccessPolicy) ProtoReflect() protoreflect.Message { // Deprecated: Use AccessPolicy.ProtoReflect.Descriptor instead. func (*AccessPolicy) Descriptor() ([]byte, []int) { - return file_ateapi_proto_rawDescGZIP(), []int{116} + return file_ateapi_proto_rawDescGZIP(), []int{117} } func (x *AccessPolicy) GetMetadata() *ResourceMetadata { @@ -8716,7 +8811,7 @@ type Binding struct { func (x *Binding) Reset() { *x = Binding{} - mi := &file_ateapi_proto_msgTypes[117] + mi := &file_ateapi_proto_msgTypes[118] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -8728,7 +8823,7 @@ func (x *Binding) String() string { func (*Binding) ProtoMessage() {} func (x *Binding) ProtoReflect() protoreflect.Message { - mi := &file_ateapi_proto_msgTypes[117] + mi := &file_ateapi_proto_msgTypes[118] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -8741,7 +8836,7 @@ func (x *Binding) ProtoReflect() protoreflect.Message { // Deprecated: Use Binding.ProtoReflect.Descriptor instead. func (*Binding) Descriptor() ([]byte, []int) { - return file_ateapi_proto_rawDescGZIP(), []int{117} + return file_ateapi_proto_rawDescGZIP(), []int{118} } func (x *Binding) GetRole() string { @@ -8767,7 +8862,7 @@ type GetGlobalAccessPolicyRequest struct { func (x *GetGlobalAccessPolicyRequest) Reset() { *x = GetGlobalAccessPolicyRequest{} - mi := &file_ateapi_proto_msgTypes[118] + mi := &file_ateapi_proto_msgTypes[119] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -8779,7 +8874,7 @@ func (x *GetGlobalAccessPolicyRequest) String() string { func (*GetGlobalAccessPolicyRequest) ProtoMessage() {} func (x *GetGlobalAccessPolicyRequest) ProtoReflect() protoreflect.Message { - mi := &file_ateapi_proto_msgTypes[118] + mi := &file_ateapi_proto_msgTypes[119] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -8792,7 +8887,7 @@ func (x *GetGlobalAccessPolicyRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use GetGlobalAccessPolicyRequest.ProtoReflect.Descriptor instead. func (*GetGlobalAccessPolicyRequest) Descriptor() ([]byte, []int) { - return file_ateapi_proto_rawDescGZIP(), []int{118} + return file_ateapi_proto_rawDescGZIP(), []int{119} } // CreateGlobalAccessPolicyRequest creates the deployment-wide global access policy singleton. @@ -8809,7 +8904,7 @@ type CreateGlobalAccessPolicyRequest struct { func (x *CreateGlobalAccessPolicyRequest) Reset() { *x = CreateGlobalAccessPolicyRequest{} - mi := &file_ateapi_proto_msgTypes[119] + mi := &file_ateapi_proto_msgTypes[120] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -8821,7 +8916,7 @@ func (x *CreateGlobalAccessPolicyRequest) String() string { func (*CreateGlobalAccessPolicyRequest) ProtoMessage() {} func (x *CreateGlobalAccessPolicyRequest) ProtoReflect() protoreflect.Message { - mi := &file_ateapi_proto_msgTypes[119] + mi := &file_ateapi_proto_msgTypes[120] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -8834,7 +8929,7 @@ func (x *CreateGlobalAccessPolicyRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use CreateGlobalAccessPolicyRequest.ProtoReflect.Descriptor instead. func (*CreateGlobalAccessPolicyRequest) Descriptor() ([]byte, []int) { - return file_ateapi_proto_rawDescGZIP(), []int{119} + return file_ateapi_proto_rawDescGZIP(), []int{120} } func (x *CreateGlobalAccessPolicyRequest) GetAccessPolicy() *AccessPolicy { @@ -8858,7 +8953,7 @@ type UpdateGlobalAccessPolicyRequest struct { func (x *UpdateGlobalAccessPolicyRequest) Reset() { *x = UpdateGlobalAccessPolicyRequest{} - mi := &file_ateapi_proto_msgTypes[120] + mi := &file_ateapi_proto_msgTypes[121] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -8870,7 +8965,7 @@ func (x *UpdateGlobalAccessPolicyRequest) String() string { func (*UpdateGlobalAccessPolicyRequest) ProtoMessage() {} func (x *UpdateGlobalAccessPolicyRequest) ProtoReflect() protoreflect.Message { - mi := &file_ateapi_proto_msgTypes[120] + mi := &file_ateapi_proto_msgTypes[121] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -8883,7 +8978,7 @@ func (x *UpdateGlobalAccessPolicyRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use UpdateGlobalAccessPolicyRequest.ProtoReflect.Descriptor instead. func (*UpdateGlobalAccessPolicyRequest) Descriptor() ([]byte, []int) { - return file_ateapi_proto_rawDescGZIP(), []int{120} + return file_ateapi_proto_rawDescGZIP(), []int{121} } func (x *UpdateGlobalAccessPolicyRequest) GetAccessPolicy() *AccessPolicy { @@ -8907,7 +9002,7 @@ type GetAtespaceAccessPolicyRequest struct { func (x *GetAtespaceAccessPolicyRequest) Reset() { *x = GetAtespaceAccessPolicyRequest{} - mi := &file_ateapi_proto_msgTypes[121] + mi := &file_ateapi_proto_msgTypes[122] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -8919,7 +9014,7 @@ func (x *GetAtespaceAccessPolicyRequest) String() string { func (*GetAtespaceAccessPolicyRequest) ProtoMessage() {} func (x *GetAtespaceAccessPolicyRequest) ProtoReflect() protoreflect.Message { - mi := &file_ateapi_proto_msgTypes[121] + mi := &file_ateapi_proto_msgTypes[122] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -8932,7 +9027,7 @@ func (x *GetAtespaceAccessPolicyRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use GetAtespaceAccessPolicyRequest.ProtoReflect.Descriptor instead. func (*GetAtespaceAccessPolicyRequest) Descriptor() ([]byte, []int) { - return file_ateapi_proto_rawDescGZIP(), []int{121} + return file_ateapi_proto_rawDescGZIP(), []int{122} } func (x *GetAtespaceAccessPolicyRequest) GetAtespace() *ObjectRef { @@ -8961,7 +9056,7 @@ type CreateAtespaceAccessPolicyRequest struct { func (x *CreateAtespaceAccessPolicyRequest) Reset() { *x = CreateAtespaceAccessPolicyRequest{} - mi := &file_ateapi_proto_msgTypes[122] + mi := &file_ateapi_proto_msgTypes[123] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -8973,7 +9068,7 @@ func (x *CreateAtespaceAccessPolicyRequest) String() string { func (*CreateAtespaceAccessPolicyRequest) ProtoMessage() {} func (x *CreateAtespaceAccessPolicyRequest) ProtoReflect() protoreflect.Message { - mi := &file_ateapi_proto_msgTypes[122] + mi := &file_ateapi_proto_msgTypes[123] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -8986,7 +9081,7 @@ func (x *CreateAtespaceAccessPolicyRequest) ProtoReflect() protoreflect.Message // Deprecated: Use CreateAtespaceAccessPolicyRequest.ProtoReflect.Descriptor instead. func (*CreateAtespaceAccessPolicyRequest) Descriptor() ([]byte, []int) { - return file_ateapi_proto_rawDescGZIP(), []int{122} + return file_ateapi_proto_rawDescGZIP(), []int{123} } func (x *CreateAtespaceAccessPolicyRequest) GetAtespace() *ObjectRef { @@ -9022,7 +9117,7 @@ type UpdateAtespaceAccessPolicyRequest struct { func (x *UpdateAtespaceAccessPolicyRequest) Reset() { *x = UpdateAtespaceAccessPolicyRequest{} - mi := &file_ateapi_proto_msgTypes[123] + mi := &file_ateapi_proto_msgTypes[124] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -9034,7 +9129,7 @@ func (x *UpdateAtespaceAccessPolicyRequest) String() string { func (*UpdateAtespaceAccessPolicyRequest) ProtoMessage() {} func (x *UpdateAtespaceAccessPolicyRequest) ProtoReflect() protoreflect.Message { - mi := &file_ateapi_proto_msgTypes[123] + mi := &file_ateapi_proto_msgTypes[124] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -9047,7 +9142,7 @@ func (x *UpdateAtespaceAccessPolicyRequest) ProtoReflect() protoreflect.Message // Deprecated: Use UpdateAtespaceAccessPolicyRequest.ProtoReflect.Descriptor instead. func (*UpdateAtespaceAccessPolicyRequest) Descriptor() ([]byte, []int) { - return file_ateapi_proto_rawDescGZIP(), []int{123} + return file_ateapi_proto_rawDescGZIP(), []int{124} } func (x *UpdateAtespaceAccessPolicyRequest) GetAtespace() *ObjectRef { @@ -9082,7 +9177,7 @@ type DeleteAtespaceAccessPolicyRequest struct { func (x *DeleteAtespaceAccessPolicyRequest) Reset() { *x = DeleteAtespaceAccessPolicyRequest{} - mi := &file_ateapi_proto_msgTypes[124] + mi := &file_ateapi_proto_msgTypes[125] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -9094,7 +9189,7 @@ func (x *DeleteAtespaceAccessPolicyRequest) String() string { func (*DeleteAtespaceAccessPolicyRequest) ProtoMessage() {} func (x *DeleteAtespaceAccessPolicyRequest) ProtoReflect() protoreflect.Message { - mi := &file_ateapi_proto_msgTypes[124] + mi := &file_ateapi_proto_msgTypes[125] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -9107,7 +9202,7 @@ func (x *DeleteAtespaceAccessPolicyRequest) ProtoReflect() protoreflect.Message // Deprecated: Use DeleteAtespaceAccessPolicyRequest.ProtoReflect.Descriptor instead. func (*DeleteAtespaceAccessPolicyRequest) Descriptor() ([]byte, []int) { - return file_ateapi_proto_rawDescGZIP(), []int{124} + return file_ateapi_proto_rawDescGZIP(), []int{125} } func (x *DeleteAtespaceAccessPolicyRequest) GetAtespace() *ObjectRef { @@ -9161,14 +9256,15 @@ const file_ateapi_proto_rawDesc = "" + "\vcreate_time\x18\x05 \x01(\v2\x1a.google.protobuf.TimestampR\n" + "createTime\x12;\n" + "\vupdate_time\x18\x06 \x01(\v2\x1a.google.protobuf.TimestampR\n" + - "updateTime\"\xa4\x03\n" + + "updateTime\"\xd6\x03\n" + "\x11ActorVolumeStatus\x12\x12\n" + "\x04name\x18\x01 \x01(\tR\x04name\x12*\n" + "\x11storage_volume_id\x18\x02 \x01(\tR\x0fstorageVolumeId\x12\x1f\n" + "\vvolume_type\x18\x03 \x01(\tR\n" + "volumeType\x128\n" + "\x06status\x18\x04 \x01(\x0e2 .ateapi.ActorVolumeStatus.StatusR\x06status\x12S\n" + - "\x0evolume_context\x18\x05 \x03(\v2,.ateapi.ActorVolumeStatus.VolumeContextEntryR\rvolumeContext\x1a@\n" + + "\x0evolume_context\x18\x05 \x03(\v2,.ateapi.ActorVolumeStatus.VolumeContextEntryR\rvolumeContext\x120\n" + + "\x14external_volume_name\x18\x06 \x01(\tR\x12externalVolumeName\x1a@\n" + "\x12VolumeContextEntry\x12\x10\n" + "\x03key\x18\x01 \x01(\tR\x03key\x12\x14\n" + "\x05value\x18\x02 \x01(\tR\x05value:\x028\x01\"]\n" + @@ -9176,14 +9272,18 @@ const file_ateapi_proto_rawDesc = "" + "\x12STATUS_UNSPECIFIED\x10\x00\x12\x12\n" + "\x0eSTATUS_PENDING\x10\x01\x12\x12\n" + "\x0eSTATUS_CREATED\x10\x02\x12\x13\n" + - "\x0fSTATUS_DELETING\x10\x03\"\x91\x02\n" + + "\x0fSTATUS_DELETING\x10\x03\"\xc1\x03\n" + "\x05Actor\x124\n" + "\bmetadata\x18\x01 \x01(\v2\x18.ateapi.ResourceMetadataR\bmetadata\x128\n" + "\x0eactor_template\x18\x04 \x01(\v2\x11.ateapi.ObjectRefR\ractorTemplate\x129\n" + "\x0fworker_selector\x18\x05 \x01(\v2\x10.ateapi.SelectorR\x0eworkerSelector\x120\n" + "\n" + "source_tag\x18\x06 \x01(\v2\x11.ateapi.ObjectRefR\tsourceTag\x12+\n" + - "\x06status\x18\a \x01(\v2\x13.ateapi.ActorStatusR\x06status\"n\n" + + "\x06status\x18\a \x01(\v2\x13.ateapi.ActorStatusR\x06status\x12c\n" + + "\x18external_volume_bindings\x18\b \x03(\v2).ateapi.Actor.ExternalVolumeBindingsEntryR\x16externalVolumeBindings\x1aI\n" + + "\x1bExternalVolumeBindingsEntry\x12\x10\n" + + "\x03key\x18\x01 \x01(\tR\x03key\x12\x14\n" + + "\x05value\x18\x02 \x01(\tR\x05value:\x028\x01\"n\n" + "\fEgressPolicy\x124\n" + "\bmetadata\x18\x01 \x01(\v2\x18.ateapi.ResourceMetadataR\bmetadata\x12(\n" + "\x05rules\x18\x02 \x03(\v2\x12.ateapi.EgressRuleR\x05rules\"\xa0\x01\n" + @@ -9332,12 +9432,13 @@ const file_ateapi_proto_rawDesc = "" + "\x0ftimeout_seconds\x18\x02 \x01(\x05R\x0etimeoutSeconds\"7\n" + "\rHTTPGetAction\x12\x12\n" + "\x04path\x18\x01 \x01(\tR\x04path\x12\x12\n" + - "\x04port\x18\x02 \x01(\x05R\x04port\"\xa9\x02\n" + + "\x04port\x18\x02 \x01(\x05R\x04port\"\xf4\x02\n" + "\x06Volume\x12\x12\n" + "\x04name\x18\x01 \x01(\tR\x04name\x12?\n" + "\vdurable_dir\x18\x02 \x01(\v2\x1e.ateapi.DurableDirVolumeSourceR\n" + "durableDir\x12X\n" + - "\x18external_volume_template\x18\x03 \x01(\v2\x1e.ateapi.ExternalVolumeTemplateR\x16externalVolumeTemplate\x12?\n" + + "\x18external_volume_template\x18\x03 \x01(\v2\x1e.ateapi.ExternalVolumeTemplateR\x16externalVolumeTemplate\x12I\n" + + "\x13external_volume_ref\x18\x04 \x01(\v2\x19.ateapi.ExternalVolumeRefR\x11externalVolumeRef\x12?\n" + "\vsystem_info\x18\x05 \x01(\v2\x1e.ateapi.SystemInfoVolumeSourceR\n" + "systemInfo\x12/\n" + "\x05image\x18\x06 \x01(\v2\x19.ateapi.ImageVolumeSourceR\x05image\"1\n" + @@ -9346,7 +9447,9 @@ const file_ateapi_proto_rawDesc = "" + "\x16DurableDirVolumeSource\"b\n" + "\x16ExternalVolumeTemplate\x12\x1a\n" + "\bcapacity\x18\x01 \x01(\tR\bcapacity\x12,\n" + - "\x12storage_class_name\x18\x02 \x01(\tR\x10storageClassName\"Y\n" + + "\x12storage_class_name\x18\x02 \x01(\tR\x10storageClassName\"'\n" + + "\x11ExternalVolumeRef\x12\x12\n" + + "\x04name\x18\x01 \x01(\tR\x04name\"Y\n" + "\x16SystemInfoVolumeSource\x12?\n" + "\fdata_sources\x18\x01 \x03(\v2\x1c.ateapi.SystemInfoDataSourceR\vdataSources\"\xa0\x01\n" + "\x14SystemInfoDataSource\x12F\n" + @@ -9722,7 +9825,7 @@ func file_ateapi_proto_rawDescGZIP() []byte { } var file_ateapi_proto_enumTypes = make([]protoimpl.EnumInfo, 13) -var file_ateapi_proto_msgTypes = make([]protoimpl.MessageInfo, 130) +var file_ateapi_proto_msgTypes = make([]protoimpl.MessageInfo, 132) var file_ateapi_proto_goTypes = []any{ (SnapshotOwner)(0), // 0: ateapi.SnapshotOwner (SnapshotDurability)(0), // 1: ateapi.SnapshotDurability @@ -9782,92 +9885,94 @@ var file_ateapi_proto_goTypes = []any{ (*ImageVolumeSource)(nil), // 55: ateapi.ImageVolumeSource (*DurableDirVolumeSource)(nil), // 56: ateapi.DurableDirVolumeSource (*ExternalVolumeTemplate)(nil), // 57: ateapi.ExternalVolumeTemplate - (*SystemInfoVolumeSource)(nil), // 58: ateapi.SystemInfoVolumeSource - (*SystemInfoDataSource)(nil), // 59: ateapi.SystemInfoDataSource - (*ActorMetadataDataSource)(nil), // 60: ateapi.ActorMetadataDataSource - (*ActorMetadataItem)(nil), // 61: ateapi.ActorMetadataItem - (*TrustBundleDataSource)(nil), // 62: ateapi.TrustBundleDataSource - (*VolumeMount)(nil), // 63: ateapi.VolumeMount - (*CreateAtespaceRequest)(nil), // 64: ateapi.CreateAtespaceRequest - (*GetAtespaceRequest)(nil), // 65: ateapi.GetAtespaceRequest - (*ListAtespacesRequest)(nil), // 66: ateapi.ListAtespacesRequest - (*ListAtespacesResponse)(nil), // 67: ateapi.ListAtespacesResponse - (*DeleteAtespaceRequest)(nil), // 68: ateapi.DeleteAtespaceRequest - (*CreateActorTemplateRequest)(nil), // 69: ateapi.CreateActorTemplateRequest - (*GetActorTemplateRequest)(nil), // 70: ateapi.GetActorTemplateRequest - (*ListActorTemplatesRequest)(nil), // 71: ateapi.ListActorTemplatesRequest - (*ListActorTemplatesResponse)(nil), // 72: ateapi.ListActorTemplatesResponse - (*DeleteActorTemplateRequest)(nil), // 73: ateapi.DeleteActorTemplateRequest - (*GetActorRequest)(nil), // 74: ateapi.GetActorRequest - (*CreateActorRequest)(nil), // 75: ateapi.CreateActorRequest - (*UpdateActorRequest)(nil), // 76: ateapi.UpdateActorRequest - (*SuspendActorRequest)(nil), // 77: ateapi.SuspendActorRequest - (*SuspendActorResponse)(nil), // 78: ateapi.SuspendActorResponse - (*PauseActorRequest)(nil), // 79: ateapi.PauseActorRequest - (*PauseActorResponse)(nil), // 80: ateapi.PauseActorResponse - (*ResumeActorRequest)(nil), // 81: ateapi.ResumeActorRequest - (*ResumeActorResponse)(nil), // 82: ateapi.ResumeActorResponse - (*RevertActorRequest)(nil), // 83: ateapi.RevertActorRequest - (*RevertActorResponse)(nil), // 84: ateapi.RevertActorResponse - (*DeleteActorRequest)(nil), // 85: ateapi.DeleteActorRequest - (*GetActorEgressPolicyRequest)(nil), // 86: ateapi.GetActorEgressPolicyRequest - (*CreateActorEgressPolicyRequest)(nil), // 87: ateapi.CreateActorEgressPolicyRequest - (*UpdateActorEgressPolicyRequest)(nil), // 88: ateapi.UpdateActorEgressPolicyRequest - (*DeleteActorEgressPolicyRequest)(nil), // 89: ateapi.DeleteActorEgressPolicyRequest - (*GetTagRequest)(nil), // 90: ateapi.GetTagRequest - (*MintActorJWTRequest)(nil), // 91: ateapi.MintActorJWTRequest - (*MintActorJWTResponse)(nil), // 92: ateapi.MintActorJWTResponse - (*MintActorCertificateRequest)(nil), // 93: ateapi.MintActorCertificateRequest - (*MintActorCertificateResponse)(nil), // 94: ateapi.MintActorCertificateResponse - (*ListTagsRequest)(nil), // 95: ateapi.ListTagsRequest - (*ListTagsResponse)(nil), // 96: ateapi.ListTagsResponse - (*CreateTagRequest)(nil), // 97: ateapi.CreateTagRequest - (*UpdateTagRequest)(nil), // 98: ateapi.UpdateTagRequest - (*DeleteTagRequest)(nil), // 99: ateapi.DeleteTagRequest - (*CreateExternalVolumeRequest)(nil), // 100: ateapi.CreateExternalVolumeRequest - (*GetExternalVolumeRequest)(nil), // 101: ateapi.GetExternalVolumeRequest - (*ListExternalVolumesRequest)(nil), // 102: ateapi.ListExternalVolumesRequest - (*ListExternalVolumesResponse)(nil), // 103: ateapi.ListExternalVolumesResponse - (*UpdateExternalVolumeRequest)(nil), // 104: ateapi.UpdateExternalVolumeRequest - (*DeleteExternalVolumeRequest)(nil), // 105: ateapi.DeleteExternalVolumeRequest - (*DeleteOptions)(nil), // 106: ateapi.DeleteOptions - (*ListWorkerActorAssignmentsRequest)(nil), // 107: ateapi.ListWorkerActorAssignmentsRequest - (*ListWorkerActorAssignmentsResponse)(nil), // 108: ateapi.ListWorkerActorAssignmentsResponse - (*ListWorkersRequest)(nil), // 109: ateapi.ListWorkersRequest - (*ListWorkersResponse)(nil), // 110: ateapi.ListWorkersResponse - (*GetWorkerRequest)(nil), // 111: ateapi.GetWorkerRequest - (*CreateWorkerRequest)(nil), // 112: ateapi.CreateWorkerRequest - (*UpdateWorkerRequest)(nil), // 113: ateapi.UpdateWorkerRequest - (*DeleteWorkerRequest)(nil), // 114: ateapi.DeleteWorkerRequest - (*DrainWorkerRequest)(nil), // 115: ateapi.DrainWorkerRequest - (*ListActorsRequest)(nil), // 116: ateapi.ListActorsRequest - (*ListActorsResponse)(nil), // 117: ateapi.ListActorsResponse - (*Worker)(nil), // 118: ateapi.Worker - (*WorkerStatus)(nil), // 119: ateapi.WorkerStatus - (*HardwareIdentity)(nil), // 120: ateapi.HardwareIdentity - (*WorkerResources)(nil), // 121: ateapi.WorkerResources - (*ActorAssignment)(nil), // 122: ateapi.ActorAssignment - (*RegisterWorkerRequest)(nil), // 123: ateapi.RegisterWorkerRequest - (*RegisterWorkerResponse)(nil), // 124: ateapi.RegisterWorkerResponse - (*MintAteomActorCertificateRequest)(nil), // 125: ateapi.MintAteomActorCertificateRequest - (*MintAteomActorCertificateResponse)(nil), // 126: ateapi.MintAteomActorCertificateResponse - (*RequestActorSuspendRequest)(nil), // 127: ateapi.RequestActorSuspendRequest - (*RequestActorSuspendResponse)(nil), // 128: ateapi.RequestActorSuspendResponse - (*AccessPolicy)(nil), // 129: ateapi.AccessPolicy - (*Binding)(nil), // 130: ateapi.Binding - (*GetGlobalAccessPolicyRequest)(nil), // 131: ateapi.GetGlobalAccessPolicyRequest - (*CreateGlobalAccessPolicyRequest)(nil), // 132: ateapi.CreateGlobalAccessPolicyRequest - (*UpdateGlobalAccessPolicyRequest)(nil), // 133: ateapi.UpdateGlobalAccessPolicyRequest - (*GetAtespaceAccessPolicyRequest)(nil), // 134: ateapi.GetAtespaceAccessPolicyRequest - (*CreateAtespaceAccessPolicyRequest)(nil), // 135: ateapi.CreateAtespaceAccessPolicyRequest - (*UpdateAtespaceAccessPolicyRequest)(nil), // 136: ateapi.UpdateAtespaceAccessPolicyRequest - (*DeleteAtespaceAccessPolicyRequest)(nil), // 137: ateapi.DeleteAtespaceAccessPolicyRequest - nil, // 138: ateapi.Selector.MatchLabelsEntry - nil, // 139: ateapi.ActorVolumeStatus.VolumeContextEntry - nil, // 140: ateapi.ExternalVolume.VolumeContextEntry - nil, // 141: ateapi.Worker.LabelsEntry - nil, // 142: ateapi.HardwareIdentity.AttributesEntry - (*timestamppb.Timestamp)(nil), // 143: google.protobuf.Timestamp + (*ExternalVolumeRef)(nil), // 58: ateapi.ExternalVolumeRef + (*SystemInfoVolumeSource)(nil), // 59: ateapi.SystemInfoVolumeSource + (*SystemInfoDataSource)(nil), // 60: ateapi.SystemInfoDataSource + (*ActorMetadataDataSource)(nil), // 61: ateapi.ActorMetadataDataSource + (*ActorMetadataItem)(nil), // 62: ateapi.ActorMetadataItem + (*TrustBundleDataSource)(nil), // 63: ateapi.TrustBundleDataSource + (*VolumeMount)(nil), // 64: ateapi.VolumeMount + (*CreateAtespaceRequest)(nil), // 65: ateapi.CreateAtespaceRequest + (*GetAtespaceRequest)(nil), // 66: ateapi.GetAtespaceRequest + (*ListAtespacesRequest)(nil), // 67: ateapi.ListAtespacesRequest + (*ListAtespacesResponse)(nil), // 68: ateapi.ListAtespacesResponse + (*DeleteAtespaceRequest)(nil), // 69: ateapi.DeleteAtespaceRequest + (*CreateActorTemplateRequest)(nil), // 70: ateapi.CreateActorTemplateRequest + (*GetActorTemplateRequest)(nil), // 71: ateapi.GetActorTemplateRequest + (*ListActorTemplatesRequest)(nil), // 72: ateapi.ListActorTemplatesRequest + (*ListActorTemplatesResponse)(nil), // 73: ateapi.ListActorTemplatesResponse + (*DeleteActorTemplateRequest)(nil), // 74: ateapi.DeleteActorTemplateRequest + (*GetActorRequest)(nil), // 75: ateapi.GetActorRequest + (*CreateActorRequest)(nil), // 76: ateapi.CreateActorRequest + (*UpdateActorRequest)(nil), // 77: ateapi.UpdateActorRequest + (*SuspendActorRequest)(nil), // 78: ateapi.SuspendActorRequest + (*SuspendActorResponse)(nil), // 79: ateapi.SuspendActorResponse + (*PauseActorRequest)(nil), // 80: ateapi.PauseActorRequest + (*PauseActorResponse)(nil), // 81: ateapi.PauseActorResponse + (*ResumeActorRequest)(nil), // 82: ateapi.ResumeActorRequest + (*ResumeActorResponse)(nil), // 83: ateapi.ResumeActorResponse + (*RevertActorRequest)(nil), // 84: ateapi.RevertActorRequest + (*RevertActorResponse)(nil), // 85: ateapi.RevertActorResponse + (*DeleteActorRequest)(nil), // 86: ateapi.DeleteActorRequest + (*GetActorEgressPolicyRequest)(nil), // 87: ateapi.GetActorEgressPolicyRequest + (*CreateActorEgressPolicyRequest)(nil), // 88: ateapi.CreateActorEgressPolicyRequest + (*UpdateActorEgressPolicyRequest)(nil), // 89: ateapi.UpdateActorEgressPolicyRequest + (*DeleteActorEgressPolicyRequest)(nil), // 90: ateapi.DeleteActorEgressPolicyRequest + (*GetTagRequest)(nil), // 91: ateapi.GetTagRequest + (*MintActorJWTRequest)(nil), // 92: ateapi.MintActorJWTRequest + (*MintActorJWTResponse)(nil), // 93: ateapi.MintActorJWTResponse + (*MintActorCertificateRequest)(nil), // 94: ateapi.MintActorCertificateRequest + (*MintActorCertificateResponse)(nil), // 95: ateapi.MintActorCertificateResponse + (*ListTagsRequest)(nil), // 96: ateapi.ListTagsRequest + (*ListTagsResponse)(nil), // 97: ateapi.ListTagsResponse + (*CreateTagRequest)(nil), // 98: ateapi.CreateTagRequest + (*UpdateTagRequest)(nil), // 99: ateapi.UpdateTagRequest + (*DeleteTagRequest)(nil), // 100: ateapi.DeleteTagRequest + (*CreateExternalVolumeRequest)(nil), // 101: ateapi.CreateExternalVolumeRequest + (*GetExternalVolumeRequest)(nil), // 102: ateapi.GetExternalVolumeRequest + (*ListExternalVolumesRequest)(nil), // 103: ateapi.ListExternalVolumesRequest + (*ListExternalVolumesResponse)(nil), // 104: ateapi.ListExternalVolumesResponse + (*UpdateExternalVolumeRequest)(nil), // 105: ateapi.UpdateExternalVolumeRequest + (*DeleteExternalVolumeRequest)(nil), // 106: ateapi.DeleteExternalVolumeRequest + (*DeleteOptions)(nil), // 107: ateapi.DeleteOptions + (*ListWorkerActorAssignmentsRequest)(nil), // 108: ateapi.ListWorkerActorAssignmentsRequest + (*ListWorkerActorAssignmentsResponse)(nil), // 109: ateapi.ListWorkerActorAssignmentsResponse + (*ListWorkersRequest)(nil), // 110: ateapi.ListWorkersRequest + (*ListWorkersResponse)(nil), // 111: ateapi.ListWorkersResponse + (*GetWorkerRequest)(nil), // 112: ateapi.GetWorkerRequest + (*CreateWorkerRequest)(nil), // 113: ateapi.CreateWorkerRequest + (*UpdateWorkerRequest)(nil), // 114: ateapi.UpdateWorkerRequest + (*DeleteWorkerRequest)(nil), // 115: ateapi.DeleteWorkerRequest + (*DrainWorkerRequest)(nil), // 116: ateapi.DrainWorkerRequest + (*ListActorsRequest)(nil), // 117: ateapi.ListActorsRequest + (*ListActorsResponse)(nil), // 118: ateapi.ListActorsResponse + (*Worker)(nil), // 119: ateapi.Worker + (*WorkerStatus)(nil), // 120: ateapi.WorkerStatus + (*HardwareIdentity)(nil), // 121: ateapi.HardwareIdentity + (*WorkerResources)(nil), // 122: ateapi.WorkerResources + (*ActorAssignment)(nil), // 123: ateapi.ActorAssignment + (*RegisterWorkerRequest)(nil), // 124: ateapi.RegisterWorkerRequest + (*RegisterWorkerResponse)(nil), // 125: ateapi.RegisterWorkerResponse + (*MintAteomActorCertificateRequest)(nil), // 126: ateapi.MintAteomActorCertificateRequest + (*MintAteomActorCertificateResponse)(nil), // 127: ateapi.MintAteomActorCertificateResponse + (*RequestActorSuspendRequest)(nil), // 128: ateapi.RequestActorSuspendRequest + (*RequestActorSuspendResponse)(nil), // 129: ateapi.RequestActorSuspendResponse + (*AccessPolicy)(nil), // 130: ateapi.AccessPolicy + (*Binding)(nil), // 131: ateapi.Binding + (*GetGlobalAccessPolicyRequest)(nil), // 132: ateapi.GetGlobalAccessPolicyRequest + (*CreateGlobalAccessPolicyRequest)(nil), // 133: ateapi.CreateGlobalAccessPolicyRequest + (*UpdateGlobalAccessPolicyRequest)(nil), // 134: ateapi.UpdateGlobalAccessPolicyRequest + (*GetAtespaceAccessPolicyRequest)(nil), // 135: ateapi.GetAtespaceAccessPolicyRequest + (*CreateAtespaceAccessPolicyRequest)(nil), // 136: ateapi.CreateAtespaceAccessPolicyRequest + (*UpdateAtespaceAccessPolicyRequest)(nil), // 137: ateapi.UpdateAtespaceAccessPolicyRequest + (*DeleteAtespaceAccessPolicyRequest)(nil), // 138: ateapi.DeleteAtespaceAccessPolicyRequest + nil, // 139: ateapi.Selector.MatchLabelsEntry + nil, // 140: ateapi.ActorVolumeStatus.VolumeContextEntry + nil, // 141: ateapi.Actor.ExternalVolumeBindingsEntry + nil, // 142: ateapi.ExternalVolume.VolumeContextEntry + nil, // 143: ateapi.Worker.LabelsEntry + nil, // 144: ateapi.HardwareIdentity.AttributesEntry + (*timestamppb.Timestamp)(nil), // 145: google.protobuf.Timestamp } var file_ateapi_proto_depIdxs = []int32{ 1, // 0: ateapi.SnapshotStorage.durability:type_name -> ateapi.SnapshotDurability @@ -9877,270 +9982,272 @@ var file_ateapi_proto_depIdxs = []int32{ 13, // 4: ateapi.SnapshotStorage.object:type_name -> ateapi.ObjectSnapshot 0, // 5: ateapi.Snapshot.owner:type_name -> ateapi.SnapshotOwner 15, // 6: ateapi.Snapshot.storage:type_name -> ateapi.SnapshotStorage - 138, // 7: ateapi.Selector.match_labels:type_name -> ateapi.Selector.MatchLabelsEntry - 143, // 8: ateapi.ResourceMetadata.create_time:type_name -> google.protobuf.Timestamp - 143, // 9: ateapi.ResourceMetadata.update_time:type_name -> google.protobuf.Timestamp + 139, // 7: ateapi.Selector.match_labels:type_name -> ateapi.Selector.MatchLabelsEntry + 145, // 8: ateapi.ResourceMetadata.create_time:type_name -> google.protobuf.Timestamp + 145, // 9: ateapi.ResourceMetadata.update_time:type_name -> google.protobuf.Timestamp 12, // 10: ateapi.ActorVolumeStatus.status:type_name -> ateapi.ActorVolumeStatus.Status - 139, // 11: ateapi.ActorVolumeStatus.volume_context:type_name -> ateapi.ActorVolumeStatus.VolumeContextEntry + 140, // 11: ateapi.ActorVolumeStatus.volume_context:type_name -> ateapi.ActorVolumeStatus.VolumeContextEntry 18, // 12: ateapi.Actor.metadata:type_name -> ateapi.ResourceMetadata 40, // 13: ateapi.Actor.actor_template:type_name -> ateapi.ObjectRef 17, // 14: ateapi.Actor.worker_selector:type_name -> ateapi.Selector 40, // 15: ateapi.Actor.source_tag:type_name -> ateapi.ObjectRef 31, // 16: ateapi.Actor.status:type_name -> ateapi.ActorStatus - 18, // 17: ateapi.EgressPolicy.metadata:type_name -> ateapi.ResourceMetadata - 22, // 18: ateapi.EgressPolicy.rules:type_name -> ateapi.EgressRule - 23, // 19: ateapi.EgressRule.http:type_name -> ateapi.HTTPRule - 24, // 20: ateapi.EgressRule.https:type_name -> ateapi.HTTPSRule - 25, // 21: ateapi.EgressRule.tls_passthrough:type_name -> ateapi.TLSPassthroughRule - 26, // 22: ateapi.HTTPRule.ports:type_name -> ateapi.Ports - 28, // 23: ateapi.HTTPRule.effects:type_name -> ateapi.HttpRuleEffects - 26, // 24: ateapi.HTTPSRule.ports:type_name -> ateapi.Ports - 28, // 25: ateapi.HTTPSRule.effects:type_name -> ateapi.HttpRuleEffects - 26, // 26: ateapi.TLSPassthroughRule.ports:type_name -> ateapi.Ports - 27, // 27: ateapi.Ports.all:type_name -> ateapi.AllPorts - 29, // 28: ateapi.HttpRuleEffects.replace_headers:type_name -> ateapi.CredentialHeader - 30, // 29: ateapi.CredentialHeader.actor_jwt:type_name -> ateapi.ActorJWTSource - 5, // 30: ateapi.ActorStatus.state:type_name -> ateapi.ActorState - 33, // 31: ateapi.ActorStatus.worker_assignment:type_name -> ateapi.WorkerAssignment - 19, // 32: ateapi.ActorStatus.external_volumes:type_name -> ateapi.ActorVolumeStatus - 32, // 33: ateapi.ActorStatus.crash:type_name -> ateapi.ActorCrash - 16, // 34: ateapi.ActorStatus.snapshots:type_name -> ateapi.Snapshot - 143, // 35: ateapi.ActorCrash.crash_time:type_name -> google.protobuf.Timestamp - 40, // 36: ateapi.WorkerAssignment.worker:type_name -> ateapi.ObjectRef - 16, // 37: ateapi.TagStatus.snapshot:type_name -> ateapi.Snapshot - 18, // 38: ateapi.Tag.metadata:type_name -> ateapi.ResourceMetadata - 34, // 39: ateapi.Tag.status:type_name -> ateapi.TagStatus - 4, // 40: ateapi.Tag.scope:type_name -> ateapi.TagScope - 40, // 41: ateapi.Tag.source_actor:type_name -> ateapi.ObjectRef - 18, // 42: ateapi.ExternalVolume.metadata:type_name -> ateapi.ResourceMetadata - 6, // 43: ateapi.ExternalVolume.delete_trigger:type_name -> ateapi.DeleteTrigger - 140, // 44: ateapi.ExternalVolume.volume_context:type_name -> ateapi.ExternalVolume.VolumeContextEntry - 37, // 45: ateapi.ExternalVolume.status:type_name -> ateapi.ExternalVolumeStatus - 7, // 46: ateapi.ExternalVolume.access_mode:type_name -> ateapi.AccessMode - 8, // 47: ateapi.ExternalVolumeStatus.state:type_name -> ateapi.ExternalVolumeState - 38, // 48: ateapi.ExternalVolumeStatus.refs:type_name -> ateapi.ActorRef - 18, // 49: ateapi.Atespace.metadata:type_name -> ateapi.ResourceMetadata - 18, // 50: ateapi.ActorTemplate.metadata:type_name -> ateapi.ResourceMetadata - 17, // 51: ateapi.ActorTemplate.worker_selector:type_name -> ateapi.Selector - 48, // 52: ateapi.ActorTemplate.containers:type_name -> ateapi.Container - 54, // 53: ateapi.ActorTemplate.volumes:type_name -> ateapi.Volume - 47, // 54: ateapi.ActorTemplate.snapshot_config:type_name -> ateapi.SnapshotConfig - 46, // 55: ateapi.ActorTemplate.sandbox_config:type_name -> ateapi.SandboxConfig - 42, // 56: ateapi.ActorTemplate.resources:type_name -> ateapi.Resources - 45, // 57: ateapi.ActorTemplate.status:type_name -> ateapi.ActorTemplateStatus - 43, // 58: ateapi.Resources.limits:type_name -> ateapi.Limits - 40, // 59: ateapi.GoldenSnapshotStatus.golden_tag:type_name -> ateapi.ObjectRef - 143, // 60: ateapi.GoldenSnapshotStatus.take_golden_snapshot_at:type_name -> google.protobuf.Timestamp - 44, // 61: ateapi.ActorTemplateStatus.golden_snapshot_status:type_name -> ateapi.GoldenSnapshotStatus - 9, // 62: ateapi.SandboxConfig.sandbox_class:type_name -> ateapi.SandboxClass - 3, // 63: ateapi.SnapshotConfig.preferred_fidelity:type_name -> ateapi.SnapshotFidelity - 51, // 64: ateapi.Container.env:type_name -> ateapi.EnvVar - 52, // 65: ateapi.Container.wakeup_probe:type_name -> ateapi.ContainerWakeupProbe - 63, // 66: ateapi.Container.volume_mounts:type_name -> ateapi.VolumeMount - 49, // 67: ateapi.Container.security_context:type_name -> ateapi.SecurityContext - 42, // 68: ateapi.Container.resources:type_name -> ateapi.Resources - 50, // 69: ateapi.SecurityContext.capabilities:type_name -> ateapi.Capabilities - 53, // 70: ateapi.ContainerWakeupProbe.http_get:type_name -> ateapi.HTTPGetAction - 56, // 71: ateapi.Volume.durable_dir:type_name -> ateapi.DurableDirVolumeSource - 57, // 72: ateapi.Volume.external_volume_template:type_name -> ateapi.ExternalVolumeTemplate - 58, // 73: ateapi.Volume.system_info:type_name -> ateapi.SystemInfoVolumeSource - 55, // 74: ateapi.Volume.image:type_name -> ateapi.ImageVolumeSource - 59, // 75: ateapi.SystemInfoVolumeSource.data_sources:type_name -> ateapi.SystemInfoDataSource - 60, // 76: ateapi.SystemInfoDataSource.actor_metadata:type_name -> ateapi.ActorMetadataDataSource - 62, // 77: ateapi.SystemInfoDataSource.trust_bundle:type_name -> ateapi.TrustBundleDataSource - 61, // 78: ateapi.ActorMetadataDataSource.items:type_name -> ateapi.ActorMetadataItem - 10, // 79: ateapi.ActorMetadataItem.field:type_name -> ateapi.ActorMetadataField - 39, // 80: ateapi.CreateAtespaceRequest.atespace:type_name -> ateapi.Atespace - 40, // 81: ateapi.GetAtespaceRequest.atespace:type_name -> ateapi.ObjectRef - 39, // 82: ateapi.ListAtespacesResponse.atespaces:type_name -> ateapi.Atespace - 40, // 83: ateapi.DeleteAtespaceRequest.atespace:type_name -> ateapi.ObjectRef - 106, // 84: ateapi.DeleteAtespaceRequest.options:type_name -> ateapi.DeleteOptions - 41, // 85: ateapi.CreateActorTemplateRequest.actor_template:type_name -> ateapi.ActorTemplate - 40, // 86: ateapi.GetActorTemplateRequest.actor_template:type_name -> ateapi.ObjectRef - 41, // 87: ateapi.ListActorTemplatesResponse.actor_templates:type_name -> ateapi.ActorTemplate - 40, // 88: ateapi.DeleteActorTemplateRequest.actor_template:type_name -> ateapi.ObjectRef - 106, // 89: ateapi.DeleteActorTemplateRequest.options:type_name -> ateapi.DeleteOptions - 40, // 90: ateapi.GetActorRequest.actor:type_name -> ateapi.ObjectRef - 20, // 91: ateapi.CreateActorRequest.actor:type_name -> ateapi.Actor - 20, // 92: ateapi.UpdateActorRequest.actor:type_name -> ateapi.Actor - 40, // 93: ateapi.SuspendActorRequest.actor:type_name -> ateapi.ObjectRef - 20, // 94: ateapi.SuspendActorResponse.actor:type_name -> ateapi.Actor - 40, // 95: ateapi.PauseActorRequest.actor:type_name -> ateapi.ObjectRef - 20, // 96: ateapi.PauseActorResponse.actor:type_name -> ateapi.Actor - 40, // 97: ateapi.ResumeActorRequest.actor:type_name -> ateapi.ObjectRef - 20, // 98: ateapi.ResumeActorResponse.actor:type_name -> ateapi.Actor - 40, // 99: ateapi.RevertActorRequest.actor:type_name -> ateapi.ObjectRef - 20, // 100: ateapi.RevertActorResponse.actor:type_name -> ateapi.Actor - 40, // 101: ateapi.DeleteActorRequest.actor:type_name -> ateapi.ObjectRef - 106, // 102: ateapi.DeleteActorRequest.options:type_name -> ateapi.DeleteOptions - 40, // 103: ateapi.GetActorEgressPolicyRequest.actor:type_name -> ateapi.ObjectRef - 40, // 104: ateapi.CreateActorEgressPolicyRequest.actor:type_name -> ateapi.ObjectRef - 21, // 105: ateapi.CreateActorEgressPolicyRequest.egress_policy:type_name -> ateapi.EgressPolicy - 40, // 106: ateapi.UpdateActorEgressPolicyRequest.actor:type_name -> ateapi.ObjectRef - 21, // 107: ateapi.UpdateActorEgressPolicyRequest.egress_policy:type_name -> ateapi.EgressPolicy - 40, // 108: ateapi.DeleteActorEgressPolicyRequest.actor:type_name -> ateapi.ObjectRef - 106, // 109: ateapi.DeleteActorEgressPolicyRequest.options:type_name -> ateapi.DeleteOptions - 40, // 110: ateapi.GetTagRequest.tag:type_name -> ateapi.ObjectRef - 40, // 111: ateapi.MintActorJWTRequest.actor:type_name -> ateapi.ObjectRef - 143, // 112: ateapi.MintActorJWTResponse.expires_at:type_name -> google.protobuf.Timestamp - 40, // 113: ateapi.MintActorCertificateRequest.actor:type_name -> ateapi.ObjectRef - 35, // 114: ateapi.ListTagsResponse.tags:type_name -> ateapi.Tag - 35, // 115: ateapi.CreateTagRequest.tag:type_name -> ateapi.Tag - 35, // 116: ateapi.UpdateTagRequest.tag:type_name -> ateapi.Tag - 40, // 117: ateapi.DeleteTagRequest.tag:type_name -> ateapi.ObjectRef - 106, // 118: ateapi.DeleteTagRequest.options:type_name -> ateapi.DeleteOptions - 36, // 119: ateapi.CreateExternalVolumeRequest.external_volume:type_name -> ateapi.ExternalVolume - 40, // 120: ateapi.GetExternalVolumeRequest.external_volume:type_name -> ateapi.ObjectRef - 36, // 121: ateapi.ListExternalVolumesResponse.external_volumes:type_name -> ateapi.ExternalVolume - 36, // 122: ateapi.UpdateExternalVolumeRequest.external_volume:type_name -> ateapi.ExternalVolume - 40, // 123: ateapi.DeleteExternalVolumeRequest.external_volume:type_name -> ateapi.ObjectRef - 106, // 124: ateapi.DeleteExternalVolumeRequest.options:type_name -> ateapi.DeleteOptions - 40, // 125: ateapi.ListWorkerActorAssignmentsRequest.worker:type_name -> ateapi.ObjectRef - 122, // 126: ateapi.ListWorkerActorAssignmentsResponse.actor_assignments:type_name -> ateapi.ActorAssignment - 118, // 127: ateapi.ListWorkersResponse.workers:type_name -> ateapi.Worker - 40, // 128: ateapi.GetWorkerRequest.worker:type_name -> ateapi.ObjectRef - 118, // 129: ateapi.CreateWorkerRequest.worker:type_name -> ateapi.Worker - 118, // 130: ateapi.UpdateWorkerRequest.worker:type_name -> ateapi.Worker - 40, // 131: ateapi.DeleteWorkerRequest.worker:type_name -> ateapi.ObjectRef - 106, // 132: ateapi.DeleteWorkerRequest.options:type_name -> ateapi.DeleteOptions - 40, // 133: ateapi.DrainWorkerRequest.worker:type_name -> ateapi.ObjectRef - 20, // 134: ateapi.ListActorsResponse.actors:type_name -> ateapi.Actor - 18, // 135: ateapi.Worker.metadata:type_name -> ateapi.ResourceMetadata - 141, // 136: ateapi.Worker.labels:type_name -> ateapi.Worker.LabelsEntry - 119, // 137: ateapi.Worker.status:type_name -> ateapi.WorkerStatus - 11, // 138: ateapi.WorkerStatus.state:type_name -> ateapi.WorkerState - 121, // 139: ateapi.WorkerStatus.capacity:type_name -> ateapi.WorkerResources - 121, // 140: ateapi.WorkerStatus.allocated:type_name -> ateapi.WorkerResources - 120, // 141: ateapi.WorkerStatus.hardware:type_name -> ateapi.HardwareIdentity - 142, // 142: ateapi.HardwareIdentity.attributes:type_name -> ateapi.HardwareIdentity.AttributesEntry - 42, // 143: ateapi.WorkerResources.resources:type_name -> ateapi.Resources - 18, // 144: ateapi.ActorAssignment.metadata:type_name -> ateapi.ResourceMetadata - 40, // 145: ateapi.ActorAssignment.actor:type_name -> ateapi.ObjectRef - 42, // 146: ateapi.ActorAssignment.resources:type_name -> ateapi.Resources - 40, // 147: ateapi.RegisterWorkerRequest.worker:type_name -> ateapi.ObjectRef - 121, // 148: ateapi.RegisterWorkerRequest.capacity:type_name -> ateapi.WorkerResources - 120, // 149: ateapi.RegisterWorkerRequest.hardware:type_name -> ateapi.HardwareIdentity - 118, // 150: ateapi.RegisterWorkerResponse.worker:type_name -> ateapi.Worker - 40, // 151: ateapi.MintAteomActorCertificateRequest.actor:type_name -> ateapi.ObjectRef - 40, // 152: ateapi.RequestActorSuspendRequest.worker:type_name -> ateapi.ObjectRef - 40, // 153: ateapi.RequestActorSuspendRequest.actor:type_name -> ateapi.ObjectRef - 20, // 154: ateapi.RequestActorSuspendResponse.actor:type_name -> ateapi.Actor - 18, // 155: ateapi.AccessPolicy.metadata:type_name -> ateapi.ResourceMetadata - 130, // 156: ateapi.AccessPolicy.bindings:type_name -> ateapi.Binding - 129, // 157: ateapi.CreateGlobalAccessPolicyRequest.access_policy:type_name -> ateapi.AccessPolicy - 129, // 158: ateapi.UpdateGlobalAccessPolicyRequest.access_policy:type_name -> ateapi.AccessPolicy - 40, // 159: ateapi.GetAtespaceAccessPolicyRequest.atespace:type_name -> ateapi.ObjectRef - 40, // 160: ateapi.CreateAtespaceAccessPolicyRequest.atespace:type_name -> ateapi.ObjectRef - 129, // 161: ateapi.CreateAtespaceAccessPolicyRequest.access_policy:type_name -> ateapi.AccessPolicy - 40, // 162: ateapi.UpdateAtespaceAccessPolicyRequest.atespace:type_name -> ateapi.ObjectRef - 129, // 163: ateapi.UpdateAtespaceAccessPolicyRequest.access_policy:type_name -> ateapi.AccessPolicy - 40, // 164: ateapi.DeleteAtespaceAccessPolicyRequest.atespace:type_name -> ateapi.ObjectRef - 106, // 165: ateapi.DeleteAtespaceAccessPolicyRequest.options:type_name -> ateapi.DeleteOptions - 74, // 166: ateapi.Control.GetActor:input_type -> ateapi.GetActorRequest - 75, // 167: ateapi.Control.CreateActor:input_type -> ateapi.CreateActorRequest - 76, // 168: ateapi.Control.UpdateActor:input_type -> ateapi.UpdateActorRequest - 77, // 169: ateapi.Control.SuspendActor:input_type -> ateapi.SuspendActorRequest - 79, // 170: ateapi.Control.PauseActor:input_type -> ateapi.PauseActorRequest - 81, // 171: ateapi.Control.ResumeActor:input_type -> ateapi.ResumeActorRequest - 83, // 172: ateapi.Control.RevertActor:input_type -> ateapi.RevertActorRequest - 85, // 173: ateapi.Control.DeleteActor:input_type -> ateapi.DeleteActorRequest - 86, // 174: ateapi.Control.GetActorEgressPolicy:input_type -> ateapi.GetActorEgressPolicyRequest - 87, // 175: ateapi.Control.CreateActorEgressPolicy:input_type -> ateapi.CreateActorEgressPolicyRequest - 88, // 176: ateapi.Control.UpdateActorEgressPolicy:input_type -> ateapi.UpdateActorEgressPolicyRequest - 89, // 177: ateapi.Control.DeleteActorEgressPolicy:input_type -> ateapi.DeleteActorEgressPolicyRequest - 91, // 178: ateapi.Control.MintActorJWT:input_type -> ateapi.MintActorJWTRequest - 93, // 179: ateapi.Control.MintActorCertificate:input_type -> ateapi.MintActorCertificateRequest - 97, // 180: ateapi.Control.CreateTag:input_type -> ateapi.CreateTagRequest - 90, // 181: ateapi.Control.GetTag:input_type -> ateapi.GetTagRequest - 95, // 182: ateapi.Control.ListTags:input_type -> ateapi.ListTagsRequest - 98, // 183: ateapi.Control.UpdateTag:input_type -> ateapi.UpdateTagRequest - 99, // 184: ateapi.Control.DeleteTag:input_type -> ateapi.DeleteTagRequest - 100, // 185: ateapi.Control.CreateExternalVolume:input_type -> ateapi.CreateExternalVolumeRequest - 101, // 186: ateapi.Control.GetExternalVolume:input_type -> ateapi.GetExternalVolumeRequest - 102, // 187: ateapi.Control.ListExternalVolumes:input_type -> ateapi.ListExternalVolumesRequest - 104, // 188: ateapi.Control.UpdateExternalVolume:input_type -> ateapi.UpdateExternalVolumeRequest - 105, // 189: ateapi.Control.DeleteExternalVolume:input_type -> ateapi.DeleteExternalVolumeRequest - 109, // 190: ateapi.Control.ListWorkers:input_type -> ateapi.ListWorkersRequest - 111, // 191: ateapi.Control.GetWorker:input_type -> ateapi.GetWorkerRequest - 112, // 192: ateapi.Control.CreateWorker:input_type -> ateapi.CreateWorkerRequest - 113, // 193: ateapi.Control.UpdateWorker:input_type -> ateapi.UpdateWorkerRequest - 114, // 194: ateapi.Control.DeleteWorker:input_type -> ateapi.DeleteWorkerRequest - 115, // 195: ateapi.Control.DrainWorker:input_type -> ateapi.DrainWorkerRequest - 107, // 196: ateapi.Control.ListWorkerActorAssignments:input_type -> ateapi.ListWorkerActorAssignmentsRequest - 116, // 197: ateapi.Control.ListActors:input_type -> ateapi.ListActorsRequest - 64, // 198: ateapi.Control.CreateAtespace:input_type -> ateapi.CreateAtespaceRequest - 65, // 199: ateapi.Control.GetAtespace:input_type -> ateapi.GetAtespaceRequest - 66, // 200: ateapi.Control.ListAtespaces:input_type -> ateapi.ListAtespacesRequest - 68, // 201: ateapi.Control.DeleteAtespace:input_type -> ateapi.DeleteAtespaceRequest - 69, // 202: ateapi.Control.CreateActorTemplate:input_type -> ateapi.CreateActorTemplateRequest - 70, // 203: ateapi.Control.GetActorTemplate:input_type -> ateapi.GetActorTemplateRequest - 71, // 204: ateapi.Control.ListActorTemplates:input_type -> ateapi.ListActorTemplatesRequest - 73, // 205: ateapi.Control.DeleteActorTemplate:input_type -> ateapi.DeleteActorTemplateRequest - 131, // 206: ateapi.Control.GetGlobalAccessPolicy:input_type -> ateapi.GetGlobalAccessPolicyRequest - 132, // 207: ateapi.Control.CreateGlobalAccessPolicy:input_type -> ateapi.CreateGlobalAccessPolicyRequest - 133, // 208: ateapi.Control.UpdateGlobalAccessPolicy:input_type -> ateapi.UpdateGlobalAccessPolicyRequest - 134, // 209: ateapi.Control.GetAtespaceAccessPolicy:input_type -> ateapi.GetAtespaceAccessPolicyRequest - 135, // 210: ateapi.Control.CreateAtespaceAccessPolicy:input_type -> ateapi.CreateAtespaceAccessPolicyRequest - 136, // 211: ateapi.Control.UpdateAtespaceAccessPolicy:input_type -> ateapi.UpdateAtespaceAccessPolicyRequest - 137, // 212: ateapi.Control.DeleteAtespaceAccessPolicy:input_type -> ateapi.DeleteAtespaceAccessPolicyRequest - 123, // 213: ateapi.WorkerService.RegisterWorker:input_type -> ateapi.RegisterWorkerRequest - 125, // 214: ateapi.WorkerService.MintAteomActorCertificate:input_type -> ateapi.MintAteomActorCertificateRequest - 127, // 215: ateapi.WorkerService.RequestActorSuspend:input_type -> ateapi.RequestActorSuspendRequest - 20, // 216: ateapi.Control.GetActor:output_type -> ateapi.Actor - 20, // 217: ateapi.Control.CreateActor:output_type -> ateapi.Actor - 20, // 218: ateapi.Control.UpdateActor:output_type -> ateapi.Actor - 78, // 219: ateapi.Control.SuspendActor:output_type -> ateapi.SuspendActorResponse - 80, // 220: ateapi.Control.PauseActor:output_type -> ateapi.PauseActorResponse - 82, // 221: ateapi.Control.ResumeActor:output_type -> ateapi.ResumeActorResponse - 84, // 222: ateapi.Control.RevertActor:output_type -> ateapi.RevertActorResponse - 20, // 223: ateapi.Control.DeleteActor:output_type -> ateapi.Actor - 21, // 224: ateapi.Control.GetActorEgressPolicy:output_type -> ateapi.EgressPolicy - 21, // 225: ateapi.Control.CreateActorEgressPolicy:output_type -> ateapi.EgressPolicy - 21, // 226: ateapi.Control.UpdateActorEgressPolicy:output_type -> ateapi.EgressPolicy - 21, // 227: ateapi.Control.DeleteActorEgressPolicy:output_type -> ateapi.EgressPolicy - 92, // 228: ateapi.Control.MintActorJWT:output_type -> ateapi.MintActorJWTResponse - 94, // 229: ateapi.Control.MintActorCertificate:output_type -> ateapi.MintActorCertificateResponse - 35, // 230: ateapi.Control.CreateTag:output_type -> ateapi.Tag - 35, // 231: ateapi.Control.GetTag:output_type -> ateapi.Tag - 96, // 232: ateapi.Control.ListTags:output_type -> ateapi.ListTagsResponse - 35, // 233: ateapi.Control.UpdateTag:output_type -> ateapi.Tag - 35, // 234: ateapi.Control.DeleteTag:output_type -> ateapi.Tag - 36, // 235: ateapi.Control.CreateExternalVolume:output_type -> ateapi.ExternalVolume - 36, // 236: ateapi.Control.GetExternalVolume:output_type -> ateapi.ExternalVolume - 103, // 237: ateapi.Control.ListExternalVolumes:output_type -> ateapi.ListExternalVolumesResponse - 36, // 238: ateapi.Control.UpdateExternalVolume:output_type -> ateapi.ExternalVolume - 36, // 239: ateapi.Control.DeleteExternalVolume:output_type -> ateapi.ExternalVolume - 110, // 240: ateapi.Control.ListWorkers:output_type -> ateapi.ListWorkersResponse - 118, // 241: ateapi.Control.GetWorker:output_type -> ateapi.Worker - 118, // 242: ateapi.Control.CreateWorker:output_type -> ateapi.Worker - 118, // 243: ateapi.Control.UpdateWorker:output_type -> ateapi.Worker - 118, // 244: ateapi.Control.DeleteWorker:output_type -> ateapi.Worker - 118, // 245: ateapi.Control.DrainWorker:output_type -> ateapi.Worker - 108, // 246: ateapi.Control.ListWorkerActorAssignments:output_type -> ateapi.ListWorkerActorAssignmentsResponse - 117, // 247: ateapi.Control.ListActors:output_type -> ateapi.ListActorsResponse - 39, // 248: ateapi.Control.CreateAtespace:output_type -> ateapi.Atespace - 39, // 249: ateapi.Control.GetAtespace:output_type -> ateapi.Atespace - 67, // 250: ateapi.Control.ListAtespaces:output_type -> ateapi.ListAtespacesResponse - 39, // 251: ateapi.Control.DeleteAtespace:output_type -> ateapi.Atespace - 41, // 252: ateapi.Control.CreateActorTemplate:output_type -> ateapi.ActorTemplate - 41, // 253: ateapi.Control.GetActorTemplate:output_type -> ateapi.ActorTemplate - 72, // 254: ateapi.Control.ListActorTemplates:output_type -> ateapi.ListActorTemplatesResponse - 41, // 255: ateapi.Control.DeleteActorTemplate:output_type -> ateapi.ActorTemplate - 129, // 256: ateapi.Control.GetGlobalAccessPolicy:output_type -> ateapi.AccessPolicy - 129, // 257: ateapi.Control.CreateGlobalAccessPolicy:output_type -> ateapi.AccessPolicy - 129, // 258: ateapi.Control.UpdateGlobalAccessPolicy:output_type -> ateapi.AccessPolicy - 129, // 259: ateapi.Control.GetAtespaceAccessPolicy:output_type -> ateapi.AccessPolicy - 129, // 260: ateapi.Control.CreateAtespaceAccessPolicy:output_type -> ateapi.AccessPolicy - 129, // 261: ateapi.Control.UpdateAtespaceAccessPolicy:output_type -> ateapi.AccessPolicy - 129, // 262: ateapi.Control.DeleteAtespaceAccessPolicy:output_type -> ateapi.AccessPolicy - 124, // 263: ateapi.WorkerService.RegisterWorker:output_type -> ateapi.RegisterWorkerResponse - 126, // 264: ateapi.WorkerService.MintAteomActorCertificate:output_type -> ateapi.MintAteomActorCertificateResponse - 128, // 265: ateapi.WorkerService.RequestActorSuspend:output_type -> ateapi.RequestActorSuspendResponse - 216, // [216:266] is the sub-list for method output_type - 166, // [166:216] is the sub-list for method input_type - 166, // [166:166] is the sub-list for extension type_name - 166, // [166:166] is the sub-list for extension extendee - 0, // [0:166] is the sub-list for field type_name + 141, // 17: ateapi.Actor.external_volume_bindings:type_name -> ateapi.Actor.ExternalVolumeBindingsEntry + 18, // 18: ateapi.EgressPolicy.metadata:type_name -> ateapi.ResourceMetadata + 22, // 19: ateapi.EgressPolicy.rules:type_name -> ateapi.EgressRule + 23, // 20: ateapi.EgressRule.http:type_name -> ateapi.HTTPRule + 24, // 21: ateapi.EgressRule.https:type_name -> ateapi.HTTPSRule + 25, // 22: ateapi.EgressRule.tls_passthrough:type_name -> ateapi.TLSPassthroughRule + 26, // 23: ateapi.HTTPRule.ports:type_name -> ateapi.Ports + 28, // 24: ateapi.HTTPRule.effects:type_name -> ateapi.HttpRuleEffects + 26, // 25: ateapi.HTTPSRule.ports:type_name -> ateapi.Ports + 28, // 26: ateapi.HTTPSRule.effects:type_name -> ateapi.HttpRuleEffects + 26, // 27: ateapi.TLSPassthroughRule.ports:type_name -> ateapi.Ports + 27, // 28: ateapi.Ports.all:type_name -> ateapi.AllPorts + 29, // 29: ateapi.HttpRuleEffects.replace_headers:type_name -> ateapi.CredentialHeader + 30, // 30: ateapi.CredentialHeader.actor_jwt:type_name -> ateapi.ActorJWTSource + 5, // 31: ateapi.ActorStatus.state:type_name -> ateapi.ActorState + 33, // 32: ateapi.ActorStatus.worker_assignment:type_name -> ateapi.WorkerAssignment + 19, // 33: ateapi.ActorStatus.external_volumes:type_name -> ateapi.ActorVolumeStatus + 32, // 34: ateapi.ActorStatus.crash:type_name -> ateapi.ActorCrash + 16, // 35: ateapi.ActorStatus.snapshots:type_name -> ateapi.Snapshot + 145, // 36: ateapi.ActorCrash.crash_time:type_name -> google.protobuf.Timestamp + 40, // 37: ateapi.WorkerAssignment.worker:type_name -> ateapi.ObjectRef + 16, // 38: ateapi.TagStatus.snapshot:type_name -> ateapi.Snapshot + 18, // 39: ateapi.Tag.metadata:type_name -> ateapi.ResourceMetadata + 34, // 40: ateapi.Tag.status:type_name -> ateapi.TagStatus + 4, // 41: ateapi.Tag.scope:type_name -> ateapi.TagScope + 40, // 42: ateapi.Tag.source_actor:type_name -> ateapi.ObjectRef + 18, // 43: ateapi.ExternalVolume.metadata:type_name -> ateapi.ResourceMetadata + 6, // 44: ateapi.ExternalVolume.delete_trigger:type_name -> ateapi.DeleteTrigger + 142, // 45: ateapi.ExternalVolume.volume_context:type_name -> ateapi.ExternalVolume.VolumeContextEntry + 37, // 46: ateapi.ExternalVolume.status:type_name -> ateapi.ExternalVolumeStatus + 7, // 47: ateapi.ExternalVolume.access_mode:type_name -> ateapi.AccessMode + 8, // 48: ateapi.ExternalVolumeStatus.state:type_name -> ateapi.ExternalVolumeState + 38, // 49: ateapi.ExternalVolumeStatus.refs:type_name -> ateapi.ActorRef + 18, // 50: ateapi.Atespace.metadata:type_name -> ateapi.ResourceMetadata + 18, // 51: ateapi.ActorTemplate.metadata:type_name -> ateapi.ResourceMetadata + 17, // 52: ateapi.ActorTemplate.worker_selector:type_name -> ateapi.Selector + 48, // 53: ateapi.ActorTemplate.containers:type_name -> ateapi.Container + 54, // 54: ateapi.ActorTemplate.volumes:type_name -> ateapi.Volume + 47, // 55: ateapi.ActorTemplate.snapshot_config:type_name -> ateapi.SnapshotConfig + 46, // 56: ateapi.ActorTemplate.sandbox_config:type_name -> ateapi.SandboxConfig + 42, // 57: ateapi.ActorTemplate.resources:type_name -> ateapi.Resources + 45, // 58: ateapi.ActorTemplate.status:type_name -> ateapi.ActorTemplateStatus + 43, // 59: ateapi.Resources.limits:type_name -> ateapi.Limits + 40, // 60: ateapi.GoldenSnapshotStatus.golden_tag:type_name -> ateapi.ObjectRef + 145, // 61: ateapi.GoldenSnapshotStatus.take_golden_snapshot_at:type_name -> google.protobuf.Timestamp + 44, // 62: ateapi.ActorTemplateStatus.golden_snapshot_status:type_name -> ateapi.GoldenSnapshotStatus + 9, // 63: ateapi.SandboxConfig.sandbox_class:type_name -> ateapi.SandboxClass + 3, // 64: ateapi.SnapshotConfig.preferred_fidelity:type_name -> ateapi.SnapshotFidelity + 51, // 65: ateapi.Container.env:type_name -> ateapi.EnvVar + 52, // 66: ateapi.Container.wakeup_probe:type_name -> ateapi.ContainerWakeupProbe + 64, // 67: ateapi.Container.volume_mounts:type_name -> ateapi.VolumeMount + 49, // 68: ateapi.Container.security_context:type_name -> ateapi.SecurityContext + 42, // 69: ateapi.Container.resources:type_name -> ateapi.Resources + 50, // 70: ateapi.SecurityContext.capabilities:type_name -> ateapi.Capabilities + 53, // 71: ateapi.ContainerWakeupProbe.http_get:type_name -> ateapi.HTTPGetAction + 56, // 72: ateapi.Volume.durable_dir:type_name -> ateapi.DurableDirVolumeSource + 57, // 73: ateapi.Volume.external_volume_template:type_name -> ateapi.ExternalVolumeTemplate + 58, // 74: ateapi.Volume.external_volume_ref:type_name -> ateapi.ExternalVolumeRef + 59, // 75: ateapi.Volume.system_info:type_name -> ateapi.SystemInfoVolumeSource + 55, // 76: ateapi.Volume.image:type_name -> ateapi.ImageVolumeSource + 60, // 77: ateapi.SystemInfoVolumeSource.data_sources:type_name -> ateapi.SystemInfoDataSource + 61, // 78: ateapi.SystemInfoDataSource.actor_metadata:type_name -> ateapi.ActorMetadataDataSource + 63, // 79: ateapi.SystemInfoDataSource.trust_bundle:type_name -> ateapi.TrustBundleDataSource + 62, // 80: ateapi.ActorMetadataDataSource.items:type_name -> ateapi.ActorMetadataItem + 10, // 81: ateapi.ActorMetadataItem.field:type_name -> ateapi.ActorMetadataField + 39, // 82: ateapi.CreateAtespaceRequest.atespace:type_name -> ateapi.Atespace + 40, // 83: ateapi.GetAtespaceRequest.atespace:type_name -> ateapi.ObjectRef + 39, // 84: ateapi.ListAtespacesResponse.atespaces:type_name -> ateapi.Atespace + 40, // 85: ateapi.DeleteAtespaceRequest.atespace:type_name -> ateapi.ObjectRef + 107, // 86: ateapi.DeleteAtespaceRequest.options:type_name -> ateapi.DeleteOptions + 41, // 87: ateapi.CreateActorTemplateRequest.actor_template:type_name -> ateapi.ActorTemplate + 40, // 88: ateapi.GetActorTemplateRequest.actor_template:type_name -> ateapi.ObjectRef + 41, // 89: ateapi.ListActorTemplatesResponse.actor_templates:type_name -> ateapi.ActorTemplate + 40, // 90: ateapi.DeleteActorTemplateRequest.actor_template:type_name -> ateapi.ObjectRef + 107, // 91: ateapi.DeleteActorTemplateRequest.options:type_name -> ateapi.DeleteOptions + 40, // 92: ateapi.GetActorRequest.actor:type_name -> ateapi.ObjectRef + 20, // 93: ateapi.CreateActorRequest.actor:type_name -> ateapi.Actor + 20, // 94: ateapi.UpdateActorRequest.actor:type_name -> ateapi.Actor + 40, // 95: ateapi.SuspendActorRequest.actor:type_name -> ateapi.ObjectRef + 20, // 96: ateapi.SuspendActorResponse.actor:type_name -> ateapi.Actor + 40, // 97: ateapi.PauseActorRequest.actor:type_name -> ateapi.ObjectRef + 20, // 98: ateapi.PauseActorResponse.actor:type_name -> ateapi.Actor + 40, // 99: ateapi.ResumeActorRequest.actor:type_name -> ateapi.ObjectRef + 20, // 100: ateapi.ResumeActorResponse.actor:type_name -> ateapi.Actor + 40, // 101: ateapi.RevertActorRequest.actor:type_name -> ateapi.ObjectRef + 20, // 102: ateapi.RevertActorResponse.actor:type_name -> ateapi.Actor + 40, // 103: ateapi.DeleteActorRequest.actor:type_name -> ateapi.ObjectRef + 107, // 104: ateapi.DeleteActorRequest.options:type_name -> ateapi.DeleteOptions + 40, // 105: ateapi.GetActorEgressPolicyRequest.actor:type_name -> ateapi.ObjectRef + 40, // 106: ateapi.CreateActorEgressPolicyRequest.actor:type_name -> ateapi.ObjectRef + 21, // 107: ateapi.CreateActorEgressPolicyRequest.egress_policy:type_name -> ateapi.EgressPolicy + 40, // 108: ateapi.UpdateActorEgressPolicyRequest.actor:type_name -> ateapi.ObjectRef + 21, // 109: ateapi.UpdateActorEgressPolicyRequest.egress_policy:type_name -> ateapi.EgressPolicy + 40, // 110: ateapi.DeleteActorEgressPolicyRequest.actor:type_name -> ateapi.ObjectRef + 107, // 111: ateapi.DeleteActorEgressPolicyRequest.options:type_name -> ateapi.DeleteOptions + 40, // 112: ateapi.GetTagRequest.tag:type_name -> ateapi.ObjectRef + 40, // 113: ateapi.MintActorJWTRequest.actor:type_name -> ateapi.ObjectRef + 145, // 114: ateapi.MintActorJWTResponse.expires_at:type_name -> google.protobuf.Timestamp + 40, // 115: ateapi.MintActorCertificateRequest.actor:type_name -> ateapi.ObjectRef + 35, // 116: ateapi.ListTagsResponse.tags:type_name -> ateapi.Tag + 35, // 117: ateapi.CreateTagRequest.tag:type_name -> ateapi.Tag + 35, // 118: ateapi.UpdateTagRequest.tag:type_name -> ateapi.Tag + 40, // 119: ateapi.DeleteTagRequest.tag:type_name -> ateapi.ObjectRef + 107, // 120: ateapi.DeleteTagRequest.options:type_name -> ateapi.DeleteOptions + 36, // 121: ateapi.CreateExternalVolumeRequest.external_volume:type_name -> ateapi.ExternalVolume + 40, // 122: ateapi.GetExternalVolumeRequest.external_volume:type_name -> ateapi.ObjectRef + 36, // 123: ateapi.ListExternalVolumesResponse.external_volumes:type_name -> ateapi.ExternalVolume + 36, // 124: ateapi.UpdateExternalVolumeRequest.external_volume:type_name -> ateapi.ExternalVolume + 40, // 125: ateapi.DeleteExternalVolumeRequest.external_volume:type_name -> ateapi.ObjectRef + 107, // 126: ateapi.DeleteExternalVolumeRequest.options:type_name -> ateapi.DeleteOptions + 40, // 127: ateapi.ListWorkerActorAssignmentsRequest.worker:type_name -> ateapi.ObjectRef + 123, // 128: ateapi.ListWorkerActorAssignmentsResponse.actor_assignments:type_name -> ateapi.ActorAssignment + 119, // 129: ateapi.ListWorkersResponse.workers:type_name -> ateapi.Worker + 40, // 130: ateapi.GetWorkerRequest.worker:type_name -> ateapi.ObjectRef + 119, // 131: ateapi.CreateWorkerRequest.worker:type_name -> ateapi.Worker + 119, // 132: ateapi.UpdateWorkerRequest.worker:type_name -> ateapi.Worker + 40, // 133: ateapi.DeleteWorkerRequest.worker:type_name -> ateapi.ObjectRef + 107, // 134: ateapi.DeleteWorkerRequest.options:type_name -> ateapi.DeleteOptions + 40, // 135: ateapi.DrainWorkerRequest.worker:type_name -> ateapi.ObjectRef + 20, // 136: ateapi.ListActorsResponse.actors:type_name -> ateapi.Actor + 18, // 137: ateapi.Worker.metadata:type_name -> ateapi.ResourceMetadata + 143, // 138: ateapi.Worker.labels:type_name -> ateapi.Worker.LabelsEntry + 120, // 139: ateapi.Worker.status:type_name -> ateapi.WorkerStatus + 11, // 140: ateapi.WorkerStatus.state:type_name -> ateapi.WorkerState + 122, // 141: ateapi.WorkerStatus.capacity:type_name -> ateapi.WorkerResources + 122, // 142: ateapi.WorkerStatus.allocated:type_name -> ateapi.WorkerResources + 121, // 143: ateapi.WorkerStatus.hardware:type_name -> ateapi.HardwareIdentity + 144, // 144: ateapi.HardwareIdentity.attributes:type_name -> ateapi.HardwareIdentity.AttributesEntry + 42, // 145: ateapi.WorkerResources.resources:type_name -> ateapi.Resources + 18, // 146: ateapi.ActorAssignment.metadata:type_name -> ateapi.ResourceMetadata + 40, // 147: ateapi.ActorAssignment.actor:type_name -> ateapi.ObjectRef + 42, // 148: ateapi.ActorAssignment.resources:type_name -> ateapi.Resources + 40, // 149: ateapi.RegisterWorkerRequest.worker:type_name -> ateapi.ObjectRef + 122, // 150: ateapi.RegisterWorkerRequest.capacity:type_name -> ateapi.WorkerResources + 121, // 151: ateapi.RegisterWorkerRequest.hardware:type_name -> ateapi.HardwareIdentity + 119, // 152: ateapi.RegisterWorkerResponse.worker:type_name -> ateapi.Worker + 40, // 153: ateapi.MintAteomActorCertificateRequest.actor:type_name -> ateapi.ObjectRef + 40, // 154: ateapi.RequestActorSuspendRequest.worker:type_name -> ateapi.ObjectRef + 40, // 155: ateapi.RequestActorSuspendRequest.actor:type_name -> ateapi.ObjectRef + 20, // 156: ateapi.RequestActorSuspendResponse.actor:type_name -> ateapi.Actor + 18, // 157: ateapi.AccessPolicy.metadata:type_name -> ateapi.ResourceMetadata + 131, // 158: ateapi.AccessPolicy.bindings:type_name -> ateapi.Binding + 130, // 159: ateapi.CreateGlobalAccessPolicyRequest.access_policy:type_name -> ateapi.AccessPolicy + 130, // 160: ateapi.UpdateGlobalAccessPolicyRequest.access_policy:type_name -> ateapi.AccessPolicy + 40, // 161: ateapi.GetAtespaceAccessPolicyRequest.atespace:type_name -> ateapi.ObjectRef + 40, // 162: ateapi.CreateAtespaceAccessPolicyRequest.atespace:type_name -> ateapi.ObjectRef + 130, // 163: ateapi.CreateAtespaceAccessPolicyRequest.access_policy:type_name -> ateapi.AccessPolicy + 40, // 164: ateapi.UpdateAtespaceAccessPolicyRequest.atespace:type_name -> ateapi.ObjectRef + 130, // 165: ateapi.UpdateAtespaceAccessPolicyRequest.access_policy:type_name -> ateapi.AccessPolicy + 40, // 166: ateapi.DeleteAtespaceAccessPolicyRequest.atespace:type_name -> ateapi.ObjectRef + 107, // 167: ateapi.DeleteAtespaceAccessPolicyRequest.options:type_name -> ateapi.DeleteOptions + 75, // 168: ateapi.Control.GetActor:input_type -> ateapi.GetActorRequest + 76, // 169: ateapi.Control.CreateActor:input_type -> ateapi.CreateActorRequest + 77, // 170: ateapi.Control.UpdateActor:input_type -> ateapi.UpdateActorRequest + 78, // 171: ateapi.Control.SuspendActor:input_type -> ateapi.SuspendActorRequest + 80, // 172: ateapi.Control.PauseActor:input_type -> ateapi.PauseActorRequest + 82, // 173: ateapi.Control.ResumeActor:input_type -> ateapi.ResumeActorRequest + 84, // 174: ateapi.Control.RevertActor:input_type -> ateapi.RevertActorRequest + 86, // 175: ateapi.Control.DeleteActor:input_type -> ateapi.DeleteActorRequest + 87, // 176: ateapi.Control.GetActorEgressPolicy:input_type -> ateapi.GetActorEgressPolicyRequest + 88, // 177: ateapi.Control.CreateActorEgressPolicy:input_type -> ateapi.CreateActorEgressPolicyRequest + 89, // 178: ateapi.Control.UpdateActorEgressPolicy:input_type -> ateapi.UpdateActorEgressPolicyRequest + 90, // 179: ateapi.Control.DeleteActorEgressPolicy:input_type -> ateapi.DeleteActorEgressPolicyRequest + 92, // 180: ateapi.Control.MintActorJWT:input_type -> ateapi.MintActorJWTRequest + 94, // 181: ateapi.Control.MintActorCertificate:input_type -> ateapi.MintActorCertificateRequest + 98, // 182: ateapi.Control.CreateTag:input_type -> ateapi.CreateTagRequest + 91, // 183: ateapi.Control.GetTag:input_type -> ateapi.GetTagRequest + 96, // 184: ateapi.Control.ListTags:input_type -> ateapi.ListTagsRequest + 99, // 185: ateapi.Control.UpdateTag:input_type -> ateapi.UpdateTagRequest + 100, // 186: ateapi.Control.DeleteTag:input_type -> ateapi.DeleteTagRequest + 101, // 187: ateapi.Control.CreateExternalVolume:input_type -> ateapi.CreateExternalVolumeRequest + 102, // 188: ateapi.Control.GetExternalVolume:input_type -> ateapi.GetExternalVolumeRequest + 103, // 189: ateapi.Control.ListExternalVolumes:input_type -> ateapi.ListExternalVolumesRequest + 105, // 190: ateapi.Control.UpdateExternalVolume:input_type -> ateapi.UpdateExternalVolumeRequest + 106, // 191: ateapi.Control.DeleteExternalVolume:input_type -> ateapi.DeleteExternalVolumeRequest + 110, // 192: ateapi.Control.ListWorkers:input_type -> ateapi.ListWorkersRequest + 112, // 193: ateapi.Control.GetWorker:input_type -> ateapi.GetWorkerRequest + 113, // 194: ateapi.Control.CreateWorker:input_type -> ateapi.CreateWorkerRequest + 114, // 195: ateapi.Control.UpdateWorker:input_type -> ateapi.UpdateWorkerRequest + 115, // 196: ateapi.Control.DeleteWorker:input_type -> ateapi.DeleteWorkerRequest + 116, // 197: ateapi.Control.DrainWorker:input_type -> ateapi.DrainWorkerRequest + 108, // 198: ateapi.Control.ListWorkerActorAssignments:input_type -> ateapi.ListWorkerActorAssignmentsRequest + 117, // 199: ateapi.Control.ListActors:input_type -> ateapi.ListActorsRequest + 65, // 200: ateapi.Control.CreateAtespace:input_type -> ateapi.CreateAtespaceRequest + 66, // 201: ateapi.Control.GetAtespace:input_type -> ateapi.GetAtespaceRequest + 67, // 202: ateapi.Control.ListAtespaces:input_type -> ateapi.ListAtespacesRequest + 69, // 203: ateapi.Control.DeleteAtespace:input_type -> ateapi.DeleteAtespaceRequest + 70, // 204: ateapi.Control.CreateActorTemplate:input_type -> ateapi.CreateActorTemplateRequest + 71, // 205: ateapi.Control.GetActorTemplate:input_type -> ateapi.GetActorTemplateRequest + 72, // 206: ateapi.Control.ListActorTemplates:input_type -> ateapi.ListActorTemplatesRequest + 74, // 207: ateapi.Control.DeleteActorTemplate:input_type -> ateapi.DeleteActorTemplateRequest + 132, // 208: ateapi.Control.GetGlobalAccessPolicy:input_type -> ateapi.GetGlobalAccessPolicyRequest + 133, // 209: ateapi.Control.CreateGlobalAccessPolicy:input_type -> ateapi.CreateGlobalAccessPolicyRequest + 134, // 210: ateapi.Control.UpdateGlobalAccessPolicy:input_type -> ateapi.UpdateGlobalAccessPolicyRequest + 135, // 211: ateapi.Control.GetAtespaceAccessPolicy:input_type -> ateapi.GetAtespaceAccessPolicyRequest + 136, // 212: ateapi.Control.CreateAtespaceAccessPolicy:input_type -> ateapi.CreateAtespaceAccessPolicyRequest + 137, // 213: ateapi.Control.UpdateAtespaceAccessPolicy:input_type -> ateapi.UpdateAtespaceAccessPolicyRequest + 138, // 214: ateapi.Control.DeleteAtespaceAccessPolicy:input_type -> ateapi.DeleteAtespaceAccessPolicyRequest + 124, // 215: ateapi.WorkerService.RegisterWorker:input_type -> ateapi.RegisterWorkerRequest + 126, // 216: ateapi.WorkerService.MintAteomActorCertificate:input_type -> ateapi.MintAteomActorCertificateRequest + 128, // 217: ateapi.WorkerService.RequestActorSuspend:input_type -> ateapi.RequestActorSuspendRequest + 20, // 218: ateapi.Control.GetActor:output_type -> ateapi.Actor + 20, // 219: ateapi.Control.CreateActor:output_type -> ateapi.Actor + 20, // 220: ateapi.Control.UpdateActor:output_type -> ateapi.Actor + 79, // 221: ateapi.Control.SuspendActor:output_type -> ateapi.SuspendActorResponse + 81, // 222: ateapi.Control.PauseActor:output_type -> ateapi.PauseActorResponse + 83, // 223: ateapi.Control.ResumeActor:output_type -> ateapi.ResumeActorResponse + 85, // 224: ateapi.Control.RevertActor:output_type -> ateapi.RevertActorResponse + 20, // 225: ateapi.Control.DeleteActor:output_type -> ateapi.Actor + 21, // 226: ateapi.Control.GetActorEgressPolicy:output_type -> ateapi.EgressPolicy + 21, // 227: ateapi.Control.CreateActorEgressPolicy:output_type -> ateapi.EgressPolicy + 21, // 228: ateapi.Control.UpdateActorEgressPolicy:output_type -> ateapi.EgressPolicy + 21, // 229: ateapi.Control.DeleteActorEgressPolicy:output_type -> ateapi.EgressPolicy + 93, // 230: ateapi.Control.MintActorJWT:output_type -> ateapi.MintActorJWTResponse + 95, // 231: ateapi.Control.MintActorCertificate:output_type -> ateapi.MintActorCertificateResponse + 35, // 232: ateapi.Control.CreateTag:output_type -> ateapi.Tag + 35, // 233: ateapi.Control.GetTag:output_type -> ateapi.Tag + 97, // 234: ateapi.Control.ListTags:output_type -> ateapi.ListTagsResponse + 35, // 235: ateapi.Control.UpdateTag:output_type -> ateapi.Tag + 35, // 236: ateapi.Control.DeleteTag:output_type -> ateapi.Tag + 36, // 237: ateapi.Control.CreateExternalVolume:output_type -> ateapi.ExternalVolume + 36, // 238: ateapi.Control.GetExternalVolume:output_type -> ateapi.ExternalVolume + 104, // 239: ateapi.Control.ListExternalVolumes:output_type -> ateapi.ListExternalVolumesResponse + 36, // 240: ateapi.Control.UpdateExternalVolume:output_type -> ateapi.ExternalVolume + 36, // 241: ateapi.Control.DeleteExternalVolume:output_type -> ateapi.ExternalVolume + 111, // 242: ateapi.Control.ListWorkers:output_type -> ateapi.ListWorkersResponse + 119, // 243: ateapi.Control.GetWorker:output_type -> ateapi.Worker + 119, // 244: ateapi.Control.CreateWorker:output_type -> ateapi.Worker + 119, // 245: ateapi.Control.UpdateWorker:output_type -> ateapi.Worker + 119, // 246: ateapi.Control.DeleteWorker:output_type -> ateapi.Worker + 119, // 247: ateapi.Control.DrainWorker:output_type -> ateapi.Worker + 109, // 248: ateapi.Control.ListWorkerActorAssignments:output_type -> ateapi.ListWorkerActorAssignmentsResponse + 118, // 249: ateapi.Control.ListActors:output_type -> ateapi.ListActorsResponse + 39, // 250: ateapi.Control.CreateAtespace:output_type -> ateapi.Atespace + 39, // 251: ateapi.Control.GetAtespace:output_type -> ateapi.Atespace + 68, // 252: ateapi.Control.ListAtespaces:output_type -> ateapi.ListAtespacesResponse + 39, // 253: ateapi.Control.DeleteAtespace:output_type -> ateapi.Atespace + 41, // 254: ateapi.Control.CreateActorTemplate:output_type -> ateapi.ActorTemplate + 41, // 255: ateapi.Control.GetActorTemplate:output_type -> ateapi.ActorTemplate + 73, // 256: ateapi.Control.ListActorTemplates:output_type -> ateapi.ListActorTemplatesResponse + 41, // 257: ateapi.Control.DeleteActorTemplate:output_type -> ateapi.ActorTemplate + 130, // 258: ateapi.Control.GetGlobalAccessPolicy:output_type -> ateapi.AccessPolicy + 130, // 259: ateapi.Control.CreateGlobalAccessPolicy:output_type -> ateapi.AccessPolicy + 130, // 260: ateapi.Control.UpdateGlobalAccessPolicy:output_type -> ateapi.AccessPolicy + 130, // 261: ateapi.Control.GetAtespaceAccessPolicy:output_type -> ateapi.AccessPolicy + 130, // 262: ateapi.Control.CreateAtespaceAccessPolicy:output_type -> ateapi.AccessPolicy + 130, // 263: ateapi.Control.UpdateAtespaceAccessPolicy:output_type -> ateapi.AccessPolicy + 130, // 264: ateapi.Control.DeleteAtespaceAccessPolicy:output_type -> ateapi.AccessPolicy + 125, // 265: ateapi.WorkerService.RegisterWorker:output_type -> ateapi.RegisterWorkerResponse + 127, // 266: ateapi.WorkerService.MintAteomActorCertificate:output_type -> ateapi.MintAteomActorCertificateResponse + 129, // 267: ateapi.WorkerService.RequestActorSuspend:output_type -> ateapi.RequestActorSuspendResponse + 218, // [218:268] is the sub-list for method output_type + 168, // [168:218] is the sub-list for method input_type + 168, // [168:168] is the sub-list for extension type_name + 168, // [168:168] is the sub-list for extension extendee + 0, // [0:168] is the sub-list for field type_name } func init() { file_ateapi_proto_init() } @@ -10154,7 +10261,7 @@ func file_ateapi_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: unsafe.Slice(unsafe.StringData(file_ateapi_proto_rawDesc), len(file_ateapi_proto_rawDesc)), NumEnums: 13, - NumMessages: 130, + NumMessages: 132, NumExtensions: 0, NumServices: 2, }, diff --git a/pkg/proto/ateapipb/ateapi.proto b/pkg/proto/ateapipb/ateapi.proto index 4217771fa4..4f5273c094 100644 --- a/pkg/proto/ateapipb/ateapi.proto +++ b/pkg/proto/ateapipb/ateapi.proto @@ -479,6 +479,15 @@ message ActorVolumeStatus { // +k8s:eachKey=+k8s:maxLength=128 // +k8s:eachVal=+k8s:maxLength=256 map volume_context = 5; + + // external_volume_name names the ExternalVolume this mount references, in the + // actor's atespace. Empty when the actor owns the volume itself. + // + // +k8s:optional + // +k8s:format=k8s-short-name + // +k8s:update=NoModify + // +k8s:update=NoUnset + string external_volume_name = 6; } message Actor { @@ -516,6 +525,17 @@ message Actor { // // +k8s:optional ActorStatus status = 7; + + // external_volume_bindings maps each unnamed external_volume_ref in the + // template, by volume name, to the ExternalVolume this actor mounts. Every + // unnamed ref must be bound; a named ref cannot be rebound. Set at creation. + // + // +k8s:optional + // +k8s:maxProperties=32 + // +k8s:eachKey=+k8s:format=k8s-short-name + // +k8s:eachVal=+k8s:format=k8s-short-name + // +k8s:immutable + map external_volume_bindings = 8; } // EgressPolicy is an egress policy resource nested under an Actor. An Actor has @@ -1493,8 +1513,8 @@ message Volume { // +k8s:format=k8s-short-name string name = 1; - // Exactly one of durable_dir / external_volume_template / image / - // system_info must be set. + // Exactly one of durable_dir / external_volume_template / + // external_volume_ref / image / system_info must be set. // // +k8s:optional // +k8s:unionMember @@ -1504,6 +1524,12 @@ message Volume { // +k8s:unionMember ExternalVolumeTemplate external_volume_template = 3; + // external_volume_ref mounts an ExternalVolume that already exists. + // + // +k8s:optional + // +k8s:unionMember + ExternalVolumeRef external_volume_ref = 4; + // +k8s:optional // +k8s:unionMember SystemInfoVolumeSource system_info = 5; @@ -1551,6 +1577,17 @@ message ExternalVolumeTemplate { string storage_class_name = 2; } +// ExternalVolumeRef mounts an ExternalVolume in the actor's atespace. The +// volume outlives the actor, so several actors can mount it in turn. +message ExternalVolumeRef { + // name of the ExternalVolume. Left empty, the actor names it at creation in + // Actor.external_volume_bindings. + // + // +k8s:optional + // +k8s:format=k8s-short-name + string name = 1; +} + // SystemInfoVolumeSource is a read-only volume of substrate-generated // per-actor files (identity fields, projected trust bundles), regenerated by // atelet on every Run/Restore. From 41f90e9216bfb55cdbc1f5225a5aebecbd9cdbf1 Mon Sep 17 00:00:00 2001 From: Elijah Rodriguez Date: Tue, 13 Oct 2026 08:52:37 -0700 Subject: [PATCH 3/3] ateapi: cold-boot actors whose template references an ExternalVolume The golden actor warms up against a local empty directory in place of a shared volume, but runsc derives the disable_file_handle_sharing mount option from the bind source's filesystem and refuses a restore whose mount options differ from the checkpoint's. On NFS the first resume of every such actor therefore failed with "Mounts" does not match across checkpoint restore. Actors created from a template with an external_volume_ref no longer seed from the golden tag: the first resume boots from the image and later resumes restore the actor's own snapshot, which was taken over the real volume. An explicit source tag is refused for these templates. Golden restores for shared volumes remain follow-up work, tracked by TODO(shared-volumes). Co-Authored-By: Claude Fable 5.1 --- cmd/ateapi/internal/controlapi/actor.go | 12 +- .../controlapi/external_volume_golden_test.go | 45 ++++++ .../controlapi/external_volume_refs.go | 9 ++ .../external_volume_golden_test.go | 151 ++++++++++++++++++ docs/csi-volumes.md | 15 +- pkg/proto/ateapipb/ateapi.pb.go | 4 + pkg/proto/ateapipb/ateapi.proto | 4 + 7 files changed, 235 insertions(+), 5 deletions(-) create mode 100644 cmd/ateapi/internal/controlapi/external_volume_golden_test.go create mode 100644 cmd/ateapi/internal/controlapi/functionaltest/external_volume_golden_test.go diff --git a/cmd/ateapi/internal/controlapi/actor.go b/cmd/ateapi/internal/controlapi/actor.go index 481ac02595..fdc00b020d 100644 --- a/cmd/ateapi/internal/controlapi/actor.go +++ b/cmd/ateapi/internal/controlapi/actor.go @@ -89,15 +89,21 @@ func (s *ServiceImpl) CreateActor(ctx context.Context, inActor *ateapipb.Actor) // Resolve the explicit tag, or freeze the template's current golden default. tagRef := inActor.GetSourceTag() - if tagRef == nil { - tagRef = template.GetStatus().GetGoldenSnapshotStatus().GetGoldenTag() - } else { + switch { + case tagRef != nil: for _, volume := range template.GetVolumes() { if volume.GetExternalVolumeTemplate() != nil { // TODO: Permit cloning after CSI volume snapshots are supported. return nil, apierror.FailedPrecondition("Tag cloning does not support ActorTemplates with external volumes") } + if volume.GetExternalVolumeRef() != nil { + return nil, apierror.FailedPrecondition("Tag cloning does not support ActorTemplates that reference an ExternalVolume") + } } + case templateHasExternalVolumeRef(template): + // TODO(shared-volumes): restore from the golden once checkpoint and restore mount options agree for external volume refs; see docs/csi-volumes.md. + default: + tagRef = template.GetStatus().GetGoldenSnapshotStatus().GetGoldenTag() } var sourceTag *ateapipb.Tag if tagRef != nil { diff --git a/cmd/ateapi/internal/controlapi/external_volume_golden_test.go b/cmd/ateapi/internal/controlapi/external_volume_golden_test.go new file mode 100644 index 0000000000..60fa32d5ab --- /dev/null +++ b/cmd/ateapi/internal/controlapi/external_volume_golden_test.go @@ -0,0 +1,45 @@ +// 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 controlapi + +import ( + "testing" + + "github.com/agent-substrate/substrate/pkg/proto/ateapipb" +) + +func TestTemplateHasExternalVolumeRef(t *testing.T) { + tests := []struct { + name string + volumes []*ateapipb.Volume + want bool + }{ + {name: "no volumes"}, + {name: "durable dir only", volumes: []*ateapipb.Volume{{Name: "home", DurableDir: &ateapipb.DurableDirVolumeSource{}}}}, + {name: "external volume template", volumes: []*ateapipb.Volume{{Name: "owned", ExternalVolumeTemplate: &ateapipb.ExternalVolumeTemplate{StorageClassName: "standard"}}}}, + {name: "named ref", volumes: []*ateapipb.Volume{{Name: "shared", ExternalVolumeRef: &ateapipb.ExternalVolumeRef{Name: "ctx"}}}, want: true}, + {name: "unnamed ref after other volumes", volumes: []*ateapipb.Volume{ + {Name: "home", DurableDir: &ateapipb.DurableDirVolumeSource{}}, + {Name: "shared", ExternalVolumeRef: &ateapipb.ExternalVolumeRef{}}, + }, want: true}, + } + for _, tc := range tests { + t.Run(tc.name, func(t *testing.T) { + if got := templateHasExternalVolumeRef(&ateapipb.ActorTemplate{Volumes: tc.volumes}); got != tc.want { + t.Errorf("templateHasExternalVolumeRef() = %v, want %v", got, tc.want) + } + }) + } +} diff --git a/cmd/ateapi/internal/controlapi/external_volume_refs.go b/cmd/ateapi/internal/controlapi/external_volume_refs.go index d8833c0b70..dfc435e986 100644 --- a/cmd/ateapi/internal/controlapi/external_volume_refs.go +++ b/cmd/ateapi/internal/controlapi/external_volume_refs.go @@ -37,6 +37,15 @@ type externalVolumeDeleter interface { DeleteExternalVolume(ctx context.Context, volumeRef resources.ExternalVolumeRef, precondition store.DeletePreconditions) (*ateapipb.ExternalVolume, error) } +func templateHasExternalVolumeRef(template *ateapipb.ActorTemplate) bool { + for _, vol := range template.GetVolumes() { + if vol.GetExternalVolumeRef() != nil { + return true + } + } + return false +} + // resolveExternalVolumeRefs checks the actor's bindings against the template // and returns a mount for every ExternalVolume the actor references. func resolveExternalVolumeRefs(ctx context.Context, st externalVolumeRefStore, actor *ateapipb.Actor, template *ateapipb.ActorTemplate) ([]*ateapipb.ActorVolumeStatus, error) { diff --git a/cmd/ateapi/internal/controlapi/functionaltest/external_volume_golden_test.go b/cmd/ateapi/internal/controlapi/functionaltest/external_volume_golden_test.go new file mode 100644 index 0000000000..07c2c8da7c --- /dev/null +++ b/cmd/ateapi/internal/controlapi/functionaltest/external_volume_golden_test.go @@ -0,0 +1,151 @@ +// 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 functionaltest + +import ( + "context" + "testing" + + "github.com/agent-substrate/substrate/pkg/proto/ateapipb" + "google.golang.org/grpc/codes" +) + +func resetAteletCalls(tc *testContext) { + tc.fakeAtelet.Lock.Lock() + defer tc.fakeAtelet.Lock.Unlock() + tc.fakeAtelet.RunCalled, tc.fakeAtelet.RunRequest = false, nil + tc.fakeAtelet.RestoreCalled, tc.fakeAtelet.RestoreRequest = false, nil +} + +func ateletCalls(tc *testContext) (run, restore bool) { + tc.fakeAtelet.Lock.Lock() + defer tc.fakeAtelet.Lock.Unlock() + return tc.fakeAtelet.RunCalled, tc.fakeAtelet.RestoreCalled +} + +func getActor(t *testing.T, tc *testContext, name string) *ateapipb.Actor { + t.Helper() + actor, err := tc.client.GetActor(context.Background(), &ateapipb.GetActorRequest{ + Actor: &ateapipb.ObjectRef{Atespace: testAtespace, Name: name}, + }) + if err != nil { + t.Fatalf("GetActor(%s) failed: %v", name, err) + } + return actor +} + +func TestExternalVolumeRef_ColdBootsThenRestoresOwnSnapshot(t *testing.T) { + ns := namespaceForTest("ns-extvol-coldboot") + tc, _ := setupExternalVolumeTest(t, ns) + defer tc.cleanup() + + createExternalVolume(t, tc, "shared", ateapipb.DeleteTrigger_DELETE_TRIGGER_MANUAL) + tmpl := createTemplateWithVolumes(t, tc, ns, + []*ateapipb.Volume{{Name: "work", ExternalVolumeRef: &ateapipb.ExternalVolumeRef{Name: "shared"}}}, + []*ateapipb.VolumeMount{{Name: "work", MountPath: "/mnt/work"}}) + if tmpl.GetStatus().GetGoldenSnapshotStatus().GetGoldenTag() == nil { + t.Fatal("test template has no golden tag; the case needs one to prove it is bypassed") + } + workerName := createWorkerPod(t, tc, ns, "worker-1", "node1", "pool1") + ctx := context.Background() + ref := &ateapipb.ObjectRef{Atespace: testAtespace, Name: "borrower"} + + createBorrowingActor(t, tc, "borrower", nil) + if snaps := getActor(t, tc, "borrower").GetStatus().GetSnapshots(); len(snaps) != 0 { + t.Fatalf("new actor carries snapshots %v, want none: it must not seed from the golden", snaps) + } + + waitForWorkerAvailable(t, tc, workerName) + resetAteletCalls(tc) + if _, err := tc.client.ResumeActor(ctx, &ateapipb.ResumeActorRequest{Actor: ref}); err != nil { + t.Fatalf("first ResumeActor failed: %v", err) + } + if run, restore := ateletCalls(tc); !run || restore { + t.Fatalf("first resume: Run=%v Restore=%v, want a cold boot through Run", run, restore) + } + + if _, err := tc.client.SuspendActor(ctx, &ateapipb.SuspendActorRequest{Actor: ref}); err != nil { + t.Fatalf("SuspendActor failed: %v", err) + } + own := durableSnapshotURI(getActor(t, tc, "borrower").GetStatus()) + if own == "" || own == goldenSnapshotURI(t) { + t.Fatalf("snapshot after suspend = %q, want the actor's own", own) + } + + waitForWorkerAvailable(t, tc, workerName) + resetAteletCalls(tc) + if _, err := tc.client.ResumeActor(ctx, &ateapipb.ResumeActorRequest{Actor: ref}); err != nil { + t.Fatalf("second ResumeActor failed: %v", err) + } + if run, restore := ateletCalls(tc); run || !restore { + t.Fatalf("second resume: Run=%v Restore=%v, want a restore", run, restore) + } + if got := tc.fakeAtelet.lastRestoreRequest().GetExternalConfig().GetSnapshotUri(); got != own { + t.Errorf("second resume restored %q, want the actor's own snapshot %q", got, own) + } +} + +func TestExternalVolumeRef_RejectsSourceTag(t *testing.T) { + ns := namespaceForTest("ns-extvol-sourcetag") + tc, _ := setupExternalVolumeTest(t, ns) + defer tc.cleanup() + + createExternalVolume(t, tc, "shared", ateapipb.DeleteTrigger_DELETE_TRIGGER_MANUAL) + tmpl := createTemplateWithVolumes(t, tc, ns, + []*ateapipb.Volume{{Name: "work", ExternalVolumeRef: &ateapipb.ExternalVolumeRef{Name: "shared"}}}, + []*ateapipb.VolumeMount{{Name: "work", MountPath: "/mnt/work"}}) + + _, err := tc.client.CreateActor(context.Background(), &ateapipb.CreateActorRequest{Actor: &ateapipb.Actor{ + Metadata: &ateapipb.ResourceMetadata{Atespace: testAtespace, Name: "clone"}, + ActorTemplate: &ateapipb.ObjectRef{Atespace: testAtespace, Name: "tmpl1"}, + SourceTag: tmpl.GetStatus().GetGoldenSnapshotStatus().GetGoldenTag(), + }}) + assertGrpcError(t, err, codes.FailedPrecondition, "Tag cloning does not support ActorTemplates that reference an ExternalVolume") +} + +func TestExternalVolumeTemplate_FirstResumeRestoresGolden(t *testing.T) { + ns := namespaceForTest("ns-extvol-owned-golden") + tc, _ := setupExternalVolumeTest(t, ns) + defer tc.cleanup() + + createTemplateWithVolumes(t, tc, ns, + []*ateapipb.Volume{{Name: "work", ExternalVolumeTemplate: &ateapipb.ExternalVolumeTemplate{StorageClassName: "standard", Capacity: "1Gi"}}}, + []*ateapipb.VolumeMount{{Name: "work", MountPath: "/mnt/work"}}) + workerName := createWorkerPod(t, tc, ns, "worker-1", "node1", "pool1") + ctx := context.Background() + ref := &ateapipb.ObjectRef{Atespace: testAtespace, Name: "owner"} + + if _, err := tc.client.CreateActor(ctx, &ateapipb.CreateActorRequest{Actor: &ateapipb.Actor{ + Metadata: &ateapipb.ResourceMetadata{Atespace: testAtespace, Name: "owner"}, + ActorTemplate: &ateapipb.ObjectRef{Atespace: testAtespace, Name: "tmpl1"}, + }}); err != nil { + t.Fatalf("CreateActor failed: %v", err) + } + if got := durableSnapshotURI(getActor(t, tc, "owner").GetStatus()); got != goldenSnapshotURI(t) { + t.Fatalf("new actor snapshot = %q, want the golden %q", got, goldenSnapshotURI(t)) + } + + waitForWorkerAvailable(t, tc, workerName) + resetAteletCalls(tc) + if _, err := tc.client.ResumeActor(ctx, &ateapipb.ResumeActorRequest{Actor: ref}); err != nil { + t.Fatalf("ResumeActor failed: %v", err) + } + if run, restore := ateletCalls(tc); run || !restore { + t.Fatalf("first resume: Run=%v Restore=%v, want a restore from the golden", run, restore) + } + if got := tc.fakeAtelet.lastRestoreRequest().GetExternalConfig().GetSnapshotUri(); got != goldenSnapshotURI(t) { + t.Errorf("first resume restored %q, want the golden %q", got, goldenSnapshotURI(t)) + } +} diff --git a/docs/csi-volumes.md b/docs/csi-volumes.md index 7242bda436..0df69c0dcc 100644 --- a/docs/csi-volumes.md +++ b/docs/csi-volumes.md @@ -229,5 +229,16 @@ kubectl ate create actor consumer-42 -a demo --template consumer --volume shared ``` Bindings are validated and recorded when the actor is created and cannot change -afterwards. Golden actors never reference a shared volume; they warm up against -an empty directory at the same mount path. +afterwards. + +The golden snapshot is not used for templates with an `externalVolumeRef`. The +first resume of such an actor is a cold boot from the image, and later resumes +restore the actor's own snapshot, which was taken over the real volume. An +explicit `sourceTag` is refused at actor creation. The reason is in gVisor: +the golden actor warms up against a local empty directory at the mount path, +but runsc derives the `disable_file_handle_sharing` mount option from the bind +source's filesystem (NFS and FUSE get it, local disks do not) and refuses a +restore whose mount options differ from the checkpoint's. Supporting golden +restores here is follow-up work; the candidate approaches are a golden actor +that warms up on a scratch volume from the same driver, or an upstream runsc +change that excludes host-derived mount options from restore validation. diff --git a/pkg/proto/ateapipb/ateapi.pb.go b/pkg/proto/ateapipb/ateapi.pb.go index dc906583ed..704120a2a5 100644 --- a/pkg/proto/ateapipb/ateapi.pb.go +++ b/pkg/proto/ateapipb/ateapi.pb.go @@ -4374,6 +4374,10 @@ func (x *ExternalVolumeTemplate) GetStorageClassName() string { // ExternalVolumeRef mounts an ExternalVolume in the actor's atespace. The // volume outlives the actor, so several actors can mount it in turn. +// +// Actors created from a template with an ExternalVolumeRef do not start from +// the template's golden snapshot: the first resume boots from the image, and +// later resumes restore the actor's own snapshot. type ExternalVolumeRef struct { state protoimpl.MessageState `protogen:"open.v1"` // name of the ExternalVolume. Left empty, the actor names it at creation in diff --git a/pkg/proto/ateapipb/ateapi.proto b/pkg/proto/ateapipb/ateapi.proto index 4f5273c094..15777ff8a7 100644 --- a/pkg/proto/ateapipb/ateapi.proto +++ b/pkg/proto/ateapipb/ateapi.proto @@ -1579,6 +1579,10 @@ message ExternalVolumeTemplate { // ExternalVolumeRef mounts an ExternalVolume in the actor's atespace. The // volume outlives the actor, so several actors can mount it in turn. +// +// Actors created from a template with an ExternalVolumeRef do not start from +// the template's golden snapshot: the first resume boots from the image, and +// later resumes restore the actor's own snapshot. message ExternalVolumeRef { // name of the ExternalVolume. Left empty, the actor names it at creation in // Actor.external_volume_bindings.