Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion cmd/ateapi/internal/controlapi/workflow_pause.go
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,8 @@ func (s *CallAteletPauseStep) Execute(ctx context.Context, input *PauseInput, st
SnapshotPrefix: state.Actor.InProgressSnapshot,
},
},
Scope: toAteletSnapshotScope(state.ActorTemplate.Spec.SnapshotsConfig.OnPause),
Scope: toAteletSnapshotScope(state.ActorTemplate.Spec.SnapshotsConfig.OnPause),
ActorUid: state.Actor.GetMetadata().Uid,
}

_, err = client.Checkpoint(ctx, req)
Expand Down
5 changes: 4 additions & 1 deletion cmd/ateapi/internal/controlapi/workflow_resume.go
Original file line number Diff line number Diff line change
Expand Up @@ -276,6 +276,7 @@ func (s *CallAteletRestoreStep) Execute(ctx context.Context, input *ResumeInput,
ActorTemplateNamespace: state.Actor.GetActorTemplateNamespace(),
ActorTemplateName: state.Actor.GetActorTemplateName(),
Spec: workloadSpec,
ActorUid: state.Actor.GetMetadata().Uid,
}
switch d := data.(type) {
case *ateapipb.SnapshotInfo_Local:
Expand Down Expand Up @@ -318,7 +319,8 @@ func (s *CallAteletRestoreStep) Execute(ctx context.Context, input *ResumeInput,
SnapshotUriPrefix: snapshot,
},
},
Scope: toAteletSnapshotScope(state.ActorTemplate.Spec.SnapshotsConfig.OnCommit),
Scope: toAteletSnapshotScope(state.ActorTemplate.Spec.SnapshotsConfig.OnCommit),
ActorUid: state.Actor.GetMetadata().Uid,
}
_, err = client.Restore(ctx, req)
return maybeCrashActor(ctx, s.store, input.Atespace, input.ActorName, err, "while creating workload from golden snapshot")
Expand All @@ -341,6 +343,7 @@ func (s *CallAteletRestoreStep) Execute(ctx context.Context, input *ResumeInput,
ActorTemplateName: state.Actor.GetActorTemplateName(),
SandboxAssets: sandboxAssets,
Spec: workloadSpec,
ActorUid: state.Actor.GetMetadata().Uid,
}
_, err = client.Run(ctx, req)
return maybeCrashActor(ctx, s.store, input.Atespace, input.ActorName, err, "while creating workload from spec")
Expand Down
3 changes: 2 additions & 1 deletion cmd/ateapi/internal/controlapi/workflow_suspend.go
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,8 @@ func (s *CallAteletSuspendStep) Execute(ctx context.Context, input *SuspendInput
SnapshotUriPrefix: state.Actor.GetInProgressSnapshot(),
},
},
Scope: toAteletSnapshotScope(state.ActorTemplate.Spec.SnapshotsConfig.OnCommit),
Scope: toAteletSnapshotScope(state.ActorTemplate.Spec.SnapshotsConfig.OnCommit),
ActorUid: state.Actor.GetMetadata().Uid,
}

_, err = client.Checkpoint(ctx, req)
Expand Down
67 changes: 37 additions & 30 deletions cmd/atelet/main.go

Large diffs are not rendered by default.

