Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion .buildkite/pipeline.yml
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,5 @@ steps:
CLEANROOM_KERNEL_IMAGE: /var/lib/buildkite-agent/.local/share/cleanroom/images/vmlinux.bin
CLEANROOM_FIRECRACKER_BINARY: /usr/local/bin/firecracker
CLEANROOM_PRIVILEGED_MODE: helper
CLEANROOM_PRIVILEGED_HELPER_PATH: /usr/local/sbin/cleanroom-root-helper
agents:
queue: cleanroom
15 changes: 8 additions & 7 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,8 @@ jobs:
fi
done

mkdir -p "release-extra/darwin_${{ matrix.arch }}"
helper_output_dir="release-extra/darwin_${{ matrix.arch }}/libexec/cleanroom"
mkdir -p "${helper_output_dir}"
CERT_PATH="${RUNNER_TEMP}/cleanroom-darwin-vz-release.p12"
PROFILE_PATH="${RUNNER_TEMP}/Cleanroom_Darwin_VZ_Backend.provisionprofile"
KEYCHAIN_PATH="${RUNNER_TEMP}/cleanroom-release-signing.keychain-db"
Expand Down Expand Up @@ -81,9 +82,9 @@ jobs:
CLEANROOM_DARWIN_VZ_HELPER_SIGN_IDENTIFIER="com.buildkite.cleanroom.darwin-vz" \
CLEANROOM_DARWIN_VZ_HELPER_PROVISION_PROFILE="${PROFILE_PATH}" \
CLEANROOM_DARWIN_VZ_HELPER_BUNDLE=1 \
scripts/build-darwin-vz-helper.sh "release-extra/darwin_${{ matrix.arch }}/cleanroom-darwin-vz.app"
cp cmd/cleanroom-darwin-vz/entitlements.plist "release-extra/darwin_${{ matrix.arch }}/entitlements.plist"
cp cmd/cleanroom-darwin-vz/entitlements-vmnet.plist "release-extra/darwin_${{ matrix.arch }}/entitlements-vmnet.plist"
scripts/build-darwin-vz-helper.sh "${helper_output_dir}/cleanroom-darwin-vz.app"
cp cmd/cleanroom-darwin-vz/entitlements.plist "${helper_output_dir}/entitlements.plist"
cp cmd/cleanroom-darwin-vz/entitlements-vmnet.plist "${helper_output_dir}/entitlements-vmnet.plist"

- uses: actions/upload-artifact@v4
with:
Expand Down Expand Up @@ -114,11 +115,11 @@ jobs:

- name: Build release extra binaries
run: |
mkdir -p release-extra/linux_amd64 release-extra/linux_arm64
mkdir -p release-extra/linux_amd64/libexec/cleanroom release-extra/linux_arm64/libexec/cleanroom
GOOS=linux GOARCH=amd64 CGO_ENABLED=0 go build -trimpath -ldflags "-s -w" \
-o release-extra/linux_amd64/cleanroom-guest-agent ./cmd/cleanroom-guest-agent
-o release-extra/linux_amd64/libexec/cleanroom/cleanroom-guest-agent-linux-amd64 ./cmd/cleanroom-guest-agent
GOOS=linux GOARCH=arm64 CGO_ENABLED=0 go build -trimpath -ldflags "-s -w" \
-o release-extra/linux_arm64/cleanroom-guest-agent ./cmd/cleanroom-guest-agent
-o release-extra/linux_arm64/libexec/cleanroom/cleanroom-guest-agent-linux-arm64 ./cmd/cleanroom-guest-agent

- uses: goreleaser/goreleaser-action@v6
with:
Expand Down
23 changes: 14 additions & 9 deletions .goreleaser.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ version: 2
builds:
- id: cleanroom-linux
main: ./cmd/cleanroom
binary: cleanroom
binary: bin/cleanroom
env:
- CGO_ENABLED=0
goos: [linux]
Expand All @@ -13,7 +13,7 @@ builds:

- id: cleanroom-darwin
main: ./cmd/cleanroom
binary: cleanroom
binary: bin/cleanroom
env:
- CGO_ENABLED=0
goos: [darwin]
Expand All @@ -26,30 +26,35 @@ archives:
ids: [cleanroom-linux]
formats: [tar.gz]
name_template: >-
{{ .Binary }}_
{{ .ProjectName }}_
{{- title .Os }}_
{{- if eq .Arch "amd64" }}x86_64
{{- else }}{{ .Arch }}{{ end }}
files:
- src: release-extra/linux_{{ .Arch }}/cleanroom-guest-agent
- src: release-extra/linux_{{ .Arch }}/libexec/cleanroom/cleanroom-guest-agent-linux-{{ .Arch }}
dst: libexec/cleanroom
strip_parent: true

- id: cleanroom-darwin
ids: [cleanroom-darwin]
formats: [tar.gz]
name_template: >-
{{ .Binary }}_
{{ .ProjectName }}_
{{- title .Os }}_
{{- if eq .Arch "amd64" }}x86_64
{{- else }}{{ .Arch }}{{ end }}
files:
- src: release-extra/linux_{{ .Arch }}/cleanroom-guest-agent
- src: release-extra/linux_{{ .Arch }}/libexec/cleanroom/cleanroom-guest-agent-linux-{{ .Arch }}
dst: libexec/cleanroom
strip_parent: true
- src: release-extra/darwin_{{ .Arch }}/cleanroom-darwin-vz.app
- src: release-extra/darwin_{{ .Arch }}/libexec/cleanroom/cleanroom-darwin-vz.app
dst: libexec/cleanroom
strip_parent: true
- src: release-extra/darwin_{{ .Arch }}/entitlements-vmnet.plist
- src: release-extra/darwin_{{ .Arch }}/libexec/cleanroom/entitlements-vmnet.plist
dst: libexec/cleanroom
strip_parent: true
- src: release-extra/darwin_{{ .Arch }}/entitlements.plist
- src: release-extra/darwin_{{ .Arch }}/libexec/cleanroom/entitlements.plist
dst: libexec/cleanroom
strip_parent: true

checksum:
Expand Down
25 changes: 10 additions & 15 deletions .mise.toml
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,12 @@ description = "Run full Go test suite"
run = "go test ./..."

[tasks."build:go"]
description = "Build Go binaries into dist/"
description = "Build staged host binaries into dist/<os>-<arch>/"
run = "scripts/build-go.sh"

[tasks."build:darwin"]
description = "Build macOS darwin-vz helper into dist/"
run = "{% if os() == \"macos\" %}scripts/build-darwin-vz-helper.sh dist/cleanroom-darwin-vz.app{% else %}true{% endif %}"
description = "Build macOS darwin-vz helper into the staged dist layout"
run = "{% if os() == \"macos\" %}scripts/build-darwin-vz-helper.sh{% else %}true{% endif %}"

[tasks."build:image:alpine"]
description = "Build local alpine base image"
Expand All @@ -46,28 +46,23 @@ depends = ["build:image:alpine", "build:image:alpine-docker", "build:image:alpin
run = "true"

[tasks.build]
description = "Build binaries into dist/"
description = "Build staged binaries into dist/<os>-<arch>/"
depends = ["build:go", "build:darwin"]
run = "true"

[tasks."install:go"]
description = "Install Go binaries into GOBIN (or GOPATH/bin)"
description = "Install the cleanroom CLI into GOBIN (or GOPATH/bin)"
run = "scripts/install-go.sh"

[tasks."install:darwin"]
description = "Install macOS darwin-vz helper into GOBIN (or GOPATH/bin)"
depends = ["build:darwin"]
run = "{% if os() == \"macos\" %}BIN_DIR=\"$(go env GOBIN)\"; if [ -z \"$BIN_DIR\" ]; then BIN_DIR=\"$(go env GOPATH)/bin\"; fi; mkdir -p \"$BIN_DIR\" && scripts/build-darwin-vz-helper.sh \"$BIN_DIR/cleanroom-darwin-vz.app\"{% else %}true{% endif %}"

[tasks.install]
description = "Install all binaries into GOBIN (or GOPATH/bin)"
depends = ["install:go", "install:darwin"]
run = "true"
description = "Install the staged runtime into ~/.local"
depends = ["build"]
run = "CLEANROOM_GLOBAL_PREFIX=\"$HOME/.local\" scripts/install-global.sh"

[tasks."install:global"]
description = "Install all runtime binaries into /usr/local/bin"
description = "Install the staged runtime into /usr/local"
depends = ["build"]
run = "scripts/install-global.sh"
run = "CLEANROOM_GLOBAL_PREFIX=\"/usr/local\" scripts/install-global.sh"

[tasks.doctor]
description = "Run cleanroom diagnostics"
Expand Down
9 changes: 5 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,11 +35,12 @@ curl -fsSL https://raw.githubusercontent.com/buildkite/cleanroom/main/scripts/in
bash -s -- --version vX.Y.Z
```

By default this installs to `/usr/local/bin`. Override with `--install-dir` or `CLEANROOM_INSTALL_DIR`.
By default the install prefix is `~/.local` for non-root installs and `/usr/local` for root installs. `cleanroom` is installed to `${prefix}/bin/cleanroom` and runtime assets are installed under `${prefix}/libexec/cleanroom`. Override the prefix with `--prefix` or `CLEANROOM_PREFIX`.

Install the locally built binaries from this checkout into `/usr/local/bin`:
Install the locally built staged runtime from this checkout:

```bash
mise run install # installs into ~/.local
mise run install:global
```

Expand Down Expand Up @@ -363,7 +364,7 @@ backends:
firecracker:
binary_path: firecracker
kernel_image: "" # auto-managed when unset
privileged_helper_path: /usr/local/sbin/cleanroom-root-helper
privileged_helper_path: /usr/local/libexec/cleanroom/cleanroom-root-helper
vcpus: 2
memory_mib: 1024
launch_seconds: 30
Expand All @@ -388,7 +389,7 @@ When `rootfs` is unset, Cleanroom derives one from `sandbox.image.ref` and injec
- Firecracker binary installed
- `mkfs.ext4` for OCI-to-ext4 materialization
- `debugfs` for runtime rootfs preparation
- `sudo -n` access to `/usr/local/sbin/cleanroom-root-helper` for host networking
- `sudo -n` access to `/usr/local/libexec/cleanroom/cleanroom-root-helper`

**macOS ([darwin-vz](docs/backend/darwin-vz.md)):**
- `cleanroom-darwin-vz` helper signed with `com.apple.security.virtualization` entitlement
Expand Down
27 changes: 16 additions & 11 deletions docs/backend/darwin-vz.md
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,8 @@ default it emits a signed `cleanroom-darwin-vz.app` bundle. When
`CLEANROOM_DARWIN_VZ_HELPER_PROVISION_PROFILE` is set it embeds that profile in
the bundle so the helper can carry restricted entitlements. Set
`CLEANROOM_DARWIN_VZ_HELPER_BUNDLE=0` to emit a loose helper binary instead.
Without an explicit output path, the helper is staged at
`dist/<host-goos>-<host-goarch>/libexec/cleanroom/cleanroom-darwin-vz.app`.

When a prebuilt helper `.app` bundle is available, the install script preserves
that bundle as-is and only re-signs it when the caller explicitly provides
Expand All @@ -207,29 +209,32 @@ CLEANROOM_DARWIN_VZ_HELPER_ENTITLEMENTS=cmd/cleanroom-darwin-vz/entitlements-vmn
CLEANROOM_DARWIN_VZ_HELPER_SIGN_IDENTITY='Apple Development: <you> (<team>)' \
CLEANROOM_DARWIN_VZ_HELPER_SIGN_IDENTIFIER='com.buildkite.cleanroom.darwin-vz' \
CLEANROOM_DARWIN_VZ_HELPER_PROVISION_PROFILE="$HOME/Downloads/Cleanroom_Darwin_VZ_Backend.provisionprofile" \
scripts/build-darwin-vz-helper.sh dist/cleanroom-darwin-vz.app
scripts/build-darwin-vz-helper.sh
```

## Runtime Discovery

The helper path is resolved in this order:

1. `CLEANROOM_DARWIN_VZ_HELPER`
2. sibling binary next to `cleanroom`
3. sibling `cleanroom-darwin-vz.app` bundle next to `cleanroom`
4. `dist/` under the current working directory or one of its ancestors
5. `dist/cleanroom-darwin-vz.app` under the current working directory or one of its ancestors
6. `PATH`
2. installed `../libexec/cleanroom/cleanroom-darwin-vz.app` relative to `cleanroom`
3. sibling binary next to `cleanroom`
4. sibling `cleanroom-darwin-vz.app` bundle next to `cleanroom`
5. `dist/<host-goos>-<host-goarch>/libexec/cleanroom/cleanroom-darwin-vz.app` under the current working directory or one of its ancestors
6. legacy `dist/cleanroom-darwin-vz.app` or `dist/cleanroom-darwin-vz` under the current working directory or one of its ancestors
7. `PATH`

If missing, runtime fails with an actionable error.

The Linux guest agent follows the same general pattern:

1. sibling binary next to `cleanroom`
2. `dist/cleanroom-guest-agent-linux-$GOARCH` under the current working directory or one of its ancestors
3. `PATH`
1. installed `../libexec/cleanroom/cleanroom-guest-agent-linux-$GOARCH` relative to `cleanroom`
2. sibling binary next to `cleanroom`
3. `dist/<host-goos>-<host-goarch>/libexec/cleanroom/cleanroom-guest-agent-linux-$GOARCH` under the current working directory or one of its ancestors
4. legacy `dist/cleanroom-guest-agent-linux-$GOARCH` under the current working directory or one of its ancestors
5. `PATH`

`mise run build` now produces the matching prebuilt set in `dist/` for macOS development.
`mise run build` now produces the matching staged runtime under `dist/<host-goos>-<host-goarch>/` for macOS development.

## Testing

Expand Down Expand Up @@ -261,7 +266,7 @@ Supported e2e overrides:
Focused vmnet spike path:

```bash
CLEANROOM_DARWIN_VZ_HELPER="$PWD/dist/cleanroom-darwin-vz.app" \
CLEANROOM_DARWIN_VZ_HELPER="$PWD/dist/$(go env GOOS)-$(go env GOARCH)/libexec/cleanroom/cleanroom-darwin-vz.app" \
CLEANROOM_DARWIN_VZ_VMNET_E2E=1 \
mise exec -- go test ./internal/backend/darwinvz -run TestVMNetSharedE2E -v
```
Expand Down
13 changes: 7 additions & 6 deletions docs/ci.md
Original file line number Diff line number Diff line change
Expand Up @@ -73,9 +73,9 @@ The `:apple: E2E (darwin-vz)` step runs launched execution checks on macOS using

Notes:

- `scripts/ci-darwin-vz-e2e.sh` builds `dist/cleanroom` and `dist/cleanroom-darwin-vz.app`, exports `CLEANROOM_DARWIN_VZ_HELPER` to the built helper, and isolates XDG runtime paths.
- `scripts/ci-darwin-vz-e2e.sh` builds the staged runtime under `dist/<host-goos>-<host-goarch>/`, exports `CLEANROOM_DARWIN_VZ_HELPER` to the staged helper bundle under `libexec/cleanroom`, and isolates XDG runtime paths.
- the CI script writes `backends.darwin-vz.network.mode: nat` into its temporary config because Buildkite only ad-hoc signs the helper; `vmnet-shared` needs a vmnet-capable provisioning profile and identifier.
- the script also builds `dist/cleanroom-guest-agent-linux-<host-arch>` so CI can self-bootstrap the Linux guest agent dependency without a separate install step.
- the staged build also includes `dist/<host-goos>-<host-goarch>/libexec/cleanroom/cleanroom-guest-agent-linux-<host-arch>` so CI can self-bootstrap the Linux guest agent dependency without a separate install step.
- Set `CLEANROOM_DARWIN_VZ_KERNEL_IMAGE` on the worker if you want an explicit kernel path; otherwise the script uses managed-kernel fallback.

### 3.2 Upload vmnet signing secrets
Expand Down Expand Up @@ -106,7 +106,7 @@ downloads the Apple WWDR G3 intermediate, builds a signed helper bundle with
`cmd/cleanroom-darwin-vz/entitlements-vmnet.plist`, and runs:

```bash
CLEANROOM_DARWIN_VZ_HELPER="$PWD/dist/cleanroom-darwin-vz.app" \
CLEANROOM_DARWIN_VZ_HELPER="$PWD/dist/$(go env GOOS)-$(go env GOARCH)/libexec/cleanroom/cleanroom-darwin-vz.app" \
CLEANROOM_DARWIN_VZ_VMNET_E2E=1 \
go test ./internal/backend/darwinvz -run TestVMNetSharedE2E -v
```
Expand Down Expand Up @@ -191,14 +191,15 @@ For CI script usage, you can also set:
Install the helper from this repository and only grant sudo access to that helper:

```bash
sudo install -o root -g root -m 0755 scripts/cleanroom-root-helper.sh /usr/local/sbin/cleanroom-root-helper
sudo install -d -o root -g root -m 0755 /usr/local/libexec/cleanroom
sudo install -o root -g root -m 0755 scripts/cleanroom-root-helper.sh /usr/local/libexec/cleanroom/cleanroom-root-helper
```

```sudoers
buildkite-agent ALL=(root) NOPASSWD: /usr/local/sbin/cleanroom-root-helper *
buildkite-agent ALL=(root) NOPASSWD: /usr/local/libexec/cleanroom/cleanroom-root-helper *
```

Then set `CLEANROOM_PRIVILEGED_HELPER_PATH=/usr/local/sbin/cleanroom-root-helper` if you need to override the runtime config.
Then set `CLEANROOM_PRIVILEGED_HELPER_PATH=/usr/local/libexec/cleanroom/cleanroom-root-helper` if you need to override the runtime config.

`scripts/ci-cleanroom-e2e.sh` probes the installed helper with `capabilities`, and `cleanroom doctor` also records the helper `version`, before running Firecracker checks. They do not compare helper file hashes and they do not self-update the helper from the checkout.

Expand Down
4 changes: 2 additions & 2 deletions docs/plans/darwin-vz-vmnet-mode.md
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,7 @@ CLEANROOM_DARWIN_VZ_HELPER_ENTITLEMENTS=cmd/cleanroom-darwin-vz/entitlements-vmn
CLEANROOM_DARWIN_VZ_HELPER_SIGN_IDENTITY='Apple Development: <you> (<team>)' \
CLEANROOM_DARWIN_VZ_HELPER_SIGN_IDENTIFIER='com.buildkite.cleanroom.darwin-vz' \
CLEANROOM_DARWIN_VZ_HELPER_PROVISION_PROFILE="$HOME/Downloads/Cleanroom_Darwin_VZ_Backend.provisionprofile" \
scripts/build-darwin-vz-helper.sh dist/cleanroom-darwin-vz
scripts/build-darwin-vz-helper.sh
```

The helper should carry:
Expand Down Expand Up @@ -221,7 +221,7 @@ binary, not packages expected to exist in the base image.
Run it with a signed helper bundle:

```bash
CLEANROOM_DARWIN_VZ_HELPER="$PWD/dist/cleanroom-darwin-vz.app" \
CLEANROOM_DARWIN_VZ_HELPER="$PWD/dist/$(go env GOOS)-$(go env GOARCH)/libexec/cleanroom/cleanroom-darwin-vz.app" \
CLEANROOM_DARWIN_VZ_VMNET_E2E=1 \
mise exec -- go test ./internal/backend/darwinvz -run TestVMNetSharedE2E -v
```
Expand Down
2 changes: 1 addition & 1 deletion infra/terraform/envs/prod/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ Default host behaviour:
- defaults to `m8i.4xlarge` with a 500 GiB root volume
- installs `scripts/bootstrap-cleanroom-host.sh`, which installs the pinned
`cleanroom` GitHub release, installs the matching
`/usr/local/sbin/cleanroom-root-helper`, installs Firecracker, writes runtime
`/usr/local/libexec/cleanroom/cleanroom-root-helper`, installs Firecracker, writes runtime
config, installs a rerunnable host bootstrap command, and installs the system
daemon
Set `cleanroom_release_repo` when `repo_url` is not a GitHub remote.
Expand Down
Loading