Merge claude/1

This commit is contained in:
librelad 2026-05-24 16:53:37 +01:00
commit bace502044
10 changed files with 34 additions and 25 deletions

View File

@ -1191,6 +1191,12 @@ completeInitMessage()
fi
}
# Only run the installer entrypoint (root check + init flow) when init.sh is
# EXECUTED directly. When it's SOURCED — start.sh loads init.sh for its function
# defs at runtime, and under Model A start.sh runs as the manager, not root — the
# defs above are all that's wanted and this root check must NOT fire.
[[ "${BASH_SOURCE[0]}" != "${0}" ]] && return 0 2>/dev/null
if [[ $EUID -ne 0 ]]; then
echo "This script must be run as root."
exit 1

View File

@ -24,17 +24,17 @@ appStatus()
isHeader "App Status: $app_name"
# Check if container is running
if docker ps --format '{{.Names}}' | grep -q "^${app_name}$"; then
if runFileOp docker ps --format '{{.Names}}' | grep -q "^${app_name}$"; then
isSuccessful "Container: RUNNING"
else
isNotice "Container: STOPPED"
fi
# Show basic container info if running
if docker ps --format '{{.Names}}' | grep -q "^${app_name}$"; then
if runFileOp docker ps --format '{{.Names}}' | grep -q "^${app_name}$"; then
echo ""
echo "Container Information:"
docker ps --format "table {{.Names}}\t{{.Status}}\t{{.Ports}}" | grep "$app_name" || echo "No port information available"
runFileOp docker ps --format "table {{.Names}}\t{{.Status}}\t{{.Ports}}" | grep "$app_name" || echo "No port information available"
fi
echo ""

View File

@ -148,9 +148,9 @@ _backupDbWaitReady()
good=0
case "$kind" in
postgres)
docker exec "$container" sh -c 'export PGPASSWORD="${POSTGRES_PASSWORD:-}"; psql -U "${POSTGRES_USER:-postgres}" -d "${POSTGRES_DB:-${POSTGRES_USER:-postgres}}" -tAc "SELECT 1"' >/dev/null 2>&1 && good=1 ;;
runFileOp docker exec "$container" sh -c 'export PGPASSWORD="${POSTGRES_PASSWORD:-}"; psql -U "${POSTGRES_USER:-postgres}" -d "${POSTGRES_DB:-${POSTGRES_USER:-postgres}}" -tAc "SELECT 1"' >/dev/null 2>&1 && good=1 ;;
*)
docker exec "$container" sh -c 'RP="${MARIADB_ROOT_PASSWORD:-$MYSQL_ROOT_PASSWORD}"; mariadb -uroot -p"$RP" -N -e "SELECT 1" 2>/dev/null || mysql -uroot -p"$RP" -N -e "SELECT 1"' >/dev/null 2>&1 && good=1 ;;
runFileOp docker exec "$container" sh -c 'RP="${MARIADB_ROOT_PASSWORD:-$MYSQL_ROOT_PASSWORD}"; mariadb -uroot -p"$RP" -N -e "SELECT 1" 2>/dev/null || mysql -uroot -p"$RP" -N -e "SELECT 1"' >/dev/null 2>&1 && good=1 ;;
esac
if [[ $good -eq 1 ]]; then
ok=$((ok + 1))
@ -199,7 +199,7 @@ backupDbDump()
case "$kind" in
postgres)
isNotice "Dumping postgres ($container) — live, consistent"
if docker exec "$container" sh -c \
if runFileOp docker exec "$container" sh -c \
'export PGPASSWORD="${POSTGRES_PASSWORD:-}"; pg_dump --clean --if-exists -U "${POSTGRES_USER:-postgres}" -d "${POSTGRES_DB:-${POSTGRES_USER:-postgres}}"' \
2>/dev/null | gzip | runFileWrite "$dump"; then
isSuccessful "postgres dump written ($container)"
@ -209,7 +209,7 @@ backupDbDump()
;;
mysql|mariadb)
isNotice "Dumping $kind ($container) — live, consistent"
if docker exec "$container" sh -c \
if runFileOp docker exec "$container" sh -c \
'RP="${MARIADB_ROOT_PASSWORD:-$MYSQL_ROOT_PASSWORD}"; DB="${MARIADB_DATABASE:-$MYSQL_DATABASE}"; (mariadb-dump -uroot -p"$RP" --single-transaction --routines --triggers --databases "$DB" 2>/dev/null || mysqldump -uroot -p"$RP" --single-transaction --routines --triggers --databases "$DB")' \
2>/dev/null | gzip | runFileWrite "$dump"; then
isSuccessful "$kind dump written ($container)"

View File

