fix(mission_runtime): re-add shared /zeroclaw-data mount for agent library
Fresh runtimes had zero agents in their config so WS handshake with ?agent=scout returned 400. Bind-mount the shared runtimes data dir so per-mission gateways inherit the seeded claw_* agents. Per-mission pairing (minted via /admin/paircode/new) still works against the shared devices.db — each mission gets its own accepted token. Concurrency caveat on sqlite sessions.db documented in the const doc comment.
This commit is contained in:
@@ -55,6 +55,22 @@ const EDGE_NETWORK: &str = "clawmates_edge";
|
|||||||
/// by `clawmates-runtime.service`.
|
/// by `clawmates-runtime.service`.
|
||||||
const MISSIONS_HOST_ROOT: &str = "/var/lib/clawmates-missions";
|
const MISSIONS_HOST_ROOT: &str = "/var/lib/clawmates-missions";
|
||||||
|
|
||||||
|
/// Host path holding the shared ZeroClaw config + seeded agent library
|
||||||
|
/// (built up over time by the shared clawmates-runtime.service). Per-
|
||||||
|
/// mission runtime containers bind-mount this so their gateway
|
||||||
|
/// inherits all the `claw_*` agents that team_template_loader has
|
||||||
|
/// provisioned. Each per-mission container then MINTS ITS OWN pairing
|
||||||
|
/// code via /admin/paircode/new so the accepted-tokens list is
|
||||||
|
/// independent per mission. Overridable for dev via
|
||||||
|
/// `CLAWMATES_RUNTIME_SEED_DIR`.
|
||||||
|
///
|
||||||
|
/// Concurrency caveat: the sqlite files under .zeroclaw/data/ are
|
||||||
|
/// currently shared across all per-mission runtimes AND the shared
|
||||||
|
/// runtime. Concurrent daemons opening the same sessions.db can
|
||||||
|
/// interleave; in practice topology_worker sequentializes runs per
|
||||||
|
/// mission so this rarely bites. Long-term: copy-on-write per mission.
|
||||||
|
const DEFAULT_SEED_DIR: &str = "/root/clawmates-runtime/data";
|
||||||
|
|
||||||
/// Deterministic docker container name for a mission's runtime.
|
/// Deterministic docker container name for a mission's runtime.
|
||||||
/// Uses the full UUID hex — UUIDv7 encodes time in the leading bytes,
|
/// Uses the full UUID hex — UUIDv7 encodes time in the leading bytes,
|
||||||
/// so a short prefix isn't guaranteed unique across missions minted
|
/// so a short prefix isn't guaranteed unique across missions minted
|
||||||
@@ -150,13 +166,11 @@ impl MissionRuntimeProvisioner {
|
|||||||
// present or docker start fails with EACCES/ENOENT.
|
// present or docker start fails with EACCES/ENOENT.
|
||||||
let mission_dir = format!("{MISSIONS_HOST_ROOT}/{mission_id}");
|
let mission_dir = format!("{MISSIONS_HOST_ROOT}/{mission_id}");
|
||||||
let _ = tokio::fs::create_dir_all(&mission_dir).await;
|
let _ = tokio::fs::create_dir_all(&mission_dir).await;
|
||||||
|
let seed_dir = std::env::var("CLAWMATES_RUNTIME_SEED_DIR")
|
||||||
|
.unwrap_or_else(|_| DEFAULT_SEED_DIR.to_string());
|
||||||
let mounts = vec![
|
let mounts = vec![
|
||||||
// Mount just this mission's directory. Agents can navigate
|
// Mount just this mission's directory. Agents can navigate
|
||||||
// its `/repo` subdir but never see other missions'.
|
// its `/repo` subdir but never see other missions'.
|
||||||
// `/zeroclaw-data` is intentionally NOT bind-mounted — each
|
|
||||||
// per-mission gateway boots with a fresh state directory
|
|
||||||
// and mints its own pairing code, scraped in
|
|
||||||
// `wait_for_pairing_code` below.
|
|
||||||
Mount {
|
Mount {
|
||||||
target: Some("/mission".to_string()),
|
target: Some("/mission".to_string()),
|
||||||
source: Some(mission_dir.clone()),
|
source: Some(mission_dir.clone()),
|
||||||
@@ -164,6 +178,18 @@ impl MissionRuntimeProvisioner {
|
|||||||
read_only: Some(false),
|
read_only: Some(false),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
},
|
},
|
||||||
|
// Share the shared-runtime data dir so this gateway inherits
|
||||||
|
// the seeded agent library (`claw_*` templates). We then
|
||||||
|
// mint a per-mission pairing code via /admin/paircode/new
|
||||||
|
// below — the mint writes into the shared devices.db but
|
||||||
|
// the resulting token is unique to this mission.
|
||||||
|
Mount {
|
||||||
|
target: Some("/zeroclaw-data".to_string()),
|
||||||
|
source: Some(seed_dir),
|
||||||
|
typ: Some(MountTypeEnum::BIND),
|
||||||
|
read_only: Some(false),
|
||||||
|
..Default::default()
|
||||||
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
let host_config = HostConfig {
|
let host_config = HostConfig {
|
||||||
|
|||||||
Reference in New Issue
Block a user