From 7530468d80c9464813eae435324940bafab53cc2 Mon Sep 17 00:00:00 2001 From: Bernd Worsch Date: Sat, 13 Sep 2025 02:39:47 +0200 Subject: [PATCH] refactor: separated command script --- bin/railiance | 42 +++++++++-------------------- lib/railiance-print.sh | 8 ++++++ tools/cmd/railiance-doctor | 55 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 76 insertions(+), 29 deletions(-) create mode 100644 lib/railiance-print.sh create mode 100644 tools/cmd/railiance-doctor diff --git a/bin/railiance b/bin/railiance index c1b38c0..1f139cf 100644 --- a/bin/railiance +++ b/bin/railiance @@ -1,62 +1,46 @@ #!/usr/bin/env bash -# bin/railiance — Rails-style CLI entrypoint for Railiance +# bin/railiance — thin dispatcher; subcommands live in tools/cmd/* set -euo pipefail ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" +PATH="${ROOT}/tools/cmd:${PATH}" usage() { cat <<'EOF' -Usage: bin/railiance +Usage: bin/railiance [args] Commands: + doctor Check workstation & provisioning toolchains next Show canonical first-time sequence - doctor Check local prerequisites (git, curl, jq, ansible) - plan-host Print provider-neutral host specs & checklist - gen-ssh-key Generate an SSH key (ed25519) and print pubkey + plan-host Provider-neutral host specs & checklist + gen-ssh-key Generate SSH key and show public part cloudinit Emit minimal cloud-init user-data init-repo Idempotently furnish repo housekeeping build-spore Build a distributable "Spore" bundle seed-local Run the seed script on this machine - checklist Print a pre-VM checklist + checklist Pre-VM checklist help Show this help EOF } -cmd="${1:-help}" - -need(){ command -v "$1" >/dev/null 2>&1 || { echo "Missing: $1" >&2; exit 1; }; } +cmd="${1:-help}"; shift || true case "$cmd" in help) usage ;; - next) cat "$ROOT/docs/first_host.md" ;; - doctor) - for c in git curl jq; do - command -v "$c" >/dev/null && echo "OK: $c" || { echo "Missing: $c"; exit 1; } - done - command -v ansible >/dev/null && echo "OK: ansible" || echo "Note: ansible not found (only needed for host bootstrap)" - ;; + doctor) exec railiance-doctor "$@" ;; plan-host) sed -n '1,200p' "$ROOT/docs/first_host.md" | sed -n '/^## 2\) Choose/,/^## 3\)/p' ;; gen-ssh-key) - need ssh-keygen + if ! command -v ssh-keygen >/dev/null 2>&1; then echo "Missing: ssh-keygen" >&2; exit 1; fi key="${HOME}/.ssh/id_ed25519" [[ -f "$key" ]] || ssh-keygen -t ed25519 -N "" -f "$key" - echo "Public key:" - cat "${key}.pub" + echo "Public key:"; cat "${key}.pub" ;; cloudinit) cat "$ROOT/cloudinit/user-data.yaml" ;; init-repo) bash "$ROOT/tools/furnish_railiance_repo.sh" ;; build-spore) bash "$ROOT/tools/build_spore.sh" ;; seed-local) bash "$ROOT/tools/seed_node.sh" ;; - init-inventory) - if [[ -f "$ROOT/ansible/hosts.ini" ]]; then - echo "ansible/hosts.ini already exists." - else - cp "$ROOT/ansible/hosts.ini.example" "$ROOT/ansible/hosts.ini" - echo "Created ansible/hosts.ini from example." - fi - ;; checklist) cat <<'CK' Rent-a-VM Checklist @@ -66,11 +50,11 @@ Rent-a-VM Checklist [ ] Image: Ubuntu 24.04 LTS [ ] Size: 2 vCPU / 4–8 GB RAM / 60+ GB SSD [ ] SSH key uploaded (see gen-ssh-key) - - Run: bin/railiance gen-ssh-key [ ] Cloud-init pasted (see: bin/railiance cloudinit) [ ] Hostname set (e.g., railiance-seed-1) [ ] Record public IP / DNS CK ;; - *) usage; exit 2 ;; + next) cat "$ROOT/QUICKSTART.md" ;; + *) echo "Unknown command: $cmd" >&2; usage; exit 2 ;; esac diff --git a/lib/railiance-print.sh b/lib/railiance-print.sh new file mode 100644 index 0000000..22a977b --- /dev/null +++ b/lib/railiance-print.sh @@ -0,0 +1,8 @@ +#!/usr/bin/env bash +# tools/lib/railiance-print.sh — shared pretty printers +set -euo pipefail + +print_hdr() { printf "\n%s\n" "$1"; printf "%0.s-" $(seq 1 "${#1}"); echo; } +ok() { printf " ✅ %-10s %s\n" "$1" "$2"; } +warn() { printf " ⚠️ %-10s %s\n" "$1" "$2"; } +bad() { printf " ❌ %-10s %s\n" "$1" "$2"; } diff --git a/tools/cmd/railiance-doctor b/tools/cmd/railiance-doctor new file mode 100644 index 0000000..6720eed --- /dev/null +++ b/tools/cmd/railiance-doctor @@ -0,0 +1,55 @@ +#!/usr/bin/env bash +# tools/cmd/railiance-doctor — workstation & provisioning toolchain checks +set -euo pipefail + +ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)" +source "${ROOT}/lib/railiance-print.sh" + +ver() { + local cmd="$1" out="" + if command -v "$cmd" >/dev/null 2>&1; then + out="$("$cmd" --version 2>/dev/null || "$cmd" -V 2>/dev/null || "$cmd" version 2>/dev/null || true)" + echo "$out" | head -n1 + else + echo "" + fi +} +have(){ command -v "$1" >/dev/null 2>&1; } + +OP_REQ=(curl git jq python3 ssh) +PROV_REQ=(ansible) +PROV_OPT=(age docker helm kubectl kustomize podman rsync scp sops tar yq) + +missing_req=0 + +print_hdr "Operator toolchain (required on your workstation)" +for cmd in "${OP_REQ[@]}"; do + if have "$cmd"; then ok "$cmd" "$(ver "$cmd")"; else bad "$cmd" "missing"; missing_req=1; fi +done + +print_hdr "Provisioning toolchain" +for cmd in "${PROV_REQ[@]}"; do + if have "$cmd"; then ok "$cmd" "$(ver "$cmd")"; else bad "$cmd" "missing (needed to run playbooks)"; missing_req=1; fi +done +for cmd in "${PROV_OPT[@]}"; do + if have "$cmd"; then ok "$cmd" "$(ver "$cmd")"; else warn "$cmd" "not installed (only needed if you use related features)"; fi +done + +cat <<'NOTE' + +Notes: +- Operator tools are needed on your local machine to drive Railiance. +- Provisioning: + • ansible — required to bootstrap hosts + • kubectl/helm/kustomize — needed once Kubernetes is up + • sops/age — for managing encrypted secrets (recommended) + • docker or podman — only if building images locally + • yq — handy for YAML manipulation in scripts + • rsync/scp/tar — file transfer & packaging utilities + +TIP: On Debian/Ubuntu install basics with: + sudo apt-get update && sudo apt-get install -y \ + curl git jq python3 openssh-client ansible rsync tar +NOTE + +exit $missing_req