fix(package): preserve service state across upgrades (#8024)

* fix(package): preserve service state across upgrades

* fix(package): match legacy DEB versions in tilde form

Published prerelease packages carry ~ in the dpkg control version
(package_versions.sh maps the SemVer prerelease - to ~), so the
legacy fallback list written with dots never matched 1.0.0~rc.x and
upgrades away from those DEBs still left the service stopped (#8011).

Fix the legacy glob to the tilde form and update the contract test,
which had enshrined the dot form. Verified on Ubuntu 24.04 systemd
containers: DEB upgrade 1.0.0~rc.5 -> 1.0.1 now keeps the service
running; 1.0.0 -> 1.0.1 and 1.0.1 -> 1.0.2 marker path still pass.

* docs(package): expand /etc/default/rustfs example template

Document the commonly used RUSTFS_* settings as commented examples in
the packaged conffile and point to docs.rustfs.com.
This commit is contained in:
hector
2026-09-20 11:27:41 +08:00
committed by GitHub
parent 22243e791d
commit ed2c3eaf77
7 changed files with 289 additions and 124 deletions
+1
View File
@@ -90,6 +90,7 @@ their issue closes.
| `test_build_rustfs_options.sh` | dev-tool | Shell test for rustfs build-option wiring | `make test` (script-tests) |
| `test_entrypoint_credentials.sh` | dev-tool | Container entrypoint credential-handling test | `make test` (script-tests) |
| `test_helm_chart_version.sh` | dev-tool | Test for `helm_chart_version.sh` | — |
| `test_package_service_scripts.sh` | ci-gate | Verifies DEB/RPM install, upgrade, removal, and service restart scriptlets | audit.yml `workflow-pin-report` |
| `test_package_versions.sh` | ci-gate | Exact-output and fail-closed tests for DEB/RPM package version normalization | audit.yml `workflow-pin-report`; package.yml RPM build |
| `windows-sftp-listener-smoke.sh` | dev-tool | Confirms `rustfs.exe --features sftp` binds an SFTP listener on Windows | — |
+112
View File
@@ -0,0 +1,112 @@
#!/usr/bin/env bash
set -euo pipefail
case ${1:-} in
after-install)
cat <<'SCRIPT'
#!/bin/sh
set -e
if ! getent passwd rustfs > /dev/null 2>&1; then
useradd -r -s /bin/false -d /opt/rustfs rustfs
fi
mkdir -p /opt/rustfs /data/rustfs /var/log/rustfs
chown rustfs:rustfs /opt/rustfs /data/rustfs /var/log/rustfs
if [ -d /run/systemd/system ]; then
systemctl daemon-reload
if [ "${1:-}" = configure ]; then
marker=/run/rustfs-package-upgrade-was-active
if [ -z "${2:-}" ]; then
rm -f "$marker"
else
# Versions published before this fix had no upgrade-aware prerm:
# the old prerm stopped the service and left no marker, so the
# marker check below cannot see it. Fall back to restarting for
# upgrades from those versions. NOTE: these are dpkg control-file
# versions - package_versions.sh maps the SemVer prerelease "-"
# to "~", so 1.0.0-rc.5 was published as 1.0.0~rc.5. Drop this list once
# upgrades from <= 1.0.0 no longer need support.
case $2 in
1.0.0|1.0.0~rc.[1-6]|1.0.0~rc.[1-6]~preview.*) legacy_upgrade=true ;;
*) legacy_upgrade=false ;;
esac
if [ -f "$marker" ] || [ "$legacy_upgrade" = true ]; then
rm -f "$marker"
if command -v deb-systemd-invoke > /dev/null 2>&1; then
deb-systemd-invoke restart rustfs.service
else
systemctl restart rustfs.service
fi
fi
fi
fi
fi
SCRIPT
;;
before-remove)
cat <<'SCRIPT'
#!/bin/sh
set -e
case ${1:-} in
upgrade)
marker=/run/rustfs-package-upgrade-was-active
rm -f "$marker"
if [ -d /run/systemd/system ] && systemctl is-active --quiet rustfs; then
touch "$marker"
fi
exit 0
;;
0|remove|deconfigure) ;;
*) exit 0 ;;
esac
if [ -d /run/systemd/system ] && systemctl is-active --quiet rustfs; then
systemctl stop rustfs
fi
SCRIPT
;;
after-remove)
cat <<'SCRIPT'
#!/bin/sh
set -e
if [ -d /run/systemd/system ]; then
systemctl daemon-reload
fi
if [ "${1:-}" != upgrade ]; then
rm -f /run/rustfs-package-upgrade-was-active
fi
SCRIPT
;;
rpm-before-install)
cat <<'SCRIPT'
#!/bin/sh
set -e
rm -f /run/rustfs-package-upgrade-was-active
SCRIPT
;;
rpm-before-upgrade)
cat <<'SCRIPT'
#!/bin/sh
set -e
marker=/run/rustfs-package-upgrade-was-active
rm -f "$marker"
if [ -d /run/systemd/system ] && systemctl is-active --quiet rustfs; then
touch "$marker"
fi
SCRIPT
;;
rpm-posttrans)
cat <<'SCRIPT'
#!/bin/sh
set -e
marker=/run/rustfs-package-upgrade-was-active
if [ -f "$marker" ]; then
rm -f "$marker"
systemctl restart rustfs
fi
SCRIPT
;;
*)
echo "usage: $0 {after-install|before-remove|after-remove|rpm-before-install|rpm-before-upgrade|rpm-posttrans}" >&2
exit 2
;;
esac
+116
View File
@@ -0,0 +1,116 @@
#!/usr/bin/env bash
set -euo pipefail
repo_root=$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)
generator="${repo_root}/scripts/release/package_service_scripts.sh"
test_tmp=$(mktemp -d)
trap 'rm -rf "$test_tmp"' EXIT
mkdir -p "${test_tmp}/bin"
mkdir -p "${test_tmp}/run/systemd/system"
cat > "${test_tmp}/bin/getent" <<'SCRIPT'
#!/bin/sh
exit 0
SCRIPT
cat > "${test_tmp}/bin/mkdir" <<'SCRIPT'
#!/bin/sh
exit 0
SCRIPT
cat > "${test_tmp}/bin/chown" <<'SCRIPT'
#!/bin/sh
exit 0
SCRIPT
cat > "${test_tmp}/bin/systemctl" <<'SCRIPT'
#!/bin/sh
printf 'systemctl %s\n' "$*" >> "$PACKAGE_SCRIPT_LOG"
case "$1" in
is-active) exit "${SYSTEMCTL_ACTIVE_EXIT:-0}" ;;
esac
SCRIPT
cat > "${test_tmp}/bin/deb-systemd-invoke" <<'SCRIPT'
#!/bin/sh
printf 'deb-systemd-invoke %s\n' "$*" >> "$PACKAGE_SCRIPT_LOG"
SCRIPT
chmod +x "${test_tmp}/bin/"*
export PATH="${test_tmp}/bin:${PATH}"
export PACKAGE_SCRIPT_LOG="${test_tmp}/calls"
run_script() {
local name=$1
shift
"$generator" "$name" |
sed \
-e "s#/run/systemd/system#${test_tmp}/run/systemd/system#g" \
-e "s#/run/rustfs-package-upgrade-was-active#${test_tmp}/run/rustfs-package-upgrade-was-active#g" \
> "${test_tmp}/${name}"
chmod +x "${test_tmp}/${name}"
"${test_tmp}/${name}" "$@"
}
assert_log() {
local expected=$1
printf '%s\n' "$expected" > "${test_tmp}/expected"
diff -u "${test_tmp}/expected" "$PACKAGE_SCRIPT_LOG"
}
: > "$PACKAGE_SCRIPT_LOG"
run_script before-remove upgrade 1.0.0
assert_log 'systemctl is-active --quiet rustfs'
marker="${test_tmp}/run/rustfs-package-upgrade-was-active"
[[ -f $marker ]]
: > "$PACKAGE_SCRIPT_LOG"
run_script after-remove upgrade 1.0.1
[[ -f $marker ]]
run_script after-install configure 1.0.1
[[ ! -e $marker ]]
assert_log $'systemctl daemon-reload\nsystemctl daemon-reload\ndeb-systemd-invoke restart rustfs.service'
: > "$PACKAGE_SCRIPT_LOG"
touch "$marker"
SYSTEMCTL_ACTIVE_EXIT=1 run_script before-remove upgrade 1.0.1
[[ ! -e $marker ]]
run_script after-remove upgrade 1.0.2
run_script after-install configure 1.0.1
assert_log $'systemctl is-active --quiet rustfs\nsystemctl daemon-reload\nsystemctl daemon-reload'
: > "$PACKAGE_SCRIPT_LOG"
run_script after-install configure 1.0.0~rc.5
assert_log $'systemctl daemon-reload\ndeb-systemd-invoke restart rustfs.service'
: > "$PACKAGE_SCRIPT_LOG"
run_script after-install configure 0~dev.9000.0123456789abcdef
assert_log 'systemctl daemon-reload'
: > "$PACKAGE_SCRIPT_LOG"
run_script before-remove remove
assert_log $'systemctl is-active --quiet rustfs\nsystemctl stop rustfs'
: > "$PACKAGE_SCRIPT_LOG"
touch "$marker"
run_script after-remove remove
[[ ! -e $marker ]]
assert_log 'systemctl daemon-reload'
: > "$PACKAGE_SCRIPT_LOG"
touch "$marker"
run_script after-install configure
[[ ! -e $marker ]]
assert_log 'systemctl daemon-reload'
: > "$PACKAGE_SCRIPT_LOG"
run_script rpm-before-upgrade
[[ -f $marker ]]
run_script rpm-posttrans
[[ ! -e $marker ]]
assert_log $'systemctl is-active --quiet rustfs\nsystemctl restart rustfs'
: > "$PACKAGE_SCRIPT_LOG"
SYSTEMCTL_ACTIVE_EXIT=1 run_script rpm-before-upgrade
[[ ! -e $marker ]]
run_script rpm-posttrans
assert_log 'systemctl is-active --quiet rustfs'
echo "PASS package service script contract"