fix: race condition in eval

This commit is contained in:
Patrick 2024-12-04 19:07:52 +01:00
parent 0cd8406ba5
commit 0fb5fc3c7b
Signed by: patrick
GPG key ID: 451F95EFB8BECD0F

View file

@ -1,10 +1,13 @@
use color_eyre::{eyre::Result, owo_colors::OwoColorize};
use color_eyre::{
eyre::{Context, Result},
owo_colors::OwoColorize,
};
use futures::future::join_all;
use openssh::{KnownHosts, Session};
use std::{
env,
path::PathBuf,
process::{Command, Stdio},
process::{Command, Output, Stdio},
};
fn gen_systems_path(system: &str) -> String {
@ -14,10 +17,7 @@ fn gen_systems_path(system: &str) -> String {
)
}
pub fn build(systems: &[String], show_trace: bool) -> Result<()> {
if systems.is_empty() {
return Ok(());
}
pub fn build(systems: &[String], show_trace: bool) -> Result<Output> {
let dir = env::var("PRJ_ROOT")
.map(PathBuf::from)
.or_else(|_| env::current_dir())?;
@ -50,8 +50,7 @@ pub fn build(systems: &[String], show_trace: bool) -> Result<()> {
.arg("--print-out-paths")
.arg("--no-link")
.args(configs);
cmd.spawn()?.wait()?;
Ok(())
cmd.output().wrap_err("Error building systems")
}
pub async fn deploy(systems: &[String], show_trace: bool, mode: &str) -> Result<()> {
@ -68,22 +67,24 @@ pub async fn deploy(systems: &[String], show_trace: bool, mode: &str) -> Result<
.await
.into_iter()
.collect::<std::result::Result<Vec<_>, openssh::Error>>()?;
let toplevels = String::from_utf8(
build(
&systems.iter().map(|x| x.to_string()).collect::<Vec<_>>(),
show_trace,
)?
.stdout,
)?;
for (system, (con, host)) in systems.into_iter().zip(connections.into_iter().zip(hosts)) {
let path = gen_systems_path(system);
let mut cmd = Command::new("nix");
let cmd = cmd.arg("eval").arg("--read-only").arg("--raw").arg(path);
let toplevel = String::from_utf8(cmd.output()?.stdout)?;
for (toplevel, (system, (con, host))) in toplevels
.lines()
.zip(systems.into_iter().zip(connections.into_iter().zip(hosts)))
{
println!("Copyings toplevel for {}", system.blue());
let mut cmd = Command::new("nix");
let cmd = cmd
.arg("copy")
.arg("--to")
.arg(format!("ssh://{}", host))
.arg(&toplevel);
.arg(toplevel);
cmd.spawn()?.wait()?;
let prev_system = con
.command("readlink")
@ -97,7 +98,7 @@ pub async fn deploy(systems: &[String], show_trace: bool, mode: &str) -> Result<
.arg("--profile")
.arg("/nix/var/nix/profiles/system")
.arg("--set")
.arg(&toplevel)
.arg(toplevel)
.spawn()
.await?;
con.command(format!("{}/bin/switch-to-configuration", toplevel))