This commit is contained in:
@@ -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
@@ -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"
|
||||||
|
|||||||
+28
-13
@@ -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",
|
||||||
"-nographic",
|
"qemu-system-x86_64",
|
||||||
"-kernel", vmlinuz_path.to_str().unwrap(),
|
"-m",
|
||||||
"-initrd", initrd_path.to_str().unwrap(),
|
"256",
|
||||||
"-append", "console=ttyS0"])
|
"-nographic",
|
||||||
|
"-kernel",
|
||||||
|
vmlinuz_path.to_str().unwrap(),
|
||||||
|
"-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(())
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user