hyperhive/hive-c0re/src/actions.rs

45 lines
1.7 KiB
Rust

//! Operations that are exposed through more than one surface (the host admin
//! socket *and* the dashboard's POST endpoints). Each function takes a
//! `&Coordinator` and the request parameters; callers stitch the response
//! shape they want (HTTP redirect vs JSON).
use anyhow::Result;
use crate::coordinator::Coordinator;
use crate::lifecycle;
/// Approve a pending request: read the agent.nix at the approval's commit from
/// the proposed repo, copy into the applied repo, commit there, and rebuild
/// the agent container. On failure marks the approval failed (with the error
/// note) and returns the error.
pub async fn approve(coord: &Coordinator, id: i64) -> Result<()> {
let approval = coord.approvals.mark_approved(id)?;
tracing::info!(%approval.id, %approval.agent, %approval.commit_ref, "approval: applying + rebuilding");
let agent_dir = coord.register_agent(&approval.agent)?;
let proposed_dir = Coordinator::agent_proposed_dir(&approval.agent);
let applied_dir = Coordinator::agent_applied_dir(&approval.agent);
let result: Result<()> = async {
lifecycle::apply_commit(&applied_dir, &proposed_dir, &approval.commit_ref).await?;
lifecycle::rebuild(
&approval.agent,
&coord.hyperhive_flake,
&agent_dir,
&applied_dir,
)
.await
}
.await;
if let Err(e) = result {
let note = format!("{e:#}");
let _ = coord.approvals.mark_failed(approval.id, &note);
return Err(e);
}
Ok(())
}
pub fn deny(coord: &Coordinator, id: i64) -> Result<()> {
coord.approvals.mark_denied(id)?;
tracing::info!(%id, "approval denied");
Ok(())
}