One-shot install.sh for a fresh Pi; retire setup.sh (node-26#4) #5

Merged
logan merged 1 commits from feat/one-shot-install into main 2026-09-06 19:29:31 -04:00
Owner

Addresses node-26#4.

install.sh is the curl -fsSL <url> | sudo bash -s -- --token … bootstrap for a clean Raspberry Pi OS:

  1. Preflight — root / arch / apt / SDR dongle
  2. Install Docker + compose plugin + git + jq
  3. Clone node-26 at a pinned ref (default v1, --track-main opt-in) into /opt/drb/node-26
  4. Write .env non-interactively from flags/env, with a /dev/tty interactive fallback (necessary — stdin is the pipe under curl | bash)
  5. Enroll: POST /nodes/enroll → poll GET /nodes/{id}/credentials → write configs/credentials.json. Verified against drb-c2-core/app/routers/enrollment.py — headers (X-Enrollment-Token, X-Pickup-Secret), request/response fields, and the 401/403/429 semantics all match.
  6. docker compose pull && up -d — prebuilt by default; --build opts into the ~1h op25 build
  7. Print the admin-approval step

Idempotent: re-run preserves .env, skips enrollment if a key is on disk, picks up the api_key after approval.

Also:

  • setup.sh deleted — two scripts writing .env drift.
  • Makefile setup: no longer calls the removed script.
  • README.md Setup section rewritten around the one-liner; make setup / make up kept as the local-dev path.

After merge: re-cut v1 at the merge commit so the tag actually contains install.sh (git tag -f v1 <merge-sha> && git push -f origin v1). The images (:latest/:stable) are unaffected — this touches no drb-edge-node/** or op25-container/** path.

Not addressed (follow-ups):

  • Client-side enrollment belongs in the edge-node app (mqtt_manager.py:73-85); install.sh doing it is interim.
  • Standing hazard D3 (script header): docker-compose.yml bind-mounts app source over the image, so a pinned ref and the pulled image tags must not diverge.
  • install.sh is bash -n clean but has not been run on a real clean Pi OS image — the RTL-SDR kernel-module path is unverified.

🤖 Generated with Claude Code

Addresses node-26#4. `install.sh` is the `curl -fsSL <url> | sudo bash -s -- --token …` bootstrap for a clean Raspberry Pi OS: 1. Preflight — root / arch / apt / SDR dongle 2. Install Docker + compose plugin + git + jq 3. Clone `node-26` at a **pinned ref** (default `v1`, `--track-main` opt-in) into `/opt/drb/node-26` 4. Write `.env` non-interactively from flags/env, with a `/dev/tty` interactive fallback (necessary — stdin is the pipe under `curl | bash`) 5. **Enroll**: `POST /nodes/enroll` → poll `GET /nodes/{id}/credentials` → write `configs/credentials.json`. Verified against `drb-c2-core/app/routers/enrollment.py` — headers (`X-Enrollment-Token`, `X-Pickup-Secret`), request/response fields, and the 401/403/429 semantics all match. 6. `docker compose pull && up -d` — prebuilt by default; `--build` opts into the ~1h op25 build 7. Print the admin-approval step Idempotent: re-run preserves `.env`, skips enrollment if a key is on disk, picks up the `api_key` after approval. **Also:** - `setup.sh` deleted — two scripts writing `.env` drift. - `Makefile` `setup:` no longer calls the removed script. - `README.md` Setup section rewritten around the one-liner; `make setup` / `make up` kept as the local-dev path. **After merge:** re-cut `v1` at the merge commit so the tag actually contains `install.sh` (`git tag -f v1 <merge-sha> && git push -f origin v1`). The images (`:latest`/`:stable`) are unaffected — this touches no `drb-edge-node/**` or `op25-container/**` path. **Not addressed (follow-ups):** - Client-side enrollment belongs in the edge-node app (`mqtt_manager.py:73-85`); `install.sh` doing it is interim. - Standing hazard D3 (script header): `docker-compose.yml` bind-mounts app source over the image, so a pinned ref and the pulled image tags must not diverge. - `install.sh` is `bash -n` clean but has not been run on a real clean Pi OS image — the RTL-SDR kernel-module path is unverified. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
logan added 1 commit 2026-09-06 19:15:00 -04:00
node: one-shot install.sh for a fresh Pi; retire setup.sh (node-26#4)
CI / lint (pull_request) Successful in 10s
CI / lint (push) Successful in 11s
CI / test (pull_request) Successful in 46s
CI / test (push) Successful in 46s
5b0048e8db
install.sh is the `curl -fsSL <url> | sudo bash -s -- --token ...` bootstrap:
preflight (root/arch/apt/SDR) → install docker + compose + git + jq → clone
node-26 at a pinned ref (default `v1`, `--track-main` opt-in) → write .env
non-interactively from flags/env with a /dev/tty interactive fallback →
enroll with C2 (POST /nodes/enroll, poll GET /nodes/{id}/credentials, matches
drb-c2-core/app/routers/enrollment.py exactly) and write configs/credentials.json
→ docker compose pull && up -d (prebuilt; --build opts into the ~1h op25 build)
→ print the admin-approval step. Idempotent: re-run picks up the api_key after
approval; existing .env is preserved.

- setup.sh deleted — two scripts writing .env drift. install.sh owns it now.
- Makefile `setup:` no longer calls the removed script (cp .env.example fallback).
- README Setup section rewritten around the one-liner; `make setup`/`make up`
  kept as the local-dev path.

Notes carried in the script header: git.vpn.cusano.net is public (D1, settled);
`v1` must be re-cut at this change's merge commit so the tag actually contains
install.sh. Standing hazard D3: docker-compose.yml bind-mounts the app source
over the image, so a pinned ref and the pulled image tags must not diverge.

Client-side enrollment still belongs in the edge-node app (mqtt_manager.py:73-85);
install.sh doing it is the interim. Tracked for follow-up.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
logan merged commit 94c3e2a952 into main 2026-09-06 19:29:31 -04:00
logan deleted branch feat/one-shot-install 2026-09-06 19:29:33 -04:00
Sign in to join this conversation.
No Reviewers
No labels
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: logan/node-26#5