Skip to content

Add ActorDirs message to carry per-actor directories and and split the path packages by owner - #1730

Merged
Benjamin Elder (BenTheElder) merged 5 commits into
agent-substrate:mainfrom
HavenXia:ateom-actor-dirs
Sep 25, 2026
Merged

Benjamin Elder (BenTheElder) merged 5 commits into
agent-substrate:mainfrom
HavenXia:ateom-actor-dirs

Conversation

@HavenXia

@HavenXia Haven Xia (HavenXia) commented Sep 18, 2026 •

Copy link
Copy Markdown
Member

Today atelet and ateom derive the per-actor directories (oci bundles, runsc state, pid files, checkpoint and restore state, durable-dir, system-info and volume roots) from the actor UID through the same package, internal/ateompath.

This PR:

  1. Add an ActorDirs message to RunWorkloadRequest, RestoreWorkloadRequest, CheckpointWorkloadRequest and TerminateWorkloadRequest, and have atelet fill it with the directories it prepared. The ateoms do not read it yet.

  2. Split internal/ateompath into:

    • cmd/atelet/internal/ateletpath: atelet's pathes, the per-actor directories (and ActorDirs, built from them) plus the directories only atelet uses.
    • internal/nodepath: shared pathes, the base dir both mount, the ateom socket, the OTLP
      sockets, and the netns name.
    • internal/ateompath: what the ateoms still derive from the actor UID, each function marked with the ActorDirs field it duplicates. atelet no longer imports it.

This is the first part of #1604 to decouple atelet and ateom shared pathes. Behavior does not change: both sides still compute the same paths, atelet from ateletpath and the ateoms from ateompath.

Followup PRs will remove ateompath by making ateom-gvisor and ateom-microvm read the ActorDirs message from RPC.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

so for dirs that atelet feeds to ateom, let's split those off to a package internal to atelet so we know ateoms are not assuming it? (and vice versa, atelet should stop using ateompath)

there should probably be a third package for the socket paths they share

@HavenXia

Copy link
Copy Markdown
Member Author

so for dirs that atelet feeds to ateom, let's split those off to a package internal to atelet so we know ateoms are not assuming it? (and vice versa, atelet should stop using ateompath)

there should probably be a third package for the socket paths they share

I agree on the shape for 3 packages: atelet/internal/ for this PR's pathes, a shared path for shared pathes and an ateom specific path for ateoms.

But this PR add only the proto and RPC, the follow up PRs will do the refactors, do you want me to have them together in this PR?

@BenTheElder

Copy link
Copy Markdown
Collaborator

But this PR add only the proto and RPC, the follow up PRs will do the refactors, do you want me to have them together in this PR?

I think we want to reason about what these paths are and how they should be split more easily. If you don't have time a follow-up is OK, but to me that part is more important than cramming the paths into the RPCs. Otherwise you can't tell if the RPC change adequately captured the path knowledge.

@HavenXia Haven Xia (HavenXia) changed the title Add ActorDirs message to carry per-actor directories Add ActorDirs message to carry per-actor directories and and split the path packages by owner Sep 22, 2026
@HavenXia
Haven Xia (HavenXia) force-pushed the ateom-actor-dirs branch 2 times, most recently from bc33f8f to 9529d68 Compare September 22, 2026 01:02
@HavenXia

Copy link
Copy Markdown
Member Author

But this PR add only the proto and RPC, the follow up PRs will do the refactors, do you want me to have them together in this PR?

I think we want to reason about what these paths are and how they should be split more easily. If you don't have time a follow-up is OK, but to me that part is more important than cramming the paths into the RPCs. Otherwise you can't tell if the RPC change adequately captured the path knowledge.

Added the refactor part into this PR, the removing of ateom itself and using the ActorDirs message from RPC is put into next PR

@HavenXia

Copy link
Copy Markdown
Member Author

rebased over #1689, Benjamin Elder (@BenTheElder) PTAL

@@ -0,0 +1,77 @@
// Copyright 2026 Google LLC

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Aside: we will eventually export this package when atelet/ateom settle down.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ACK

Comment thread tools/validate-image-cache/main.go Resolved
// to request credentials for the worker's current actor assignment.
var AteomSupportSocket = filepath.Join(BasePath, "ateom-support.sock")

// AteletOTLPSocketPath is the node-scoped unix socket atelet serves the OTLP

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note to self: we will drop the relay and just let ateom push directly following #1689 🎉

Comment thread kubeconfig Resolved
Comment thread internal/resources/snapshot.go Outdated
tagsOwnerKind = "tags"
)

// DurableDirTarFile is the snapshot file holding the tar of an actor's

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is supposed to be opaque to the snapshot tooling it should not know about the specific files.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

moved to a separete snapshotfiles.go next to it

return filepath.Join(LocalCheckpointsDir(actorUID), snapshotName)
}

// DurableDirTarFile is the snapshot file holding the tar of an

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK so maybe it's not for this PR, but please file a TODO, this is a really bad API, atlet should just ask for a data snapshot if that's what it wants and we should not take a full snapshot to begin with, nor know about specific snapshot filenames.

Then atelet can upload whatever files happen to be produced by the snapshot, regardless of type.

Dmitry Berkovich (@dberkov) something we should roll up with any updated snapshot lifeycle.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added TODO

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should probably be a tracking issue, beyond a code todo. This is a bug that will limit our options in the future.

FYI Michelle Au (@msau42)

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Comment thread internal/proto/ateompb/ateom.pb.go Outdated
// Holds one OCI bundle per container, named after the container.
OciBundleDir string `protobuf:"bytes,2,opt,name=oci_bundle_dir,json=ociBundleDir,proto3" json:"oci_bundle_dir,omitempty"`
// runsc --root for the actor's sandbox. gVisor only.
RunscStateDir string `protobuf:"bytes,3,opt,name=runsc_state_dir,json=runscStateDir,proto3" json:"runsc_state_dir,omitempty"`

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TODO: can we eliminate ateom knowing about gvisor vs ...? it mostly doesn't.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

