Skip to content

Conversation

Copy link

Copilot AI commented Nov 18, 2025

Debian packages currently never auto-restart on upgrade (operator must manually restart). RPM packages always restart. This implements selective restart: auto-restart only for patch upgrades, skip for minor/major upgrades to reduce risk of automatic failures.

Changes

Added debian/preinst

  • Captures old package version during upgrade
  • Persists to /var/lib/crowdsec-haproxy-spoa-bouncer/old-version for postinst consumption

Modified debian/postinst

  • Parses major.minor from old and new versions
  • Restarts service only if major.minor match (patch upgrade)
  • Cleans up state file after reading

Behavior

# Patch upgrade: auto-restart
1.0.0 → 1.0.1  ✓ service restarts

# Minor/major upgrade: manual restart required  
1.0.x → 1.1.0  ✗ operator must restart
1.x.x → 2.0.0  ✗ operator must restart

Version comparison strips Debian revision (1.0.0-11.0), handles pre-release tags, and uses simple string equality on major.minor.

Original prompt

Summary

Implement selective service restart behavior for Debian packages: only attempt an automatic reload/restart for patch-only upgrades (same major and minor), and do NOT auto-restart for minor or major upgrades. This reduces risk of automatic restarts causing failures during minor/major upgrades while preserving smooth behavior for safe patch releases.

Background and motivation

Current Debian maintainer scripts in debian/ (postinst and prerm) stop and disable the service on upgrade but do not restart it. The RPM packaging currently restarts the service on upgrade, but Debian behavior intentionally avoids automatically restarting. We want a middle-ground: try to automatically reload/restart on patch upgrades only. This change makes upgrades smoother for patch releases while keeping operators in control for potentially breaking minor/major upgrades.

What to change

  1. Add debian/preinst
  • Purpose: capture the old package version on upgrade (preinst receives the old version when called with "upgrade") and persist it to a state file for postinst to read.
  • Behavior: when invoked with "upgrade" and an old-version argument, write the old version to /var/lib/crowdsec-haproxy-spoa-bouncer/old-version (create directory if needed). Otherwise do nothing.

File: debian/preinst
Mode: executable
Contents (proposed):

#!/bin/sh
set -eu

PKG="crowdsec-haproxy-spoa-bouncer"
STATE_DIR="/var/lib/${PKG}"

preinst is called with 'upgrade' when upgrading

if [ "$1" = "upgrade" ] && [ -n "$2" ]; then
mkdir -p "$STATE_DIR"
echo "$2" > "$STATE_DIR/old-version"
fi

exit 0

  1. Modify debian/postinst
  • Purpose: after installation, compare the saved old-version (if present) with the newly-installed version. If only the patch part changed (same major and minor), attempt a graceful reload-or-restart (systemctl reload-or-restart) and fall back to a safe try-restart. If major or minor changed, do NOT restart and instead print clear guidance to the operator.
  • Behavior should be robust: if version parsing fails or no previous version is recorded (fresh install), do not auto-restart (safer). The script must not fail the package installation if restart fails: use --quiet or trap errors and continue.

Modifications to existing debian/postinst (proposed patch):

  • Keep existing logic in postinst (daemon-reload, enable unit, user creation, permission fixes, etc.)
  • Add logic to read /var/lib/crowdsec-haproxy-spoa-bouncer/old-version and compare to the new version from dpkg-query
  • If old and new exist and only patch changed -> run: systemctl --quiet reload-or-restart "$SERVICE" || systemctl try-restart --quiet "$SERVICE" || echo "warning: $SERVICE failed to restart automatically"
  • If major/minor changed -> echo a note instructing operator to review release notes and manually restart the service: systemctl restart $SERVICE

Edge cases and safety

  • Version parsing: strip epoch and Debian revision (strip up to ':' and remove suffix after '-') and split by dots to extract major/minor/patch. If parsing fails or fields not numeric, default to not auto-restarting.
  • Always ensure scripts do not cause dpkg errors (use || true where appropriate and avoid exiting with non-zero).

Testing

  • Install/upgrade scenarios to test locally:
    • Fresh install: ensure service is enabled but not auto-started beyond current behavior.
    • Upgrade from 1.2.3 -> 1.2.4 (patch) -> expect reload-or-restart or try-restart performed.
    • Upgrade from 1.2.3 -> 1.3.0 (minor) -> expect no auto-restart and clear notice.
    • Upgrade from 1.2.3 -> 2.0.0 (major) -> expect no auto-restart and clear notice.
  • Test that postinst never causes the package manager to fail even if systemctl commands fail.

Deliverables

  • Add debian/preinst (executable)
  • Update debian/postinst with the selective restart logic while keeping the existing functionality (API key generation, enabling unit, permission fixes, printing the install banner)
  • Add brief changelog entry in debian/changelog or update packaging notes (optional)

Why this is safe

  • The script only auto-restarts for patch-only upgrades (assumed backward-compatible). For minor/major upgrades, the operator is responsible to review release notes and restart the service manually.
  • If something goes wrong during the automatic restart the script will not fail the dpkg operation and will log a warning, avoiding package manager failure.

Review request

  • Packaging team: please review the proposed scripts for policy compliance (debhelper usage, debian/ maintscript best practices), handle any lintian/policy issues, and confirm the desired behavior for automatic restarts. If you prefer a different state path or debconf prompt to ask operators, I can adjust.

Files to be added/modified

  • debian/preinst (new executable)
  • debian/postinst (modified)

I have inspected the repository's current debian/postinst and debian/prerm to ensure compatibility (I noted prerm currently stops and disables the service). See source fi...

