2026-08-11 10:37:03 -04:00
|
|
|
#!/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
|
|
|
|
|
|
2026-08-25 22:18:56 -04:00
|
|
|
if [[ -n "${straywild_INSTALL_ROOT:-}" ]]; then
|
|
|
|
|
install_root="${straywild_INSTALL_ROOT}"
|
|
|
|
|
elif [[ -n "${NETFISHING_INSTALL_ROOT:-}" ]]; then
|
|
|
|
|
install_root="${NETFISHING_INSTALL_ROOT}"
|
|
|
|
|
elif [[ -d /opt/netfishing-server ]]; then
|
|
|
|
|
install_root="/opt/netfishing-server"
|
|
|
|
|
else
|
|
|
|
|
install_root="/opt/straywild-server"
|
|
|
|
|
fi
|
|
|
|
|
if [[ -n "${straywild_SERVICE_NAME:-}" ]]; then
|
|
|
|
|
service_name="${straywild_SERVICE_NAME}"
|
|
|
|
|
elif [[ -n "${NETFISHING_SERVICE_NAME:-}" ]]; then
|
|
|
|
|
service_name="${NETFISHING_SERVICE_NAME}"
|
|
|
|
|
elif command -v systemctl >/dev/null \
|
|
|
|
|
&& systemctl cat netfishing-server.service >/dev/null 2>&1; then
|
|
|
|
|
service_name="netfishing-server.service"
|
|
|
|
|
else
|
|
|
|
|
service_name="straywild-server.service"
|
|
|
|
|
fi
|
2026-08-11 10:37:03 -04:00
|
|
|
releases_dir="${install_root}/releases"
|
|
|
|
|
|
|
|
|
|
if [[ "${install_root}" != /* || "${install_root}" == "/" ]]; then
|
2026-08-25 22:18:56 -04:00
|
|
|
echo "The install root must be a specific absolute directory." >&2
|
2026-08-11 10:37:03 -04:00
|
|
|
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}")."
|