From 13895a98f5c4e036c4215d2b00405586bf769f23 Mon Sep 17 00:00:00 2001 From: Taahir Ahmed Date: Tue, 2 Jun 2026 18:50:24 -0700 Subject: [PATCH] ateom/atelet: Remove actor template name/namespace from directories Earlier in development, the actor ID was namespaced under its corresponding ActorTemplate. This is no longer the case --- Actor IDs are now unique within the substrate database, and we want to support migration of actors between ActorTemplates (for upgrade scenarios). This means that some of the the things atelet/ateom do no longer make sense: * The actor state directory no longer needs to be qualified with ActorTemplate information. * The actor logs should not be qualified with the ActorTemplate information * The ActorTemplate information no longer needs to be passed in --- .../internal/controlapi/workflow_pause.go | 8 +- .../internal/controlapi/workflow_resume.go | 32 +++-- .../internal/controlapi/workflow_suspend.go | 8 +- cmd/atelet/main.go | 98 +++++++--------- cmd/atelet/main_test.go | 55 ++++----- cmd/atelet/oci.go | 4 +- cmd/ateom-gvisor/internal/ateom/logger.go | 18 +-- .../internal/ateom/logger_test.go | 16 +-- cmd/ateom-gvisor/main.go | 40 +++---- cmd/ateom-gvisor/runsc.go | 26 ++--- docs/observability.md | 2 - internal/ateompath/ateompath.go | 44 +++---- internal/proto/ateletpb/atelet.pb.go | 110 +++++------------- internal/proto/ateletpb/atelet.proto | 22 ++-- internal/proto/ateompb/ateom.pb.go | 100 ++++------------ internal/proto/ateompb/ateom.proto | 21 ++-- internal/resources/validate.go | 24 +--- internal/resources/validate_test.go | 41 +++---- 18 files changed, 239 insertions(+), 430 deletions(-) diff --git a/cmd/ateapi/internal/controlapi/workflow_pause.go b/cmd/ateapi/internal/controlapi/workflow_pause.go index 4617c465e..84952c9d6 100644 --- a/cmd/ateapi/internal/controlapi/workflow_pause.go +++ b/cmd/ateapi/internal/controlapi/workflow_pause.go @@ -134,11 +134,9 @@ func (s *CallAteletPauseStep) Execute(ctx context.Context, input *PauseInput, st } req := &ateletpb.CheckpointRequest{ - TargetAteomUid: state.Actor.GetAteomPodUid(), - ActorTemplateNamespace: state.Actor.GetActorTemplateNamespace(), - ActorTemplateName: state.Actor.GetActorTemplateName(), - ActorId: state.Actor.GetActorId(), - Runsc: runscCfg, + TargetAteomUid: state.Actor.GetAteomPodUid(), + ActorId: state.Actor.GetActorId(), + Runsc: runscCfg, Spec: &ateletpb.WorkloadSpec{ PauseImage: state.ActorTemplate.Spec.PauseImage, }, diff --git a/cmd/ateapi/internal/controlapi/workflow_resume.go b/cmd/ateapi/internal/controlapi/workflow_resume.go index 83678d7ed..6cb7557db 100644 --- a/cmd/ateapi/internal/controlapi/workflow_resume.go +++ b/cmd/ateapi/internal/controlapi/workflow_resume.go @@ -206,12 +206,10 @@ func (s *CallAteletRestoreStep) Execute(ctx context.Context, input *ResumeInput, slog.InfoContext(ctx, "Actor has snapshot; Restoring from snapshot") req := &ateletpb.RestoreRequest{ - TargetAteomUid: state.Actor.GetAteomPodUid(), - ActorTemplateNamespace: state.Actor.GetActorTemplateNamespace(), - ActorTemplateName: state.Actor.GetActorTemplateName(), - ActorId: state.Actor.GetActorId(), - Runsc: runscCfg, - Spec: workloadSpec, + TargetAteomUid: state.Actor.GetAteomPodUid(), + ActorId: state.Actor.GetActorId(), + Runsc: runscCfg, + Spec: workloadSpec, } switch state.Actor.GetLatestSnapshotInfo().GetType() { case ateapipb.SnapshotType_SNAPSHOT_TYPE_LOCAL: @@ -243,13 +241,11 @@ func (s *CallAteletRestoreStep) Execute(ctx context.Context, input *ResumeInput, snapshot := state.ActorTemplate.Status.GoldenSnapshot req := &ateletpb.RestoreRequest{ - TargetAteomUid: state.Actor.GetAteomPodUid(), - ActorTemplateNamespace: state.Actor.GetActorTemplateNamespace(), - ActorTemplateName: state.Actor.GetActorTemplateName(), - ActorId: state.Actor.GetActorId(), - Runsc: runscCfg, - Spec: workloadSpec, - Type: ateletpb.CheckpointType_CHECKPOINT_TYPE_EXTERNAL, + TargetAteomUid: state.Actor.GetAteomPodUid(), + ActorId: state.Actor.GetActorId(), + Runsc: runscCfg, + Spec: workloadSpec, + Type: ateletpb.CheckpointType_CHECKPOINT_TYPE_EXTERNAL, Config: &ateletpb.RestoreRequest_ExternalConfig{ ExternalConfig: &ateletpb.ExternalCheckpointConfiguration{ SnapshotUriPrefix: snapshot, @@ -264,12 +260,10 @@ func (s *CallAteletRestoreStep) Execute(ctx context.Context, input *ResumeInput, } else { slog.InfoContext(ctx, "Actor has no snapshot; ActorTemplate has no golden snapshot; Booting from ActorTemplate spec") req := &ateletpb.RunRequest{ - TargetAteomUid: state.Actor.GetAteomPodUid(), - ActorTemplateNamespace: state.Actor.GetActorTemplateNamespace(), - ActorTemplateName: state.Actor.GetActorTemplateName(), - ActorId: state.Actor.GetActorId(), - Runsc: runscCfg, - Spec: workloadSpec, + TargetAteomUid: state.Actor.GetAteomPodUid(), + ActorId: state.Actor.GetActorId(), + Runsc: runscCfg, + Spec: workloadSpec, } _, err = client.Run(ctx, req) if err != nil { diff --git a/cmd/ateapi/internal/controlapi/workflow_suspend.go b/cmd/ateapi/internal/controlapi/workflow_suspend.go index cd3d63870..92d1ffb16 100644 --- a/cmd/ateapi/internal/controlapi/workflow_suspend.go +++ b/cmd/ateapi/internal/controlapi/workflow_suspend.go @@ -136,11 +136,9 @@ func (s *CallAteletSuspendStep) Execute(ctx context.Context, input *SuspendInput } req := &ateletpb.CheckpointRequest{ - TargetAteomUid: state.Actor.GetAteomPodUid(), - ActorTemplateNamespace: state.Actor.GetActorTemplateNamespace(), - ActorTemplateName: state.Actor.GetActorTemplateName(), - ActorId: state.Actor.GetActorId(), - Runsc: runscCfg, + TargetAteomUid: state.Actor.GetAteomPodUid(), + ActorId: state.Actor.GetActorId(), + Runsc: runscCfg, Spec: &ateletpb.WorkloadSpec{ PauseImage: state.ActorTemplate.Spec.PauseImage, }, diff --git a/cmd/atelet/main.go b/cmd/atelet/main.go index 7b3316038..046083a47 100644 --- a/cmd/atelet/main.go +++ b/cmd/atelet/main.go @@ -296,13 +296,14 @@ func (s *AteomHerder) Run(ctx context.Context, req *ateletpb.RunRequest) (*atele return nil, err } - if err := resetActorDirs(req.GetActorTemplateNamespace(), req.GetActorTemplateName(), req.GetActorId()); err != nil { + if err := resetActorDirs(req.GetActorId()); err != nil { return nil, fmt.Errorf("while resetting actor dirs: %w", err) } if err := s.prepareOCIBundles(ctx, - req.GetActorTemplateNamespace(), req.GetActorTemplateName(), req.GetActorId(), - req.GetSpec(), req.GetTargetAteomUid(), + req.GetActorId(), + req.GetSpec(), + req.GetTargetAteomUid(), ); err != nil { return nil, err } @@ -315,11 +316,9 @@ func (s *AteomHerder) Run(ctx context.Context, req *ateletpb.RunRequest) (*atele // Tell ateom to do runsc create + runsc start for pause container and // all application containers. if _, err := client.RunWorkload(ctx, &ateompb.RunWorkloadRequest{ - ActorTemplateNamespace: req.GetActorTemplateNamespace(), - ActorTemplateName: req.GetActorTemplateName(), - ActorId: req.GetActorId(), - RunscPath: runscPath, - Spec: buildAteomWorkloadSpec(req.GetSpec()), + ActorId: req.GetActorId(), + RunscPath: runscPath, + Spec: buildAteomWorkloadSpec(req.GetSpec()), }); err != nil { return nil, fmt.Errorf("while calling ateom.RunWorkload: %w", err) } @@ -343,7 +342,7 @@ func initSnapshotSizeMetric() error { return err } -func recordSnapshotSize(ctx context.Context, kind, path, atNamespace, atName string) { +func recordSnapshotSize(ctx context.Context, kind, path string) { if snapshotSizeBytes == nil { return } @@ -358,8 +357,6 @@ func recordSnapshotSize(ctx context.Context, kind, path, atNamespace, atName str } snapshotSizeBytes.Record(ctx, fi.Size(), metric.WithAttributes( attribute.String("kind", kind), - attribute.String("actor_template_namespace", atNamespace), - attribute.String("actor_template_name", atName), )) } @@ -373,7 +370,7 @@ func (s *AteomHerder) Checkpoint(ctx context.Context, req *ateletpb.CheckpointRe return nil, err } - checkpointDir := ateompath.CheckpointStateDir(req.GetActorTemplateNamespace(), req.GetActorTemplateName(), req.GetActorId()) + checkpointDir := ateompath.CheckpointStateDir(req.GetActorId()) client, err := s.dialAteom(ctx, req.GetTargetAteomUid()) if err != nil { @@ -382,17 +379,13 @@ func (s *AteomHerder) Checkpoint(ctx context.Context, req *ateletpb.CheckpointRe // Tell ateom to take checkpoint and delete containers. if _, err := client.CheckpointWorkload(ctx, &ateompb.CheckpointWorkloadRequest{ - ActorTemplateNamespace: req.GetActorTemplateNamespace(), - ActorTemplateName: req.GetActorTemplateName(), - ActorId: req.GetActorId(), - RunscPath: runscPath, - Spec: buildAteomWorkloadSpec(req.GetSpec()), + ActorId: req.GetActorId(), + RunscPath: runscPath, + Spec: buildAteomWorkloadSpec(req.GetSpec()), }); err != nil { return nil, fmt.Errorf("while calling ateom.CheckpointWorkload: %w", err) } - ns, tmpl, actorID := req.GetActorTemplateNamespace(), req.GetActorTemplateName(), req.GetActorId() - switch req.GetType() { case ateletpb.CheckpointType_CHECKPOINT_TYPE_EXTERNAL: if err := s.uploadExternalCheckpoint(ctx, req, checkpointDir); err != nil { @@ -406,7 +399,7 @@ func (s *AteomHerder) Checkpoint(ctx context.Context, req *ateletpb.CheckpointRe return nil, fmt.Errorf("unexpected checkpoint type: %v", req.GetType()) } - if err := resetActorDirs(ns, tmpl, actorID); err != nil { + if err := resetActorDirs(req.GetActorId()); err != nil { return nil, fmt.Errorf("while resetting actor dirs: %w", err) } @@ -414,17 +407,15 @@ func (s *AteomHerder) Checkpoint(ctx context.Context, req *ateletpb.CheckpointRe } func (s *AteomHerder) moveLocalCheckpoint(ctx context.Context, req *ateletpb.CheckpointRequest, checkpointDir string) error { - localCheckpointPath := filepath.Join(ateompath.LocalCheckpointsDir(req.GetActorTemplateNamespace(), req.GetActorTemplateName(), req.GetActorId()), req.GetLocalConfig().GetSnapshotPrefix()) + localCheckpointPath := filepath.Join(ateompath.LocalCheckpointsDir(req.GetActorId()), req.GetLocalConfig().GetSnapshotPrefix()) if err := os.MkdirAll(localCheckpointPath, 0o700); err != nil { return fmt.Errorf("while creating local checkpoint directory: %w", err) } - ns, tmpl := req.GetActorTemplateNamespace(), req.GetActorTemplateName() - for _, fileName := range []string{"checkpoint.img", "pages.img", "pages_meta.img"} { src := filepath.Join(checkpointDir, fileName) dst := filepath.Join(localCheckpointPath, fileName) - recordSnapshotSize(ctx, strings.TrimSuffix(fileName, ".img"), src, ns, tmpl) + recordSnapshotSize(ctx, strings.TrimSuffix(fileName, ".img"), src) if err := os.Rename(src, dst); err != nil { return fmt.Errorf("failed to move %s to %s: %w", src, dst, err) @@ -435,14 +426,13 @@ func (s *AteomHerder) moveLocalCheckpoint(ctx context.Context, req *ateletpb.Che } func (s *AteomHerder) uploadExternalCheckpoint(ctx context.Context, req *ateletpb.CheckpointRequest, checkpointDir string) error { - ns, tmpl := req.GetActorTemplateNamespace(), req.GetActorTemplateName() prefix := strings.TrimSuffix(req.GetExternalConfig().GetSnapshotUriPrefix(), "/") checkpointImgPath := filepath.Join(checkpointDir, "checkpoint.img") pagesImgPath := filepath.Join(checkpointDir, "pages.img") pagesMetaImgPath := filepath.Join(checkpointDir, "pages_meta.img") - recordSnapshotSize(ctx, "checkpoint", checkpointImgPath, ns, tmpl) + recordSnapshotSize(ctx, "checkpoint", checkpointImgPath) // Upload checkpoint from local dir. if err := ategcs.SendLocalFileToGCSWithZstd(ctx, s.gcsClient, @@ -452,14 +442,14 @@ func (s *AteomHerder) uploadExternalCheckpoint(ctx context.Context, req *ateletp return fmt.Errorf("while uploading checkpoint.img to GCS: %w", err) } - recordSnapshotSize(ctx, "pages", pagesImgPath, ns, tmpl) + recordSnapshotSize(ctx, "pages", pagesImgPath) if err := uploadIfExists(ctx, s.gcsClient, prefix+"/pages.img.zstd", pagesImgPath, ); err != nil { return err } - recordSnapshotSize(ctx, "pages_meta", pagesMetaImgPath, ns, tmpl) + recordSnapshotSize(ctx, "pages_meta", pagesMetaImgPath) if err := uploadIfExists(ctx, s.gcsClient, prefix+"/pages_meta.img.zstd", pagesMetaImgPath, @@ -479,13 +469,13 @@ func (s *AteomHerder) Restore(ctx context.Context, req *ateletpb.RestoreRequest) return nil, err } - ns, tmpl, actorID := req.GetActorTemplateNamespace(), req.GetActorTemplateName(), req.GetActorId() + actorID := req.GetActorId() - if err := resetActorDirs(ns, tmpl, actorID); err != nil { + if err := resetActorDirs(actorID); err != nil { return nil, fmt.Errorf("while resetting actor dirs: %w", err) } - checkpointDir := ateompath.RestoreStateDir(req.GetActorTemplateNamespace(), req.GetActorTemplateName(), req.GetActorId()) + checkpointDir := ateompath.RestoreStateDir(req.GetActorId()) switch req.GetType() { case ateletpb.CheckpointType_CHECKPOINT_TYPE_EXTERNAL: if err := s.downloadExternalCheckpoint(ctx, req.GetExternalConfig().GetSnapshotUriPrefix(), checkpointDir); err != nil { @@ -493,7 +483,7 @@ func (s *AteomHerder) Restore(ctx context.Context, req *ateletpb.RestoreRequest) } case ateletpb.CheckpointType_CHECKPOINT_TYPE_LOCAL: // TODO(dberkov): the old pause checkpoint files are not deleted after they are copied to checkpointDir. This needs to be fixed in following PR. - localCheckpointDir := ateompath.LocalCheckpointsDir(req.GetActorTemplateNamespace(), req.GetActorTemplateName(), req.GetActorId()) + localCheckpointDir := ateompath.LocalCheckpointsDir(req.GetActorId()) if err := s.copyLocalCheckpoint(ctx, req.GetLocalConfig().GetSnapshotPrefix(), localCheckpointDir, checkpointDir); err != nil { return nil, err } @@ -501,9 +491,7 @@ func (s *AteomHerder) Restore(ctx context.Context, req *ateletpb.RestoreRequest) return nil, fmt.Errorf("unexpected checkpoint type: %v", req.GetType()) } - if err := s.prepareOCIBundles(ctx, ns, tmpl, actorID, - req.GetSpec(), req.GetTargetAteomUid(), - ); err != nil { + if err := s.prepareOCIBundles(ctx, actorID, req.GetSpec(), req.GetTargetAteomUid()); err != nil { return nil, err } @@ -515,11 +503,9 @@ func (s *AteomHerder) Restore(ctx context.Context, req *ateletpb.RestoreRequest) // Tell ateom to do runsc create + runsc restore for pause container and // all application containers. if _, err := client.RestoreWorkload(ctx, &ateompb.RestoreWorkloadRequest{ - ActorTemplateNamespace: ns, - ActorTemplateName: tmpl, - ActorId: actorID, - RunscPath: runscPath, - Spec: buildAteomWorkloadSpec(req.GetSpec()), + ActorId: actorID, + RunscPath: runscPath, + Spec: buildAteomWorkloadSpec(req.GetSpec()), }); err != nil { return nil, fmt.Errorf("while calling ateom.RestoreWorkload: %w", err) } @@ -612,7 +598,7 @@ func (s *AteomHerder) fetchRunscAndPrep(ctx context.Context, runscCfg *ateletpb. // container and every application container in spec, in parallel. func (s *AteomHerder) prepareOCIBundles( ctx context.Context, - actorTemplateNamespace, actorTemplateName, actorID string, + actorID string, spec *ateletpb.WorkloadSpec, targetAteomUid string, ) error { @@ -621,7 +607,7 @@ func (s *AteomHerder) prepareOCIBundles( // Populate the per-actor identity directory that gets bind-mounted into // the application containers. Regenerated on every resume, so it carries // the correct per-actor ID even when restoring from the golden snapshot. - identityDir := ateompath.ActorIdentityDirPath(actorTemplateNamespace, actorTemplateName, actorID) + identityDir := ateompath.ActorIdentityDirPath(actorID) if err := os.MkdirAll(identityDir, 0o755); err != nil { return fmt.Errorf("while creating actor identity dir: %w", err) } @@ -636,7 +622,7 @@ func (s *AteomHerder) prepareOCIBundles( if err := prepareOCIDirectory( gCtx, s.pullCache, - actorTemplateNamespace, actorTemplateName, actorID, + actorID, "pause", spec.GetPauseImage(), []string{"/pause"}, @@ -664,7 +650,7 @@ func (s *AteomHerder) prepareOCIBundles( if err := prepareOCIDirectory( gCtx, s.pullCache, - actorTemplateNamespace, actorTemplateName, actorID, + actorID, ctr.GetName(), ctr.GetImage(), ctr.GetCommand(), @@ -754,11 +740,11 @@ func (d *AteomDialer) DialAteomPod(ctx context.Context, podUID string) (*grpc.Cl // boundary, before any path is built. The field rules live in // internal/resources so other components can apply them at their boundaries. func validateRunRequest(req *ateletpb.RunRequest) error { - return validateActorRequest(req.GetActorTemplateNamespace(), req.GetActorTemplateName(), req.GetActorId(), req.GetTargetAteomUid(), req.GetSpec()) + return validateActorRequest(req.GetActorId(), req.GetTargetAteomUid(), req.GetSpec()) } func validateCheckpointRequest(req *ateletpb.CheckpointRequest) error { - if err := validateActorRequest(req.GetActorTemplateNamespace(), req.GetActorTemplateName(), req.GetActorId(), req.GetTargetAteomUid(), req.GetSpec()); err != nil { + if err := validateActorRequest(req.GetActorId(), req.GetTargetAteomUid(), req.GetSpec()); err != nil { return err } switch req.GetType() { @@ -777,7 +763,7 @@ func validateCheckpointRequest(req *ateletpb.CheckpointRequest) error { } func validateRestoreRequest(req *ateletpb.RestoreRequest) error { - if err := validateActorRequest(req.GetActorTemplateNamespace(), req.GetActorTemplateName(), req.GetActorId(), req.GetTargetAteomUid(), req.GetSpec()); err != nil { + if err := validateActorRequest(req.GetActorId(), req.GetTargetAteomUid(), req.GetSpec()); err != nil { return err } switch req.GetType() { @@ -797,8 +783,8 @@ func validateRestoreRequest(req *ateletpb.RestoreRequest) error { // validateActorRequest is the shared core for the fields common to all three // RPCs. -func validateActorRequest(namespace, template, actorID, targetAteomUID string, spec *ateletpb.WorkloadSpec) error { - if err := resources.ValidateActorRef(namespace, template, actorID); err != nil { +func validateActorRequest(actorID, targetAteomUID string, spec *ateletpb.WorkloadSpec) error { + if err := resources.ValidateActorRef(actorID); err != nil { return err } if err := resources.ValidateAteomUID(targetAteomUID); err != nil { @@ -850,10 +836,10 @@ func writeFileAtomic(path string, data []byte, perm os.FileMode) error { return dir.Sync() } -func resetActorDirs(actorTemplateNamespace, actorTemplateName, actorID string) error { +func resetActorDirs(actorID string) error { // Explicitly leave runsc logs dir untouched. - bundleDir := ateompath.OCIBundleDir(actorTemplateNamespace, actorTemplateName, actorID) + bundleDir := ateompath.OCIBundleDir(actorID) if err := os.RemoveAll(bundleDir); err != nil { return fmt.Errorf("while deleting bundle dir: %w", err) } @@ -861,7 +847,7 @@ func resetActorDirs(actorTemplateNamespace, actorTemplateName, actorID string) e return fmt.Errorf("while creating bundle dir: %w", err) } - runscDir := ateompath.RunSCStateDir(actorTemplateNamespace, actorTemplateName, actorID) + runscDir := ateompath.RunSCStateDir(actorID) if err := os.RemoveAll(runscDir); err != nil { return fmt.Errorf("while deleting runsc state dir: %w", err) } @@ -869,7 +855,7 @@ func resetActorDirs(actorTemplateNamespace, actorTemplateName, actorID string) e return fmt.Errorf("while creating runsc state dir: %w", err) } - pidFileDir := ateompath.PIDFileDir(actorTemplateNamespace, actorTemplateName, actorID) + pidFileDir := ateompath.PIDFileDir(actorID) if err := os.RemoveAll(pidFileDir); err != nil { return fmt.Errorf("while deleting PID file dir: %w", err) } @@ -877,7 +863,7 @@ func resetActorDirs(actorTemplateNamespace, actorTemplateName, actorID string) e return fmt.Errorf("while creating PID file dir: %w", err) } - checkpointDir := ateompath.CheckpointStateDir(actorTemplateNamespace, actorTemplateName, actorID) + checkpointDir := ateompath.CheckpointStateDir(actorID) if err := os.RemoveAll(checkpointDir); err != nil { return fmt.Errorf("while deleting checkpoint-state dir: %w", err) } @@ -885,7 +871,7 @@ func resetActorDirs(actorTemplateNamespace, actorTemplateName, actorID string) e return fmt.Errorf("while creating checkpoint-state dir: %w", err) } - restoreStateDir := ateompath.RestoreStateDir(actorTemplateNamespace, actorTemplateName, actorID) + restoreStateDir := ateompath.RestoreStateDir(actorID) if err := os.RemoveAll(restoreStateDir); err != nil { return fmt.Errorf("while deleting restore-state dir: %w", err) } @@ -895,7 +881,7 @@ func resetActorDirs(actorTemplateNamespace, actorTemplateName, actorID string) e // World-readable (0o755): bind-mounted into the actor, whose workload // reads it through the gofer. - identityDir := ateompath.ActorIdentityDirPath(actorTemplateNamespace, actorTemplateName, actorID) + identityDir := ateompath.ActorIdentityDirPath(actorID) if err := os.RemoveAll(identityDir); err != nil { return fmt.Errorf("while deleting actor identity dir: %w", err) } diff --git a/cmd/atelet/main_test.go b/cmd/atelet/main_test.go index ddf86370b..139fa0a62 100644 --- a/cmd/atelet/main_test.go +++ b/cmd/atelet/main_test.go @@ -76,24 +76,23 @@ func TestWriteFileAtomic(t *testing.T) { } func TestValidateActorRequest(t *testing.T) { - const okNS, okTmpl, okID, okUID = "ate-demo", "counter", "counter-1", "422938ba-8860-4983-a25d-d6bcb0a69d4e" + const okID, okUID = "counter-1", "422938ba-8860-4983-a25d-d6bcb0a69d4e" okSpec := &ateletpb.WorkloadSpec{Containers: []*ateletpb.Container{{Name: "worker"}}} tests := []struct { - name string - ns, tmpl, id, uid string - spec *ateletpb.WorkloadSpec - wantErr bool + name string + id, uid string + spec *ateletpb.WorkloadSpec + wantErr bool }{ - {"all valid", okNS, okTmpl, okID, okUID, okSpec, false}, - {"bad namespace", "../x", okTmpl, okID, okUID, okSpec, true}, - {"bad actor id", okNS, okTmpl, "../x", okUID, okSpec, true}, - {"bad uid", okNS, okTmpl, okID, "../x", okSpec, true}, - {"bad container", okNS, okTmpl, okID, okUID, &ateletpb.WorkloadSpec{Containers: []*ateletpb.Container{{Name: "../x"}}}, true}, + {"all valid", okID, okUID, okSpec, false}, + {"bad actor id", "../x", okUID, okSpec, true}, + {"bad uid", okID, "../x", okSpec, true}, + {"bad container", okID, okUID, &ateletpb.WorkloadSpec{Containers: []*ateletpb.Container{{Name: "../x"}}}, true}, } for _, tc := range tests { t.Run(tc.name, func(t *testing.T) { - if err := validateActorRequest(tc.ns, tc.tmpl, tc.id, tc.uid, tc.spec); (err != nil) != tc.wantErr { + if err := validateActorRequest(tc.id, tc.uid, tc.spec); (err != nil) != tc.wantErr { t.Errorf("validateActorRequest err = %v, wantErr %v", err, tc.wantErr) } }) @@ -105,22 +104,18 @@ func TestValidateActorRequest(t *testing.T) { // break one field per case. func validRunRequest() *ateletpb.RunRequest { return &ateletpb.RunRequest{ - ActorTemplateNamespace: "ate-demo", - ActorTemplateName: "counter", - ActorId: "counter-1", - TargetAteomUid: "422938ba-8860-4983-a25d-d6bcb0a69d4e", - Spec: &ateletpb.WorkloadSpec{Containers: []*ateletpb.Container{{Name: "worker"}}}, + ActorId: "counter-1", + TargetAteomUid: "422938ba-8860-4983-a25d-d6bcb0a69d4e", + Spec: &ateletpb.WorkloadSpec{Containers: []*ateletpb.Container{{Name: "worker"}}}, } } func validCheckpointRequest() *ateletpb.CheckpointRequest { return &ateletpb.CheckpointRequest{ - ActorTemplateNamespace: "ate-demo", - ActorTemplateName: "counter", - ActorId: "counter-1", - TargetAteomUid: "422938ba-8860-4983-a25d-d6bcb0a69d4e", - Spec: &ateletpb.WorkloadSpec{Containers: []*ateletpb.Container{{Name: "worker"}}}, - Type: ateletpb.CheckpointType_CHECKPOINT_TYPE_EXTERNAL, + ActorId: "counter-1", + TargetAteomUid: "422938ba-8860-4983-a25d-d6bcb0a69d4e", + Spec: &ateletpb.WorkloadSpec{Containers: []*ateletpb.Container{{Name: "worker"}}}, + Type: ateletpb.CheckpointType_CHECKPOINT_TYPE_EXTERNAL, Config: &ateletpb.CheckpointRequest_ExternalConfig{ ExternalConfig: &ateletpb.ExternalCheckpointConfiguration{ SnapshotUriPrefix: "gs://bucket/actors/1/snapshots/2/", @@ -131,12 +126,10 @@ func validCheckpointRequest() *ateletpb.CheckpointRequest { func validRestoreRequest() *ateletpb.RestoreRequest { return &ateletpb.RestoreRequest{ - ActorTemplateNamespace: "ate-demo", - ActorTemplateName: "counter", - ActorId: "counter-1", - TargetAteomUid: "422938ba-8860-4983-a25d-d6bcb0a69d4e", - Spec: &ateletpb.WorkloadSpec{Containers: []*ateletpb.Container{{Name: "worker"}}}, - Type: ateletpb.CheckpointType_CHECKPOINT_TYPE_EXTERNAL, + ActorId: "counter-1", + TargetAteomUid: "422938ba-8860-4983-a25d-d6bcb0a69d4e", + Spec: &ateletpb.WorkloadSpec{Containers: []*ateletpb.Container{{Name: "worker"}}}, + Type: ateletpb.CheckpointType_CHECKPOINT_TYPE_EXTERNAL, Config: &ateletpb.RestoreRequest_ExternalConfig{ ExternalConfig: &ateletpb.ExternalCheckpointConfiguration{ SnapshotUriPrefix: "gs://bucket/actors/1/snapshots/2/", @@ -288,21 +281,21 @@ func TestRPCBoundariesReject(t *testing.T) { t.Run("Run", func(t *testing.T) { _, err := s.Run(ctx, &ateletpb.RunRequest{ - ActorTemplateNamespace: okNS, ActorTemplateName: okTmpl, ActorId: okID, + ActorId: okID, TargetAteomUid: badUID, Spec: okSpec, }) wantInvalidArgument(t, "Run", err) }) t.Run("Checkpoint", func(t *testing.T) { _, err := s.Checkpoint(ctx, &ateletpb.CheckpointRequest{ - ActorTemplateNamespace: okNS, ActorTemplateName: okTmpl, ActorId: okID, + ActorId: okID, TargetAteomUid: badUID, Spec: okSpec, }) wantInvalidArgument(t, "Checkpoint", err) }) t.Run("Restore", func(t *testing.T) { _, err := s.Restore(ctx, &ateletpb.RestoreRequest{ - ActorTemplateNamespace: okNS, ActorTemplateName: okTmpl, ActorId: okID, + ActorId: okID, TargetAteomUid: badUID, Spec: okSpec, }) wantInvalidArgument(t, "Restore", err) diff --git a/cmd/atelet/oci.go b/cmd/atelet/oci.go index 4451f6362..220267fef 100644 --- a/cmd/atelet/oci.go +++ b/cmd/atelet/oci.go @@ -51,14 +51,14 @@ const ( ActorIDFileName = "actor-id" ) -func prepareOCIDirectory(ctx context.Context, pullCache *memorypullcache.MemoryPullCache, actorTemplateNamespace, actorTemplateName, actorID, containerName, ref string, args []string, env []string, annotations map[string]string, netns string, identityDir string) error { +func prepareOCIDirectory(ctx context.Context, pullCache *memorypullcache.MemoryPullCache, actorID, containerName, ref string, args []string, env []string, annotations map[string]string, netns string, identityDir string) error { tracer := otel.Tracer("prepareOCIDirectory") ctx, span := tracer.Start(ctx, "prepareOCIDirectory") span.SetAttributes(attribute.String("image", ref)) defer span.End() - bundlePath := ateompath.OCIBundlePath(actorTemplateNamespace, actorTemplateName, actorID, containerName) + bundlePath := ateompath.OCIBundlePath(actorID, containerName) rootPath := path.Join(bundlePath, "rootfs") if err := os.RemoveAll(rootPath); err != nil { diff --git a/cmd/ateom-gvisor/internal/ateom/logger.go b/cmd/ateom-gvisor/internal/ateom/logger.go index 7e3775a78..cf84fb3ce 100644 --- a/cmd/ateom-gvisor/internal/ateom/logger.go +++ b/cmd/ateom-gvisor/internal/ateom/logger.go @@ -62,14 +62,12 @@ func NewActorLogger(w io.Writer, isOnGCE bool) *ActorLogger { } // EmitLifecycleLog logs a synthetic actor lifecycle event. -func (al *ActorLogger) EmitLifecycleLog(msg, actorID, actorTemplateName, actorTemplateNamespace string) { +func (al *ActorLogger) EmitLifecycleLog(msg, actorID string) { envelope := map[string]any{ "time": time.Now().Format(time.RFC3339Nano), "message": msg, al.labelsKey: map[string]string{ - "ate.dev/actor_id": actorID, - "ate.dev/actor_template_name": actorTemplateName, - "ate.dev/actor_template_namespace": actorTemplateNamespace, + "ate.dev/actor_id": actorID, }, } if envBytes, err := json.Marshal(envelope); err == nil { @@ -79,20 +77,20 @@ func (al *ActorLogger) EmitLifecycleLog(msg, actorID, actorTemplateName, actorTe } // StartJSONLogPipe intercepts container raw stdout/stderr streams and pipes them through the logger. -func (al *ActorLogger) StartJSONLogPipe(actorID, actorTemplateName, actorTemplateNamespace string) (io.WriteCloser, error) { +func (al *ActorLogger) StartJSONLogPipe(actorID string) (io.WriteCloser, error) { pr, pw, err := os.Pipe() if err != nil { return nil, err } go func() { - al.WrapContainerLogs(pr, actorID, actorTemplateName, actorTemplateNamespace) + al.WrapContainerLogs(pr, actorID) pr.Close() }() return pw, nil } // WrapContainerLogs reads log lines from r, parses them, and logs them in a unified structured format. -func (al *ActorLogger) WrapContainerLogs(r io.Reader, actorID, actorTemplateName, actorTemplateNamespace string) { +func (al *ActorLogger) WrapContainerLogs(r io.Reader, actorID string) { rdr := bufio.NewReader(r) for { lineBytes, err := rdr.ReadBytes('\n') @@ -122,9 +120,7 @@ func (al *ActorLogger) WrapContainerLogs(r io.Reader, actorID, actorTemplateName "time": time.Now().Format(time.RFC3339Nano), "message": string(lineBytes), al.labelsKey: map[string]string{ - "ate.dev/actor_id": actorID, - "ate.dev/actor_template_name": actorTemplateName, - "ate.dev/actor_template_namespace": actorTemplateNamespace, + "ate.dev/actor_id": actorID, }, } } else { @@ -137,8 +133,6 @@ func (al *ActorLogger) WrapContainerLogs(r io.Reader, actorID, actorTemplateName m[al.labelsKey] = labels } labels["ate.dev/actor_id"] = actorID - labels["ate.dev/actor_template_name"] = actorTemplateName - labels["ate.dev/actor_template_namespace"] = actorTemplateNamespace envelope = m } diff --git a/cmd/ateom-gvisor/internal/ateom/logger_test.go b/cmd/ateom-gvisor/internal/ateom/logger_test.go index 5566beff5..bd48827a9 100644 --- a/cmd/ateom-gvisor/internal/ateom/logger_test.go +++ b/cmd/ateom-gvisor/internal/ateom/logger_test.go @@ -28,7 +28,7 @@ func TestWrapContainerLogs(t *testing.T) { var buf bytes.Buffer al := NewActorLogger(&buf, false) - al.WrapContainerLogs(rdr, "act-1", "tmpl-1", "default") + al.WrapContainerLogs(rdr, "act-1") var m map[string]any if err := json.Unmarshal(buf.Bytes(), &m); err != nil { @@ -57,12 +57,6 @@ func TestWrapContainerLogs(t *testing.T) { if labels["ate.dev/actor_id"] != "act-1" { t.Errorf("got actor_id = %v, want 'act-1'", labels["ate.dev/actor_id"]) } - if labels["ate.dev/actor_template_name"] != "tmpl-1" { - t.Errorf("got actor_template_name = %v, want 'tmpl-1'", labels["ate.dev/actor_template_name"]) - } - if labels["ate.dev/actor_template_namespace"] != "default" { - t.Errorf("got actor_template_namespace = %v, want 'default'", labels["ate.dev/actor_template_namespace"]) - } } func TestWrapContainerLogs_JSONInput(t *testing.T) { @@ -72,7 +66,7 @@ func TestWrapContainerLogs_JSONInput(t *testing.T) { var buf bytes.Buffer al := NewActorLogger(&buf, false) - al.WrapContainerLogs(rdr, "act-1", "tmpl-1", "default") + al.WrapContainerLogs(rdr, "act-1") dec := json.NewDecoder(&buf) dec.UseNumber() @@ -161,7 +155,7 @@ func TestWrapContainerLogs_MergeLabels(t *testing.T) { var buf bytes.Buffer al := NewActorLogger(&buf, false) // labelsKey will be "labels" - al.WrapContainerLogs(rdr, "act-1", "tmpl-1", "default") + al.WrapContainerLogs(rdr, "act-1") var m map[string]any if err := json.Unmarshal(buf.Bytes(), &m); err != nil { @@ -194,7 +188,7 @@ func TestWrapContainerLogs_LabelCollision(t *testing.T) { var buf bytes.Buffer al := NewActorLogger(&buf, false) - al.WrapContainerLogs(rdr, "act-1", "tmpl-1", "default") + al.WrapContainerLogs(rdr, "act-1") var m map[string]any if err := json.Unmarshal(buf.Bytes(), &m); err != nil { @@ -224,7 +218,7 @@ func TestWrapContainerLogs_TrailingGarbage(t *testing.T) { var buf bytes.Buffer al := NewActorLogger(&buf, false) - al.WrapContainerLogs(rdr, "act-1", "tmpl-1", "default") + al.WrapContainerLogs(rdr, "act-1") var m map[string]any if err := json.Unmarshal(buf.Bytes(), &m); err != nil { diff --git a/cmd/ateom-gvisor/main.go b/cmd/ateom-gvisor/main.go index 365447fca..0983cdc2b 100644 --- a/cmd/ateom-gvisor/main.go +++ b/cmd/ateom-gvisor/main.go @@ -179,7 +179,7 @@ func (s *AteomService) RunWorkload(ctx context.Context, req *ateompb.RunWorkload s.lock.Lock() defer s.lock.Unlock() - s.actorLogger.EmitLifecycleLog("Actor starting", req.GetActorId(), req.GetActorTemplateName(), req.GetActorTemplateNamespace()) + s.actorLogger.EmitLifecycleLog("Actor starting", req.GetActorId()) // Contract with atelet: // @@ -196,10 +196,8 @@ func (s *AteomService) RunWorkload(ctx context.Context, req *ateompb.RunWorkload }() rcmd := &runsc{ - path: req.GetRunscPath(), - actorTemplateNamespace: req.GetActorTemplateNamespace(), - actorTemplateName: req.GetActorTemplateName(), - actorID: req.GetActorId(), + path: req.GetRunscPath(), + actorID: req.GetActorId(), } // Create and start pause container @@ -210,7 +208,7 @@ func (s *AteomService) RunWorkload(ctx context.Context, req *ateompb.RunWorkload return nil, fmt.Errorf("while starting pause container: %w", err) } - pw, err := s.actorLogger.StartJSONLogPipe(req.GetActorId(), req.GetActorTemplateName(), req.GetActorTemplateNamespace()) + pw, err := s.actorLogger.StartJSONLogPipe(req.GetActorId()) if err != nil { return nil, fmt.Errorf("while starting json log pipe: %w", err) } @@ -226,7 +224,7 @@ func (s *AteomService) RunWorkload(ctx context.Context, req *ateompb.RunWorkload } } - s.actorLogger.EmitLifecycleLog("Actor started", req.GetActorId(), req.GetActorTemplateName(), req.GetActorTemplateNamespace()) + s.actorLogger.EmitLifecycleLog("Actor started", req.GetActorId()) return &ateompb.RunWorkloadResponse{}, nil } @@ -235,7 +233,7 @@ func (s *AteomService) CheckpointWorkload(ctx context.Context, req *ateompb.Chec s.lock.Lock() defer s.lock.Unlock() - s.actorLogger.EmitLifecycleLog("Actor checkpointing", req.GetActorId(), req.GetActorTemplateName(), req.GetActorTemplateNamespace()) + s.actorLogger.EmitLifecycleLog("Actor checkpointing", req.GetActorId()) // Contract with atelet: // @@ -243,13 +241,11 @@ func (s *AteomService) CheckpointWorkload(ctx context.Context, req *ateompb.Chec // * After we exit, atelet will tear down OCI bundles and reset the actor directory. rcmd := &runsc{ - path: req.GetRunscPath(), - actorTemplateNamespace: req.GetActorTemplateNamespace(), - actorTemplateName: req.GetActorTemplateName(), - actorID: req.GetActorId(), + path: req.GetRunscPath(), + actorID: req.GetActorId(), } - checkpointPath := ateompath.CheckpointStateDir(req.GetActorTemplateNamespace(), req.GetActorTemplateName(), req.GetActorId()) + checkpointPath := ateompath.CheckpointStateDir(req.GetActorId()) if err := os.MkdirAll(checkpointPath, 0o700); err != nil { return nil, fmt.Errorf("while creating checkpoint directory: %w", err) } @@ -266,14 +262,12 @@ func (s *AteomService) CheckpointWorkload(ctx context.Context, req *ateompb.Chec if err := rcmd.cleanupContainersAfterCheckpoint(ctx, req.GetSpec().GetContainers()); err != nil { slog.WarnContext(ctx, "Failed to clean up runsc containers after checkpoint", "actorID", req.GetActorId(), - "actorTemplateName", req.GetActorTemplateName(), - "actorTemplateNamespace", req.GetActorTemplateNamespace(), "err", err) } s.cleanupActorNetworkOrExit(ctx, "Failed to clean up actor network after checkpoint") - s.actorLogger.EmitLifecycleLog("Actor checkpointed", req.GetActorId(), req.GetActorTemplateName(), req.GetActorTemplateNamespace()) + s.actorLogger.EmitLifecycleLog("Actor checkpointed", req.GetActorId()) return nil, nil } @@ -308,7 +302,7 @@ func (s *AteomService) RestoreWorkload(ctx context.Context, req *ateompb.Restore s.lock.Lock() defer s.lock.Unlock() - s.actorLogger.EmitLifecycleLog("Actor restoring", req.GetActorId(), req.GetActorTemplateName(), req.GetActorTemplateNamespace()) + s.actorLogger.EmitLifecycleLog("Actor restoring", req.GetActorId()) // Contract with atelet: // @@ -326,13 +320,11 @@ func (s *AteomService) RestoreWorkload(ctx context.Context, req *ateompb.Restore }() rcmd := &runsc{ - path: req.GetRunscPath(), - actorTemplateNamespace: req.GetActorTemplateNamespace(), - actorTemplateName: req.GetActorTemplateName(), - actorID: req.GetActorId(), + path: req.GetRunscPath(), + actorID: req.GetActorId(), } - checkpointDir := ateompath.RestoreStateDir(req.GetActorTemplateNamespace(), req.GetActorTemplateName(), req.GetActorId()) + checkpointDir := ateompath.RestoreStateDir(req.GetActorId()) // Create and restore pause container if err := rcmd.cmdCreate(ctx, os.Stdout, "pause"); err != nil { @@ -342,7 +334,7 @@ func (s *AteomService) RestoreWorkload(ctx context.Context, req *ateompb.Restore return nil, fmt.Errorf("while starting pause container: %w", err) } - pw, err := s.actorLogger.StartJSONLogPipe(req.GetActorId(), req.GetActorTemplateName(), req.GetActorTemplateNamespace()) + pw, err := s.actorLogger.StartJSONLogPipe(req.GetActorId()) if err != nil { return nil, fmt.Errorf("while starting json log pipe: %w", err) } @@ -358,7 +350,7 @@ func (s *AteomService) RestoreWorkload(ctx context.Context, req *ateompb.Restore } } - s.actorLogger.EmitLifecycleLog("Actor restored", req.GetActorId(), req.GetActorTemplateName(), req.GetActorTemplateNamespace()) + s.actorLogger.EmitLifecycleLog("Actor restored", req.GetActorId()) return &ateompb.RestoreWorkloadResponse{}, nil } diff --git a/cmd/ateom-gvisor/runsc.go b/cmd/ateom-gvisor/runsc.go index 19ba017ae..8a35dc51f 100644 --- a/cmd/ateom-gvisor/runsc.go +++ b/cmd/ateom-gvisor/runsc.go @@ -28,10 +28,8 @@ import ( ) type runsc struct { - path string - actorTemplateNamespace string - actorTemplateName string - actorID string + path string + actorID string } func (r *runsc) cmdCreate(ctx context.Context, out io.Writer, containerName string) error { @@ -50,10 +48,10 @@ func (r *runsc) cmdCreate(ctx context.Context, out io.Writer, containerName stri // "-debug-to-user-log", // "-log-packets", // "-strace", - "-root", ateompath.RunSCStateDir(r.actorTemplateNamespace, r.actorTemplateName, r.actorID), + "-root", ateompath.RunSCStateDir(r.actorID), "create", - "-bundle", ateompath.OCIBundlePath(r.actorTemplateNamespace, r.actorTemplateName, r.actorID, containerName), - "-pid-file", ateompath.PIDFilePath(r.actorTemplateNamespace, r.actorTemplateName, r.actorID, containerName), + "-bundle", ateompath.OCIBundlePath(r.actorID, containerName), + "-pid-file", ateompath.PIDFilePath(r.actorID, containerName), containerName, // Name of the container ) cmd.Stdout = out @@ -84,7 +82,7 @@ func (r *runsc) cmdStart(ctx context.Context, out io.Writer, containerName strin // "-log-packets", // "-strace", "-allow-connected-on-save", - "-root", ateompath.RunSCStateDir(r.actorTemplateNamespace, r.actorTemplateName, r.actorID), + "-root", ateompath.RunSCStateDir(r.actorID), "start", containerName, // Name of the container ) @@ -115,7 +113,7 @@ func (r *runsc) cmdCheckpoint(ctx context.Context, containerName, checkpointPath // "-debug-to-user-log", // "-log-packets", // "-strace", - "-root", ateompath.RunSCStateDir(r.actorTemplateNamespace, r.actorTemplateName, r.actorID), + "-root", ateompath.RunSCStateDir(r.actorID), "checkpoint", "-image-path", checkpointPath, containerName, // Name of the container @@ -147,11 +145,11 @@ func (r *runsc) cmdRestore(ctx context.Context, out io.Writer, containerName, ch // "-debug-to-user-log", // "-log-packets", // "-strace", - "-root", ateompath.RunSCStateDir(r.actorTemplateNamespace, r.actorTemplateName, r.actorID), + "-root", ateompath.RunSCStateDir(r.actorID), "restore", - "-bundle", ateompath.OCIBundlePath(r.actorTemplateNamespace, r.actorTemplateName, r.actorID, containerName), + "-bundle", ateompath.OCIBundlePath(r.actorID, containerName), "-image-path", checkpointPath, - "-pid-file", ateompath.PIDFilePath(r.actorTemplateNamespace, r.actorTemplateName, r.actorID, containerName), + "-pid-file", ateompath.PIDFilePath(r.actorID, containerName), "-background", "-direct", "-detach", @@ -178,7 +176,7 @@ func (r *runsc) cmdDelete(ctx context.Context, containerName string) error { "-log-format", "json", "--alsologtostderr", // "-debug", - "-root", ateompath.RunSCStateDir(r.actorTemplateNamespace, r.actorTemplateName, r.actorID), + "-root", ateompath.RunSCStateDir(r.actorID), "delete", "-force", containerName, @@ -203,7 +201,7 @@ func (r *runsc) cmdState(ctx context.Context, containerName string) error { r.path, "-log-format", "json", "--alsologtostderr", - "-root", ateompath.RunSCStateDir(r.actorTemplateNamespace, r.actorTemplateName, r.actorID), + "-root", ateompath.RunSCStateDir(r.actorID), "state", containerName, ) diff --git a/docs/observability.md b/docs/observability.md index 5d05a4ce3..a05d079a8 100644 --- a/docs/observability.md +++ b/docs/observability.md @@ -8,8 +8,6 @@ This guide explains how Agent Substrate achieves observability across these susp To make underlying infrastructure transitions transparent, Agent Substrate establishes a standardized metadata model to identify actors across worker pods: * `ate.dev/actor_id`: The unique identifier of the actor (e.g., `my-counter-1` or `test`). -* `ate.dev/actor_template_name`: The name of the actor's ActorTemplate (e.g., `counter`). -* `ate.dev/actor_template_namespace`: The Kubernetes namespace of the actor's ActorTemplate (e.g., `ate-demo-counter`). Currently, Agent Substrate automatically wraps container output and injects these metadata labels into **container logs**. For metrics and distributed tracing, Agent Substrate provides foundational system telemetry and on-demand request tracing, with roadmap plans to fully integrate actor-level correlation. diff --git a/internal/ateompath/ateompath.go b/internal/ateompath/ateompath.go index 9e846dc7f..defd8e4e2 100644 --- a/internal/ateompath/ateompath.go +++ b/internal/ateompath/ateompath.go @@ -60,11 +60,11 @@ func AteomNetNSPath(podUID string) string { ) } -func ActorPath(actorTemplateNamespace, actorTemplateName, actorID string) string { +func ActorPath(actorID string) string { return filepath.Join( BasePath, "actors", - actorTemplateNamespace+":"+actorTemplateName+":"+actorID, + actorID, ) } @@ -73,52 +73,52 @@ func ActorPath(actorTemplateNamespace, actorTemplateName, actorID string) string // bind-mounts read-only into the actor. It is per-actor and regenerated on // every resume, so (unlike the checkpointed process environment) it reflects // the correct ID after a restore from the golden snapshot. -func ActorIdentityDirPath(actorTemplateNamespace, actorTemplateName, actorID string) string { +func ActorIdentityDirPath(actorID string) string { return filepath.Join( - ActorPath(actorTemplateNamespace, actorTemplateName, actorID), + ActorPath(actorID), "identity", ) } -func RunSCStateDir(actorTemplateNamespace, actorTemplateName, actorID string) string { +func RunSCStateDir(actorID string) string { return filepath.Join( - ActorPath(actorTemplateNamespace, actorTemplateName, actorID), + ActorPath(actorID), "runsc-state", ) } -func OCIBundleDir(actorTemplateNamespace, actorTemplateName, actorID string) string { +func OCIBundleDir(actorID string) string { return filepath.Join( - ActorPath(actorTemplateNamespace, actorTemplateName, actorID), + ActorPath(actorID), "bundles", ) } -func OCIBundlePath(actorTemplateNamespace, actorTemplateName, actorID, containerName string) string { +func OCIBundlePath(actorID, containerName string) string { return filepath.Join( - OCIBundleDir(actorTemplateNamespace, actorTemplateName, actorID), + OCIBundleDir(actorID), containerName, ) } -func RunscDebugLogDir(actorTemplateNamespace, actorTemplateName, actorID, containerName string) string { +func RunscDebugLogDir(actorID, containerName string) string { return filepath.Join( - ActorPath(actorTemplateNamespace, actorTemplateName, actorID), + ActorPath(actorID), "runsc-debug-logs", containerName, ) } -func CheckpointStateDir(actorTemplateNamespace, actorTemplateName, actorID string) string { +func CheckpointStateDir(actorID string) string { return filepath.Join( - ActorPath(actorTemplateNamespace, actorTemplateName, actorID), + ActorPath(actorID), "checkpoint-state", ) } -func LocalCheckpointsDir(actorTemplateNamespace, actorTemplateName, actorID string) string { +func LocalCheckpointsDir(actorID string) string { return filepath.Join( - ActorPath(actorTemplateNamespace, actorTemplateName, actorID), + ActorPath(actorID), "local-checkpoint", ) } @@ -134,23 +134,23 @@ func LocalCheckpointsDir(actorTemplateNamespace, actorTemplateName, actorID stri // make sure we write the suspension checkpoint to a different location. This // will work properly, with `runsc checkpoint` paging in any data that hasn't // yet been loaded. -func RestoreStateDir(actorTemplateNamespace, actorTemplateName, actorID string) string { +func RestoreStateDir(actorID string) string { return filepath.Join( - ActorPath(actorTemplateNamespace, actorTemplateName, actorID), + ActorPath(actorID), "restore-state", ) } -func PIDFileDir(actorTemplateNamespace, actorTemplateName, actorID string) string { +func PIDFileDir(actorID string) string { return filepath.Join( - ActorPath(actorTemplateNamespace, actorTemplateName, actorID), + ActorPath(actorID), "pidfiles", ) } -func PIDFilePath(actorTemplateNamespace, actorTemplateName, actorID, containerName string) string { +func PIDFilePath(actorID, containerName string) string { return filepath.Join( - PIDFileDir(actorTemplateNamespace, actorTemplateName, actorID), + PIDFileDir(actorID), containerName+".pid", ) } diff --git a/internal/proto/ateletpb/atelet.pb.go b/internal/proto/ateletpb/atelet.pb.go index a9bb734a7..ec33ee38a 100644 --- a/internal/proto/ateletpb/atelet.pb.go +++ b/internal/proto/ateletpb/atelet.pb.go @@ -88,15 +88,13 @@ func (CheckpointType) EnumDescriptor() ([]byte, []int) { } type RunRequest struct { - state protoimpl.MessageState `protogen:"open.v1"` - TargetAteomUid string `protobuf:"bytes,1,opt,name=target_ateom_uid,json=targetAteomUid,proto3" json:"target_ateom_uid,omitempty"` - ActorTemplateNamespace string `protobuf:"bytes,3,opt,name=actor_template_namespace,json=actorTemplateNamespace,proto3" json:"actor_template_namespace,omitempty"` - ActorTemplateName string `protobuf:"bytes,4,opt,name=actor_template_name,json=actorTemplateName,proto3" json:"actor_template_name,omitempty"` - ActorId string `protobuf:"bytes,5,opt,name=actor_id,json=actorId,proto3" json:"actor_id,omitempty"` - Runsc *RunscConfig `protobuf:"bytes,8,opt,name=runsc,proto3" json:"runsc,omitempty"` - Spec *WorkloadSpec `protobuf:"bytes,7,opt,name=spec,proto3" json:"spec,omitempty"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache + state protoimpl.MessageState `protogen:"open.v1"` + TargetAteomUid string `protobuf:"bytes,1,opt,name=target_ateom_uid,json=targetAteomUid,proto3" json:"target_ateom_uid,omitempty"` + ActorId string `protobuf:"bytes,5,opt,name=actor_id,json=actorId,proto3" json:"actor_id,omitempty"` + Runsc *RunscConfig `protobuf:"bytes,8,opt,name=runsc,proto3" json:"runsc,omitempty"` + Spec *WorkloadSpec `protobuf:"bytes,7,opt,name=spec,proto3" json:"spec,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache } func (x *RunRequest) Reset() { @@ -136,20 +134,6 @@ func (x *RunRequest) GetTargetAteomUid() string { return "" } -func (x *RunRequest) GetActorTemplateNamespace() string { - if x != nil { - return x.ActorTemplateNamespace - } - return "" -} - -func (x *RunRequest) GetActorTemplateName() string { - if x != nil { - return x.ActorTemplateName - } - return "" -} - func (x *RunRequest) GetActorId() string { if x != nil { return x.ActorId @@ -685,14 +669,12 @@ func (x *ExternalCheckpointConfiguration) GetSnapshotUriPrefix() string { } type CheckpointRequest struct { - state protoimpl.MessageState `protogen:"open.v1"` - TargetAteomUid string `protobuf:"bytes,1,opt,name=target_ateom_uid,json=targetAteomUid,proto3" json:"target_ateom_uid,omitempty"` - ActorTemplateNamespace string `protobuf:"bytes,3,opt,name=actor_template_namespace,json=actorTemplateNamespace,proto3" json:"actor_template_namespace,omitempty"` - ActorTemplateName string `protobuf:"bytes,4,opt,name=actor_template_name,json=actorTemplateName,proto3" json:"actor_template_name,omitempty"` - ActorId string `protobuf:"bytes,5,opt,name=actor_id,json=actorId,proto3" json:"actor_id,omitempty"` - Runsc *RunscConfig `protobuf:"bytes,6,opt,name=runsc,proto3" json:"runsc,omitempty"` - Spec *WorkloadSpec `protobuf:"bytes,7,opt,name=spec,proto3" json:"spec,omitempty"` - Type CheckpointType `protobuf:"varint,9,opt,name=type,proto3,enum=atelet.CheckpointType" json:"type,omitempty"` + state protoimpl.MessageState `protogen:"open.v1"` + TargetAteomUid string `protobuf:"bytes,1,opt,name=target_ateom_uid,json=targetAteomUid,proto3" json:"target_ateom_uid,omitempty"` + ActorId string `protobuf:"bytes,5,opt,name=actor_id,json=actorId,proto3" json:"actor_id,omitempty"` + Runsc *RunscConfig `protobuf:"bytes,6,opt,name=runsc,proto3" json:"runsc,omitempty"` + Spec *WorkloadSpec `protobuf:"bytes,7,opt,name=spec,proto3" json:"spec,omitempty"` + Type CheckpointType `protobuf:"varint,9,opt,name=type,proto3,enum=atelet.CheckpointType" json:"type,omitempty"` // The checkpoint configuration, depending on the type. // // Types that are valid to be assigned to Config: @@ -741,20 +723,6 @@ func (x *CheckpointRequest) GetTargetAteomUid() string { return "" } -func (x *CheckpointRequest) GetActorTemplateNamespace() string { - if x != nil { - return x.ActorTemplateNamespace - } - return "" -} - -func (x *CheckpointRequest) GetActorTemplateName() string { - if x != nil { - return x.ActorTemplateName - } - return "" -} - func (x *CheckpointRequest) GetActorId() string { if x != nil { return x.ActorId @@ -861,14 +829,12 @@ func (*CheckpointResponse) Descriptor() ([]byte, []int) { } type RestoreRequest struct { - state protoimpl.MessageState `protogen:"open.v1"` - TargetAteomUid string `protobuf:"bytes,1,opt,name=target_ateom_uid,json=targetAteomUid,proto3" json:"target_ateom_uid,omitempty"` - ActorTemplateNamespace string `protobuf:"bytes,3,opt,name=actor_template_namespace,json=actorTemplateNamespace,proto3" json:"actor_template_namespace,omitempty"` - ActorTemplateName string `protobuf:"bytes,4,opt,name=actor_template_name,json=actorTemplateName,proto3" json:"actor_template_name,omitempty"` - ActorId string `protobuf:"bytes,5,opt,name=actor_id,json=actorId,proto3" json:"actor_id,omitempty"` - Runsc *RunscConfig `protobuf:"bytes,6,opt,name=runsc,proto3" json:"runsc,omitempty"` - Spec *WorkloadSpec `protobuf:"bytes,7,opt,name=spec,proto3" json:"spec,omitempty"` - Type CheckpointType `protobuf:"varint,9,opt,name=type,proto3,enum=atelet.CheckpointType" json:"type,omitempty"` + state protoimpl.MessageState `protogen:"open.v1"` + TargetAteomUid string `protobuf:"bytes,1,opt,name=target_ateom_uid,json=targetAteomUid,proto3" json:"target_ateom_uid,omitempty"` + ActorId string `protobuf:"bytes,5,opt,name=actor_id,json=actorId,proto3" json:"actor_id,omitempty"` + Runsc *RunscConfig `protobuf:"bytes,6,opt,name=runsc,proto3" json:"runsc,omitempty"` + Spec *WorkloadSpec `protobuf:"bytes,7,opt,name=spec,proto3" json:"spec,omitempty"` + Type CheckpointType `protobuf:"varint,9,opt,name=type,proto3,enum=atelet.CheckpointType" json:"type,omitempty"` // The checkpoint configuration, depending on the type. // // Types that are valid to be assigned to Config: @@ -917,20 +883,6 @@ func (x *RestoreRequest) GetTargetAteomUid() string { return "" } -func (x *RestoreRequest) GetActorTemplateNamespace() string { - if x != nil { - return x.ActorTemplateNamespace - } - return "" -} - -func (x *RestoreRequest) GetActorTemplateName() string { - if x != nil { - return x.ActorTemplateName - } - return "" -} - func (x *RestoreRequest) GetActorId() string { if x != nil { return x.ActorId @@ -1040,15 +992,13 @@ var File_atelet_proto protoreflect.FileDescriptor const file_atelet_proto_rawDesc = "" + "\n" + - "\fatelet.proto\x12\x06atelet\"\x90\x02\n" + + "\fatelet.proto\x12\x06atelet\"\xe7\x01\n" + "\n" + "RunRequest\x12(\n" + - "\x10target_ateom_uid\x18\x01 \x01(\tR\x0etargetAteomUid\x128\n" + - "\x18actor_template_namespace\x18\x03 \x01(\tR\x16actorTemplateNamespace\x12.\n" + - "\x13actor_template_name\x18\x04 \x01(\tR\x11actorTemplateName\x12\x19\n" + + "\x10target_ateom_uid\x18\x01 \x01(\tR\x0etargetAteomUid\x12\x19\n" + "\bactor_id\x18\x05 \x01(\tR\aactorId\x12)\n" + "\x05runsc\x18\b \x01(\v2\x13.atelet.RunscConfigR\x05runsc\x12(\n" + - "\x04spec\x18\a \x01(\v2\x14.atelet.WorkloadSpecR\x04spec\"+\n" + + "\x04spec\x18\a \x01(\v2\x14.atelet.WorkloadSpecR\x04specJ\x04\b\x02\x10\x03J\x04\b\x03\x10\x04J\x04\b\x04\x10\x05R\x18actor_template_namespaceR\x13actor_template_name\"+\n" + "\x17GCPAuthenticationConfig\x12\x10\n" + "\x03use\x18\x01 \x01(\bR\x03use\"I\n" + "\x14AuthenticationConfig\x121\n" + @@ -1079,11 +1029,9 @@ const file_atelet_proto_rawDesc = "" + "\x1cLocalCheckpointConfiguration\x12'\n" + "\x0fsnapshot_prefix\x18\x01 \x01(\tR\x0esnapshotPrefix\"Q\n" + "\x1fExternalCheckpointConfiguration\x12.\n" + - "\x13snapshot_uri_prefix\x18\x01 \x01(\tR\x11snapshotUriPrefix\"\xf2\x03\n" + + "\x13snapshot_uri_prefix\x18\x01 \x01(\tR\x11snapshotUriPrefix\"\xde\x03\n" + "\x11CheckpointRequest\x12(\n" + - "\x10target_ateom_uid\x18\x01 \x01(\tR\x0etargetAteomUid\x128\n" + - "\x18actor_template_namespace\x18\x03 \x01(\tR\x16actorTemplateNamespace\x12.\n" + - "\x13actor_template_name\x18\x04 \x01(\tR\x11actorTemplateName\x12\x19\n" + + "\x10target_ateom_uid\x18\x01 \x01(\tR\x0etargetAteomUid\x12\x19\n" + "\bactor_id\x18\x05 \x01(\tR\aactorId\x12)\n" + "\x05runsc\x18\x06 \x01(\v2\x13.atelet.RunscConfigR\x05runsc\x12(\n" + "\x04spec\x18\a \x01(\v2\x14.atelet.WorkloadSpecR\x04spec\x12*\n" + @@ -1091,12 +1039,10 @@ const file_atelet_proto_rawDesc = "" + "\flocal_config\x18\n" + " \x01(\v2$.atelet.LocalCheckpointConfigurationH\x00R\vlocalConfig\x12R\n" + "\x0fexternal_config\x18\v \x01(\v2'.atelet.ExternalCheckpointConfigurationH\x00R\x0eexternalConfigB\b\n" + - "\x06configJ\x04\b\b\x10\t\"\x14\n" + - "\x12CheckpointResponse\"\xef\x03\n" + + "\x06configJ\x04\b\x02\x10\x03J\x04\b\x03\x10\x04J\x04\b\x04\x10\x05J\x04\b\b\x10\tR\x18actor_template_namespaceR\x13actor_template_nameR\x13snapshot_uri_prefix\"\x14\n" + + "\x12CheckpointResponse\"\xdb\x03\n" + "\x0eRestoreRequest\x12(\n" + - "\x10target_ateom_uid\x18\x01 \x01(\tR\x0etargetAteomUid\x128\n" + - "\x18actor_template_namespace\x18\x03 \x01(\tR\x16actorTemplateNamespace\x12.\n" + - "\x13actor_template_name\x18\x04 \x01(\tR\x11actorTemplateName\x12\x19\n" + + "\x10target_ateom_uid\x18\x01 \x01(\tR\x0etargetAteomUid\x12\x19\n" + "\bactor_id\x18\x05 \x01(\tR\aactorId\x12)\n" + "\x05runsc\x18\x06 \x01(\v2\x13.atelet.RunscConfigR\x05runsc\x12(\n" + "\x04spec\x18\a \x01(\v2\x14.atelet.WorkloadSpecR\x04spec\x12*\n" + @@ -1104,7 +1050,7 @@ const file_atelet_proto_rawDesc = "" + "\flocal_config\x18\n" + " \x01(\v2$.atelet.LocalCheckpointConfigurationH\x00R\vlocalConfig\x12R\n" + "\x0fexternal_config\x18\v \x01(\v2'.atelet.ExternalCheckpointConfigurationH\x00R\x0eexternalConfigB\b\n" + - "\x06configJ\x04\b\b\x10\t\"\x11\n" + + "\x06configJ\x04\b\x02\x10\x03J\x04\b\x03\x10\x04J\x04\b\x04\x10\x05J\x04\b\b\x10\tR\x18actor_template_namespaceR\x13actor_template_nameR\x13snapshot_uri_prefix\"\x11\n" + "\x0fRestoreResponse*j\n" + "\x0eCheckpointType\x12\x1f\n" + "\x1bCHECKPOINT_TYPE_UNSPECIFIED\x10\x00\x12\x19\n" + diff --git a/internal/proto/ateletpb/atelet.proto b/internal/proto/ateletpb/atelet.proto index acaf7a730..f5b5e3708 100644 --- a/internal/proto/ateletpb/atelet.proto +++ b/internal/proto/ateletpb/atelet.proto @@ -35,13 +35,14 @@ service AteomHerder { message RunRequest { string target_ateom_uid = 1; - string actor_template_namespace = 3; - string actor_template_name = 4; string actor_id = 5; RunscConfig runsc = 8; WorkloadSpec spec = 7; + + reserved 2, 3, 4; + reserved "actor_template_namespace", "actor_template_name"; } message GCPAuthenticationConfig { @@ -122,17 +123,12 @@ enum CheckpointType { message CheckpointRequest { string target_ateom_uid = 1; - string actor_template_namespace = 3; - string actor_template_name = 4; string actor_id = 5; RunscConfig runsc = 6; WorkloadSpec spec = 7; - // deprecated snapshot_uri_prefix - reserved 8; - CheckpointType type = 9; // The checkpoint configuration, depending on the type. @@ -140,6 +136,9 @@ message CheckpointRequest { LocalCheckpointConfiguration local_config = 10; ExternalCheckpointConfiguration external_config = 11; } + + reserved 2, 3, 4, 8; + reserved "actor_template_namespace", "actor_template_name", "snapshot_uri_prefix"; } message CheckpointResponse { @@ -149,17 +148,12 @@ message CheckpointResponse { message RestoreRequest { string target_ateom_uid = 1; - string actor_template_namespace = 3; - string actor_template_name = 4; string actor_id = 5; RunscConfig runsc = 6; WorkloadSpec spec = 7; - // deprecated snapshot_uri_prefix - reserved 8; - CheckpointType type = 9; // The checkpoint configuration, depending on the type. @@ -167,6 +161,10 @@ message RestoreRequest { LocalCheckpointConfiguration local_config = 10; ExternalCheckpointConfiguration external_config = 11; } + + // deprecated snapshot_uri_prefix + reserved 2, 3, 4, 8; + reserved "actor_template_namespace", "actor_template_name", "snapshot_uri_prefix"; } message RestoreResponse { diff --git a/internal/proto/ateompb/ateom.pb.go b/internal/proto/ateompb/ateom.pb.go index 9114a309b..4e4a17e5f 100644 --- a/internal/proto/ateompb/ateom.pb.go +++ b/internal/proto/ateompb/ateom.pb.go @@ -36,14 +36,12 @@ const ( ) type RunWorkloadRequest struct { - state protoimpl.MessageState `protogen:"open.v1"` - ActorTemplateNamespace string `protobuf:"bytes,1,opt,name=actor_template_namespace,json=actorTemplateNamespace,proto3" json:"actor_template_namespace,omitempty"` - ActorTemplateName string `protobuf:"bytes,2,opt,name=actor_template_name,json=actorTemplateName,proto3" json:"actor_template_name,omitempty"` - ActorId string `protobuf:"bytes,3,opt,name=actor_id,json=actorId,proto3" json:"actor_id,omitempty"` - RunscPath string `protobuf:"bytes,4,opt,name=runsc_path,json=runscPath,proto3" json:"runsc_path,omitempty"` - Spec *WorkloadSpec `protobuf:"bytes,5,opt,name=spec,proto3" json:"spec,omitempty"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache + state protoimpl.MessageState `protogen:"open.v1"` + ActorId string `protobuf:"bytes,3,opt,name=actor_id,json=actorId,proto3" json:"actor_id,omitempty"` + RunscPath string `protobuf:"bytes,4,opt,name=runsc_path,json=runscPath,proto3" json:"runsc_path,omitempty"` + Spec *WorkloadSpec `protobuf:"bytes,5,opt,name=spec,proto3" json:"spec,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache } func (x *RunWorkloadRequest) Reset() { @@ -76,20 +74,6 @@ func (*RunWorkloadRequest) Descriptor() ([]byte, []int) { return file_ateom_proto_rawDescGZIP(), []int{0} } -func (x *RunWorkloadRequest) GetActorTemplateNamespace() string { - if x != nil { - return x.ActorTemplateNamespace - } - return "" -} - -func (x *RunWorkloadRequest) GetActorTemplateName() string { - if x != nil { - return x.ActorTemplateName - } - return "" -} - func (x *RunWorkloadRequest) GetActorId() string { if x != nil { return x.ActorId @@ -237,12 +221,10 @@ func (*RunWorkloadResponse) Descriptor() ([]byte, []int) { } type CheckpointWorkloadRequest struct { - state protoimpl.MessageState `protogen:"open.v1"` - ActorTemplateNamespace string `protobuf:"bytes,1,opt,name=actor_template_namespace,json=actorTemplateNamespace,proto3" json:"actor_template_namespace,omitempty"` - ActorTemplateName string `protobuf:"bytes,2,opt,name=actor_template_name,json=actorTemplateName,proto3" json:"actor_template_name,omitempty"` - ActorId string `protobuf:"bytes,3,opt,name=actor_id,json=actorId,proto3" json:"actor_id,omitempty"` - RunscPath string `protobuf:"bytes,4,opt,name=runsc_path,json=runscPath,proto3" json:"runsc_path,omitempty"` - Spec *WorkloadSpec `protobuf:"bytes,5,opt,name=spec,proto3" json:"spec,omitempty"` + state protoimpl.MessageState `protogen:"open.v1"` + ActorId string `protobuf:"bytes,3,opt,name=actor_id,json=actorId,proto3" json:"actor_id,omitempty"` + RunscPath string `protobuf:"bytes,4,opt,name=runsc_path,json=runscPath,proto3" json:"runsc_path,omitempty"` + Spec *WorkloadSpec `protobuf:"bytes,5,opt,name=spec,proto3" json:"spec,omitempty"` // An object storage URI prefix below which the checkpoint data will be // stored. // @@ -286,20 +268,6 @@ func (*CheckpointWorkloadRequest) Descriptor() ([]byte, []int) { return file_ateom_proto_rawDescGZIP(), []int{4} } -func (x *CheckpointWorkloadRequest) GetActorTemplateNamespace() string { - if x != nil { - return x.ActorTemplateNamespace - } - return "" -} - -func (x *CheckpointWorkloadRequest) GetActorTemplateName() string { - if x != nil { - return x.ActorTemplateName - } - return "" -} - func (x *CheckpointWorkloadRequest) GetActorId() string { if x != nil { return x.ActorId @@ -365,12 +333,10 @@ func (*CheckpointWorkloadResponse) Descriptor() ([]byte, []int) { } type RestoreWorkloadRequest struct { - state protoimpl.MessageState `protogen:"open.v1"` - ActorTemplateNamespace string `protobuf:"bytes,1,opt,name=actor_template_namespace,json=actorTemplateNamespace,proto3" json:"actor_template_namespace,omitempty"` - ActorTemplateName string `protobuf:"bytes,2,opt,name=actor_template_name,json=actorTemplateName,proto3" json:"actor_template_name,omitempty"` - ActorId string `protobuf:"bytes,3,opt,name=actor_id,json=actorId,proto3" json:"actor_id,omitempty"` - RunscPath string `protobuf:"bytes,4,opt,name=runsc_path,json=runscPath,proto3" json:"runsc_path,omitempty"` - Spec *WorkloadSpec `protobuf:"bytes,5,opt,name=spec,proto3" json:"spec,omitempty"` + state protoimpl.MessageState `protogen:"open.v1"` + ActorId string `protobuf:"bytes,3,opt,name=actor_id,json=actorId,proto3" json:"actor_id,omitempty"` + RunscPath string `protobuf:"bytes,4,opt,name=runsc_path,json=runscPath,proto3" json:"runsc_path,omitempty"` + Spec *WorkloadSpec `protobuf:"bytes,5,opt,name=spec,proto3" json:"spec,omitempty"` // The object storage URI prefix of the snapshot to restore. SnapshotUriPrefix string `protobuf:"bytes,6,opt,name=snapshot_uri_prefix,json=snapshotUriPrefix,proto3" json:"snapshot_uri_prefix,omitempty"` unknownFields protoimpl.UnknownFields @@ -407,20 +373,6 @@ func (*RestoreWorkloadRequest) Descriptor() ([]byte, []int) { return file_ateom_proto_rawDescGZIP(), []int{6} } -func (x *RestoreWorkloadRequest) GetActorTemplateNamespace() string { - if x != nil { - return x.ActorTemplateNamespace - } - return "" -} - -func (x *RestoreWorkloadRequest) GetActorTemplateName() string { - if x != nil { - return x.ActorTemplateName - } - return "" -} - func (x *RestoreWorkloadRequest) GetActorId() string { if x != nil { return x.ActorId @@ -489,38 +441,32 @@ var File_ateom_proto protoreflect.FileDescriptor const file_ateom_proto_rawDesc = "" + "\n" + - "\vateom.proto\x12\x05ateom\"\xe1\x01\n" + - "\x12RunWorkloadRequest\x128\n" + - "\x18actor_template_namespace\x18\x01 \x01(\tR\x16actorTemplateNamespace\x12.\n" + - "\x13actor_template_name\x18\x02 \x01(\tR\x11actorTemplateName\x12\x19\n" + + "\vateom.proto\x12\x05ateom\"\xb2\x01\n" + + "\x12RunWorkloadRequest\x12\x19\n" + "\bactor_id\x18\x03 \x01(\tR\aactorId\x12\x1d\n" + "\n" + "runsc_path\x18\x04 \x01(\tR\trunscPath\x12'\n" + - "\x04spec\x18\x05 \x01(\v2\x13.ateom.WorkloadSpecR\x04spec\"@\n" + + "\x04spec\x18\x05 \x01(\v2\x13.ateom.WorkloadSpecR\x04specJ\x04\b\x01\x10\x02J\x04\b\x02\x10\x03R\x18actor_template_namespaceR\x13actor_template_name\"@\n" + "\fWorkloadSpec\x120\n" + "\n" + "containers\x18\x01 \x03(\v2\x10.ateom.ContainerR\n" + "containers\"\x1f\n" + "\tContainer\x12\x12\n" + "\x04name\x18\x01 \x01(\tR\x04name\"\x15\n" + - "\x13RunWorkloadResponse\"\x98\x02\n" + - "\x19CheckpointWorkloadRequest\x128\n" + - "\x18actor_template_namespace\x18\x01 \x01(\tR\x16actorTemplateNamespace\x12.\n" + - "\x13actor_template_name\x18\x02 \x01(\tR\x11actorTemplateName\x12\x19\n" + + "\x13RunWorkloadResponse\"\xe9\x01\n" + + "\x19CheckpointWorkloadRequest\x12\x19\n" + "\bactor_id\x18\x03 \x01(\tR\aactorId\x12\x1d\n" + "\n" + "runsc_path\x18\x04 \x01(\tR\trunscPath\x12'\n" + "\x04spec\x18\x05 \x01(\v2\x13.ateom.WorkloadSpecR\x04spec\x12.\n" + - "\x13snapshot_uri_prefix\x18\x06 \x01(\tR\x11snapshotUriPrefix\"\x1c\n" + - "\x1aCheckpointWorkloadResponse\"\x95\x02\n" + - "\x16RestoreWorkloadRequest\x128\n" + - "\x18actor_template_namespace\x18\x01 \x01(\tR\x16actorTemplateNamespace\x12.\n" + - "\x13actor_template_name\x18\x02 \x01(\tR\x11actorTemplateName\x12\x19\n" + + "\x13snapshot_uri_prefix\x18\x06 \x01(\tR\x11snapshotUriPrefixJ\x04\b\x01\x10\x02J\x04\b\x02\x10\x03R\x18actor_template_namespaceR\x13actor_template_name\"\x1c\n" + + "\x1aCheckpointWorkloadResponse\"\xe6\x01\n" + + "\x16RestoreWorkloadRequest\x12\x19\n" + "\bactor_id\x18\x03 \x01(\tR\aactorId\x12\x1d\n" + "\n" + "runsc_path\x18\x04 \x01(\tR\trunscPath\x12'\n" + "\x04spec\x18\x05 \x01(\v2\x13.ateom.WorkloadSpecR\x04spec\x12.\n" + - "\x13snapshot_uri_prefix\x18\x06 \x01(\tR\x11snapshotUriPrefix\"\x19\n" + + "\x13snapshot_uri_prefix\x18\x06 \x01(\tR\x11snapshotUriPrefixJ\x04\b\x01\x10\x02J\x04\b\x02\x10\x03R\x18actor_template_namespaceR\x13actor_template_name\"\x19\n" + "\x17RestoreWorkloadResponse2\x80\x02\n" + "\x05Ateom\x12F\n" + "\vRunWorkload\x12\x19.ateom.RunWorkloadRequest\x1a\x1a.ateom.RunWorkloadResponse\"\x00\x12[\n" + diff --git a/internal/proto/ateompb/ateom.proto b/internal/proto/ateompb/ateom.proto index 1da19e5a3..3630444e2 100644 --- a/internal/proto/ateompb/ateom.proto +++ b/internal/proto/ateompb/ateom.proto @@ -48,13 +48,14 @@ service Ateom { } message RunWorkloadRequest { - string actor_template_namespace = 1; - string actor_template_name = 2; - string actor_id = 3; + string actor_id = 3; string runsc_path = 4; WorkloadSpec spec = 5; + + reserved 1, 2; + reserved "actor_template_namespace", "actor_template_name"; } // WorkloadSpec parallels Pod, but with far fewer configurable fields. @@ -70,9 +71,7 @@ message RunWorkloadResponse { } message CheckpointWorkloadRequest { - string actor_template_namespace = 1; - string actor_template_name = 2; - string actor_id = 3; + string actor_id = 3; string runsc_path = 4; @@ -87,6 +86,9 @@ message CheckpointWorkloadRequest { // // For example: "gs://bucket/actors/1234/snapshots/5678/" string snapshot_uri_prefix = 6; + + reserved 1, 2; + reserved "actor_template_namespace", "actor_template_name"; } message CheckpointWorkloadResponse { @@ -94,9 +96,7 @@ message CheckpointWorkloadResponse { } message RestoreWorkloadRequest { - string actor_template_namespace = 1; - string actor_template_name = 2; - string actor_id = 3; + string actor_id = 3; string runsc_path = 4; @@ -104,6 +104,9 @@ message RestoreWorkloadRequest { // The object storage URI prefix of the snapshot to restore. string snapshot_uri_prefix = 6; + + reserved 1, 2; + reserved "actor_template_namespace", "actor_template_name"; } message RestoreWorkloadResponse { diff --git a/internal/resources/validate.go b/internal/resources/validate.go index 3855fe856..016ff0b07 100644 --- a/internal/resources/validate.go +++ b/internal/resources/validate.go @@ -30,32 +30,16 @@ import ( // tree, or collide OCI bundles. They are exported so the API server and // controller can apply the same rules at their own boundaries. -// ValidateActorRef ensures every component of the per-actor directory tree is -// a valid DNS-1123 name. namespace+template+actorID are concatenated by -// ateompath.ActorPath into a host path on which atelet runs os.RemoveAll and -// os.MkdirAll, so all three must be validated. Checking only one would still -// leave a traversal window via the others. Template names are DNS-1123 -// subdomains (dots allowed); namespaces and actor IDs are labels. +// ValidateActorRef ensures that the actor ID is a valid DNS-1123 name. The +// actor ID forms part of a host path on which atelet runs os.RemoveAll and +// os.MkdirAll. // // The actor ID rule here is DNS-1123 label, which matches ValidateActorID; // unifying the two implementations is tracked separately. -func ValidateActorRef(namespace, template, actorID string) error { - if errs := validation.IsDNS1123Label(namespace); len(errs) > 0 { - return fmt.Errorf("invalid namespace %q: %s", namespace, strings.Join(errs, "; ")) - } - if errs := validation.IsDNS1123Subdomain(template); len(errs) > 0 { - return fmt.Errorf("invalid template %q: %s", template, strings.Join(errs, "; ")) - } +func ValidateActorRef(actorID string) error { if errs := validation.IsDNS1123Label(actorID); len(errs) > 0 { return fmt.Errorf("invalid actor ID %q: %s", actorID, strings.Join(errs, "; ")) } - // The three names are joined into a single path component - // (: