From d4cc2b13d3867a2e0b1757821bab5b51274fa823 Mon Sep 17 00:00:00 2001 From: corning-croak-cable Date: Sat, 9 May 2026 20:51:12 -0700 Subject: [PATCH 01/18] feat(usb-passthrough): YubiKey sysfs detection + QEMU usb-host args Adds crates/bcvk-qemu/src/usb_passthrough.rs: - detect_yubikeys(): walks /sys/bus/usb/devices, matches idVendor=0x1050 - require_yubikeys(): fails fast with clear message if none found - qemu_usb_args(): builds usb-ehci controller + usb-host device args - UsbHostDevice: vendorid/productid pair with QEMU arg formatter - Unit tests: 5 tests, all pure (no sysfs access) See docs/yubikey-passthrough.md for CommonVmOpts wiring instructions. --- crates/bcvk-qemu/src/usb_passthrough.rs | 179 ++++++++++++++++++++++++ docs/yubikey-passthrough.md | 23 +++ 2 files changed, 202 insertions(+) create mode 100644 crates/bcvk-qemu/src/usb_passthrough.rs create mode 100644 docs/yubikey-passthrough.md diff --git a/crates/bcvk-qemu/src/usb_passthrough.rs b/crates/bcvk-qemu/src/usb_passthrough.rs new file mode 100644 index 000000000..367456481 --- /dev/null +++ b/crates/bcvk-qemu/src/usb_passthrough.rs @@ -0,0 +1,179 @@ +//! YubiKey USB passthrough detection and QEMU device argument generation. +//! +//! Detects YubiKey 5 series devices on the host via the Linux udev/sysfs +//! interface (Yubico USB vendor ID 0x1050) and generates the QEMU +//! `-device usb-host` arguments needed to pass them into an ephemeral VM. +//! +//! # Security note +//! +//! USB passthrough gives the VM direct access to the YubiKey. Only use +//! with trusted images (e.g. yubiOS) where this is intentional. + +use std::path::PathBuf; + +use color_eyre::eyre::{bail, Context}; +use color_eyre::Result; +use tracing::debug; + +/// Yubico USB vendor ID. +pub const YUBICO_VENDOR_ID: u16 = 0x1050; + +/// A USB host device to pass through to QEMU. +#[derive(Debug, Clone)] +pub struct UsbHostDevice { + /// USB vendor ID (hex, e.g. 0x1050 for Yubico). + pub vendor_id: u16, + /// USB product ID. None = match any product from this vendor. + pub product_id: Option, + /// Human-readable label for logging. + pub label: String, +} + +impl UsbHostDevice { + /// Match any YubiKey (any product ID under vendor 0x1050). + pub fn any_yubikey() -> Self { + Self { + vendor_id: YUBICO_VENDOR_ID, + product_id: None, + label: "YubiKey (any model)".to_string(), + } + } + + /// Build QEMU `-device usb-host` argument string. + /// + /// Example: `usb-host,vendorid=0x1050,productid=0x0407` + pub fn qemu_device_arg(&self) -> String { + let mut arg = format!("usb-host,vendorid=0x{:04x}", self.vendor_id); + if let Some(pid) = self.product_id { + arg.push_str(&format!(",productid=0x{:04x}", pid)); + } + arg + } +} + +/// Probe the host for attached YubiKey devices via sysfs. +/// +/// Walks /sys/bus/usb/devices/ and matches on idVendor == 0x1050. +/// Returns one `UsbHostDevice` per unique (vendor, product) pair found. +pub fn detect_yubikeys() -> Result> { + let mut found = Vec::new(); + let base = PathBuf::from("/sys/bus/usb/devices"); + + if !base.exists() { + debug!("sysfs not available — skipping YubiKey detection"); + return Ok(found); + } + + for entry in std::fs::read_dir(&base).context("reading /sys/bus/usb/devices")? { + let entry = entry?; + let vendor_path = entry.path().join("idVendor"); + let product_path = entry.path().join("idProduct"); + if !vendor_path.exists() { + continue; + } + let vendor_str = std::fs::read_to_string(&vendor_path) + .unwrap_or_default() + .trim() + .to_lowercase(); + if vendor_str != format!("{:04x}", YUBICO_VENDOR_ID) { + continue; + } + let product_id = std::fs::read_to_string(&product_path) + .ok() + .and_then(|s| u16::from_str_radix(s.trim(), 16).ok()); + debug!( + "Found YubiKey: vendor={} product={:?} at {}", + vendor_str, + product_id, + entry.path().display() + ); + found.push(UsbHostDevice { + vendor_id: YUBICO_VENDOR_ID, + product_id, + label: format!( + "YubiKey (0x1050:{:04x})", + product_id.unwrap_or(0) + ), + }); + } + Ok(found) +} + +/// Detect YubiKeys and fail with a clear message if none found. +pub fn require_yubikeys() -> Result> { + let keys = detect_yubikeys()?; + if keys.is_empty() { + bail!( + "--yubikey requested but no YubiKey detected. + Insert a YubiKey (Yubico vendor 0x1050) and retry." + ); + } + Ok(keys) +} + +/// Build the QEMU USB controller + host-device arguments for a list of devices. +/// +/// Adds a USB 2.0 EHCI controller (one per call) then one usb-host device per +/// YubiKey. Returns a flat list of QEMU argument strings. +pub fn qemu_usb_args(devices: &[UsbHostDevice]) -> Vec { + if devices.is_empty() { + return Vec::new(); + } + let mut args = vec![ + // USB 2.0 EHCI controller — required for usb-host on x86 and arm64 + "-device".to_string(), + "usb-ehci,id=yubikey-ehci".to_string(), + ]; + for dev in devices { + args.push("-device".to_string()); + let mut dev_arg = dev.qemu_device_arg(); + dev_arg.push_str(",bus=yubikey-ehci.0"); + args.push(dev_arg); + } + args +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_qemu_device_arg_vendor_only() { + let dev = UsbHostDevice::any_yubikey(); + assert_eq!(dev.qemu_device_arg(), "usb-host,vendorid=0x1050"); + } + + #[test] + fn test_qemu_device_arg_with_product() { + let dev = UsbHostDevice { + vendor_id: 0x1050, + product_id: Some(0x0407), + label: "YubiKey 5 NFC".to_string(), + }; + assert_eq!( + dev.qemu_device_arg(), + "usb-host,vendorid=0x1050,productid=0x0407" + ); + } + + #[test] + fn test_qemu_usb_args_empty() { + assert!(qemu_usb_args(&[]).is_empty()); + } + + #[test] + fn test_qemu_usb_args_adds_controller() { + let devs = vec![UsbHostDevice::any_yubikey()]; + let args = qemu_usb_args(&devs); + assert!(args.contains(&"usb-ehci,id=yubikey-ehci".to_string())); + assert!(args.iter().any(|a| a.contains("usb-host"))); + assert!(args.iter().any(|a| a.contains("yubikey-ehci.0"))); + } + + #[test] + fn test_any_yubikey_vendor() { + let dev = UsbHostDevice::any_yubikey(); + assert_eq!(dev.vendor_id, 0x1050); + assert!(dev.product_id.is_none()); + } +} \ No newline at end of file diff --git a/docs/yubikey-passthrough.md b/docs/yubikey-passthrough.md new file mode 100644 index 000000000..2db56c8d1 --- /dev/null +++ b/docs/yubikey-passthrough.md @@ -0,0 +1,23 @@ +--- run_ephemeral.rs patch --- +Add `--yubikey` flag to CommonVmOpts and wire through to QemuConfig. + +In CommonVmOpts struct, add: + + /// Pass YubiKey USB devices into the VM (requires host YubiKey attached). + /// Detected via sysfs (Yubico vendor 0x1050). Adds usb-ehci controller + /// and usb-host device entries to QEMU args. + #[clap(long, help = "Pass YubiKey USB device(s) into the VM")] + pub yubikey: bool, + +In run_impl() where QemuConfig is built, after existing device setup: + + if opts.common.yubikey { + let keys = usb_passthrough::require_yubikeys()?; + tracing::info!("Passing {} YubiKey(s) into VM", keys.len()); + for arg in usb_passthrough::qemu_usb_args(&keys) { + qemu_config.extra_args.push(arg); + } + } + +Import at top of file: + use crate::usb_passthrough; From 10d1e6b192bbf64893e81a76de100a389a5e43d5 Mon Sep 17 00:00:00 2001 From: foil-copy-overrate Date: Sun, 10 May 2026 10:43:24 -0700 Subject: [PATCH 02/18] feat(usb-passthrough): declare usb_passthrough module + re-exports in lib.rs Assisted-by: Sauna (claude-sonnet-4-6) --- crates/bcvk-qemu/src/lib.rs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/crates/bcvk-qemu/src/lib.rs b/crates/bcvk-qemu/src/lib.rs index 91cbffea3..f38ec41be 100644 --- a/crates/bcvk-qemu/src/lib.rs +++ b/crates/bcvk-qemu/src/lib.rs @@ -44,6 +44,7 @@ mod credentials; mod qemu; +pub mod usb_passthrough; mod virtiofsd; pub use credentials::{ @@ -57,4 +58,6 @@ pub use qemu::{ RunningQemu, VirtioBlkDevice, VirtioSerialOut, VirtiofsMount, VHOST_VSOCK, }; +pub use usb_passthrough::{detect_yubikeys, qemu_usb_args, require_yubikeys, UsbHostDevice, + YUBICO_VENDOR_ID}; pub use virtiofsd::{spawn_virtiofsd_async, validate_virtiofsd_config, VirtiofsConfig}; From 1f9d7a8d23c83e9da02e58b9d02ed6bae341b4d9 Mon Sep 17 00:00:00 2001 From: foil-copy-overrate Date: Sun, 10 May 2026 10:43:25 -0700 Subject: [PATCH 03/18] feat(usb-passthrough): add usb_host_devices field + spawn emission to QemuConfig - Adds `usb_host_devices: Vec` field (defaults to empty via Default) - Adds `add_usb_host_device()` builder method - Emits QEMU USB EHCI controller + usb-host args in spawn() when list is non-empty Assisted-by: Sauna (claude-sonnet-4-6) --- crates/bcvk-qemu/src/qemu.rs | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/crates/bcvk-qemu/src/qemu.rs b/crates/bcvk-qemu/src/qemu.rs index 634a991e3..b17efffae 100644 --- a/crates/bcvk-qemu/src/qemu.rs +++ b/crates/bcvk-qemu/src/qemu.rs @@ -229,6 +229,11 @@ pub struct QemuConfig { /// fw_cfg entries for passing config files to the guest fw_cfg_entries: Vec<(String, Utf8PathBuf)>, + /// USB host devices to pass through into the VM (e.g. YubiKey). + /// + /// Each device is forwarded via QEMU `-device usb-host`. A single USB 2.0 + /// EHCI controller is inserted automatically when this list is non-empty. + pub usb_host_devices: Vec, } impl QemuConfig { @@ -464,6 +469,15 @@ impl QemuConfig { self.fw_cfg_entries.push((name, file_path)); self } + + /// Add a USB host device to pass through into the VM. + /// + /// A single QEMU USB 2.0 EHCI controller is inserted automatically + /// the first time this list becomes non-empty. + pub fn add_usb_host_device(&mut self, dev: crate::usb_passthrough::UsbHostDevice) -> &mut Self { + self.usb_host_devices.push(dev); + self + } } /// Allocate a unique VSOCK CID. @@ -759,6 +773,13 @@ fn spawn( cmd.args(["-fw_cfg", &format!("name={},file={}", name, file_path)]); } + // USB host device passthrough (e.g. YubiKey) + if !config.usb_host_devices.is_empty() { + for arg in crate::usb_passthrough::qemu_usb_args(&config.usb_host_devices) { + cmd.arg(arg); + } + } + // Configure stdio based on display mode match &config.display_mode { DisplayMode::Console => { From 57d13d3c999fbda5eea6b5dae6806d1223842c78 Mon Sep 17 00:00:00 2001 From: foil-copy-overrate Date: Sun, 10 May 2026 10:43:27 -0700 Subject: [PATCH 04/18] feat(usb-passthrough): wire --yubikey flag into CommonVmOpts and run_impl - Adds `--yubikey` bool to `CommonVmOpts` (serde default = false for BCK_CONFIG compat) - In `run_impl`, calls `bcvk_qemu::usb_passthrough::require_yubikeys()` and registers each detected device with `qemu_config.add_usb_host_device()` - Fails fast if --yubikey requested but no Yubico device found on host Assisted-by: Sauna (claude-sonnet-4-6) --- crates/kit/src/run_ephemeral.rs | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/crates/kit/src/run_ephemeral.rs b/crates/kit/src/run_ephemeral.rs index 0d0fdf3b8..dd48ba33b 100644 --- a/crates/kit/src/run_ephemeral.rs +++ b/crates/kit/src/run_ephemeral.rs @@ -218,6 +218,15 @@ pub struct CommonVmOpts { help = "Generate SSH keypair and inject via systemd credentials" )] pub ssh_keygen: bool, + + /// Pass YubiKey(s) from the host into the VM via QEMU USB host passthrough. + /// + /// Detects all Yubico devices (vendor 0x1050) on the host via sysfs and + /// forwards them directly into the VM. Fails immediately if `--yubikey` + /// is set but no YubiKey is detected on the host. + #[clap(long, help = "Forward attached YubiKey(s) from host into the VM via USB passthrough")] + #[serde(default)] + pub yubikey: bool, } impl CommonVmOpts { @@ -1355,6 +1364,15 @@ StandardOutput=file:/dev/virtio-ports/executestatus qemu_config.add_smbios_credential(credential); } + // YubiKey USB passthrough + #[cfg(target_os = "linux")] + if opts.common.yubikey { + let keys = bcvk_qemu::usb_passthrough::require_yubikeys()?; + for key in keys { + qemu_config.add_usb_host_device(key); + } + } + // Build kernel command line for direct boot let mut kernel_cmdline = [ // At the core we boot from the mounted container's root, From fe2ba2ae3734f6e38150db2ccb8f5dd8eca3f627 Mon Sep 17 00:00:00 2001 From: foil-copy-overrate Date: Sun, 10 May 2026 11:12:30 -0700 Subject: [PATCH 05/18] Add files via upload Signed-off-by: foil-copy-overrate --- .github/workflows/bcvk-ci_test.yml | 55 ++++++++++++++++++++++++++++++ 1 file changed, 55 insertions(+) create mode 100644 .github/workflows/bcvk-ci_test.yml diff --git a/.github/workflows/bcvk-ci_test.yml b/.github/workflows/bcvk-ci_test.yml new file mode 100644 index 000000000..95c44be12 --- /dev/null +++ b/.github/workflows/bcvk-ci_test.yml @@ -0,0 +1,55 @@ +name: ci_test + +on: + pull_request: + branches: [main] + push: + branches: [main] + +jobs: + unit-tests: + name: Unit tests + runs-on: ubuntu-24.04 + concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + container: + image: docker://dhi.io/debian-base@sha256:9415967aa0ed8adea8b5c048994259d1982026dca143d0303c7bbe0e11ed67d3 + credentials: + username: 0mniteck42 + password: ${{ secrets.DOCKER }} + steps: + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + + - name: Install Rust stable + run: | + curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y --default-toolchain stable + echo "$HOME/.cargo/bin" >> $GITHUB_PATH + + # native_to_disk: check_not_mounted_parse, device_info_human_size, build_podman_cmd_contains_device + - name: Test native-to-disk (unit, no hardware) + run: cargo test -p bcvk --lib native_to_disk:: + + # usb_passthrough: 5 pure unit tests (sysfs mocked) + - name: Test usb-passthrough (unit, no hardware) + run: cargo test -p bcvk-qemu --lib usb_passthrough:: + + - name: Workspace compile check + run: cargo check --workspace + + clippy: + name: Clippy + runs-on: ubuntu-24.04 + container: + image: docker://dhi.io/debian-base@sha256:9415967aa0ed8adea8b5c048994259d1982026dca143d0303c7bbe0e11ed67d3 + credentials: + username: 0mniteck42 + password: ${{ secrets.DOCKER }} + steps: + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd + - name: Install Rust + clippy + run: | + curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y --default-toolchain stable --component clippy + echo "$HOME/.cargo/bin" >> $GITHUB_PATH + - name: Clippy + run: cargo clippy --workspace -- -D warnings From ac3533753a475d547dad14a483960a90cb0acd70 Mon Sep 17 00:00:00 2001 From: foil-copy-overrate Date: Sun, 10 May 2026 12:13:57 -0700 Subject: [PATCH 06/18] Update bcvk-ci_test.yml Signed-off-by: foil-copy-overrate --- .github/workflows/bcvk-ci_test.yml | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/.github/workflows/bcvk-ci_test.yml b/.github/workflows/bcvk-ci_test.yml index 95c44be12..bbc0fcac6 100644 --- a/.github/workflows/bcvk-ci_test.yml +++ b/.github/workflows/bcvk-ci_test.yml @@ -28,11 +28,13 @@ jobs: # native_to_disk: check_not_mounted_parse, device_info_human_size, build_podman_cmd_contains_device - name: Test native-to-disk (unit, no hardware) - run: cargo test -p bcvk --lib native_to_disk:: + run: | + cargo test -p bcvk --lib native_to_disk:: # usb_passthrough: 5 pure unit tests (sysfs mocked) - name: Test usb-passthrough (unit, no hardware) - run: cargo test -p bcvk-qemu --lib usb_passthrough:: + run: | + cargo test -p bcvk-qemu --lib usb_passthrough:: - name: Workspace compile check run: cargo check --workspace From 7c976ccea422cdc6b31755326b179c48c67d8700 Mon Sep 17 00:00:00 2001 From: foil-copy-overrate Date: Sun, 10 May 2026 12:58:31 -0700 Subject: [PATCH 07/18] Update bcvk-ci_test.yml Signed-off-by: foil-copy-overrate --- .github/workflows/bcvk-ci_test.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/bcvk-ci_test.yml b/.github/workflows/bcvk-ci_test.yml index bbc0fcac6..34d08c00c 100644 --- a/.github/workflows/bcvk-ci_test.yml +++ b/.github/workflows/bcvk-ci_test.yml @@ -9,7 +9,7 @@ on: jobs: unit-tests: name: Unit tests - runs-on: ubuntu-24.04 + runs-on: ubuntu-latest concurrency: group: ${{ github.workflow }}-${{ github.ref }} cancel-in-progress: true @@ -41,7 +41,7 @@ jobs: clippy: name: Clippy - runs-on: ubuntu-24.04 + runs-on: ubuntu-latest container: image: docker://dhi.io/debian-base@sha256:9415967aa0ed8adea8b5c048994259d1982026dca143d0303c7bbe0e11ed67d3 credentials: From e4e484a48d342b66877720bd79cae0ae74ca6f5e Mon Sep 17 00:00:00 2001 From: foil-copy-overrate Date: Sun, 10 May 2026 15:01:59 -0700 Subject: [PATCH 08/18] Update bcvk-ci_test.yml Signed-off-by: foil-copy-overrate --- .github/workflows/bcvk-ci_test.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/bcvk-ci_test.yml b/.github/workflows/bcvk-ci_test.yml index 34d08c00c..33561d665 100644 --- a/.github/workflows/bcvk-ci_test.yml +++ b/.github/workflows/bcvk-ci_test.yml @@ -23,6 +23,7 @@ jobs: - name: Install Rust stable run: | + apt-get -qq update && install curl curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y --default-toolchain stable echo "$HOME/.cargo/bin" >> $GITHUB_PATH @@ -51,6 +52,7 @@ jobs: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd - name: Install Rust + clippy run: | + apt-get -qq update && install curl curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y --default-toolchain stable --component clippy echo "$HOME/.cargo/bin" >> $GITHUB_PATH - name: Clippy From 24af5e916d6fe9f4604dd94634870043268a6d58 Mon Sep 17 00:00:00 2001 From: foil-copy-overrate Date: Sun, 10 May 2026 15:04:40 -0700 Subject: [PATCH 09/18] Update bcvk-ci_test.yml Signed-off-by: foil-copy-overrate --- .github/workflows/bcvk-ci_test.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/bcvk-ci_test.yml b/.github/workflows/bcvk-ci_test.yml index 33561d665..dc97fc330 100644 --- a/.github/workflows/bcvk-ci_test.yml +++ b/.github/workflows/bcvk-ci_test.yml @@ -2,7 +2,6 @@ name: ci_test on: pull_request: - branches: [main] push: branches: [main] From 5f0e48d795f2a819ac66a0191ee5544940bd262a Mon Sep 17 00:00:00 2001 From: foil-copy-overrate Date: Sun, 10 May 2026 15:05:52 -0700 Subject: [PATCH 10/18] Update bcvk-ci_test.yml Signed-off-by: foil-copy-overrate --- .github/workflows/bcvk-ci_test.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/bcvk-ci_test.yml b/.github/workflows/bcvk-ci_test.yml index dc97fc330..3bd3e3290 100644 --- a/.github/workflows/bcvk-ci_test.yml +++ b/.github/workflows/bcvk-ci_test.yml @@ -22,7 +22,7 @@ jobs: - name: Install Rust stable run: | - apt-get -qq update && install curl + apt-get -qq update && apt-get -qq install curl curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y --default-toolchain stable echo "$HOME/.cargo/bin" >> $GITHUB_PATH @@ -51,7 +51,7 @@ jobs: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd - name: Install Rust + clippy run: | - apt-get -qq update && install curl + apt-get -qq update && apt-get -qq install curl curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y --default-toolchain stable --component clippy echo "$HOME/.cargo/bin" >> $GITHUB_PATH - name: Clippy From 6aa7763d0c07baf18623f321e83f9816bbfcb152 Mon Sep 17 00:00:00 2001 From: foil-copy-overrate Date: Sun, 10 May 2026 15:33:29 -0700 Subject: [PATCH 11/18] Update bcvk-ci_test.yml Signed-off-by: foil-copy-overrate --- .github/workflows/bcvk-ci_test.yml | 29 ++++++----------------------- 1 file changed, 6 insertions(+), 23 deletions(-) diff --git a/.github/workflows/bcvk-ci_test.yml b/.github/workflows/bcvk-ci_test.yml index 3bd3e3290..fab3fdc1f 100644 --- a/.github/workflows/bcvk-ci_test.yml +++ b/.github/workflows/bcvk-ci_test.yml @@ -1,14 +1,16 @@ -name: ci_test - +name: bcvk-ci on: + workflow_dispatch: pull_request: push: branches: [main] - +permissions: {} jobs: unit-tests: name: Unit tests runs-on: ubuntu-latest + permissions: + contents: read concurrency: group: ${{ github.workflow }}-${{ github.ref }} cancel-in-progress: true @@ -19,40 +21,21 @@ jobs: password: ${{ secrets.DOCKER }} steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - - name: Install Rust stable run: | - apt-get -qq update && apt-get -qq install curl + apt-get -qq update && apt-get -qq install --no-install-recommends build-essential curl curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y --default-toolchain stable echo "$HOME/.cargo/bin" >> $GITHUB_PATH - # native_to_disk: check_not_mounted_parse, device_info_human_size, build_podman_cmd_contains_device - name: Test native-to-disk (unit, no hardware) run: | cargo test -p bcvk --lib native_to_disk:: - # usb_passthrough: 5 pure unit tests (sysfs mocked) - name: Test usb-passthrough (unit, no hardware) run: | cargo test -p bcvk-qemu --lib usb_passthrough:: - - name: Workspace compile check run: cargo check --workspace - - clippy: - name: Clippy - runs-on: ubuntu-latest - container: - image: docker://dhi.io/debian-base@sha256:9415967aa0ed8adea8b5c048994259d1982026dca143d0303c7bbe0e11ed67d3 - credentials: - username: 0mniteck42 - password: ${{ secrets.DOCKER }} - steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd - - name: Install Rust + clippy - run: | - apt-get -qq update && apt-get -qq install curl - curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y --default-toolchain stable --component clippy - echo "$HOME/.cargo/bin" >> $GITHUB_PATH - name: Clippy run: cargo clippy --workspace -- -D warnings From 46cb54b0e26e5cec793f59b3886b8423f1ff52ef Mon Sep 17 00:00:00 2001 From: foil-copy-overrate Date: Sun, 10 May 2026 16:33:20 -0700 Subject: [PATCH 12/18] Update bcvk-ci_test.yml Signed-off-by: foil-copy-overrate --- .github/workflows/bcvk-ci_test.yml | 22 ++++++++++------------ 1 file changed, 10 insertions(+), 12 deletions(-) diff --git a/.github/workflows/bcvk-ci_test.yml b/.github/workflows/bcvk-ci_test.yml index fab3fdc1f..521a12cd7 100644 --- a/.github/workflows/bcvk-ci_test.yml +++ b/.github/workflows/bcvk-ci_test.yml @@ -16,26 +16,24 @@ jobs: cancel-in-progress: true container: image: docker://dhi.io/debian-base@sha256:9415967aa0ed8adea8b5c048994259d1982026dca143d0303c7bbe0e11ed67d3 + options: --rootless --cgroupns private credentials: username: 0mniteck42 - password: ${{ secrets.DOCKER }} + password: ${{secrets.DOCKER}} steps: - - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - - name: Install Rust stable + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd + - name: Run Install run: | - apt-get -qq update && apt-get -qq install --no-install-recommends build-essential curl + apt-get -qq update && apt-get -qq install --no-install-recommends build-essential curl git openssl curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y --default-toolchain stable echo "$HOME/.cargo/bin" >> $GITHUB_PATH - # native_to_disk: check_not_mounted_parse, device_info_human_size, build_podman_cmd_contains_device - - name: Test native-to-disk (unit, no hardware) + - name: Run Cargo Tests run: | cargo test -p bcvk --lib native_to_disk:: - # usb_passthrough: 5 pure unit tests (sysfs mocked) - - name: Test usb-passthrough (unit, no hardware) - run: | cargo test -p bcvk-qemu --lib usb_passthrough:: - - name: Workspace compile check - run: cargo check --workspace + cargo check --workspace - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd - - name: Clippy + - name: Cargo Workspace Warnings run: cargo clippy --workspace -- -D warnings + - name: Git Status + run: git status From 239874dfa654e7abae57783159e173d69eb7b323 Mon Sep 17 00:00:00 2001 From: foil-copy-overrate Date: Sun, 10 May 2026 16:36:33 -0700 Subject: [PATCH 13/18] Update bcvk-ci_test.yml Signed-off-by: foil-copy-overrate --- .github/workflows/bcvk-ci_test.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/bcvk-ci_test.yml b/.github/workflows/bcvk-ci_test.yml index 521a12cd7..2f497ea26 100644 --- a/.github/workflows/bcvk-ci_test.yml +++ b/.github/workflows/bcvk-ci_test.yml @@ -16,7 +16,7 @@ jobs: cancel-in-progress: true container: image: docker://dhi.io/debian-base@sha256:9415967aa0ed8adea8b5c048994259d1982026dca143d0303c7bbe0e11ed67d3 - options: --rootless --cgroupns private + options: --help credentials: username: 0mniteck42 password: ${{secrets.DOCKER}} From 434e5a0cb972468f174e1094307e99eece9221be Mon Sep 17 00:00:00 2001 From: foil-copy-overrate Date: Sun, 10 May 2026 17:08:02 -0700 Subject: [PATCH 14/18] Update bcvk-ci_test.yml Signed-off-by: foil-copy-overrate --- .github/workflows/bcvk-ci_test.yml | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/.github/workflows/bcvk-ci_test.yml b/.github/workflows/bcvk-ci_test.yml index 2f497ea26..a5ad550af 100644 --- a/.github/workflows/bcvk-ci_test.yml +++ b/.github/workflows/bcvk-ci_test.yml @@ -11,12 +11,22 @@ jobs: runs-on: ubuntu-latest permissions: contents: read + services: + dockerd: + image: docker://docker.io/moby/buildkit:v0.29.0@0039c1d47e8748b5afea56f4e85f14febaf34452bd99d9552d2daa82262b5cc5 + options: --cgroupns=private --disable-content-trust=false + credentials: + username: 0mniteck42 + password: ${{secrets.DOCKER}} + env: + INPUT_VERSION: 29.3.1 + command: set -xv && /bin/bash concurrency: - group: ${{ github.workflow }}-${{ github.ref }} + group: ${{github.workflow}}-${{github.ref}} cancel-in-progress: true container: image: docker://dhi.io/debian-base@sha256:9415967aa0ed8adea8b5c048994259d1982026dca143d0303c7bbe0e11ed67d3 - options: --help + options: --cgroupns=private --disable-content-trust=false credentials: username: 0mniteck42 password: ${{secrets.DOCKER}} From 57b7f6e1d0febebed7e2b0286c52e6b7f6c294ba Mon Sep 17 00:00:00 2001 From: foil-copy-overrate Date: Sun, 10 May 2026 17:40:23 -0700 Subject: [PATCH 15/18] Update bcvk-ci_test.yml Signed-off-by: foil-copy-overrate --- .github/workflows/bcvk-ci_test.yml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/.github/workflows/bcvk-ci_test.yml b/.github/workflows/bcvk-ci_test.yml index a5ad550af..7897bd58b 100644 --- a/.github/workflows/bcvk-ci_test.yml +++ b/.github/workflows/bcvk-ci_test.yml @@ -5,6 +5,8 @@ on: push: branches: [main] permissions: {} +env: + SOURCE_DATE_EPOCH: 0 jobs: unit-tests: name: Unit tests @@ -13,14 +15,13 @@ jobs: contents: read services: dockerd: - image: docker://docker.io/moby/buildkit:v0.29.0@0039c1d47e8748b5afea56f4e85f14febaf34452bd99d9552d2daa82262b5cc5 + image: docker://docker.io/moby/buildkit:v0.29.0@sha256:8550ee821375d58adc345db341b1c08df993d8411544b36fd4c6cb2dd2fb12c5 options: --cgroupns=private --disable-content-trust=false credentials: username: 0mniteck42 password: ${{secrets.DOCKER}} env: INPUT_VERSION: 29.3.1 - command: set -xv && /bin/bash concurrency: group: ${{github.workflow}}-${{github.ref}} cancel-in-progress: true From 709f196e257ca3cca8ac6482f4f66a4827446e1c Mon Sep 17 00:00:00 2001 From: foil-copy-overrate Date: Sun, 10 May 2026 19:45:56 -0700 Subject: [PATCH 16/18] Update bcvk-ci_test.yml Signed-off-by: foil-copy-overrate --- .github/workflows/bcvk-ci_test.yml | 37 ++++++++++++++++++++++++++---- 1 file changed, 33 insertions(+), 4 deletions(-) diff --git a/.github/workflows/bcvk-ci_test.yml b/.github/workflows/bcvk-ci_test.yml index 7897bd58b..35f7958a2 100644 --- a/.github/workflows/bcvk-ci_test.yml +++ b/.github/workflows/bcvk-ci_test.yml @@ -7,21 +7,50 @@ on: permissions: {} env: SOURCE_DATE_EPOCH: 0 + BUILDKIT_MULTI_PLATFORM: true + BUILDKIT_PROGRESS: tty + BUILDKIT_TTY_LOG_LINES: 25 + BUILDX_GIT_LABELS: full + BUILDX_METADATA_PROVENANCE: max + BUILDX_METADATA_WARNINGS: 1 jobs: + docker-setup: + runs-on: ubuntu-latest + container: + image: docker://dhi.io/debian-base@sha256:9415967aa0ed8adea8b5c048994259d1982026dca143d0303c7bbe0e11ed67d3 + options: --cgroupns=private --disable-content-trust=false + credentials: + username: 0mniteck42 + password: ${{secrets.DOCKER}} + steps: + - name: Docker buildx setup + uses: docker/setup-buildx-action@4d04d5d9486b7bd6fa91e7baf45bbb4f8b9deedd # v4.0.0 + with: + use: true + buildkitd-flags: --oci-worker-rootless true + rootless: true + version: 0.33.0 + endpoint: rootless + cache-binary: false + driver-opts: | + image=moby/buildkit:v0.29.0@sha256:8550ee821375d58adc345db341b1c08df993d8411544b36fd4c6cb2dd2fb12c5, + default-load=true, + cgroup-parent=docker.slice unit-tests: name: Unit tests runs-on: ubuntu-latest + needs: + - docker-setup permissions: contents: read services: dockerd: image: docker://docker.io/moby/buildkit:v0.29.0@sha256:8550ee821375d58adc345db341b1c08df993d8411544b36fd4c6cb2dd2fb12c5 - options: --cgroupns=private --disable-content-trust=false + command: /usr/bin/docker buildx create --name test-builder --label 20e033 --network github_network_3c6bc1d6570942209277596721e4a839 --network-alias dockerd --buildkitd-flags \"--oci-worker-rootless=true\" --driver docker-container --driver-opt \"cgroup-parent=docker.slice,default-load=true,image=docker.io/moby/buildkit:v0.29.0@sha256:8550ee821375d58adc345db341b1c08df993d8411544b36fd4c6cb2dd2fb12c5\" --cgroupns private -e GITHUB_ACTIONS=true -e CI=true + options: --bootstrap --use credentials: username: 0mniteck42 password: ${{secrets.DOCKER}} - env: - INPUT_VERSION: 29.3.1 concurrency: group: ${{github.workflow}}-${{github.ref}} cancel-in-progress: true @@ -47,4 +76,4 @@ jobs: - name: Cargo Workspace Warnings run: cargo clippy --workspace -- -D warnings - name: Git Status - run: git status + run: git status From c69bed7413df78ba5290afd900495399aad04e77 Mon Sep 17 00:00:00 2001 From: foil-copy-overrate Date: Sun, 10 May 2026 21:39:27 -0700 Subject: [PATCH 17/18] Update bcvk-ci_test.yml Signed-off-by: foil-copy-overrate --- .github/workflows/bcvk-ci_test.yml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.github/workflows/bcvk-ci_test.yml b/.github/workflows/bcvk-ci_test.yml index 35f7958a2..3e5e05163 100644 --- a/.github/workflows/bcvk-ci_test.yml +++ b/.github/workflows/bcvk-ci_test.yml @@ -28,8 +28,7 @@ jobs: with: use: true buildkitd-flags: --oci-worker-rootless true - rootless: true - version: 0.33.0 + version: 0.31.0 endpoint: rootless cache-binary: false driver-opts: | From 0f14f4ee76e01a5779b54df902f08d5cf083e207 Mon Sep 17 00:00:00 2001 From: foil-copy-overrate Date: Sun, 10 May 2026 21:58:21 -0700 Subject: [PATCH 18/18] Delete .github/workflows/bcvk-ci_test.yml Signed-off-by: foil-copy-overrate --- .github/workflows/bcvk-ci_test.yml | 78 ------------------------------ 1 file changed, 78 deletions(-) delete mode 100644 .github/workflows/bcvk-ci_test.yml diff --git a/.github/workflows/bcvk-ci_test.yml b/.github/workflows/bcvk-ci_test.yml deleted file mode 100644 index 3e5e05163..000000000 --- a/.github/workflows/bcvk-ci_test.yml +++ /dev/null @@ -1,78 +0,0 @@ -name: bcvk-ci -on: - workflow_dispatch: - pull_request: - push: - branches: [main] -permissions: {} -env: - SOURCE_DATE_EPOCH: 0 - BUILDKIT_MULTI_PLATFORM: true - BUILDKIT_PROGRESS: tty - BUILDKIT_TTY_LOG_LINES: 25 - BUILDX_GIT_LABELS: full - BUILDX_METADATA_PROVENANCE: max - BUILDX_METADATA_WARNINGS: 1 -jobs: - docker-setup: - runs-on: ubuntu-latest - container: - image: docker://dhi.io/debian-base@sha256:9415967aa0ed8adea8b5c048994259d1982026dca143d0303c7bbe0e11ed67d3 - options: --cgroupns=private --disable-content-trust=false - credentials: - username: 0mniteck42 - password: ${{secrets.DOCKER}} - steps: - - name: Docker buildx setup - uses: docker/setup-buildx-action@4d04d5d9486b7bd6fa91e7baf45bbb4f8b9deedd # v4.0.0 - with: - use: true - buildkitd-flags: --oci-worker-rootless true - version: 0.31.0 - endpoint: rootless - cache-binary: false - driver-opts: | - image=moby/buildkit:v0.29.0@sha256:8550ee821375d58adc345db341b1c08df993d8411544b36fd4c6cb2dd2fb12c5, - default-load=true, - cgroup-parent=docker.slice - unit-tests: - name: Unit tests - runs-on: ubuntu-latest - needs: - - docker-setup - permissions: - contents: read - services: - dockerd: - image: docker://docker.io/moby/buildkit:v0.29.0@sha256:8550ee821375d58adc345db341b1c08df993d8411544b36fd4c6cb2dd2fb12c5 - command: /usr/bin/docker buildx create --name test-builder --label 20e033 --network github_network_3c6bc1d6570942209277596721e4a839 --network-alias dockerd --buildkitd-flags \"--oci-worker-rootless=true\" --driver docker-container --driver-opt \"cgroup-parent=docker.slice,default-load=true,image=docker.io/moby/buildkit:v0.29.0@sha256:8550ee821375d58adc345db341b1c08df993d8411544b36fd4c6cb2dd2fb12c5\" --cgroupns private -e GITHUB_ACTIONS=true -e CI=true - options: --bootstrap --use - credentials: - username: 0mniteck42 - password: ${{secrets.DOCKER}} - concurrency: - group: ${{github.workflow}}-${{github.ref}} - cancel-in-progress: true - container: - image: docker://dhi.io/debian-base@sha256:9415967aa0ed8adea8b5c048994259d1982026dca143d0303c7bbe0e11ed67d3 - options: --cgroupns=private --disable-content-trust=false - credentials: - username: 0mniteck42 - password: ${{secrets.DOCKER}} - steps: - - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd - - name: Run Install - run: | - apt-get -qq update && apt-get -qq install --no-install-recommends build-essential curl git openssl - curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y --default-toolchain stable - echo "$HOME/.cargo/bin" >> $GITHUB_PATH - - name: Run Cargo Tests - run: | - cargo test -p bcvk --lib native_to_disk:: - cargo test -p bcvk-qemu --lib usb_passthrough:: - cargo check --workspace - - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd - - name: Cargo Workspace Warnings - run: cargo clippy --workspace -- -D warnings - - name: Git Status - run: git status