fix: verify service health after installation
TallyNote release / linux-x64 (push) Successful in 7m7s
TallyNote release / linux-x64 (push) Successful in 7m7s
This commit is contained in:
+70
-1
@@ -60,6 +60,10 @@ INSTALL_BACKUP_DIR=''
|
||||
INSTALL_WAS_ACTIVE=0
|
||||
INSTALL_PATH_WAS_ACTIVE=0
|
||||
INSTALL_UPDATE_WAS_ACTIVE=0
|
||||
INSTALL_WAS_ENABLED=0
|
||||
INSTALL_PATH_WAS_ENABLED=0
|
||||
INSTALL_UPDATE_WAS_ENABLED=0
|
||||
INSTALL_SYSTEMD_TOUCHED=0
|
||||
DATA_DIR_TEMP_ROOT=0
|
||||
DATA_DIR_ORIGINAL_OWNER=''
|
||||
|
||||
@@ -218,6 +222,24 @@ check_requested_port() {
|
||||
esac
|
||||
}
|
||||
|
||||
wait_for_service_health() {
|
||||
local host=$1 port=$2 health_host health_url attempt
|
||||
health_host=$host
|
||||
case "$health_host" in
|
||||
0.0.0.0) health_host=127.0.0.1 ;;
|
||||
::) health_host=::1 ;;
|
||||
esac
|
||||
if [[ "$health_host" == *:* && "$health_host" != \[* ]]; then health_host="[$health_host]"; fi
|
||||
health_url="http://${health_host}:${port}/health"
|
||||
for attempt in 1 2 3 4 5 6 7 8 9 10 11 12; do
|
||||
if curl --proto '=http' --connect-timeout 2 --max-time 3 --fail --silent "$health_url" >/dev/null 2>&1; then
|
||||
return 0
|
||||
fi
|
||||
(( attempt < 12 )) && sleep 1
|
||||
done
|
||||
return 1
|
||||
}
|
||||
|
||||
has_network_environment() {
|
||||
[[ -n "${TALLYNOTE_HOST+x}" || -n "${TALLYNOTE_PORT+x}" || -n "${TALLYNOTE_PUBLIC_ORIGIN+x}" || -n "${TALLYNOTE_ALLOW_INSECURE_HTTP+x}" ]]
|
||||
}
|
||||
@@ -770,6 +792,17 @@ stop_existing_services() {
|
||||
# Stop the path trigger first so it cannot launch the privileged updater while
|
||||
# the data tree is being repaired.
|
||||
for unit in tallynote-update.path tallynote-update.service tallynote.service; do
|
||||
case "$unit" in
|
||||
tallynote.service)
|
||||
if systemctl is-enabled --quiet "$unit"; then INSTALL_WAS_ENABLED=1; fi
|
||||
;;
|
||||
tallynote-update.path)
|
||||
if systemctl is-enabled --quiet "$unit"; then INSTALL_PATH_WAS_ENABLED=1; fi
|
||||
;;
|
||||
tallynote-update.service)
|
||||
if systemctl is-enabled --quiet "$unit"; then INSTALL_UPDATE_WAS_ENABLED=1; fi
|
||||
;;
|
||||
esac
|
||||
if systemctl is-active --quiet "$unit"; then
|
||||
case "$unit" in
|
||||
tallynote.service) INSTALL_WAS_ACTIVE=1 ;;
|
||||
@@ -783,6 +816,17 @@ stop_existing_services() {
|
||||
|
||||
rollback_install_if_needed() {
|
||||
local result=$? rollback_tmp
|
||||
if (( INSTALL_COMMITTED == 0 && INSTALL_SYSTEMD_TOUCHED == 1 )) && command -v systemctl >/dev/null 2>&1; then
|
||||
# The failed install may have started units that were inactive before the
|
||||
# attempt. Stop them before restoring files so systemd never keeps running
|
||||
# code from a release directory that rollback is about to remove.
|
||||
for unit in tallynote-update.path tallynote-update.service tallynote.service; do
|
||||
systemctl stop "$unit" >/dev/null 2>&1 || true
|
||||
done
|
||||
if (( INSTALL_WAS_ENABLED == 0 )); then systemctl disable tallynote.service >/dev/null 2>&1 || true; fi
|
||||
if (( INSTALL_PATH_WAS_ENABLED == 0 )); then systemctl disable tallynote-update.path >/dev/null 2>&1 || true; fi
|
||||
if (( INSTALL_UPDATE_WAS_ENABLED == 0 )); then systemctl disable tallynote-update.service >/dev/null 2>&1 || true; fi
|
||||
fi
|
||||
if (( INSTALL_SWITCHED == 1 && INSTALL_COMMITTED == 0 )); then
|
||||
if [[ -n "$INSTALL_PREVIOUS_TARGET" && -d "$INSTALL_PREVIOUS_TARGET" ]]; then
|
||||
rollback_tmp="$PREFIX/.current-rollback-$$-${RANDOM}.tmp"
|
||||
@@ -821,6 +865,7 @@ rollback_install_if_needed() {
|
||||
done
|
||||
fi
|
||||
if command -v systemctl >/dev/null 2>&1; then
|
||||
if (( INSTALL_SYSTEMD_TOUCHED == 1 )); then systemctl daemon-reload >/dev/null 2>&1 || true; fi
|
||||
if (( INSTALL_WAS_ACTIVE == 1 )); then systemctl start tallynote.service 2>/dev/null || true; fi
|
||||
if (( INSTALL_UPDATE_WAS_ACTIVE == 1 )); then systemctl start tallynote-update.service 2>/dev/null || true; fi
|
||||
if (( INSTALL_PATH_WAS_ACTIVE == 1 )); then systemctl start tallynote-update.path 2>/dev/null || true; fi
|
||||
@@ -1038,7 +1083,10 @@ validate_existing_env() {
|
||||
install_release() {
|
||||
local archive=$1 version=$2 tmp release_dir current_tmp=''
|
||||
tmp=$(mktemp -d)
|
||||
trap 'rm -rf "$tmp" "$current_tmp" 2>/dev/null || true' RETURN
|
||||
# RETURN traps survive the function that installs them. Clear the trap from
|
||||
# inside its first invocation so a later function cannot evaluate the local
|
||||
# temporary path after it has gone out of scope under `set -u`.
|
||||
trap 'trap - RETURN; if [[ -n "${tmp-}" ]]; then rm -rf -- "$tmp" 2>/dev/null || true; fi; if [[ -n "${current_tmp-}" ]]; then rm -f -- "$current_tmp" 2>/dev/null || true; fi' RETURN
|
||||
safe_extract "$archive" "$tmp/unpacked"
|
||||
normalize_release_tree "$tmp/unpacked"
|
||||
[[ -d "$tmp/unpacked/dist" ]] || die 'release archive must contain dist/ at its root'
|
||||
@@ -1364,7 +1412,28 @@ main() {
|
||||
chown root:root "$CONFIG_DIR/tallynote.env"
|
||||
chmod 640 "$CONFIG_DIR/tallynote.env"
|
||||
systemctl daemon-reload
|
||||
INSTALL_SYSTEMD_TOUCHED=1
|
||||
systemctl enable --now tallynote.service tallynote-update.path
|
||||
local health_host health_port
|
||||
health_host=$(read_env_value "$CONFIG_DIR/tallynote.env" TALLYNOTE_HOST 2>/dev/null || true)
|
||||
health_port=$(read_env_value "$CONFIG_DIR/tallynote.env" TALLYNOTE_PORT 2>/dev/null || true)
|
||||
health_host=${health_host:-$INSTALL_HOST}
|
||||
health_port=${health_port:-$INSTALL_PORT}
|
||||
stage "检查本机健康接口(${health_host}:${health_port})"
|
||||
if ! wait_for_service_health "$health_host" "$health_port"; then
|
||||
log "本机健康检查失败:http://${health_host}:${health_port}/health"
|
||||
systemctl status tallynote.service --no-pager -l || true
|
||||
if command -v journalctl >/dev/null 2>&1; then
|
||||
journalctl -u tallynote.service -n 30 --no-pager || true
|
||||
fi
|
||||
die 'TallyNote 服务未通过健康检查;安装未完成,请根据上面的 systemd 日志修复后重试'
|
||||
fi
|
||||
stage_done '本机健康检查通过,服务正在监听'
|
||||
if [[ "$health_host" == 127.0.0.1 || "$health_host" == localhost || "$health_host" == ::1 ]]; then
|
||||
log '当前监听仅限本机;公网或其他设备无法直接访问,请重新安装并选择 0.0.0.0,或配置 HTTPS 反向代理'
|
||||
else
|
||||
log '当前监听已绑定非本机地址;若外部仍无法连接,请检查云安全组、主机防火墙和公网 IP/NAT'
|
||||
fi
|
||||
stage_done 'TallyNote 服务已启用并启动'
|
||||
stage '清理旧版本并完成安装'
|
||||
prune_releases
|
||||
|
||||
Reference in New Issue
Block a user