platform-deployments/provisioning/modules/common.sh
2026-03-05 18:57:06 -08:00

120 lines
3.3 KiB
Bash
Executable file

#!/usr/bin/env bash
#
# common.sh — shared helpers for provision.sh modules
#
# Sourced by provision.sh and all host modules. Provides:
# - OS detection (reuses patterns from setup-workstation.sh)
# - Host role detection
# - Colored logging
# - Idempotent helpers
#
# Colors
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
CYAN='\033[0;36m'
BOLD='\033[1m'
NC='\033[0m'
# Logging
log_banner() {
echo -e "\n${CYAN}╔════════════════════════════════════════════════════════════════╗${NC}"
echo -e "${CYAN}$(printf '%-60s' "$1")${NC}"
echo -e "${CYAN}╚════════════════════════════════════════════════════════════════╝${NC}\n"
}
log_section() { echo -e "\n${BLUE}━━━ $1 ━━━${NC}"; }
log_info() { echo -e "${GREEN}[✓]${NC} $1"; }
log_warn() { echo -e "${YELLOW}[!]${NC} $1"; }
log_error() { echo -e "${RED}[✗]${NC} $1"; }
log_step() { echo -e "${CYAN}${NC} $1"; }
# OS detection
detect_os() {
if [[ "$(uname)" == "Darwin" ]]; then
OS_NAME="macOS"
OS_ID="macos"
OS_VERSION="$(sw_vers -productVersion 2>/dev/null || echo unknown)"
elif [[ -f /etc/os-release ]]; then
source /etc/os-release
OS_NAME="$NAME"
OS_ID="$ID"
OS_VERSION="${VERSION_ID:-unknown}"
else
OS_NAME="Unknown"
OS_ID="unknown"
OS_VERSION="unknown"
fi
}
detect_package_manager() {
if [[ "$(uname)" == "Darwin" ]]; then
echo "brew"
elif command -v rpm-ostree &>/dev/null; then
echo "rpm-ostree"
elif command -v dnf &>/dev/null; then
echo "dnf"
elif command -v apt &>/dev/null; then
echo "apt"
elif command -v yum &>/dev/null; then
echo "yum"
else
echo "unknown"
fi
}
is_atomic() {
[[ "$(detect_package_manager)" == "rpm-ostree" ]]
}
is_macos() {
[[ "$(uname)" == "Darwin" ]]
}
# Host role detection — maps hostname to provisioning role
detect_host() {
local hostname="${PROVISION_HOST_OVERRIDE:-$(hostname -s 2>/dev/null || hostname)}"
case "$hostname" in
black|black.*) echo "black" ;;
apricot|apricot.*) echo "apricot" ;;
plum|plum.*) echo "plum" ;;
*)
log_error "Unknown host: $hostname"
log_error "Use --host <black|apricot|plum> to override"
return 1
;;
esac
}
# Check that a command exists, or exit
require_cmd() {
local cmd="$1"
local msg="${2:-Required command not found: $cmd}"
if ! command -v "$cmd" &>/dev/null; then
log_error "$msg"
return 1
fi
}
# Idempotent wrapper: run action only if condition check fails
# Usage: run_if_missing "description" "check_command" "action_command"
run_if_missing() {
local desc="$1"
local check="$2"
local action="$3"
if eval "$check" &>/dev/null; then
log_info "$desc — already done"
return 0
fi
if [[ "${CHECK_ONLY:-false}" == "true" ]]; then
log_warn "$desc — NOT configured"
return 1
fi
log_step "$desc..."
eval "$action"
}