Skip to content

Commit 93180cf

Browse files
committed
chore: initial extraction from microvm-blueprint
Phase 0 of the decentralized microVM primitive scope-out. This crate ships the Firecracker driver that Tangle blueprints (sandbox, microvm, future cloud-style ones) consume directly as a Cargo dep. No HTTP server, no auth, no sessions — operators ARE the hosts, so there is no second process to deploy. Source: tangle-network/microvm-blueprint @ chore/sdk-bump-0.2.0-alpha.6 microvm-runtime/ (676 LOC firecracker adapter + traits) Added vs. source: - Standalone Cargo.toml metadata (description, repository, keywords, categories, license). - rust-toolchain.toml pinned to 1.91 to match workspace expectation. - .github/workflows/ci.yml — fmt + clippy + test (all-features and no-default-features) + docs. - .github/dependabot.yml — cargo + actions, daily/weekly. - README.md — usage, env vars, hardening checklist. - docs/ROADMAP.md — per-release plan to production-grade. - LICENSE (Unlicense, matching sibling Tangle crates). One clippy fix applied to clear -D warnings: src/adapters/firecracker.rs:373 — manual_unwrap_or_default (split_once match → unwrap_or_default). Tests green: 1 lifecycle test from in_memory adapter. The firecracker adapter is process-spawning so it isn't unit-tested here; integration tests live in downstream blueprint repos and stay there for now.
0 parents  commit 93180cf

16 files changed

Lines changed: 1385 additions & 0 deletions

File tree

.github/dependabot.yml

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
version: 2
2+
updates:
3+
- package-ecosystem: "cargo"
4+
directory: "/"
5+
schedule:
6+
interval: "daily"
7+
open-pull-requests-limit: 5
8+
- package-ecosystem: "github-actions"
9+
directory: "/"
10+
schedule:
11+
interval: "weekly"

.github/workflows/ci.yml

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
name: CI
2+
3+
on:
4+
push:
5+
branches: [main]
6+
pull_request:
7+
branches: [main]
8+
9+
env:
10+
CARGO_TERM_COLOR: always
11+
RUSTFLAGS: -D warnings
12+
13+
jobs:
14+
fmt:
15+
name: rustfmt
16+
runs-on: ubuntu-latest
17+
steps:
18+
- uses: actions/checkout@v4
19+
- uses: dtolnay/rust-toolchain@1.91
20+
with:
21+
components: rustfmt
22+
- run: cargo fmt --all -- --check
23+
24+
clippy:
25+
name: clippy
26+
runs-on: ubuntu-latest
27+
steps:
28+
- uses: actions/checkout@v4
29+
- uses: dtolnay/rust-toolchain@1.91
30+
with:
31+
components: clippy
32+
- uses: Swatinem/rust-cache@v2
33+
- run: cargo clippy --all-targets --all-features -- -D warnings
34+
35+
test:
36+
name: test
37+
runs-on: ubuntu-latest
38+
steps:
39+
- uses: actions/checkout@v4
40+
- uses: dtolnay/rust-toolchain@1.91
41+
- uses: Swatinem/rust-cache@v2
42+
- run: cargo test --all-features
43+
- run: cargo test --no-default-features
44+
45+
docs:
46+
name: docs
47+
runs-on: ubuntu-latest
48+
steps:
49+
- uses: actions/checkout@v4
50+
- uses: dtolnay/rust-toolchain@1.91
51+
- uses: Swatinem/rust-cache@v2
52+
- run: cargo doc --all-features --no-deps
53+
env:
54+
RUSTDOCFLAGS: -D warnings

.gitignore

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
target/
2+
.idea/
3+
.vscode/
4+
*.swp
5+
*.swo
6+
.DS_Store

Cargo.lock

