slim-rs v1: initrd build, qemu run, gitea actions
CI / build (push) Successful in 10s

This commit is contained in:
2026-08-25 20:10:03 +00:00
parent f7ca39117a
commit b9b5e3942b
3 changed files with 76 additions and 21 deletions
+40
View File
@@ -0,0 +1,40 @@
name: CI
on:
push:
branches: [master]
pull_request:
jobs:
build:
runs-on: amd64
steps:
- name: Install node
run: |
if command -v apk >/dev/null 2>&1; then
apk add --no-cache nodejs npm
elif command -v apt-get >/dev/null 2>&1; then
apt-get update && apt-get install -y nodejs npm
else
echo "No package manager found, assuming node present"
fi
- uses: actions/checkout@v4
- name: Install Rust
run: |
if command -v rustc >/dev/null 2>&1 && command -v cargo >/dev/null 2>&1; then
echo "Rust already present"
elif command -v apk >/dev/null 2>&1; then
apk add --no-cache rust rustfmt rust-clippy
elif command -v apt-get >/dev/null 2>&1; then
apt-get update && apt-get install -y rustc cargo rustfmt rust-clippy
else
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y --default-toolchain stable --component rustfmt,clippy
fi
- name: cargo check
run: cargo check
- name: cargo clippy
run: cargo clippy -- -D warnings
- name: cargo test
run: cargo test
- name: cargo fmt --check
run: cargo fmt -- --check
+8 -8
View File
@@ -1,15 +1,15 @@
[package] [package]
name = "slim" name = "slim"
version = "0.1.0" version = "0.1.0"
edition = "2021" edition = "2024"
[dependencies] [dependencies]
anyhow = "1" anyhow = "1.0.104"
clap = { version = "4", features = ["derive"] } clap = { version = "4.6.6", features = ["derive"] }
flate2 = "1" flate2 = "1.1.9"
walkdir = "2" walkdir = "2.5.0"
cpio = "0.2" cpio = "0.4.1"
xdg = "2" xdg = "3.0.0"
[dev-dependencies] [dev-dependencies]
tempfile = "3" tempfile = "3.27.0"
+27 -12
View File
@@ -43,9 +43,9 @@ fn main() -> Result<()> {
} }
fn registry_dir(image: &str) -> PathBuf { fn registry_dir(image: &str) -> PathBuf {
let base = xdg::BaseDirectories::with_prefix("slim-rs").unwrap(); let base = xdg::BaseDirectories::with_prefix("slim-rs");
base.place_data_file(format!("registry/{}/vmlinuz", image)).unwrap(); let initrd_path = base.place_data_file(format!("registry/{}/initrd", image));
base.place_data_file(format!("registry/{}/initrd", image)).unwrap().parent().unwrap().to_path_buf() initrd_path.unwrap().parent().unwrap().to_path_buf()
} }
fn build(image: &str) -> Result<()> { fn build(image: &str) -> Result<()> {
@@ -64,7 +64,9 @@ fn build(image: &str) -> Result<()> {
// Step 2: find vmlinuz // Step 2: find vmlinuz
let vmlinuz_src = mount_path.join("vmlinuz"); let vmlinuz_src = mount_path.join("vmlinuz");
if !vmlinuz_src.exists() { if !vmlinuz_src.exists() {
anyhow::bail!("Image missing required /vmlinuz. Place kernel at /vmlinuz in Containerfile."); anyhow::bail!(
"Image missing required /vmlinuz. Place kernel at /vmlinuz in Containerfile."
);
} }
// Step 3: prepare registry dir // Step 3: prepare registry dir
@@ -106,8 +108,12 @@ fn build(image: &str) -> Result<()> {
// Gzip initrd // Gzip initrd
let initrd_file = fs::File::open(&initrd_raw)?; let initrd_file = fs::File::open(&initrd_raw)?;
let mut initrd_writer = flate2::write::GzEncoder::new(File::create(&initrd_path)?, flate2::Compression::default()); let mut initrd_writer =
std::io::copy(&mut std::io::BufReader::new(initrd_file), &mut initrd_writer)?; flate2::write::GzEncoder::new(File::create(&initrd_path)?, flate2::Compression::default());
std::io::copy(
&mut std::io::BufReader::new(initrd_file),
&mut initrd_writer,
)?;
initrd_writer.finish()?; initrd_writer.finish()?;
fs::remove_file(&initrd_raw)?; fs::remove_file(&initrd_raw)?;
println!("Created initrd -> {}", initrd_path.display()); println!("Created initrd -> {}", initrd_path.display());
@@ -139,18 +145,27 @@ fn run(name: &str) -> Result<()> {
); );
// Launch with a 5-second timeout for quick smoke verification // Launch with a 5-second timeout for quick smoke verification
let status = Command::new("timeout") let status = Command::new("timeout")
.args(["5", "qemu-system-x86_64", .args([
"-m", "256", "5",
"qemu-system-x86_64",
"-m",
"256",
"-nographic", "-nographic",
"-kernel", vmlinuz_path.to_str().unwrap(), "-kernel",
"-initrd", initrd_path.to_str().unwrap(), vmlinuz_path.to_str().unwrap(),
"-append", "console=ttyS0"]) "-initrd",
initrd_path.to_str().unwrap(),
"-append",
"console=ttyS0",
])
.status() .status()
.context("Failed to launch qemu-system-x86_64")?; .context("Failed to launch qemu-system-x86_64")?;
if status.success() { if status.success() {
println!("QEMU exited cleanly (timeout or normal exit)."); println!("QEMU exited cleanly (timeout or normal exit).");
} else { } else {
println!("QEMU exited with non-zero status (timeout/expected for initrd boot without init)."); println!(
"QEMU exited with non-zero status (timeout/expected for initrd boot without init)."
);
} }
Ok(()) Ok(())
} }