108 lines
3.7 KiB
Bash
108 lines
3.7 KiB
Bash
|
|
#!/usr/bin/env bash
|
||
|
|
# =============================================================================
|
||
|
|
# preflight/preflight.sh — foundation host & toolchain pre-flight validation.
|
||
|
|
#
|
||
|
|
# PLAN-002 Phase 1 / §9.1: a freshly-cloned repo validates host + toolchain
|
||
|
|
# BEFORE any `pulumi up`. Fails CLOSED: exits NON-ZERO if ANY required check
|
||
|
|
# fails. Composable: one script per concern under checks/, aggregated here.
|
||
|
|
#
|
||
|
|
# Runs on the operator workstation AND in CI, on macOS (bash 3.2) and Linux.
|
||
|
|
# No hard bashisms: no associative arrays, no mapfile, no ${var^^}, no
|
||
|
|
# process substitution.
|
||
|
|
#
|
||
|
|
# USAGE
|
||
|
|
# ./preflight/preflight.sh # run all checks
|
||
|
|
# ./preflight/preflight.sh tools env # run only the named checks
|
||
|
|
# NO_COLOR=1 ./preflight/preflight.sh # disable ANSI color
|
||
|
|
#
|
||
|
|
# EXIT CODES
|
||
|
|
# 0 all REQUIRED checks passed (gated ssh/dns may WARN — that's fine)
|
||
|
|
# 1 at least one required check failed (missing/old tool, missing ENV, etc.)
|
||
|
|
# =============================================================================
|
||
|
|
set -euo pipefail
|
||
|
|
|
||
|
|
PF_DIR=$(cd "$(dirname "$0")" && pwd)
|
||
|
|
CHECKS_DIR="$PF_DIR/checks"
|
||
|
|
|
||
|
|
# Colors for the top-level summary (lib/common.sh handles per-check coloring).
|
||
|
|
if [ -t 1 ] && [ -z "${NO_COLOR:-}" ]; then
|
||
|
|
C_RED=$(printf '\033[31m'); C_GRN=$(printf '\033[32m')
|
||
|
|
C_YEL=$(printf '\033[33m'); C_BLD=$(printf '\033[1m'); C_RST=$(printf '\033[0m')
|
||
|
|
else
|
||
|
|
C_RED=""; C_GRN=""; C_YEL=""; C_BLD=""; C_RST=""
|
||
|
|
fi
|
||
|
|
|
||
|
|
# Ordered list of checks. REQUIRED checks gate the exit code; GATED checks
|
||
|
|
# (ssh, dns) are allowed to be absent/unreachable and only warn — they are
|
||
|
|
# listed so they run, but their result never flips the overall status.
|
||
|
|
REQUIRED_CHECKS="versions tools env docker"
|
||
|
|
GATED_CHECKS="ssh dns"
|
||
|
|
|
||
|
|
# Optional positional args restrict which checks run (any from either list).
|
||
|
|
if [ "$#" -gt 0 ]; then
|
||
|
|
REQUIRED_CHECKS=""
|
||
|
|
GATED_CHECKS=""
|
||
|
|
for arg in "$@"; do
|
||
|
|
case "$arg" in
|
||
|
|
ssh|dns) GATED_CHECKS="$GATED_CHECKS $arg" ;;
|
||
|
|
*) REQUIRED_CHECKS="$REQUIRED_CHECKS $arg" ;;
|
||
|
|
esac
|
||
|
|
done
|
||
|
|
fi
|
||
|
|
|
||
|
|
printf '%s== foundation preflight ==%s\n' "$C_BLD" "$C_RST"
|
||
|
|
printf 'repo: %s\n' "$(cd "$PF_DIR/.." && pwd)"
|
||
|
|
printf 'host: %s (%s)\n\n' "$(uname -s)" "$(uname -m)"
|
||
|
|
|
||
|
|
FAILED_CHECKS=""
|
||
|
|
RAN_CHECKS=""
|
||
|
|
|
||
|
|
run_check() {
|
||
|
|
name="$1"
|
||
|
|
script="$CHECKS_DIR/$name.sh"
|
||
|
|
if [ ! -f "$script" ]; then
|
||
|
|
printf '%s[%s] no such check (%s) %s\n' "$C_RED" "$name" "$script" "$C_RST"
|
||
|
|
FAILED_CHECKS="$FAILED_CHECKS $name"
|
||
|
|
return
|
||
|
|
fi
|
||
|
|
RAN_CHECKS="$RAN_CHECKS $name"
|
||
|
|
# Run in its own shell so `set -e` inside a check can't abort the orchestrator.
|
||
|
|
if bash "$script"; then
|
||
|
|
: # check returned 0
|
||
|
|
else
|
||
|
|
FAILED_CHECKS="$FAILED_CHECKS $name"
|
||
|
|
fi
|
||
|
|
printf '\n'
|
||
|
|
}
|
||
|
|
|
||
|
|
# Required checks first (these gate exit status).
|
||
|
|
for c in $REQUIRED_CHECKS; do
|
||
|
|
[ -n "$c" ] && run_check "$c"
|
||
|
|
done
|
||
|
|
# Gated checks (run for visibility; their failure does NOT gate exit status,
|
||
|
|
# but a non-zero from them would only happen on an internal error — we still
|
||
|
|
# don't let it fail the run, matching the "skip with WARNING" requirement).
|
||
|
|
for c in $GATED_CHECKS; do
|
||
|
|
[ -n "$c" ] || continue
|
||
|
|
script="$CHECKS_DIR/$c.sh"
|
||
|
|
if [ -f "$script" ]; then
|
||
|
|
RAN_CHECKS="$RAN_CHECKS $c"
|
||
|
|
bash "$script" || true # gated: never gates the exit code
|
||
|
|
printf '\n'
|
||
|
|
fi
|
||
|
|
done
|
||
|
|
|
||
|
|
# ---- summary ----
|
||
|
|
printf '%s== summary ==%s\n' "$C_BLD" "$C_RST"
|
||
|
|
printf 'ran:%s\n' "$RAN_CHECKS"
|
||
|
|
|
||
|
|
if [ -n "$FAILED_CHECKS" ]; then
|
||
|
|
printf '%sFAIL%s — failing checks:%s\n' "$C_RED" "$C_RST" "$FAILED_CHECKS"
|
||
|
|
printf '%spreflight FAILED — fix the above before `pulumi up`.%s\n' "$C_RED" "$C_RST"
|
||
|
|
exit 1
|
||
|
|
fi
|
||
|
|
|
||
|
|
printf '%sPASS%s — all required checks passed.\n' "$C_GRN" "$C_RST"
|
||
|
|
printf '%sNote:%s gated ssh/dns checks WARN-skip until the Pulumi stack is configured.\n' "$C_YEL" "$C_RST"
|
||
|
|
exit 0
|