diff --git a/init/scripts/compose_gen.sh b/init/scripts/compose_gen.sh index f5936ed..bb74b58 100755 --- a/init/scripts/compose_gen.sh +++ b/init/scripts/compose_gen.sh @@ -11,51 +11,41 @@ OUTPUT_FILE="${ROOT_DIR}/compose.yaml" require_file "$TEMPLATE_FILE" "Compose template" -log_info "Configuring optional services..." +log_info "Generating compose.yaml based on .env configuration..." -read -r -p "Enable LiveKit RTC Stack? (Used for Element call) (Y/n) [Y]: " LIVEKIT_INPUT -LIVEKIT_INPUT="${LIVEKIT_INPUT:-Y}" -if [[ "$LIVEKIT_INPUT" =~ ^[Yy]$ ]]; then - INCLUDE_LIVEKIT=true - LIVEKIT_KEY=$(openssl rand -hex 16) - LIVEKIT_SECRET=$(openssl rand -hex 32) - cat >> "$ENV_FILE" </dev/null | grep -q "idp_id"; then yq -y -i "$(cat "$TEMP_FILTER")" "$SYNAPSE_CFG" || { log_error "Failed to inject OIDC config"; exit 1; } fi -if [[ -n "${LIVEKIT_API_KEY:-}" ]]; then +if [[ "${INCLUDE_LIVEKIT}" == "TRUE" ]]; then JWT_URL="https://${JWT_FQDN:-jwt.${DOMAIN}}" - if yq '.livekit.url' "$SYNAPSE_CFG" 2>/dev/null | grep -q "."; then - yq -y -i ".livekit.url = \"$JWT_URL\"" "$SYNAPSE_CFG" - else - yq -y -i ".livekit.url = \"$JWT_URL\"" "$SYNAPSE_CFG" - fi + yq -y -i ".livekit.url = \"$JWT_URL\"" "$SYNAPSE_CFG" fi log_info "OIDC and LiveKit linking complete" diff --git a/init/scripts/set_env.sh b/init/scripts/set_env.sh deleted file mode 100755 index 3086f56..0000000 --- a/init/scripts/set_env.sh +++ /dev/null @@ -1,62 +0,0 @@ -#!/usr/bin/env bash -set -euo pipefail - -SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" -source "${SCRIPT_DIR}/functions.sh" -resolve_paths - -main() { - > "$ENV_FILE" - - read -r -p "Base Domain (e.g. example.org) [example.org]: " DOMAIN_INPUT - DOMAIN="${DOMAIN_INPUT:-example.org}" - auto_var "DOMAIN" $DOMAIN "no" - log_info "Base Domain set to: ${DOMAIN}" - - read -r -p "Auto-generate secure defaults for remaining fields? [Y/n]: " GEN_INPUT - GEN_INPUT="${GEN_INPUT:-Y}" - - if [[ "$GEN_INPUT" =~ ^[Yy]$ ]]; then - log_info "Generating secure defaults..." - - auto_var "USER_ID" "1000" "no" - auto_var "GROUP_ID" "1000" "no" - auto_var "VOLUME_PATH" "./matrix" "no" - auto_var "COUNTRY" "GB" "no" - auto_var "PG_USER" "postgres" "no" - auto_var "PG_PASSWORD" "generated" "yes" - auto_var "PG_USER_MATRIX" "matrix" "no" - auto_var "PG_DB_MATRIX" "synapse" "no" - auto_var "PG_PASSWORD_MATRIX" "generated" "yes" - auto_var "PG_USER_MAS" "mas" "no" - auto_var "PG_DB_MAS" "auth" "no" - auto_var "PG_PASSWORD_MAS" "generated" "yes" - - log_info "All fields auto-generated." - else - log_info "Manual entry mode." - - - - - - prompt_var "USER_ID" "Docker UserId" "1000" "no" - prompt_var "GROUP_ID" "Docker GroupID" "1000" "no" - prompt_var "VOLUME_PATH" "Install directory" "./matrix" "no" - prompt_var "COUNTRY" "Country Code (e.g. GB)" "GB" "no" - prompt_var "PG_USER" "PostgreSQL Superuser" "postgres" "no" - prompt_var "PG_PASSWORD" "PostgreSQL Superuser Password" "generated" "yes" - prompt_var "PG_USER_MATRIX" "Synapse Database User" "matrix" "no" - prompt_var "PG_DB_MATRIX" "Synapse Database Name" "synapse" "no" - prompt_var "PG_PASSWORD_MATRIX" "Synapse Database Password" "generated" "yes" - prompt_var "PG_USER_MAS" "MAS Database User" "mas" "no" - prompt_var "PG_DB_MAS" "MAS Database Name" "auth" "no" - prompt_var "PG_PASSWORD_MAS" "MAS Database Password" "generated" "yes" - - chmod 600 "$ENV_FILE" - - log_info "Environment file created: $ENV_FILE" - log_warn "Add $ENV_FILE to .gitignore and backup securely" -} - -main "$@" diff --git a/init/scripts/worker_gen.sh b/init/scripts/worker_gen.sh index 607ac61..b9460e5 100755 --- a/init/scripts/worker_gen.sh +++ b/init/scripts/worker_gen.sh @@ -38,9 +38,9 @@ for ((i=1; i<=WORKER_COUNT; i++)); do sed -e "s/{{WORKER_NAME}}/${worker_name}/g" \ -e "s/{{PORT}}/${port}/g" \ -e "s/{{SERVER_NAME}}/${HOMESERVER_FQDN}/g" \ - -e "s/{{DB_USER}}/${DB_USER:-synapse}/g" \ - -e "s/{{DB_PASSWORD}}/${DB_PASSWORD:-synapse_password}/g" \ - -e "s/{{DB_NAME}}/${DB_NAME:-synapse}/g" \ + -e "s/{{DB_USER}}/${PG_USER_MATRIX}/g" + -e "s/{{DB_PASSWORD}}/${PG_PASSWORD_MATRIX}/g" + -e "s/{{DB_NAME}}/${PG_DB_MATRIX}/g" "$TEMPLATE_CONFIG" > "${WORKERS_DIR}/${worker_name}.yaml" sed -e "s/{{WORKER_NAME}}/${worker_name}/g" \ @@ -51,7 +51,7 @@ for ((i=1; i<=WORKER_COUNT; i++)); do "$TEMPLATE_LOG" > "${WORKERS_DIR}/${worker_name}.log.config" TRAEFIK_LABELS="" - if [[ "$TRAEFIK_ENABLED" == "1" && -n "$DOMAIN" ]]; then + if [[ "$PROXY" == "TRAEFIK" && -n "$DOMAIN" ]]; then TRAEFIK_LABELS=" labels: - traefik.enable=true - traefik.http.services.${worker_name}.loadbalancer.server.port=${port} diff --git a/setup.sh b/setup.sh index 341c7f6..2f5f125 100755 --- a/setup.sh +++ b/setup.sh @@ -1,7 +1,6 @@ #!/usr/bin/env bash -# AMMIDS Setup Orchestrator -# Author: Cortex@Fossgate -# Src: https://git.fossgate.uk/ammids +# AMMIDS Master Setup Wizard +# Orchestrates the entire deployment flow via a single interactive session set -euo pipefail @@ -9,60 +8,144 @@ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" source "${SCRIPT_DIR}/init/scripts/functions.sh" resolve_paths -ENV_FILE="${ROOT_DIR}/.env" +# Ensure dependencies +require_command "openssl" || require_command "pwgen" -log_info "=== AMMIDS Setup Orchestrator ===" +log_info "=== AMMIDS Interactive Setup Wizard ===" -# 1. Environment Setup -if [[ -f "$ENV_FILE" ]]; then - log_warn ".env exists." - read -r -p " Overwrite and create backup? [y/N]: " confirm - if [[ "$confirm" =~ ^[Yy]$ ]]; then - mkdir -p "$BACKUP_DIR" - BACKUP_FILE="${SCRIPT_DIR}/.env.$(date +%Y%m%d_%H%M%S)" - cp "$ENV_FILE" "$BACKUP_FILE" - log_info "Backup created: $BACKUP_FILE" - "${SCRIPT_DIR}/init/scripts/set_env.sh" - else - log_info "Preserving existing .env. Skipping regeneration." +# 1. Base Configuration +read -r -p "Base Domain (e.g. example.org) [example.org]: " DOMAIN_INPUT +BASE_DOMAIN="${DOMAIN_INPUT:-example.org}" + +log_info "Domain set: ${BASE_DOMAIN}" + +# 2. Service Selection +echo "" +log_info "Select Services:" + +# LiveKit +read -r -p "Enable LiveKit RTC Stack? (Y/n) [Y]: " LIVEKIT_INPUT +LIVEKIT_INPUT="${LIVEKIT_INPUT:-Y}" +if [[ "$LIVEKIT_INPUT" =~ ^[Yy]$ ]]; then + INCLUDE_LIVEKIT="true" +else + INCLUDE_LIVEKIT="false" +fi + +# Web Client (Set to a single value: ELEMENT, CINNY, FLUFFY, or NONE) +echo "Select Web Client: 1) Element 2) Cinny 3) FluffyChat 4) None" +read -r -p "Default [1]: " WEB_APP_INPUT +WEB_APP_INPUT="${WEB_APP_INPUT:-1}" +case "$WEB_APP_INPUT" in + 1) WEBAPP="ELEMENT" ;; + 2) WEBAPP="CINNY" ;; + 3) WEBAPP="FLUFFY" ;; + *) WEBAPP="NONE" ;; +esac +log_info "Web Client selected: ${WEBAPP}" + +# Reverse Proxy (Set to a single value: TRAEFIK or NGINX) +echo "Select Reverse Proxy: 1) Traefik (Handles TLS) 2) Nginx (Behind existing proxy)" +read -r -p "Default [1]: " PROXY_INPUT +PROXY_INPUT="${PROXY_INPUT:-1}" +case "$PROXY_INPUT" in + 1) PROXY="TRAEFIK" ;; + *) PROXY="NGINX" ;; +esac +log_info "Proxy selected: ${PROXY}" + +# Worker Count +read -r -p "Number of Synapse Workers? [Default: 1]: " WORKER_INPUT +WORKER_INPUT="${WORKER_INPUT:-1}" +if ! [[ "$WORKER_INPUT" =~ ^[0-9]+$ ]]; then + log_error "Invalid number. Defaulting to 1." + WORKER_INPUT=1 +fi + +# 3. Environment Variables +echo "" +read -r -p "Auto-generate secure passwords and defaults? [Y/n]: " AUTO_GEN_INPUT +AUTO_GEN_INPUT="${AUTO_GEN_INPUT:-Y}" + +# Initialize .env +> "$ENV_FILE" + +# --- Generate Secrets & Defaults --- +if [[ "$AUTO_GEN_INPUT" =~ ^[Yy]$ ]]; then + log_info "Generating secure defaults..." + auto_var "VOLUME_PATH" "./matrix" "no" + auto_var "DOMAIN" "${BASE_DOMAIN}" "no" + auto_var "HOMESERVER_FQDN" "matrix.${BASE_DOMAIN}" "no" + auto_var "MAS_FQDN" "auth.${BASE_DOMAIN}" "no" + if [[ "$WEBAPP" != "NONE" ]]; then + auto_var "APP_FQDN" "app.${BASE_DOMAIN}" "no" + fi + auto_var "USER_ID" "1000" "no" + auto_var "GROUP_ID" "1000" "no" + auto_var "COUNTRY" "GB" "no" + auto_var "PG_USER" "postgres" "no" + auto_var "PG_PASSWORD" "generated" "yes" + auto_var "PG_USER_MATRIX" "matrix" "no" + auto_var "PG_DB_MATRIX" "synapse" "no" + auto_var "PG_PASSWORD_MATRIX" "generated" "yes" + auto_var "PG_USER_MAS" "mas" "no" + auto_var "PG_DB_MAS" "auth" "no" + auto_var "PG_PASSWORD_MAS" "generated" "yes" + # Generate LiveKit keys if enabled + if [[ "$INCLUDE_LIVEKIT" == "true" ]]; then + echo "LIVEKIT_API_KEY=\"$(openssl rand -hex 16)\"" >> "$ENV_FILE" + echo "LIVEKIT_API_SECRET=\"$(openssl rand -hex 32)\"" >> "$ENV_FILE" + echo "LIVEKIT_FQDN=\"rtc.${BASE_DOMAIN}\"" >> "$ENV_FILE" + echo "JWT_FQDN=\"jwt.${BASE_DOMAIN}\"" >> "$ENV_FILE" + echo "LIVEKIT_UDP_RANGE=\"10000-20000\"" >> "$ENV_FILE" fi else - log_info "No .env found. Running initial setup..." - "${SCRIPT_DIR}/init/scripts/set_env.sh" + log_info "Manual entry mode." + prompt_var "VOLUME_PATH" "Install directory" "./matrix" "no" + auto_var "DOMAIN" "${BASE_DOMAIN}" "no" + prompt_var "HOMESERVER_FQDN" "Homeserver SubDomain" "matrix" "no" + prompt_var "MAS_FQDN" "authentication SubDomain" "auth" "no" + if [[ "$WEBAPP" != "NONE" ]]; then + prompt_var "APP_FQDN" "Web App SubDomain" "app" "no" + fi + prompt_var "USER_ID" "Docker UserID" "1000" "no" + prompt_var "GROUP_ID" "Docker GroupID" "1000" "no" + prompt_var "COUNTRY" "Country Code (e.g. GB)" "GB" "no" + prompt_var "PG_USER" "PostgreSQL Superuser" "postgres" "no" + prompt_var "PG_PASSWORD" "PostgreSQL Superuser Password" "generated" "yes" + prompt_var "PG_USER_MATRIX" "Synapse Database User" "matrix" "no" + prompt_var "PG_DB_MATRIX" "Synapse Database Name" "synapse" "no" + prompt_var "PG_PASSWORD_MATRIX" "Synapse Database Password" "generated" "yes" + prompt_var "PG_USER_MAS" "MAS Database User" "mas" "no" + prompt_var "PG_DB_MAS" "MAS Database Name" "auth" "no" + prompt_var "PG_PASSWORD_MAS" "MAS Database Password" "generated" "yes" fi -# 2. Load Environment & Resolve Paths -source "$ENV_FILE" -resolve_volume_path +auto_var "WORKER_COUNT" "${WORKER_INPUT}" "no" +auto_var "INCLUDE_LIVEKIT" "${INCLUDE_LIVEKIT}" "no" +auto_var "WEBAPP" "${WEBAPP}" "no" +auto_var "PROXY" "${PROXY}" "no" -# 3. Directory & Permission Management -if [[ ! -d "$VOLUME_PATH" ]]; then - log_info "Creating data directory: $VOLUME_PATH" - mkdir -p "$VOLUME_PATH" -fi -fix_ownership "$VOLUME_PATH" +chmod 600 "$ENV_FILE" +log_info "Configuration saved to ${ENV_FILE}" -# 4. Stack Generation -log_info "Generating compose and configurations..." +# 4. Execution Phase +echo "" +log_info "=== Executing Deployment Plan ===" + +log_info "1. Generating Compose File..." "${SCRIPT_DIR}/init/scripts/compose_gen.sh" + +log_info "2. Initializing Database & Configs..." "${SCRIPT_DIR}/init/scripts/config_gen.sh" + +log_info "3. Linking Services (OIDC)..." "${SCRIPT_DIR}/init/scripts/config_link.sh" -# 5. Worker Generation -read -r -p "Number of worker processes? [Default: 1]: " worker_count -worker_count="${worker_count:-1}" - -if ! [[ "$worker_count" =~ ^[0-9]+$ ]]; then - log_error "Invalid number. Aborting worker generation." - exit 1 +if [[ ${WORKER_INPUT} -gt 1 ]]; then + log_info "4. Generating Workers (${WORKER_INPUT})..." + "${SCRIPT_DIR}/init/scripts/worker_gen.sh" -c "$WORKER_INPUT" fi - -if [[ "$worker_count" -gt 0 ]]; then - log_info "Generating $worker_count worker(s)..." - "${SCRIPT_DIR}/init/scripts/worker_gen.sh" -c "$worker_count" -else - log_info "Skipping worker generation (count: 0)." -fi - -log_info "Setup complete. Run 'docker compose up -d' to start services." +log_info "=== Setup Complete ===" +log_info "Run 'docker compose up -d' to start your stack."