Skip to content

Commit 70e7626

Browse files
JAORMXclaude
andcommitted
Improve README for release readiness
Add experimental warning banner, CI/license/Go badges, and Contributing section. Remove all toolhive-appliance references from README and ARCHITECTURE.md. Fix Go version (1.26), update Quick Start to use vm.ID(), add missing packages to overview, and add build-runner/fetch-runtime/fetch-firmware to build table. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent 3c37a1b commit 70e7626

3 files changed

Lines changed: 32 additions & 77 deletions

File tree

CONTRIBUTING.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
## Prerequisites
44

5-
- **Go 1.25.7+**
5+
- **Go 1.26+**
66
- **[Task](https://taskfile.dev/)** -- `go install github.com/go-task/task/v3/cmd/task@latest`
77
- **golangci-lint** -- `go install github.com/golangci/golangci-lint/cmd/golangci-lint@latest`
88
- **goimports** -- `go install golang.org/x/tools/cmd/goimports@latest`

README.md

Lines changed: 30 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,27 @@
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> &middot;
1017
<a href="#architecture">Architecture</a> &middot;
1118
<a href="docs/ARCHITECTURE.md">Docs</a> &middot;
19+
<a href="#contributing">Contributing</a> &middot;
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

1831
propolis 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
2235
call.
2336

2437
You 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
2639
image caching, preflight validation, port forwarding, virtio-fs mounts, and
2740
process 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
118126
except `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
165172
package 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

323332
Only `krun` and `runner/cmd/propolis-runner` require CGO and `libkrun-devel`.
324333
All 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

docs/ARCHITECTURE.md

Lines changed: 1 addition & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@ state management, security measures, and extension points.
1818
- [State Management](#state-management)
1919
- [Security Model](#security-model)
2020
- [SSH Utilities](#ssh-utilities)
21-
- [Relationship to toolhive-appliance](#relationship-to-toolhive-appliance)
2221

2322
## The Two-Process Model
2423

@@ -772,8 +771,7 @@ escape blast radius, and hardening recommendations, see
772771

773772
## SSH Utilities
774773

775-
The `ssh` package provides two capabilities used by consumers like
776-
toolhive-appliance:
774+
The `ssh` package provides two capabilities for guest communication:
777775

778776
### Key Generation
779777

@@ -822,38 +820,3 @@ or the context is cancelled. Connection timeout per attempt is 10 seconds.
822820
**Security note:** The SSH client uses `InsecureIgnoreHostKey()` for host key
823821
verification. This is acceptable because we trust the VM we just created -- it
824822
was booted from an image we pulled and configured.
825-
826-
## Relationship to toolhive-appliance
827-
828-
[toolhive-appliance](https://github.com/stacklok/toolhive-appliance) is the
829-
primary consumer of propolis. It uses the extension points to build a complete
830-
appliance experience:
831-
832-
| Extension Point | toolhive-appliance Usage |
833-
|-----------------|--------------------------|
834-
| `WithName` | Names the VM "toolhive-appliance" |
835-
| `WithInitOverride` | Injects `toolhive-init.sh` that starts k3s and services |
836-
| `WithRootFSHook` | Writes SSH keys, TLS certificates, configuration files |
837-
| `WithPostBoot` | Waits for SSH, pushes runtime config, syncs kubeconfig, verifies health |
838-
| `WithPreflightChecks` | Validates KVM, disk space, connectivity |
839-
| `WithVirtioFS` | Shares host directories for data persistence |
840-
| `WithDataDir` | Uses `~/.config/toolhive-appliance/` |
841-
| `WithRootFSPath` | Uses pre-built rootfs (skips OCI image pull) |
842-
| `WithPreflightChecker` | Replaces default preflight with empty checker (appliance has its own) |
843-
| `WithBackend(libkrun.NewBackend(...))` | Configures libkrun backend with `libkrun.WithRunnerPath` and `libkrun.WithLibDir` for embedded binaries |
844-
| `WithPorts` | Forwards HTTP (8080), HTTPS (8443), k8s API (6443), SSH (2222) |
845-
| `WithCPUs` / `WithMemory` | Configures VM resources per user settings |
846-
847-
### Migration Path
848-
849-
propolis was extracted from toolhive-appliance to provide a reusable library.
850-
If you are building a similar appliance:
851-
852-
1. Import `github.com/stacklok/propolis` as a library
853-
2. Build your own init script for the guest
854-
3. Use `WithRootFSHook` to inject your configuration
855-
4. Use `WithPostBoot` for your post-boot orchestration
856-
5. Build your own CLI around `propolis.Run()`
857-
858-
The propolis library handles the OCI-to-microVM pipeline. You provide the
859-
domain-specific logic via hooks and options.

0 commit comments

Comments
 (0)