use std::env; use std::fs; use std::path::PathBuf; use std::process::Command; use alt_controller_image::{artifact_path, Profile}; fn run(command: &mut Command, description: &str) { let status = command.status().unwrap_or_else(|error| panic!("{description}: {error}")); assert!(status.success(), "{description} exited with {status}"); } fn main() { let project = env::current_dir().expect("current directory"); let profile_path = project.join("profiles/alt-controller.profile"); let profile = Profile::load(&profile_path).unwrap_or_else(|error| panic!("profile: {error}")); let workdir: PathBuf = project.join("work/alt-controller"); let rootfs = workdir.join("chroot"); let artifact = artifact_path(&project); let archive_existing = env::args().any(|argument| argument == "--archive-existing"); if !archive_existing { if workdir.exists() { run( Command::new("sudo").args(["rm", "-rf"]).arg(&workdir), "remove previous Hasher workdir", ); } fs::create_dir_all(&workdir).expect("create Hasher workdir"); run( Command::new("hsh") .args(["--mountpoints=/proc", "--initroot-only", "--workdir"]) .arg(&workdir), "initialize isolated Hasher root", ); let mut install = Command::new("hsh-install"); install.args(["--mountpoints=/proc", "--workdir"]); install.arg(&workdir); install.args(profile.install_arguments()); run(&mut install, "install target rootfs packages"); } assert!(rootfs.is_dir(), "isolated rootfs is missing: {}", rootfs.display()); fs::create_dir_all(artifact.parent().expect("artifact parent")).expect("create output directory"); if artifact.exists() { fs::remove_file(&artifact).expect("remove previous artifact"); } run( Command::new("sudo") .arg("tar") .args(["--numeric-owner", "--exclude=./.host", "-C"]) .arg(&rootfs) .args(["-cpf"]) .arg(&artifact) .arg("."), "archive isolated rootfs", ); println!("{}", artifact.display()); }