#!/usr/bin/env bash set -euo pipefail # Seby's Calagopus Wings Installer # Designed for curl | bash usage ######################################## # helpers ######################################## TTY="/dev/tty" say() { printf "\n\033[1m%s\033[0m\n" "$*"; } warn() { printf "\n\033[33m[warn]\033[0m %s\n" "$*"; } err() { printf "\n\033[31m[error]\033[0m %s\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 "%s" "$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 $SUDO apt-get install -y "$@" } ######################################## # SSL config updater ######################################## update_wings_ssl_config() { local domain="$1" local cfg="/etc/calagopus/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 at $cfg — skipping SSL update." return fi say "Updating SSL section in $cfg" $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 } ######################################## # Start ######################################## need_tty require_root_or_sudo if ! have apt-get; then err "Only Debian/Ubuntu systems supported." exit 1 fi say "Calagopus Wings Installer" ######################################## # Docker ######################################## if have docker; then say "Docker detected: $(docker --version || true)" else warn "Docker not installed." if confirm_default_no "Install Docker?"; then apt_install ca-certificates curl curl -fsSL https://get.docker.com/ | CHANNEL=stable $SUDO bash else err "Docker required. Exiting." exit 1 fi fi ######################################## # SSL (Certbot standalone) ######################################## DO_SSL=false DOMAIN="" EMAIL="" if confirm_default_no "Set up SSL with certbot (standalone)?"; then DOMAIN="$(prompt "Enter domain (e.g. node.example.com): ")" EMAIL="$(prompt "Enter email for Let's Encrypt notices: ")" if [[ -n "$DOMAIN" && -n "$EMAIL" ]]; then DO_SSL=true else err "Domain and email required for SSL. Skipping." fi fi if $DO_SSL; then say "Installing certbot..." apt_install certbot warn "Ports 80/443 must be open and unused." $SUDO certbot certonly \ --standalone \ -d "$DOMAIN" \ --non-interactive \ --agree-tos \ --email "$EMAIL" \ --no-eff-email update_wings_ssl_config "$DOMAIN" fi ######################################## # Download Wings ######################################## say "Downloading Wings binary..." 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" $SUDO chmod +x "$WINGS_BIN" say "Wings installed to $WINGS_BIN" "$WINGS_BIN" version || true ######################################## # Configure ######################################## 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/calagopus $SUDO "$WINGS_BIN" configure --join-data "$JOIN_DATA" fi fi ######################################## # Install Service ######################################## if confirm_default_no "Install as systemd service? (wings service-install)"; then $SUDO "$WINGS_BIN" service-install $SUDO systemctl --no-pager status wings || true fi ######################################## # Done ######################################## say "Installation complete."