Add comprehensive tests and fix compiler warnings
- Fix false-positive unused_assignments warnings from thiserror/miette
derive macros in Rust 2024 edition with crate-level #![allow]
- Add 5 tests for tar_layer (empty dir, files, nested dirs, symlinks,
deterministic digest)
- Add 5 tests for manifest (default options, entrypoint/env, multiple
layers, config digest verification, no entrypoint)
- Add 6 tests for layout (structure creation, oci-layout content,
index.json references, layer blobs, config digest, multiple layers)
- Add 11 tests for overlays (file copy, empty file, missing source,
ensure dir, symlink, remove file, remove dir contents, shadow
create/update, multiple overlays)
- Add 4 tests for customizations (single user, multiple users, append
to existing, no users noop)
- Add 3 tests for phase2/oci (layout output, entrypoint/env, empty
staging)
- Add tempfile dev-dependency to forge-oci for test support
42 tests passing, 0 warnings.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-15 15:40:16 +01:00
|
|
|
// thiserror/miette derive macros generate code that triggers false-positive unused_assignments
|
|
|
|
|
#![allow(unused_assignments)]
|
|
|
|
|
|
2026-02-15 15:30:22 +01:00
|
|
|
pub mod profile;
|
|
|
|
|
pub mod resolve;
|
|
|
|
|
pub mod schema;
|
|
|
|
|
|
|
|
|
|
use miette::Diagnostic;
|
|
|
|
|
use thiserror::Error;
|
|
|
|
|
|
|
|
|
|
#[derive(Debug, Error, Diagnostic)]
|
|
|
|
|
pub enum ParseError {
|
Add comprehensive tests and fix compiler warnings
- Fix false-positive unused_assignments warnings from thiserror/miette
derive macros in Rust 2024 edition with crate-level #![allow]
- Add 5 tests for tar_layer (empty dir, files, nested dirs, symlinks,
deterministic digest)
- Add 5 tests for manifest (default options, entrypoint/env, multiple
layers, config digest verification, no entrypoint)
- Add 6 tests for layout (structure creation, oci-layout content,
index.json references, layer blobs, config digest, multiple layers)
- Add 11 tests for overlays (file copy, empty file, missing source,
ensure dir, symlink, remove file, remove dir contents, shadow
create/update, multiple overlays)
- Add 4 tests for customizations (single user, multiple users, append
to existing, no users noop)
- Add 3 tests for phase2/oci (layout output, entrypoint/env, empty
staging)
- Add tempfile dev-dependency to forge-oci for test support
42 tests passing, 0 warnings.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-15 15:40:16 +01:00
|
|
|
#[error("Failed to parse KDL spec: {detail}")]
|
2026-02-15 15:30:22 +01:00
|
|
|
#[diagnostic(
|
|
|
|
|
help("Check the KDL syntax in your spec file"),
|
|
|
|
|
code(spec_parser::kdl_parse)
|
|
|
|
|
)]
|
Add comprehensive tests and fix compiler warnings
- Fix false-positive unused_assignments warnings from thiserror/miette
derive macros in Rust 2024 edition with crate-level #![allow]
- Add 5 tests for tar_layer (empty dir, files, nested dirs, symlinks,
deterministic digest)
- Add 5 tests for manifest (default options, entrypoint/env, multiple
layers, config digest verification, no entrypoint)
- Add 6 tests for layout (structure creation, oci-layout content,
index.json references, layer blobs, config digest, multiple layers)
- Add 11 tests for overlays (file copy, empty file, missing source,
ensure dir, symlink, remove file, remove dir contents, shadow
create/update, multiple overlays)
- Add 4 tests for customizations (single user, multiple users, append
to existing, no users noop)
- Add 3 tests for phase2/oci (layout output, entrypoint/env, empty
staging)
- Add tempfile dev-dependency to forge-oci for test support
42 tests passing, 0 warnings.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-15 15:40:16 +01:00
|
|
|
KdlError { detail: String },
|
2026-02-15 15:30:22 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
impl From<knuffel::Error> for ParseError {
|
|
|
|
|
fn from(err: knuffel::Error) -> Self {
|
|
|
|
|
ParseError::KdlError {
|
|
|
|
|
detail: err.to_string(),
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pub fn parse(kdl: &str) -> Result<schema::ImageSpec, ParseError> {
|
|
|
|
|
knuffel::parse("image.kdl", kdl).map_err(ParseError::from)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[cfg(test)]
|
|
|
|
|
mod tests {
|
|
|
|
|
use super::*;
|
|
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
|
fn test_parse_example() {
|
|
|
|
|
let kdl = r#"
|
|
|
|
|
metadata name="my-image" version="1.0.0" description="A test image"
|
|
|
|
|
|
|
|
|
|
base "path/to/base.tar.gz"
|
|
|
|
|
build-host "path/to/build-vm.qcow2"
|
|
|
|
|
|
|
|
|
|
repositories {
|
|
|
|
|
publisher name="test-pub" origin="http://pkg.test.com"
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
incorporation "pkg:/test/incorporation"
|
|
|
|
|
|
|
|
|
|
packages {
|
|
|
|
|
package "system/kernel"
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
packages if="desktop" {
|
|
|
|
|
package "desktop/gnome"
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
customization {
|
|
|
|
|
user "admin"
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
overlays {
|
|
|
|
|
file source="local/file" destination="/remote/file"
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
target "vm" kind="qcow2" {
|
|
|
|
|
disk-size "20G"
|
|
|
|
|
bootloader "grub"
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
target "container" kind="oci" {
|
|
|
|
|
entrypoint command="/bin/sh"
|
|
|
|
|
environment {
|
|
|
|
|
set "PATH" "/bin:/usr/bin"
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
"#;
|
|
|
|
|
|
|
|
|
|
let spec = parse(kdl).expect("Failed to parse KDL");
|
|
|
|
|
assert_eq!(spec.metadata.name, "my-image");
|
|
|
|
|
assert_eq!(spec.base, Some("path/to/base.tar.gz".to_string()));
|
|
|
|
|
assert_eq!(
|
|
|
|
|
spec.build_host,
|
|
|
|
|
Some("path/to/build-vm.qcow2".to_string())
|
|
|
|
|
);
|
|
|
|
|
assert_eq!(spec.repositories.publishers.len(), 1);
|
|
|
|
|
assert_eq!(spec.packages.len(), 2);
|
|
|
|
|
assert_eq!(spec.targets.len(), 2);
|
|
|
|
|
|
|
|
|
|
let vm_target = &spec.targets[0];
|
|
|
|
|
assert_eq!(vm_target.name, "vm");
|
|
|
|
|
assert_eq!(vm_target.kind, schema::TargetKind::Qcow2);
|
|
|
|
|
assert_eq!(vm_target.disk_size, Some("20G".to_string()));
|
|
|
|
|
assert_eq!(vm_target.bootloader, Some("grub".to_string()));
|
|
|
|
|
|
|
|
|
|
let container_target = &spec.targets[1];
|
|
|
|
|
assert_eq!(container_target.name, "container");
|
|
|
|
|
assert_eq!(container_target.kind, schema::TargetKind::Oci);
|
|
|
|
|
assert_eq!(
|
|
|
|
|
container_target.entrypoint.as_ref().unwrap().command,
|
|
|
|
|
"/bin/sh"
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
|
fn test_parse_variants_and_certificates() {
|
|
|
|
|
let kdl = r#"
|
|
|
|
|
metadata name="test" version="0.1.0"
|
|
|
|
|
repositories {
|
|
|
|
|
publisher name="omnios" origin="https://pkg.omnios.org/bloody/core/"
|
|
|
|
|
}
|
|
|
|
|
variants {
|
|
|
|
|
set name="opensolaris.zone" value="global"
|
|
|
|
|
}
|
|
|
|
|
certificates {
|
|
|
|
|
ca publisher="omnios" certfile="omniosce-ca.cert.pem"
|
|
|
|
|
}
|
|
|
|
|
"#;
|
|
|
|
|
|
|
|
|
|
let spec = parse(kdl).expect("Failed to parse KDL");
|
|
|
|
|
let variants = spec.variants.unwrap();
|
|
|
|
|
assert_eq!(variants.vars.len(), 1);
|
|
|
|
|
assert_eq!(variants.vars[0].name, "opensolaris.zone");
|
|
|
|
|
assert_eq!(variants.vars[0].value, "global");
|
|
|
|
|
|
|
|
|
|
let certs = spec.certificates.unwrap();
|
|
|
|
|
assert_eq!(certs.ca.len(), 1);
|
|
|
|
|
assert_eq!(certs.ca[0].publisher, "omnios");
|
|
|
|
|
}
|
|
|
|
|
|
2026-02-15 16:29:12 +01:00
|
|
|
#[test]
|
|
|
|
|
fn test_parse_ubuntu_spec() {
|
|
|
|
|
let kdl = r#"
|
|
|
|
|
metadata name="ubuntu-ci" version="0.1.0"
|
|
|
|
|
distro "ubuntu-22.04"
|
|
|
|
|
repositories {
|
|
|
|
|
apt-mirror "http://archive.ubuntu.com/ubuntu" suite="jammy" components="main universe"
|
|
|
|
|
}
|
|
|
|
|
packages {
|
|
|
|
|
package "build-essential"
|
|
|
|
|
package "curl"
|
|
|
|
|
}
|
|
|
|
|
target "qcow2" kind="qcow2" {
|
|
|
|
|
disk-size "8G"
|
|
|
|
|
bootloader "grub"
|
|
|
|
|
filesystem "ext4"
|
|
|
|
|
push-to "ghcr.io/cloudnebulaproject/ubuntu-rust:latest"
|
|
|
|
|
}
|
|
|
|
|
"#;
|
|
|
|
|
|
|
|
|
|
let spec = parse(kdl).expect("Failed to parse Ubuntu spec");
|
|
|
|
|
assert_eq!(spec.distro, Some("ubuntu-22.04".to_string()));
|
|
|
|
|
assert_eq!(spec.repositories.apt_mirrors.len(), 1);
|
|
|
|
|
let mirror = &spec.repositories.apt_mirrors[0];
|
|
|
|
|
assert_eq!(mirror.url, "http://archive.ubuntu.com/ubuntu");
|
|
|
|
|
assert_eq!(mirror.suite, "jammy");
|
|
|
|
|
assert_eq!(mirror.components, Some("main universe".to_string()));
|
|
|
|
|
|
|
|
|
|
let target = &spec.targets[0];
|
|
|
|
|
assert_eq!(target.filesystem, Some("ext4".to_string()));
|
|
|
|
|
assert_eq!(
|
|
|
|
|
target.push_to,
|
|
|
|
|
Some("ghcr.io/cloudnebulaproject/ubuntu-rust:latest".to_string())
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
|
fn test_parse_omnios_spec_unchanged() {
|
|
|
|
|
// Existing OmniOS specs should parse without errors (backward compat)
|
|
|
|
|
let kdl = r#"
|
|
|
|
|
metadata name="omnios-disk" version="0.0.1"
|
|
|
|
|
repositories {
|
|
|
|
|
publisher name="omnios" origin="https://pkg.omnios.org/bloody/core/"
|
|
|
|
|
}
|
|
|
|
|
packages {
|
|
|
|
|
package "system/kernel"
|
|
|
|
|
}
|
|
|
|
|
target "vm" kind="qcow2" {
|
|
|
|
|
disk-size "2000M"
|
|
|
|
|
bootloader "uefi"
|
|
|
|
|
pool {
|
|
|
|
|
property name="ashift" value="12"
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
"#;
|
|
|
|
|
|
|
|
|
|
let spec = parse(kdl).expect("Failed to parse OmniOS spec");
|
|
|
|
|
assert_eq!(spec.distro, None);
|
|
|
|
|
assert!(spec.repositories.apt_mirrors.is_empty());
|
|
|
|
|
assert_eq!(spec.targets[0].filesystem, None);
|
|
|
|
|
assert_eq!(spec.targets[0].push_to, None);
|
|
|
|
|
|
|
|
|
|
// DistroFamily should default to OmniOS
|
|
|
|
|
assert_eq!(
|
|
|
|
|
schema::DistroFamily::from_distro_str(spec.distro.as_deref()),
|
|
|
|
|
schema::DistroFamily::OmniOS
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
|
fn test_distro_family_detection() {
|
|
|
|
|
assert_eq!(
|
|
|
|
|
schema::DistroFamily::from_distro_str(None),
|
|
|
|
|
schema::DistroFamily::OmniOS
|
|
|
|
|
);
|
|
|
|
|
assert_eq!(
|
|
|
|
|
schema::DistroFamily::from_distro_str(Some("omnios")),
|
|
|
|
|
schema::DistroFamily::OmniOS
|
|
|
|
|
);
|
|
|
|
|
assert_eq!(
|
|
|
|
|
schema::DistroFamily::from_distro_str(Some("ubuntu-22.04")),
|
|
|
|
|
schema::DistroFamily::Ubuntu
|
|
|
|
|
);
|
|
|
|
|
assert_eq!(
|
|
|
|
|
schema::DistroFamily::from_distro_str(Some("ubuntu-24.04")),
|
|
|
|
|
schema::DistroFamily::Ubuntu
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
2026-02-15 15:30:22 +01:00
|
|
|
#[test]
|
|
|
|
|
fn test_parse_pool_properties() {
|
|
|
|
|
let kdl = r#"
|
|
|
|
|
metadata name="test" version="0.1.0"
|
|
|
|
|
repositories {}
|
|
|
|
|
target "disk" kind="qcow2" {
|
|
|
|
|
disk-size "2000M"
|
|
|
|
|
bootloader "uefi"
|
|
|
|
|
pool {
|
|
|
|
|
property name="ashift" value="12"
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
"#;
|
|
|
|
|
|
|
|
|
|
let spec = parse(kdl).expect("Failed to parse KDL");
|
|
|
|
|
let target = &spec.targets[0];
|
|
|
|
|
let pool = target.pool.as_ref().unwrap();
|
|
|
|
|
assert_eq!(pool.properties.len(), 1);
|
|
|
|
|
assert_eq!(pool.properties[0].name, "ashift");
|
|
|
|
|
assert_eq!(pool.properties[0].value, "12");
|
|
|
|
|
}
|
Add builder VM support for cross-platform and unprivileged builds
Introduce the forge-builder crate that automatically delegates builds to
an ephemeral VM when the host can't build locally (e.g., QCOW2 targets
without root, or OmniOS images on Linux). The builder detects these
conditions, spins up a VM via vm-manager with user-mode networking,
uploads inputs, streams the remote build output, and retrieves artifacts.
Key changes:
- New forge-builder crate with detection, binary resolution, VM lifecycle
management, file transfer, and miette diagnostic errors
- BuilderNode added to spec-parser schema for per-spec VM config
- --local and --use-builder CLI flags on the build command
- Feature-gated (default on) integration in forger CLI
- Fix ext4 QCOW2 grub-install failure by using absolute paths in chroot
- Improve debootstrap to pass --components and write full sources.list
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-15 17:17:30 +01:00
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
|
fn test_parse_builder_node_full() {
|
|
|
|
|
let kdl = r#"
|
|
|
|
|
metadata name="test" version="0.1.0"
|
|
|
|
|
repositories {}
|
|
|
|
|
builder {
|
|
|
|
|
image "oci://ghcr.io/custom/builder:v1"
|
|
|
|
|
vcpus 4
|
|
|
|
|
memory 4096
|
Fix builder VM disk sizing, rootfs copy, and diagnostics
- Add disk_gb field to BuilderNode/BuilderConfig with 20GB default,
fixing debootstrap failure caused by 2GB cloud image running out of
space. Cloud-init growpart/resize_rootfs expand the partition.
- Replace walkdir-based copy_rootfs with cp -a to preserve symlinks,
fixing grub-install failure caused by broken merged-/usr symlinks
(/lib, /bin, /sbin -> /usr/*) in modern Ubuntu.
- Add network verification step that checks DNS before building and
auto-fixes resolv.conf with SLIRP DNS (10.0.2.3) if needed.
- Add diagnostic collection on failure (debootstrap log, resolv.conf,
disk space) before VM teardown.
- Include build stderr/stdout in RemoteBuildFailed error for better
error reporting.
- Install build dependencies (debootstrap, qemu-utils, etc.) inside
the builder VM before running the build.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-15 18:01:49 +01:00
|
|
|
disk 50
|
Add builder VM support for cross-platform and unprivileged builds
Introduce the forge-builder crate that automatically delegates builds to
an ephemeral VM when the host can't build locally (e.g., QCOW2 targets
without root, or OmniOS images on Linux). The builder detects these
conditions, spins up a VM via vm-manager with user-mode networking,
uploads inputs, streams the remote build output, and retrieves artifacts.
Key changes:
- New forge-builder crate with detection, binary resolution, VM lifecycle
management, file transfer, and miette diagnostic errors
- BuilderNode added to spec-parser schema for per-spec VM config
- --local and --use-builder CLI flags on the build command
- Feature-gated (default on) integration in forger CLI
- Fix ext4 QCOW2 grub-install failure by using absolute paths in chroot
- Improve debootstrap to pass --components and write full sources.list
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-15 17:17:30 +01:00
|
|
|
}
|
|
|
|
|
"#;
|
|
|
|
|
|
|
|
|
|
let spec = parse(kdl).expect("Failed to parse KDL");
|
|
|
|
|
let builder = spec.builder.as_ref().unwrap();
|
|
|
|
|
assert_eq!(builder.image.as_deref(), Some("oci://ghcr.io/custom/builder:v1"));
|
|
|
|
|
assert_eq!(builder.vcpus, Some(4));
|
|
|
|
|
assert_eq!(builder.memory, Some(4096));
|
Fix builder VM disk sizing, rootfs copy, and diagnostics
- Add disk_gb field to BuilderNode/BuilderConfig with 20GB default,
fixing debootstrap failure caused by 2GB cloud image running out of
space. Cloud-init growpart/resize_rootfs expand the partition.
- Replace walkdir-based copy_rootfs with cp -a to preserve symlinks,
fixing grub-install failure caused by broken merged-/usr symlinks
(/lib, /bin, /sbin -> /usr/*) in modern Ubuntu.
- Add network verification step that checks DNS before building and
auto-fixes resolv.conf with SLIRP DNS (10.0.2.3) if needed.
- Add diagnostic collection on failure (debootstrap log, resolv.conf,
disk space) before VM teardown.
- Include build stderr/stdout in RemoteBuildFailed error for better
error reporting.
- Install build dependencies (debootstrap, qemu-utils, etc.) inside
the builder VM before running the build.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-15 18:01:49 +01:00
|
|
|
assert_eq!(builder.disk, Some(50));
|
Add builder VM support for cross-platform and unprivileged builds
Introduce the forge-builder crate that automatically delegates builds to
an ephemeral VM when the host can't build locally (e.g., QCOW2 targets
without root, or OmniOS images on Linux). The builder detects these
conditions, spins up a VM via vm-manager with user-mode networking,
uploads inputs, streams the remote build output, and retrieves artifacts.
Key changes:
- New forge-builder crate with detection, binary resolution, VM lifecycle
management, file transfer, and miette diagnostic errors
- BuilderNode added to spec-parser schema for per-spec VM config
- --local and --use-builder CLI flags on the build command
- Feature-gated (default on) integration in forger CLI
- Fix ext4 QCOW2 grub-install failure by using absolute paths in chroot
- Improve debootstrap to pass --components and write full sources.list
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-15 17:17:30 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
|
fn test_parse_builder_node_partial() {
|
|
|
|
|
let kdl = r#"
|
|
|
|
|
metadata name="test" version="0.1.0"
|
|
|
|
|
repositories {}
|
|
|
|
|
builder {
|
|
|
|
|
vcpus 8
|
|
|
|
|
}
|
|
|
|
|
"#;
|
|
|
|
|
|
|
|
|
|
let spec = parse(kdl).expect("Failed to parse KDL");
|
|
|
|
|
let builder = spec.builder.as_ref().unwrap();
|
|
|
|
|
assert_eq!(builder.image, None);
|
|
|
|
|
assert_eq!(builder.vcpus, Some(8));
|
|
|
|
|
assert_eq!(builder.memory, None);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
|
fn test_parse_builder_node_empty() {
|
|
|
|
|
let kdl = r#"
|
|
|
|
|
metadata name="test" version="0.1.0"
|
|
|
|
|
repositories {}
|
|
|
|
|
builder {
|
|
|
|
|
}
|
|
|
|
|
"#;
|
|
|
|
|
|
|
|
|
|
let spec = parse(kdl).expect("Failed to parse KDL");
|
|
|
|
|
let builder = spec.builder.as_ref().unwrap();
|
|
|
|
|
assert_eq!(builder.image, None);
|
|
|
|
|
assert_eq!(builder.vcpus, None);
|
|
|
|
|
assert_eq!(builder.memory, None);
|
Fix builder VM disk sizing, rootfs copy, and diagnostics
- Add disk_gb field to BuilderNode/BuilderConfig with 20GB default,
fixing debootstrap failure caused by 2GB cloud image running out of
space. Cloud-init growpart/resize_rootfs expand the partition.
- Replace walkdir-based copy_rootfs with cp -a to preserve symlinks,
fixing grub-install failure caused by broken merged-/usr symlinks
(/lib, /bin, /sbin -> /usr/*) in modern Ubuntu.
- Add network verification step that checks DNS before building and
auto-fixes resolv.conf with SLIRP DNS (10.0.2.3) if needed.
- Add diagnostic collection on failure (debootstrap log, resolv.conf,
disk space) before VM teardown.
- Include build stderr/stdout in RemoteBuildFailed error for better
error reporting.
- Install build dependencies (debootstrap, qemu-utils, etc.) inside
the builder VM before running the build.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-15 18:01:49 +01:00
|
|
|
assert_eq!(builder.disk, None);
|
Add builder VM support for cross-platform and unprivileged builds
Introduce the forge-builder crate that automatically delegates builds to
an ephemeral VM when the host can't build locally (e.g., QCOW2 targets
without root, or OmniOS images on Linux). The builder detects these
conditions, spins up a VM via vm-manager with user-mode networking,
uploads inputs, streams the remote build output, and retrieves artifacts.
Key changes:
- New forge-builder crate with detection, binary resolution, VM lifecycle
management, file transfer, and miette diagnostic errors
- BuilderNode added to spec-parser schema for per-spec VM config
- --local and --use-builder CLI flags on the build command
- Feature-gated (default on) integration in forger CLI
- Fix ext4 QCOW2 grub-install failure by using absolute paths in chroot
- Improve debootstrap to pass --components and write full sources.list
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-15 17:17:30 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
|
fn test_parse_no_builder_node() {
|
|
|
|
|
let kdl = r#"
|
|
|
|
|
metadata name="test" version="0.1.0"
|
|
|
|
|
repositories {}
|
|
|
|
|
"#;
|
|
|
|
|
|
|
|
|
|
let spec = parse(kdl).expect("Failed to parse KDL");
|
|
|
|
|
assert!(spec.builder.is_none());
|
|
|
|
|
}
|
2026-02-15 15:30:22 +01:00
|
|
|
}
|