diff --git a/agent/src/agent.rs b/agent/src/agent.rs index a9fa354..8a6633c 100644 --- a/agent/src/agent.rs +++ b/agent/src/agent.rs @@ -400,13 +400,11 @@ impl Agent { self.zmq_handler.publish_command_output(&message).await } - /// Execute nixos-rebuild with simulated output streaming (for now) + /// Execute nixos-rebuild with real-time output streaming async fn execute_nixos_rebuild_with_streaming(&self, command_id: &str, working_dir: &str) -> Result<()> { + use tokio::io::{AsyncBufReadExt, BufReader}; use tokio::process::Command; - // Send progress updates during rebuild - self.send_command_output(command_id, "SystemRebuild", "Building...").await?; - let mut child = Command::new("sudo") .arg("/run/current-system/sw/bin/nixos-rebuild") .arg("switch") @@ -416,18 +414,53 @@ impl Agent { .arg("--flake") .arg(".") .current_dir(working_dir) + .stdout(std::process::Stdio::piped()) + .stderr(std::process::Stdio::piped()) .spawn()?; - // Send periodic updates while waiting - let mut interval = tokio::time::interval(tokio::time::Duration::from_secs(5)); - let mut update_count = 0; - + // Get stdout and stderr handles + let stdout = child.stdout.take().expect("Failed to get stdout"); + let stderr = child.stderr.take().expect("Failed to get stderr"); + + // Create readers for both streams + let stdout_reader = BufReader::new(stdout); + let stderr_reader = BufReader::new(stderr); + + let mut stdout_lines = stdout_reader.lines(); + let mut stderr_lines = stderr_reader.lines(); + + // Stream output lines in real-time loop { tokio::select! { - _ = interval.tick() => { - update_count += 1; - self.send_command_output(command_id, "SystemRebuild", &format!("Building... ({} seconds)", update_count * 5)).await?; + // Read from stdout + line = stdout_lines.next_line() => { + match line { + Ok(Some(line)) => { + self.send_command_output(command_id, "SystemRebuild", &line).await?; + } + Ok(None) => { + // stdout closed + } + Err(e) => { + self.send_command_output(command_id, "SystemRebuild", &format!("stdout error: {}", e)).await?; + } + } } + // Read from stderr + line = stderr_lines.next_line() => { + match line { + Ok(Some(line)) => { + self.send_command_output(command_id, "SystemRebuild", &line).await?; + } + Ok(None) => { + // stderr closed + } + Err(e) => { + self.send_command_output(command_id, "SystemRebuild", &format!("stderr error: {}", e)).await?; + } + } + } + // Wait for process completion result = child.wait() => { let status = result?; if status.success() {