Skip to content

Support custom guest kernels - #1041

Merged
DorianZheng merged 3 commits into
mainfrom
agent/support-custom-kernel
Jul 26, 2026
Merged

DorianZheng merged 3 commits into
mainfrom
agent/support-custom-kernel

Conversation

@DorianZheng

@DorianZheng DorianZheng commented Jul 26, 2026 •

Copy link
Copy Markdown
Member

What

  • add typed custom-kernel and initramfs options under AdvancedBoxOptions
  • detect and validate supported kernel formats at the runtime boundary
  • stage boot artifacts into each box's read-only boot directory before configuring libkrun
  • expose advanced --kernel, --kernel-format, --initramfs, and --kernel-args CLI options for run and create
  • reject unsupported custom-kernel requests through the REST runtime
  • document the Rust and CLI interfaces

Why

This lets local BoxLite users boot guest kernels they provide without sending host paths through the shim or changing the default boot path.

Compatibility

Default behavior is unchanged. Custom kernels are opt-in and available only through the local runtime; existing CLI usage remains compatible.

Validation

  • make fmt:check
  • BOXLITE_DEPS_STUB=1 make clippy
  • Rust tests: 856 + 47 passed
  • Node tests: 71 passed
  • CLI non-VM tests: 166 passed
  • focused custom-kernel core and CLI tests passed

A real custom-kernel VM boot was not run in this environment because the native submodules and mke2fs are unavailable.

Summary by CodeRabbit

  • New Features
    • Added custom Linux kernel boot support with optional initramfs and kernel command-line arguments (via advanced boot options).
    • Extended the CLI with kernel-related flags (format selection, disk sizing, and required option relationships) for both boxlite run and boxlite create.
    • Introduced Rust configuration types for kernel settings and added optional health_check support.
  • Bug Fixes
    • REST runtime now rejects custom kernel configuration with a clear “local runtime only” error.
  • Documentation
    • Updated CLI, Rust, and initialization architecture docs for the enhanced kernel/boot initialization flow.
  • Tests
    • Added/updated coverage for plan shape changes and kernel asset preparation/reuse behavior.

@coderabbitai

coderabbitai Bot commented Jul 26, 2026 •

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: f5cbabe4-3873-4738-9c80-5f092e180d2b

📥 Commits

Reviewing files that changed from the base of the PR and between 1c01629 and 75120c6.

📒 Files selected for processing (5)
  • docs/reference/rust/README.md
  • src/boxlite/src/litebox/init/tasks/boot_assets.rs
  • src/boxlite/src/runtime/core.rs
  • src/boxlite/src/runtime/options.rs
  • src/boxlite/src/runtime/rt_impl.rs
🚧 Files skipped from review as they are similar to previous changes (3)
  • docs/reference/rust/README.md
  • src/boxlite/src/litebox/init/tasks/boot_assets.rs
  • src/boxlite/src/runtime/options.rs

📝 Walkthrough

Walkthrough

Custom kernel support now spans public configuration, CLI flags, per-box immutable boot-asset generations, initialization planning, VMM serialization, and Krun configuration. REST runtime creation rejects custom kernels, while local runtime startup reuses or publishes validated kernel generations.

Changes

Custom kernel boot support

