Переглянути джерело

Better script compat (#138)

* updating the docker scripts to be in the scripts dir and to be more portable

* updating the docker scripts to be in the scripts dir and to be more portable

* better error handling so we dont kill the shell

* using a prompt function to deal with interactive issues

* prompt logic for cert_choice too

* Getting this to run via local bash and/or curl and piped to bash means formatting of these files is pretty important

* bringing this more inline with what is on main

* use background command for script

* After testing functionality I have restored formatting to docker compose

* adding some host validation and better error handling

* Update docker-setup.sh

Update docs URL :P
Joey Carmello 10 місяців тому
батько
коміт
8f2895630a
3 змінених файлів з 226 додано та 134 видалено
  1. 14 17
      docker-compose.yaml
  2. 0 117
      docker-setup.sh
  3. 212 0
      scripts/docker-setup.sh

+ 14 - 17
docker-compose.yaml

@@ -7,16 +7,14 @@ services:
     entrypoint: [ "/bin/sh", "-c" ]
     environment:
       - OSCAR_HOST=${OSCAR_HOST}
-    command: >
-      '
-      openssl req -x509 -newkey rsa:1024 \
-        -keyout key.pem \
-        -out cert.pem \
-        -sha256 -days 365 -nodes \
-        -subj "/CN=${OSCAR_HOST}" &&
-      cat cert.pem key.pem > server.pem &&
-      rm cert.pem key.pem
-      '
+    command:
+      - "openssl req -x509 -newkey rsa:1024
+         -keyout key.pem
+         -out cert.pem
+         -sha256 -days 365 -nodes
+         -subj \"/CN=${OSCAR_HOST}\"
+         && cat cert.pem key.pem > server.pem
+         && rm cert.pem key.pem"
 
   nss-gen:
     image: ras-certgen:latest
@@ -24,19 +22,18 @@ services:
       - ./certs:/work/certs
     working_dir: /work/certs
     entrypoint: [ "/bin/sh", "-c" ]
-    command: >
-      '
-      mkdir -p nss &&
-      certutil -N -d nss --empty-password &&
-      certutil -A -n "RAS" -t "CT,,C" -i server.pem -d nss
-      '
+    command:
+      - "rm -rf nss
+         && mkdir -p nss
+         && certutil -N -d nss --empty-password
+         && certutil -A -n \"RAS\" -t \"CT,,C\" -i server.pem -d nss"
 
   retro-aim-server:
     image: ras:latest
     ports:
       - "5190:5190"
-      - "9898:9898"
       - "8080:8080"
+      - "9898:9898"
     env_file:
       - ./config/ssl/settings.env
     volumes:

+ 0 - 117
docker-setup.sh

@@ -1,117 +0,0 @@
-#!/usr/bin/env bash
-
-# setup.sh
-# Installer for Retro AIM Server Docker Setup
-
-set -e
-
-#
-# boiler plate
-#
-RED='\033[0;31m'
-GREEN='\033[0;32m'
-YELLOW='\033[1;33m'
-CYAN='\033[0;36m'
-NC='\033[0m'
-
-log()    { echo -e "${CYAN}[*] $1${NC}"; }
-success(){ echo -e "${GREEN}[✔] $1${NC}"; }
-warn()   { echo -e "${YELLOW}[!] $1${NC}"; }
-error()  { echo -e "${RED}[✖] $1${NC}"; exit 1; }
-
-check_prereqs() {
-    log "Checking for required tools..."
-    for cmd in git docker make; do
-        if ! command -v $cmd &> /dev/null; then
-            error "Missing required command: $cmd"
-        fi
-    done
-    success "All prerequisites are installed."
-}
-
-clone_repo() {
-    if [ -d "retro-aim-server" ]; then
-        warn "Directory 'retro-aim-server' already exists. Skipping clone."
-    else
-        log "Cloning Retro AIM Server repository..."
-        git clone https://github.com/mk6i/retro-aim-server.git || error "Failed to clone repository"
-    fi
-    cd retro-aim-server || error "Failed to enter repo directory"
-    success "Repository ready."
-}
-
-build_images() {
-    log "Building Docker images..."
-    make docker-images || error "Docker image build failed"
-    success "Docker images built successfully."
-}
-
-setup_ssl_cert() {
-    read -rp "$(echo -e ${YELLOW}"Enter the OSCAR_HOST (e.g., ras.dev): "${NC})" OSCAR_HOST < /dev/tty
-    if [ -z "$OSCAR_HOST" ]; then
-        error "OSCAR_HOST is required"
-    fi
-
-    log "SSL certificate options:"
-    echo -e "${YELLOW}1) Generate self-signed certificate"
-    echo -e "2) Use existing PEM certificate at certs/server.pem${NC}"
-    read -rp "$(echo -e ${CYAN}"Choose an option [1/2]: "${NC})" cert_choice < /dev/tty
-
-    if [ "$cert_choice" == "1" ]; then
-        log "Generating self-signed SSL certificate for $OSCAR_HOST..."
-        make docker-cert OSCAR_HOST="$OSCAR_HOST" || error "Failed to generate self-signed cert"
-        success "Self-signed certificate generated."
-    elif [ "$cert_choice" == "2" ]; then
-        if [ ! -f "certs/server.pem" ]; then
-            error "certs/server.pem not found. Please place your PEM file there and rerun."
-        fi
-        success "Using existing certificate at certs/server.pem."
-    else
-        error "Invalid option for certificate setup."
-    fi
-}
-
-generate_nss() {
-    log "Generating NSS certificate database..."
-    make docker-nss || error "Failed to generate NSS cert DB"
-    success "NSS certificate database created at certs/nss/"
-}
-
-start_server() {
-    log "Starting Retro AIM Server with hostname $OSCAR_HOST..."
-    make docker-run-bg OSCAR_HOST="$OSCAR_HOST" || error "Failed to start server"
-    success "Retro AIM Server is running."
-}
-
-final_steps() {
-    echo -e "${GREEN}
-Retro AIM Server setup complete!
-===================================
-Next Steps:
-
-1. Copy the NSS certs from 'certs/nss/' to each AIM 6.2+ client.
-
-2. Ensure clients can resolve '${OSCAR_HOST}' to your server IP.
-   Add the following to each client's hosts file if DNS isn't used:
-   ${NC}
-${YELLOW}127.0.0.1 $OSCAR_HOST${NC}
-${GREEN}
-3. For AIM 6.x client setup instructions, see:
-   https://github.com/mk6i/retro-aim-server/blob/main/docs/AIM6.md#aim-6265312-setup
-
-Enjoy!
-${NC}"
-}
-
-main() {
-    check_prereqs
-    clone_repo
-    build_images
-    setup_ssl_cert
-    generate_nss
-    start_server
-    final_steps
-}
-
-main "$@"
-

+ 212 - 0
scripts/docker-setup.sh

@@ -0,0 +1,212 @@
+#!/usr/bin/env bash
+
+# docker-setup.sh
+# Cross-platform installer for Retro AIM Server Docker Setup
+# Compatible with Linux and macOS
+
+set -e
+set -u  # Exit on undefined variables
+
+# ANSI color codes (fallback for POSIX shells that support it)
+RED='\033[0;31m'
+GREEN='\033[0;32m'
+YELLOW='\033[1;33m'
+CYAN='\033[0;36m'
+NC='\033[0m'
+
+log()    { printf "%b\n" "${CYAN}[*] $1${NC}" >&2; }
+success(){ printf "%b\n" "${GREEN}[✔] $1${NC}" >&2; }
+warn()   { printf "%b\n" "${YELLOW}[!] $1${NC}" >&2; }
+error()  { printf "%b\n" "${RED}[✖] $1${NC}" >&2; return 1; }
+
+prompt() {
+    local varname=$1
+    local prompt_text=$2
+
+    if [ -t 0 ] && [ -t 1 ]; then
+        # Interactive shell with both stdin and stdout connected to terminal
+        printf "%b" "$prompt_text"
+        read -r "$varname"
+    else
+        # Non-interactive shell (like curl | bash) or output redirected
+        printf "%b" "$prompt_text" >&2
+        read -r "$varname" < /dev/tty
+    fi
+
+    # Use eval for POSIX-compatible indirect variable access
+    local value
+    eval "value=\$$varname"
+    if [ -z "$value" ]; then
+        printf "%b\n" "${RED}[✖] Input required but not provided.${NC}" >&2
+        return 1
+    fi
+}
+
+check_os() {
+    case "$(uname -s)" in
+        Linux|Darwin)
+            : # supported
+            ;;
+        *)
+            error "Unsupported OS: $(uname -s)"
+            return 1
+            ;;
+    esac
+}
+
+check_prereqs() {
+    log "Checking for required tools..."
+    for cmd in git docker make; do
+        if ! command -v "$cmd" >/dev/null 2>&1; then
+            error "Missing required command: $cmd"
+            return 1
+        fi
+    done
+    success "All prerequisites are installed."
+}
+
+stop_existing_services() {
+    log "Stopping any existing Docker Compose services..."
+    if docker compose ps -q 2>/dev/null | grep -q .; then
+        log "Found running services, stopping them..."
+        docker compose down 2>/dev/null || true
+        success "Stopped existing services."
+    else
+        log "No running services found."
+    fi
+}
+
+resolve_repo_root() {
+    SCRIPT_DIR=$(cd "$(dirname "$0")" && pwd)
+
+    # If this script is inside a Git repo already, use that
+    if git -C "$SCRIPT_DIR" rev-parse --is-inside-work-tree >/dev/null 2>&1; then
+        REPO_ROOT=$(git -C "$SCRIPT_DIR" rev-parse --show-toplevel)
+    else
+        TMP_DIR="retro-aim-server"
+        if [ -d "$TMP_DIR/.git" ]; then
+            warn "Directory '$TMP_DIR' is already a git repo. Using existing directory."
+        else
+            log "Cloning Retro AIM Server repository..."
+            if ! git clone https://github.com/mk6i/retro-aim-server.git "$TMP_DIR"; then
+                error "Failed to clone repository"
+                return 1
+            fi
+        fi
+        REPO_ROOT=$(cd "$TMP_DIR" && pwd)
+    fi
+    if ! cd "$REPO_ROOT"; then
+        error "Failed to enter repository directory"
+        return 1
+    fi
+}
+
+build_images() {
+    log "Building Docker images..."
+    if ! make docker-images; then
+        error "Docker image build failed"
+        return 1
+    fi
+    success "Docker images built successfully."
+}
+
+setup_ssl_cert() {
+    if ! prompt OSCAR_HOST "Enter the OSCAR_HOST (e.g., ras.dev): "; then
+        return 1
+    fi
+    
+    # Validate OSCAR_HOST format (basic hostname validation)
+    if ! echo "$OSCAR_HOST" | grep -qE '^[a-zA-Z0-9]([a-zA-Z0-9.-]*[a-zA-Z0-9])?$'; then
+        error "Invalid hostname format: $OSCAR_HOST"
+        return 1
+    fi
+    
+    # Export OSCAR_HOST so docker-compose can use it
+    export OSCAR_HOST
+
+    log "SSL certificate options:"
+    printf "%b\n" "${YELLOW}1) Generate self-signed certificate"
+    printf "%b"   "2) Use existing PEM certificate at certs/server.pem${NC}\n"
+
+    if ! prompt cert_choice "${CYAN}Choose an option [1/2]: ${NC}"; then
+        return 1
+    fi
+
+    case "$cert_choice" in
+        1)
+            log "Generating self-signed SSL certificate for $OSCAR_HOST..."
+            make clean-certs
+            log "OSCAR_HOST set to ${OSCAR_HOST}"
+            if ! make docker-cert OSCAR_HOST="$OSCAR_HOST"; then
+                error "Failed to generate self-signed cert"
+                return 1
+            fi
+            success "Self-signed certificate generated."
+            ;;
+        2)
+            if [ ! -f "certs/server.pem" ]; then
+                error "certs/server.pem not found. Please place your PEM file there and rerun."
+                return 1
+            else
+                success "Using existing certificate at certs/server.pem."
+            fi
+            ;;
+        *)
+            error "Invalid option for certificate setup."
+            return 1
+            ;;
+    esac
+}
+
+generate_nss() {
+    log "Generating NSS certificate database..."
+    if ! make docker-nss; then
+        error "Failed to generate NSS cert DB"
+        return 1
+    fi
+    success "NSS certificate database created at certs/nss/"
+}
+
+start_server() {
+    log "Starting Retro AIM Server with hostname $OSCAR_HOST..."
+    if ! make docker-run-bg OSCAR_HOST="$OSCAR_HOST"; then
+        error "Failed to start server"
+        return 1
+    fi
+    success "Retro AIM Server is running."
+}
+
+final_steps() {
+    printf "%b\n" "${GREEN}
+Retro AIM Server setup complete!
+===================================
+Next Steps:
+
+1. Copy the NSS certs from 'certs/nss/' to each AIM 6.2+ client.
+
+2. Ensure clients can resolve '${OSCAR_HOST}' to your server IP.
+   Add the following to each client's hosts file if DNS isn't used:
+
+${YELLOW}127.0.0.1 $OSCAR_HOST${NC}
+
+${GREEN}3. For AIM 6.x client setup instructions, see:
+   https://github.com/mk6i/retro-aim-server/blob/main/docs/AIM_6_7.md#aim-62-75-setup
+
+Enjoy!
+${NC}" >&2
+}
+
+main() {
+    check_os || return 1
+    check_prereqs || return 1
+    resolve_repo_root || return 1
+    stop_existing_services || return 1
+    build_images || return 1
+    setup_ssl_cert || return 1
+    generate_nss || return 1
+    start_server || return 1
+    final_steps
+}
+
+main "$@"
+