The borg/restic/kopia engines all dropped to the dedicated backup user via scattered 'sudo -E -u $docker_install_user'. Centralize that into a single runBackupOp helper so the backup subsystem has one audit point and the scoped sudoers needs only the (dockerinstall) drop rule. Also: - owncloud config heredoc tees -> runSystem (container-UID file) - webui_display_logins: fix the broken 'command -v sudo sqlite3' guard to 'command -v sqlite3' (body already runs sqlite3 via runInstallOp) Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> Signed-off-by: librelad <librelad@digitalangels.vip>
184 lines
7.7 KiB
Bash
Executable File
184 lines
7.7 KiB
Bash
Executable File
#!/bin/bash
|
|
|
|
getLibrePortalWebUIUrls()
|
|
{
|
|
local libreportal_external_url=""
|
|
local libreportal_internal_url=""
|
|
|
|
# Ensure required variables are set
|
|
local docker_dir="${docker_dir:-/docker}"
|
|
local db_file="${db_file:-database.db}"
|
|
|
|
# Check if sqlite3 is available and database exists
|
|
if command -v sqlite3 &> /dev/null && [ -f "$docker_dir/$db_file" ]; then
|
|
# Check if LibrePortal app is installed
|
|
local libreportal_check=$(runInstallOp sqlite3 "$docker_dir/$db_file" "SELECT name FROM apps WHERE name = 'libreportal' AND status = 1;" 2>/dev/null)
|
|
|
|
if [[ -n "$libreportal_check" ]]; then
|
|
# Get the main service IP for LibrePortal
|
|
local docker_service=$(runInstallOp sqlite3 "$docker_dir/$db_file" "SELECT DISTINCT service_name, resource_value FROM network_resources WHERE app_name = 'libreportal' AND resource_type = 'ip' AND status = 'active' ORDER BY service_name LIMIT 1;" 2>/dev/null)
|
|
|
|
if [[ -n "$docker_service" ]]; then
|
|
local service_name=$(echo "$docker_service" | cut -d'|' -f1)
|
|
local service_ip=$(echo "$docker_service" | cut -d'|' -f2)
|
|
|
|
# Get the webui port mapping for this service
|
|
local port_mapping=$(runInstallOp sqlite3 "$docker_dir/$db_file" "SELECT service_name, resource_value FROM network_resources WHERE app_name = 'libreportal' AND resource_type = 'port' AND parent_service = '$service_name' AND service_name LIKE '%webui%' AND status = 'active' ORDER BY service_name LIMIT 1;" 2>/dev/null)
|
|
|
|
if [[ -n "$port_mapping" ]]; then
|
|
local port_service_name=$(echo "$port_mapping" | cut -d'|' -f1)
|
|
local port_data=$(echo "$port_mapping" | cut -d'|' -f2)
|
|
|
|
# Parse port mapping: external:internal:access:protocol
|
|
local external_port=$(echo "$port_data" | cut -d':' -f1)
|
|
local internal_port=$(echo "$port_data" | cut -d':' -f2)
|
|
local access_type=$(echo "$port_data" | cut -d':' -f3)
|
|
|
|
# Check if Traefik is installed for domain access
|
|
local traefik_installed=$(runInstallOp sqlite3 "$docker_dir/$db_file" "SELECT name FROM apps WHERE name = 'traefik' AND status = 1;" 2>/dev/null)
|
|
|
|
if [[ -n "$traefik_installed" ]]; then
|
|
# Get domain from general config
|
|
local domain=$(runInstallOp sqlite3 "$docker_dir/$db_file" "SELECT resource_value FROM options WHERE option = 'domain_LIBREPORTAL_DOMAIN';" 2>/dev/null)
|
|
if [[ -n "$domain" ]]; then
|
|
libreportal_external_url="https://libreportal.$domain"
|
|
else
|
|
libreportal_external_url="https://libreportal.local"
|
|
fi
|
|
else
|
|
# Use IP:Port for external access
|
|
if [[ -z "$public_ip_v4" ]]; then
|
|
public_ip_v4=$(dig +short myip.opendns.com @resolver1.opendns.com 2>/dev/null || hostname -I | awk '{print $1}' || echo "localhost")
|
|
fi
|
|
local public_ip=${public_ip_v4:-"localhost"}
|
|
libreportal_external_url="http://$public_ip:$external_port"
|
|
fi
|
|
|
|
# Internal URL
|
|
libreportal_internal_url="http://$service_ip:$internal_port"
|
|
fi
|
|
fi
|
|
fi
|
|
fi
|
|
|
|
# Better fallback: try to find any available port for LibrePortal
|
|
if [[ -z "$libreportal_external_url" ]]; then
|
|
# Try to get any port mapping for LibrePortal
|
|
local any_port=$(runInstallOp sqlite3 "$docker_dir/$db_file" "SELECT resource_value FROM network_resources WHERE app_name = 'libreportal' AND resource_type = 'port' AND status = 'active' LIMIT 1;" 2>/dev/null)
|
|
|
|
if [[ -n "$any_port" ]]; then
|
|
local external_port=$(echo "$any_port" | cut -d':' -f1)
|
|
if [[ -z "$public_ip_v4" ]]; then
|
|
public_ip_v4=$(dig +short myip.opendns.com @resolver1.opendns.com 2>/dev/null || hostname -I | awk '{print $1}' || echo "localhost")
|
|
fi
|
|
local public_ip=${public_ip_v4:-"localhost"}
|
|
libreportal_external_url="http://$public_ip:$external_port"
|
|
else
|
|
# No ports found at all - don't show external URL
|
|
libreportal_external_url=""
|
|
fi
|
|
fi
|
|
|
|
if [[ -z "$libreportal_internal_url" ]]; then
|
|
libreportal_internal_url="http://localhost:1111"
|
|
fi
|
|
|
|
echo "$libreportal_external_url|$libreportal_internal_url"
|
|
}
|
|
|
|
webuiPrintInstallCard()
|
|
{
|
|
local external_url="$1"
|
|
local internal_url="$2"
|
|
|
|
# UTF-8 box-drawing chars; fall back to ASCII on non-UTF-8 locales.
|
|
local TL ML BL VB HB
|
|
if [[ "${LANG}${LC_ALL}" =~ [Uu][Tt][Ff] ]]; then
|
|
TL='╔'; ML='╠'; BL='╚'; VB='║'; HB='═'
|
|
else
|
|
TL='+'; ML='+'; BL='+'; VB='|'; HB='='
|
|
fi
|
|
local bar="" i
|
|
for ((i=0; i<60; i++)); do bar+="$HB"; done
|
|
|
|
# ac = accent (bright cyan, bold) used for section headings
|
|
local g="${GREEN}" b="${BLUE}" c="${CYAN}" d="${DIM}" bd="${BOLD}" n="${NC}"
|
|
local ac=$'\033[1;96m'
|
|
|
|
echo -e "${TL}${bar}"
|
|
echo -e "${VB}"
|
|
echo -e "${VB} ${bd}${g}✅ LibrePortal installation complete! <3${n}"
|
|
if [[ -n "$install_log_path" && -f "$install_log_path" ]]; then
|
|
local ap=$'\033[1;95m'
|
|
echo -e "${VB}"
|
|
echo -e "${VB} ${ap}📄 Full install log${n}"
|
|
echo -e "${VB} ${d}${install_log_path}${n}"
|
|
fi
|
|
echo -e "${VB}"
|
|
echo -e "${ML}${bar}"
|
|
echo -e "${VB}"
|
|
echo -e "${VB} ${ac}🔐 WebUI Credentials${n}"
|
|
echo -e "${VB} Username ${c}${CFG_WEBUI_USERNAME}${n}"
|
|
echo -e "${VB} Password ${c}${CFG_WEBUI_PASSWORD}${n}"
|
|
echo -e "${VB}"
|
|
echo -e "${VB} ${ac}🌐 Access URLs${n}"
|
|
if [[ -n "$external_url" ]]; then
|
|
echo -e "${VB} External ${b}${external_url}${n}"
|
|
fi
|
|
echo -e "${VB} Internal ${b}${internal_url}${n}"
|
|
echo -e "${VB}"
|
|
echo -e "${ML}${bar}"
|
|
echo -e "${VB}"
|
|
local ay=$'\033[1;93m'
|
|
echo -e "${VB} ${ay}💡 Recovery commands${n} ${d}(run as the 'libreportal' user)${n}"
|
|
echo -e "${VB}"
|
|
echo -e "${VB} libreportal webui login show"
|
|
echo -e "${VB} ${d}→ display the current WebUI login credentials${n}"
|
|
echo -e "${VB}"
|
|
echo -e "${VB} libreportal webui login reset"
|
|
echo -e "${VB} ${d}→ generate new WebUI login credentials${n}"
|
|
echo -e "${VB}"
|
|
echo -e "${BL}${bar}"
|
|
echo ""
|
|
}
|
|
|
|
webuiPrintLoginBlock()
|
|
{
|
|
local mode="${1:-default}" # default | show | reset
|
|
|
|
local webui_urls=$(getLibrePortalWebUIUrls)
|
|
local external_url=$(echo "$webui_urls" | cut -d'|' -f1)
|
|
local internal_url=$(echo "$webui_urls" | cut -d'|' -f2)
|
|
|
|
if [[ "$mode" == "default" ]]; then
|
|
webuiPrintInstallCard "$external_url" "$internal_url"
|
|
return
|
|
fi
|
|
|
|
local title
|
|
case "$mode" in
|
|
show) title="LibrePortal WebUI Credentials (current)" ;;
|
|
reset) title="LibrePortal WebUI Credentials (new)" ;;
|
|
esac
|
|
|
|
isHeader "$title"
|
|
echo " Username: $CFG_WEBUI_USERNAME"
|
|
echo " Password: $CFG_WEBUI_PASSWORD"
|
|
if [[ -n "$external_url" ]]; then
|
|
echo " External: $external_url"
|
|
fi
|
|
echo " Internal: $internal_url"
|
|
echo ""
|
|
echo " 💡 Tip: run these as the 'libreportal' user if you need to recover:"
|
|
echo " libreportal webui login show # show this info again"
|
|
echo " libreportal webui login reset # make new credentials"
|
|
echo ""
|
|
}
|
|
|
|
webuiDisplayLogins()
|
|
{
|
|
if [[ $CFG_REQUIREMENT_WEBUI == "true" ]]; then
|
|
webuiPrintLoginBlock "${1:-default}"
|
|
fi
|
|
}
|