Layer / File(s) Summary
Kernel contracts and validation
src/boxlite/src/runtime/options.rs, src/boxlite/src/runtime/advanced_options.rs, src/boxlite/src/runtime/layout.rs, src/boxlite/src/vmm/*, src/deps/libkrun-sys/lib.rs, docs/reference/rust/README.md
Adds kernel option types, validation modes, boot-directory layout, prepared kernel configuration, and libkrun format constants.
CLI kernel option wiring
src/cli/src/cli.rs, src/cli/src/commands/*, src/cli/README.md, docs/reference/cli/README.md
Adds advanced boot flags for run and create, applies them to BoxOptions, validates companion flags, and documents the APIs.
Boot-asset generation storage
src/boxlite/src/litebox/init/tasks/boot_assets.rs, src/boxlite/src/jailer/mod.rs
Publishes immutable kernel generations with manifests and checksums, supports reuse and legacy migration, and exposes boot assets read-only to the jailer.
Initialization and VMM handoff
src/boxlite/src/litebox/init/*, src/boxlite/src/vmm/controller/shim.rs, src/boxlite/src/vmm/krun/engine.rs, src/boxlite/src/rest/runtime.rs, src/boxlite/src/runtime/core.rs, src/boxlite/src/runtime/rt_impl.rs, docs/architecture/README.md
Schedules boot preparation, carries prepared kernels into InstanceSpec, serializes them to the shim, configures Krun, updates runtime sanitization, tests plan shapes, and rejects custom kernels for REST creation.

Estimated code review effort: 4 (Complex) | ~60 minutes

Sequence Diagram(s)

sequenceDiagram
  participant CLI
  participant BoxOptions
  participant BootAssetStore
  participant InitPipeline
  participant ShimController
  participant Krun

  CLI->>BoxOptions: Apply KernelFlags
  InitPipeline->>BootAssetStore: Prepare or reuse kernel generation
  BootAssetStore-->>InitPipeline: PreparedKernel
  InitPipeline->>ShimController: Serialize InstanceSpec with kernel
  ShimController->>Krun: Start VM with kernel configuration
  Krun-->>ShimController: Configure VM context
Loading

Possibly related PRs

Suggested reviewers: g4614

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly matches the PR’s main change: adding custom guest kernel support.
Description check ✅ Passed The description covers the change, rationale, compatibility, and validation, though it uses different headings than the template.
Docstring Coverage ✅ Passed Docstring coverage is 94.57% which is sufficient. The required threshold is 80.00%.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch agent/support-custom-kernel

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@cla-assistant

cla-assistant Bot commented Jul 26, 2026

Copy link
Copy Markdown

CLA assistant check
Thank you for your submission! We really appreciate it. Like many open source projects, we ask that you sign our Contributor License Agreement before we can accept your contribution.


tester seems not to be a GitHub user. You need a GitHub account to be able to sign the CLA. If you have already a GitHub account, please add the email address used for this commit to your account.
You have signed the CLA already but the status is still pending? Let us recheck it.

@DorianZheng
DorianZheng marked this pull request as ready for review July 26, 2026 15:04
@boxlite-agent

boxlite-agent Bot commented Jul 26, 2026 •

Copy link
Copy Markdown

📦 BoxLite review — looks good · 75120c6

Review evidence

  • ✅ git diff --numstat origin/main...HEAD && git diff origin/main...HEAD — 23 files, +1650/-114; inspected diff in full
  • ✅ read boot_assets.rs, options.rs KernelOptions/Format, vmm_spawn.rs, engine.rs, jailer/mod.rs — logic consistent; atomic rename publish, checksum-verified reuse
  • ⚪ cargo test -p boxlite boot_assets / kernel — skipped, bash-call budget exhausted after static review
  • ✅ trace create()/get_or_create() call paths for kernel validation — REST rejects kernel; Local runs full sanitize via spawn_blocking

Risk notes

  • boot asset generation store — stage/publish uses tmp-dir+rename for atomicity, checksum-verifies reuse, prunes only non-current generations; race between two concurrent start() calls on same box could delete a generation another caller just returned, but box status machine (can_start()/Running gating) appears to already serialize box lifecycle ops, so likely mitigated — not independently verified
  • jailer path exposure — boot_dir added read-only alongside bin_dir with test coverage confirming RO; consistent with existing bin_dir pattern
  • REST vs local runtime contract — kernel option explicitly rejected in RestRuntime::create with test; get_or_create delegates to create so same guard applies
  • sanitize split (sanitize_common/sanitize_persisted/sanitize) — top-level BoxliteRuntime::create/get_or_create now call sanitize_common only; full kernel file validation deferred to LocalRuntime via sanitize_local_options — verified no path skips validation for local backend
  • coverage — docs/.md, cli.rs help-text/flag wiring, and --disk-size flag addition were sampled only (low risk, non-executable/doc changes), not deeply cross-checked against actual libkrun ABI constants (KRUN_KERNEL_FORMAT_ values assumed correct, not verified against libkrun header)
src/boxlite/src/litebox/init/tasks/boot_assets.rs
  BootAssetStore::prepare/stage/publish_generation  +578/-0  new generation-based kernel staging
src/boxlite/src/runtime/options.rs
  KernelFormat, KernelOptions, sanitize*  +434/-2  kernel option types + validation split
src/boxlite/src/vmm/mod.rs
  PreparedKernel::new  +48/-1  box-scoped resolved kernel spec
src/boxlite/src/vmm/krun/engine.rs
  Krun::set_kernel  +58/-0  maps format to libkrun constants
src/boxlite/src/litebox/init/mod.rs
  get_execution_plan, BoxBuilder::new  +83/-9  BootAssetsTask wired into pipeline
src/boxlite/src/litebox/init/tasks/vmm_spawn.rs
  VmmSpawnInputs::from_context  +77/-62  refactor to carry prepared_kernel
src/boxlite/src/jailer/mod.rs
  build_path_access  +15/-8  adds boot_dir read-only grant
src/boxlite/src/rest/runtime.rs
  RestRuntime::create  +29/-0  rejects advanced.kernel
src/boxlite/src/runtime/rt_impl.rs
  sanitize_local_options  +16/-0  blocking full sanitize for local
src/cli/src/cli.rs
  KernelFlags::apply_to  +136/-2  new --kernel/--initramfs/--kernel-args flags
src/deps/libkrun-sys/src/lib.rs
  KRUN_KERNEL_FORMAT_*  +8/-0  new FFI format constants

reviewed 75120c6 in a BoxLite microVM · @boxlite-agent review to re-run · powered by BoxLite

@DorianZheng DorianZheng added the e2e-local Triggers the local (in-process) E2E suite on the self-hosted runner label Jul 26, 2026

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 5

🧹 Nitpick comments (1)
src/boxlite/src/litebox/init/tasks/boot_assets.rs (1)

87-101: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Superseded generations and migrated legacy files are never reclaimed.

publish_generation only cleans up on failure; a successful re-stage leaves the previous generations/{id} directory (and, after migration, the legacy boot/kernel + boot/initramfs copies) on disk for the life of the box. Consider pruning generations not referenced by current.json after a successful publish.

Also applies to: 203-294

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/boxlite/src/litebox/init/tasks/boot_assets.rs` around lines 87 - 101,
Update the successful publish flow used by prepare, publish_generation, and the
migration path to prune superseded generation directories after current.json is
updated, retaining only the generation referenced by current.json. Ensure
migrated legacy boot/kernel and boot/initramfs files are also removed once the
new generation is successfully published, while preserving cleanup-on-failure
behavior.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@docs/reference/rust/README.md`:
- Around line 593-613: Update the Custom kernel documentation around
KernelOptions::new to state that advanced.kernel with a custom kernel is
supported only by the local runtime and is rejected for REST creation. Keep the
existing Rust configuration example unchanged.
- Around line 628-633: Correct the Default entry for the security field in the
AdvancedBoxOptions reference table to document SecurityOptions::default() as the
fully enabled security profile, including jailer enabled on Linux. Remove the
platform-specific claim that jailer defaults false while preserving the
descriptions of the available isolation options.

In `@src/boxlite/src/runtime/options.rs`:
- Around line 1065-1101: Gate the entire custom_kernel_configuration_roundtrips
test with cfg(any(target_arch = "x86_64", target_arch = "aarch64")) so its
architecture-specific kernel fixture writes and format definitions are
unavailable on unsupported targets. Preserve the existing test behavior on
x86_64 and aarch64.
- Around line 344-363: Update `detect` to read the four-byte ELF prefix with
`read_exact` instead of a single `read`, treating `UnexpectedEof` as a non-ELF
fallback while propagating other read errors through the existing
`BoxliteError::Config` handling. Preserve the current ELF classification when
the full `\x7fELF` signature is read.
- Around line 372-425: Update KernelFormat::detect so signature scanning is
limited to a bounded plausible header window rather than the entire kernel file;
stop reading once that window is exhausted and return Self::Raw when no
signature is found. Preserve the existing earliest-match behavior within the
window and avoid performing the synchronous whole-file read/seek on the async
creation path by moving this detection work off that path or otherwise using the
established blocking-task mechanism.

---

Nitpick comments:
In `@src/boxlite/src/litebox/init/tasks/boot_assets.rs`:
- Around line 87-101: Update the successful publish flow used by prepare,
publish_generation, and the migration path to prune superseded generation
directories after current.json is updated, retaining only the generation
referenced by current.json. Ensure migrated legacy boot/kernel and
boot/initramfs files are also removed once the new generation is successfully
published, while preserving cleanup-on-failure behavior.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: ba627719-50e7-4adc-aa4d-cf66d231dee6

📥 Commits

Reviewing files that changed from the base of the PR and between fd593cc and 1c01629.

📒 Files selected for processing (22)
  • docs/architecture/README.md
  • docs/reference/cli/README.md
  • docs/reference/rust/README.md
  • src/boxlite/src/jailer/mod.rs
  • src/boxlite/src/lib.rs
  • src/boxlite/src/litebox/init/mod.rs
  • src/boxlite/src/litebox/init/tasks/boot_assets.rs
  • src/boxlite/src/litebox/init/tasks/mod.rs
  • src/boxlite/src/litebox/init/tasks/vmm_spawn.rs
  • src/boxlite/src/litebox/init/types.rs
  • src/boxlite/src/rest/runtime.rs
  • src/boxlite/src/runtime/advanced_options.rs
  • src/boxlite/src/runtime/layout.rs
  • src/boxlite/src/runtime/options.rs
  • src/boxlite/src/vmm/controller/shim.rs
  • src/boxlite/src/vmm/krun/engine.rs
  • src/boxlite/src/vmm/mod.rs
  • src/cli/README.md
  • src/cli/src/cli.rs
  • src/cli/src/commands/create.rs
  • src/cli/src/commands/run.rs
  • src/deps/libkrun-sys/src/lib.rs

Comment thread docs/reference/rust/README.md
Comment thread docs/reference/rust/README.md
Comment thread src/boxlite/src/runtime/options.rs
Comment thread src/boxlite/src/runtime/options.rs
Comment thread src/boxlite/src/runtime/options.rs
@DorianZheng
DorianZheng merged commit 2b717a4 into main Jul 26, 2026
39 of 40 checks passed
@DorianZheng
DorianZheng deleted the agent/support-custom-kernel branch July 26, 2026 15:34
DorianZheng pushed a commit that referenced this pull request Jul 27, 2026
Custom kernels (#1041, #1051) and the capability policy both extend
`AdvancedBoxOptions`, the CLI flag set, and option validation, so the
two features are combined rather than either replacing the other.

Capability name validation moves to `sanitize_common`, which main split
out of `sanitize`: a capability list is request data, not a filesystem
source, so it must also be checked on the persisted path.

The warm-pool capability test now stubs `organizationUsageService`,
which the org-quota work (#1028) made a required collaborator of
`BoxService::create`.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

e2e-local Triggers the local (in-process) E2E suite on the self-hosted runner

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant