fix: stabilize external-db deployment and updates
Release / release (push) Canceled after 0s

This commit is contained in:
Qiufeng
2026-08-18 22:51:35 +08:00
parent 227c4b0129
commit 8c6c10eb85
22 changed files with 767 additions and 279 deletions
+26 -8
View File
@@ -46,7 +46,7 @@ if KAIDI_APP_ROOT="$WORK/bootstrap/app" \
sh "$ROOT/deploy/update.sh" > "$WORK/bootstrap.log" 2>&1; then
fail 'updater accepted a missing service identity during bootstrap'
fi
grep -Fq "Service user $missing_service_user is missing" "$WORK/bootstrap.log" \
grep -Fq '缺少服务用户' "$WORK/bootstrap.log" \
|| fail 'updater bootstrap failure did not preserve its diagnostic'
[ "$(jq -r '.state' "$WORK/bootstrap/state/status.json")" = FAILED ] \
|| fail 'updater bootstrap failure did not persist FAILED'
@@ -330,6 +330,7 @@ run_update() {
local fixture=$1
local health=$2
local skip_backup=${3:-true}
local backup_mode=${4:-}
env \
PATH="$fixture/mock-bin:$PATH" \
REAL_OPENSSL="$REAL_OPENSSL" \
@@ -353,6 +354,7 @@ run_update() {
KAIDI_UPDATER_PATH="$fixture/app/bin/update.sh" \
KAIDI_RUNTIME_ENV_FILE="$fixture/runtime.env" \
KAIDI_SKIP_DB_BACKUP="$skip_backup" \
KAIDI_DB_BACKUP_MODE="$backup_mode" \
KAIDI_UPDATE_HEALTH_ATTEMPTS=1 \
KAIDI_UPDATE_HEALTH_INTERVAL_SECONDS=0 \
UPDATE_RELEASE_BASE_URL="${FIXTURE_RELEASE_BASE_URL-https://release.fixture.invalid}" \
@@ -366,6 +368,20 @@ run_update() {
"$ROOT/deploy/update.sh"
}
assert_database_backup_opt_in_case() {
local fixture="$WORK/database-backup-opt-in"
local version='1.0.0-preview.2'
mkdir -p "$fixture"
write_mock_commands "$fixture/mock-bin"
build_release "$fixture" "$version"
prepare_installation "$fixture" "$version"
download_and_prepare_install "$fixture" "$version"
run_update "$fixture" success false mysqldump
find "$fixture/state/backups" -type f -name 'mysql-*.sql.gz' -print -quit | grep -q . \
|| fail 'explicit mysqldump mode did not create a database backup'
}
assert_private_gitea_release_case() {
local fixture="$WORK/private-gitea"
local version='1.0.0-preview.2'
@@ -476,7 +492,7 @@ assert_update_path_failure_keeps_application_case() {
|| fail 'path watcher failure rolled back a healthy application'
[ "$(jq -r '.state' "$fixture/state/status.json")" = SUCCEEDED ] \
|| fail 'path watcher failure did not preserve successful application state'
grep -Fq 'automatic update watcher could not be started' "$fixture/state/status.json" \
grep -Fq '自动更新监听器未能启动' "$fixture/state/status.json" \
|| fail 'path watcher failure did not preserve its diagnostic'
}
@@ -492,7 +508,7 @@ assert_rollback_case() {
if run_update "$fixture" fail-new > "$fixture/update.log" 2>&1; then
fail 'rollback case unexpectedly succeeded'
fi
grep -q 'previous application release was restored and verified' "$fixture/update.log" \
grep -q '已恢复并验证旧版本' "$fixture/update.log" \
|| fail 'rollback case did not report a complete restoration'
[ "$(readlink "$fixture/app/current")" = "$fixture/app/releases/1.0.0-preview.1" ] \
|| fail 'rollback case did not restore the previous application'
@@ -524,7 +540,7 @@ assert_incomplete_rollback_requires_manual_recovery_case() {
if run_update "$fixture" fail-after-first > "$fixture/update.log" 2>&1; then
fail 'incomplete rollback case unexpectedly succeeded'
fi
grep -Fq 'manual recovery is required' "$fixture/update.log" \
grep -Fq '需要人工恢复' "$fixture/update.log" \
|| fail 'incomplete rollback case did not require explicit recovery'
[ ! -e "$fixture/state/processing/request.json" ] \
|| fail 'incomplete rollback case left an automatically retriggered processing request'
@@ -602,7 +618,7 @@ assert_unhealthy_baseline_blocks_restart_case() {
if run_update "$fixture" fail > "$fixture/update.log" 2>&1; then
fail 'unhealthy baseline unexpectedly reached installation'
fi
grep -Fq 'Current release preflight failed' "$fixture/update.log" \
grep -Fq '当前版本预检查失败' "$fixture/update.log" \
|| fail 'unhealthy baseline did not preserve its preflight diagnostic'
! grep -Eq '^(start|restart|stop) kaidi-finance.service$' "$fixture/systemctl.log" \
|| fail 'unhealthy baseline restarted the application'
@@ -633,7 +649,7 @@ EOF
if run_update "$fixture" success > "$fixture/update.log" 2>&1; then
fail 'invalid database URL unexpectedly reached installation'
fi
grep -Fq 'DB_URL does not match the configured MySQL host, port, and database' "$fixture/update.log" \
grep -Fq 'DB_URL 与主机、端口、库名不一致' "$fixture/update.log" \
|| fail 'structurally invalid JDBC URL did not preserve its diagnostic'
! grep -q '^restart kaidi-finance.service$' "$fixture/systemctl.log" \
|| fail 'invalid database URL restarted the application'
@@ -655,7 +671,7 @@ assert_symlink_request_rejected() {
if run_update "$fixture" success > "$fixture/update.log" 2>&1; then
fail 'symlink request case unexpectedly succeeded'
fi
grep -q 'Update request must be a regular file' "$fixture/update.log" \
grep -q '更新请求必须是普通文件' "$fixture/update.log" \
|| fail 'symlink request case did not report the unsafe request'
[ "$(cat "$fixture/sentinel")" = 'operator-owned sentinel' ] \
|| fail 'symlink request case changed the link target'
@@ -679,7 +695,7 @@ assert_install_without_verified_cache_rejected() {
if run_update "$fixture" success > "$fixture/update.log" 2>&1; then
fail 'install without cache unexpectedly succeeded'
fi
grep -q 'Verified release cache is missing' "$fixture/update.log" \
grep -q '缺少已校验的发布缓存' "$fixture/update.log" \
|| fail 'install without cache did not report the missing verified cache'
[ "$(readlink "$fixture/app/current")" = "$fixture/app/releases/1.0.0-preview.1" ] \
|| fail 'install without cache changed the active application'
@@ -699,6 +715,8 @@ printf '[update-fixture] download-failure\n'
assert_download_failure_case
printf '[update-fixture] database-backup-failure\n'
assert_database_failure_case
printf '[update-fixture] database-backup-opt-in\n'
assert_database_backup_opt_in_case
printf '[update-fixture] unhealthy-baseline\n'
assert_unhealthy_baseline_blocks_restart_case
printf '[update-fixture] invalid-database-url\n'