mirror of
https://github.com/vhaudiquet/ecrou.git
synced 2026-11-12 22:22:44 +00:00
docs: document macOS support and Homebrew distribution
SPEC records the two macOS facts the code bends around (bare-soname dlopens needing startup-time DYLD paths; the hypervisor entitlement) and the packaging decisions; README gains the brew install and the from-source sign step.
This commit is contained in:
1 parent
ff73624891
commit
6a631a3707
2 files changed
+83
-4
No files matched your search
@@ -8,12 +8,30 @@
|
|||||||
|
|
||||||
### Installation
|
### Installation
|
||||||
|
|
||||||
ecrou is available as a strictly confined snap:
|
Linux (strictly confined snap, KVM required):
|
||||||
```
|
```
|
||||||
sudo snap install ecrou
|
sudo snap install ecrou
|
||||||
sudo snap connect ecrou:kvm
|
sudo snap connect ecrou:kvm
|
||||||
```
|
```
|
||||||
|
|
||||||
|
macOS (Apple Silicon, Homebrew):
|
||||||
|
```
|
||||||
|
brew tap vhaudiquet/ecrou https://github.com/vhaudiquet/homebrew-ecrou
|
||||||
|
brew install ecrou
|
||||||
|
```
|
||||||
|
|
||||||
|
The macOS build loads libkrun from the
|
||||||
|
[`libkrun/homebrew-krun`](https://github.com/libkrun/homebrew-krun) tap
|
||||||
|
at runtime and boots through Hypervisor.framework; the formula signs
|
||||||
|
the binary with the hypervisor entitlement macOS requires, so the
|
||||||
|
install needs no extra steps. Building from source instead:
|
||||||
|
|
||||||
|
```
|
||||||
|
brew install libkrun/homebrew-krun/libkrun e2fsprogs
|
||||||
|
cargo build --release -p ecrou-cli
|
||||||
|
codesign --force --sign - --entitlements packaging/macos/ecrou.entitlements target/release/ecrou
|
||||||
|
```
|
||||||
|
|
||||||
### Usage
|
### Usage
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|||||||
@@ -34,9 +34,11 @@ and fails with a remediation message naming the install when it is
|
|||||||
missing; nothing links at build time, and the snap bundles the library
|
missing; nothing links at build time, and the snap bundles the library
|
||||||
plus libkrunfw next to itself.
|
plus libkrunfw next to itself.
|
||||||
|
|
||||||
KVM is required; there is no TCG fallback. A machine without working
|
KVM is required on Linux, Hypervisor.framework on macOS; there is no
|
||||||
KVM is `Error::KvmUnavailable` with the remediation text, and `ecrou
|
TCG fallback. A machine without working KVM is `Error::KvmUnavailable`
|
||||||
probe` reports it before any run. The VMM runs inside the machine
|
with the remediation text, and `ecrou probe` reports it before any
|
||||||
|
run (on macOS the probe goes further: it checks the hypervisor
|
||||||
|
entitlement too, see the macOS section). The VMM runs inside the machine
|
||||||
child, not on the caller's thread (see Cancellation).
|
child, not on the caller's thread (see Cancellation).
|
||||||
|
|
||||||
libkrun's mapped-volumes entry point is explicitly unsupported on
|
libkrun's mapped-volumes entry point is explicitly unsupported on
|
||||||
@@ -282,6 +284,65 @@ stop:
|
|||||||
point: 24 s end to end, boot and apt included, cache-warm (snap
|
point: 24 s end to end, boot and apt included, cache-warm (snap
|
||||||
0.1.0 engine, October 2026).
|
0.1.0 engine, October 2026).
|
||||||
|
|
||||||
|
## macOS
|
||||||
|
|
||||||
|
The same ABI, a different substrate. The engine is dlopen'd from the
|
||||||
|
Homebrew kegs (`libkrun` from the `libkrun/homebrew-krun` tap, which
|
||||||
|
builds the HVF backend and links Hypervisor.framework); the keg path
|
||||||
|
is a search fallback, not a hard-coded prefix, and the run fails with
|
||||||
|
a remediation naming the tap when the library is absent. macOS needs
|
||||||
|
no snap: no store sandbox, no staged libraries — Homebrew's prefix is
|
||||||
|
the distribution channel. There is no riscv64 or amd64 build; libkrun
|
||||||
|
supports Hypervisor.framework on arm64 only.
|
||||||
|
|
||||||
|
Two macOS facts shape the code:
|
||||||
|
|
||||||
|
**Bare-soname dlopens.** The engine loads `libkrunfw.5.dylib` by bare
|
||||||
|
soname at `krun_start_enter`, and a libarchive-capable `mke2fs` loads
|
||||||
|
`libarchive.13.dylib` the same way. dyld never searches the brew
|
||||||
|
prefix, and it reads `DYLD_FALLBACK_LIBRARY_PATH` once, at process
|
||||||
|
startup — a setenv afterwards is invisible to it. The CLI therefore
|
||||||
|
re-execs itself (exec restarts dyld) when the variable is unset and
|
||||||
|
the kegs exist; library consumers must set the variable themselves
|
||||||
|
before their process starts. mkfs children are exec'd fresh, so the
|
||||||
|
per-spawn env in image.rs works regardless.
|
||||||
|
|
||||||
|
**The hypervisor entitlement.** Hypervisor.framework grants VM
|
||||||
|
creation only to binaries signed with the
|
||||||
|
`com.apple.security.hypervisor` entitlement — current macOS enforces
|
||||||
|
this for ad-hoc-signed binaries too, where older releases granted the
|
||||||
|
framework implicitly. The denial surfaces as `hv_vm_create` returning
|
||||||
|
`HV_DENIED` (0xfae94007), which without a probe showed up only as an
|
||||||
|
opaque `krun_start_enter` EINVAL after a full image build. `probe` now
|
||||||
|
creates and destroys a real framework VM (dlopen'd, no link-time
|
||||||
|
dependency) so the denial is reported with the re-sign remediation
|
||||||
|
before any image work. Packaging signs at install (the Homebrew
|
||||||
|
formula, the same pattern krunkit's formula carries, and the release
|
||||||
|
tarball's codesign step); a `cargo build` developer re-signs after
|
||||||
|
each build, per the README snippet.
|
||||||
|
|
||||||
|
The ext4 image is built the same way as on Linux, with one fallback:
|
||||||
|
when the found `mke2fs` cannot populate from a tarball (Homebrew's
|
||||||
|
e2fsprogs bottle builds without libarchive), the image builder
|
||||||
|
unpacks the rootfs to a tree and lets mke2fs populate from the
|
||||||
|
directory — slower, and run states it in the log. The T6 strace audit
|
||||||
|
and the `/dev/kvm` gating stay Linux-only: strace does not exist on
|
||||||
|
macOS and the hypervisor gate is the entitlement probe instead. CI
|
||||||
|
runs the whole gate plus a real `ecrou run` boot on a `macos-26`
|
||||||
|
runner; the release workflow ships a signed darwin-arm64 tarball.
|
||||||
|
|
||||||
|
## Homebrew
|
||||||
|
|
||||||
|
`packaging/homebrew/Formula/ecrou.rb` installs into a
|
||||||
|
`vhaudiquet/homebrew-ecrou` tap. The formula carries the runtime
|
||||||
|
dependencies (`libkrun` from the krun tap, `e2fsprogs`, `libarchive`),
|
||||||
|
builds from source with cargo, and re-signs the binary with the
|
||||||
|
entitlements plist from `packaging/macos/` — brew bottles are
|
||||||
|
ad-hoc signed, so the signature is part of the formula's install,
|
||||||
|
not of the artifact. The formula is pinned by tag until the first
|
||||||
|
release exists, then switches to the release tarball + sha256 the
|
||||||
|
release workflow produces.
|
||||||
|
|
||||||
## Snap packaging
|
## Snap packaging
|
||||||
|
|
||||||
Confinement: strict. Plugs: `network`, `home`, `kvm`. The manual
|
Confinement: strict. Plugs: `network`, `home`, `kvm`. The manual
|
||||||
|
|||||||
Reference in new issue
Block a user