From 16ea853f5bb1585b840c53b63ccc0bc65faa99a0 Mon Sep 17 00:00:00 2001 From: Christoffer Martinsson Date: Sat, 25 Oct 2025 15:09:17 +0200 Subject: [PATCH] Fix agent self-update issue by running nixos-rebuild detached Run nixos-rebuild with nohup in background to prevent the agent from killing itself during system rebuild. The rebuild process now runs independently, allowing the agent to return success immediately and avoid crashes during binary updates. This fixes the issue where agent would crash during rebuild and restart with the old binary due to missing daemon-reload. --- agent/src/agent.rs | 33 ++++++++++++++------------------- 1 file changed, 14 insertions(+), 19 deletions(-) diff --git a/agent/src/agent.rs b/agent/src/agent.rs index 9c0b7e6..ec73349 100644 --- a/agent/src/agent.rs +++ b/agent/src/agent.rs @@ -296,10 +296,11 @@ impl Agent { // Clone or update repository let git_result = self.ensure_git_repository(git_url, git_branch, working_dir, api_key_file).await; - // Execute nixos-rebuild if git operation succeeded + // Execute nixos-rebuild if git operation succeeded - run detached to avoid killing current agent let rebuild_result = if git_result.is_ok() { - info!("Git repository ready, executing nixos-rebuild"); - tokio::process::Command::new("sudo") + info!("Git repository ready, executing nixos-rebuild in detached mode"); + tokio::process::Command::new("nohup") + .arg("sudo") .arg("/run/current-system/sw/bin/nixos-rebuild") .arg("switch") .arg("--option") @@ -308,8 +309,10 @@ impl Agent { .arg("--flake") .arg(".") .current_dir(working_dir) - .output() - .await + .stdin(std::process::Stdio::null()) + .stdout(std::process::Stdio::null()) + .stderr(std::process::Stdio::null()) + .spawn() } else { return git_result.and_then(|_| unreachable!()); }; @@ -323,23 +326,15 @@ impl Agent { info!("Maintenance mode disabled"); } - // Check rebuild result + // Check rebuild start result match rebuild_result { - Ok(output) => { - if output.status.success() { - info!("NixOS rebuild completed successfully"); - if !output.stdout.is_empty() { - debug!("rebuild stdout: {}", String::from_utf8_lossy(&output.stdout)); - } - } else { - let stderr = String::from_utf8_lossy(&output.stderr); - error!("NixOS rebuild failed: {}", stderr); - return Err(anyhow::anyhow!("nixos-rebuild failed: {}", stderr)); - } + Ok(_child) => { + info!("NixOS rebuild started successfully in background"); + // Don't wait for completion to avoid agent being killed during rebuild } Err(e) => { - error!("Failed to execute nixos-rebuild: {}", e); - return Err(anyhow::anyhow!("Failed to execute nixos-rebuild: {}", e)); + error!("Failed to start nixos-rebuild: {}", e); + return Err(anyhow::anyhow!("Failed to start nixos-rebuild: {}", e)); } }