From c0b3a0e665d4af8cd16d6717c3cbdb97c03adc8d Mon Sep 17 00:00:00 2001 From: rcourtman Date: Sat, 7 Mar 2026 10:46:19 +0000 Subject: [PATCH] Restart Pulse service after failed auto-update (#1323) The auto-update flow stops the Pulse service before applying updates. If the update fails, the rollback path restored files but never restarted the service. Since the main unit was explicitly stopped (not crashed), systemd's Restart=always didn't rescue it. Add restart-on-failure guards to both pulse-auto-update.sh and install.sh so Pulse is always restarted after a failed update attempt. --- install.sh | 53 ++++++++++++++++++++++++++---------- scripts/pulse-auto-update.sh | 20 ++++++++++++-- 2 files changed, 57 insertions(+), 16 deletions(-) diff --git a/install.sh b/install.sh index a73e092e0..2e04a6520 100755 --- a/install.sh +++ b/install.sh @@ -29,6 +29,7 @@ CURRENT_INSTALL_CTID="" CONTAINER_CREATED_FOR_CLEANUP=false BUILD_FROM_SOURCE_MARKER="$INSTALL_DIR/BUILD_FROM_SOURCE" DETECTED_CTID="" +STOPPED_PULSE_SERVICE="" # Installer version - the major version this script is bundled with INSTALLER_MAJOR_VERSION=5 @@ -187,6 +188,35 @@ safe_systemctl() { } } +stop_pulse_service_for_update() { + local service_name="${1:-$(detect_service_name)}" + + if ! command -v systemctl >/dev/null 2>&1; then + return 1 + fi + + if timeout 5 systemctl is-active --quiet "$service_name" 2>/dev/null; then + STOPPED_PULSE_SERVICE="$service_name" + print_info "Stopping existing Pulse service ($service_name)..." + safe_systemctl stop "$service_name" || true + sleep 2 + return 0 + fi + + return 1 +} + +restart_stopped_pulse_service_on_failure() { + local exit_code=$? + + if [[ "$exit_code" -ne 0 ]] && [[ -n "$STOPPED_PULSE_SERVICE" ]] && command -v systemctl >/dev/null 2>&1; then + print_info "Restarting Pulse service ($STOPPED_PULSE_SERVICE) after failed update" + safe_systemctl start "$STOPPED_PULSE_SERVICE" || true + fi +} + +trap restart_stopped_pulse_service_on_failure EXIT + # Detect existing service name (pulse or pulse-backend) detect_service_name() { if ! command -v systemctl >/dev/null 2>&1; then @@ -2084,12 +2114,8 @@ download_pulse() { # Detect and stop existing service BEFORE downloading (to free the binary) EXISTING_SERVICE=$(detect_service_name) - if timeout 5 systemctl is-active --quiet $EXISTING_SERVICE 2>/dev/null; then - print_info "Stopping existing Pulse service ($EXISTING_SERVICE)..." - safe_systemctl stop $EXISTING_SERVICE || true - sleep 2 # Give the process time to fully stop and release the binary - fi - + stop_pulse_service_for_update "$EXISTING_SERVICE" || true + cd /tmp if ! command -v sha256sum >/dev/null 2>&1; then @@ -2696,11 +2722,7 @@ build_from_source() { fi service_name=$(detect_service_name) - if timeout 5 systemctl is-active --quiet "$service_name" 2>/dev/null; then - print_info "Stopping existing Pulse service ($service_name)..." - safe_systemctl stop "$service_name" || true - sleep 2 - fi + stop_pulse_service_for_update "$service_name" || true mkdir -p "$INSTALL_DIR/bin" "$INSTALL_DIR/scripts" @@ -3063,8 +3085,11 @@ start_pulse() { if ! safe_systemctl start $SERVICE_NAME; then print_info "Note: systemctl start failed (common in unprivileged containers)" print_info "The service will start automatically when the container starts" + STOPPED_PULSE_SERVICE="" return 0 fi + + STOPPED_PULSE_SERVICE="" # Wait for service to start sleep 3 @@ -3239,7 +3264,7 @@ main() { SERVICE_NAME=$(detect_service_name) backup_existing - systemctl stop $SERVICE_NAME || true + stop_pulse_service_for_update "$SERVICE_NAME" || true create_user download_pulse setup_update_command @@ -3449,7 +3474,7 @@ main() { fi backup_existing - systemctl stop $SERVICE_NAME || true + stop_pulse_service_for_update "$SERVICE_NAME" || true create_user download_pulse setup_update_command @@ -3504,7 +3529,7 @@ main() { fi backup_existing - systemctl stop $SERVICE_NAME || true + stop_pulse_service_for_update "$SERVICE_NAME" || true create_user download_pulse setup_directories diff --git a/scripts/pulse-auto-update.sh b/scripts/pulse-auto-update.sh index 6b72be002..64d6fe8ad 100755 --- a/scripts/pulse-auto-update.sh +++ b/scripts/pulse-auto-update.sh @@ -140,10 +140,25 @@ detect_service_name() { fi } +restart_service_if_needed() { + local service_name=$1 + local service_was_active=$2 + + if [[ "$service_was_active" == "true" ]]; then + log info "Starting Pulse service after failed update" + systemctl start "$service_name" || true + fi +} + # Perform the update perform_update() { local new_version=$1 local service_name=$(detect_service_name) + local service_was_active=false + + if systemctl is-active --quiet "$service_name" 2>/dev/null; then + service_was_active=true + fi log info "Starting update to $new_version" @@ -211,8 +226,7 @@ perform_update() { cp -f "$backup_dir/VERSION" "$INSTALL_DIR/VERSION" fi - # Restart service with old version - systemctl restart "$service_name" || true + restart_service_if_needed "$service_name" "$service_was_active" # Clean up backup rm -rf "$backup_dir" @@ -234,6 +248,8 @@ perform_update() { if [[ -f "$backup_dir/VERSION" ]]; then cp -f "$backup_dir/VERSION" "$INSTALL_DIR/VERSION" fi + + restart_service_if_needed "$service_name" "$service_was_active" # Clean up backup rm -rf "$backup_dir"