feat: Add the ability to choose a tempdir for builds

This commit is contained in:
Gerald Pinder 2024-12-08 22:01:36 -05:00
parent 7bc67bf766
commit d9b812d59b
5 changed files with 49 additions and 18 deletions

View file

@ -44,4 +44,5 @@ pub struct RechunkOpts<'scope> {
/// The compression type to use when pushing. /// The compression type to use when pushing.
#[builder(default)] #[builder(default)]
pub compression: CompressionType, pub compression: CompressionType,
pub tempdir: Option<&'scope Path>,
} }

View file

@ -308,7 +308,11 @@ pub trait RechunkDriver: RunDriver + BuildDriver + ContainerMountDriver {
Self::prune_image(mount, container, raw_image, opts)?; Self::prune_image(mount, container, raw_image, opts)?;
Self::create_ostree_commit(mount, ostree_cache_id, 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(); let temp_dir_str = &*temp_dir.path().to_string_lossy();
Self::rechunk_image(ostree_cache_id, temp_dir_str, current_dir, opts)?; Self::rechunk_image(ostree_cache_id, temp_dir_str, current_dir, opts)?;

View file

@ -120,6 +120,11 @@ pub struct BuildCommand {
#[cfg(feature = "rechunk")] #[cfg(feature = "rechunk")]
rechunk: bool, rechunk: bool,
/// The location to temporarily store files
/// while building. If unset, it will use `/tmp`.
#[arg(long)]
tempdir: Option<PathBuf>,
#[clap(flatten)] #[clap(flatten)]
#[builder(default)] #[builder(default)]
credentials: CredentialsArgs, credentials: CredentialsArgs,
@ -127,9 +132,6 @@ pub struct BuildCommand {
#[clap(flatten)] #[clap(flatten)]
#[builder(default)] #[builder(default)]
drivers: DriverArgs, drivers: DriverArgs,
#[clap(skip)]
temp_dir: Option<TempDir>,
} }
impl BlueBuildCommand for BuildCommand { impl BlueBuildCommand for BuildCommand {
@ -157,8 +159,11 @@ impl BlueBuildCommand for BuildCommand {
Driver::signing_login()?; Driver::signing_login()?;
} }
self.temp_dir = Some(TempDir::new().into_diagnostic()?); let tempdir = if let Some(ref dir) = self.tempdir {
let temp_dir = self.temp_dir.as_ref().unwrap(); TempDir::new_in(dir).into_diagnostic()?
} else {
TempDir::new().into_diagnostic()?
};
#[cfg(feature = "multi-recipe")] #[cfg(feature = "multi-recipe")]
{ {
@ -181,7 +186,7 @@ impl BlueBuildCommand for BuildCommand {
recipe_paths.par_iter().try_for_each(|recipe| { recipe_paths.par_iter().try_for_each(|recipe| {
GenerateCommand::builder() 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)? blue_build_utils::generate_containerfile_path(recipe)?
} else { } else {
PathBuf::from(CONTAINER_FILE) PathBuf::from(CONTAINER_FILE)
@ -193,7 +198,7 @@ impl BlueBuildCommand for BuildCommand {
.try_run() .try_run()
})?; })?;
self.start(&recipe_paths) self.start(&recipe_paths, tempdir.path())
} }
#[cfg(not(feature = "multi-recipe"))] #[cfg(not(feature = "multi-recipe"))]
@ -210,29 +215,28 @@ impl BlueBuildCommand for BuildCommand {
}); });
GenerateCommand::builder() GenerateCommand::builder()
.output(temp_dir.path().join(CONTAINER_FILE)) .output(tempdir.path().join(CONTAINER_FILE))
.recipe(&recipe_path) .recipe(&recipe_path)
.drivers(self.drivers) .drivers(self.drivers)
.build() .build()
.try_run()?; .try_run()?;
self.start(&recipe_path) self.start(&recipe_path, tempdir.path())
} }
} }
} }
impl BuildCommand { impl BuildCommand {
#[cfg(feature = "multi-recipe")] #[cfg(feature = "multi-recipe")]
fn start(&self, recipe_paths: &[PathBuf]) -> Result<()> { fn start(&self, recipe_paths: &[PathBuf], temp_dir: &Path) -> Result<()> {
use rayon::prelude::*; use rayon::prelude::*;
trace!("BuildCommand::build_image()"); trace!("BuildCommand::build_image()");
let temp_dir = self.temp_dir.as_ref().unwrap();
let images = recipe_paths let images = recipe_paths
.par_iter() .par_iter()
.try_fold(Vec::new, |mut images, recipe_path| -> Result<Vec<String>> { .try_fold(Vec::new, |mut images, recipe_path| -> Result<Vec<String>> {
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)? blue_build_utils::generate_containerfile_path(recipe_path)?
} else { } else {
PathBuf::from(CONTAINER_FILE) PathBuf::from(CONTAINER_FILE)
@ -258,11 +262,10 @@ impl BuildCommand {
} }
#[cfg(not(feature = "multi-recipe"))] #[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()"); 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(); let color = gen_random_ansi_color();
info!( info!(
@ -355,6 +358,7 @@ impl BuildCommand {
.name(&*recipe.name) .name(&*recipe.name)
.description(&*recipe.description) .description(&*recipe.description)
.base_image(format!("{}:{}", &recipe.base_image, &recipe.image_version)) .base_image(format!("{}:{}", &recipe.base_image, &recipe.image_version))
.maybe_tempdir(self.tempdir.as_deref())
.build(), .build(),
)? )?
} else { } else {

View file

@ -71,6 +71,11 @@ pub struct GenerateIsoCommand {
#[builder(into)] #[builder(into)]
iso_name: Option<String>, iso_name: Option<String>,
/// The location to temporarily store files
/// while building. If unset, it will use `/tmp`.
#[arg(long)]
tempdir: Option<PathBuf>,
#[clap(flatten)] #[clap(flatten)]
#[builder(default)] #[builder(default)]
drivers: DriverArgs, drivers: DriverArgs,
@ -128,7 +133,11 @@ impl BlueBuildCommand for GenerateIsoCommand {
bail!("You must be root to build an ISO!"); 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() { let output_dir = if let Some(output_dir) = self.output_dir.clone() {
if output_dir.exists() && !output_dir.is_dir() { if output_dir.exists() && !output_dir.is_dir() {
@ -150,6 +159,7 @@ impl BlueBuildCommand for GenerateIsoCommand {
BuildCommand::builder() BuildCommand::builder()
.recipe(vec![recipe.clone()]) .recipe(vec![recipe.clone()])
.archive(image_out_dir.path()) .archive(image_out_dir.path())
.maybe_tempdir(self.tempdir.clone())
.build() .build()
}; };
#[cfg(not(feature = "multi-recipe"))] #[cfg(not(feature = "multi-recipe"))]
@ -157,6 +167,7 @@ impl BlueBuildCommand for GenerateIsoCommand {
BuildCommand::builder() BuildCommand::builder()
.recipe(recipe.clone()) .recipe(recipe.clone())
.archive(image_out_dir.path()) .archive(image_out_dir.path())
.maybe_tempdir(self.tempdir.clone())
.build() .build()
}; };

View file

@ -36,6 +36,11 @@ pub struct SwitchCommand {
#[builder(default)] #[builder(default)]
reboot: bool, reboot: bool,
/// The location to temporarily store files
/// while building. If unset, it will use `/tmp`.
#[arg(long)]
tempdir: Option<PathBuf>,
#[clap(flatten)] #[clap(flatten)]
#[builder(default)] #[builder(default)]
drivers: DriverArgs, drivers: DriverArgs,
@ -54,19 +59,25 @@ impl BlueBuildCommand for SwitchCommand {
bail!("There is a transaction in progress. Please cancel it using `rpm-ostree cancel`"); 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:?}"); trace!("{tempdir:?}");
#[cfg(feature = "multi-recipe")] #[cfg(feature = "multi-recipe")]
BuildCommand::builder() BuildCommand::builder()
.recipe([self.recipe.clone()]) .recipe([self.recipe.clone()])
.archive(tempdir.path()) .archive(tempdir.path())
.maybe_tempdir(self.tempdir.clone())
.build() .build()
.try_run()?; .try_run()?;
#[cfg(not(feature = "multi-recipe"))] #[cfg(not(feature = "multi-recipe"))]
BuildCommand::builder() BuildCommand::builder()
.recipe(self.recipe.clone()) .recipe(self.recipe.clone())
.archive(tempdir.path()) .archive(tempdir.path())
.maybe_tempdir(self.tempdir.clone())
.build() .build()
.try_run()?; .try_run()?;