This pull request was created as a result of the following prompt from Copilot chat.

Summary

Implement selective service restart behavior for Debian packages: only attempt an automatic reload/restart for patch-only upgrades (same major and minor), and do NOT auto-restart for minor or major upgrades. This reduces risk of automatic restarts causing failures during minor/major upgrades while preserving smooth behavior for safe patch releases.

Background and motivation

Current Debian maintainer scripts in debian/ (postinst and prerm) stop and disable the service on upgrade but do not restart it. The RPM packaging currently restarts the service on upgrade, but Debian behavior intentionally avoids automatically restarting. We want a middle-ground: try to automatically reload/restart on patch upgrades only. This change makes upgrades smoother for patch releases while keeping operators in control for potentially breaking minor/major upgrades.

What to change

  1. Add debian/preinst
  • Purpose: capture the old package version on upgrade (preinst receives the old version when called with "upgrade") and persist it to a state file for postinst to read.
  • Behavior: when invoked with "upgrade" and an old-version argument, write the old version to /var/lib/crowdsec-haproxy-spoa-bouncer/old-version (create directory if needed). Otherwise do nothing.

File: debian/preinst
Mode: executable
Contents (proposed):

#!/bin/sh
set -eu

PKG="crowdsec-haproxy-spoa-bouncer"
STATE_DIR="/var/lib/${PKG}"

preinst is called with 'upgrade' when upgrading

if [ "$1" = "upgrade" ] && [ -n "$2" ]; then
mkdir -p "$STATE_DIR"
echo "$2" > "$STATE_DIR/old-version"
fi

exit 0

  1. Modify debian/postinst
  • Purpose: after installation, compare the saved old-version (if present) with the newly-installed version. If only the patch part changed (same major and minor), attempt a graceful reload-or-restart (systemctl reload-or-restart) and fall back to a safe try-restart. If major or minor changed, do NOT restart and instead print clear guidance to the operator.
  • Behavior should be robust: if version parsing fails or no previous version is recorded (fresh install), do not auto-restart (safer). The script must not fail the package installation if restart fails: use --quiet or trap errors and continue.

Modifications to existing debian/postinst (proposed patch):

  • Keep existing logic in postinst (daemon-reload, enable unit, user creation, permission fixes, etc.)
  • Add logic to read /var/lib/crowdsec-haproxy-spoa-bouncer/old-version and compare to the new version from dpkg-query
  • If old and new exist and only patch changed -> run: systemctl --quiet reload-or-restart "$SERVICE" || systemctl try-restart --quiet "$SERVICE" || echo "warning: $SERVICE failed to restart automatically"
  • If major/minor changed -> echo a note instructing operator to review release notes and manually restart the service: systemctl restart $SERVICE

Edge cases and safety

  • Version parsing: strip epoch and Debian revision (strip up to ':' and remove suffix after '-') and split by dots to extract major/minor/patch. If parsing fails or fields not numeric, default to not auto-restarting.
  • Always ensure scripts do not cause dpkg errors (use || true where appropriate and avoid exiting with non-zero).

Testing

  • Install/upgrade scenarios to test locally:
    • Fresh install: ensure service is enabled but not auto-started beyond current behavior.
    • Upgrade from 1.2.3 -> 1.2.4 (patch) -> expect reload-or-restart or try-restart performed.
    • Upgrade from 1.2.3 -> 1.3.0 (minor) -> expect no auto-restart and clear notice.
    • Upgrade from 1.2.3 -> 2.0.0 (major) -> expect no auto-restart and clear notice.
  • Test that postinst never causes the package manager to fail even if systemctl commands fail.

Deliverables

  • Add debian/preinst (executable)
  • Update debian/postinst with the selective restart logic while keeping the existing functionality (API key generation, enabling unit, permission fixes, printing the install banner)
  • Add brief changelog entry in debian/changelog or update packaging notes (optional)

Why this is safe

  • The script only auto-restarts for patch-only upgrades (assumed backward-compatible). For minor/major upgrades, the operator is responsible to review release notes and restart the service manually.
  • If something goes wrong during the automatic restart the script will not fail the dpkg operation and will log a warning, avoiding package manager failure.

Review request

  • Packaging team: please review the proposed scripts for policy compliance (debhelper usage, debian/ maintscript best practices), handle any lintian/policy issues, and confirm the desired behavior for automatic restarts. If you prefer a different state path or debconf prompt to ask operators, I can adjust.

Files to be added/modified

  • debian/preinst (new executable)
  • debian/postinst (modified)

I have inspected the repository's current debian/postinst and debian/prerm to ensure compatibility (I noted prerm currently stops and disables the service). See source files in the repo for context:

Please review and I'll open a pull request with the proposed changes for your review.

Note: I will create the PR branch and include the two files with the exact contents described above. If you prefer a different location for the state file or a different behavior (e.g., restart on minor too), tell me now; otherwise I'll proceed with the change as specified.


✨ Let Copilot coding agent set things up for you — coding agent works faster and does higher quality work when set up for your repo.

Add preinst script to capture old version and modify postinst to only
auto-restart service on patch upgrades (same major.minor version).
Skip auto-restart for minor and major upgrades to reduce risk.

Co-authored-by: LaurenceJJones <[email protected]>
Copilot AI changed the title [WIP] Implement selective service restart behavior for Debian packages Implement selective service restart for Debian package upgrades Nov 18, 2025
Copilot finished work on behalf of LaurenceJJones November 19, 2025 08:15
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants