From 0adaa55c8e91d1f186409feb0a785f15e1b26166 Mon Sep 17 00:00:00 2001 From: Haven Xia Date: Thu, 17 Sep 2026 16:28:34 -0700 Subject: [PATCH] atelet: hand ateom the actor directories in each RPC atelet and both ateoms derive the per-actor directories (bundles, runsc state, pid files, checkpoint and restore state, durable-dir, system-info and CSI volume roots) from the actor UID through the same package, internal/ateompath. Add an ActorDirs message to RunWorkloadRequest, RestoreWorkloadRequest, CheckpointWorkloadRequest and TerminateWorkloadRequest, and have atelet fill it with the directories it prepared. --- cmd/atelet/lifecycle_test.go | 40 ++- cmd/atelet/main.go | 20 ++ cmd/atelet/main_test.go | 29 ++ internal/proto/ateompb/ateom.pb.go | 470 ++++++++++++++++++++--------- internal/proto/ateompb/ateom.proto | 28 ++ 5 files changed, 433 insertions(+), 154 deletions(-) diff --git a/cmd/atelet/lifecycle_test.go b/cmd/atelet/lifecycle_test.go index ed27fa9eb0..ca88fe7948 100644 --- a/cmd/atelet/lifecycle_test.go +++ b/cmd/atelet/lifecycle_test.go @@ -28,6 +28,7 @@ import ( "github.com/agent-substrate/substrate/internal/proto/ateletpb" "github.com/agent-substrate/substrate/internal/proto/ateompb" "google.golang.org/grpc" + "google.golang.org/protobuf/proto" ) // useTempNodeDirs roots atelet's on-node state in temp directories so a test @@ -45,24 +46,36 @@ func useTempNodeDirs(t *testing.T) { } // fakeAteom is a fake ateom in a worker pod. It writes the files a -// real checkpoint would leave in the checkpoint-state dir, and reads back -// what a restore was handed. +// real checkpoint would leave in the checkpoint dir, and reads back what a +// restore was handed. Like a real ateom it takes every actor directory from +// the request, never from ateompath. type fakeAteom struct { ateompb.UnimplementedAteomServer // snapshotFiles are written at checkpoint and reported back to atelet as // the exact set the snapshot consists of. snapshotFiles map[string]string - // restored holds the file contents staged into the restore-state dir by - // the most recent RestoreWorkload. + // restored holds the file contents staged into the restore dir by the + // most recent RestoreWorkload. restored map[string]string + // dirs records the ActorDirs each RPC arrived with, by RPC name. + dirs map[string]*ateompb.ActorDirs } -func (f *fakeAteom) RunWorkload(context.Context, *ateompb.RunWorkloadRequest) (*ateompb.RunWorkloadResponse, error) { +func (f *fakeAteom) recordDirs(rpc string, dirs *ateompb.ActorDirs) { + if f.dirs == nil { + f.dirs = map[string]*ateompb.ActorDirs{} + } + f.dirs[rpc] = dirs +} + +func (f *fakeAteom) RunWorkload(_ context.Context, req *ateompb.RunWorkloadRequest) (*ateompb.RunWorkloadResponse, error) { + f.recordDirs("RunWorkload", req.GetActorDirs()) return &ateompb.RunWorkloadResponse{}, nil } func (f *fakeAteom) CheckpointWorkload(_ context.Context, req *ateompb.CheckpointWorkloadRequest) (*ateompb.CheckpointWorkloadResponse, error) { - dir := ateompath.CheckpointStateDir(req.GetActorUid()) + f.recordDirs("CheckpointWorkload", req.GetActorDirs()) + dir := req.GetActorDirs().GetCheckpointDir() names := make([]string, 0, len(f.snapshotFiles)) for name, body := range f.snapshotFiles { if err := os.WriteFile(filepath.Join(dir, name), []byte(body), 0o600); err != nil { @@ -74,7 +87,8 @@ func (f *fakeAteom) CheckpointWorkload(_ context.Context, req *ateompb.Checkpoin } func (f *fakeAteom) RestoreWorkload(_ context.Context, req *ateompb.RestoreWorkloadRequest) (*ateompb.RestoreWorkloadResponse, error) { - dir := ateompath.RestoreStateDir(req.GetActorUid()) + f.recordDirs("RestoreWorkload", req.GetActorDirs()) + dir := req.GetActorDirs().GetRestoreDir() f.restored = map[string]string{} for name := range f.snapshotFiles { body, err := os.ReadFile(filepath.Join(dir, name)) @@ -86,7 +100,8 @@ func (f *fakeAteom) RestoreWorkload(_ context.Context, req *ateompb.RestoreWorkl return &ateompb.RestoreWorkloadResponse{}, nil } -func (f *fakeAteom) TerminateWorkload(context.Context, *ateompb.TerminateWorkloadRequest) (*ateompb.TerminateWorkloadResponse, error) { +func (f *fakeAteom) TerminateWorkload(_ context.Context, req *ateompb.TerminateWorkloadRequest) (*ateompb.TerminateWorkloadResponse, error) { + f.recordDirs("TerminateWorkload", req.GetActorDirs()) return &ateompb.TerminateWorkloadResponse{}, nil } @@ -231,6 +246,15 @@ func TestLocalSnapshotGC(t *testing.T) { t.Fatalf("Terminate: %v", err) } + // Every RPC hands ateom the same directory set; the fake already relied + // on checkpoint_dir and restore_dir above to place and find the snapshot. + want := actorDirsFor(actorUID) + for _, rpc := range []string{"RunWorkload", "CheckpointWorkload", "RestoreWorkload", "TerminateWorkload"} { + if got := ateom.dirs[rpc]; !proto.Equal(got, want) { + t.Errorf("%s carried actor dirs %v, want %v", rpc, got, want) + } + } + localDir := ateompath.LocalCheckpointsDir(actorUID) if _, err := os.Stat(localDir); !os.IsNotExist(err) { leaked, _ := filepath.Glob(filepath.Join(localDir, "*", "*")) diff --git a/cmd/atelet/main.go b/cmd/atelet/main.go index 6155e49aa0..0b88597605 100644 --- a/cmd/atelet/main.go +++ b/cmd/atelet/main.go @@ -539,6 +539,7 @@ func (s *AteomHerder) Run(ctx context.Context, req *ateletpb.RunRequest) (resp * RuntimeAssetPaths: assetPaths, Spec: spec, ActorUid: actorUID, + ActorDirs: actorDirsFor(actorUID), EgressGateway: toAteomEgressGateway(req.GetEgressGateway()), CpuMilli: req.GetCpuMilli(), MemoryBytes: req.GetMemoryBytes(), @@ -658,6 +659,7 @@ func (s *AteomHerder) Checkpoint(ctx context.Context, req *ateletpb.CheckpointRe Spec: spec, Scope: toAteomSnapshotScope(req.GetScope()), ActorUid: actorUID, + ActorDirs: actorDirsFor(actorUID), }) dAteom = time.Since(tAteom) if err != nil { @@ -1237,6 +1239,7 @@ func (s *AteomHerder) Restore(ctx context.Context, req *ateletpb.RestoreRequest) Spec: spec, Scope: toAteomSnapshotScope(req.GetScope()), ActorUid: req.GetActorUid(), + ActorDirs: actorDirsFor(actorUID), EgressGateway: toAteomEgressGateway(req.GetEgressGateway()), CpuMilli: req.GetCpuMilli(), MemoryBytes: req.GetMemoryBytes(), @@ -1304,6 +1307,7 @@ func (s *AteomHerder) Terminate(ctx context.Context, req *ateletpb.TerminateRequ ActorTemplateName: req.GetActorTemplateName(), RunscPath: runscPathFor(assetPaths), Spec: spec, + ActorDirs: actorDirsFor(actorUID), }); err != nil { if status.Code(err) == codes.NotFound { slog.InfoContext(ctx, "workload not found on ateom during terminate", slog.Any("actor", actorRef), slog.String("actorUID", actorUID)) @@ -1502,6 +1506,22 @@ func (s *AteomHerder) dialAteom(ctx context.Context, targetAteomUid string) (ate return ateompb.NewAteomClient(conn), nil } +// actorDirsFor is the directory set atelet passes to ateom for an actor. ateom +// takes these from the request rather than deriving them from the actor UID. +func actorDirsFor(actorUID string) *ateompb.ActorDirs { + return &ateompb.ActorDirs{ + RootDir: ateompath.ActorPath(actorUID), + OciBundleDir: ateompath.OCIBundleDir(actorUID), + RunscStateDir: ateompath.RunSCStateDir(actorUID), + PidFileDir: ateompath.PIDFileDir(actorUID), + CheckpointDir: ateompath.CheckpointStateDir(actorUID), + RestoreDir: ateompath.RestoreStateDir(actorUID), + DurableDirVolumeMountsDir: ateompath.DurableDirVolumeMountsDir(actorUID), + SystemInfoVolumeRootsDir: ateompath.SystemInfoVolumeRootsDir(actorUID), + VolumesDir: ateompath.VolumesDir(actorUID), + } +} + // buildAteomWorkloadSpec projects the atelet-facing workload spec onto // the ateom-facing one. func buildAteomWorkloadSpec(spec *ateletpb.WorkloadSpec) (*ateompb.WorkloadSpec, error) { diff --git a/cmd/atelet/main_test.go b/cmd/atelet/main_test.go index ba0127acb3..edf8741ab0 100644 --- a/cmd/atelet/main_test.go +++ b/cmd/atelet/main_test.go @@ -407,6 +407,35 @@ func TestValidateRestoreRequest(t *testing.T) { // Every valid atelet scope must map to its ateom counterpart; in particular // DATA_ON_GOLDEN must never silently degrade to FULL. +func TestActorDirsFor(t *testing.T) { + const actorUID = "actor-uid-1" + dirs := actorDirsFor(actorUID) + if dirs.GetRootDir() != ateompath.ActorPath(actorUID) { + t.Fatalf("root_dir = %q, want %q", dirs.GetRootDir(), ateompath.ActorPath(actorUID)) + } + under := map[string]string{ + "oci_bundle_dir": dirs.GetOciBundleDir(), + "runsc_state_dir": dirs.GetRunscStateDir(), + "pid_file_dir": dirs.GetPidFileDir(), + "checkpoint_dir": dirs.GetCheckpointDir(), + "restore_dir": dirs.GetRestoreDir(), + "durable_dir_volume_mounts_dir": dirs.GetDurableDirVolumeMountsDir(), + "system_info_volume_roots_dir": dirs.GetSystemInfoVolumeRootsDir(), + "volumes_dir": dirs.GetVolumesDir(), + } + seen := map[string]string{} + for field, dir := range under { + rel, err := filepath.Rel(dirs.GetRootDir(), dir) + if err != nil || rel == "." || strings.HasPrefix(rel, "..") { + t.Errorf("%s = %q is not a proper subdirectory of root_dir %q", field, dir, dirs.GetRootDir()) + } + if other, dup := seen[dir]; dup { + t.Errorf("%s and %s share %q", field, other, dir) + } + seen[dir] = field + } +} + func TestToAteomSnapshotScope(t *testing.T) { tests := []struct { in ateletpb.SnapshotScope diff --git a/internal/proto/ateompb/ateom.pb.go b/internal/proto/ateompb/ateom.pb.go index 59ce521b64..3bb8f3febe 100644 --- a/internal/proto/ateompb/ateom.pb.go +++ b/internal/proto/ateompb/ateom.pb.go @@ -212,6 +212,126 @@ func (StatsSource) EnumDescriptor() ([]byte, []int) { return file_ateom_proto_rawDescGZIP(), []int{2} } +// ActorDirs is the set of per-actor directories atelet prepares on the volume +// it shares with ateom. ateom takes them from the RPC instead of deriving +// them from the actor UID. +// Every directory is under root_dir. +type ActorDirs struct { + state protoimpl.MessageState `protogen:"open.v1"` + RootDir string `protobuf:"bytes,1,opt,name=root_dir,json=rootDir,proto3" json:"root_dir,omitempty"` + // Holds one OCI bundle per container, named after the container. + OciBundleDir string `protobuf:"bytes,2,opt,name=oci_bundle_dir,json=ociBundleDir,proto3" json:"oci_bundle_dir,omitempty"` + // runsc --root for the actor's sandbox. gVisor only. + RunscStateDir string `protobuf:"bytes,3,opt,name=runsc_state_dir,json=runscStateDir,proto3" json:"runsc_state_dir,omitempty"` + // Where runsc writes .pid. gVisor only. + PidFileDir string `protobuf:"bytes,4,opt,name=pid_file_dir,json=pidFileDir,proto3" json:"pid_file_dir,omitempty"` + // Where CheckpointWorkload writes the snapshot files. + CheckpointDir string `protobuf:"bytes,5,opt,name=checkpoint_dir,json=checkpointDir,proto3" json:"checkpoint_dir,omitempty"` + // Where the snapshot files RestoreWorkload reads have been downloaded to. + RestoreDir string `protobuf:"bytes,6,opt,name=restore_dir,json=restoreDir,proto3" json:"restore_dir,omitempty"` + // Holds one subdirectory per durable-dir volume. + DurableDirVolumeMountsDir string `protobuf:"bytes,7,opt,name=durable_dir_volume_mounts_dir,json=durableDirVolumeMountsDir,proto3" json:"durable_dir_volume_mounts_dir,omitempty"` + // Holds one subdirectory per system-info volume. + SystemInfoVolumeRootsDir string `protobuf:"bytes,8,opt,name=system_info_volume_roots_dir,json=systemInfoVolumeRootsDir,proto3" json:"system_info_volume_roots_dir,omitempty"` + // Holds one mount point per CSI volume. + VolumesDir string `protobuf:"bytes,9,opt,name=volumes_dir,json=volumesDir,proto3" json:"volumes_dir,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *ActorDirs) Reset() { + *x = ActorDirs{} + mi := &file_ateom_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ActorDirs) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ActorDirs) ProtoMessage() {} + +func (x *ActorDirs) ProtoReflect() protoreflect.Message { + mi := &file_ateom_proto_msgTypes[0] + 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 ActorDirs.ProtoReflect.Descriptor instead. +func (*ActorDirs) Descriptor() ([]byte, []int) { + return file_ateom_proto_rawDescGZIP(), []int{0} +} + +func (x *ActorDirs) GetRootDir() string { + if x != nil { + return x.RootDir + } + return "" +} + +func (x *ActorDirs) GetOciBundleDir() string { + if x != nil { + return x.OciBundleDir + } + return "" +} + +func (x *ActorDirs) GetRunscStateDir() string { + if x != nil { + return x.RunscStateDir + } + return "" +} + +func (x *ActorDirs) GetPidFileDir() string { + if x != nil { + return x.PidFileDir + } + return "" +} + +func (x *ActorDirs) GetCheckpointDir() string { + if x != nil { + return x.CheckpointDir + } + return "" +} + +func (x *ActorDirs) GetRestoreDir() string { + if x != nil { + return x.RestoreDir + } + return "" +} + +func (x *ActorDirs) GetDurableDirVolumeMountsDir() string { + if x != nil { + return x.DurableDirVolumeMountsDir + } + return "" +} + +func (x *ActorDirs) GetSystemInfoVolumeRootsDir() string { + if x != nil { + return x.SystemInfoVolumeRootsDir + } + return "" +} + +func (x *ActorDirs) GetVolumesDir() string { + if x != nil { + return x.VolumesDir + } + return "" +} + type TerminateWorkloadRequest struct { state protoimpl.MessageState `protogen:"open.v1"` Atespace string `protobuf:"bytes,1,opt,name=atespace,proto3" json:"atespace,omitempty"` @@ -221,13 +341,14 @@ type TerminateWorkloadRequest struct { ActorTemplateName string `protobuf:"bytes,5,opt,name=actor_template_name,json=actorTemplateName,proto3" json:"actor_template_name,omitempty"` RunscPath string `protobuf:"bytes,6,opt,name=runsc_path,json=runscPath,proto3" json:"runsc_path,omitempty"` Spec *WorkloadSpec `protobuf:"bytes,7,opt,name=spec,proto3" json:"spec,omitempty"` + ActorDirs *ActorDirs `protobuf:"bytes,8,opt,name=actor_dirs,json=actorDirs,proto3" json:"actor_dirs,omitempty"` unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache } func (x *TerminateWorkloadRequest) Reset() { *x = TerminateWorkloadRequest{} - mi := &file_ateom_proto_msgTypes[0] + mi := &file_ateom_proto_msgTypes[1] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -239,7 +360,7 @@ func (x *TerminateWorkloadRequest) String() string { func (*TerminateWorkloadRequest) ProtoMessage() {} func (x *TerminateWorkloadRequest) ProtoReflect() protoreflect.Message { - mi := &file_ateom_proto_msgTypes[0] + mi := &file_ateom_proto_msgTypes[1] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -252,7 +373,7 @@ func (x *TerminateWorkloadRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use TerminateWorkloadRequest.ProtoReflect.Descriptor instead. func (*TerminateWorkloadRequest) Descriptor() ([]byte, []int) { - return file_ateom_proto_rawDescGZIP(), []int{0} + return file_ateom_proto_rawDescGZIP(), []int{1} } func (x *TerminateWorkloadRequest) GetAtespace() string { @@ -304,6 +425,13 @@ func (x *TerminateWorkloadRequest) GetSpec() *WorkloadSpec { return nil } +func (x *TerminateWorkloadRequest) GetActorDirs() *ActorDirs { + if x != nil { + return x.ActorDirs + } + return nil +} + type TerminateWorkloadResponse struct { state protoimpl.MessageState `protogen:"open.v1"` unknownFields protoimpl.UnknownFields @@ -312,7 +440,7 @@ type TerminateWorkloadResponse struct { func (x *TerminateWorkloadResponse) Reset() { *x = TerminateWorkloadResponse{} - mi := &file_ateom_proto_msgTypes[1] + mi := &file_ateom_proto_msgTypes[2] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -324,7 +452,7 @@ func (x *TerminateWorkloadResponse) String() string { func (*TerminateWorkloadResponse) ProtoMessage() {} func (x *TerminateWorkloadResponse) ProtoReflect() protoreflect.Message { - mi := &file_ateom_proto_msgTypes[1] + mi := &file_ateom_proto_msgTypes[2] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -337,7 +465,7 @@ func (x *TerminateWorkloadResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use TerminateWorkloadResponse.ProtoReflect.Descriptor instead. func (*TerminateWorkloadResponse) Descriptor() ([]byte, []int) { - return file_ateom_proto_rawDescGZIP(), []int{1} + return file_ateom_proto_rawDescGZIP(), []int{2} } type RunWorkloadRequest struct { @@ -360,15 +488,16 @@ type RunWorkloadRequest struct { // sizes the sandbox to these (cgroup caps via the OCI spec, and for the // micro-VM the VM's vCPU count and memory). Zero means "unset": keep the // runtime default (unlimited for gVisor, the kata config for the micro-VM). - CpuMilli int64 `protobuf:"varint,11,opt,name=cpu_milli,json=cpuMilli,proto3" json:"cpu_milli,omitempty"` // CPU limit in millicores (1000 = one core). - MemoryBytes int64 `protobuf:"varint,12,opt,name=memory_bytes,json=memoryBytes,proto3" json:"memory_bytes,omitempty"` // Memory limit in bytes. + CpuMilli int64 `protobuf:"varint,11,opt,name=cpu_milli,json=cpuMilli,proto3" json:"cpu_milli,omitempty"` // CPU limit in millicores (1000 = one core). + MemoryBytes int64 `protobuf:"varint,12,opt,name=memory_bytes,json=memoryBytes,proto3" json:"memory_bytes,omitempty"` // Memory limit in bytes. + ActorDirs *ActorDirs `protobuf:"bytes,13,opt,name=actor_dirs,json=actorDirs,proto3" json:"actor_dirs,omitempty"` unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache } func (x *RunWorkloadRequest) Reset() { *x = RunWorkloadRequest{} - mi := &file_ateom_proto_msgTypes[2] + mi := &file_ateom_proto_msgTypes[3] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -380,7 +509,7 @@ func (x *RunWorkloadRequest) String() string { func (*RunWorkloadRequest) ProtoMessage() {} func (x *RunWorkloadRequest) ProtoReflect() protoreflect.Message { - mi := &file_ateom_proto_msgTypes[2] + mi := &file_ateom_proto_msgTypes[3] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -393,7 +522,7 @@ func (x *RunWorkloadRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use RunWorkloadRequest.ProtoReflect.Descriptor instead. func (*RunWorkloadRequest) Descriptor() ([]byte, []int) { - return file_ateom_proto_rawDescGZIP(), []int{2} + return file_ateom_proto_rawDescGZIP(), []int{3} } func (x *RunWorkloadRequest) GetAtespace() string { @@ -473,6 +602,13 @@ func (x *RunWorkloadRequest) GetMemoryBytes() int64 { return 0 } +func (x *RunWorkloadRequest) GetActorDirs() *ActorDirs { + if x != nil { + return x.ActorDirs + } + return nil +} + // EgressGateway configures tunneled egress for one actor activation. type EgressGateway struct { state protoimpl.MessageState `protogen:"open.v1"` @@ -485,7 +621,7 @@ type EgressGateway struct { func (x *EgressGateway) Reset() { *x = EgressGateway{} - mi := &file_ateom_proto_msgTypes[3] + mi := &file_ateom_proto_msgTypes[4] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -497,7 +633,7 @@ func (x *EgressGateway) String() string { func (*EgressGateway) ProtoMessage() {} func (x *EgressGateway) ProtoReflect() protoreflect.Message { - mi := &file_ateom_proto_msgTypes[3] + mi := &file_ateom_proto_msgTypes[4] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -510,7 +646,7 @@ func (x *EgressGateway) ProtoReflect() protoreflect.Message { // Deprecated: Use EgressGateway.ProtoReflect.Descriptor instead. func (*EgressGateway) Descriptor() ([]byte, []int) { - return file_ateom_proto_rawDescGZIP(), []int{3} + return file_ateom_proto_rawDescGZIP(), []int{4} } func (x *EgressGateway) GetAddress() string { @@ -530,7 +666,7 @@ type WorkloadSpec struct { func (x *WorkloadSpec) Reset() { *x = WorkloadSpec{} - mi := &file_ateom_proto_msgTypes[4] + mi := &file_ateom_proto_msgTypes[5] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -542,7 +678,7 @@ func (x *WorkloadSpec) String() string { func (*WorkloadSpec) ProtoMessage() {} func (x *WorkloadSpec) ProtoReflect() protoreflect.Message { - mi := &file_ateom_proto_msgTypes[4] + mi := &file_ateom_proto_msgTypes[5] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -555,7 +691,7 @@ func (x *WorkloadSpec) ProtoReflect() protoreflect.Message { // Deprecated: Use WorkloadSpec.ProtoReflect.Descriptor instead. func (*WorkloadSpec) Descriptor() ([]byte, []int) { - return file_ateom_proto_rawDescGZIP(), []int{4} + return file_ateom_proto_rawDescGZIP(), []int{5} } func (x *WorkloadSpec) GetContainers() []*Container { @@ -586,7 +722,7 @@ type Container struct { func (x *Container) Reset() { *x = Container{} - mi := &file_ateom_proto_msgTypes[5] + mi := &file_ateom_proto_msgTypes[6] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -598,7 +734,7 @@ func (x *Container) String() string { func (*Container) ProtoMessage() {} func (x *Container) ProtoReflect() protoreflect.Message { - mi := &file_ateom_proto_msgTypes[5] + mi := &file_ateom_proto_msgTypes[6] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -611,7 +747,7 @@ func (x *Container) ProtoReflect() protoreflect.Message { // Deprecated: Use Container.ProtoReflect.Descriptor instead. func (*Container) Descriptor() ([]byte, []int) { - return file_ateom_proto_rawDescGZIP(), []int{5} + return file_ateom_proto_rawDescGZIP(), []int{6} } func (x *Container) GetName() string { @@ -667,7 +803,7 @@ type VolumeMount struct { func (x *VolumeMount) Reset() { *x = VolumeMount{} - mi := &file_ateom_proto_msgTypes[6] + mi := &file_ateom_proto_msgTypes[7] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -679,7 +815,7 @@ func (x *VolumeMount) String() string { func (*VolumeMount) ProtoMessage() {} func (x *VolumeMount) ProtoReflect() protoreflect.Message { - mi := &file_ateom_proto_msgTypes[6] + mi := &file_ateom_proto_msgTypes[7] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -692,7 +828,7 @@ func (x *VolumeMount) ProtoReflect() protoreflect.Message { // Deprecated: Use VolumeMount.ProtoReflect.Descriptor instead. func (*VolumeMount) Descriptor() ([]byte, []int) { - return file_ateom_proto_rawDescGZIP(), []int{6} + return file_ateom_proto_rawDescGZIP(), []int{7} } func (x *VolumeMount) GetVolumeName() string { @@ -723,7 +859,7 @@ type DurableDirVolumeMount struct { func (x *DurableDirVolumeMount) Reset() { *x = DurableDirVolumeMount{} - mi := &file_ateom_proto_msgTypes[7] + mi := &file_ateom_proto_msgTypes[8] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -735,7 +871,7 @@ func (x *DurableDirVolumeMount) String() string { func (*DurableDirVolumeMount) ProtoMessage() {} func (x *DurableDirVolumeMount) ProtoReflect() protoreflect.Message { - mi := &file_ateom_proto_msgTypes[7] + mi := &file_ateom_proto_msgTypes[8] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -748,7 +884,7 @@ func (x *DurableDirVolumeMount) ProtoReflect() protoreflect.Message { // Deprecated: Use DurableDirVolumeMount.ProtoReflect.Descriptor instead. func (*DurableDirVolumeMount) Descriptor() ([]byte, []int) { - return file_ateom_proto_rawDescGZIP(), []int{7} + return file_ateom_proto_rawDescGZIP(), []int{8} } func (x *DurableDirVolumeMount) GetVolumeName() string { @@ -781,7 +917,7 @@ type SystemInfoVolumeMount struct { func (x *SystemInfoVolumeMount) Reset() { *x = SystemInfoVolumeMount{} - mi := &file_ateom_proto_msgTypes[8] + mi := &file_ateom_proto_msgTypes[9] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -793,7 +929,7 @@ func (x *SystemInfoVolumeMount) String() string { func (*SystemInfoVolumeMount) ProtoMessage() {} func (x *SystemInfoVolumeMount) ProtoReflect() protoreflect.Message { - mi := &file_ateom_proto_msgTypes[8] + mi := &file_ateom_proto_msgTypes[9] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -806,7 +942,7 @@ func (x *SystemInfoVolumeMount) ProtoReflect() protoreflect.Message { // Deprecated: Use SystemInfoVolumeMount.ProtoReflect.Descriptor instead. func (*SystemInfoVolumeMount) Descriptor() ([]byte, []int) { - return file_ateom_proto_rawDescGZIP(), []int{8} + return file_ateom_proto_rawDescGZIP(), []int{9} } func (x *SystemInfoVolumeMount) GetVolumeName() string { @@ -838,7 +974,7 @@ type ImageVolumeMount struct { func (x *ImageVolumeMount) Reset() { *x = ImageVolumeMount{} - mi := &file_ateom_proto_msgTypes[9] + mi := &file_ateom_proto_msgTypes[10] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -850,7 +986,7 @@ func (x *ImageVolumeMount) String() string { func (*ImageVolumeMount) ProtoMessage() {} func (x *ImageVolumeMount) ProtoReflect() protoreflect.Message { - mi := &file_ateom_proto_msgTypes[9] + mi := &file_ateom_proto_msgTypes[10] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -863,7 +999,7 @@ func (x *ImageVolumeMount) ProtoReflect() protoreflect.Message { // Deprecated: Use ImageVolumeMount.ProtoReflect.Descriptor instead. func (*ImageVolumeMount) Descriptor() ([]byte, []int) { - return file_ateom_proto_rawDescGZIP(), []int{9} + return file_ateom_proto_rawDescGZIP(), []int{10} } func (x *ImageVolumeMount) GetVolumeName() string { @@ -894,7 +1030,7 @@ type Readyz struct { func (x *Readyz) Reset() { *x = Readyz{} - mi := &file_ateom_proto_msgTypes[10] + mi := &file_ateom_proto_msgTypes[11] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -906,7 +1042,7 @@ func (x *Readyz) String() string { func (*Readyz) ProtoMessage() {} func (x *Readyz) ProtoReflect() protoreflect.Message { - mi := &file_ateom_proto_msgTypes[10] + mi := &file_ateom_proto_msgTypes[11] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -919,7 +1055,7 @@ func (x *Readyz) ProtoReflect() protoreflect.Message { // Deprecated: Use Readyz.ProtoReflect.Descriptor instead. func (*Readyz) Descriptor() ([]byte, []int) { - return file_ateom_proto_rawDescGZIP(), []int{10} + return file_ateom_proto_rawDescGZIP(), []int{11} } func (x *Readyz) GetHttpGet() *HTTPGetAction { @@ -949,7 +1085,7 @@ type HTTPGetAction struct { func (x *HTTPGetAction) Reset() { *x = HTTPGetAction{} - mi := &file_ateom_proto_msgTypes[11] + mi := &file_ateom_proto_msgTypes[12] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -961,7 +1097,7 @@ func (x *HTTPGetAction) String() string { func (*HTTPGetAction) ProtoMessage() {} func (x *HTTPGetAction) ProtoReflect() protoreflect.Message { - mi := &file_ateom_proto_msgTypes[11] + mi := &file_ateom_proto_msgTypes[12] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -974,7 +1110,7 @@ func (x *HTTPGetAction) ProtoReflect() protoreflect.Message { // Deprecated: Use HTTPGetAction.ProtoReflect.Descriptor instead. func (*HTTPGetAction) Descriptor() ([]byte, []int) { - return file_ateom_proto_rawDescGZIP(), []int{11} + return file_ateom_proto_rawDescGZIP(), []int{12} } func (x *HTTPGetAction) GetPath() string { @@ -999,7 +1135,7 @@ type RunWorkloadResponse struct { func (x *RunWorkloadResponse) Reset() { *x = RunWorkloadResponse{} - mi := &file_ateom_proto_msgTypes[12] + mi := &file_ateom_proto_msgTypes[13] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1011,7 +1147,7 @@ func (x *RunWorkloadResponse) String() string { func (*RunWorkloadResponse) ProtoMessage() {} func (x *RunWorkloadResponse) ProtoReflect() protoreflect.Message { - mi := &file_ateom_proto_msgTypes[12] + mi := &file_ateom_proto_msgTypes[13] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1024,7 +1160,7 @@ func (x *RunWorkloadResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use RunWorkloadResponse.ProtoReflect.Descriptor instead. func (*RunWorkloadResponse) Descriptor() ([]byte, []int) { - return file_ateom_proto_rawDescGZIP(), []int{12} + return file_ateom_proto_rawDescGZIP(), []int{13} } type CheckpointWorkloadRequest struct { @@ -1052,13 +1188,14 @@ type CheckpointWorkloadRequest struct { RuntimeAssetPaths map[string]string `protobuf:"bytes,9,rep,name=runtime_asset_paths,json=runtimeAssetPaths,proto3" json:"runtime_asset_paths,omitempty" protobuf_key:"bytes,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value"` // What content to include in the checkpoint. Scope SnapshotScope `protobuf:"varint,10,opt,name=scope,proto3,enum=ateom.SnapshotScope" json:"scope,omitempty"` + ActorDirs *ActorDirs `protobuf:"bytes,11,opt,name=actor_dirs,json=actorDirs,proto3" json:"actor_dirs,omitempty"` unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache } func (x *CheckpointWorkloadRequest) Reset() { *x = CheckpointWorkloadRequest{} - mi := &file_ateom_proto_msgTypes[13] + mi := &file_ateom_proto_msgTypes[14] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1070,7 +1207,7 @@ func (x *CheckpointWorkloadRequest) String() string { func (*CheckpointWorkloadRequest) ProtoMessage() {} func (x *CheckpointWorkloadRequest) ProtoReflect() protoreflect.Message { - mi := &file_ateom_proto_msgTypes[13] + mi := &file_ateom_proto_msgTypes[14] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1083,7 +1220,7 @@ func (x *CheckpointWorkloadRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use CheckpointWorkloadRequest.ProtoReflect.Descriptor instead. func (*CheckpointWorkloadRequest) Descriptor() ([]byte, []int) { - return file_ateom_proto_rawDescGZIP(), []int{13} + return file_ateom_proto_rawDescGZIP(), []int{14} } func (x *CheckpointWorkloadRequest) GetAtespace() string { @@ -1156,6 +1293,13 @@ func (x *CheckpointWorkloadRequest) GetScope() SnapshotScope { return SnapshotScope_SNAPSHOT_SCOPE_UNSPECIFIED } +func (x *CheckpointWorkloadRequest) GetActorDirs() *ActorDirs { + if x != nil { + return x.ActorDirs + } + return nil +} + type CheckpointWorkloadResponse struct { state protoimpl.MessageState `protogen:"open.v1"` // snapshot_files lists the files ateom wrote into the checkpoint directory @@ -1168,7 +1312,7 @@ type CheckpointWorkloadResponse struct { func (x *CheckpointWorkloadResponse) Reset() { *x = CheckpointWorkloadResponse{} - mi := &file_ateom_proto_msgTypes[14] + mi := &file_ateom_proto_msgTypes[15] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1180,7 +1324,7 @@ func (x *CheckpointWorkloadResponse) String() string { func (*CheckpointWorkloadResponse) ProtoMessage() {} func (x *CheckpointWorkloadResponse) ProtoReflect() protoreflect.Message { - mi := &file_ateom_proto_msgTypes[14] + mi := &file_ateom_proto_msgTypes[15] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1193,7 +1337,7 @@ func (x *CheckpointWorkloadResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use CheckpointWorkloadResponse.ProtoReflect.Descriptor instead. func (*CheckpointWorkloadResponse) Descriptor() ([]byte, []int) { - return file_ateom_proto_rawDescGZIP(), []int{14} + return file_ateom_proto_rawDescGZIP(), []int{15} } func (x *CheckpointWorkloadResponse) GetSnapshotFiles() []string { @@ -1230,15 +1374,16 @@ type RestoreWorkloadRequest struct { // (re)size the sandbox on a DATA-scope restore (fresh guest container). On a // FULL micro-VM restore the size baked into the snapshot is authoritative and // these are ignored. Zero means "unset": keep the runtime default. - CpuMilli int64 `protobuf:"varint,14,opt,name=cpu_milli,json=cpuMilli,proto3" json:"cpu_milli,omitempty"` // CPU limit in millicores (1000 = one core). - MemoryBytes int64 `protobuf:"varint,15,opt,name=memory_bytes,json=memoryBytes,proto3" json:"memory_bytes,omitempty"` // Memory limit in bytes. + CpuMilli int64 `protobuf:"varint,14,opt,name=cpu_milli,json=cpuMilli,proto3" json:"cpu_milli,omitempty"` // CPU limit in millicores (1000 = one core). + MemoryBytes int64 `protobuf:"varint,15,opt,name=memory_bytes,json=memoryBytes,proto3" json:"memory_bytes,omitempty"` // Memory limit in bytes. + ActorDirs *ActorDirs `protobuf:"bytes,16,opt,name=actor_dirs,json=actorDirs,proto3" json:"actor_dirs,omitempty"` unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache } func (x *RestoreWorkloadRequest) Reset() { *x = RestoreWorkloadRequest{} - mi := &file_ateom_proto_msgTypes[15] + mi := &file_ateom_proto_msgTypes[16] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1250,7 +1395,7 @@ func (x *RestoreWorkloadRequest) String() string { func (*RestoreWorkloadRequest) ProtoMessage() {} func (x *RestoreWorkloadRequest) ProtoReflect() protoreflect.Message { - mi := &file_ateom_proto_msgTypes[15] + mi := &file_ateom_proto_msgTypes[16] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1263,7 +1408,7 @@ func (x *RestoreWorkloadRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use RestoreWorkloadRequest.ProtoReflect.Descriptor instead. func (*RestoreWorkloadRequest) Descriptor() ([]byte, []int) { - return file_ateom_proto_rawDescGZIP(), []int{15} + return file_ateom_proto_rawDescGZIP(), []int{16} } func (x *RestoreWorkloadRequest) GetAtespace() string { @@ -1364,6 +1509,13 @@ func (x *RestoreWorkloadRequest) GetMemoryBytes() int64 { return 0 } +func (x *RestoreWorkloadRequest) GetActorDirs() *ActorDirs { + if x != nil { + return x.ActorDirs + } + return nil +} + type RestoreWorkloadResponse struct { state protoimpl.MessageState `protogen:"open.v1"` unknownFields protoimpl.UnknownFields @@ -1372,7 +1524,7 @@ type RestoreWorkloadResponse struct { func (x *RestoreWorkloadResponse) Reset() { *x = RestoreWorkloadResponse{} - mi := &file_ateom_proto_msgTypes[16] + mi := &file_ateom_proto_msgTypes[17] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1384,7 +1536,7 @@ func (x *RestoreWorkloadResponse) String() string { func (*RestoreWorkloadResponse) ProtoMessage() {} func (x *RestoreWorkloadResponse) ProtoReflect() protoreflect.Message { - mi := &file_ateom_proto_msgTypes[16] + mi := &file_ateom_proto_msgTypes[17] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1397,7 +1549,7 @@ func (x *RestoreWorkloadResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use RestoreWorkloadResponse.ProtoReflect.Descriptor instead. func (*RestoreWorkloadResponse) Descriptor() ([]byte, []int) { - return file_ateom_proto_rawDescGZIP(), []int{16} + return file_ateom_proto_rawDescGZIP(), []int{17} } type GetWorkloadStatsRequest struct { @@ -1413,7 +1565,7 @@ type GetWorkloadStatsRequest struct { func (x *GetWorkloadStatsRequest) Reset() { *x = GetWorkloadStatsRequest{} - mi := &file_ateom_proto_msgTypes[17] + mi := &file_ateom_proto_msgTypes[18] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1425,7 +1577,7 @@ func (x *GetWorkloadStatsRequest) String() string { func (*GetWorkloadStatsRequest) ProtoMessage() {} func (x *GetWorkloadStatsRequest) ProtoReflect() protoreflect.Message { - mi := &file_ateom_proto_msgTypes[17] + mi := &file_ateom_proto_msgTypes[18] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1438,7 +1590,7 @@ func (x *GetWorkloadStatsRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use GetWorkloadStatsRequest.ProtoReflect.Descriptor instead. func (*GetWorkloadStatsRequest) Descriptor() ([]byte, []int) { - return file_ateom_proto_rawDescGZIP(), []int{17} + return file_ateom_proto_rawDescGZIP(), []int{18} } func (x *GetWorkloadStatsRequest) GetActorUid() string { @@ -1502,7 +1654,7 @@ type WorkloadStatsSample struct { func (x *WorkloadStatsSample) Reset() { *x = WorkloadStatsSample{} - mi := &file_ateom_proto_msgTypes[18] + mi := &file_ateom_proto_msgTypes[19] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1514,7 +1666,7 @@ func (x *WorkloadStatsSample) String() string { func (*WorkloadStatsSample) ProtoMessage() {} func (x *WorkloadStatsSample) ProtoReflect() protoreflect.Message { - mi := &file_ateom_proto_msgTypes[18] + mi := &file_ateom_proto_msgTypes[19] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1527,7 +1679,7 @@ func (x *WorkloadStatsSample) ProtoReflect() protoreflect.Message { // Deprecated: Use WorkloadStatsSample.ProtoReflect.Descriptor instead. func (*WorkloadStatsSample) Descriptor() ([]byte, []int) { - return file_ateom_proto_rawDescGZIP(), []int{18} + return file_ateom_proto_rawDescGZIP(), []int{19} } func (x *WorkloadStatsSample) GetAtespace() string { @@ -1623,7 +1775,7 @@ type GetWorkloadStatsResponse struct { func (x *GetWorkloadStatsResponse) Reset() { *x = GetWorkloadStatsResponse{} - mi := &file_ateom_proto_msgTypes[19] + mi := &file_ateom_proto_msgTypes[20] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1635,7 +1787,7 @@ func (x *GetWorkloadStatsResponse) String() string { func (*GetWorkloadStatsResponse) ProtoMessage() {} func (x *GetWorkloadStatsResponse) ProtoReflect() protoreflect.Message { - mi := &file_ateom_proto_msgTypes[19] + mi := &file_ateom_proto_msgTypes[20] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1648,7 +1800,7 @@ func (x *GetWorkloadStatsResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use GetWorkloadStatsResponse.ProtoReflect.Descriptor instead. func (*GetWorkloadStatsResponse) Descriptor() ([]byte, []int) { - return file_ateom_proto_rawDescGZIP(), []int{19} + return file_ateom_proto_rawDescGZIP(), []int{20} } func (x *GetWorkloadStatsResponse) GetSample() *WorkloadStatsSample { @@ -1666,7 +1818,7 @@ type GetActiveWorkloadStatsRequest struct { func (x *GetActiveWorkloadStatsRequest) Reset() { *x = GetActiveWorkloadStatsRequest{} - mi := &file_ateom_proto_msgTypes[20] + mi := &file_ateom_proto_msgTypes[21] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1678,7 +1830,7 @@ func (x *GetActiveWorkloadStatsRequest) String() string { func (*GetActiveWorkloadStatsRequest) ProtoMessage() {} func (x *GetActiveWorkloadStatsRequest) ProtoReflect() protoreflect.Message { - mi := &file_ateom_proto_msgTypes[20] + mi := &file_ateom_proto_msgTypes[21] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1691,7 +1843,7 @@ func (x *GetActiveWorkloadStatsRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use GetActiveWorkloadStatsRequest.ProtoReflect.Descriptor instead. func (*GetActiveWorkloadStatsRequest) Descriptor() ([]byte, []int) { - return file_ateom_proto_rawDescGZIP(), []int{20} + return file_ateom_proto_rawDescGZIP(), []int{21} } type GetActiveWorkloadStatsResponse struct { @@ -1711,7 +1863,7 @@ type GetActiveWorkloadStatsResponse struct { func (x *GetActiveWorkloadStatsResponse) Reset() { *x = GetActiveWorkloadStatsResponse{} - mi := &file_ateom_proto_msgTypes[21] + mi := &file_ateom_proto_msgTypes[22] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1723,7 +1875,7 @@ func (x *GetActiveWorkloadStatsResponse) String() string { func (*GetActiveWorkloadStatsResponse) ProtoMessage() {} func (x *GetActiveWorkloadStatsResponse) ProtoReflect() protoreflect.Message { - mi := &file_ateom_proto_msgTypes[21] + mi := &file_ateom_proto_msgTypes[22] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1736,7 +1888,7 @@ func (x *GetActiveWorkloadStatsResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use GetActiveWorkloadStatsResponse.ProtoReflect.Descriptor instead. func (*GetActiveWorkloadStatsResponse) Descriptor() ([]byte, []int) { - return file_ateom_proto_rawDescGZIP(), []int{21} + return file_ateom_proto_rawDescGZIP(), []int{22} } func (x *GetActiveWorkloadStatsResponse) GetSamples() []*WorkloadStatsSample { @@ -1750,7 +1902,20 @@ var File_ateom_proto protoreflect.FileDescriptor const file_ateom_proto_rawDesc = "" + "\n" + - "\vateom.proto\x12\x05ateom\"\xa2\x02\n" + + "\vateom.proto\x12\x05ateom\"\x81\x03\n" + + "\tActorDirs\x12\x19\n" + + "\broot_dir\x18\x01 \x01(\tR\arootDir\x12$\n" + + "\x0eoci_bundle_dir\x18\x02 \x01(\tR\fociBundleDir\x12&\n" + + "\x0frunsc_state_dir\x18\x03 \x01(\tR\rrunscStateDir\x12 \n" + + "\fpid_file_dir\x18\x04 \x01(\tR\n" + + "pidFileDir\x12%\n" + + "\x0echeckpoint_dir\x18\x05 \x01(\tR\rcheckpointDir\x12\x1f\n" + + "\vrestore_dir\x18\x06 \x01(\tR\n" + + "restoreDir\x12@\n" + + "\x1ddurable_dir_volume_mounts_dir\x18\a \x01(\tR\x19durableDirVolumeMountsDir\x12>\n" + + "\x1csystem_info_volume_roots_dir\x18\b \x01(\tR\x18systemInfoVolumeRootsDir\x12\x1f\n" + + "\vvolumes_dir\x18\t \x01(\tR\n" + + "volumesDir\"\xd3\x02\n" + "\x18TerminateWorkloadRequest\x12\x1a\n" + "\batespace\x18\x01 \x01(\tR\batespace\x12\x1d\n" + "\n" + @@ -1760,8 +1925,10 @@ const file_ateom_proto_rawDesc = "" + "\x13actor_template_name\x18\x05 \x01(\tR\x11actorTemplateName\x12\x1d\n" + "\n" + "runsc_path\x18\x06 \x01(\tR\trunscPath\x12'\n" + - "\x04spec\x18\a \x01(\v2\x13.ateom.WorkloadSpecR\x04spec\"\x1b\n" + - "\x19TerminateWorkloadResponse\"\xd9\x04\n" + + "\x04spec\x18\a \x01(\v2\x13.ateom.WorkloadSpecR\x04spec\x12/\n" + + "\n" + + "actor_dirs\x18\b \x01(\v2\x10.ateom.ActorDirsR\tactorDirs\"\x1b\n" + + "\x19TerminateWorkloadResponse\"\x8a\x05\n" + "\x12RunWorkloadRequest\x12\x1a\n" + "\batespace\x18\x01 \x01(\tR\batespace\x12\x1d\n" + "\n" + @@ -1776,7 +1943,9 @@ const file_ateom_proto_rawDesc = "" + "\x0eegress_gateway\x18\n" + " \x01(\v2\x14.ateom.EgressGatewayH\x00R\regressGateway\x88\x01\x01\x12\x1b\n" + "\tcpu_milli\x18\v \x01(\x03R\bcpuMilli\x12!\n" + - "\fmemory_bytes\x18\f \x01(\x03R\vmemoryBytes\x1aD\n" + + "\fmemory_bytes\x18\f \x01(\x03R\vmemoryBytes\x12/\n" + + "\n" + + "actor_dirs\x18\r \x01(\v2\x10.ateom.ActorDirsR\tactorDirs\x1aD\n" + "\x16RuntimeAssetPathsEntry\x12\x10\n" + "\x03key\x18\x01 \x01(\tR\x03key\x12\x14\n" + "\x05value\x18\x02 \x01(\tR\x05value:\x028\x01B\x11\n" + @@ -1820,7 +1989,7 @@ const file_ateom_proto_rawDesc = "" + "\rHTTPGetAction\x12\x12\n" + "\x04path\x18\x01 \x01(\tR\x04path\x12\x12\n" + "\x04port\x18\x02 \x01(\x05R\x04port\"\x15\n" + - "\x13RunWorkloadResponse\"\xa1\x04\n" + + "\x13RunWorkloadResponse\"\xd2\x04\n" + "\x19CheckpointWorkloadRequest\x12\x1a\n" + "\batespace\x18\x01 \x01(\tR\batespace\x12\x1d\n" + "\n" + @@ -1834,12 +2003,14 @@ const file_ateom_proto_rawDesc = "" + "\fsnapshot_uri\x18\b \x01(\tR\vsnapshotUri\x12g\n" + "\x13runtime_asset_paths\x18\t \x03(\v27.ateom.CheckpointWorkloadRequest.RuntimeAssetPathsEntryR\x11runtimeAssetPaths\x12*\n" + "\x05scope\x18\n" + - " \x01(\x0e2\x14.ateom.SnapshotScopeR\x05scope\x1aD\n" + + " \x01(\x0e2\x14.ateom.SnapshotScopeR\x05scope\x12/\n" + + "\n" + + "actor_dirs\x18\v \x01(\v2\x10.ateom.ActorDirsR\tactorDirs\x1aD\n" + "\x16RuntimeAssetPathsEntry\x12\x10\n" + "\x03key\x18\x01 \x01(\tR\x03key\x12\x14\n" + "\x05value\x18\x02 \x01(\tR\x05value:\x028\x01\"C\n" + "\x1aCheckpointWorkloadResponse\x12%\n" + - "\x0esnapshot_files\x18\x01 \x03(\tR\rsnapshotFiles\"\xe0\x05\n" + + "\x0esnapshot_files\x18\x01 \x03(\tR\rsnapshotFiles\"\x91\x06\n" + "\x16RestoreWorkloadRequest\x12\x1a\n" + "\batespace\x18\x01 \x01(\tR\batespace\x12\x1d\n" + "\n" + @@ -1857,7 +2028,9 @@ const file_ateom_proto_rawDesc = "" + "\x0eegress_gateway\x18\f \x01(\v2\x14.ateom.EgressGatewayH\x00R\regressGateway\x88\x01\x01\x12.\n" + "\x13golden_snapshot_uri\x18\r \x01(\tR\x11goldenSnapshotUri\x12\x1b\n" + "\tcpu_milli\x18\x0e \x01(\x03R\bcpuMilli\x12!\n" + - "\fmemory_bytes\x18\x0f \x01(\x03R\vmemoryBytes\x1aD\n" + + "\fmemory_bytes\x18\x0f \x01(\x03R\vmemoryBytes\x12/\n" + + "\n" + + "actor_dirs\x18\x10 \x01(\v2\x10.ateom.ActorDirsR\tactorDirs\x1aD\n" + "\x16RuntimeAssetPathsEntry\x12\x10\n" + "\x03key\x18\x01 \x01(\tR\x03key\x12\x14\n" + "\x05value\x18\x02 \x01(\tR\x05value:\x028\x01B\x11\n" + @@ -1919,77 +2092,82 @@ func file_ateom_proto_rawDescGZIP() []byte { } var file_ateom_proto_enumTypes = make([]protoimpl.EnumInfo, 3) -var file_ateom_proto_msgTypes = make([]protoimpl.MessageInfo, 25) +var file_ateom_proto_msgTypes = make([]protoimpl.MessageInfo, 26) var file_ateom_proto_goTypes = []any{ (SnapshotScope)(0), // 0: ateom.SnapshotScope (SandboxClass)(0), // 1: ateom.SandboxClass (StatsSource)(0), // 2: ateom.StatsSource - (*TerminateWorkloadRequest)(nil), // 3: ateom.TerminateWorkloadRequest - (*TerminateWorkloadResponse)(nil), // 4: ateom.TerminateWorkloadResponse - (*RunWorkloadRequest)(nil), // 5: ateom.RunWorkloadRequest - (*EgressGateway)(nil), // 6: ateom.EgressGateway - (*WorkloadSpec)(nil), // 7: ateom.WorkloadSpec - (*Container)(nil), // 8: ateom.Container - (*VolumeMount)(nil), // 9: ateom.VolumeMount - (*DurableDirVolumeMount)(nil), // 10: ateom.DurableDirVolumeMount - (*SystemInfoVolumeMount)(nil), // 11: ateom.SystemInfoVolumeMount - (*ImageVolumeMount)(nil), // 12: ateom.ImageVolumeMount - (*Readyz)(nil), // 13: ateom.Readyz - (*HTTPGetAction)(nil), // 14: ateom.HTTPGetAction - (*RunWorkloadResponse)(nil), // 15: ateom.RunWorkloadResponse - (*CheckpointWorkloadRequest)(nil), // 16: ateom.CheckpointWorkloadRequest - (*CheckpointWorkloadResponse)(nil), // 17: ateom.CheckpointWorkloadResponse - (*RestoreWorkloadRequest)(nil), // 18: ateom.RestoreWorkloadRequest - (*RestoreWorkloadResponse)(nil), // 19: ateom.RestoreWorkloadResponse - (*GetWorkloadStatsRequest)(nil), // 20: ateom.GetWorkloadStatsRequest - (*WorkloadStatsSample)(nil), // 21: ateom.WorkloadStatsSample - (*GetWorkloadStatsResponse)(nil), // 22: ateom.GetWorkloadStatsResponse - (*GetActiveWorkloadStatsRequest)(nil), // 23: ateom.GetActiveWorkloadStatsRequest - (*GetActiveWorkloadStatsResponse)(nil), // 24: ateom.GetActiveWorkloadStatsResponse - nil, // 25: ateom.RunWorkloadRequest.RuntimeAssetPathsEntry - nil, // 26: ateom.CheckpointWorkloadRequest.RuntimeAssetPathsEntry - nil, // 27: ateom.RestoreWorkloadRequest.RuntimeAssetPathsEntry + (*ActorDirs)(nil), // 3: ateom.ActorDirs + (*TerminateWorkloadRequest)(nil), // 4: ateom.TerminateWorkloadRequest + (*TerminateWorkloadResponse)(nil), // 5: ateom.TerminateWorkloadResponse + (*RunWorkloadRequest)(nil), // 6: ateom.RunWorkloadRequest + (*EgressGateway)(nil), // 7: ateom.EgressGateway + (*WorkloadSpec)(nil), // 8: ateom.WorkloadSpec + (*Container)(nil), // 9: ateom.Container + (*VolumeMount)(nil), // 10: ateom.VolumeMount + (*DurableDirVolumeMount)(nil), // 11: ateom.DurableDirVolumeMount + (*SystemInfoVolumeMount)(nil), // 12: ateom.SystemInfoVolumeMount + (*ImageVolumeMount)(nil), // 13: ateom.ImageVolumeMount + (*Readyz)(nil), // 14: ateom.Readyz + (*HTTPGetAction)(nil), // 15: ateom.HTTPGetAction + (*RunWorkloadResponse)(nil), // 16: ateom.RunWorkloadResponse + (*CheckpointWorkloadRequest)(nil), // 17: ateom.CheckpointWorkloadRequest + (*CheckpointWorkloadResponse)(nil), // 18: ateom.CheckpointWorkloadResponse + (*RestoreWorkloadRequest)(nil), // 19: ateom.RestoreWorkloadRequest + (*RestoreWorkloadResponse)(nil), // 20: ateom.RestoreWorkloadResponse + (*GetWorkloadStatsRequest)(nil), // 21: ateom.GetWorkloadStatsRequest + (*WorkloadStatsSample)(nil), // 22: ateom.WorkloadStatsSample + (*GetWorkloadStatsResponse)(nil), // 23: ateom.GetWorkloadStatsResponse + (*GetActiveWorkloadStatsRequest)(nil), // 24: ateom.GetActiveWorkloadStatsRequest + (*GetActiveWorkloadStatsResponse)(nil), // 25: ateom.GetActiveWorkloadStatsResponse + nil, // 26: ateom.RunWorkloadRequest.RuntimeAssetPathsEntry + nil, // 27: ateom.CheckpointWorkloadRequest.RuntimeAssetPathsEntry + nil, // 28: ateom.RestoreWorkloadRequest.RuntimeAssetPathsEntry } var file_ateom_proto_depIdxs = []int32{ - 7, // 0: ateom.TerminateWorkloadRequest.spec:type_name -> ateom.WorkloadSpec - 7, // 1: ateom.RunWorkloadRequest.spec:type_name -> ateom.WorkloadSpec - 25, // 2: ateom.RunWorkloadRequest.runtime_asset_paths:type_name -> ateom.RunWorkloadRequest.RuntimeAssetPathsEntry - 6, // 3: ateom.RunWorkloadRequest.egress_gateway:type_name -> ateom.EgressGateway - 8, // 4: ateom.WorkloadSpec.containers:type_name -> ateom.Container - 13, // 5: ateom.Container.readyz:type_name -> ateom.Readyz - 10, // 6: ateom.Container.durable_dir_volume_mounts:type_name -> ateom.DurableDirVolumeMount - 9, // 7: ateom.Container.csi_volume_mounts:type_name -> ateom.VolumeMount - 11, // 8: ateom.Container.system_info_volume_mounts:type_name -> ateom.SystemInfoVolumeMount - 12, // 9: ateom.Container.image_volume_mounts:type_name -> ateom.ImageVolumeMount - 14, // 10: ateom.Readyz.http_get:type_name -> ateom.HTTPGetAction - 7, // 11: ateom.CheckpointWorkloadRequest.spec:type_name -> ateom.WorkloadSpec - 26, // 12: ateom.CheckpointWorkloadRequest.runtime_asset_paths:type_name -> ateom.CheckpointWorkloadRequest.RuntimeAssetPathsEntry - 0, // 13: ateom.CheckpointWorkloadRequest.scope:type_name -> ateom.SnapshotScope - 7, // 14: ateom.RestoreWorkloadRequest.spec:type_name -> ateom.WorkloadSpec - 27, // 15: ateom.RestoreWorkloadRequest.runtime_asset_paths:type_name -> ateom.RestoreWorkloadRequest.RuntimeAssetPathsEntry - 0, // 16: ateom.RestoreWorkloadRequest.scope:type_name -> ateom.SnapshotScope - 6, // 17: ateom.RestoreWorkloadRequest.egress_gateway:type_name -> ateom.EgressGateway - 1, // 18: ateom.WorkloadStatsSample.sandbox_class:type_name -> ateom.SandboxClass - 2, // 19: ateom.WorkloadStatsSample.source:type_name -> ateom.StatsSource - 21, // 20: ateom.GetWorkloadStatsResponse.sample:type_name -> ateom.WorkloadStatsSample - 21, // 21: ateom.GetActiveWorkloadStatsResponse.samples:type_name -> ateom.WorkloadStatsSample - 5, // 22: ateom.Ateom.RunWorkload:input_type -> ateom.RunWorkloadRequest - 16, // 23: ateom.Ateom.CheckpointWorkload:input_type -> ateom.CheckpointWorkloadRequest - 18, // 24: ateom.Ateom.RestoreWorkload:input_type -> ateom.RestoreWorkloadRequest - 20, // 25: ateom.Ateom.GetWorkloadStats:input_type -> ateom.GetWorkloadStatsRequest - 23, // 26: ateom.Ateom.GetActiveWorkloadStats:input_type -> ateom.GetActiveWorkloadStatsRequest - 3, // 27: ateom.Ateom.TerminateWorkload:input_type -> ateom.TerminateWorkloadRequest - 15, // 28: ateom.Ateom.RunWorkload:output_type -> ateom.RunWorkloadResponse - 17, // 29: ateom.Ateom.CheckpointWorkload:output_type -> ateom.CheckpointWorkloadResponse - 19, // 30: ateom.Ateom.RestoreWorkload:output_type -> ateom.RestoreWorkloadResponse - 22, // 31: ateom.Ateom.GetWorkloadStats:output_type -> ateom.GetWorkloadStatsResponse - 24, // 32: ateom.Ateom.GetActiveWorkloadStats:output_type -> ateom.GetActiveWorkloadStatsResponse - 4, // 33: ateom.Ateom.TerminateWorkload:output_type -> ateom.TerminateWorkloadResponse - 28, // [28:34] is the sub-list for method output_type - 22, // [22:28] is the sub-list for method input_type - 22, // [22:22] is the sub-list for extension type_name - 22, // [22:22] is the sub-list for extension extendee - 0, // [0:22] is the sub-list for field type_name + 8, // 0: ateom.TerminateWorkloadRequest.spec:type_name -> ateom.WorkloadSpec + 3, // 1: ateom.TerminateWorkloadRequest.actor_dirs:type_name -> ateom.ActorDirs + 8, // 2: ateom.RunWorkloadRequest.spec:type_name -> ateom.WorkloadSpec + 26, // 3: ateom.RunWorkloadRequest.runtime_asset_paths:type_name -> ateom.RunWorkloadRequest.RuntimeAssetPathsEntry + 7, // 4: ateom.RunWorkloadRequest.egress_gateway:type_name -> ateom.EgressGateway + 3, // 5: ateom.RunWorkloadRequest.actor_dirs:type_name -> ateom.ActorDirs + 9, // 6: ateom.WorkloadSpec.containers:type_name -> ateom.Container + 14, // 7: ateom.Container.readyz:type_name -> ateom.Readyz + 11, // 8: ateom.Container.durable_dir_volume_mounts:type_name -> ateom.DurableDirVolumeMount + 10, // 9: ateom.Container.csi_volume_mounts:type_name -> ateom.VolumeMount + 12, // 10: ateom.Container.system_info_volume_mounts:type_name -> ateom.SystemInfoVolumeMount + 13, // 11: ateom.Container.image_volume_mounts:type_name -> ateom.ImageVolumeMount + 15, // 12: ateom.Readyz.http_get:type_name -> ateom.HTTPGetAction + 8, // 13: ateom.CheckpointWorkloadRequest.spec:type_name -> ateom.WorkloadSpec + 27, // 14: ateom.CheckpointWorkloadRequest.runtime_asset_paths:type_name -> ateom.CheckpointWorkloadRequest.RuntimeAssetPathsEntry + 0, // 15: ateom.CheckpointWorkloadRequest.scope:type_name -> ateom.SnapshotScope + 3, // 16: ateom.CheckpointWorkloadRequest.actor_dirs:type_name -> ateom.ActorDirs + 8, // 17: ateom.RestoreWorkloadRequest.spec:type_name -> ateom.WorkloadSpec + 28, // 18: ateom.RestoreWorkloadRequest.runtime_asset_paths:type_name -> ateom.RestoreWorkloadRequest.RuntimeAssetPathsEntry + 0, // 19: ateom.RestoreWorkloadRequest.scope:type_name -> ateom.SnapshotScope + 7, // 20: ateom.RestoreWorkloadRequest.egress_gateway:type_name -> ateom.EgressGateway + 3, // 21: ateom.RestoreWorkloadRequest.actor_dirs:type_name -> ateom.ActorDirs + 1, // 22: ateom.WorkloadStatsSample.sandbox_class:type_name -> ateom.SandboxClass + 2, // 23: ateom.WorkloadStatsSample.source:type_name -> ateom.StatsSource + 22, // 24: ateom.GetWorkloadStatsResponse.sample:type_name -> ateom.WorkloadStatsSample + 22, // 25: ateom.GetActiveWorkloadStatsResponse.samples:type_name -> ateom.WorkloadStatsSample + 6, // 26: ateom.Ateom.RunWorkload:input_type -> ateom.RunWorkloadRequest + 17, // 27: ateom.Ateom.CheckpointWorkload:input_type -> ateom.CheckpointWorkloadRequest + 19, // 28: ateom.Ateom.RestoreWorkload:input_type -> ateom.RestoreWorkloadRequest + 21, // 29: ateom.Ateom.GetWorkloadStats:input_type -> ateom.GetWorkloadStatsRequest + 24, // 30: ateom.Ateom.GetActiveWorkloadStats:input_type -> ateom.GetActiveWorkloadStatsRequest + 4, // 31: ateom.Ateom.TerminateWorkload:input_type -> ateom.TerminateWorkloadRequest + 16, // 32: ateom.Ateom.RunWorkload:output_type -> ateom.RunWorkloadResponse + 18, // 33: ateom.Ateom.CheckpointWorkload:output_type -> ateom.CheckpointWorkloadResponse + 20, // 34: ateom.Ateom.RestoreWorkload:output_type -> ateom.RestoreWorkloadResponse + 23, // 35: ateom.Ateom.GetWorkloadStats:output_type -> ateom.GetWorkloadStatsResponse + 25, // 36: ateom.Ateom.GetActiveWorkloadStats:output_type -> ateom.GetActiveWorkloadStatsResponse + 5, // 37: ateom.Ateom.TerminateWorkload:output_type -> ateom.TerminateWorkloadResponse + 32, // [32:38] is the sub-list for method output_type + 26, // [26:32] is the sub-list for method input_type + 26, // [26:26] is the sub-list for extension type_name + 26, // [26:26] is the sub-list for extension extendee + 0, // [0:26] is the sub-list for field type_name } func init() { file_ateom_proto_init() } @@ -1997,15 +2175,15 @@ func file_ateom_proto_init() { if File_ateom_proto != nil { return } - file_ateom_proto_msgTypes[2].OneofWrappers = []any{} - file_ateom_proto_msgTypes[15].OneofWrappers = []any{} + file_ateom_proto_msgTypes[3].OneofWrappers = []any{} + file_ateom_proto_msgTypes[16].OneofWrappers = []any{} type x struct{} out := protoimpl.TypeBuilder{ File: protoimpl.DescBuilder{ GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: unsafe.Slice(unsafe.StringData(file_ateom_proto_rawDesc), len(file_ateom_proto_rawDesc)), NumEnums: 3, - NumMessages: 25, + NumMessages: 26, NumExtensions: 0, NumServices: 1, }, diff --git a/internal/proto/ateompb/ateom.proto b/internal/proto/ateompb/ateom.proto index 15f57b09f1..f15fc48c52 100644 --- a/internal/proto/ateompb/ateom.proto +++ b/internal/proto/ateompb/ateom.proto @@ -106,6 +106,30 @@ service Ateom { rpc TerminateWorkload(TerminateWorkloadRequest) returns (TerminateWorkloadResponse) {} } +// ActorDirs is the set of per-actor directories atelet prepares on the volume +// it shares with ateom. ateom takes them from the RPC instead of deriving +// them from the actor UID. +// Every directory is under root_dir. +message ActorDirs { + string root_dir = 1; + // Holds one OCI bundle per container, named after the container. + string oci_bundle_dir = 2; + // runsc --root for the actor's sandbox. gVisor only. + string runsc_state_dir = 3; + // Where runsc writes .pid. gVisor only. + string pid_file_dir = 4; + // Where CheckpointWorkload writes the snapshot files. + string checkpoint_dir = 5; + // Where the snapshot files RestoreWorkload reads have been downloaded to. + string restore_dir = 6; + // Holds one subdirectory per durable-dir volume. + string durable_dir_volume_mounts_dir = 7; + // Holds one subdirectory per system-info volume. + string system_info_volume_roots_dir = 8; + // Holds one mount point per CSI volume. + string volumes_dir = 9; +} + message TerminateWorkloadRequest { string atespace = 1; string actor_name = 2; @@ -114,6 +138,7 @@ message TerminateWorkloadRequest { string actor_template_name = 5; string runsc_path = 6; WorkloadSpec spec = 7; + ActorDirs actor_dirs = 8; } message TerminateWorkloadResponse { @@ -145,6 +170,7 @@ message RunWorkloadRequest { // runtime default (unlimited for gVisor, the kata config for the micro-VM). int64 cpu_milli = 11; // CPU limit in millicores (1000 = one core). int64 memory_bytes = 12; // Memory limit in bytes. + ActorDirs actor_dirs = 13; } // EgressGateway configures tunneled egress for one actor activation. @@ -287,6 +313,7 @@ message CheckpointWorkloadRequest { // What content to include in the checkpoint. SnapshotScope scope = 10; + ActorDirs actor_dirs = 11; } message CheckpointWorkloadResponse { @@ -332,6 +359,7 @@ message RestoreWorkloadRequest { // these are ignored. Zero means "unset": keep the runtime default. int64 cpu_milli = 14; // CPU limit in millicores (1000 = one core). int64 memory_bytes = 15; // Memory limit in bytes. + ActorDirs actor_dirs = 16; } message RestoreWorkloadResponse {