apply_commit handles first-time spawns, request_spawn deprecated

This commit is contained in:
damocles 2026-05-22 09:20:50 +02:00
parent 6974634326
commit 66f1568e8f
6 changed files with 166 additions and 34 deletions

View file

@ -206,6 +206,14 @@ async fn agents_after_spawn(name: &str) -> Result<Vec<crate::meta::AgentSpec>> {
agents_for_meta(Some(name)).await
}
/// Like `agents_for_meta_listing` but with an extra agent added (for a
/// container that doesn't exist yet). Used by the first-spawn path in
/// `actions::run_apply_commit` to register the new agent in meta before
/// `prepare_deploy` tries to update its input lock.
pub async fn agents_for_meta_listing_with(extra: &str) -> Result<Vec<crate::meta::AgentSpec>> {
agents_for_meta(Some(extra)).await
}
/// Public enumeration of currently-existing agents (whatever
/// `nixos-container list` says), sorted, no extras. For callers
/// outside this module that need to reseed meta after lifecycle
@ -214,6 +222,19 @@ pub async fn agents_for_meta_listing() -> Result<Vec<crate::meta::AgentSpec>> {
agents_for_meta(None).await
}
/// True when the named container already exists (appears in
/// `nixos-container list`). Used by the apply-commit path to decide
/// between first-spawn (`nixos-container create`) and normal rebuild
/// (`nixos-container update`).
pub async fn container_exists(name: &str) -> bool {
let container = container_name(name);
list()
.await
.unwrap_or_default()
.iter()
.any(|c| c == &container)
}
pub async fn kill(name: &str) -> Result<()> {
validate(name)?;
let container = container_name(name);
@ -314,13 +335,24 @@ pub async fn rebuild_no_meta(
ensure_state_dir(notes_dir)?;
let container = container_name(name);
let flake_ref = format!("{}#{name}", crate::meta::meta_dir().display());
set_nspawn_flags(&container, agent_dir, claude_dir, notes_dir)?;
set_resource_limits(&container)?;
systemd_daemon_reload().await?;
run(&["update", &container, "--flake", &flake_ref]).await?;
// Restart so any nspawn-level changes (bind mounts, networking, etc.) apply.
run(&["stop", &container]).await?;
run(&["start", &container]).await
if container_exists(name).await {
// Existing container: update nspawn flags, then rebuild + restart
// so any bind-mount / networking changes take effect.
set_nspawn_flags(&container, agent_dir, claude_dir, notes_dir)?;
set_resource_limits(&container)?;
systemd_daemon_reload().await?;
run(&["update", &container, "--flake", &flake_ref]).await?;
run(&["stop", &container]).await?;
run(&["start", &container]).await
} else {
// First spawn: create the container first (which writes the nspawn
// conf file), then overwrite with our flags and start.
run(&["create", &container, "--flake", &flake_ref]).await?;
set_nspawn_flags(&container, agent_dir, claude_dir, notes_dir)?;
set_resource_limits(&container)?;
systemd_daemon_reload().await?;
run(&["start", &container]).await
}
}
pub async fn list() -> Result<Vec<String>> {