The Services tab restart button POSTed to a backend endpoint that (a) checked the app's compose path from INSIDE the webui container, where the host's containers root isn't mounted — so every restart failed with 'Compose file not found' — and (b) queued a raw 'docker compose restart' that the host task processor would run as the manager user, which can't talk to the rootless daemon anyway. Errors surfaced via a bare alert(). Per-service restart now follows the exact shape of the whole-app verbs: - CLI: 'libreportal app restart <app> [service]' — the optional service arg makes dockerRestartApp restart just that compose service, via dockerCommandRun (right user in rootless mode) from the app dir on the host, where the compose file actually lives. Service names validated against compose-legal characters before touching a shell line. - WebUI: the button dispatches a 'service_restart' task action through the task router (mutations-via-tasks), runs in the background with the standard task toast + link — no page switch — and failures use the notification system instead of alert(). Because the task runs host- side, restarting the WebUI's own libreportal-service now works too. - Backend: the mutating restart endpoint and its now-unused helpers are removed; service-routes.js is read-only surface (status + log tails). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Signed-off-by: librelad <librelad@digitalangels.vip>
49 lines
2.1 KiB
Bash
Executable File
49 lines
2.1 KiB
Bash
Executable File
#!/bin/bash
|
|
|
|
dockerRestartApp()
|
|
{
|
|
local app_name="$1"
|
|
local service_name="$2" # optional: restart just this one compose service
|
|
|
|
if [[ -z "$app_name" ]]; then
|
|
isNotice "No app name provided. Unable to restart containers."
|
|
return 1
|
|
fi
|
|
|
|
# Single-service restart — the WebUI Services tab's per-row button routes
|
|
# here as a task (libreportal app restart <app> <service>). Uses compose so
|
|
# the restart respects the deployed service definition, and dockerCommandRun
|
|
# so it runs as the right user in rootless mode.
|
|
if [[ -n "$service_name" ]]; then
|
|
# The name reaches a shell line — accept only compose-legal names.
|
|
if [[ ! "$service_name" =~ ^[A-Za-z0-9][A-Za-z0-9._-]*$ ]]; then
|
|
isError "Invalid service name: $service_name"
|
|
return 1
|
|
fi
|
|
local app_dir="${containers_dir%/}/$app_name"
|
|
if [[ ! -f "$app_dir/docker-compose.yml" ]]; then
|
|
isError "No compose file for '$app_name' at $app_dir/docker-compose.yml"
|
|
return 1
|
|
fi
|
|
isNotice "Restarting service '$service_name' of '$app_name'. Please wait..."
|
|
local result; result=$(dockerCommandRun "cd $app_dir && docker compose restart $service_name" 2>&1)
|
|
checkSuccess "Restarted service '$service_name' of '$app_name'"
|
|
return
|
|
fi
|
|
|
|
isNotice "Restarting Docker containers for '$app_name'. Please wait..."
|
|
|
|
# Restart containers in one go
|
|
local result; result=$(dockerCommandRun "docker ps -aqf name=$app_name | xargs -r docker restart" >/dev/null 2>&1)
|
|
checkSuccess "Restarted Docker containers matching '$app_name'"
|
|
|
|
# App-specific restart hook — host-installed apps define restart<App> to
|
|
# restart their systemd services etc. (mirrors dockerUninstallApp's
|
|
# uninstall<App> hook). No-op for pure-docker apps that don't define one.
|
|
local app_name_ucfirst="$(tr '[:lower:]' '[:upper:]' <<< ${app_name:0:1})${app_name:1}"
|
|
local restartFuncName="restart${app_name_ucfirst}"
|
|
if declare -f "$restartFuncName" >/dev/null 2>&1; then
|
|
"$restartFuncName"
|
|
fi
|
|
}
|