Skip to content

Commit ede653a

Browse files
JAORMXclaude
andcommitted
Update docs for dual networking model and new packages
Documentation was out of date with the current codebase. Key updates: - Document runner-side (default) vs hosted networking modes - Add net/hosted and net/topology packages to all doc surfaces - Document ImageFetcher interface and fetcher implementations - Document Spawner/ProcessHandle runner interfaces - Add missing options to README (WithRootFSPath, WithImageFetcher, WithSpawner, WithPreflightChecker) - Update SECURITY.md trust boundary and blast radius for both modes - Update net.Config docs to include FirewallRules/DefaultAction fields Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent f61bbac commit ede653a

5 files changed

Lines changed: 350 additions & 111 deletions

File tree

CLAUDE.md

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -21,15 +21,17 @@ Run a single test: `go test -v -race -run TestName ./path/to/package`
2121

2222
## Architecture
2323

24-
- `propolis.go` -- Entry point: `Run()` orchestrates a 7-step pipeline (pull, extract, hooks, config, net, spawn, boot)
24+
- `propolis.go` -- Entry point: `Run()` orchestrates the pipeline (preflight, pull, hooks, config, net, spawn, post-boot)
2525
- `options.go` -- All `With*` option constructors, `config` struct, `defaultConfig()`
2626
- `vm.go` -- `VM` type returned by `Run()` with `Stop`, `Status`, `Remove`
27-
- `image/` -- OCI pull via crane, layer flattening, content-addressable cache by manifest digest
28-
- `runner/` -- `Spawn()` launches detached propolis-runner subprocess via setsid
29-
- `runner/cmd/propolis-runner/` -- CGO binary: calls `krun.StartEnter`, never returns
27+
- `image/` -- OCI pull via `ImageFetcher` interface (daemon then remote fallback), layer flattening, content-addressable cache
28+
- `runner/` -- `Spawner`/`ProcessHandle` interfaces, launches detached propolis-runner subprocess via setsid
29+
- `runner/cmd/propolis-runner/` -- CGO binary: calls `krun.StartEnter`, never returns; creates in-process VirtualNetwork by default
3030
- `krun/` -- CGO bindings to libkrun C API
31-
- `net/` -- `Provider` interface; default in-process VirtualNetwork (gvisor-tap-vsock)
31+
- `net/` -- `Provider` interface for custom networking backends
3232
- `net/firewall/` -- Frame-level packet filtering, connection tracking, relay
33+
- `net/hosted/` -- Hosted `net.Provider` running VirtualNetwork in caller's process with HTTP services on gateway IP
34+
- `net/topology/` -- Shared network topology constants (subnet, gateway, guest IP, MTU)
3335
- `preflight/` -- `Checker` interface, platform-specific checks via build tags
3436
- `ssh/` -- ECDSA P-256 keygen and SSH client for guest communication
3537
- `state/` -- flock-based atomic JSON state persistence
@@ -80,6 +82,6 @@ When tests fail, fix the implementation, not the tests.
8082

8183
- @docs/ARCHITECTURE.md -- Deep technical architecture
8284
- @docs/SECURITY.md -- Trust boundaries, guest escape analysis, hardening
83-
- @docs/NETWORKING.md -- In-process networking, firewall, wire protocol
85+
- @docs/NETWORKING.md -- Networking modes (runner-side, hosted), firewall, wire protocol
8486
- @docs/MACOS.md -- macOS support, code signing, Hypervisor.framework
8587
- @docs/TROUBLESHOOTING.md -- Common issues, log files, resource limits

README.md

Lines changed: 17 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -264,29 +264,35 @@ func main() {
264264
| `WithMemory(mib)` | RAM in MiB | `512` |
265265
| `WithPorts(...)` | TCP port forwards from host to guest | none |
266266
| `WithInitOverride(cmd...)` | Replace OCI ENTRYPOINT/CMD | OCI config |
267+
| `WithRootFSPath(path)` | Use pre-built rootfs directory, skip OCI image pull | none |
267268
| `WithRootFSHook(...)` | Modify rootfs before boot | none |
268269
| `WithPostBoot(...)` | Run logic after VM process starts | none |
269-
| `WithNetProvider(p)` | Replace default in-process networking | in-process vnet |
270+
| `WithNetProvider(p)` | Replace default runner-side networking with a custom provider | runner-side vnet |
270271
| `WithFirewallRules(...)` | Firewall rules for frame-level packet filtering | none |
271272
| `WithFirewallDefaultAction(action)` | Default firewall action when no rule matches | `Allow` |
273+
| `WithPreflightChecker(c)` | Replace entire preflight checker | platform defaults |
272274
| `WithPreflightChecks(...)` | Add custom pre-boot checks | KVM + resources |
273275
| `WithVirtioFS(...)` | Host directory mounts via virtio-fs | none |
274276
| `WithDataDir(p)` | State, cache, and log directory | `~/.config/propolis` |
275277
| `WithRunnerPath(p)` | Path to propolis-runner binary | auto-detect |
276278
| `WithLibDir(p)` | Directory for libkrun/libkrunfw shared libraries | system libs |
277279
| `WithImageCache(c)` | Custom image cache instance | `$dataDir/cache/` |
280+
| `WithImageFetcher(f)` | Custom image fetcher for OCI retrieval | local-then-remote |
281+
| `WithSpawner(s)` | Custom runner subprocess spawner | `DefaultSpawner` |
278282

279283
## Package Overview
280284

281285
| Package | CGO? | Description |
282286
|---------|------|-------------|
283287
| `propolis` (root) | No | Top-level API: `Run()`, `VM` type, functional options, hook types |
284-
| `image` | No | OCI image pull via crane, layer flattening, rootfs extraction, `KrunConfig` |
288+
| `image` | No | OCI image pull via `ImageFetcher`, layer flattening, rootfs extraction, `KrunConfig` |
285289
| `krun` | **Yes** | CGO bindings to libkrun C API (context, VM config, `StartEnter`) |
286290
| `net` | No | `Provider` interface and `Config`/`PortForward` types |
287291
| `net/firewall` | No | Frame-level packet filtering with stateful connection tracking |
292+
| `net/hosted` | No | Hosted `net.Provider` running VirtualNetwork in caller's process with HTTP services |
293+
| `net/topology` | No | Shared network topology constants (subnet, gateway, IPs, MTU) |
288294
| `preflight` | No | `Checker` interface, `Check` struct, built-in KVM/HVF and port checks |
289-
| `runner` | No | `Spawn()` / `Process` for managing the propolis-runner subprocess |
295+
| `runner` | No | `Spawner` / `ProcessHandle` interfaces for managing the propolis-runner subprocess |
290296
| `runner/cmd/propolis-runner` | **Yes** | The runner binary (calls `krun.StartEnter`, never returns) |
291297
| `ssh` | No | ECDSA key generation and SSH client for guest communication |
292298
| `state` | No | flock-based state persistence with atomic JSON writes |
@@ -400,13 +406,14 @@ Go runtime.
400406
+-------------------+ +-------------------+
401407
```
402408

403-
The in-process VirtualNetwork (gvisor-tap-vsock) provides a virtual network
404-
(192.168.127.0/24), DHCP, DNS, and TCP port forwarding between host and guest.
405-
It communicates with the VM over a Unix domain socket using the QEMU transport
406-
(SOCK_STREAM with 4-byte big-endian length-prefixed Ethernet frames). An
407-
optional frame-level firewall with stateful connection tracking can be enabled
408-
via `WithFirewallRules()`. See [docs/NETWORKING.md](docs/NETWORKING.md) for
409-
a deep dive.
409+
By default, the runner creates an in-process VirtualNetwork (gvisor-tap-vsock)
410+
providing a virtual network (192.168.127.0/24), DHCP, DNS, and TCP port
411+
forwarding. For advanced use cases, `WithNetProvider()` moves the network stack
412+
to the caller's process -- the `net/hosted` package provides a ready-made
413+
provider that also supports HTTP services on the gateway IP. An optional
414+
frame-level firewall with stateful connection tracking can be enabled via
415+
`WithFirewallRules()`. See [docs/NETWORKING.md](docs/NETWORKING.md) for a
416+
deep dive.
410417

411418
### Extension Points
412419

0 commit comments

Comments
 (0)