14 changes: 10 additions & 4 deletions cmd/atelet/main_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@ func validRunRequest() *ateletpb.RunRequest {
ActorTemplateNamespace: "ate-demo",
ActorTemplateName: "counter",
TargetAteomUid: "422938ba-8860-4983-a25d-d6bcb0a69d4e",
ActorUid: "123e4567-e89b-12d3-a456-426614174000",
Spec: &ateletpb.WorkloadSpec{Containers: []*ateletpb.Container{{Name: "worker"}}},
}
}
Expand All @@ -107,6 +108,7 @@ func validCheckpointRequest() *ateletpb.CheckpointRequest {
ActorTemplateNamespace: "ate-demo",
ActorTemplateName: "counter",
TargetAteomUid: "422938ba-8860-4983-a25d-d6bcb0a69d4e",
ActorUid: "123e4567-e89b-12d3-a456-426614174000",
Spec: &ateletpb.WorkloadSpec{Containers: []*ateletpb.Container{{Name: "worker"}}},
Type: ateletpb.CheckpointType_CHECKPOINT_TYPE_EXTERNAL,
Config: &ateletpb.CheckpointRequest_ExternalConfig{
Expand All @@ -125,6 +127,7 @@ func validRestoreRequest() *ateletpb.RestoreRequest {
ActorTemplateNamespace: "ate-demo",
ActorTemplateName: "counter",
TargetAteomUid: "422938ba-8860-4983-a25d-d6bcb0a69d4e",
ActorUid: "123e4567-e89b-12d3-a456-426614174000",
Spec: &ateletpb.WorkloadSpec{Containers: []*ateletpb.Container{{Name: "worker"}}},
Type: ateletpb.CheckpointType_CHECKPOINT_TYPE_EXTERNAL,
Config: &ateletpb.RestoreRequest_ExternalConfig{
Expand All @@ -146,6 +149,7 @@ func TestValidateRunRequest(t *testing.T) {
{"invalid ateom uid", func(r *ateletpb.RunRequest) { r.TargetAteomUid = "../escape" }, true},
{"invalid atespace", func(r *ateletpb.RunRequest) { r.Atespace = "../escape" }, true},
{"invalid actor name", func(r *ateletpb.RunRequest) { r.ActorName = "../escape" }, true},
{"invalid actor uid", func(r *ateletpb.RunRequest) { r.ActorUid = "../escape" }, true},
{"invalid actor template namespace", func(r *ateletpb.RunRequest) { r.ActorTemplateNamespace = "Not_Valid" }, true},
{"invalid actor template name", func(r *ateletpb.RunRequest) { r.ActorTemplateName = "Not_Valid" }, true},
{"invalid container name", func(r *ateletpb.RunRequest) {
Expand Down Expand Up @@ -185,6 +189,7 @@ func TestValidateCheckpointRequest(t *testing.T) {
{"invalid ateom uid", makeReq(func(r *ateletpb.CheckpointRequest) { r.TargetAteomUid = "../escape" }), true},
{"invalid atespace", makeReq(func(r *ateletpb.CheckpointRequest) { r.Atespace = "../escape" }), true},
{"invalid actor name", makeReq(func(r *ateletpb.CheckpointRequest) { r.ActorName = "../escape" }), true},
{"invalid actor uid", makeReq(func(r *ateletpb.CheckpointRequest) { r.ActorUid = "../escape" }), true},
{"invalid actor template namespace", makeReq(func(r *ateletpb.CheckpointRequest) { r.ActorTemplateNamespace = "Not_Valid" }), true},
{"invalid actor template name", makeReq(func(r *ateletpb.CheckpointRequest) { r.ActorTemplateName = "Not_Valid" }), true},
{"invalid container name", makeReq(func(r *ateletpb.CheckpointRequest) {
Expand Down Expand Up @@ -227,6 +232,7 @@ func TestValidateRestoreRequest(t *testing.T) {
{"invalid ateom uid", makeReq(func(r *ateletpb.RestoreRequest) { r.TargetAteomUid = "../escape" }), true},
{"invalid atespace", makeReq(func(r *ateletpb.RestoreRequest) { r.Atespace = "../escape" }), true},
{"invalid actor name", makeReq(func(r *ateletpb.RestoreRequest) { r.ActorName = "../escape" }), true},
{"invalid actor uid", makeReq(func(r *ateletpb.RestoreRequest) { r.ActorUid = "../escape" }), true},
{"invalid actor template namespace", makeReq(func(r *ateletpb.RestoreRequest) { r.ActorTemplateNamespace = "Not_Valid" }), true},
{"invalid actor template name", makeReq(func(r *ateletpb.RestoreRequest) { r.ActorTemplateName = "Not_Valid" }), true},
{"invalid container name", makeReq(func(r *ateletpb.RestoreRequest) {
Expand Down Expand Up @@ -415,7 +421,7 @@ func TestRPCBoundariesReject(t *testing.T) {
s := &AteomHerder{}
ctx := context.Background()
badUID := "../escape" // valid actor ref, invalid ateom UID
const okAtespace, okID = "ate-demo", "counter-1"
const okAtespace, okID, okActorUID = "ate-demo", "counter-1", "123e4567-e89b-12d3-a456-426614174000"
okSpec := &ateletpb.WorkloadSpec{Containers: []*ateletpb.Container{{Name: "worker"}}}

wantInvalidArgument := func(t *testing.T, rpc string, err error) {
Expand All @@ -432,21 +438,21 @@ func TestRPCBoundariesReject(t *testing.T) {
t.Run("Run", func(t *testing.T) {
_, err := s.Run(ctx, &ateletpb.RunRequest{
Atespace: okAtespace, ActorName: okID,
TargetAteomUid: badUID, Spec: okSpec,
ActorUid: okActorUID, TargetAteomUid: badUID, Spec: okSpec,
})
wantInvalidArgument(t, "Run", err)
})
t.Run("Checkpoint", func(t *testing.T) {
_, err := s.Checkpoint(ctx, &ateletpb.CheckpointRequest{
Atespace: okAtespace, ActorName: okID,
TargetAteomUid: badUID, Spec: okSpec,
ActorUid: okActorUID, TargetAteomUid: badUID, Spec: okSpec,
})
wantInvalidArgument(t, "Checkpoint", err)
})
t.Run("Restore", func(t *testing.T) {
_, err := s.Restore(ctx, &ateletpb.RestoreRequest{
Atespace: okAtespace, ActorName: okID,
TargetAteomUid: badUID, Spec: okSpec,
ActorUid: okActorUID, TargetAteomUid: badUID, Spec: okSpec,
})
wantInvalidArgument(t, "Restore", err)
})
Expand Down
10 changes: 5 additions & 5 deletions cmd/atelet/oci.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,14 +56,14 @@ const (
ActorIDFileName = "actor-id"
)

func prepareOCIDirectory(ctx context.Context, pullCache *memorypullcache.MemoryPullCache, atespace, actorName, containerName, ref string, args []string, env []string, annotations map[string]string, netns string, identityDir string, durableDirVolumeMounts []*ateletpb.VolumeMount) error {
func prepareOCIDirectory(ctx context.Context, pullCache *memorypullcache.MemoryPullCache, actorUID, containerName, ref string, args []string, env []string, annotations map[string]string, netns string, identityDir string, durableDirVolumeMounts []*ateletpb.VolumeMount) error {
tracer := otel.Tracer("prepareOCIDirectory")

ctx, span := tracer.Start(ctx, "prepareOCIDirectory")
span.SetAttributes(attribute.String("image", ref))
defer span.End()

bundlePath := ateompath.OCIBundlePath(atespace, actorName, containerName)
bundlePath := ateompath.OCIBundlePath(actorUID, containerName)
rootPath := path.Join(bundlePath, "rootfs")

if err := removeAllWritable(rootPath); err != nil {
Expand Down Expand Up @@ -93,7 +93,7 @@ func prepareOCIDirectory(ctx context.Context, pullCache *memorypullcache.MemoryP
}
}

ociSpec := buildActorOCISpec(atespace, actorName, imageCfg, args, env, annotations, netns, identityDir, durableDirVolumeMounts)
ociSpec := buildActorOCISpec(actorUID, imageCfg, args, env, annotations, netns, identityDir, durableDirVolumeMounts)
ociSpecBytes, err := json.MarshalIndent(ociSpec, "", " ")
if err != nil {
return fmt.Errorf("while marshaling OCI spec: %w", err)
Expand Down Expand Up @@ -136,7 +136,7 @@ func mergeActorEnv(imageEnv, templateEnv []string) []string {
// When identityDir is non-empty it adds a read-only bind mount of that host
// directory at IdentityMountPath so the actor can read its own ID (see
// IdentityMountPath for why this is a bind mount rather than env vars).
func buildActorOCISpec(atespace string, actorName string, imageCfg *v1.Config, args []string, env []string, annotations map[string]string, netns string, identityDir string, durableDirVolumeMounts []*ateletpb.VolumeMount) *specs.Spec {
func buildActorOCISpec(actorUID string, imageCfg *v1.Config, args []string, env []string, annotations map[string]string, netns string, identityDir string, durableDirVolumeMounts []*ateletpb.VolumeMount) *specs.Spec {
var imageEnv []string
if imageCfg != nil {
imageEnv = imageCfg.Env
Expand Down Expand Up @@ -255,7 +255,7 @@ func buildActorOCISpec(atespace string, actorName string, imageCfg *v1.Config, a
spec.Mounts = append(spec.Mounts, specs.Mount{
Destination: vm.GetMountPath(),
Type: "bind",
Source: ateompath.DurableDirVolumeMountPoint(atespace, actorName, vm.GetName()),
Source: ateompath.DurableDirVolumeMountPoint(actorUID, vm.GetName()),
})
}

Expand Down
14 changes: 7 additions & 7 deletions cmd/atelet/oci_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -87,13 +87,13 @@ func runUntar(t *testing.T, entries []tarEntry) (string, error) {
// With an identity dir, a read-only bind mount appears at IdentityMountPath.
func TestBuildActorOCISpec_IdentityMount(t *testing.T) {
spec := buildActorOCISpec(
"atespace", "id",
"actor_uid",
nil,
[]string{"/app"},
[]string{"FOO=bar"},
map[string]string{"k": "v"},
"/run/netns/x",
"/host/actors/atespace:id/identity",
"/host/actors/actor_uid/identity",
nil,
)
found := false
Expand All @@ -102,7 +102,7 @@ func TestBuildActorOCISpec_IdentityMount(t *testing.T) {
continue
}
found = true
if m.Source != "/host/actors/atespace:id/identity" {
if m.Source != "/host/actors/actor_uid/identity" {
t.Errorf("identity mount source = %q, want the per-actor nameentity dir", m.Source)
}
if m.Type != "bind" {
Expand Down Expand Up @@ -167,7 +167,7 @@ func TestMergeActorEnv(t *testing.T) {

// Without an identity dir (the pause container), no identity mount appears.
func TestBuildActorOCISpec_NoIdentityMountForPause(t *testing.T) {
bare := buildActorOCISpec("atespace", "id", nil, []string{"/pause"}, nil, nil, "/run/netns/x", "", nil)
bare := buildActorOCISpec("actor_uid", nil, []string{"/pause"}, nil, nil, "/run/netns/x", "", nil)
for _, m := range bare.Mounts {
if m.Destination == IdentityMountPath {
t.Errorf("identity mount must be absent when identityDir is empty")
Expand All @@ -178,21 +178,21 @@ func TestBuildActorOCISpec_NoIdentityMountForPause(t *testing.T) {
// Each durable-dir volume mount becomes a bind mount whose source is the
// per-actor on-host DurableDirVolumeMountPoint for that volume name.
func TestBuildActorOCISpec_DurableDirVolumeMounts(t *testing.T) {
const atespace, id = "atespace", "id"
const actorUID = "actor_uid"
durableDirs := []*ateletpb.VolumeMount{
{Name: "data", MountPath: "/var/data"},
{Name: "cache", MountPath: "/var/cache"},
}
spec := buildActorOCISpec(
atespace, id,
actorUID,
nil, []string{"/app"}, nil, nil,
"/run/netns/x",
"",
durableDirs,
)

for _, vm := range durableDirs {
wantSrc := ateompath.DurableDirVolumeMountPoint(atespace, id, vm.Name)
wantSrc := ateompath.DurableDirVolumeMountPoint(actorUID, vm.Name)
found := false
for _, m := range spec.Mounts {
if m.Destination != vm.MountPath {
Expand Down
8 changes: 4 additions & 4 deletions cmd/atelet/sandbox_assets.go
Original file line number Diff line number Diff line change
Expand Up @@ -206,12 +206,12 @@ func (s *AteomHerder) openAsset(ctx context.Context, url string) (io.ReadCloser,
// writeSandboxRecord persists the actor's running sandbox assets on-node so a
// later Checkpoint (whose request no longer carries the sandbox config) can
// re-fetch the same binaries and pin them into the snapshot manifest.
func writeSandboxRecord(atespace, actorName string, rec *sandboxAssetsRecord) error {
func writeSandboxRecord(actorUID string, rec *sandboxAssetsRecord) error {
data, err := json.Marshal(rec)
if err != nil {
return wrapFileSystemErr("while marshaling sandbox record", err)
}
path := ateompath.ActorSandboxAssetsFile(atespace, actorName)
path := ateompath.ActorSandboxAssetsFile(actorUID)
if err := os.MkdirAll(filepath.Dir(path), 0o700); err != nil {
return wrapFileSystemErr("while creating actor dir", err)
}
Expand All @@ -223,8 +223,8 @@ func writeSandboxRecord(atespace, actorName string, rec *sandboxAssetsRecord) er

// readSandboxRecord loads the actor's on-node sandbox record written at
// Run/Restore.
func readSandboxRecord(atespace, actorName string) (*sandboxAssetsRecord, error) {
path := ateompath.ActorSandboxAssetsFile(atespace, actorName)
func readSandboxRecord(actorUID string) (*sandboxAssetsRecord, error) {
path := ateompath.ActorSandboxAssetsFile(actorUID)
data, err := os.ReadFile(path)
if err != nil {
return nil, wrapFileSystemErr("while reading sandbox record", err)
Expand Down
Loading