for similar APIs we got rid of atelet knowing about this vs ateom knowing it. need to trace this one to see why we have to pass it between them vs deriving it in an opaque way without atelet carrying this knowledge at all.

@HavenXia Haven Xia (HavenXia) Sep 24, 2026 •

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

okay, they can be removed from ActorDir as they are not directly write by atelet but only read by ateom-gvisor.

SystemInfoVolumeRootsDir string `protobuf:"bytes,8,opt,name=system_info_volume_roots_dir,json=systemInfoVolumeRootsDir,proto3" json:"system_info_volume_roots_dir,omitempty"`
// Holds one mount point per CSI volume.
VolumesDir string `protobuf:"bytes,9,opt,name=volumes_dir,json=volumesDir,proto3" json:"volumes_dir,omitempty"`
unknownFields protoimpl.UnknownFields

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hmmmm

@HavenXia Haven Xia (HavenXia) Sep 24, 2026 •

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These two should be kept, atelet writes into them (it mounts the CSI volumes and generates the system-info files), and ateom-microvm reads them to for the guest paths.

Comment on lines +67 to +72
func RunSCStateDir(actorUID string) string {
return filepath.Join(
ActorPath(actorUID),
"runsc-state",
)
}

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤖 should-fix 🟡 – Dropping runsc_state_dir and pid_file_dir from ActorDirs removed them from the interface, but atelet still owns them. resetActorDirs (cmd/atelet/main.go:1864-1878) still wipes and creates runsc-state and pidfiles for every actor, micro-VM ones included, through this function and PIDFileDir below.

ateom-gvisor never creates either directory; it relies on atelet having made them. So the gVisor knowledge hasn't left atelet yet.

To finish the move, have ateom-gvisor create both under its root dir before it first calls runsc, the way it already does for the checkpoint dir. Then this function, PIDFileDir and that block in resetActorDirs can go.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Human: Yes that's the next PR I think.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes, in next pr. Don't want to cause any skew between two PRs

@BenTheElder
Benjamin Elder (BenTheElder) added this pull request to the merge queue Sep 25, 2026
@github-merge-queue
github-merge-queue Bot removed this pull request from the merge queue due to failed status checks Sep 25, 2026
atelet and both ateoms derive the per-actor directories (bundles, runsc
state, pid files, checkpoint and restore state, durable-dir, system-info
and CSI volume roots) from the actor UID through the same package,
internal/ateompath. 

Add an ActorDirs message to RunWorkloadRequest, RestoreWorkloadRequest,
CheckpointWorkloadRequest and TerminateWorkloadRequest, and have atelet
fill it with the directories it prepared.
- cmd/atelet/internal/ateletpath: atelet's on-node pathes, the per-actor
  directories it prepares (and ActorDirs, built from them) plus the
  node-level directories only atelet uses. 
- internal/nodepath: what both sides need before the first RPC, the
  host directory they mount and the sockets and netns they find each
  other by. atecontroller renders the worker pod's hostPath from it.
- internal/ateompath: only what the ateoms still uses it self.
atelet never reads the runsc state directory or the pid file directory.
Both belong to ateom-gvisor, which can keep them under root_dir the way it keeps the sandbox resolv.conf, so ActorDirs no longer carries runsc_state_dir or pid_file_dir.
after agent-substrate#1843 StaticFilesDir is no longer atelet-only.
@BenTheElder
Benjamin Elder (BenTheElder) added this pull request to the merge queue Sep 25, 2026
Merged via the queue into agent-substrate:main with commit a0b680d Sep 25, 2026
11 checks passed
pull Bot pushed a commit to RolfLobo/substrate that referenced this pull request Sep 28, 2026
…trate#1865)

This PR let ateom-gvisor reads the per-actor directories from the
`ActorDirs` (added in agent-substrate#1730) in the request instead of deriving them
from the actor UID.

The paths `ateom-gvisor` still builds itself are put into gvisor
specific `cmd/ateom-gvisor/actorpath.go`.

Resetting `runsc-state` and `pidfiles` moves from atelet's
`resetActorDirs` to ateom-gvisor's `main.go` to conduct at beginning of
`RunWorkload` and `RestoreWorkload`, which empties them at the start of
Run and Restore. Atelet doesn't actually read them, so agent-substrate#1730 drops them
from `ActorDirs`.

Added a new `ActorDirs` validation to reject a request with
`InvalidArgument` when `ActorDirs` is missing or any directory in it is
empty, relative or unclean.

The gVisor paths are removed from `internal/ateompath`; the rest goes
with ateom-microvm in the next PR.

Part of agent-substrate#1604.
Vu Le (lekhoavu2909) pushed a commit to lekhoavu2909/substrate that referenced this pull request Sep 29, 2026
… ateompath package (agent-substrate#1872)

This PR let ateom-microvm reads the per-actor directories from the
`ActorDirs` (added in agent-substrate#1730) in the request instead of deriving them
from the actor UID.

The paths ateom-microvm still builds itself are put into microvm
specific`cmd/ateom-microvm/actorpath.go`.

The `ateompath` package as nothing uses it anymore.

Fix agent-substrate#1604
@HavenXia
Haven Xia (HavenXia) deleted the ateom-actor-dirs branch October 28, 2026 16:26
@HavenXia
Haven Xia (HavenXia) restored the ateom-actor-dirs branch October 28, 2026 16:27
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area/api User-facing API changes area/api-machinery

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants