184 lines
6.6 KiB
Markdown
Executable File
184 lines
6.6 KiB
Markdown
Executable File
# Installing Sorcery-Go in an existing Source Mage chroot
|
|
|
|
> *"Drop the binary in. Cast your first spell. The Coven awakens."*
|
|
|
|
This is the definitive drop-in guide. After following it you will have a
|
|
working `sorcery-go` binary living alongside the legacy Bash `sorcery`,
|
|
reading the same grimoire, able to cast real spells end-to-end.
|
|
|
|
## Prerequisites
|
|
|
|
| Requirement | Why | Check |
|
|
|-------------|-----|-------|
|
|
| Source Mage chroot | We reuse its grimoire | `ls /var/lib/sorcery/codex/grimoire` |
|
|
| Go ≥ 1.21 | Build the binary | `go version` |
|
|
| root (sudo) | Mount OverlayFS, install to /usr/local/sbin | `id -u` == 0 |
|
|
| Linux ≥ 4.15 | OverlayFS + cgroup v2 freezer | `uname -r` |
|
|
| `bash`, `tar`, `gpg` | Spell sourcing + unpack + PGP | `which bash tar gpg` |
|
|
|
|
Optional but recommended:
|
|
- `setcap` (from `libcap`) — for running the binary as non-root with CAP_SYS_ADMIN
|
|
- `bpftool` — for loading eBPF Tomb Guard programs
|
|
- `lxc-freeze` or `systemctl` — for the Warding's quarantine logic
|
|
|
|
## 1. Build
|
|
|
|
```bash
|
|
cd sorcery-go
|
|
make build
|
|
```
|
|
|
|
This produces `./build/sorcery`. The build is CGO-free by default so the
|
|
binary is portable across glibc/musl hosts.
|
|
|
|
## 2. Drop-in install
|
|
|
|
The one-shot installer:
|
|
|
|
```bash
|
|
sudo ./scripts/bootstrap.sh
|
|
```
|
|
|
|
This will:
|
|
1. Build the binary (if `./build/sorcery` doesn't exist).
|
|
2. Install it to `/usr/local/sbin/sorcery-go` (NOT `/usr/sbin/sorcery` —
|
|
the legacy Bash sorcery stays untouched).
|
|
3. Create `/var/lib/sorcery-go/{state,tomb,build,log}` — separate from
|
|
`/var/lib/sorcery` so both tools can coexist.
|
|
4. Apply `CAP_SYS_ADMIN`, `CAP_CHOWN`, `CAP_DAC_OVERRIDE` via `setcap`.
|
|
5. Initialise the bbolt state DB at `/var/lib/sorcery-go/state/state.db`.
|
|
6. Walk the existing grimoire at `/var/lib/sorcery/codex/grimoire` and
|
|
index every spell into memory (printed count should be in the
|
|
thousands on a real SMGL install).
|
|
7. Install the systemd unit (or OpenRC init script, autodetected).
|
|
8. Optionally load the eBPF Tomb Guard programs.
|
|
|
|
Or, equivalently, with `make`:
|
|
|
|
```bash
|
|
sudo make drop-in
|
|
```
|
|
|
|
## 3. Verify
|
|
|
|
```bash
|
|
# State DB is alive
|
|
sorcery-go init
|
|
|
|
# Grimoire index works
|
|
sorcery-go gaze depends wget
|
|
# → 📜 Dependency tree for wget (5):
|
|
# binutils
|
|
# glibc
|
|
# linux-headers
|
|
# openssl
|
|
# zlib
|
|
|
|
# Tomb is empty (nothing cast yet)
|
|
sorcery-go tomb list
|
|
|
|
# Warding is active
|
|
sorcery-go ward status
|
|
```
|
|
|
|
## 4. Cast your first spell
|
|
|
|
```bash
|
|
# Static build of busybox — runs without root if you applied setcap
|
|
sudo sorcery-go cast busybox --static --default
|
|
```
|
|
|
|
What happens:
|
|
1. `grimoire.IndexAll` walks `/var/lib/sorcery/codex/grimoire` and finds `busybox`.
|
|
2. `warding.VerifySpell` checks for a PGP signature on `DETAILS.asc` (skipped if absent).
|
|
3. `legal.Sentinel.Validate` checks the license (GPL-2.0 — allowed under `strict_copyleft`).
|
|
4. `cast.Pipeline.Execute` runs:
|
|
- **Summon** — `http.Get` downloads the source tarball to `/var/spool/sorcery-go/`.
|
|
- **Verify** — sha512 hash is computed in-stream and compared to `SOURCE_HASH`.
|
|
- **Sandbox** — `sandbox.New` mounts an OverlayFS at `/var/lib/sorcery-go/build/busybox-<taskID>/`.
|
|
- **Unpack** — `tar -xf` extracts the source into the merged view.
|
|
- **ICE** — `cast.RunICE` parses `CONFIGURE` for `config_query` directives and prompts (or uses `--default` to accept defaults).
|
|
- **Build** — `bash -e BUILD` runs inside the sandbox with `CLONE_NEWNS | CLONE_NEWUTS`.
|
|
- **Collect** — `filepath.Walk` of the OverlayFS `upper` dir produces the manifest.
|
|
- **Ingest** — every file is sha256-hashed and copied into `/var/lib/sorcery-go/tomb/blobs/<ab>/<hash>`.
|
|
- **Seal** — the Sarcophagus epitaph (JSON) is written to `tomb/epitaphs/<merkleRoot>.json`.
|
|
- **Journal** — the bbolt Journal bucket records `StateInstalled`.
|
|
|
|
5. `sorcery-go gaze install busybox` lists every file owned by the Essence.
|
|
6. `sorcery-go tomb list` shows the new Essence in the Tomb.
|
|
|
|
## 5. Launch the Coven Mirror WebUI
|
|
|
|
```bash
|
|
sudo sorcery-go web --port 8080
|
|
```
|
|
|
|
Open `http://localhost:8080` in a browser. You'll see:
|
|
- **Grimoire** tab — every spell in the index, searchable.
|
|
- **Tomb** tab — every Essence, with its Merkle seal.
|
|
- **Pulse** tab — Coven node list (just `self` until you join a cluster).
|
|
- **Sanctum** tab — Warding status (green when eBPF Tomb Guard is active).
|
|
- **Portable Bin** tab — static ELF downloads.
|
|
- **Compliance** tab — license heatmap + SBOM export.
|
|
|
|
The WebUI's `POST /api/v1/cast` triggers a real cast pipeline; the
|
|
`/api/v1/stream/{id}` WebSocket streams real-time log lines from the
|
|
EventBus to the browser.
|
|
|
|
## 6. Coexistence with legacy Bash sorcery
|
|
|
|
Both tools can run side-by-side indefinitely:
|
|
|
|
| Concern | Bash sorcery | Sorcery-Go |
|
|
|---------|--------------|------------|
|
|
| Binary | `/usr/sbin/cast` | `/usr/local/sbin/sorcery-go` |
|
|
| State | `/var/lib/sorcery/` | `/var/lib/sorcery-go/` |
|
|
| Spool | `/var/spool/sorcery/` | `/var/spool/sorcery-go/` |
|
|
| Grimoire | `/var/lib/sorcery/codex/grimoire` (shared, read-only) | same |
|
|
| Spell format | Bash scripts | same (we source them via bash) |
|
|
|
|
The grimoire is read-only for both tools — neither modifies spell files.
|
|
You can switch between them freely:
|
|
|
|
```bash
|
|
sudo cast wget # legacy Bash cast
|
|
sudo sorcery-go cast wget # new Go cast
|
|
```
|
|
|
|
The Go binary's state (Tomb, Tablet, Journal) is completely separate, so
|
|
a broken Go cast never affects the Bash install and vice versa.
|
|
|
|
## 7. Uninstall
|
|
|
|
```bash
|
|
sudo make uninstall # removes /usr/local/sbin/sorcery-go
|
|
sudo rm -rf /var/lib/sorcery-go # removes all Go state (Tomb, Tablet, Journal)
|
|
sudo rm -rf /var/spool/sorcery-go # removes cached source tarballs
|
|
```
|
|
|
|
The legacy Bash sorcery is untouched.
|
|
|
|
## Troubleshooting
|
|
|
|
### "sandbox: overlay mount failed"
|
|
You're not root, or your kernel lacks `CONFIG_OVERLAY_FS`. The pipeline
|
|
falls back to a plain-dir mode automatically — builds still work, they're
|
|
just slightly slower (manifest is collected by diffing before/after).
|
|
|
|
### "summon: hash mismatch"
|
|
The `SOURCE_HASH` in the spell's DETAILS doesn't match what's currently
|
|
being served at the `SOURCE_URL`. Upstream may have re-rolled the tarball.
|
|
Re-compute the hash with `sha512sum wget-1.21.4.tar.gz` and update DETAILS.
|
|
|
|
### "pgp: no GOODSIG in gpg output"
|
|
The DETAILS file is signed but the signing key isn't in your keyring.
|
|
Either import the key (`gpg --import <key>`) or unset
|
|
`SORCERY_GO_PGP_KEYRING` to disable PGP attestation.
|
|
|
|
### "legal: license X is blacklisted"
|
|
Your active posture blocks the spell's license. Switch posture:
|
|
```bash
|
|
sudo SORCERY_GO_POSTURE=lawless sorcery-go cast <spell>
|
|
```
|
|
Or persist the change in `/etc/sorcery-go/env`.
|