Enable real-time output streaming for nixos-rebuild command
All checks were successful
Build and Release / build-and-release (push) Successful in 1m24s

- Replace simulated progress messages with actual stdout/stderr capture
- Stream all nixos-rebuild output line-by-line to terminal popup
- Show transparent build process including downloads, compilation, and activation
- Maintain real-time visibility into complete rebuild process
This commit is contained in:
Christoffer Martinsson 2025-10-26 13:00:53 +01:00
parent b6da71b7e7
commit bc94f75328

View File

@ -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() {