missions: topology_worker dials per-mission runtime endpoint (C3 slice 3)
When a topology_run is bound to a mission whose runtime_endpoint is
set, the worker constructs ZeroClawDriveExecutor against that URL
instead of the env-derived shared gateway. Falls back to shared for
non-mission runs and pre-C3 missions.
With slices 1-3 combined, a mission launched after this deploy will:
1. get its per-mission container spawned during on_launch
2. have its checkout dropped into /var/lib/clawmates-missions/<id>
which is bind-mounted to /mission inside that container
3. run its agents against ZEROCLAW_WORKSPACE=/mission/repo — so
they can see and edit only this missions repo, no bleed-over.
This commit is contained in:
@@ -147,13 +147,9 @@ async fn launch_phase(
|
|||||||
// pre-C3 missions or retries against a torn-down container land
|
// pre-C3 missions or retries against a torn-down container land
|
||||||
// here. Non-fatal: if docker is unreachable the run falls back to
|
// here. Non-fatal: if docker is unreachable the run falls back to
|
||||||
// the shared runtime.
|
// the shared runtime.
|
||||||
let mission = cm_db::repo::missions::get(
|
let mission = cm_db::repo::missions::get(pool, mission_id, workspace_id)
|
||||||
pool,
|
.await
|
||||||
mission_id,
|
.map_err(|e| format!("load mission for runtime binding: {e}"))?;
|
||||||
workspace_id,
|
|
||||||
)
|
|
||||||
.await
|
|
||||||
.map_err(|e| format!("load mission for runtime binding: {e}"))?;
|
|
||||||
if let Some(m) = mission {
|
if let Some(m) = mission {
|
||||||
if m.runtime_endpoint.is_none() {
|
if m.runtime_endpoint.is_none() {
|
||||||
if let Some(prov) = crate::mission_runtime::MissionRuntimeProvisioner::from_env() {
|
if let Some(prov) = crate::mission_runtime::MissionRuntimeProvisioner::from_env() {
|
||||||
|
|||||||
@@ -148,11 +148,26 @@ async fn run_job(
|
|||||||
.and_then(|c| serde_json::from_value(c).ok())
|
.and_then(|c| serde_json::from_value(c).ok())
|
||||||
.unwrap_or_default();
|
.unwrap_or_default();
|
||||||
|
|
||||||
// Missions-era runs drive through the shared, env-derived ZeroClaw
|
// C3: prefer the mission's per-run runtime endpoint when set on
|
||||||
// gateway — per-claw provisioning happens ahead of time via
|
// the missions row; else fall back to the shared env-derived
|
||||||
// `RuntimeProvisioner` (see `mission_orchestrator::on_launch`), so
|
// gateway (pre-C3 missions + non-mission runs). This is what
|
||||||
// there's no per-run container/gateway resolution left to do here.
|
// isolates agents' workspace filesystem to that mission's repo.
|
||||||
let leaf_result = ZeroClawDriveExecutor::from_env();
|
let mission_endpoint: Option<String> = sqlx::query_scalar::<_, Option<String>>(
|
||||||
|
"SELECT m.runtime_endpoint
|
||||||
|
FROM topology_runs r
|
||||||
|
JOIN missions m ON m.id = r.mission_id
|
||||||
|
WHERE r.id = $1",
|
||||||
|
)
|
||||||
|
.bind(id)
|
||||||
|
.fetch_optional(pool)
|
||||||
|
.await
|
||||||
|
.ok()
|
||||||
|
.flatten()
|
||||||
|
.flatten();
|
||||||
|
let leaf_result = match mission_endpoint {
|
||||||
|
Some(url) => ZeroClawDriveExecutor::from_env_for_gateway(url),
|
||||||
|
None => ZeroClawDriveExecutor::from_env(),
|
||||||
|
};
|
||||||
let leaf = match leaf_result {
|
let leaf = match leaf_result {
|
||||||
Ok(e) => e,
|
Ok(e) => e,
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
|
|||||||
Reference in New Issue
Block a user