Run nix build.
This commit is contained in:
@@ -1,4 +1,4 @@
|
|||||||
# work_directory = "/home/nixworker/persist/nix_builder"
|
# repo_directory = "/home/nixworker/persist/nix_builder"
|
||||||
|
|
||||||
[[targets]]
|
[[targets]]
|
||||||
name = "odo"
|
name = "odo"
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ use crate::fs_util::assert_directory;
|
|||||||
use crate::fs_util::is_git_repo;
|
use crate::fs_util::is_git_repo;
|
||||||
use crate::git_util::git_force_into_state;
|
use crate::git_util::git_force_into_state;
|
||||||
use crate::git_util::git_init_at_rev;
|
use crate::git_util::git_init_at_rev;
|
||||||
|
use crate::nix_util::nixos_build_target;
|
||||||
|
|
||||||
pub(crate) async fn run_build(args: BuildArgs) -> Result<(), CustomError> {
|
pub(crate) async fn run_build(args: BuildArgs) -> Result<(), CustomError> {
|
||||||
println!("{:?}", args);
|
println!("{:?}", args);
|
||||||
@@ -23,6 +24,7 @@ pub(crate) async fn run_build(args: BuildArgs) -> Result<(), CustomError> {
|
|||||||
};
|
};
|
||||||
|
|
||||||
prepare_flake_repo(&config, target_config).await?;
|
prepare_flake_repo(&config, target_config).await?;
|
||||||
|
build_target(&config, target_config).await?;
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
@@ -32,17 +34,17 @@ async fn prepare_flake_repo(
|
|||||||
config_root: &Config,
|
config_root: &Config,
|
||||||
target_config: &TargetConfig,
|
target_config: &TargetConfig,
|
||||||
) -> Result<(), CustomError> {
|
) -> Result<(), CustomError> {
|
||||||
let flake_directory = target_config.get_flake_directory(config_root)?;
|
let repo_directory = target_config.get_repo_directory(config_root)?;
|
||||||
assert_directory!(
|
assert_directory!(
|
||||||
&flake_directory,
|
&repo_directory,
|
||||||
"Creating flake directory {}",
|
"Creating repo directory {}",
|
||||||
(&flake_directory).to_string_lossy()
|
(&repo_directory).to_string_lossy()
|
||||||
);
|
);
|
||||||
|
|
||||||
if is_git_repo(&flake_directory).await? {
|
if is_git_repo(&repo_directory).await? {
|
||||||
// Clean up the existing clone
|
// Clean up the existing clone
|
||||||
git_force_into_state(
|
git_force_into_state(
|
||||||
&flake_directory,
|
&repo_directory,
|
||||||
target_config.get_branch()?,
|
target_config.get_branch()?,
|
||||||
"origin",
|
"origin",
|
||||||
target_config.get_repo()?,
|
target_config.get_repo()?,
|
||||||
@@ -51,7 +53,7 @@ async fn prepare_flake_repo(
|
|||||||
.await?;
|
.await?;
|
||||||
} else {
|
} else {
|
||||||
git_init_at_rev(
|
git_init_at_rev(
|
||||||
&flake_directory,
|
&repo_directory,
|
||||||
target_config.get_branch()?,
|
target_config.get_branch()?,
|
||||||
target_config.get_repo()?,
|
target_config.get_repo()?,
|
||||||
target_config.get_revision()?,
|
target_config.get_revision()?,
|
||||||
@@ -60,3 +62,20 @@ async fn prepare_flake_repo(
|
|||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async fn build_target(
|
||||||
|
config_root: &Config,
|
||||||
|
target_config: &TargetConfig,
|
||||||
|
) -> Result<(), CustomError> {
|
||||||
|
let flake_directory = target_config.get_flake_directory(config_root)?;
|
||||||
|
let build_directory = target_config.get_build_directory(config_root)?;
|
||||||
|
assert_directory!(
|
||||||
|
&build_directory,
|
||||||
|
"Creating build directory {}",
|
||||||
|
(&build_directory).to_string_lossy()
|
||||||
|
);
|
||||||
|
|
||||||
|
nixos_build_target(build_directory, flake_directory, target_config.get_attr()?).await?;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ use super::TargetConfig;
|
|||||||
pub(crate) struct Config {
|
pub(crate) struct Config {
|
||||||
#[serde(skip)]
|
#[serde(skip)]
|
||||||
config_path: Option<PathBuf>,
|
config_path: Option<PathBuf>,
|
||||||
work_directory: Option<PathBuf>,
|
output_directory: Option<PathBuf>,
|
||||||
targets: Vec<TargetConfig>,
|
targets: Vec<TargetConfig>,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -63,9 +63,9 @@ impl Config {
|
|||||||
Ok(target_config)
|
Ok(target_config)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn get_work_directory(&self) -> Result<Cow<'_, Path>, CustomError> {
|
pub(crate) fn get_output_directory(&self) -> Result<Cow<'_, Path>, CustomError> {
|
||||||
let maybe_work_directory = self.work_directory.as_deref().map(Cow::Borrowed);
|
let maybe_repo_directory = self.output_directory.as_deref().map(Cow::Borrowed);
|
||||||
if let Some(work_dir) = maybe_work_directory {
|
if let Some(work_dir) = maybe_repo_directory {
|
||||||
return Ok(work_dir);
|
return Ok(work_dir);
|
||||||
}
|
}
|
||||||
let current_dir: PathBuf = std::env::current_dir()?;
|
let current_dir: PathBuf = std::env::current_dir()?;
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ pub(crate) struct TargetConfig {
|
|||||||
pub(super) path: Option<String>,
|
pub(super) path: Option<String>,
|
||||||
|
|
||||||
#[serde(default)]
|
#[serde(default)]
|
||||||
pub(super) attr: Option<String>,
|
pub(super) attr: String,
|
||||||
|
|
||||||
#[serde(default)]
|
#[serde(default)]
|
||||||
pub(super) update: Option<bool>,
|
pub(super) update: Option<bool>,
|
||||||
@@ -34,26 +34,44 @@ pub(crate) struct TargetConfig {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl TargetConfig {
|
impl TargetConfig {
|
||||||
|
/// The root directory for this specific build target.
|
||||||
pub(crate) fn get_target_directory<'target, 'root>(
|
pub(crate) fn get_target_directory<'target, 'root>(
|
||||||
&'target self,
|
&'target self,
|
||||||
config_root: &'root Config,
|
config_root: &'root Config,
|
||||||
) -> Result<Cow<'target, Path>, CustomError> {
|
) -> Result<Cow<'target, Path>, CustomError> {
|
||||||
let work_directory = config_root.get_work_directory()?;
|
let repo_directory = config_root.get_output_directory()?;
|
||||||
Ok(Cow::Owned(work_directory.join(&self.name)))
|
Ok(Cow::Owned(repo_directory.join(&self.name)))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn get_flake_directory<'target, 'root>(
|
/// The root of the checkout of the git repository.
|
||||||
|
pub(crate) fn get_repo_directory<'target, 'root>(
|
||||||
&'target self,
|
&'target self,
|
||||||
config_root: &'root Config,
|
config_root: &'root Config,
|
||||||
) -> Result<Cow<'target, Path>, CustomError> {
|
) -> Result<Cow<'target, Path>, CustomError> {
|
||||||
let target_directory = self.get_target_directory(config_root)?;
|
let target_directory = self.get_target_directory(config_root)?;
|
||||||
Ok(Cow::Owned(target_directory.join("flake")))
|
Ok(Cow::Owned(target_directory.join("repo")))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// The directory that contains flake.nix.
|
||||||
|
pub(crate) fn get_flake_directory<'target, 'root>(
|
||||||
|
&'target self,
|
||||||
|
config_root: &'root Config,
|
||||||
|
) -> Result<Cow<'target, Path>, CustomError> {
|
||||||
|
let repo_directory = self.get_repo_directory(config_root)?;
|
||||||
|
let subpath = self.path.as_deref();
|
||||||
|
if let Some(subpath) = subpath {
|
||||||
|
Ok(Cow::Owned(repo_directory.join(subpath)))
|
||||||
|
} else {
|
||||||
|
Ok(repo_directory)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// The URL to the upstream git repository.
|
||||||
pub(crate) fn get_repo(&'_ self) -> Result<&String, CustomError> {
|
pub(crate) fn get_repo(&'_ self) -> Result<&String, CustomError> {
|
||||||
Ok(&self.repo)
|
Ok(&self.repo)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// The git branch name to track.
|
||||||
pub(crate) fn get_branch(&'_ self) -> Result<Cow<'_, str>, CustomError> {
|
pub(crate) fn get_branch(&'_ self) -> Result<Cow<'_, str>, CustomError> {
|
||||||
if let Some(b) = &self.branch {
|
if let Some(b) = &self.branch {
|
||||||
Ok(Cow::Borrowed(b))
|
Ok(Cow::Borrowed(b))
|
||||||
@@ -62,7 +80,22 @@ impl TargetConfig {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// If we want to pin to a specific revision, this is the reference to that commit.
|
||||||
pub(crate) fn get_revision(&self) -> Result<&Option<String>, CustomError> {
|
pub(crate) fn get_revision(&self) -> Result<&Option<String>, CustomError> {
|
||||||
Ok(&self.revision)
|
Ok(&self.revision)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// The folder where nixos-rebuild is invoked and the outputs are linked.
|
||||||
|
pub(crate) fn get_build_directory<'target, 'root>(
|
||||||
|
&'target self,
|
||||||
|
config_root: &'root Config,
|
||||||
|
) -> Result<Cow<'target, Path>, CustomError> {
|
||||||
|
let target_directory = self.get_target_directory(config_root)?;
|
||||||
|
Ok(Cow::Owned(target_directory.join("build")))
|
||||||
|
}
|
||||||
|
|
||||||
|
/// The flake output attribute to build (the part after '#' in the build command).
|
||||||
|
pub(crate) fn get_attr(&'_ self) -> Result<&String, CustomError> {
|
||||||
|
Ok(&self.attr)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ mod error;
|
|||||||
mod fs_util;
|
mod fs_util;
|
||||||
mod git_util;
|
mod git_util;
|
||||||
mod init_tracing;
|
mod init_tracing;
|
||||||
|
mod nix_util;
|
||||||
|
|
||||||
fn main() -> Result<ExitCode, CustomError> {
|
fn main() -> Result<ExitCode, CustomError> {
|
||||||
let rt = tokio::runtime::Runtime::new()?;
|
let rt = tokio::runtime::Runtime::new()?;
|
||||||
|
|||||||
58
src/nix_util/high_level.rs
Normal file
58
src/nix_util/high_level.rs
Normal file
@@ -0,0 +1,58 @@
|
|||||||
|
use std::ffi::OsStr;
|
||||||
|
use std::ffi::OsString;
|
||||||
|
use std::path::Path;
|
||||||
|
|
||||||
|
use tokio::process::Command;
|
||||||
|
|
||||||
|
use crate::error::CustomError;
|
||||||
|
|
||||||
|
pub(crate) async fn nixos_build_target<B, F, A>(
|
||||||
|
build_path: B,
|
||||||
|
flake_path: F,
|
||||||
|
attr: A,
|
||||||
|
) -> Result<(), CustomError>
|
||||||
|
where
|
||||||
|
B: AsRef<Path>,
|
||||||
|
F: AsRef<Path>,
|
||||||
|
A: AsRef<str>,
|
||||||
|
{
|
||||||
|
let reference = {
|
||||||
|
let path = AsRef::<OsStr>::as_ref(flake_path.as_ref());
|
||||||
|
let attr = attr.as_ref();
|
||||||
|
let mut reference = OsString::with_capacity(path.len() + attr.len() + 1);
|
||||||
|
reference.push(path);
|
||||||
|
reference.push("#");
|
||||||
|
reference.push(attr);
|
||||||
|
reference
|
||||||
|
};
|
||||||
|
|
||||||
|
// nixos-rebuild build --show-trace --sudo --max-jobs "$JOBS" --flake "$DIR/../../#odo" --log-format internal-json -v "${@}"
|
||||||
|
let mut command = Command::new("nixos-rebuild");
|
||||||
|
command.current_dir(build_path);
|
||||||
|
command.args(&[
|
||||||
|
"build",
|
||||||
|
"--show-trace",
|
||||||
|
"--sudo",
|
||||||
|
"--max-jobs",
|
||||||
|
"1",
|
||||||
|
"--log-format",
|
||||||
|
"internal-json",
|
||||||
|
"-v",
|
||||||
|
]);
|
||||||
|
command.arg("--flake");
|
||||||
|
command.arg(reference);
|
||||||
|
command.kill_on_drop(true);
|
||||||
|
|
||||||
|
let mut child = command.spawn()?;
|
||||||
|
let status = child.wait().await?;
|
||||||
|
if !status.success() {
|
||||||
|
return Err("Nixos rebuild failed.".into());
|
||||||
|
}
|
||||||
|
|
||||||
|
// tokio::spawn(async move {
|
||||||
|
// let status = child.wait().await.expect("mpv encountered an error");
|
||||||
|
// println!("mpv status was: {}", status);
|
||||||
|
// });
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
2
src/nix_util/mod.rs
Normal file
2
src/nix_util/mod.rs
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
mod high_level;
|
||||||
|
pub(crate) use high_level::*;
|
||||||
Reference in New Issue
Block a user