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.
297 lines
9.7 KiB
Bash
Executable File
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
|