sebys-hosting-scripts/install-wings.sh
2026-02-27 12:26:57 -05:00

273 lines
6.4 KiB
Bash

#!/usr/bin/env bash
set -euo pipefail
########################################
# Seby's Calagopus Wings Installer
# curl | bash safe
########################################
########################################
# Styling
########################################
TTY="/dev/tty"
BOLD="\033[1m"
GREEN="\033[32m"
YELLOW="\033[33m"
RED="\033[31m"
BLUE="\033[34m"
RESET="\033[0m"
section() { printf "\n${BLUE}${BOLD}==> %s${RESET}\n" "$*"; }
say() { printf "${GREEN}✔ %s${RESET}\n" "$*"; }
warn() { printf "${YELLOW}⚠ %s${RESET}\n" "$*"; }
err() { printf "${RED}✖ %s${RESET}\n" "$*"; }
have() { command -v "$1" >/dev/null 2>&1; }
need_tty() {
if [[ ! -r "$TTY" || ! -w "$TTY" ]]; then
err "No interactive TTY available."
exit 1
fi
}
prompt() {
local msg="$1"
local out
printf "${BOLD}%s${RESET}" "$msg" >"$TTY"
IFS= read -r out <"$TTY"
printf "%s" "$out"
}
confirm_default_no() {
local msg="$1"
local ans
ans="$(prompt "$msg [y/N]: ")"
[[ "${ans,,}" == "y" || "${ans,,}" == "yes" ]]
}
require_root_or_sudo() {
if [[ "${EUID:-$(id -u)}" -ne 0 ]]; then
if have sudo; then
SUDO="sudo"
else
err "Root or sudo required."
exit 1
fi
else
SUDO=""
fi
}
apt_install() {
$SUDO apt-get update -y >/dev/null 2>&1
$SUDO apt-get install -y "$@" >/dev/null 2>&1
}
########################################
# Spinner (writes to /dev/tty so curl|bash stays safe)
########################################
run_with_spinner() {
local label="$1"; shift
# Run the provided command in the background
("$@") &
local pid=$!
local spin='|/-\'
local i=0
# Hide cursor
printf "\033[?25l" >"$TTY" || true
# Spinner loop
while kill -0 "$pid" 2>/dev/null; do
i=$(( (i + 1) % 4 ))
printf "\r${BLUE}${BOLD}..${RESET} %s %s" "${spin:$i:1}" "$label" >"$TTY"
sleep 0.12
done
# Wait for completion + capture exit status
wait "$pid"
local rc=$?
# Clear spinner line + show cursor
printf "\r\033[K" >"$TTY"
printf "\033[?25h" >"$TTY" || true
return "$rc"
}
########################################
# SSL config updater
########################################
update_ssl_config() {
local domain="$1"
local cfg="/etc/pterodactyl/config.yml"
local cert="/etc/letsencrypt/live/${domain}/fullchain.pem"
local key="/etc/letsencrypt/live/${domain}/privkey.pem"
if [[ ! -f "$cfg" ]]; then
warn "Config not found — skipping SSL update."
return
fi
if [[ ! -f "$cert" || ! -f "$key" ]]; then
warn "Cert files not found — skipping SSL update."
return
fi
section "Updating SSL configuration"
$SUDO cp -a "$cfg" "${cfg}.bak"
$SUDO awk -v cert="$cert" -v key="$key" '
BEGIN { inssl=0 }
{
if ($0 ~ /^ ssl:[[:space:]]*$/) { inssl=1; print; next }
if (inssl==1) {
if ($0 ~ /^ [^[:space:]]/ && $0 !~ /^ ssl:/) { inssl=0 }
else if ($0 ~ /^ enabled:/) { print " enabled: true"; next }
else if ($0 ~ /^ cert:/) { print " cert: " cert; next }
else if ($0 ~ /^ key:/) { print " key: " key; next }
}
print
}
' "$cfg" | $SUDO tee "$cfg" >/dev/null
say "SSL block updated (backup saved)"
}
########################################
# Header
########################################
clear
cat << "EOF"
____ _
/ ___|__ _| | __ _ __ _ ___ _ __ _ _ ___
| | / _` | |/ _` |/ _` |/ _ \| '_ \| | | / __|
| |__| (_| | | (_| | (_| | (_) | |_) | |_| \__ \
\____\__,_|_|\__,_|\__, |\___/| .__/ \__,_|___/
|___/ |_|
Calagopus Wings Installer | v1.1
EOF
need_tty
require_root_or_sudo
if ! have apt-get; then
err "Only Debian/Ubuntu supported."
exit 1
fi
########################################
# Docker
########################################
section "Docker Check"
if have docker; then
say "Docker detected: $(docker --version || true)"
else
warn "Docker not installed."
if confirm_default_no "Install Docker?"; then
section "Installing Docker (quiet mode)"
apt_install ca-certificates curl
# Quiet install + spinner so users know it's working
if run_with_spinner "Installing Docker..." bash -c "curl -fsSL https://get.docker.com/ | CHANNEL=stable ${SUDO:-} bash >/dev/null 2>&1"; then
say "Docker installed successfully"
say "$(docker --version)"
else
err "Docker installation failed"
exit 1
fi
else
err "Docker required. Exiting."
exit 1
fi
fi
########################################
# Download Wings
########################################
section "Downloading Wings"
ARCH="$(uname -m)"
case "$ARCH" in
x86_64|amd64) WINGS_ARCH="x86_64" ;;
aarch64|arm64) WINGS_ARCH="aarch64" ;;
*)
err "Unsupported architecture: $ARCH"
exit 1
;;
esac
WINGS_URL="https://github.com/calagopus/wings/releases/latest/download/wings-rs-${WINGS_ARCH}-linux"
WINGS_BIN="/usr/local/bin/wings"
$SUDO curl -fL "$WINGS_URL" -o "$WINGS_BIN" >/dev/null 2>&1
$SUDO chmod +x "$WINGS_BIN"
say "Wings installed"
"$WINGS_BIN" version || true
########################################
# Configure
########################################
CONFIG_CREATED=false
section "Configuration"
if confirm_default_no "Run wings configure --join-data now?"; then
JOIN_DATA="$(prompt "Paste join-data string: ")"
if [[ -n "$JOIN_DATA" ]]; then
$SUDO mkdir -p /etc/pterodactyl
$SUDO "$WINGS_BIN" configure --join-data "$JOIN_DATA"
CONFIG_CREATED=true
say "Configuration complete"
else
warn "No join-data provided"
fi
fi
########################################
# SSL
########################################
if $CONFIG_CREATED && confirm_default_no "Set up SSL with certbot?"; then
section "SSL Setup"
DOMAIN="$(prompt "Enter domain: ")"
EMAIL="$(prompt "Enter email: ")"
if [[ -n "$DOMAIN" && -n "$EMAIL" ]]; then
apt_install certbot
$SUDO certbot certonly \
--standalone \
-d "$DOMAIN" \
--non-interactive \
--agree-tos \
--email "$EMAIL" \
--no-eff-email
update_ssl_config "$DOMAIN"
else
warn "Domain/email missing — skipping SSL"
fi
fi
########################################
# Service
########################################
section "Service Installation"
if confirm_default_no "Install as systemd service?"; then
$SUDO "$WINGS_BIN" service-install
say "Service installed"
$SUDO systemctl --no-pager status wings || true
fi
section "Done"
say "Calagopus Wings installation complete."