wire types: add sha + tag to Approval and HelperEvent
approval grows fetched_sha (canonical hive-c0re-vouched sha,
distinct from manager-supplied commit_ref). helperevent
{approvalresolved,spawned,rebuilt} grow optional sha + tag so
the manager can git-show the exact tree it's hearing about
(against the upcoming /agents/<n>/applied.git RO mount) and
know which terminal tag landed. all serde-defaulted; existing
construction sites pass none until the tag-driven flow lands.
This commit is contained in:
parent
497cd15137
commit
871e7bf3fa
5 changed files with 55 additions and 1 deletions
|
|
@ -105,6 +105,8 @@ fn finish_approval(
|
||||||
commit_ref: approval.commit_ref.clone(),
|
commit_ref: approval.commit_ref.clone(),
|
||||||
status,
|
status,
|
||||||
note: note.clone(),
|
note: note.clone(),
|
||||||
|
sha: approval.fetched_sha.clone(),
|
||||||
|
tag: None,
|
||||||
});
|
});
|
||||||
// For spawn/rebuild approvals, also surface the underlying action so
|
// For spawn/rebuild approvals, also surface the underlying action so
|
||||||
// the manager knows whether the container actually came up. The
|
// the manager knows whether the container actually came up. The
|
||||||
|
|
@ -116,11 +118,14 @@ fn finish_approval(
|
||||||
agent: approval.agent.clone(),
|
agent: approval.agent.clone(),
|
||||||
ok,
|
ok,
|
||||||
note,
|
note,
|
||||||
|
sha: approval.fetched_sha.clone(),
|
||||||
}),
|
}),
|
||||||
ApprovalKind::ApplyCommit => coord.notify_manager(&HelperEvent::Rebuilt {
|
ApprovalKind::ApplyCommit => coord.notify_manager(&HelperEvent::Rebuilt {
|
||||||
agent: approval.agent.clone(),
|
agent: approval.agent.clone(),
|
||||||
ok,
|
ok,
|
||||||
note,
|
note,
|
||||||
|
sha: approval.fetched_sha.clone(),
|
||||||
|
tag: None,
|
||||||
}),
|
}),
|
||||||
}
|
}
|
||||||
result
|
result
|
||||||
|
|
@ -183,12 +188,15 @@ pub fn deny(coord: &Coordinator, id: i64, note: Option<&str>) -> Result<()> {
|
||||||
coord.approvals.mark_denied(id, note)?;
|
coord.approvals.mark_denied(id, note)?;
|
||||||
tracing::info!(%id, note, "approval denied");
|
tracing::info!(%id, note, "approval denied");
|
||||||
if let Some(a) = approval {
|
if let Some(a) = approval {
|
||||||
|
let sha = a.fetched_sha.clone();
|
||||||
coord.notify_manager(&HelperEvent::ApprovalResolved {
|
coord.notify_manager(&HelperEvent::ApprovalResolved {
|
||||||
id: a.id,
|
id: a.id,
|
||||||
agent: a.agent,
|
agent: a.agent,
|
||||||
commit_ref: a.commit_ref,
|
commit_ref: a.commit_ref,
|
||||||
status: ApprovalStatus::Denied,
|
status: ApprovalStatus::Denied,
|
||||||
note: note.map(String::from),
|
note: note.map(String::from),
|
||||||
|
sha,
|
||||||
|
tag: None,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|
|
||||||
|
|
@ -139,6 +139,7 @@ impl Approvals {
|
||||||
status: ApprovalStatus::Approved,
|
status: ApprovalStatus::Approved,
|
||||||
resolved_at: Some(resolved_at),
|
resolved_at: Some(resolved_at),
|
||||||
note: None,
|
note: None,
|
||||||
|
fetched_sha: None,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -214,6 +215,7 @@ fn row_to_approval(row: &rusqlite::Row<'_>) -> rusqlite::Result<Approval> {
|
||||||
status,
|
status,
|
||||||
resolved_at: row.get(6)?,
|
resolved_at: row.get(6)?,
|
||||||
note: row.get(7)?,
|
note: row.get(7)?,
|
||||||
|
fetched_sha: None,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -78,6 +78,8 @@ pub async fn rebuild_agent(coord: &Arc<Coordinator>, name: &str, current_rev: &s
|
||||||
agent: name.to_owned(),
|
agent: name.to_owned(),
|
||||||
ok: true,
|
ok: true,
|
||||||
note: None,
|
note: None,
|
||||||
|
sha: None,
|
||||||
|
tag: None,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
|
|
@ -85,6 +87,8 @@ pub async fn rebuild_agent(coord: &Arc<Coordinator>, name: &str, current_rev: &s
|
||||||
agent: name.to_owned(),
|
agent: name.to_owned(),
|
||||||
ok: false,
|
ok: false,
|
||||||
note: Some(format!("{e:#}")),
|
note: Some(format!("{e:#}")),
|
||||||
|
sha: None,
|
||||||
|
tag: None,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -83,6 +83,7 @@ async fn dispatch(req: &HostRequest, coord: Arc<Coordinator>) -> HostResponse {
|
||||||
agent: name.clone(),
|
agent: name.clone(),
|
||||||
ok: true,
|
ok: true,
|
||||||
note: None,
|
note: None,
|
||||||
|
sha: None,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
|
|
@ -92,6 +93,7 @@ async fn dispatch(req: &HostRequest, coord: Arc<Coordinator>) -> HostResponse {
|
||||||
agent: name.clone(),
|
agent: name.clone(),
|
||||||
ok: false,
|
ok: false,
|
||||||
note: Some(format!("{e:#}")),
|
note: Some(format!("{e:#}")),
|
||||||
|
sha: None,
|
||||||
});
|
});
|
||||||
return Err(e);
|
return Err(e);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -65,8 +65,18 @@ pub struct Approval {
|
||||||
pub agent: String,
|
pub agent: String,
|
||||||
#[serde(default)]
|
#[serde(default)]
|
||||||
pub kind: ApprovalKind,
|
pub kind: ApprovalKind,
|
||||||
/// For `ApplyCommit`: the git sha to apply. For `Spawn`: empty.
|
/// For `ApplyCommit`: the git sha the manager submitted. For `Spawn`:
|
||||||
|
/// empty. Note that this is the manager's *claimed* ref — the
|
||||||
|
/// canonical, hive-c0re-vouched sha after the proposal fetch lives
|
||||||
|
/// in `fetched_sha`.
|
||||||
pub commit_ref: String,
|
pub commit_ref: String,
|
||||||
|
/// The sha hive-c0re fetched from the proposed repo into applied at
|
||||||
|
/// submission time, then tagged `proposal/<id>`. Stable for the
|
||||||
|
/// lifetime of the approval — manager amends in proposed don't
|
||||||
|
/// change what gets built. Only set for `ApplyCommit` after the
|
||||||
|
/// successful fetch.
|
||||||
|
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||||
|
pub fetched_sha: Option<String>,
|
||||||
pub requested_at: i64,
|
pub requested_at: i64,
|
||||||
pub status: ApprovalStatus,
|
pub status: ApprovalStatus,
|
||||||
#[serde(default, skip_serializing_if = "Option::is_none")]
|
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||||
|
|
@ -236,6 +246,18 @@ pub enum HelperEvent {
|
||||||
status: ApprovalStatus,
|
status: ApprovalStatus,
|
||||||
#[serde(default, skip_serializing_if = "Option::is_none")]
|
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||||
note: Option<String>,
|
note: Option<String>,
|
||||||
|
/// Canonical sha hive-c0re fetched into applied at submission
|
||||||
|
/// time. `git show <sha>` against `/agents/<n>/applied.git`
|
||||||
|
/// inside the manager container yields the exact tree being
|
||||||
|
/// referenced.
|
||||||
|
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||||
|
sha: Option<String>,
|
||||||
|
/// Terminal tag name in the applied repo for this approval —
|
||||||
|
/// `deployed/<id>`, `failed/<id>`, or `denied/<id>` (and
|
||||||
|
/// `approved/<id>` for the rare bare-approval case where
|
||||||
|
/// no underlying action runs).
|
||||||
|
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||||
|
tag: Option<String>,
|
||||||
},
|
},
|
||||||
/// A new container was spawned (post-approval or via the admin CLI
|
/// A new container was spawned (post-approval or via the admin CLI
|
||||||
/// bypass path). `ok=false` means the spawn failed.
|
/// bypass path). `ok=false` means the spawn failed.
|
||||||
|
|
@ -244,6 +266,10 @@ pub enum HelperEvent {
|
||||||
ok: bool,
|
ok: bool,
|
||||||
#[serde(default, skip_serializing_if = "Option::is_none")]
|
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||||
note: Option<String>,
|
note: Option<String>,
|
||||||
|
/// Sha of the `deployed/0` commit seeded by hive-c0re on
|
||||||
|
/// first spawn (Some on success, None on failure).
|
||||||
|
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||||
|
sha: Option<String>,
|
||||||
},
|
},
|
||||||
/// A container was rebuilt (auto-update on flake rev change, or a
|
/// A container was rebuilt (auto-update on flake rev change, or a
|
||||||
/// manual rebuild from CLI/dashboard).
|
/// manual rebuild from CLI/dashboard).
|
||||||
|
|
@ -252,6 +278,18 @@ pub enum HelperEvent {
|
||||||
ok: bool,
|
ok: bool,
|
||||||
#[serde(default, skip_serializing_if = "Option::is_none")]
|
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||||
note: Option<String>,
|
note: Option<String>,
|
||||||
|
/// Sha that ended up at `deployed/<id>` on success, or the
|
||||||
|
/// proposal sha that just got tagged `failed/<id>` on
|
||||||
|
/// failure. None for the (rare) rebuild path that doesn't go
|
||||||
|
/// through an approval (e.g. auto_update::rebuild_agent
|
||||||
|
/// reapplying the existing main).
|
||||||
|
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||||
|
sha: Option<String>,
|
||||||
|
/// `deployed/<id>` or `failed/<id>` for approval-driven
|
||||||
|
/// rebuilds; None for auto-update / dashboard rebuilds that
|
||||||
|
/// don't change the deployed commit.
|
||||||
|
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||||
|
tag: Option<String>,
|
||||||
},
|
},
|
||||||
/// A sub-agent's container was stopped (the systemd unit is down;
|
/// A sub-agent's container was stopped (the systemd unit is down;
|
||||||
/// persistent state is unchanged).
|
/// persistent state is unchanged).
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue