115 lines
2.7 KiB
Bash
Executable File
115 lines
2.7 KiB
Bash
Executable File
#!/bin/bash
|
|
|
|
# angie-upgrade - Upgrade all running Angie instances with zero downtime
|
|
|
|
# Upgrade all running Angie instances by sending the USR2 signal to the
|
|
# master process of each instance, then gracefully stopping the old master.
|
|
# This allows for zero-downtime upgrades of Angie.
|
|
|
|
# Last updated: 2026-10-18
|
|
|
|
TIMEOUT=10
|
|
|
|
wait_for_file() {
|
|
# usage: wait_for_file <present|absent> <file> <label>
|
|
local mode=$1 file=$2 label=$3
|
|
local i
|
|
|
|
for ((i=0; i<TIMEOUT; i++)); do
|
|
[[ $mode == present && -f $file ]] && return 0
|
|
[[ $mode == absent && ! -f $file ]] && return 0
|
|
sleep 1
|
|
done
|
|
|
|
echo "ERROR: $label - file never ${mode}ed: $file" >&2
|
|
return 1
|
|
}
|
|
|
|
upgrade_instance() {
|
|
# usage: upgrade_instance <service-unit> <pid-file>
|
|
local unit="$1" pid_file="$2"
|
|
local old_pid_file="${pid_file}.oldbin"
|
|
|
|
if [ ! -f "$pid_file" ]; then
|
|
echo "[$unit] No PID file at $pid_file - skipping."
|
|
return 0
|
|
fi
|
|
|
|
echo "[$unit] Starting new master process..."
|
|
/bin/systemctl kill --signal=SIGUSR2 --kill-who=main "$unit"
|
|
|
|
wait_for_file present "$old_pid_file" "$unit - new master start" || return 1
|
|
|
|
echo "[$unit] New master is up. Gracefully stopping old master..."
|
|
local old_pid
|
|
old_pid=$(cat "$old_pid_file" 2>/dev/null)
|
|
/bin/kill -s QUIT "$old_pid" 2>/dev/null
|
|
|
|
wait_for_file absent "$old_pid_file" "$unit - old master stop" || return 1
|
|
|
|
echo "[$unit] Done."
|
|
return 0
|
|
}
|
|
|
|
overall_rc=0
|
|
|
|
# Discover every active Angie instance via systemctl
|
|
instances=$(systemctl list-units --type=service --state=running --no-legend "angie*" |
|
|
awk '{print $1}' |
|
|
grep -E '^angie(@\w+)?\.service$')
|
|
|
|
for unit in $instances; do
|
|
pid_file=$(systemctl show "$unit" -p PIDFile --value)
|
|
|
|
if [ -z "$pid_file" ]; then
|
|
echo "[$unit] Could not determine PID file - skipping." >&2
|
|
continue
|
|
fi
|
|
|
|
upgrade_instance "$unit" "$pid_file"
|
|
rc=$?
|
|
[ $rc -ne 0 ] && overall_rc=$rc
|
|
done
|
|
|
|
exit $overall_rc
|
|
|
|
: <<'POD'
|
|
=pod
|
|
|
|
=encoding UTF-8
|
|
|
|
=head1 NAME
|
|
|
|
angie-upgrade - tool to upgrade Angie without any downtime
|
|
|
|
=head1 SYNOPSIS
|
|
|
|
angie-upgrade
|
|
|
|
=head1 DESCRIPTION
|
|
|
|
This downstream shell script updates Angie without any downtime. After
|
|
upgrading Angie via the package manager, running this script will create
|
|
a new Angie master. This master takes over all new requests. The old
|
|
masters and workers are then gracefully shutdown without breaking any
|
|
existing connections.
|
|
|
|
For further information, see: L<https://en.angie.software/angie/docs/configuration/runtime/>
|
|
|
|
=head1 BUGS
|
|
|
|
If you find any bugs, please send an email to the author.
|
|
|
|
=head1 AUTHORS
|
|
|
|
Felix Kaechele E<lt>felix@kaechele.caE<gt>
|
|
|
|
Adapted for Angie by
|
|
Zoran Peričić E<lt>zpericic@netst.orgE<gt>
|
|
|
|
Originally written by
|
|
Jamie Nguyen E<lt>jamielinux@fedoraproject.orgE<gt>
|
|
|
|
=cut
|
|
POD
|