#!/bin/bash # Walks installed apps and offers to flip CFG__NETWORK to gluetun for each # eligible one. Honors the curated category list + CFG_REQUIREMENT_GLUETUN_FOR_ALL # override flag. Skips itself, Traefik, LibrePortal, fail2ban. gluetunRouteExistingAppsPrompt() { local categories_file="${containers_dir}libreportal/frontend/data/apps/gluetun-eligible-categories.json" local override="${CFG_REQUIREMENT_GLUETUN_FOR_ALL:-false}" if ! command -v sqlite3 >/dev/null 2>&1 || [[ ! -f "$docker_dir/$db_file" ]]; then isNotice "Database not available; skipping per-app routing prompt." return 0 fi local allow_csv="" if [[ -f "$categories_file" ]] && command -v jq >/dev/null 2>&1; then allow_csv=$(jq -r '.categories | join(",")' "$categories_file" 2>/dev/null | tr '[:upper:]' '[:lower:]') fi local installed installed=$(runInstallOp sqlite3 "$docker_dir/$db_file" \ "SELECT name FROM apps WHERE status = 1 AND name NOT IN ('gluetun','libreportal','traefik','fail2ban') ORDER BY name;" 2>/dev/null) if [[ -z "$installed" ]]; then isNotice "No other apps installed yet. Skipping." return 0 fi local eligible=() while IFS= read -r app; do [[ -z "$app" ]] && continue local cfg_file="${containers_dir}${app}/${app}.config" [[ -f "$cfg_file" ]] || continue local category category=$(grep -E "^CFG_${app^^}_CATEGORY=" "$cfg_file" 2>/dev/null \ | head -1 | cut -d'=' -f2 | tr -d '"' | tr '[:upper:]' '[:lower:]') local is_eligible="false" if [[ "$override" == "true" ]]; then is_eligible="true" elif [[ -n "$allow_csv" ]]; then IFS=',' read -ra cats <<< "$allow_csv" for c in "${cats[@]}"; do if [[ "$c" == "$category" ]]; then is_eligible="true"; break; fi done fi [[ "$is_eligible" == "true" ]] && eligible+=("$app") done <<< "$installed" if [[ ${#eligible[@]} -eq 0 ]]; then isNotice "No eligible installed apps. (Enable CFG_REQUIREMENT_GLUETUN_FOR_ALL to expose every app.)" return 0 fi echo " The following installed apps can be routed through Gluetun:" for app in "${eligible[@]}"; do local cfg_file="${containers_dir}${app}/${app}.config" local current current=$(grep -E "^CFG_${app^^}_NETWORK=" "$cfg_file" 2>/dev/null | head -1 | cut -d'=' -f2) [[ -z "$current" ]] && current="default" echo " - ${app} (current: ${current})" done echo "" isQuestion "Apply gluetun routing now? Tick each app to flip. (y/N): " local resp read -rp "" resp echo "" case "$resp" in [yY]*) ;; *) isNotice "Skipped. You can apply later via the WebUI gluetun page or per-app config."; return 0 ;; esac for app in "${eligible[@]}"; do local cfg_file="${containers_dir}${app}/${app}.config" local current current=$(grep -E "^CFG_${app^^}_NETWORK=" "$cfg_file" 2>/dev/null | head -1 | cut -d'=' -f2) [[ -z "$current" ]] && current="default" isQuestion " Route '$app' through gluetun? (current: $current) [y/n/skip]: " local r read -rp "" r case "$r" in [yY]*) updateConfigOption "CFG_${app^^}_NETWORK" "gluetun" "$cfg_file" isSuccessful " Set CFG_${app^^}_NETWORK=gluetun. Re-running install for $app..." dockerInstallApp "$app" ;; [nN]*) if [[ "$current" == "gluetun" ]]; then updateConfigOption "CFG_${app^^}_NETWORK" "default" "$cfg_file" isSuccessful " Reverted $app to default network. Re-running install..." dockerInstallApp "$app" fi ;; *) ;; esac done }