Node-placed agent terminal: container PTY on the agent's node + WebRTC, shared node-local drives
Completes "agent on a node" (single-node): when an agent's placement points at a fleet node, its terminal container runs there and the browser reaches it over a direct WebRTC DataChannel (LAN speed), sharing a node-local volume with the sandbox. gw-04-local agents are byte-identical to before. - cm-sandbox/docker.rs: empty drive subpath → mount the whole volume at the target (volume_options None), so a per-agent node-local volume auto-creates at ~/drives. - cm-api/fleet.rs: NodeHub.open_pty/webrtc_offer carry optional container+session (injected only when Some); node-terminal caller passes None (host shell unchanged). - cm-runtime/terminals.rs: TerminalManager gains node_provider + placement (mirrors SandboxManager, draining-aware); node_local_drive_mount(agent) = clawmates_agent_<id> at ~/drives; placement_for() ensures + locates the container; attach uses driver_for(node) (local byte-identical). - cm-runtime/sandboxes.rs: a node-placed agent sandbox mounts the same per-agent volume → shares files with the terminal on that node. - cm-api/routes/terminal.rs: ticket response gains `node`; ws() bridges node-placed agents through the NodeHub relay (WebRTC + fallback) execing into the container; local path unchanged. server main wires with_node_provider. - frontend: agentTerminalConnector mints the ticket then picks WebRTC (node-placed, ⚡ direct / relayed badge) vs WS (local); webrtcConnector generalized to be endpoint-agnostic (node terminal reuses it). Known follow-up: terminal (uid 65532) and sandbox (uid 10001) share the volume but differ in uid — cross-container writes need an aligned uid/gid (group-writable). Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
This commit is contained in:
co-authored by
Claude Opus 4.8
parent
12212c72ac
commit
10c89f5157
@@ -185,14 +185,21 @@ async fn run() -> Result<(), String> {
|
||||
} else {
|
||||
None
|
||||
};
|
||||
let terminals = std::sync::Arc::new(cm_runtime::TerminalManager::new(
|
||||
driver,
|
||||
pool.clone(),
|
||||
"local",
|
||||
&config.sandbox.terminal_image,
|
||||
config.sandbox.terminal_egress,
|
||||
drives,
|
||||
));
|
||||
let terminals = std::sync::Arc::new(
|
||||
cm_runtime::TerminalManager::new(
|
||||
driver,
|
||||
pool.clone(),
|
||||
"local",
|
||||
&config.sandbox.terminal_image,
|
||||
config.sandbox.terminal_egress,
|
||||
drives,
|
||||
)
|
||||
// An agent placed on a fleet node runs its terminal there too
|
||||
// (beside its sandbox), sharing the agent's node-local drives.
|
||||
.with_node_provider(std::sync::Arc::new(
|
||||
cm_api::fleet::HubDriverProvider::new(node_hub.clone()),
|
||||
)),
|
||||
);
|
||||
// Boot reconciliation: any sandbox the engine still holds is an
|
||||
// orphan from a dead process (we track none yet) — remove them
|
||||
// before warming so a crash/redeploy can't leak containers.
|
||||
|
||||
Reference in New Issue
Block a user