@ -18,8 +18,8 @@ checkDockerNetworkRequirement()
((preinstallneeded++))
fi
elif [[ $CFG_DOCKER_INSTALL_TYPE == "rooted" ]]; then
if docker network inspect $CFG_NETWORK_NAME > /dev/null 2>&1; then
local current_subnet=$(docker network inspect $CFG_NETWORK_NAME --format '{{range .IPAM.Config}}{{.Subnet}}{{end}}' 2>/dev/null)
if runFileOp docker network inspect $CFG_NETWORK_NAME > /dev/null 2>&1; then
local current_subnet=$(runFileOp docker network inspect $CFG_NETWORK_NAME --format '{{range .IPAM.Config}}{{.Subnet}}{{end}}' 2>/dev/null)
if [[ "$current_subnet" == "$CFG_NETWORK_SUBNET" ]]; then
isSuccessful "Docker Network $CFG_NETWORK_NAME exists with matching subnet"

View File

@ -1,14 +1,17 @@
#!/bin/bash
checkRootRequirement()
{
{
if [[ $CFG_REQUIREMENT_ROOT == "true" ]]; then
# Check if script is run as root
if [[ $EUID -ne 0 ]]; then
echo "This script must be run as root."
exit 1
# Model A least-privilege: the app runs AS the manager user and escalates
# only specific commands via runSystem, so accept the manager as well as
# root — not root-only. (init.sh keeps its own install-time root check.)
local mgr="${sudo_user_name:-libreportal}"
if [[ $EUID -eq 0 || "$(id -un)" == "$mgr" ]]; then
isSuccessful "Running as $(id -un)."
else
isSuccessful "Script ran under root user."
echo "This script must be run as root or the manager user ($mgr)."
exit 1
fi
fi
}
}

View File

@ -204,7 +204,7 @@ validateDockerService() {
}
validateContainerHealth() {
local containerInfo=$(docker ps -a --filter "name=libreportal-service" --format "{{.Status}}|{{.Names}}" 2>/dev/null)
local containerInfo=$(runFileOp docker ps -a --filter "name=libreportal-service" --format "{{.Status}}|{{.Names}}" 2>/dev/null)
if [ -z "$containerInfo" ]; then
healthLogError "LibrePortal WebUI container not found"
@ -214,7 +214,7 @@ validateContainerHealth() {
if echo "$status" | grep -q "Up"; then
# Check if container is responsive
if docker exec libreportal-service pgrep -f "node.*webui" >/dev/null 2>&1; then
if runFileOp docker exec libreportal-service pgrep -f "node.*webui" >/dev/null 2>&1; then
healthLogSuccess "Container is running and responsive"
else
healthLogWarning "Container is running but WebUI process not found"
@ -226,7 +226,7 @@ validateContainerHealth() {
validateWebUIReadiness() {
# Get the actual port mapping from the container
local portMapping=$(docker port libreportal-service 2>/dev/null | head -1)
local portMapping=$(runFileOp docker port libreportal-service 2>/dev/null | head -1)
if [ -z "$portMapping" ]; then
healthLogWarning "No port mapping found for libreportal-service container"

View File

@ -4,6 +4,6 @@ dockerCheckAppHealthDetails()
{
local app_name="$1"
result=$(docker inspect --format "{{json .State.Health }}" $app_name | jq)
result=$(runFileOp docker inspect --format "{{json .State.Health }}" $app_name | jq)
checkSuccess "Getting $app_name health details."
}

View File

@ -4,6 +4,6 @@ dockerCheckAppHealthStatus()
{
local app_name="$1"
result=$(docker inspect --format "{{json .State.Health.Status }}" $app_name)
result=$(runFileOp docker inspect --format "{{json .State.Health.Status }}" $app_name)
checkSuccess "Getting $app_name health status."
}

View File

@ -7,11 +7,11 @@ dockerPruneAppNetworks()
if [ ! -z "$app_name" ]; then
local networks_found=false
# Prune all networks except those containing the specified app_name
for network_id in $(docker network ls --quiet); do
network_name=$(docker network inspect --format '{{.Name}}' "$network_id")
for network_id in $(runFileOp docker network ls --quiet); do
network_name=$(runFileOp docker network inspect --format '{{.Name}}' "$network_id")
if [[ "$network_name" == *"$app_name"* ]]; then
local result=$(dockerCommandRun "docker network rm "$network_id"")
checkSuccess "Removing the unused docker network - $network_name"
checkSuccess "Removing the unused runFileOp docker network - $network_name"
networks_found=true
fi
done

View File

@ -14,7 +14,7 @@ ipIsAvailable()
local existing=$(sqlite3 "$docker_dir/$db_file" "SELECT resource_value FROM network_resources WHERE resource_type = 'ip' AND resource_value = '$test_ip' AND status = 'active';" 2>/dev/null)
if [[ -n "$existing" ]]; then
ip_available=""
elif docker network inspect $CFG_NETWORK_NAME --format '{{range .Containers}}{{.IPv4Address}} {{end}}' 2>/dev/null | grep -q "$test_ip"; then
elif runFileOp docker network inspect $CFG_NETWORK_NAME --format '{{range .Containers}}{{.IPv4Address}} {{end}}' 2>/dev/null | grep -q "$test_ip"; then
ip_available=""
else
ip_available="$test_ip"