200 lines
7.5 KiB
Bash
Executable File
200 lines
7.5 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# ==============================================================================
|
|
# Unified Deploy Wrapper
|
|
# ==============================================================================
|
|
# Auto-discovers deploy-{docker,local}-*.sh scripts in the same directory and
|
|
# dispatches to them with a shorter CLI interface.
|
|
#
|
|
# Usage:
|
|
# deploy.sh # List available services
|
|
# deploy.sh mattermost # Deploy via docker (default)
|
|
# deploy.sh -l paperclip # Deploy via local (bare-metal)
|
|
# deploy.sh --local hermes --domain h.an2.io # Local deploy with flags
|
|
# deploy.sh -r mattermost # --remove
|
|
# deploy.sh -r -p mattermost # --remove --purge
|
|
# deploy.sh -r -p -y mattermost # --remove --purge --yes
|
|
# deploy.sh web --domain w.an2.io --dir acme # Pass-through flags
|
|
# ==============================================================================
|
|
|
|
set -euo pipefail
|
|
|
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
|
|
# ── Colours ──────────────────────────────────────────────────────────────────
|
|
RED='\033[0;31m'; GREEN='\033[0;32m'; YELLOW='\033[1;33m'; CYAN='\033[0;36m'
|
|
BOLD='\033[1m'; DIM='\033[2m'; NC='\033[0m'
|
|
|
|
# ── Discover available deploy scripts ────────────────────────────────────────
|
|
# Builds two associative arrays:
|
|
# DOCKER_SCRIPTS[service] = script_path
|
|
# LOCAL_SCRIPTS[service] = script_path
|
|
# And a sorted list of unique service names.
|
|
|
|
declare -A DOCKER_SCRIPTS=()
|
|
declare -A LOCAL_SCRIPTS=()
|
|
declare -a ALL_SERVICES=()
|
|
|
|
discover_scripts() {
|
|
local script basename method service
|
|
for script in "${SCRIPT_DIR}"/deploy-docker-*.sh "${SCRIPT_DIR}"/deploy-local-*.sh; do
|
|
[[ -f "$script" ]] || continue
|
|
basename="$(basename "$script" .sh)" # deploy-docker-hermes
|
|
method="${basename#deploy-}" # docker-hermes
|
|
method="${method%%-*}" # docker or local
|
|
service="${basename#deploy-${method}-}" # hermes
|
|
|
|
case "$method" in
|
|
docker) DOCKER_SCRIPTS["$service"]="$script" ;;
|
|
local) LOCAL_SCRIPTS["$service"]="$script" ;;
|
|
esac
|
|
done
|
|
|
|
# Build sorted unique service list
|
|
local -A seen=()
|
|
for s in "${!DOCKER_SCRIPTS[@]}" "${!LOCAL_SCRIPTS[@]}"; do
|
|
seen["$s"]=1
|
|
done
|
|
IFS=$'\n' read -r -d '' -a ALL_SERVICES < <(printf '%s\n' "${!seen[@]}" | sort && printf '\0') || true
|
|
}
|
|
|
|
# ── Usage / list ─────────────────────────────────────────────────────────────
|
|
|
|
print_usage() {
|
|
echo ""
|
|
echo -e "${CYAN}══════════════════════════════════════════════${NC}"
|
|
echo -e "${CYAN} Deploy — Unified Wrapper${NC}"
|
|
echo -e "${CYAN}══════════════════════════════════════════════${NC}"
|
|
echo ""
|
|
echo -e " ${BOLD}Usage:${NC} deploy.sh [flags] <service>"
|
|
echo ""
|
|
echo -e " ${BOLD}Flags:${NC}"
|
|
echo -e " ${GREEN}--local, -l${NC} Use bare-metal (local) deploy instead of Docker"
|
|
echo -e " ${GREEN}--remove, -r${NC} Remove the service (keep data)"
|
|
echo -e " ${GREEN}--purge, -p${NC} Delete all data (requires --remove)"
|
|
echo -e " ${GREEN}--yes, -y${NC} Skip confirmations"
|
|
echo -e " ${GREEN}--domain <fqdn>${NC} Set the service domain"
|
|
echo -e " ${GREEN}--dir <name>${NC} Instance directory (for web)"
|
|
echo -e " ${GREEN}--cold${NC} Cold backup mode (passed through)"
|
|
echo ""
|
|
echo -e " ${BOLD}Available services:${NC}"
|
|
echo ""
|
|
|
|
# Table header
|
|
printf " ${DIM}%-16s %-8s %-8s${NC}\n" "SERVICE" "DOCKER" "LOCAL"
|
|
printf " ${DIM}%-16s %-8s %-8s${NC}\n" "───────────────" "────────" "────────"
|
|
|
|
for service in "${ALL_SERVICES[@]}"; do
|
|
local d_mark l_mark
|
|
if [[ -n "${DOCKER_SCRIPTS[$service]+x}" ]]; then
|
|
d_mark="${GREEN} ✓${NC}"
|
|
else
|
|
d_mark="${DIM} —${NC}"
|
|
fi
|
|
if [[ -n "${LOCAL_SCRIPTS[$service]+x}" ]]; then
|
|
l_mark="${GREEN} ✓${NC}"
|
|
else
|
|
l_mark="${DIM} —${NC}"
|
|
fi
|
|
printf " %-16s %b %b\n" "$service" "$d_mark" "$l_mark"
|
|
done
|
|
|
|
echo ""
|
|
echo -e " ${BOLD}Examples:${NC}"
|
|
echo -e " ${DIM}deploy.sh mattermost${NC} # Docker deploy"
|
|
echo -e " ${DIM}deploy.sh -l paperclip --domain clip.an2.io${NC} # Local deploy"
|
|
echo -e " ${DIM}deploy.sh -r -p gitea${NC} # Remove + purge"
|
|
echo -e " ${DIM}deploy.sh web --domain w.an2.io --dir acme${NC} # Multi-instance"
|
|
echo ""
|
|
}
|
|
|
|
# ── Main ─────────────────────────────────────────────────────────────────────
|
|
|
|
discover_scripts
|
|
|
|
# Parse wrapper flags — separate them from pass-through flags
|
|
USE_LOCAL=0
|
|
SERVICE=""
|
|
PASSTHROUGH=()
|
|
|
|
while [[ $# -gt 0 ]]; do
|
|
case "$1" in
|
|
--local|-l)
|
|
USE_LOCAL=1
|
|
shift
|
|
;;
|
|
--remove|-r)
|
|
PASSTHROUGH+=("--remove")
|
|
shift
|
|
;;
|
|
--purge|-p)
|
|
PASSTHROUGH+=("--purge")
|
|
shift
|
|
;;
|
|
--yes|-y)
|
|
PASSTHROUGH+=("--yes")
|
|
shift
|
|
;;
|
|
--domain)
|
|
PASSTHROUGH+=("--domain" "$2")
|
|
shift 2
|
|
;;
|
|
--dir)
|
|
PASSTHROUGH+=("--dir" "$2")
|
|
shift 2
|
|
;;
|
|
--cold)
|
|
PASSTHROUGH+=("--cold")
|
|
shift
|
|
;;
|
|
-*)
|
|
# Unknown flag — pass through
|
|
PASSTHROUGH+=("$1")
|
|
shift
|
|
;;
|
|
*)
|
|
if [[ -z "$SERVICE" ]]; then
|
|
SERVICE="$1"
|
|
else
|
|
# Extra positional — pass through
|
|
PASSTHROUGH+=("$1")
|
|
fi
|
|
shift
|
|
;;
|
|
esac
|
|
done
|
|
|
|
# No service specified — show usage
|
|
if [[ -z "$SERVICE" ]]; then
|
|
print_usage
|
|
exit 0
|
|
fi
|
|
|
|
# Resolve script
|
|
TARGET_SCRIPT=""
|
|
if (( USE_LOCAL )); then
|
|
if [[ -n "${LOCAL_SCRIPTS[$SERVICE]+x}" ]]; then
|
|
TARGET_SCRIPT="${LOCAL_SCRIPTS[$SERVICE]}"
|
|
else
|
|
echo -e "${RED}[FAIL]${NC} No local deploy script for '${SERVICE}'."
|
|
if [[ -n "${DOCKER_SCRIPTS[$SERVICE]+x}" ]]; then
|
|
echo -e " A Docker variant exists — run without ${GREEN}-l${NC}."
|
|
fi
|
|
exit 1
|
|
fi
|
|
else
|
|
if [[ -n "${DOCKER_SCRIPTS[$SERVICE]+x}" ]]; then
|
|
TARGET_SCRIPT="${DOCKER_SCRIPTS[$SERVICE]}"
|
|
elif [[ -n "${LOCAL_SCRIPTS[$SERVICE]+x}" ]]; then
|
|
echo -e "${YELLOW}[WARN]${NC} No Docker variant for '${SERVICE}' — using local."
|
|
TARGET_SCRIPT="${LOCAL_SCRIPTS[$SERVICE]}"
|
|
else
|
|
echo -e "${RED}[FAIL]${NC} Unknown service '${SERVICE}'."
|
|
echo ""
|
|
echo -e " Available: ${ALL_SERVICES[*]}"
|
|
exit 1
|
|
fi
|
|
fi
|
|
|
|
# Dispatch
|
|
exec bash "$TARGET_SCRIPT" "${PASSTHROUGH[@]}"
|