refactor(service): make task processor service setup idempotent
installLibrePortalWebUITaskService only wrote the unit if it didn't already exist, so env/User/mode changes never reached an existing install and a docker-type switch couldn't update the service. Make it converge: compute the desired unit for the current mode and only rewrite + daemon-reload + restart when it actually differs (otherwise just ensure enabled+running, no restart, so routine re-runs don't bounce the processor and kill in-flight tasks). The docker-type switcher now calls this idempotent setup (replacing the one-shot restart helper), so a swap updates the env AND restarts in one step. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> Signed-off-by: librelad <librelad@digitalangels.vip>
This commit is contained in:
parent
6f7c239753
commit
e5f637bca6
@ -75,7 +75,7 @@ dockerSwitcherSwap()
|
|||||||
dockerStartAllApps;
|
dockerStartAllApps;
|
||||||
databaseOptionInsert "docker_type" $CFG_DOCKER_INSTALL_TYPE;
|
databaseOptionInsert "docker_type" $CFG_DOCKER_INSTALL_TYPE;
|
||||||
switchMigrateRestoreApps;
|
switchMigrateRestoreApps;
|
||||||
restartLibrePortalWebUITaskService;
|
installLibrePortalWebUITaskService;
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
@ -114,7 +114,7 @@ dockerSwitcherSwap()
|
|||||||
dockerStartAllApps;
|
dockerStartAllApps;
|
||||||
databaseOptionInsert "docker_type" $CFG_DOCKER_INSTALL_TYPE;
|
databaseOptionInsert "docker_type" $CFG_DOCKER_INSTALL_TYPE;
|
||||||
switchMigrateRestoreApps;
|
switchMigrateRestoreApps;
|
||||||
restartLibrePortalWebUITaskService;
|
installLibrePortalWebUITaskService;
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
elif [[ $flag == "cli" ]]; then
|
elif [[ $flag == "cli" ]]; then
|
||||||
|
|||||||
@ -1,34 +1,37 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
|
||||||
# LibrePortal Task Processor Systemd Service Setup
|
# LibrePortal Task Processor Systemd Service Setup
|
||||||
# Replaces crontabSetupTaskProcessor with systemd service
|
# Replaces crontabSetupTaskProcessor with systemd service.
|
||||||
installLibrePortalWebUITaskService()
|
#
|
||||||
|
# Idempotent: computes the desired unit for the CURRENT docker mode and only
|
||||||
|
# rewrites + daemon-reloads + restarts when it actually differs from what's on
|
||||||
|
# disk. So routine re-runs are no-ops (no needless restart that would kill an
|
||||||
|
# in-flight task), while a rooted<->rootless switch — which changes the env
|
||||||
|
# block — triggers exactly one rewrite + restart so the processor re-reads the
|
||||||
|
# new mode. Safe to call from install AND from the docker-type switcher.
|
||||||
|
installLibrePortalWebUITaskService()
|
||||||
{
|
{
|
||||||
if [[ "$CFG_REQUIREMENT_WEBUI_SERVICE" == "true" ]]; then
|
[[ "$CFG_REQUIREMENT_WEBUI_SERVICE" == "true" ]] || return 0
|
||||||
local service_file="/etc/systemd/system/libreportal.service"
|
|
||||||
if [[ ! -f "$service_file" ]]; then
|
|
||||||
local task_processor_script="$install_scripts_dir/crontab/task/crontab_task_processor.sh"
|
|
||||||
local task_dir="$containers_dir/libreportal/frontend/data/tasks"
|
|
||||||
|
|
||||||
# Update TASK_DIR in the task processor script
|
|
||||||
if [ -f "$task_processor_script" ]; then
|
|
||||||
sed -i "s|TASK_DIR=\".*\"|TASK_DIR=\"$task_dir\"|g" "$task_processor_script"
|
|
||||||
chmod +x "$task_processor_script"
|
|
||||||
else
|
|
||||||
isNotice "Task processor script not found"
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Rootless docker exposes the daemon at /run/user/<uid>/docker.sock and
|
local service_file="/etc/systemd/system/libreportal.service"
|
||||||
# depends on XDG_RUNTIME_DIR being set. Systemd units don't inherit user
|
local task_processor_script="$install_scripts_dir/crontab/task/crontab_task_processor.sh"
|
||||||
# bashrc, so without these Environment= lines the processor would fall
|
local task_dir="$containers_dir/libreportal/frontend/data/tasks"
|
||||||
# back to /var/run/docker.sock (which rootless does not create) and any
|
|
||||||
# `docker …` call inside the task would fail. Rootful gets no extras —
|
# Point the processor at the task dir (idempotent).
|
||||||
# the default /var/run path is already correct.
|
if [ -f "$task_processor_script" ]; then
|
||||||
#
|
sed -i "s|TASK_DIR=\".*\"|TASK_DIR=\"$task_dir\"|g" "$task_processor_script"
|
||||||
# The rootless daemon runs as the DOCKER INSTALL USER, so its socket lives in
|
chmod +x "$task_processor_script"
|
||||||
# that user's runtime dir — not the manager's. Use the docker install user's
|
else
|
||||||
# uid here (matches dockerCommandRunInstallUser); pointing at the manager's
|
isNotice "Task processor script not found"
|
||||||
# uid was wrong — that socket doesn't exist.
|
fi
|
||||||
|
|
||||||
|
# Rootless docker exposes the daemon at /run/user/<uid>/docker.sock and depends
|
||||||
|
# on XDG_RUNTIME_DIR being set. Systemd units don't inherit user bashrc, so
|
||||||
|
# without these Environment= lines the processor would fall back to
|
||||||
|
# /var/run/docker.sock (which rootless does not create). The rootless daemon
|
||||||
|
# runs as the DOCKER INSTALL USER, so its socket lives in THAT user's runtime
|
||||||
|
# dir (matches dockerCommandRunInstallUser). Rooted gets no extras — the
|
||||||
|
# default /var/run path is already correct.
|
||||||
local service_env_block=""
|
local service_env_block=""
|
||||||
if [[ "$CFG_DOCKER_INSTALL_TYPE" == "rootless" ]]; then
|
if [[ "$CFG_DOCKER_INSTALL_TYPE" == "rootless" ]]; then
|
||||||
local docker_install_uid
|
local docker_install_uid
|
||||||
@ -37,8 +40,8 @@ installLibrePortalWebUITaskService()
|
|||||||
Environment=XDG_RUNTIME_DIR=/run/user/${docker_install_uid}"
|
Environment=XDG_RUNTIME_DIR=/run/user/${docker_install_uid}"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Create systemd service file
|
local desired
|
||||||
runSystem tee "$service_file" > /dev/null <<EOF
|
desired="$(cat <<EOF
|
||||||
[Unit]
|
[Unit]
|
||||||
Description=LibrePortal Task Processor
|
Description=LibrePortal Task Processor
|
||||||
After=network.target
|
After=network.target
|
||||||
@ -61,32 +64,27 @@ PrivateTmp=true
|
|||||||
[Install]
|
[Install]
|
||||||
WantedBy=multi-user.target
|
WantedBy=multi-user.target
|
||||||
EOF
|
EOF
|
||||||
|
)"
|
||||||
|
|
||||||
# Remove from crontab if it exists
|
local current=""
|
||||||
if sudo -u $sudo_user_name crontab -l 2>/dev/null | grep -q "task_processor.sh"; then
|
[[ -f "$service_file" ]] && current="$(sudo cat "$service_file" 2>/dev/null)"
|
||||||
sudo -u $sudo_user_name crontab -l 2>/dev/null | grep -v "task_processor.sh" | sudo -u $sudo_user_name crontab -
|
|
||||||
isNotice "Removed task processor from crontab"
|
if [[ "$desired" != "$current" ]]; then
|
||||||
fi
|
printf '%s\n' "$desired" | runSystem tee "$service_file" > /dev/null
|
||||||
|
runSystem systemctl daemon-reload
|
||||||
# Reload systemd and enable service
|
runSystem systemctl enable libreportal.service >/dev/null 2>&1
|
||||||
runSystem systemctl daemon-reload
|
runSystem systemctl restart libreportal.service
|
||||||
runSystem systemctl enable libreportal.service >/dev/null 2>&1
|
isSuccessful "LibrePortal task processor service installed/updated ($CFG_DOCKER_INSTALL_TYPE)."
|
||||||
runSystem systemctl start libreportal.service
|
else
|
||||||
|
# Unit already correct — ensure it's enabled + running, without a restart.
|
||||||
isSuccessful "LibrePortal task processor service setup."
|
runSystem systemctl enable libreportal.service >/dev/null 2>&1
|
||||||
fi
|
sudo systemctl is-active --quiet libreportal.service || runSystem systemctl start libreportal.service
|
||||||
|
isSuccessful "LibrePortal task processor service already up to date."
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Drop the legacy crontab entry if present (superseded by the service).
|
||||||
|
if sudo -u "$sudo_user_name" crontab -l 2>/dev/null | grep -q "task_processor.sh"; then
|
||||||
|
sudo -u "$sudo_user_name" crontab -l 2>/dev/null | grep -v "task_processor.sh" | sudo -u "$sudo_user_name" crontab -
|
||||||
|
isNotice "Removed task processor from crontab"
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
# Restart the task processor after a docker-type switch. The processor reads the
|
|
||||||
# install type (rooted/rootless) ONCE at startup to decide how runFileOp writes
|
|
||||||
# into the docker-install-owned task dir, so a running instance keeps using the
|
|
||||||
# old mode until it's bounced. The switch is a CLI one-shot (not a processor
|
|
||||||
# task), so this won't kill an in-flight switch.
|
|
||||||
restartLibrePortalWebUITaskService()
|
|
||||||
{
|
|
||||||
[[ "$CFG_REQUIREMENT_WEBUI_SERVICE" == "true" ]] || return 0
|
|
||||||
[[ -f /etc/systemd/system/libreportal.service ]] || return 0
|
|
||||||
runSystem systemctl restart libreportal.service 2>/dev/null
|
|
||||||
isSuccessful "Restarted task processor for $CFG_DOCKER_INSTALL_TYPE Docker mode"
|
|
||||||
}
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user