One-line install: a node still needs a manual git clone before setup.sh can run #4

Open
opened 2026-08-23 12:57:52 -04:00 by logan · 3 comments
Owner

Bringing a node online is currently: clone the repo by hand, cp .env.example .env, run bash setup.sh, answer its prompts, then make up. The product copy promises something quite different — drb-frontend/app/page.tsx:39 says "Deploy a node — point a field SDR node at your local P25 or analog system", and the closing CTA says a user can "add a node, and start seeing incidents within minutes of your first call". There is no path that matches that.

What exists. Client/setup.sh already does most of the real work: installs Docker/make/curl via apt, writes .env, optionally builds and starts the stack. But it begins with cd "$(dirname "$0")" — it assumes the repo is already on the machine, so it cannot be the thing a user runs first. It is also fully interactive, which rules out an unattended flash-and-boot.

What's missing is the step before it, and the credential plumbing:

curl -fsSL https://drb.cusano.net/install.sh | bash -s -- --token DRB-xxxxxxxx

That should: install prerequisites, fetch the node repo (or a release tarball) to a known path, write .env with the enrollment token and the C2 URL baked in, and bring the stack up — with no prompts when --token is supplied.

The token half already works. Per-org enrollment tokens exist (server-26 routers/enrollment.py, X-Enrollment-Token), are minted from Settings → Nodes, and a node presents one to POST /nodes/enroll to land in the right org. So the one-liner has a natural credential to carry, and this is what turns "clone and configure" into "paste one command".

The frontend half is small and belongs with it: drb-frontend/app/settings/nodes/page.tsx:87 currently shows the raw token with "copy it now, it won't be shown again". It should show the whole install command with the token already in it, since that is the only thing anyone does with the token. Filing here because the script is the substantial part; the frontend change is a few lines once the URL is settled.

Worth deciding as part of this:

  • Where install.sh is hosted. Caddy already fronts the domain, so serving one static file is the cheap option; the alternative is raw.git.vpn.cusano.net, which is not public.
  • Whether it pins a release or tracks main. A one-liner that tracks main means a node installed today and one installed next month are different software.
  • Whether setup.sh keeps its interactive mode or becomes the non-interactive tail of install.sh with flags. Two scripts that both write .env will drift.
  • Re-run behaviour: the same command on an already-installed node should update it, not clobber a working .env.
Bringing a node online is currently: clone the repo by hand, `cp .env.example .env`, run `bash setup.sh`, answer its prompts, then `make up`. The product copy promises something quite different — `drb-frontend/app/page.tsx:39` says "Deploy a node — point a field SDR node at your local P25 or analog system", and the closing CTA says a user can "add a node, and start seeing incidents within minutes of your first call". There is no path that matches that. **What exists.** `Client/setup.sh` already does most of the real work: installs Docker/make/curl via apt, writes `.env`, optionally builds and starts the stack. But it begins with `cd "$(dirname "$0")"` — it assumes the repo is already on the machine, so it cannot be the thing a user runs first. It is also fully interactive, which rules out an unattended flash-and-boot. **What's missing** is the step before it, and the credential plumbing: ``` curl -fsSL https://drb.cusano.net/install.sh | bash -s -- --token DRB-xxxxxxxx ``` That should: install prerequisites, fetch the node repo (or a release tarball) to a known path, write `.env` with the enrollment token and the C2 URL baked in, and bring the stack up — with no prompts when `--token` is supplied. **The token half already works.** Per-org enrollment tokens exist (`server-26` `routers/enrollment.py`, `X-Enrollment-Token`), are minted from Settings → Nodes, and a node presents one to `POST /nodes/enroll` to land in the right org. So the one-liner has a natural credential to carry, and this is what turns "clone and configure" into "paste one command". The frontend half is small and belongs with it: `drb-frontend/app/settings/nodes/page.tsx:87` currently shows the raw token with "copy it now, it won't be shown again". It should show the **whole install command** with the token already in it, since that is the only thing anyone does with the token. Filing here because the script is the substantial part; the frontend change is a few lines once the URL is settled. Worth deciding as part of this: - Where `install.sh` is hosted. Caddy already fronts the domain, so serving one static file is the cheap option; the alternative is `raw.git.vpn.cusano.net`, which is not public. - Whether it pins a release or tracks `main`. A one-liner that tracks `main` means a node installed today and one installed next month are different software. - Whether `setup.sh` keeps its interactive mode or becomes the non-interactive tail of `install.sh` with flags. Two scripts that both write `.env` will drift. - Re-run behaviour: the same command on an already-installed node should update it, not clobber a working `.env`.
Author
Owner

Deferred by board minutes #62 (2026-08-24), with a reason. Label board:agenda removed. Revisit at the first signed customer.

