feat: add progressbar for extraction and initramfs creation

This commit is contained in:
2026-06-17 00:11:12 +02:00
parent a81e699619
commit 4475dff141
2 changed files with 100 additions and 102 deletions
+24 -9
View File
@@ -1,6 +1,7 @@
use crate::veprintln;
use anyhow::{anyhow, Context, Result};
use cpio::{newc, NewcBuilder};
use indicatif::{ProgressBar, ProgressStyle};
use std::io::Write;
use std::os::unix::fs::MetadataExt;
use std::path::{Path, PathBuf};
@@ -147,13 +148,20 @@ fn get_arch_package_suffix(arch: &str) -> &str {
/// Create a gzipped cpio initramfs from a directory
fn create_initramfs(rootfs: &PathBuf) -> Result<PathBuf> {
veprintln!("Creating initramfs from rootfs...");
// Create a temporary file for the initramfs
let initramfs_path = rootfs.parent().unwrap().join("initramfs.cpio.gz");
// Create the cpio archive
let cpio_data = create_cpio_archive(rootfs)?;
// Create progress bar
let pb = ProgressBar::new_spinner();
pb.set_style(ProgressStyle::default_spinner()
.template("{spinner:.green} {msg} ({pos} files)")
.unwrap());
pb.set_message("Scanning rootfs...");
// Create the cpio archive with progress
let cpio_data = create_cpio_archive(rootfs, &pb)?;
pb.set_message("Compressing initramfs...");
// Compress with gzip
let mut output_file = std::fs::File::create(&initramfs_path)
@@ -165,21 +173,25 @@ fn create_initramfs(rootfs: &PathBuf) -> Result<PathBuf> {
encoder.finish()
.context("Failed to finalize gzip compression")?;
veprintln!("Initramfs created: {} bytes (uncompressed)", cpio_data.len());
// Clear progress bar and print message only in verbose mode
pb.finish_and_clear();
veprintln!("Initramfs created: {} bytes, {} files", cpio_data.len(), pb.position());
Ok(initramfs_path)
}
/// Create a newc-format cpio archive from a directory using the cpio crate
fn create_cpio_archive(rootfs: &Path) -> Result<Vec<u8>> {
fn create_cpio_archive(rootfs: &Path, pb: &ProgressBar) -> Result<Vec<u8>> {
let mut archive = Vec::new();
// Collect all entries with their data
let entries = collect_entries(rootfs, rootfs)?;
let entries = collect_entries(rootfs, rootfs, pb)?;
// Collect entry names for checking existence later
let entry_names: Vec<&str> = entries.iter().map(|(n, _, _, _, _)| n.as_str()).collect();
pb.set_message("Writing initramfs...");
// Write each entry using the cpio crate
for (name, mode, mtime, nlink, data) in &entries {
let file_size = data.len() as u32;
@@ -243,7 +255,7 @@ fn create_cpio_archive(rootfs: &Path) -> Result<Vec<u8>> {
}
/// Collect all filesystem entries recursively
fn collect_entries(base: &Path, current: &Path) -> Result<Vec<(String, u32, u32, u32, Vec<u8>)>> {
fn collect_entries(base: &Path, current: &Path, pb: &ProgressBar) -> Result<Vec<(String, u32, u32, u32, Vec<u8>)>> {
let mut entries = Vec::new();
// Read directory entries
@@ -267,6 +279,9 @@ fn collect_entries(base: &Path, current: &Path) -> Result<Vec<(String, u32, u32,
}
};
// Increment progress counter
pb.inc(1);
let file_type = metadata.file_type();
// Determine mode (file type + permissions from filesystem)
@@ -314,7 +329,7 @@ fn collect_entries(base: &Path, current: &Path) -> Result<Vec<(String, u32, u32,
// Recurse into directories
if file_type.is_dir() {
let mut sub_entries = collect_entries(base, &path)?;
let mut sub_entries = collect_entries(base, &path, pb)?;
entries.append(&mut sub_entries);
}
}