Record error when setting up repo fails rather than abort entire script.

This commit is contained in:
Tom Alexander
2026-08-08 23:50:23 -04:00
parent 6386febdb8
commit 0a270dcbdd
5 changed files with 85 additions and 44 deletions

View File

@@ -1,5 +1,12 @@
# repo_directory = "/home/nixworker/persist/nix_builder" # repo_directory = "/home/nixworker/persist/nix_builder"
[[targets]]
name = "foo"
repo = "https://code.fizz.buzz/talexander/machine_setup.git"
branch = "foo"
path = "nix/configuration"
attr = "nixosConfigurations.odo.config.system.build.toplevel"
[[targets]] [[targets]]
name = "odo" name = "odo"
repo = "https://code.fizz.buzz/talexander/machine_setup.git" repo = "https://code.fizz.buzz/talexander/machine_setup.git"

View File

@@ -1,4 +1,7 @@
use std::process::ExitStatus;
use sqlx::Row; use sqlx::Row;
use tracing::error;
use tracing::info; use tracing::info;
use crate::Result; use crate::Result;
@@ -37,20 +40,46 @@ pub(crate) async fn run_build(args: BuildArgs) -> Result<()> {
verify_nix_store().await?; verify_nix_store().await?;
for target_name in args.target { for target_name in args.target {
let target_config = { // Record start of build
let target_config = config.get_target_config(&target_name)?; let build_id: i64 = sqlx::query(
if let Some(conf) = target_config { r#"INSERT INTO build (start_time, target) SELECT unixepoch('now'), ? RETURNING id"#,
conf )
} else { .bind(&target_name)
return Err(format!("Could not find target {}", target_name).into()); .fetch_one(&db_handle.conn)
.await?
.try_get("id")?;
// Put the rest into a function
let result = full_build_target(&config, &db_handle, &target_name, build_id).await;
match result {
Ok(exit_status) => {
let update: u64 = sqlx::query(
r#"UPDATE build SET end_time=unixepoch('now'), status=? WHERE id=?"#,
)
.bind(
exit_status
.code()
.expect("Process should have an exit code."),
)
.bind(build_id)
.execute(&db_handle.conn)
.await?
.rows_affected();
assert!(update == 1);
}
Err(e) => {
error!("Error building target {}: {}", target_name, e);
let update: u64 = sqlx::query(
r#"UPDATE build SET end_time=unixepoch('now'), status=? WHERE id=?"#,
)
.bind(-1)
.bind(build_id)
.execute(&db_handle.conn)
.await?
.rows_affected();
assert!(update == 1);
} }
}; };
prepare_flake_repo(&config, target_config).await?;
if target_config.get_update() {
run_nix_update(&config, target_config).await?;
}
build_target(&db_handle, &config, target_config).await?;
} }
db_handle.conn.close().await; db_handle.conn.close().await;
@@ -58,6 +87,29 @@ pub(crate) async fn run_build(args: BuildArgs) -> Result<()> {
Ok(()) Ok(())
} }
async fn full_build_target(
config: &Config,
db_handle: &DbHandle,
target_name: &str,
build_id: i64,
) -> Result<ExitStatus> {
let target_config = {
let target_config = config.get_target_config(&target_name)?;
if let Some(conf) = target_config {
conf
} else {
return Err(format!("Could not find target {}", target_name).into());
}
};
prepare_flake_repo(&config, target_config).await?;
if target_config.get_update() {
run_nix_update(&config, target_config).await?;
}
let exit_status = build_target(&db_handle, &config, target_config, build_id).await?;
Ok(exit_status)
}
async fn prepare_flake_repo(config_root: &Config, target_config: &TargetConfig) -> Result<()> { async fn prepare_flake_repo(config_root: &Config, target_config: &TargetConfig) -> Result<()> {
let repo_directory = target_config.get_repo_directory(config_root)?; let repo_directory = target_config.get_repo_directory(config_root)?;
assert_directory!( assert_directory!(
@@ -106,7 +158,8 @@ async fn build_target(
db_handle: &DbHandle, db_handle: &DbHandle,
config_root: &Config, config_root: &Config,
target_config: &TargetConfig, target_config: &TargetConfig,
) -> Result<()> { build_id: i64,
) -> Result<ExitStatus> {
let flake_directory = target_config.get_flake_directory(config_root)?; let flake_directory = target_config.get_flake_directory(config_root)?;
let build_directory = target_config.get_build_directory(config_root)?; let build_directory = target_config.get_build_directory(config_root)?;
assert_directory!( assert_directory!(
@@ -117,18 +170,10 @@ async fn build_target(
let target_name = target_config.get_name()?; let target_name = target_config.get_name()?;
let build_id: i64 = sqlx::query(
r#"INSERT INTO build (start_time, target) SELECT unixepoch('now'), ? RETURNING id"#,
)
.bind(target_name)
.fetch_one(&db_handle.conn)
.await?
.try_get("id")?;
let flake_lock = parse_flake_lock(&flake_directory).await?; let flake_lock = parse_flake_lock(&flake_directory).await?;
write_input_revs_to_db(db_handle, &flake_lock, build_id).await?; write_input_revs_to_db(db_handle, &flake_lock, build_id).await?;
nixos_build_target( let exit_status = nixos_build_target(
db_handle, db_handle,
build_directory, build_directory,
flake_directory, flake_directory,
@@ -138,7 +183,7 @@ async fn build_target(
) )
.await?; .await?;
Ok(()) Ok(exit_status)
} }
async fn write_input_revs_to_db( async fn write_input_revs_to_db(

View File

@@ -1,6 +1,7 @@
use std::ffi::OsStr; use std::ffi::OsStr;
use std::ffi::OsString; use std::ffi::OsString;
use std::path::Path; use std::path::Path;
use std::process::ExitStatus;
use std::process::Stdio; use std::process::Stdio;
use tokio::process::Command; use tokio::process::Command;
@@ -19,7 +20,7 @@ pub(crate) async fn nixos_build_target<B, F, A, TN>(
attr: A, attr: A,
target_name: TN, target_name: TN,
build_id: i64, build_id: i64,
) -> Result<()> ) -> Result<ExitStatus>
where where
B: AsRef<Path>, B: AsRef<Path>,
F: AsRef<Path>, F: AsRef<Path>,
@@ -58,9 +59,9 @@ where
let child = command.spawn()?; let child = command.spawn()?;
let mut running_build = RunningBuild::new(db_handle, build_id)?; let mut running_build = RunningBuild::new(db_handle, build_id)?;
running_build.run_to_completion(child, target_name).await?; let exit_status = running_build.run_to_completion(child, target_name).await?;
Ok(()) Ok(exit_status)
} }
pub(crate) async fn nix_flake_update<F>(flake_path: F) -> Result<()> pub(crate) async fn nix_flake_update<F>(flake_path: F) -> Result<()>

View File

@@ -1,4 +1,5 @@
use std::borrow::Cow; use std::borrow::Cow;
use std::process::ExitStatus;
use std::time::Duration; use std::time::Duration;
use std::time::Instant; use std::time::Instant;
use std::time::SystemTime; use std::time::SystemTime;
@@ -43,7 +44,7 @@ impl<'db> RunningBuild<'db> {
&mut self, &mut self,
mut child: Child, mut child: Child,
target_name: TN, target_name: TN,
) -> Result<()> ) -> Result<ExitStatus>
where where
TN: AsRef<str>, TN: AsRef<str>,
{ {
@@ -66,20 +67,7 @@ impl<'db> RunningBuild<'db> {
let exit_status = exit_status_handle.await?; let exit_status = exit_status_handle.await?;
println!("nix build status was: {}", exit_status); println!("nix build status was: {}", exit_status);
let update: u64 = Ok(exit_status)
sqlx::query(r#"UPDATE build SET end_time=unixepoch('now'), status=? WHERE id=?"#)
.bind(
exit_status
.code()
.expect("Process should have an exit code."),
)
.bind(self.build_id)
.execute(&self.db_handle.conn)
.await?
.rows_affected();
assert!(update == 1);
Ok(())
} }
pub(crate) fn handle_message(&mut self, message: NixMessage) -> Result<()> { pub(crate) fn handle_message(&mut self, message: NixMessage) -> Result<()> {

View File

@@ -71,9 +71,9 @@ impl RunningVerify {
}; };
match message { match message {
NixAction::Msg(msg_message) => { NixAction::Msg(msg_message) => {
// if msg_message.level > 0 && msg_message.level < 5 { if msg_message.level > 0 && msg_message.level < 4 {
// eprintln!("LOG MESSAGE {}: {}", msg_message.level, msg_message.msg); eprintln!("LOG MESSAGE {}: {}", msg_message.level, msg_message.msg);
// } }
} }
NixAction::Start(activity_start_message) => { NixAction::Start(activity_start_message) => {
// println!("START: {}", serde_json::to_string(&activity_start_message)?); // println!("START: {}", serde_json::to_string(&activity_start_message)?);