diff --git a/cmd/atelet/main.go b/cmd/atelet/main.go index 9a5eaefaa..9c8cc8958 100644 --- a/cmd/atelet/main.go +++ b/cmd/atelet/main.go @@ -647,15 +647,15 @@ func (s *AteomHerder) prepareOCIBundles( spec *ateletpb.WorkloadSpec, targetAteomUid string, ) error { - // Populate the per-actor nameentity directory that gets bind-mounted into + // 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 name even when restoring from the golden snapshot. identityDir := ateompath.ActorIdentityDirPath(atespace, actorName) if err := os.MkdirAll(identityDir, 0o755); err != nil { - return fmt.Errorf("while creating actor nameentity dir: %w", err) + return fmt.Errorf("while creating actor identity dir: %w", err) } - if err := writeFileAtomic(filepath.Join(identityDir, ActorIDFileName), []byte(actorName), 0o644); err != nil { - return fmt.Errorf("while writing actor nameentity file: %w", err) + if err := writeFileAtomic(filepath.Join(identityDir, ActorNameFileName), []byte(actorName), 0o644); err != nil { + return fmt.Errorf("while writing actor identity file: %w", err) } ddVolumes := make(map[string]bool) @@ -698,7 +698,7 @@ func (s *AteomHerder) prepareOCIBundles( nil, annotations, ateompath.AteomNetNSPath(targetAteomUid), - "", // pause is sandbox infra; it gets no actor nameentity mount. + "", // pause is sandbox infra; it gets no actor identity mount. nil, ); err != nil { return wrapFileSystemErr("while creating pause OCI bundle", err) @@ -1044,10 +1044,10 @@ func resetActorDirs(atespace, actorName string) error { // reads it through the gofer. identityDir := ateompath.ActorIdentityDirPath(atespace, actorName) if err := os.RemoveAll(identityDir); err != nil { - return wrapFileSystemErr("while deleting actor nameentity dir: %w", err) + return wrapFileSystemErr("while deleting actor identity dir: %w", err) } if err := os.MkdirAll(identityDir, 0o755); err != nil { - return wrapFileSystemErr("while creating actor nameentity dir: %w", err) + return wrapFileSystemErr("while creating actor identity dir: %w", err) } durableDirVolumesMountDir := ateompath.DurableDirVolumeMountsDir(atespace, actorName) diff --git a/cmd/atelet/main_test.go b/cmd/atelet/main_test.go index fcbac250e..007e91c2d 100644 --- a/cmd/atelet/main_test.go +++ b/cmd/atelet/main_test.go @@ -39,7 +39,7 @@ import ( func TestWriteFileAtomic(t *testing.T) { dir := t.TempDir() - target := filepath.Join(dir, "actor-id") + target := filepath.Join(dir, "actor-name") // One shared write over an existing value, as happens on every resume; // each subtest checks one postcondition. diff --git a/cmd/atelet/oci.go b/cmd/atelet/oci.go index 0f5e99765..aade983a8 100644 --- a/cmd/atelet/oci.go +++ b/cmd/atelet/oci.go @@ -49,9 +49,9 @@ const ( // changing the mount shape. IdentityMountPath = "/run/ate" - // ActorIDFileName is the file inside IdentityMountPath holding the - // actor's own ID, raw with no trailing newline. - ActorIDFileName = "actor-id" + // ActorNameFileName is the file inside IdentityMountPath holding the + // actor's own name, raw with no trailing newline. + ActorNameFileName = "actor-name" ) 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 { @@ -82,8 +82,8 @@ func prepareOCIDirectory(ctx context.Context, pullCache *memorypullcache.MemoryP return fmt.Errorf("in untar: %w", err) } - // Bind-mount the per-actor nameentity directory so the workload can read its - // own ID at IdentityMountPath/ActorIDFileName. The bind target must exist + // Bind-mount the per-actor identity directory so the workload can read its + // own name at IdentityMountPath/ActorNameFileName. The bind target must exist // in the rootfs for the mount to attach. if identityDir != "" { if err := createMountPoint(rootPath, IdentityMountPath); err != nil { diff --git a/cmd/atelet/oci_test.go b/cmd/atelet/oci_test.go index 11576fd29..c29c7e4a5 100644 --- a/cmd/atelet/oci_test.go +++ b/cmd/atelet/oci_test.go @@ -103,7 +103,7 @@ func TestBuildActorOCISpec_IdentityMount(t *testing.T) { } found = true if m.Source != "/host/actors/atespace:id/identity" { - t.Errorf("identity mount source = %q, want the per-actor nameentity dir", m.Source) + t.Errorf("identity mount source = %q, want the per-actor identity dir", m.Source) } if m.Type != "bind" { t.Errorf("identity mount type = %q, want bind", m.Type) diff --git a/cmd/ateom-microvm/spec.go b/cmd/ateom-microvm/spec.go index 7962bc5aa..ab60fa326 100644 --- a/cmd/ateom-microvm/spec.go +++ b/cmd/ateom-microvm/spec.go @@ -89,7 +89,7 @@ func ensureKataCompatibleSpec(bundle, id, netnsPath string) (*specs.Spec, error) // agent accepts. (Static shaper; pod DNS integration is future work.) // // KNOWN GAP vs the gVisor runtime: this also drops atelet's read-only actor - // identity bind mount (/run/ate/actor-id). The micro-VM guest can't see host + // identity bind mount (/run/ate/actor-name). The micro-VM guest can't see host // paths (the rootfs is an overlay of a virtio-fs base + a guest-RAM upper, not a // host bind), so atelet's host-path identity mount has nothing to bind to. // Exposing the identity needs a per-actor volume plumbed into the guest; not yet diff --git a/docs/api-guide.md b/docs/api-guide.md index f00d5d3f4..0ff5d9b92 100644 --- a/docs/api-guide.md +++ b/docs/api-guide.md @@ -101,14 +101,14 @@ Because a snapshot is not restorable across sandbox runtimes, `sandboxClass` is Container environment variables support literal `value` entries and `valueFrom.secretKeyRef`. Secret references are resolved by `ate-api-server` from the `ActorTemplate` namespace when a workload spec is materialized. For the golden actor, the resolved values are captured in the golden snapshot and future actors inherit those values until the golden snapshot is recreated. For an actor that bypasses the golden snapshot and boots from the current template spec, the resolved values are sent to atelet but are not serialized into the public Actor API. Other Kubernetes `valueFrom` sources are not supported yet. Secret changes do not automatically restart actors or invalidate snapshots; rotating a Secret requires an explicit actor or template lifecycle action. ### Workload Connectivity (Uniform DNS) -Substrate uses a **Uniform DNS Mesh**: every actor created from a template is automatically reachable through the **Substrate Router** via its atespace and ID: +Substrate uses a **Uniform DNS Mesh**: every actor created from a template is automatically reachable through the **Substrate Router** via its atespace and name: -**Format:** `..actors.resources.substrate.ate.dev` +**Format:** `..actors.resources.substrate.ate.dev` ### Actor Identity -Substrate bind-mounts a read-only, per-actor identity directory at **`/run/ate`** into each of the actor's containers. An actor can learn its own ID without parsing the `Host` header by reading the file **`/run/ate/actor-id`** inside it, which contains the raw actor ID with no trailing newline. Further identity and configuration data may appear in this directory over time. +Substrate bind-mounts a read-only, per-actor identity directory at **`/run/ate`** into each of the actor's containers. An actor can learn its own name without parsing the `Host` header by reading the file **`/run/ate/actor-name`** inside it, which contains the raw actor name with no trailing newline. Further identity and configuration data may appear in this directory over time. -Read it fresh rather than caching it at process start. It is delivered as a per-actor bind mount, not an environment variable, precisely so it carries the correct ID after a resume from the golden snapshot — an env var (or a file baked into the image) would be frozen at the *golden* actor's ID, since it lives in the checkpointed process memory, and would therefore be identical for every actor of the template. +Read it fresh rather than caching it at process start. It is delivered as a per-actor bind mount, not an environment variable, precisely so it carries the correct name after a resume from the golden snapshot — an env var (or a file baked into the image) would be frozen at the *golden* actor's name, since it lives in the checkpointed process memory, and would therefore be identical for every actor of the template. ### Container Readiness Probe (`readyz`) diff --git a/internal/ateompath/ateompath.go b/internal/ateompath/ateompath.go index 16f3c63aa..ec4ffda2e 100644 --- a/internal/ateompath/ateompath.go +++ b/internal/ateompath/ateompath.go @@ -69,7 +69,7 @@ func ActorPath(atespace, actorName string) string { } // ActorIdentityDirPath is the host directory atelet populates with the -// actor's identity data (currently the single file "actor-id") and +// actor's identity data (currently the single file "actor-name") and // 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. diff --git a/internal/e2e/fixtures/probe/main.go b/internal/e2e/fixtures/probe/main.go index 6927a1d04..ff5a1b52e 100644 --- a/internal/e2e/fixtures/probe/main.go +++ b/internal/e2e/fixtures/probe/main.go @@ -27,9 +27,9 @@ import ( "os" ) -// identityFile is the actor-id file inside the identity directory atelet +// identityFile is the actor-name file inside the identity directory atelet // bind-mounts at IdentityMountPath. -const identityFile = "/run/ate/actor-id" +const identityFile = "/run/ate/actor-name" // whoami reports the actor's identity as observed at request time from the // bind-mounted identity file. A read failure is reported in the response diff --git a/internal/e2e/suites/identity/identity_test.go b/internal/e2e/suites/identity/identity_test.go index f32ced832..7f54507ba 100644 --- a/internal/e2e/suites/identity/identity_test.go +++ b/internal/e2e/suites/identity/identity_test.go @@ -78,7 +78,7 @@ func TestActorIdentity_AfterRestore_IsOwnID_NotGolden(t *testing.T) { got := whoami(t, ctx, rc, id) if got.File != id { - t.Errorf("actor %q: /run/ate/actor-id = %q, want %q (probe read error: %q)", id, got.File, id, got.Error) + t.Errorf("actor %q: /run/ate/actor-name = %q, want %q (probe read error: %q)", id, got.File, id, got.Error) } if got.File == golden { t.Errorf("actor %q: identity is the GOLDEN snapshot id %q — restore leaked shared state", id, golden)