Merge claude/1
This commit is contained in:
commit
bace502044
6
init.sh
6
init.sh
@ -1191,6 +1191,12 @@ completeInitMessage()
|
|||||||
fi
|
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
|
if [[ $EUID -ne 0 ]]; then
|
||||||
echo "This script must be run as root."
|
echo "This script must be run as root."
|
||||||
exit 1
|
exit 1
|
||||||
|
|||||||
@ -24,17 +24,17 @@ appStatus()
|
|||||||
isHeader "App Status: $app_name"
|
isHeader "App Status: $app_name"
|
||||||
|
|
||||||
# Check if container is running
|
# 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"
|
isSuccessful "Container: RUNNING"
|
||||||
else
|
else
|
||||||
isNotice "Container: STOPPED"
|
isNotice "Container: STOPPED"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Show basic container info if running
|
# 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 ""
|
||||||
echo "Container Information:"
|
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
|
fi
|
||||||
|
|
||||||
echo ""
|
echo ""
|
||||||
|
|||||||
@ -148,9 +148,9 @@ _backupDbWaitReady()
|
|||||||
good=0
|
good=0
|
||||||
case "$kind" in
|
case "$kind" in
|
||||||
postgres)
|
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
|
esac
|
||||||
if [[ $good -eq 1 ]]; then
|
if [[ $good -eq 1 ]]; then
|
||||||
ok=$((ok + 1))
|
ok=$((ok + 1))
|
||||||
@ -199,7 +199,7 @@ backupDbDump()
|
|||||||
case "$kind" in
|
case "$kind" in
|
||||||
postgres)
|
postgres)
|
||||||
isNotice "Dumping postgres ($container) — live, consistent"
|
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}}"' \
|
'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
|
2>/dev/null | gzip | runFileWrite "$dump"; then
|
||||||
isSuccessful "postgres dump written ($container)"
|
isSuccessful "postgres dump written ($container)"
|
||||||
@ -209,7 +209,7 @@ backupDbDump()
|
|||||||
;;
|
;;
|
||||||
mysql|mariadb)
|
mysql|mariadb)
|
||||||
isNotice "Dumping $kind ($container) — live, consistent"
|
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")' \
|
'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
|
2>/dev/null | gzip | runFileWrite "$dump"; then
|
||||||
isSuccessful "$kind dump written ($container)"
|
isSuccessful "$kind dump written ($container)"
|
||||||
|
|||||||
@ -18,8 +18,8 @@ checkDockerNetworkRequirement()
|
|||||||
((preinstallneeded++))
|
((preinstallneeded++))
|
||||||
fi
|
fi
|
||||||
elif [[ $CFG_DOCKER_INSTALL_TYPE == "rooted" ]]; then
|
elif [[ $CFG_DOCKER_INSTALL_TYPE == "rooted" ]]; then
|
||||||
if docker network inspect $CFG_NETWORK_NAME > /dev/null 2>&1; then
|
if runFileOp 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)
|
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
|
if [[ "$current_subnet" == "$CFG_NETWORK_SUBNET" ]]; then
|
||||||
isSuccessful "Docker Network $CFG_NETWORK_NAME exists with matching subnet"
|
isSuccessful "Docker Network $CFG_NETWORK_NAME exists with matching subnet"
|
||||||
|
|||||||
@ -1,14 +1,17 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
|
||||||
checkRootRequirement()
|
checkRootRequirement()
|
||||||
{
|
{
|
||||||
if [[ $CFG_REQUIREMENT_ROOT == "true" ]]; then
|
if [[ $CFG_REQUIREMENT_ROOT == "true" ]]; then
|
||||||
# Check if script is run as root
|
# Model A least-privilege: the app runs AS the manager user and escalates
|
||||||
if [[ $EUID -ne 0 ]]; then
|
# only specific commands via runSystem, so accept the manager as well as
|
||||||
echo "This script must be run as root."
|
# root — not root-only. (init.sh keeps its own install-time root check.)
|
||||||
exit 1
|
local mgr="${sudo_user_name:-libreportal}"
|
||||||
|
if [[ $EUID -eq 0 || "$(id -un)" == "$mgr" ]]; then
|
||||||
|
isSuccessful "Running as $(id -un)."
|
||||||
else
|
else
|
||||||
isSuccessful "Script ran under root user."
|
echo "This script must be run as root or the manager user ($mgr)."
|
||||||
|
exit 1
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
@ -204,7 +204,7 @@ validateDockerService() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
validateContainerHealth() {
|
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
|
if [ -z "$containerInfo" ]; then
|
||||||
healthLogError "LibrePortal WebUI container not found"
|
healthLogError "LibrePortal WebUI container not found"
|
||||||
@ -214,7 +214,7 @@ validateContainerHealth() {
|
|||||||
|
|
||||||
if echo "$status" | grep -q "Up"; then
|
if echo "$status" | grep -q "Up"; then
|
||||||
# Check if container is responsive
|
# 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"
|
healthLogSuccess "Container is running and responsive"
|
||||||
else
|
else
|
||||||
healthLogWarning "Container is running but WebUI process not found"
|
healthLogWarning "Container is running but WebUI process not found"
|
||||||
@ -226,7 +226,7 @@ validateContainerHealth() {
|
|||||||
|
|
||||||
validateWebUIReadiness() {
|
validateWebUIReadiness() {
|
||||||
# Get the actual port mapping from the container
|
# 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
|
if [ -z "$portMapping" ]; then
|
||||||
healthLogWarning "No port mapping found for libreportal-service container"
|
healthLogWarning "No port mapping found for libreportal-service container"
|
||||||
|
|||||||
@ -4,6 +4,6 @@ dockerCheckAppHealthDetails()
|
|||||||
{
|
{
|
||||||
local app_name="$1"
|
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."
|
checkSuccess "Getting $app_name health details."
|
||||||
}
|
}
|
||||||
|
|||||||
@ -4,6 +4,6 @@ dockerCheckAppHealthStatus()
|
|||||||
{
|
{
|
||||||
local app_name="$1"
|
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."
|
checkSuccess "Getting $app_name health status."
|
||||||
}
|
}
|
||||||
|
|||||||
@ -7,11 +7,11 @@ dockerPruneAppNetworks()
|
|||||||
if [ ! -z "$app_name" ]; then
|
if [ ! -z "$app_name" ]; then
|
||||||
local networks_found=false
|
local networks_found=false
|
||||||
# Prune all networks except those containing the specified app_name
|
# Prune all networks except those containing the specified app_name
|
||||||
for network_id in $(docker network ls --quiet); do
|
for network_id in $(runFileOp docker network ls --quiet); do
|
||||||
network_name=$(docker network inspect --format '{{.Name}}' "$network_id")
|
network_name=$(runFileOp docker network inspect --format '{{.Name}}' "$network_id")
|
||||||
if [[ "$network_name" == *"$app_name"* ]]; then
|
if [[ "$network_name" == *"$app_name"* ]]; then
|
||||||
local result=$(dockerCommandRun "docker network rm "$network_id"")
|
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
|
networks_found=true
|
||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
|
|||||||
@ -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)
|
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
|
if [[ -n "$existing" ]]; then
|
||||||
ip_available=""
|
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=""
|
ip_available=""
|
||||||
else
|
else
|
||||||
ip_available="$test_ip"
|
ip_available="$test_ip"
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user