v1.2.2.1: rewrite monitor unit on every update to point at AppRun (#222)

The v1.2.2 install layout extracts the AppImage into
/usr/local/share/proxmenux/monitor-app/ and runs AppRun out of that
directory — but install_proxmenux_monitor's update branch only
called create_monitor_service on fresh installs, leaving the inherited
unit's `ExecStart=/usr/local/share/proxmenux/ProxMenux-Monitor.AppImage`
in place. That path used to be the FUSE-mounted AppImage entry point,
which v1.2.2 deliberately replaced to clear a Wazuh rule-521 false
positive on /tmp/.mount_*. On PVE 9.x / Debian 13 the bare AppImage
fails to exec straight away (status=203/EXEC) so the service entered
the activating loop reported in #222 and never came back up.

Always rewrite the unit before the post-update `systemctl start` —
idempotent for installs whose unit is already correct, recovering
for those whose isn't. The new helper
`_proxmenux_rewrite_monitor_unit_for_apprun` mirrors the unit body
the fresh-install path emits in `create_monitor_service`, with the
same template-from-repo / inline-fallback fork, so both paths
converge on the same content.

Reproduced and validated on PVE 9.x lab:

  before:
    Process: ExecStart=/usr/local/share/proxmenux/ProxMenux-Monitor.AppImage
             (code=exited, status=203/EXEC)
    Active: activating (auto-restart)

  after:
    ExecStart=/usr/local/share/proxmenux/monitor-app/AppRun
    Active: active (running)

Bumps version.txt to 1.2.2.1 so the existing menu update path picks
this up automatically. For users already stuck on a broken v1.2.2,
re-running the installer manually applies the same fix:
  bash -c "$(wget -qLO - https://raw.githubusercontent.com/MacRimi/ProxMenux/main/install_proxmenux.sh)"

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
MacRimi
2026-06-02 20:31:33 +02:00
parent 32a3e20c76
commit 17c5b89cc8
4 changed files with 72 additions and 3 deletions

View File

@@ -682,14 +682,25 @@ install_proxmenux_monitor() {
fi
msg_ok "ProxMenux Monitor v$appimage_version installed."
if [ "$service_exists" = false ]; then
return 0 # New installation - service needs to be created
else
# The v1.2.2 install layout extracts the AppImage into
# MONITOR_RUNTIME_DIR/ and runs AppRun out of that directory
# (`extract_appimage_to_runtime_dir` above), so the unit must
# point at AppRun — not at the bare AppImage. Existing users
# updating from v1.2.1.x stable still have a unit whose
# ExecStart targets `/usr/local/share/proxmenux/ProxMenux-Monitor.AppImage`
# which was fine when the AppImage was FUSE-mounted but breaks
# under PVE 9.x / Debian 13 (status=203/EXEC, GitHub issue #222).
# Rewrite the unit on every update — idempotent for users
# whose unit is already correct.
_proxmenux_rewrite_monitor_unit_for_apprun
systemctl start proxmenux-monitor.service
sleep 2
if systemctl is-active --quiet proxmenux-monitor.service; then
update_config "proxmenux_monitor" "updated"
@@ -702,6 +713,44 @@ install_proxmenux_monitor() {
fi
}
# Idempotent rewriter of the proxmenux-monitor unit file. Used by the
# update path in `install_proxmenux_monitor` so that existing
# installations updated to v1.2.2+ get their ExecStart corrected to
# point at the extracted AppRun even when the unit already exists.
# Mirrors `create_monitor_service`'s unit body so both code paths
# converge on the same file content. Returns 0 always; failures are
# logged so the surrounding flow can still attempt the start and
# report a more accurate failure to the user.
_proxmenux_rewrite_monitor_unit_for_apprun() {
local exec_path="$MONITOR_RUNTIME_DIR/AppRun"
if [ -f "$TEMP_DIR/systemd/proxmenux-monitor.service" ]; then
sed "s|ExecStart=.*|ExecStart=$exec_path|g" \
"$TEMP_DIR/systemd/proxmenux-monitor.service" > "$MONITOR_SERVICE_FILE"
else
cat > "$MONITOR_SERVICE_FILE" << EOF
[Unit]
Description=ProxMenux Monitor - Web Dashboard
After=network.target
[Service]
Type=simple
User=root
WorkingDirectory=$MONITOR_INSTALL_DIR
ExecStart=$exec_path
Restart=on-failure
RestartSec=10
Environment="PORT=$MONITOR_PORT"
[Install]
WantedBy=multi-user.target
EOF
fi
systemctl daemon-reload
return 0
}
create_monitor_service() {
local exec_path="$MONITOR_RUNTIME_DIR/AppRun"