This commit is contained in:
@@ -166,11 +166,18 @@ impl UnshareDriver {
|
|||||||
env: &[(String, String)],
|
env: &[(String, String)],
|
||||||
cwd: Option<&str>,
|
cwd: Option<&str>,
|
||||||
) -> ContextCommand<'_> {
|
) -> ContextCommand<'_> {
|
||||||
let mut cmd = self.parent().command("sudo");
|
let mut cmd = self.parent().command("unshare");
|
||||||
cmd.args(env.iter().map(|(k, v)| format!("{k}={v}")));
|
|
||||||
|
|
||||||
cmd.arg("unshare")
|
cmd.envs(env.iter().cloned());
|
||||||
.arg("--mount-proc")
|
|
||||||
|
cmd.arg("--mount-proc")
|
||||||
|
.arg("--pid")
|
||||||
|
.arg("--ipc")
|
||||||
|
.arg("--uts")
|
||||||
|
.arg("--map-auto")
|
||||||
|
.arg("-r")
|
||||||
|
.arg("--mount")
|
||||||
|
.arg("--fork")
|
||||||
.arg("-R")
|
.arg("-R")
|
||||||
.arg(&self.path);
|
.arg(&self.path);
|
||||||
|
|
||||||
|
|||||||
@@ -1,9 +1,12 @@
|
|||||||
use crate::context;
|
use crate::context;
|
||||||
use crate::context::{Context, ContextConfig};
|
use crate::context::{Context, ContextConfig};
|
||||||
|
use directories::ProjectDirs;
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::error::Error;
|
use std::error::Error;
|
||||||
|
use std::fs;
|
||||||
use std::path::PathBuf;
|
use std::path::{Path, PathBuf};
|
||||||
|
use tar::Archive;
|
||||||
|
use xz2::read::XzDecoder;
|
||||||
|
|
||||||
pub struct EphemeralContextGuard {
|
pub struct EphemeralContextGuard {
|
||||||
previous_context: String,
|
previous_context: String,
|
||||||
@@ -24,19 +27,8 @@ impl EphemeralContextGuard {
|
|||||||
chroot_path.display()
|
chroot_path.display()
|
||||||
);
|
);
|
||||||
|
|
||||||
let status = context::current()
|
// Download and extract the chroot tarball
|
||||||
.command("sudo")
|
Self::download_and_extract_chroot(series, &chroot_path)?;
|
||||||
.arg("mmdebstrap")
|
|
||||||
.arg("--variant=buildd")
|
|
||||||
.arg(series)
|
|
||||||
.arg(chroot_path.to_string_lossy().to_string())
|
|
||||||
.status()?;
|
|
||||||
|
|
||||||
if !status.success() {
|
|
||||||
// Clean up on failure
|
|
||||||
let _ = std::fs::remove_dir_all(&chroot_path);
|
|
||||||
return Err(format!("mmdebstrap failed for series {}", series).into());
|
|
||||||
}
|
|
||||||
|
|
||||||
// Switch to an ephemeral context to build the package in the chroot
|
// Switch to an ephemeral context to build the package in the chroot
|
||||||
context::manager().set_current_ephemeral(Context::new(ContextConfig::Unshare {
|
context::manager().set_current_ephemeral(Context::new(ContextConfig::Unshare {
|
||||||
@@ -49,6 +41,70 @@ impl EphemeralContextGuard {
|
|||||||
chroot_path,
|
chroot_path,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn download_and_extract_chroot(
|
||||||
|
series: &str,
|
||||||
|
chroot_path: &PathBuf,
|
||||||
|
) -> Result<(), Box<dyn Error>> {
|
||||||
|
// Get project directories for caching
|
||||||
|
let proj_dirs = ProjectDirs::from("com", "pkh", "pkh")
|
||||||
|
.ok_or("Could not determine project directories")?;
|
||||||
|
let cache_dir = proj_dirs.cache_dir();
|
||||||
|
fs::create_dir_all(cache_dir)?;
|
||||||
|
|
||||||
|
// Create tarball filename based on series
|
||||||
|
let tarball_filename = format!("{}-buildd.tar.xz", series);
|
||||||
|
let tarball_path = cache_dir.join(&tarball_filename);
|
||||||
|
|
||||||
|
// Download tarball if it doesn't exist
|
||||||
|
if !tarball_path.exists() {
|
||||||
|
log::debug!("Downloading chroot tarball for {}...", series);
|
||||||
|
Self::download_chroot_tarball(series, &tarball_path)?;
|
||||||
|
} else {
|
||||||
|
log::debug!("Using cached chroot tarball for {}", series);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Extract tarball to chroot directory
|
||||||
|
log::debug!("Extracting chroot tarball to {}...", chroot_path.display());
|
||||||
|
Self::extract_tarball(&tarball_path, chroot_path)?;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn download_chroot_tarball(series: &str, tarball_path: &Path) -> Result<(), Box<dyn Error>> {
|
||||||
|
// Use mmdebstrap to download the tarball to the cache directory
|
||||||
|
let status = context::current()
|
||||||
|
.command("mmdebstrap")
|
||||||
|
.arg("--variant=buildd")
|
||||||
|
.arg("--format=tar")
|
||||||
|
.arg(series)
|
||||||
|
.arg(tarball_path.to_string_lossy().to_string())
|
||||||
|
.status()?;
|
||||||
|
|
||||||
|
if !status.success() {
|
||||||
|
return Err(format!("Failed to download chroot tarball for series {}", series).into());
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn extract_tarball(
|
||||||
|
tarball_path: &PathBuf,
|
||||||
|
chroot_path: &PathBuf,
|
||||||
|
) -> Result<(), Box<dyn Error>> {
|
||||||
|
// Create the chroot directory
|
||||||
|
fs::create_dir_all(chroot_path)?;
|
||||||
|
|
||||||
|
// Open the tarball file
|
||||||
|
let tarball_file = std::fs::File::open(tarball_path)?;
|
||||||
|
let xz_decoder = XzDecoder::new(tarball_file);
|
||||||
|
let mut archive = Archive::new(xz_decoder);
|
||||||
|
|
||||||
|
// Extract all files to the chroot directory
|
||||||
|
archive.unpack(chroot_path)?;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Drop for EphemeralContextGuard {
|
impl Drop for EphemeralContextGuard {
|
||||||
|
|||||||
Reference in New Issue
Block a user