#!/usr/bin/env bash # ============================================================================= # Changemaker Lite — One-Line Installer # # Downloads the latest release tarball and runs the configuration wizard. # # Usage: # curl -fsSL https://gitea.bnkops.com/admin/changemaker.lite/raw/branch/v2/scripts/install.sh | bash # bash install.sh [OPTIONS] # # Options: # --dir DIR Install directory (default: ~/changemaker.lite) # --version TAG Specific version tag (default: latest release) # --tarball FILE Use a local tarball instead of downloading # --help Show this help # ============================================================================= set -euo pipefail GITEA_URL="https://gitea.bnkops.com" REPO="admin/changemaker.lite" INSTALL_DIR="${HOME}/changemaker.lite" VERSION="" LOCAL_TARBALL="" # --- Colors --- if [[ -t 1 ]] && [[ -z "${NO_COLOR:-}" ]]; then RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[0;33m' BLUE='\033[0;34m' BOLD='\033[1m' NC='\033[0m' else RED='' GREEN='' YELLOW='' BLUE='' BOLD='' NC='' fi info() { echo -e "${BLUE}[INFO]${NC} $*"; } success() { echo -e "${GREEN}[OK]${NC} $*"; } warn() { echo -e "${YELLOW}[WARN]${NC} $*"; } error() { echo -e "${RED}[ERROR]${NC} $*" >&2; } # --- Arg parser --- while [[ $# -gt 0 ]]; do case "$1" in --dir) INSTALL_DIR="$2"; shift 2 ;; --version) VERSION="$2"; shift 2 ;; --tarball) LOCAL_TARBALL="$2"; shift 2 ;; --help|-h) sed -n '2,20p' "$0" | grep '^#' | sed 's/^# \?//' exit 0 ;; *) shift ;; esac done echo -e "${BOLD}Changemaker Lite — Installer${NC}" echo "" # --- Step 1: Check prerequisites --- info "Checking prerequisites..." MISSING=() command -v docker >/dev/null 2>&1 || MISSING+=("docker") docker compose version >/dev/null 2>&1 || MISSING+=("docker-compose-v2") command -v openssl >/dev/null 2>&1 || MISSING+=("openssl") command -v curl >/dev/null 2>&1 || MISSING+=("curl") if [[ ${#MISSING[@]} -gt 0 ]]; then error "Missing required tools: ${MISSING[*]}" echo "" echo "Install Docker: https://docs.docker.com/engine/install/" echo "Install OpenSSL: apt install openssl (or equivalent)" exit 1 fi success "Prerequisites OK (Docker $(docker --version | grep -oP '\d+\.\d+\.\d+'), OpenSSL available)" # --- Step 2: Check install directory --- if [[ -d "$INSTALL_DIR" ]]; then if [[ -f "$INSTALL_DIR/docker-compose.yml" ]]; then error "Changemaker Lite is already installed at $INSTALL_DIR" echo " To upgrade: cd $INSTALL_DIR && ./scripts/upgrade.sh" echo " To reinstall: rm -rf $INSTALL_DIR && re-run this script" exit 1 fi fi # --- Step 3: Get tarball --- TARBALL_PATH="" if [[ -n "$LOCAL_TARBALL" ]]; then if [[ ! -f "$LOCAL_TARBALL" ]]; then error "Tarball not found: $LOCAL_TARBALL" exit 1 fi TARBALL_PATH="$LOCAL_TARBALL" info "Using local tarball: $LOCAL_TARBALL" else # Determine download URL if [[ -n "$VERSION" ]]; then RELEASE_URL="${GITEA_URL}/api/v1/repos/${REPO}/releases/tags/${VERSION}" else RELEASE_URL="${GITEA_URL}/api/v1/repos/${REPO}/releases/latest" fi info "Fetching release info from Gitea..." RELEASE_JSON=$(curl -sf "$RELEASE_URL" 2>/dev/null || true) if [[ -z "$RELEASE_JSON" ]]; then error "Could not fetch release info from ${GITEA_URL}" echo "" echo "If the registry requires authentication:" echo " 1. Download the tarball manually from ${GITEA_URL}/${REPO}/releases" echo " 2. Run: bash install.sh --tarball /path/to/changemaker-lite-*.tar.gz" exit 1 fi TARBALL_URL=$(echo "$RELEASE_JSON" | python3 -c " import sys, json data = json.load(sys.stdin) assets = data.get('assets', []) for a in assets: if a['name'].endswith('.tar.gz'): print(a['browser_download_url']) break " 2>/dev/null || true) if [[ -z "$TARBALL_URL" ]]; then error "No tarball found in the release. Check ${GITEA_URL}/${REPO}/releases" exit 1 fi RELEASE_TAG=$(echo "$RELEASE_JSON" | python3 -c "import sys,json; print(json.load(sys.stdin).get('tag_name','unknown'))" 2>/dev/null) info "Downloading Changemaker Lite ${RELEASE_TAG}..." TARBALL_PATH="/tmp/changemaker-lite-install.tar.gz" curl -fSL "$TARBALL_URL" -o "$TARBALL_PATH" success "Downloaded $(du -h "$TARBALL_PATH" | cut -f1)" fi # --- Step 4: Extract --- info "Extracting to ${INSTALL_DIR}..." mkdir -p "$(dirname "$INSTALL_DIR")" # Extract to temp, then move (handles tarball root directory naming) EXTRACT_DIR=$(mktemp -d) tar xzf "$TARBALL_PATH" -C "$EXTRACT_DIR" # Find the extracted directory (tarball might have any root name) EXTRACTED=$(find "$EXTRACT_DIR" -maxdepth 1 -mindepth 1 -type d | head -1) if [[ -z "$EXTRACTED" ]]; then error "Tarball extraction failed — no directory found" rm -rf "$EXTRACT_DIR" exit 1 fi mv "$EXTRACTED" "$INSTALL_DIR" rm -rf "$EXTRACT_DIR" # Clean up downloaded tarball if [[ -z "$LOCAL_TARBALL" ]] && [[ -f "$TARBALL_PATH" ]]; then rm -f "$TARBALL_PATH" fi success "Extracted to ${INSTALL_DIR}" # --- Step 5: Run config wizard --- echo "" echo -e "${BOLD}Starting configuration wizard...${NC}" echo "" cd "$INSTALL_DIR" bash config.sh # --- Done --- echo "" echo -e "${BOLD}${GREEN}Installation complete!${NC}" echo "" echo " Start all services:" echo " cd ${INSTALL_DIR} && docker compose up -d" echo "" echo " Check status:" echo " docker compose ps" echo "" echo " View API logs:" echo " docker compose logs -f api --tail 20" echo ""