morphit/scripts/validate-fresh-install.sh

156 lines
7.2 KiB
Bash
Executable file

#!/usr/bin/env bash
#
# validate-fresh-install.sh — exercise the Morphit install arc on a
# THROWAWAY Ubuntu 24.04 VM and report what works vs what breaks.
#
# PURPOSE
# We cannot certify "fresh box -> live node, no hiccups" from a dev
# sandbox — it needs a real machine. Run this on a disposable VM
# (a $5 droplet you delete after, or a local multipass/lxd/VM) to
# find the real-world gaps before an operator does. It is
# deliberately NOISY and NON-DESTRUCTIVE-ish: it installs packages
# and writes under /opt, so ONLY run it on a VM you will throw away.
#
# WHAT IT CHECKS, in order:
# 0. Confirms it's on Ubuntu 24.04 and you really meant to run it.
# 1. Prerequisites the installer expects (node>=22, npm, psql, git).
# 2. That `npx morphit-ops install` exists and its preflight runs.
# 3. The systemd unit installation path (the cp192 gap: units must
# be copied to /etc/systemd/system and enabled — verifies the
# shipped units load and the service names match the docs).
# 4. That `npx morphit-ops upgrade` can discover the latest release
# (the cp191 pre-release-discovery fix, against the live API).
#
# It does NOT fully configure a node (that needs Postgres creds, a
# Blurt account, keys). It validates the SCAFFOLDING and SEQUENCING —
# the parts that have been breaking — and prints a PASS/FAIL summary.
#
# USAGE
# git clone https://git.agorise.net/agorise/morphit.git
# cd morphit
# sudo bash scripts/validate-fresh-install.sh
#
set -uo pipefail
PASS=0
FAIL=0
WARN=0
note() { printf ' \033[36m·\033[0m %s\n' "$*"; }
ok() { printf ' \033[32m✓\033[0m %s\n' "$*"; PASS=$((PASS+1)); }
bad() { printf ' \033[31m✗\033[0m %s\n' "$*"; FAIL=$((FAIL+1)); }
warn() { printf ' \033[33m!\033[0m %s\n' "$*"; WARN=$((WARN+1)); }
hdr() { printf '\n\033[1m── %s ──\033[0m\n' "$*"; }
REPO_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
# ── 0. Safety + environment ──────────────────────────────────────
hdr "0. Environment & safety"
if [ -r /etc/os-release ]; then
. /etc/os-release
if [ "${ID:-}" = "ubuntu" ] && [ "${VERSION_ID:-}" = "24.04" ]; then
ok "Ubuntu 24.04 detected"
else
warn "Not Ubuntu 24.04 (found ${PRETTY_NAME:-unknown}) — results may differ from the supported target"
fi
else
warn "Cannot read /etc/os-release — proceeding, but this may not be a supported OS"
fi
if [ "${MORPHIT_VALIDATE_YES:-}" != "1" ]; then
printf '\n\033[33mThis installs packages and writes under /opt. Run ONLY on a throwaway VM.\033[0m\n'
printf 'Re-run with MORPHIT_VALIDATE_YES=1 to confirm:\n'
printf ' sudo MORPHIT_VALIDATE_YES=1 bash %s\n\n' "${BASH_SOURCE[0]}"
exit 2
fi
# ── 1. Prerequisites ─────────────────────────────────────────────
hdr "1. Prerequisites"
check_cmd() {
local name="$1" cmd="$2"
if command -v "$cmd" >/dev/null 2>&1; then
ok "$name present ($("$cmd" --version 2>&1 | head -1))"
else
bad "$name MISSING (install it: see docs/RUN-A-MORPHIT-NODE.md, or run the Ansible playbook in ops/ansible/)"
fi
}
check_cmd "Node.js" node
check_cmd "npm" npm
check_cmd "PostgreSQL client" psql
check_cmd "git" git
# Node major version >= 22
if command -v node >/dev/null 2>&1; then
NODE_MAJOR="$(node -p 'process.versions.node.split(".")[0]' 2>/dev/null || echo 0)"
if [ "${NODE_MAJOR:-0}" -ge 22 ]; then ok "Node major >= 22 (${NODE_MAJOR})"; else bad "Node major < 22 (${NODE_MAJOR}); install Node 22 LTS"; fi
fi
# ── 2. morphit-ops install exists + preflight runs ───────────────
hdr "2. morphit-ops install (the cp192 guided installer)"
cd "$REPO_DIR" || { bad "cannot cd to repo dir $REPO_DIR"; }
if [ ! -d node_modules ]; then
note "node_modules absent — running npm ci (one-time, needed for the CLI)"
npm ci --no-audit --no-fund >/tmp/morphit-npmci.log 2>&1 \
&& ok "npm ci succeeded" \
|| bad "npm ci FAILED (see /tmp/morphit-npmci.log)"
fi
# Does the install subcommand exist in THIS tree's CLI? (it won't in
# pre-cp192 releases — that's the sysadmin's "Unknown subcommand".)
if npx --no-install morphit-ops --help 2>&1 | grep -q "install"; then
ok "morphit-ops has an 'install' subcommand"
# Run its preflight non-interactively (answer 'no' to proceeding).
if printf 'n\n' | npx --no-install morphit-ops install 2>&1 | grep -q "checking prerequisites"; then
ok "morphit-ops install preflight runs"
else
bad "morphit-ops install preflight did not run as expected"
fi
else
bad "morphit-ops has NO 'install' subcommand — this tree predates cp192 (release built from cp192+ needed)"
fi
# ── 3. systemd unit installation (the gap the sysadmin hit) ──────
hdr "3. systemd units"
UNIT_SRC="$REPO_DIR/ops/systemd"
for unit in morphit-indexer.service morphit-relay.service; do
if [ -f "$UNIT_SRC/$unit" ]; then
ok "shipped unit present: ops/systemd/$unit"
# Verify systemd can parse it (analyze without enabling).
if systemd-analyze verify "$UNIT_SRC/$unit" >/tmp/morphit-unit-$unit.log 2>&1; then
ok "$unit parses cleanly (systemd-analyze verify)"
else
warn "$unit has analyze warnings (often just EnvironmentFile/WorkingDirectory not present yet on a fresh box) — see /tmp/morphit-unit-$unit.log"
fi
else
bad "shipped unit MISSING: ops/systemd/$unit"
fi
# Is it actually installed on this box?
if systemctl list-unit-files 2>/dev/null | grep -q "^$unit"; then
ok "$unit is INSTALLED on this host"
else
warn "$unit is NOT installed here yet — install with: sudo cp ops/systemd/$unit /etc/systemd/system/ && sudo systemctl daemon-reload && sudo systemctl enable $unit"
fi
done
note "NOTE: the relay unit expects WorkingDirectory=/opt/morphit-relay and"
note "EnvironmentFile=/etc/morphit/relay.env — confirm these match your actual"
note "deployment layout (this is a known doc/unit seam flagged in cp192)."
# ── 4. release discovery (cp191 fix) ─────────────────────────────
hdr "4. Release discovery (morphit-ops upgrade --check-only)"
if npx --no-install morphit-ops upgrade --check-only 2>&1 | tee /tmp/morphit-upgrade-check.log | grep -qiE "latest version|already on|new release"; then
ok "upgrade --check-only reached the release API and reported a version"
note "$(grep -iE 'current version|latest version' /tmp/morphit-upgrade-check.log | head -2)"
else
warn "upgrade --check-only did not report a version (network? no release published? or this tree has no release-info.json) — see /tmp/morphit-upgrade-check.log"
fi
# ── Summary ──────────────────────────────────────────────────────
hdr "Summary"
printf ' PASS: %d FAIL: %d WARN: %d\n\n' "$PASS" "$FAIL" "$WARN"
if [ "$FAIL" -gt 0 ]; then
printf '\033[31mInstall arc has FAILURES above — fix before telling operators it is smooth.\033[0m\n'
exit 1
fi
if [ "$WARN" -gt 0 ]; then
printf '\033[33mNo hard failures, but warnings above are the real-world rough edges to address.\033[0m\n'
exit 0
fi
printf '\033[32mFresh-install arc looks clean on this VM.\033[0m\n'