55
66 <p ><strong >Run OCI container images as microVMs with libkrun.</strong ></p >
77
8+ <p >
9+ <a href="https://github.com/stacklok/propolis/actions/workflows/ci.yaml"><img src="https://github.com/stacklok/propolis/actions/workflows/ci.yaml/badge.svg" alt="CI status" /></a>
10+ <a href="https://pkg.go.dev/github.com/stacklok/propolis"><img src="https://pkg.go.dev/badge/github.com/stacklok/propolis.svg" alt="Go Reference" /></a>
11+ <a href="LICENSE"><img src="https://img.shields.io/badge/license-Apache--2.0-blue.svg" alt="License: Apache-2.0" /></a>
12+ <a href="https://goreportcard.com/report/github.com/stacklok/propolis"><img src="https://goreportcard.com/badge/github.com/stacklok/propolis" alt="Go Report Card" /></a>
13+ </p >
14+
815 <p >
916 <a href="#quick-start">Quick Start</a> ·
1017 <a href="#architecture">Architecture</a> ·
1118 <a href="docs/ARCHITECTURE.md">Docs</a> ·
19+ <a href="#contributing">Contributing</a> ·
1220 <a href="#license">License</a>
1321 </p >
1422</div >
1523
24+ > [ !WARNING]
25+ > ** Experimental** -- propolis is under active development. APIs, configuration
26+ > formats, and behavior may change without notice between releases. It is not
27+ > yet recommended for production use.
28+
1629---
1730
1831propolis is a Go library and runner binary that turns any OCI container image
@@ -22,15 +35,10 @@ into a rootfs, configures in-process networking, and boots the result using
2235call.
2336
2437You would use propolis when you need stronger isolation than containers provide
25- but want to keep the OCI image workflow you already have. The framework handles
38+ but want to keep the OCI image workflow you already have. The library handles
2639image caching, preflight validation, port forwarding, virtio-fs mounts, and
2740process lifecycle so you can focus on what runs inside the VM.
2841
29- propolis was extracted from
30- [ toolhive-appliance] ( https://github.com/stacklok/toolhive-appliance ) to
31- provide a reusable, general-purpose OCI-to-microVM pipeline. toolhive-appliance
32- remains the primary consumer of this library.
33-
3442## Table of Contents
3543
3644- [ Prerequisites] ( #prerequisites )
@@ -41,7 +49,7 @@ remains the primary consumer of this library.
4149- [ Architecture] ( #architecture )
4250- [ Security Model] ( #security-model )
4351- [ Troubleshooting] ( #troubleshooting )
44- - [ Relationship to toolhive-appliance ] ( #relationship-to-toolhive-appliance )
52+ - [ Contributing ] ( #contributing )
4553- [ License] ( #license )
4654
4755## Prerequisites
@@ -114,7 +122,7 @@ sudo modprobe kvm kvm_amd # AMD CPUs
114122
115123### Go Toolchain
116124
117- propolis requires ** Go 1.25.7 ** or later. The library packages (everything
125+ propolis requires ** Go 1.26 ** or later. The library packages (everything
118126except ` krun ` and ` propolis-runner ` ) do not require CGO and compile with
119127` CGO_ENABLED=0 ` . The runner binary requires ` CGO_ENABLED=1 ` and ` libkrun-devel ` .
120128
@@ -142,7 +150,7 @@ func main() {
142150 defer vm.Stop (ctx)
143151
144152 info , _ := vm.Status (ctx)
145- log.Printf (" VM %s running (pid %d )" , info.Name , info.PID )
153+ log.Printf (" VM %s running (id %s )" , info.Name , info.ID )
146154
147155 // The VM is now serving on localhost:8080.
148156 // Block until interrupted, or integrate with your own lifecycle.
@@ -157,9 +165,8 @@ or remove the VM.
157165
158166## Advanced Usage
159167
160- For appliance-style deployments (like
161- [ toolhive-appliance] ( https://github.com/stacklok/toolhive-appliance ) ),
162- propolis exposes hooks and overrides at every stage of the pipeline:
168+ For appliance-style deployments, propolis exposes hooks and overrides at every
169+ stage of the pipeline:
163170
164171``` go
165172package main
@@ -318,7 +325,9 @@ func main() {
318325| ` runner/cmd/propolis-runner ` | ** Yes** | The runner binary (calls ` krun.StartEnter ` , never returns) |
319326| ` ssh ` | No | ECDSA key generation and SSH client for guest communication |
320327| ` state ` | No | flock-based state persistence with atomic JSON writes |
328+ | ` rootfs ` | No | Rootfs cloning with reflink (copy-on-write) support |
321329| ` internal/pathutil ` | No | Path traversal validation for safe file operations |
330+ | ` internal/xattr ` | No | Extended attribute helpers for ` override_stat ` ownership mapping |
322331
323332Only ` krun ` and ` runner/cmd/propolis-runner ` require CGO and ` libkrun-devel ` .
324333All other packages are pure Go and can be imported and tested with
@@ -333,7 +342,9 @@ propolis uses [Task](https://taskfile.dev/) as its build tool. Run
333342| ---------| -------------|
334343| ` task build-dev ` | Build runner for development on Linux (requires system ` libkrun-devel ` , ` CGO_ENABLED=1 ` ) |
335344| ` task build-dev-darwin ` | Build runner on macOS (requires Homebrew libkrun, signs with entitlements) |
336- | ` task build-dev-race ` | Build runner with Go race detector enabled |
345+ | ` task build-runner ` | Build runner + libs using builder container (no system libkrun needed) |
346+ | ` task fetch-runtime ` | Download pre-built runtime from GitHub Release |
347+ | ` task fetch-firmware ` | Download pre-built firmware from GitHub Release |
337348| ` task test ` | Run all tests with race detector (` go test -v -race ./... ` ) |
338349| ` task test-coverage ` | Run tests with coverage, generates ` coverage.html ` |
339350| ` task lint ` | Run ` golangci-lint ` |
@@ -342,7 +353,7 @@ propolis uses [Task](https://taskfile.dev/) as its build tool. Run
342353| ` task tidy ` | Run ` go mod tidy ` |
343354| ` task verify ` | Run fmt, lint, and test in sequence (CI pipeline) |
344355| ` task version ` | Print version, commit, and build date from git |
345- | ` task clean ` | Remove ` bin/ ` directory and coverage files |
356+ | ` task clean ` | Remove ` bin/ ` , ` dist/ ` , and coverage files |
346357
347358### Testing Without CGO
348359
@@ -541,30 +552,11 @@ ss -tlnp | grep ':8080'
541552- See [ docs/MACOS.md] ( docs/MACOS.md ) for details on filesystem permissions
542553 (virtiofs xattr), guest networking differences, and troubleshooting.
543554
544- ## Relationship to toolhive-appliance
545-
546- propolis was extracted from
547- [ toolhive-appliance] ( https://github.com/stacklok/toolhive-appliance ) to
548- provide a reusable OCI-to-microVM pipeline. The appliance uses the extension
549- points to build a complete appliance experience:
550-
551- - ` WithInitOverride ` to inject a custom init script that starts k3s and
552- appliance services
553- - ` WithRootFSHook ` to write SSH keys, TLS certificates, and configuration
554- files into the rootfs before boot
555- - ` WithPostBoot ` to wait for SSH, push runtime configuration, sync kubeconfig,
556- and verify service health
557- - ` WithPreflightChecks ` to validate appliance-specific prerequisites (disk
558- space, connectivity)
559- - ` WithVirtioFS ` to share host directories with the guest
560- - ` WithDataDir ` to use appliance-specific state directories
561- - ` WithBackend(libkrun.NewBackend(...)) ` with ` libkrun.WithRunnerPath ` and
562- ` libkrun.WithLibDir ` to point at embedded binaries
563-
564- propolis provides the general-purpose pipeline. The appliance layer adds the
565- domain-specific orchestration on top. If you are building something similar --
566- a self-contained binary that boots a VM from an OCI image -- propolis gives you
567- the building blocks.
555+ ## Contributing
556+
557+ Contributions are welcome! See [ CONTRIBUTING.md] ( CONTRIBUTING.md ) for
558+ development setup, build commands, code conventions, and the workflow for
559+ submitting changes.
568560
569561## License
570562
0 commit comments