Files
rustybeds/scripts/preflight.sh
gramps 75163fb520 feat: add preflight environment checklist script
scripts/preflight.sh checks all required dependencies:
- Rust/Cargo build toolchain
- RabbitMQ (installed + reachable + management plugin)
- MongoDB (installed + reachable)
- MariaDB (installed + reachable)
- Apache + PHP + php-mongodb (observer tool requirements)

Modes:
  --check    report only, no installs
  (default)  check + apt install missing packages (Debian/Ubuntu)

Idempotent, no sudo prompts during check-only mode.
Detection uses dpkg/systemctl rather than PATH-dependent command -v.
2026-04-10 18:21:47 -07:00

297 lines
9.7 KiB
Bash
Executable File

#!/usr/bin/env bash
# =============================================================================
# preflight.sh — BEDS environment preflight checklist
#
# Checks that all required services and tools are present and reachable.
# Installs anything missing (Debian/Ubuntu only).
# Idempotent — safe to run multiple times.
#
# Usage:
# ./scripts/preflight.sh # check + install missing
# ./scripts/preflight.sh --check # check only, no installs
#
# Requirements: bash 5+, sudo access (for installs)
# Supported: Debian 11+ / Ubuntu 22.04+
# =============================================================================
set -euo pipefail
# --- config ------------------------------------------------------------------
RABBITMQ_HOST="${RABBITMQ_HOST:-localhost}"
RABBITMQ_PORT="${RABBITMQ_PORT:-5672}"
MONGO_HOST="${MONGO_HOST:-localhost}"
MONGO_PORT="${MONGO_PORT:-27017}"
MARIADB_HOST="${MARIADB_HOST:-localhost}"
MARIADB_PORT="${MARIADB_PORT:-3306}"
CHECK_ONLY=false
if [[ "${1:-}" == "--check" ]]; then
CHECK_ONLY=true
fi
# --- output helpers ----------------------------------------------------------
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
CYAN='\033[0;36m'
BOLD='\033[1m'
RESET='\033[0m'
PASS=0
FAIL=0
WARN=0
pass() { echo -e " ${GREEN}[PASS]${RESET} $1"; PASS=$(( PASS + 1 )); }
fail() { echo -e " ${RED}[FAIL]${RESET} $1"; FAIL=$(( FAIL + 1 )); }
warn() { echo -e " ${YELLOW}[WARN]${RESET} $1"; WARN=$(( WARN + 1 )); }
info() { echo -e " ${CYAN} ${RESET} $1"; }
section() { echo; echo -e "${BOLD}$1${RESET}"; echo "$(printf '%.0s-' {1..60})"; }
# --- distro check ------------------------------------------------------------
detect_distro() {
if [[ -f /etc/os-release ]]; then
source /etc/os-release
DISTRO_ID="${ID:-unknown}"
DISTRO_LIKE="${ID_LIKE:-}"
else
DISTRO_ID="unknown"
DISTRO_LIKE=""
fi
}
is_debian_family() {
[[ "$DISTRO_ID" == "debian" || "$DISTRO_ID" == "ubuntu" || "$DISTRO_LIKE" == *"debian"* ]]
}
apt_install() {
if $CHECK_ONLY; then
fail "$1 — not installed (run without --check to install)"
return
fi
info "Installing $*..."
sudo apt-get install -y "$@" 2>&1 | tail -3
}
# Check via systemd (more reliable than searching sbin paths)
svc_installed() {
systemctl cat "$1" &>/dev/null
}
svc_active() {
systemctl is-active --quiet "$1" 2>/dev/null
}
# Check via dpkg (fast, no PATH issues)
pkg_installed() {
dpkg -s "$1" &>/dev/null && dpkg -s "$1" | grep -q 'Status: install ok installed'
}
# --- tcp reachability --------------------------------------------------------
tcp_check() {
local host="$1" port="$2"
timeout 2 bash -c ">/dev/tcp/${host}/${port}" 2>/dev/null
}
# =============================================================================
section "BEDS Preflight Checklist"
echo " Mode: $( $CHECK_ONLY && echo 'check only' || echo 'check + install')"
detect_distro
echo " Distro: ${DISTRO_ID:-unknown} ${VERSION_ID:-}"
echo
# =============================================================================
section "1. Build Toolchain"
if command -v rustc &>/dev/null; then
RUST_VER=$(rustc --version)
pass "Rust — $RUST_VER"
else
fail "Rust — not found"
info "Install: curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh"
info "(rustup is not managed by apt — install manually)"
fi
if command -v cargo &>/dev/null; then
CARGO_VER=$(cargo --version)
pass "Cargo — $CARGO_VER"
else
fail "Cargo — not found (install Rust via rustup)"
fi
# =============================================================================
section "2. RabbitMQ"
if pkg_installed rabbitmq-server; then
pass "RabbitMQ — installed"
else
if $CHECK_ONLY; then
fail "RabbitMQ — not installed"
else
if is_debian_family; then
info "Adding RabbitMQ apt repository..."
curl -fsSL https://packagecloud.io/rabbitmq/rabbitmq-server/gpgkey | sudo gpg --dearmor -o /usr/share/keyrings/rabbitmq-archive-keyring.gpg 2>/dev/null
echo "deb [signed-by=/usr/share/keyrings/rabbitmq-archive-keyring.gpg] https://packagecloud.io/rabbitmq/rabbitmq-server/debian/ $(source /etc/os-release && echo $VERSION_CODENAME) main" \
| sudo tee /etc/apt/sources.list.d/rabbitmq.list > /dev/null
sudo apt-get update -qq
apt_install rabbitmq-server
else
fail "RabbitMQ — not installed; automatic install only supported on Debian/Ubuntu"
info "See: https://www.rabbitmq.com/docs/install-debian"
fi
fi
fi
if tcp_check "$RABBITMQ_HOST" "$RABBITMQ_PORT"; then
pass "RabbitMQ reachable at ${RABBITMQ_HOST}:${RABBITMQ_PORT}"
else
fail "RabbitMQ not reachable at ${RABBITMQ_HOST}:${RABBITMQ_PORT}"
info "Start: sudo systemctl start rabbitmq-server"
fi
if svc_active rabbitmq-server; then
# Check management plugin via the HTTP API (no sudo needed)
if tcp_check localhost 15672; then
pass "RabbitMQ management plugin enabled (port 15672 open)"
else
warn "RabbitMQ management plugin not enabled"
info "Enable: sudo rabbitmq-plugins enable rabbitmq_management"
info " (provides the admin UI at http://localhost:15672)"
fi
fi
# =============================================================================
section "3. MongoDB"
if svc_installed mongod; then
MONGO_VER=$(mongod --version 2>/dev/null | head -1 || echo 'installed')
pass "MongoDB — $MONGO_VER"
else
if $CHECK_ONLY; then
fail "MongoDB — not installed"
else
if is_debian_family; then
info "Adding MongoDB apt repository..."
curl -fsSL https://www.mongodb.org/static/pgp/server-8.0.asc | sudo gpg --dearmor -o /usr/share/keyrings/mongodb-server-8.0.gpg 2>/dev/null
echo "deb [arch=amd64,arm64 signed-by=/usr/share/keyrings/mongodb-server-8.0.gpg] https://repo.mongodb.org/apt/debian bookworm/mongodb-org/8.0 main" \
| sudo tee /etc/apt/sources.list.d/mongodb-org-8.0.list > /dev/null
sudo apt-get update -qq
apt_install mongodb-org
else
fail "MongoDB — not installed; automatic install only supported on Debian/Ubuntu"
info "See: https://www.mongodb.org/docs/manual/installation/"
fi
fi
fi
if tcp_check "$MONGO_HOST" "$MONGO_PORT"; then
pass "MongoDB reachable at ${MONGO_HOST}:${MONGO_PORT}"
else
fail "MongoDB not reachable at ${MONGO_HOST}:${MONGO_PORT}"
info "Start: sudo systemctl start mongod"
fi
# =============================================================================
section "4. MariaDB"
if svc_installed mariadb; then
pass "MariaDB — installed"
else
if $CHECK_ONLY; then
fail "MariaDB — not installed"
else
if is_debian_family; then
apt_install mariadb-server
else
fail "MariaDB — not installed; automatic install only supported on Debian/Ubuntu"
info "See: https://mariadb.org/download/"
fi
fi
fi
if tcp_check "$MARIADB_HOST" "$MARIADB_PORT"; then
pass "MariaDB reachable at ${MARIADB_HOST}:${MARIADB_PORT}"
else
fail "MariaDB not reachable at ${MARIADB_HOST}:${MARIADB_PORT}"
info "Start: sudo systemctl start mariadb"
fi
# =============================================================================
section "5. Apache + PHP (Observer Tool)"
if svc_installed apache2; then
APACHE_VER=$(apache2 -v 2>/dev/null | head -1 | awk '{print $3}' || echo 'installed')
pass "Apache — $APACHE_VER"
else
if $CHECK_ONLY; then
fail "Apache — not installed"
else
if is_debian_family; then
apt_install apache2
else
fail "Apache — not installed; automatic install only supported on Debian/Ubuntu"
fi
fi
fi
if tcp_check localhost 80; then
pass "Apache reachable at localhost:80"
else
fail "Apache not reachable at localhost:80"
info "Start: sudo systemctl start apache2"
fi
if pkg_installed php; then
PHP_VER=$(php --version 2>/dev/null | head -1 || echo 'installed')
pass "PHP — $PHP_VER"
else
if $CHECK_ONLY; then
fail "PHP — not installed"
else
if is_debian_family; then
apt_install php libapache2-mod-php php-mongodb php-cli
sudo systemctl restart apache2
else
fail "PHP — not installed; automatic install only supported on Debian/Ubuntu"
fi
fi
fi
# Check php-mongodb extension specifically
if pkg_installed php-mongodb; then
pass "PHP mongodb extension — installed"
else
warn "PHP mongodb extension — not installed"
info "Install: sudo apt install php-mongodb && sudo systemctl restart apache2"
fi
# =============================================================================
section "Summary"
TOTAL=$(( PASS + FAIL + WARN ))
echo
echo -e " Checked : $TOTAL"
echo -e " ${GREEN}Passed : $PASS${RESET}"
if [[ $WARN -gt 0 ]]; then
echo -e " ${YELLOW}Warnings: $WARN${RESET}"
fi
if [[ $FAIL -gt 0 ]]; then
echo -e " ${RED}Failed : $FAIL${RESET}"
echo
if $CHECK_ONLY; then
echo -e " Run ${BOLD}./scripts/preflight.sh${RESET} (without --check) to install missing dependencies."
else
echo -e " Some checks failed. Review output above and resolve before running BEDS."
fi
exit 1
else
echo
echo -e " ${GREEN}${BOLD}All checks passed. Environment is ready.${RESET}"
if ! $CHECK_ONLY; then
echo
echo -e " Next steps:"
echo -e " 1. Copy config template: cp config/beds.toml.example config/beds.toml"
echo -e " 2. Edit credentials: \$EDITOR config/env_dev.toml"
echo -e " 3. Build and run: cargo run"
fi
fi