diff --git a/README.md b/README.md index 3c40a9f..5dd4c9c 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,137 @@ -# sebys-hosting-scripts +# Seby’s Hosting Scripts +Interactive installation scripts for **Calagopus Wings** nodes. + +This script installs: + +- Docker (optional, prompted) +- Certbot SSL (optional, prompted) +- Calagopus Wings (auto-detects x86_64 or ARM64) +- Systemd service (via `wings service-install`) +- Optional SSL configuration auto-wiring in `config.yml` + +--- + +## 🚀 Quick Install (Copy & Paste) + +```bash +curl -fsSL https://git.okseby.com/okseby/sebys-hosting-scripts/raw/branch/main/install-wings.sh | bash +``` + +> ⚠️ Make sure ports 80 and 443 are open if you plan to enable SSL. + +--- + +## 📦 What the Script Does + +### 1️⃣ Docker +- Checks if Docker is installed +- Prompts to install if missing +- Default answer: **No** + +### 2️⃣ SSL (Optional) + +If you choose to enable SSL: + +- Installs `certbot` +- Runs: + ```bash + certbot certonly --standalone -d yourdomain.com + ``` +- Automatically modifies: + +`/etc/calagopus/config.yml` + +From: + +```yaml + ssl: + enabled: false + cert: '' + key: '' +``` + +To: + +```yaml + ssl: + enabled: true + cert: /etc/letsencrypt/live/yourdomain.com/fullchain.pem + key: /etc/letsencrypt/live/yourdomain.com/privkey.pem +``` + +A backup of the config is created as: + +``` +/etc/calagopus/config.yml.bak +``` + +--- + +### 3️⃣ Wings Binary + +- Detects architecture: + - `x86_64` + - `aarch64` +- Downloads the correct release from: + +https://github.com/calagopus/wings + +Installed to: + +``` +/usr/local/bin/wings +``` + +--- + +### 4️⃣ Configuration + +Optionally runs: + +```bash +wings configure --join-data +``` + +Then optionally installs as a systemd service: + +```bash +wings service-install +``` + +`service-install` automatically: +- Creates systemd unit +- Reloads daemon +- Enables service +- Starts service + +--- + +## 🧱 Requirements + +- Debian / Ubuntu based system +- `apt` +- Root or sudo access +- Ports 80/443 open (for SSL standalone mode) + +--- + +## 🔐 Security Note + +Always inspect remote scripts before running them: + +```bash +curl -fsSL https://git.okseby.com/okseby/sebys-hosting-scripts/raw/branch/main/install-wings.sh +``` + +--- + +## 🛠 Manual Install Option + +If you prefer not to pipe to bash: + +```bash +curl -O https://git.okseby.com/okseby/sebys-hosting-scripts/raw/branch/main/install-wings.sh +chmod +x install-wings.sh +./install-wings.sh +``` diff --git a/install-wings.sh b/install-wings.sh new file mode 100644 index 0000000..41c7984 --- /dev/null +++ b/install-wings.sh @@ -0,0 +1,234 @@ +#!/usr/bin/env bash +set -euo pipefail + +# Interactive installer for Docker + (optional) Certbot SSL + Calagopus Wings (calagopus/wings) +# Intended usage: +# curl -fsSL https://example.com/install-wings.sh | bash +# +# Notes: +# - Prompts read from /dev/tty so it still works when piped from curl. +# - Default answers are conservative (Docker install: NO, SSL setup: NO, reboot: NO). + +######################################## +# 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 TTY available for interactive prompts. Run in an interactive shell." + 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 "This script needs root privileges (or sudo). Re-run as root or install sudo." + exit 1 + fi + else + SUDO="" + fi +} + +apt_install() { + local pkgs=("$@") + $SUDO apt-get update -y + $SUDO apt-get install -y "${pkgs[@]}" +} + +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 "Calagopus config not found at $cfg; skipping SSL config update." + return 0 + fi + + if [[ ! -f "$cert" || ! -f "$key" ]]; then + warn "Certbot files not found ($cert / $key); skipping SSL config update." + return 0 + fi + + say "Updating Calagopus SSL settings in $cfg (backup: ${cfg}.bak)..." + $SUDO cp -a "$cfg" "${cfg}.bak" + + # Update the 'ssl:' block values (assumes the block exists with standard indentation) + $SUDO awk -v cert="$cert" -v key="$key" ' + BEGIN { inssl=0 } + { + if ($0 ~ /^ ssl:[[:space:]]*$/) { inssl=1; print; next } + + if (inssl==1) { + # leave ssl block when we hit the next top-level (two-space) section + 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 "Calagopus SSL block updated." +} + +######################################## +# checks +######################################## +need_tty +require_root_or_sudo + +if ! have apt-get; then + err "This script currently supports Debian/Ubuntu (apt)." + exit 1 +fi + +say "Calagopus Wings bootstrap (Docker + optional SSL + Wings binary)" + +######################################## +# Docker +######################################## +if have docker; then + say "Docker detected: $(docker --version || true)" +else + warn "Docker is NOT installed." + if confirm_default_no "Install Docker now?"; then + say "Installing Docker via get.docker.com (CHANNEL=stable)..." + apt_install ca-certificates curl + curl -fsSL https://get.docker.com/ | CHANNEL=stable $SUDO bash + say "Docker installed: $(docker --version || true)" + else + err "Docker is required for Wings. Exiting because you chose not to install Docker." + exit 1 + fi +fi + +######################################## +# Optional SSL (Certbot standalone) +######################################## +DO_SSL=false +DOMAIN="" + +if confirm_default_no "Set up SSL with certbot (standalone) now?"; then + DO_SSL=true + DOMAIN="$(prompt "Enter the domain name to issue a cert for (e.g. node1.example.com): ")" + if [[ -z "$DOMAIN" ]]; then + err "No domain entered. Skipping SSL." + DO_SSL=false + fi +fi + +if $DO_SSL; then + say "Installing certbot..." + apt_install certbot + + say "Requesting certificate for: $DOMAIN" + warn "Certbot standalone requires ports 80/443 to be reachable and not in use." + $SUDO certbot certonly --standalone -d "$DOMAIN" + + # Update Calagopus config.yml ssl section + update_wings_ssl_config "$DOMAIN" +fi + +######################################## +# Download Wings binary (calagopus/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 (expected x86_64/amd64 or aarch64/arm64)." + exit 1 + ;; +esac + +WINGS_URL="https://github.com/calagopus/wings/releases/latest/download/wings-rs-${WINGS_ARCH}-linux" +WINGS_BIN="/usr/local/bin/wings" + +say "Detected arch: $ARCH -> using asset: wings-rs-${WINGS_ARCH}-linux" +say "Downloading: $WINGS_URL" +$SUDO curl -fL "$WINGS_URL" -o "$WINGS_BIN" +$SUDO chmod +x "$WINGS_BIN" + +say "Wings installed to $WINGS_BIN" +"$WINGS_BIN" version || true + +######################################## +# Configure Wings (join-data) +######################################## +say "Wings configuration" + +JOIN_DATA="" +if confirm_default_no "Run 'wings configure --join-data ...' now?"; then + JOIN_DATA="$(prompt "Paste the join-data string from your Calagopus panel (it can be long): ")" + if [[ -z "$JOIN_DATA" ]]; then + err "No join-data provided; skipping wings configure." + else + $SUDO mkdir -p /etc/calagopus + $SUDO "$WINGS_BIN" configure --join-data "$JOIN_DATA" + say "Wings configured." + fi +else + warn "Skipping 'wings configure'. You'll need to configure manually later." +fi + +if [[ -t 0 ]] && [[ -t 1 ]] && confirm_default_no "Open /etc/calagopus/config.yml in nano now?"; then + $SUDO nano /etc/calagopus/config.yml +fi + +######################################## +# Install & start service +######################################## +if confirm_default_no "Install Wings as a systemd service now? (wings service-install)"; then + $SUDO "$WINGS_BIN" service-install + say "Service status:" + $SUDO systemctl --no-pager status wings || true +else + warn "Skipping service installation." +fi + +######################################## +# Optional reboot +######################################## +if confirm_default_no "Reboot now?"; then + say "Rebooting..." + $SUDO reboot +else + say "Done. No reboot performed." +fi