From d9b812d59b1a7df227642907a3f60fb1e859e4aa Mon Sep 17 00:00:00 2001 From: Gerald Pinder Date: Sun, 8 Dec 2024 22:01:36 -0500 Subject: [PATCH] feat: Add the ability to choose a tempdir for builds --- process/drivers/opts/rechunk.rs | 1 + process/drivers/traits.rs | 6 +++++- src/commands/build.rs | 34 ++++++++++++++++++--------------- src/commands/generate_iso.rs | 13 ++++++++++++- src/commands/switch.rs | 13 ++++++++++++- 5 files changed, 49 insertions(+), 18 deletions(-) diff --git a/process/drivers/opts/rechunk.rs b/process/drivers/opts/rechunk.rs index ebb6653d..e85d909e 100644 --- a/process/drivers/opts/rechunk.rs +++ b/process/drivers/opts/rechunk.rs @@ -44,4 +44,5 @@ pub struct RechunkOpts<'scope> { /// The compression type to use when pushing. #[builder(default)] pub compression: CompressionType, + pub tempdir: Option<&'scope Path>, } diff --git a/process/drivers/traits.rs b/process/drivers/traits.rs index 25bcd093..bdccafd9 100644 --- a/process/drivers/traits.rs +++ b/process/drivers/traits.rs @@ -308,7 +308,11 @@ pub trait RechunkDriver: RunDriver + BuildDriver + ContainerMountDriver { Self::prune_image(mount, container, raw_image, opts)?; Self::create_ostree_commit(mount, ostree_cache_id, container, raw_image, opts)?; - let temp_dir = tempfile::TempDir::new().into_diagnostic()?; + let temp_dir = if let Some(dir) = opts.tempdir { + tempfile::TempDir::new_in(dir).into_diagnostic()? + } else { + tempfile::TempDir::new().into_diagnostic()? + }; let temp_dir_str = &*temp_dir.path().to_string_lossy(); Self::rechunk_image(ostree_cache_id, temp_dir_str, current_dir, opts)?; diff --git a/src/commands/build.rs b/src/commands/build.rs index 0662ba26..36b4be24 100644 --- a/src/commands/build.rs +++ b/src/commands/build.rs @@ -120,6 +120,11 @@ pub struct BuildCommand { #[cfg(feature = "rechunk")] rechunk: bool, + /// The location to temporarily store files + /// while building. If unset, it will use `/tmp`. + #[arg(long)] + tempdir: Option, + #[clap(flatten)] #[builder(default)] credentials: CredentialsArgs, @@ -127,9 +132,6 @@ pub struct BuildCommand { #[clap(flatten)] #[builder(default)] drivers: DriverArgs, - - #[clap(skip)] - temp_dir: Option, } impl BlueBuildCommand for BuildCommand { @@ -157,8 +159,11 @@ impl BlueBuildCommand for BuildCommand { Driver::signing_login()?; } - self.temp_dir = Some(TempDir::new().into_diagnostic()?); - let temp_dir = self.temp_dir.as_ref().unwrap(); + let tempdir = if let Some(ref dir) = self.tempdir { + TempDir::new_in(dir).into_diagnostic()? + } else { + TempDir::new().into_diagnostic()? + }; #[cfg(feature = "multi-recipe")] { @@ -181,7 +186,7 @@ impl BlueBuildCommand for BuildCommand { recipe_paths.par_iter().try_for_each(|recipe| { GenerateCommand::builder() - .output(temp_dir.path().join(if recipe_paths.len() > 1 { + .output(tempdir.path().join(if recipe_paths.len() > 1 { blue_build_utils::generate_containerfile_path(recipe)? } else { PathBuf::from(CONTAINER_FILE) @@ -193,7 +198,7 @@ impl BlueBuildCommand for BuildCommand { .try_run() })?; - self.start(&recipe_paths) + self.start(&recipe_paths, tempdir.path()) } #[cfg(not(feature = "multi-recipe"))] @@ -210,29 +215,28 @@ impl BlueBuildCommand for BuildCommand { }); GenerateCommand::builder() - .output(temp_dir.path().join(CONTAINER_FILE)) + .output(tempdir.path().join(CONTAINER_FILE)) .recipe(&recipe_path) .drivers(self.drivers) .build() .try_run()?; - self.start(&recipe_path) + self.start(&recipe_path, tempdir.path()) } } } impl BuildCommand { #[cfg(feature = "multi-recipe")] - fn start(&self, recipe_paths: &[PathBuf]) -> Result<()> { + fn start(&self, recipe_paths: &[PathBuf], temp_dir: &Path) -> Result<()> { use rayon::prelude::*; trace!("BuildCommand::build_image()"); - let temp_dir = self.temp_dir.as_ref().unwrap(); let images = recipe_paths .par_iter() .try_fold(Vec::new, |mut images, recipe_path| -> Result> { - let containerfile = temp_dir.path().join(if recipe_paths.len() > 1 { + let containerfile = temp_dir.join(if recipe_paths.len() > 1 { blue_build_utils::generate_containerfile_path(recipe_path)? } else { PathBuf::from(CONTAINER_FILE) @@ -258,11 +262,10 @@ impl BuildCommand { } #[cfg(not(feature = "multi-recipe"))] - fn start(&self, recipe_path: &Path) -> Result<()> { + fn start(&self, recipe_path: &Path, temp_dir: &Path) -> Result<()> { trace!("BuildCommand::start()"); - let temp_dir = self.temp_dir.as_ref().unwrap(); - let images = self.build(recipe_path, &temp_dir.path().join(CONTAINER_FILE))?; + let images = self.build(recipe_path, &temp_dir.join(CONTAINER_FILE))?; let color = gen_random_ansi_color(); info!( @@ -355,6 +358,7 @@ impl BuildCommand { .name(&*recipe.name) .description(&*recipe.description) .base_image(format!("{}:{}", &recipe.base_image, &recipe.image_version)) + .maybe_tempdir(self.tempdir.as_deref()) .build(), )? } else { diff --git a/src/commands/generate_iso.rs b/src/commands/generate_iso.rs index e80c3bc3..67d25862 100644 --- a/src/commands/generate_iso.rs +++ b/src/commands/generate_iso.rs @@ -71,6 +71,11 @@ pub struct GenerateIsoCommand { #[builder(into)] iso_name: Option, + /// The location to temporarily store files + /// while building. If unset, it will use `/tmp`. + #[arg(long)] + tempdir: Option, + #[clap(flatten)] #[builder(default)] drivers: DriverArgs, @@ -128,7 +133,11 @@ impl BlueBuildCommand for GenerateIsoCommand { bail!("You must be root to build an ISO!"); } - let image_out_dir = TempDir::new().into_diagnostic()?; + let image_out_dir = if let Some(ref dir) = self.tempdir { + TempDir::new_in(dir).into_diagnostic()? + } else { + TempDir::new().into_diagnostic()? + }; let output_dir = if let Some(output_dir) = self.output_dir.clone() { if output_dir.exists() && !output_dir.is_dir() { @@ -150,6 +159,7 @@ impl BlueBuildCommand for GenerateIsoCommand { BuildCommand::builder() .recipe(vec![recipe.clone()]) .archive(image_out_dir.path()) + .maybe_tempdir(self.tempdir.clone()) .build() }; #[cfg(not(feature = "multi-recipe"))] @@ -157,6 +167,7 @@ impl BlueBuildCommand for GenerateIsoCommand { BuildCommand::builder() .recipe(recipe.clone()) .archive(image_out_dir.path()) + .maybe_tempdir(self.tempdir.clone()) .build() }; diff --git a/src/commands/switch.rs b/src/commands/switch.rs index edc48d1c..05b274bc 100644 --- a/src/commands/switch.rs +++ b/src/commands/switch.rs @@ -36,6 +36,11 @@ pub struct SwitchCommand { #[builder(default)] reboot: bool, + /// The location to temporarily store files + /// while building. If unset, it will use `/tmp`. + #[arg(long)] + tempdir: Option, + #[clap(flatten)] #[builder(default)] drivers: DriverArgs, @@ -54,19 +59,25 @@ impl BlueBuildCommand for SwitchCommand { bail!("There is a transaction in progress. Please cancel it using `rpm-ostree cancel`"); } - let tempdir = TempDir::new().into_diagnostic()?; + let tempdir = if let Some(ref dir) = self.tempdir { + TempDir::new_in(dir).into_diagnostic()? + } else { + TempDir::new().into_diagnostic()? + }; trace!("{tempdir:?}"); #[cfg(feature = "multi-recipe")] BuildCommand::builder() .recipe([self.recipe.clone()]) .archive(tempdir.path()) + .maybe_tempdir(self.tempdir.clone()) .build() .try_run()?; #[cfg(not(feature = "multi-recipe"))] BuildCommand::builder() .recipe(self.recipe.clone()) .archive(tempdir.path()) + .maybe_tempdir(self.tempdir.clone()) .build() .try_run()?;