Add verifiable atomic server updates
This commit is contained in:
parent
2d135acab7
commit
a68d6157be
8 changed files with 371 additions and 24 deletions
70
scripts/rollback-native.sh
Executable file
70
scripts/rollback-native.sh
Executable file
|
|
@ -0,0 +1,70 @@
|
|||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
if [[ $# -ne 0 ]]; then
|
||||
echo "Usage: $0" >&2
|
||||
exit 2
|
||||
fi
|
||||
if [[ ${EUID} -ne 0 ]]; then
|
||||
echo "Run this rollback tool as root." >&2
|
||||
exit 2
|
||||
fi
|
||||
|
||||
install_root="${NETFISHING_INSTALL_ROOT:-/opt/netfishing-server}"
|
||||
service_name="${NETFISHING_SERVICE_NAME:-netfishing-server.service}"
|
||||
releases_dir="${install_root}/releases"
|
||||
|
||||
if [[ "${install_root}" != /* || "${install_root}" == "/" ]]; then
|
||||
echo "NETFISHING_INSTALL_ROOT must be a specific absolute directory." >&2
|
||||
exit 2
|
||||
fi
|
||||
if [[ ! -L "${install_root}/current" || ! -L "${install_root}/previous" ]]; then
|
||||
echo "Both current and previous release links are required." >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
current_target="$(readlink -f -- "${install_root}/current")"
|
||||
previous_target="$(readlink -f -- "${install_root}/previous")"
|
||||
for target in "${current_target}" "${previous_target}"; do
|
||||
if [[ ! -d "${target}" || "${target}" != "${releases_dir}/"* ]]; then
|
||||
echo "Refusing to use a release outside ${releases_dir}." >&2
|
||||
exit 1
|
||||
fi
|
||||
(cd -- "${target}" && sha256sum -c SHA256SUMS)
|
||||
done
|
||||
|
||||
replace_symlink() {
|
||||
local target="$1"
|
||||
local link_path="$2"
|
||||
local temporary_link="${install_root}/.$(basename -- "${link_path}").new.$$"
|
||||
ln -s -- "${target}" "${temporary_link}"
|
||||
mv -Tf -- "${temporary_link}" "${link_path}"
|
||||
}
|
||||
|
||||
service_active=false
|
||||
if systemctl is-active --quiet "${service_name}"; then
|
||||
service_active=true
|
||||
systemctl stop "${service_name}"
|
||||
fi
|
||||
|
||||
replace_symlink "${previous_target}" "${install_root}/current"
|
||||
replace_symlink "${current_target}" "${install_root}/previous"
|
||||
|
||||
if ${service_active}; then
|
||||
if ! systemctl start "${service_name}"; then
|
||||
start_succeeded=false
|
||||
else
|
||||
sleep 1
|
||||
start_succeeded=true
|
||||
systemctl is-active --quiet "${service_name}" || start_succeeded=false
|
||||
fi
|
||||
if ! ${start_succeeded}; then
|
||||
echo "Rollback target failed to start; restoring the original release." >&2
|
||||
replace_symlink "${current_target}" "${install_root}/current"
|
||||
replace_symlink "${previous_target}" "${install_root}/previous"
|
||||
systemctl start "${service_name}" || true
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
echo "Rolled back to $(basename -- "${previous_target}")."
|
||||
Loading…
Add table
Add a link
Reference in a new issue