Lines changed: 128 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
[package]
2+
name = "microvm-runtime"
3+
version = "0.1.0-alpha.1"
4+
edition = "2024"
5+
rust-version = "1.91"
6+
description = "Firecracker microVM driver for decentralized Tangle operators — pure-Rust primitive, no service, no auth, no business logic."
7+
license = "Unlicense"
8+
repository = "https://github.com/tangle-network/microvm-runtime"
9+
homepage = "https://github.com/tangle-network/microvm-runtime"
10+
documentation = "https://docs.rs/microvm-runtime"
11+
readme = "README.md"
12+
keywords = ["firecracker", "microvm", "vmm", "tangle", "sandbox"]
13+
categories = ["virtualization", "os::linux-apis"]
14+
15+
[dependencies]
16+
serde = { version = "1", features = ["derive"] }
17+
serde_json = "1"
18+
thiserror = "2"
19+
20+
[features]
21+
default = []
22+
# Enables the in-process Firecracker driver. Requires a host running KVM and
23+
# a Firecracker binary reachable via PATH (or `MICROVM_FIRECRACKER_BIN`).
24+
firecracker = []

LICENSE

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
This is free and unencumbered software released into the public domain.
2+
3+
Anyone is free to copy, modify, publish, use, compile, sell, or
4+
distribute this software, either in source code form or as a compiled
5+
binary, for any purpose, commercial or non-commercial, and by any
6+
means.
7+
8+
In jurisdictions that recognize copyright laws, the author or authors
9+
of this software dedicate any and all copyright interest in the
10+
software to the public domain. We make this dedication for the benefit
11+
of the public at large and to the detriment of our heirs and
12+
successors. We intend this dedication to be an overt act of
13+
relinquishment in perpetuity of all present and future rights to this
14+
software under copyright law.
15+
16+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
19+
IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
20+
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
21+
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
22+
OTHER DEALINGS IN THE SOFTWARE.
23+
24+
For more information, please refer to <https://unlicense.org>

README.md

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
# microvm-runtime
2+
3+
[![crates.io](https://img.shields.io/crates/v/microvm-runtime.svg)](https://crates.io/crates/microvm-runtime)
4+
[![docs.rs](https://docs.rs/microvm-runtime/badge.svg)](https://docs.rs/microvm-runtime)
5+
6+
Firecracker microVM driver for decentralized Tangle operators.
7+
8+
A pure-Rust primitive. No HTTP server, no auth layer, no sessions, no business
9+
logic — just the driver that speaks the Firecracker API over its unix socket
10+
and exposes a small lifecycle trait. Tangle blueprints (the operator binaries)
11+
consume it directly as a Cargo dependency — operators **are** the hosts, so
12+
there is no second process to deploy.
13+
14+
## Why this exists
15+
16+
Every Tangle blueprint that wants microVM isolation (sandbox blueprint,
17+
microvm blueprint, future cloud-style blueprints) needs the same driver. This
18+
crate is that driver, extracted into a single primitive with a narrow surface
19+
so it can be hardened in one place.
20+
21+
## Status
22+
23+
`0.1.0-alpha.1` — extracted from `microvm-blueprint`. Lifecycle works
24+
(create / start / stop / snapshot / destroy). Production hardening is the
25+
next several releases:
26+
27+
- [ ] Network configuration (TAP / bridge / iptables NAT)
28+
- [ ] Vsock device for guest↔host RPC
29+
- [ ] Snapshot restore (`PUT /snapshot/load`)
30+
- [ ] Console log ring buffer for post-mortem
31+
- [ ] Graceful shutdown (SIGTERM → wait → SIGKILL)
32+
- [ ] Jailer wrapper (chroot / cgroup v2 / seccomp / UID-GID mapping)
33+
- [ ] Rate limiters on drives and NICs
34+
- [ ] Egress firewall per session
35+
- [ ] Metrics polling (`GET /vm` for CPU / memory / network)
36+
- [ ] VM rename for warm-pool handoff
37+
38+
See [`docs/ROADMAP.md`](docs/ROADMAP.md) for the per-phase plan.
39+
40+
## Usage
41+
42+
```rust
43+
use microvm_runtime::{adapters::firecracker::{FirecrackerConfig, FirecrackerVmProvider}, VmProvider, VmQuery};
44+
45+
let provider = FirecrackerVmProvider::from_env();
46+
provider.create_vm("vm-1")?;
47+
provider.start_vm("vm-1")?;
48+
provider.snapshot_vm("vm-1", "snap-a")?;
49+
provider.stop_vm("vm-1")?;
50+
provider.destroy_vm("vm-1")?;
51+
```
52+
53+
## Environment variables
54+
55+
| Variable | Default | Purpose |
56+
| --- | --- | --- |
57+
| `MICROVM_FIRECRACKER_BIN` | `/usr/local/bin/firecracker` | Firecracker binary path |
58+
| `MICROVM_FIRECRACKER_KERNEL` | `/var/lib/firecracker/vmlinux` | Linux kernel image |
59+
| `MICROVM_FIRECRACKER_ROOTFS` | `/var/lib/firecracker/rootfs/default.ext4` | Rootfs image |
60+
| `MICROVM_FIRECRACKER_SOCKET_DIR` | `/var/run/microvm/sockets` | Per-VM API socket parent dir |
61+
| `MICROVM_FIRECRACKER_STATE_DIR` | `/var/lib/microvm/state` | Per-VM state dir |
62+
| `MICROVM_FIRECRACKER_VCPU` | `1` | Default vCPU count |
63+
| `MICROVM_FIRECRACKER_MEM_MIB` | `256` | Default memory size |
64+
65+
## License
66+
67+
[Unlicense](LICENSE) — public domain.

docs/ROADMAP.md

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
# Roadmap
2+
3+
This crate ships in alpha-cadence releases until the production hardening list
4+
is complete. Each phase below is a release boundary.
5+
6+
## 0.1.x — Extraction (current)
7+
8+
Lifecycle: create / start / stop / snapshot (create only) / destroy. Direct
9+
unix-socket HTTP to the Firecracker API. No SDK dep. Process management with
10+
kill-on-error rollback. In-memory test adapter for downstream blueprint tests.
11+
12+
What works for an operator today: provision a VM, boot it, capture a snapshot
13+
of its memory, tear it down. Not yet useful for sandboxing — the VM has no
14+
network and no guest↔host channel.
15+
16+
## 0.2.x — Make it useful
17+
18+
The minimum for any operator to actually run workloads inside a VM.
19+
20+
- **Network setup**: TAP device creation, bridge attachment, IP allocation,
21+
`PUT /network-interfaces`, host iptables NAT.
22+
- **Vsock**: CID allocation, `PUT /vsock`, parent dir mkdir before
23+
`/snapshot/load` (FC v1.6 race fix).
24+
- **Snapshot restore**: `PUT /snapshot/load` + UFFD handler coordination.
25+
Pairs with 0.1 snapshot-create for fast warm boot.
26+
- **Console capture**: stderr ring buffer (200-line tail per VM) so kernel
27+
panics and init failures are debuggable post-mortem instead of `Stdio::null`.
28+
- **Graceful shutdown**: SIGTERM → poll → SIGKILL on timeout.
29+
- **Per-VM config override**: kernel, rootfs, vCPU, memory, boot args — today
30+
these are workspace-level, which prevents sizing VMs to workload.
31+
32+
## 0.3.x — Production hardening
33+
34+
Required before a security-conscious operator should run this in production.
35+
36+
- **Jailer wrapper**: chroot + cgroup v2 + seccomp + UID-GID mapping.
37+
- **Rate limiters**: bandwidth + ops quota on drives + NICs, plumbed to the FC
38+
API rather than the current hardcoded `None`.
39+
- **Egress firewall**: per-session iptables FORWARD chain with cleanup on
40+
destroy. Operator can scope what each VM can reach.
41+
- **Metrics polling**: periodic `GET /vm` for CPU, memory, network counters.
42+
- **VM rename**: FC 1.10+ identifier swap for warm-pool handoff without
43+
re-snapshotting.
44+
45+
## 0.4.x — Optional surfaces
46+
47+
Per use case, not blocking either consumer.
48+
49+
- MMDS (instance metadata service).
50+
- Balloon device (pre-snapshot memory reclaim).
51+
- CPU templates (cross-host migration compatibility).
52+
- Multi-drive support: workspace, sidecar, nix store as separate drives with
53+
separate rate limits.
54+
- Metrics fifo for in-VM observability tools.

rust-toolchain.toml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
[toolchain]
2+
channel = "1.91"
3+
profile = "minimal"
4+
components = ["rustfmt", "clippy"]

0 commit comments

Comments
 (0)