diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index bfbaec2..fc50074 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -9,6 +9,6 @@ jobs: steps: - uses: actions/checkout@v4 - name: shellcheck - run: shellcheck install.sh bin/deployor commands/*.sh test/cli.sh + run: shellcheck install.sh bin/rig commands/*.sh test/cli.sh - name: cli tests run: bash test/cli.sh diff --git a/README.md b/README.md index ac5ccd8..c3ff72d 100644 --- a/README.md +++ b/README.md @@ -1,33 +1,33 @@ -# deployor +# rig A CLI that turns a **pristine Debian server into a hardened, tailnet-joined node** — one curl, one command. A second command installs a version-pinned Coolify on a control-plane box. Philosophy (shared with [claudebox](https://github.com/heavy-duty/claudebox)): -**public tool, private state**. deployor carries plumbing logic only — no +**public tool, private state**. rig carries plumbing logic only — no hostnames, no bindings, no secrets, nothing about *your* infrastructure. It takes arguments, does its work, and stores no credential, ever. ## Install ```sh -curl -fsSL https://raw.githubusercontent.com/claude-hdb/deployor/main/install.sh | bash +curl -fsSL https://raw.githubusercontent.com/heavy-duty/rig/main/install.sh | bash ``` -Installs the tree to `~/.local/share/deployor` and links `deployor` onto your +Installs the tree to `~/.local/share/rig` and links `rig` onto your PATH (`/usr/local/bin` when root). Re-run any time to upgrade. ## Commands -### `deployor bootstrap ` +### `rig bootstrap ` Run as root on the fresh box (over SSH). Convergent — safe to re-run; a second run changes nothing. ```sh -deployor bootstrap control-plane --hostname my-coolify-box -deployor bootstrap workload --hostname my-prod-box +rig bootstrap control-plane --hostname my-coolify-box +rig bootstrap workload --hostname my-prod-box ``` - `--hostname ` — tailnet hostname (default: the role name) @@ -40,28 +40,28 @@ tailscale and joins your tailnet. **The pre-auth key:** provide it via the `TS_AUTHKEY` env var or type it at the interactive prompt. Use a **single-use, tagged, short-expiry** key. It -lives in process memory only — deployor never writes a credential to disk. +lives in process memory only — rig never writes a credential to disk. The two roles are identical today except the default hostname; they exist because control-plane and workload boxes diverge over time, and because the next command applies to exactly one of them. -### `deployor coolify install --version ` +### `rig coolify install --version ` Control-plane box only. Installs Coolify at exactly the pinned version with `AUTOUPDATE=false` — your deploy tooling is verified against an API surface; the platform must never move underneath it on its own. Upgrading is an explicit re-run with a new pin. The pin is required; there is no default. -## What deployor deliberately does NOT do +## What rig deliberately does NOT do - **Provider firewalls** — Docker publishes ports past host firewalls, so the real boundary is your cloud provider's firewall, configured outside this tool. - **Fetch your config** — boxes never receive repo credentials. Everything - deployor needs arrives as arguments or an interactive prompt. + rig needs arrives as arguments or an interactive prompt. - **Manage deployments** — deploy manifests/executors are separate concerns. - (Planned: the `apply`/`diff` executor half joins deployor as commands that + (Planned: the `apply`/`diff` executor half joins rig as commands that run on operator machines, never on boxes.) ## Testing diff --git a/bin/deployor b/bin/rig similarity index 84% rename from bin/deployor rename to bin/rig index ed41c69..286ab12 100755 --- a/bin/deployor +++ b/bin/rig @@ -5,7 +5,7 @@ ROOT="$(cd "$(dirname "$(readlink -f "${BASH_SOURCE[0]}")")/.." && pwd)" usage() { cat <<'EOF' -usage: deployor [args] +usage: rig [args] commands: bootstrap [--hostname ] [--ts-tag ] @@ -16,7 +16,7 @@ commands: Pinned Coolify install (AUTOUPDATE=false). Control-plane box only. install/upgrade: - curl -fsSL https://raw.githubusercontent.com/claude-hdb/deployor/main/install.sh | bash + curl -fsSL https://raw.githubusercontent.com/heavy-duty/rig/main/install.sh | bash EOF } @@ -45,7 +45,7 @@ case "$cmd" in exit 2 ;; *) - printf 'deployor: unknown command: %s\n' "$cmd" >&2 + printf 'rig: unknown command: %s\n' "$cmd" >&2 usage >&2 exit 2 ;; diff --git a/commands/bootstrap.sh b/commands/bootstrap.sh index 817e4c4..4b82fc5 100755 --- a/commands/bootstrap.sh +++ b/commands/bootstrap.sh @@ -1,15 +1,15 @@ #!/usr/bin/env bash -# deployor bootstrap — OS plumbing for a pristine Debian box. +# rig bootstrap — OS plumbing for a pristine Debian box. # Convergent: safe to re-run; a second run changes nothing. set -euo pipefail -log() { printf 'deployor-bootstrap: %s\n' "$*"; } -warn() { printf 'deployor-bootstrap: WARNING: %s\n' "$*" >&2; } -die() { printf 'deployor-bootstrap: ERROR: %s\n' "$1" >&2; exit "${2:-1}"; } +log() { printf 'rig-bootstrap: %s\n' "$*"; } +warn() { printf 'rig-bootstrap: WARNING: %s\n' "$*" >&2; } +die() { printf 'rig-bootstrap: ERROR: %s\n' "$1" >&2; exit "${2:-1}"; } usage() { cat <<'EOF' -usage: deployor bootstrap [--hostname ] [--ts-tag ] +usage: rig bootstrap [--hostname ] [--ts-tag ] --hostname tailnet hostname (default: the role name) --ts-tag tailnet tag to advertise (default: tag:server) @@ -75,7 +75,7 @@ APT::Periodic::Unattended-Upgrade "1"; EOF # --- sshd hardening (restart only when the drop-in actually changed) --------- -DROPIN=/etc/ssh/sshd_config.d/99-deployor.conf +DROPIN=/etc/ssh/sshd_config.d/99-rig.conf TMP="$(mktemp)" cat > "$TMP" <<'EOF' PermitRootLogin prohibit-password @@ -104,5 +104,5 @@ fi log "done — role ${ROLE}, hostname ${TS_HOSTNAME}" if [ "$ROLE" = "control-plane" ]; then - log "next: deployor coolify install --version " + log "next: rig coolify install --version " fi diff --git a/commands/coolify-install.sh b/commands/coolify-install.sh index 5ef862e..4e6d915 100755 --- a/commands/coolify-install.sh +++ b/commands/coolify-install.sh @@ -1,15 +1,15 @@ #!/usr/bin/env bash -# deployor coolify install — pinned Coolify install; AUTOUPDATE=false so the +# rig coolify install — pinned Coolify install; AUTOUPDATE=false so the # platform never self-updates underneath its operators. Upgrades are an # explicit act. set -euo pipefail -log() { printf 'deployor-coolify: %s\n' "$*"; } -die() { printf 'deployor-coolify: ERROR: %s\n' "$1" >&2; exit "${2:-1}"; } +log() { printf 'rig-coolify: %s\n' "$*"; } +die() { printf 'rig-coolify: ERROR: %s\n' "$1" >&2; exit "${2:-1}"; } usage() { cat <<'EOF' -usage: deployor coolify install --version +usage: rig coolify install --version Installs Coolify at exactly (e.g. 4.1.2) with AUTOUPDATE=false. Control-plane box only. The version pin is required — you state the floor diff --git a/install.sh b/install.sh index 3191097..e10f9db 100644 --- a/install.sh +++ b/install.sh @@ -1,24 +1,24 @@ #!/usr/bin/env bash set -euo pipefail -# deployor installer — intended for: curl -fsSL .../install.sh | bash +# rig installer — intended for: curl -fsSL .../install.sh | bash # -# Downloads the deployor repo tarball, installs the whole tree under $DEST, -# and puts a `deployor` symlink on PATH via $BINDIR. Re-run any time to +# Downloads the rig repo tarball, installs the whole tree under $DEST, +# and puts a `rig` symlink on PATH via $BINDIR. Re-run any time to # upgrade. -REPO="${DEPLOYOR_REPO:-claude-hdb/deployor}" -REF="${DEPLOYOR_REF:-main}" -DEST="${DEPLOYOR_HOME:-$HOME/.local/share/deployor}" +REPO="${RIG_REPO:-heavy-duty/rig}" +REF="${RIG_REF:-main}" +DEST="${RIG_HOME:-$HOME/.local/share/rig}" if [ "$(id -u)" -eq 0 ]; then - BINDIR="${DEPLOYOR_BIN:-/usr/local/bin}" + BINDIR="${RIG_BIN:-/usr/local/bin}" else - BINDIR="${DEPLOYOR_BIN:-$HOME/.local/bin}" + BINDIR="${RIG_BIN:-$HOME/.local/bin}" fi -log() { printf 'deployor-install: %s\n' "$*"; } -warn() { printf 'deployor-install: WARNING: %s\n' "$*" >&2; } -die() { printf 'deployor-install: ERROR: %s\n' "$*" >&2; exit 1; } +log() { printf 'rig-install: %s\n' "$*"; } +warn() { printf 'rig-install: WARNING: %s\n' "$*" >&2; } +die() { printf 'rig-install: ERROR: %s\n' "$*" >&2; exit 1; } # --- prerequisites ----------------------------------------------------------- command -v curl >/dev/null 2>&1 || die "curl is required but was not found." @@ -31,19 +31,19 @@ trap cleanup EXIT URL="https://github.com/$REPO/archive/refs/heads/$REF.tar.gz" -log "installing deployor ($REPO@$REF)" +log "installing rig ($REPO@$REF)" log "downloading $URL" -curl -fsSL "$URL" -o "$TMPDIR/deployor.tar.gz" \ +curl -fsSL "$URL" -o "$TMPDIR/rig.tar.gz" \ || die "failed to download $URL" log "extracting archive" -tar -xzf "$TMPDIR/deployor.tar.gz" -C "$TMPDIR" \ +tar -xzf "$TMPDIR/rig.tar.gz" -C "$TMPDIR" \ || die "failed to extract archive" -# GitHub archives extract to a single top-level dir like deployor-/ -EXTRACTED="$(find "$TMPDIR" -maxdepth 1 -type d -name 'deployor-*' | head -n1)" -[ -n "$EXTRACTED" ] || die "could not find extracted deployor-* directory in archive" -[ -f "$EXTRACTED/bin/deployor" ] || die "archive does not contain bin/deployor — is $REPO@$REF correct?" +# GitHub archives extract to a single top-level dir like rig-/ +EXTRACTED="$(find "$TMPDIR" -maxdepth 1 -type d -name 'rig-*' | head -n1)" +[ -n "$EXTRACTED" ] || die "could not find extracted rig-* directory in archive" +[ -f "$EXTRACTED/bin/rig" ] || die "archive does not contain bin/rig — is $REPO@$REF correct?" # --- atomically replace $DEST -------------------------------------------------- log "installing into $DEST" @@ -51,12 +51,12 @@ rm -rf "$DEST" mkdir -p "$(dirname "$DEST")" mv "$EXTRACTED" "$DEST" -chmod +x "$DEST/bin/deployor" "$DEST"/commands/*.sh +chmod +x "$DEST/bin/rig" "$DEST"/commands/*.sh -# --- put deployor on PATH ------------------------------------------------------ +# --- put rig on PATH ------------------------------------------------------ mkdir -p "$BINDIR" -ln -sf "$DEST/bin/deployor" "$BINDIR/deployor" -log "linked $BINDIR/deployor -> $DEST/bin/deployor" +ln -sf "$DEST/bin/rig" "$BINDIR/rig" +log "linked $BINDIR/rig -> $DEST/bin/rig" # --- PATH check ---------------------------------------------------------------- case ":$PATH:" in @@ -67,4 +67,4 @@ case ":$PATH:" in ;; esac -log "done — try: deployor --help" +log "done — try: rig --help" diff --git a/test/cli.sh b/test/cli.sh index 6cd0ee0..df81a0f 100644 --- a/test/cli.sh +++ b/test/cli.sh @@ -25,11 +25,11 @@ check() { echo "ok: $desc"; PASS=$((PASS + 1)) } -check "no args shows usage, exit 2" 2 "usage:" "$ROOT/bin/deployor" -check "--help exits 0" 0 "usage:" "$ROOT/bin/deployor" --help -check "help exits 0" 0 "usage:" "$ROOT/bin/deployor" help -check "unknown command exits 2" 2 "unknown command" "$ROOT/bin/deployor" frobnicate -check "bare coolify shows usage, exit 2" 2 "usage:" "$ROOT/bin/deployor" coolify +check "no args shows usage, exit 2" 2 "usage:" "$ROOT/bin/rig" +check "--help exits 0" 0 "usage:" "$ROOT/bin/rig" --help +check "help exits 0" 0 "usage:" "$ROOT/bin/rig" help +check "unknown command exits 2" 2 "unknown command" "$ROOT/bin/rig" frobnicate +check "bare coolify shows usage, exit 2" 2 "usage:" "$ROOT/bin/rig" coolify check "bootstrap: role required, exit 2" 2 "role required" "$ROOT/commands/bootstrap.sh" check "bootstrap: --help exits 0" 0 "usage:" "$ROOT/commands/bootstrap.sh" --help