CTO draft (server-26#60 rec. 8): Gate A blocks publishing any price, so there is no self-serve customer to onboard. Building install automation now is ahead of the funnel - it would be finished work sitting idle behind a gate that has not moved. COO wanted it done this week; overruled on sequencing, not on merit.

This is a deferral with a trigger, not a shelving: the first signed customer reopens it.

Binding condition if it ever proceeds, from CISO (server-26#61): the enrollment token must never appear as a plaintext CLI argument - shell history and ps both expose it. Design for stdin or a file path.

Refs server-26#62.

**Deferred by board minutes #62 (2026-08-24), with a reason. Label `board:agenda` removed. Revisit at the first signed customer.** CTO draft (server-26#60 rec. 8): Gate A blocks publishing any price, so there is no self-serve customer to onboard. Building install automation now is ahead of the funnel - it would be finished work sitting idle behind a gate that has not moved. COO wanted it done this week; overruled on sequencing, not on merit. This is a deferral with a trigger, not a shelving: **the first signed customer reopens it.** Binding condition if it ever proceeds, from CISO (server-26#61): **the enrollment token must never appear as a plaintext CLI argument** - shell history and `ps` both expose it. Design for stdin or a file path. Refs server-26#62.
Author
Owner

Board ruling — server-26 FINAL MINUTES #97, 2026-09-01. Held, with a date for its date.

This is blocked on a hosting decision for install.sh and a pin-vs-track-main call (DEFERRED.md), and it is not on the path to the 2026-09-05 beachhead checkpoint. It stays held.

The COO (#90) was right that leaving it undated in the backlog is not a decision, so: this issue is re-dated at the 2026-09-05 sitting, not before. Owner: COO (#97 D8). Holding an item is legitimate; holding it undated is not, which is why the re-dating itself now has a date.

Note for whoever picks it up: the marketing copy already promises add a node, and start seeing incidents within minutes, and the real path is clone, copy .env, answer prompts. That gap is a claims-accuracy problem as much as an onboarding one.

**Board ruling — server-26 FINAL MINUTES #97, 2026-09-01. Held, with a date for its date.** This is blocked on a hosting decision for `install.sh` and a pin-vs-track-main call (`DEFERRED.md`), and it is not on the path to the 2026-09-05 beachhead checkpoint. It stays held. The COO (#90) was right that leaving it undated in the backlog is not a decision, so: **this issue is re-dated at the 2026-09-05 sitting, not before. Owner: COO** (#97 D8). Holding an item is legitimate; holding it undated is not, which is why the re-dating itself now has a date. Note for whoever picks it up: the marketing copy already promises *add a node, and start seeing incidents within minutes*, and the real path is clone, copy `.env`, answer prompts. That gap is a claims-accuracy problem as much as an onboarding one.
Author
Owner

Both halves are up as PRs:

  • node-26 #5 (feat/one-shot-install) — install.sh one-shot bootstrap (preflight → docker → clone at pinned ref → .env → enroll via POST /nodes/enroll + credential poll, verified against enrollment.py → compose pull && up -d → approval step). setup.sh deleted; Makefile + README updated.
  • server-26 #106 (feat/mint-panel-install-command) — the mint panel renders the full paste-ready curl … | sudo bash line.

Owner TODO after both merge: re-cut v1 on node-26 at PR #5's merge commit so the tag contains install.sh (git tag -f v1 <sha> && git push -f origin v1). Run npm run typecheck in drb-frontend/ before merging #106 (not runnable in the authoring env).

Still open (own issues, not this one): client-side enrollment belongs in the edge-node app (mqtt_manager.py:73-85); compose source-overlay hazard (pinned ref vs image tags); install.sh unrun on a real clean Pi OS.

Both halves are up as PRs: - **node-26 #5** (`feat/one-shot-install`) — `install.sh` one-shot bootstrap (preflight → docker → clone at pinned ref → `.env` → enroll via `POST /nodes/enroll` + credential poll, verified against `enrollment.py` → `compose pull && up -d` → approval step). `setup.sh` deleted; Makefile + README updated. - **server-26 #106** (`feat/mint-panel-install-command`) — the mint panel renders the full paste-ready `curl … | sudo bash` line. **Owner TODO after both merge:** re-cut `v1` on node-26 at PR #5's merge commit so the tag contains `install.sh` (`git tag -f v1 <sha> && git push -f origin v1`). Run `npm run typecheck` in `drb-frontend/` before merging #106 (not runnable in the authoring env). **Still open** (own issues, not this one): client-side enrollment belongs in the edge-node app (`mqtt_manager.py:73-85`); compose source-overlay hazard (pinned ref vs image tags); `install.sh` unrun on a real clean Pi OS.
Sign in to join this conversation.
No labels
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: logan/node-26#4