208 lines
6.5 KiB
Bash
Executable File
208 lines
6.5 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
|
|
set -Eeuo pipefail
|
|
|
|
WM_DEPLOY_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
|
# shellcheck source=common.sh
|
|
source "$WM_DEPLOY_DIR/scripts/common.sh"
|
|
wm_load_env
|
|
wm_assert_data_mount
|
|
|
|
if [[ "$(id -u)" -ne 0 ]]; then
|
|
wm_die "Dieses Skript muss als root ausgeführt werden."
|
|
fi
|
|
|
|
force_rebuild=false
|
|
if [[ "${1:-}" == "--force" ]]; then
|
|
force_rebuild=true
|
|
shift
|
|
fi
|
|
[[ "$#" -eq 0 ]] || wm_die "Unbekannte Argumente für update-route-data.sh."
|
|
|
|
install -d -m 0755 "$WATERMAPS_RUNTIME_DIR/locks" "$WATERMAPS_DATA_DIR/local"
|
|
if [[ "${WATERMAPS_ROUTE_LOCK_HELD:-false}" != "true" ]]; then
|
|
if ! wm_acquire_route_lock; then
|
|
exit 0
|
|
fi
|
|
fi
|
|
|
|
route_file="$(wm_route_file)"
|
|
route_marker="$(wm_route_marker)"
|
|
route_dir="$(dirname "$route_file")"
|
|
candidate_file="$route_dir/.germany-netherlands-fairways.candidate.json"
|
|
candidate_marker="$route_dir/.germany-netherlands-fairways.candidate.ready"
|
|
backup_file="$route_dir/.germany-netherlands-fairways.previous.json"
|
|
backup_marker="$route_dir/.germany-netherlands-fairways.previous.ready"
|
|
transaction_file="$WATERMAPS_RUNTIME_DIR/locks/route-update.transaction"
|
|
container_candidate="/workspace/data/local/$(basename "$candidate_file")"
|
|
container_candidate_marker="/workspace/data/local/$(basename "$candidate_marker")"
|
|
|
|
transaction_active=false
|
|
rollback_restored_previous=false
|
|
|
|
wm_copy_route_atomically() {
|
|
local source_file="$1"
|
|
local destination_file="$2"
|
|
local temporary_file
|
|
|
|
temporary_file="$(mktemp "$(dirname "$destination_file")/.route-copy.XXXXXX")"
|
|
if ! cp --reflink=auto "$source_file" "$temporary_file"; then
|
|
rm -f "$temporary_file"
|
|
return 1
|
|
fi
|
|
chmod 0644 "$temporary_file"
|
|
mv -f "$temporary_file" "$destination_file"
|
|
}
|
|
|
|
wm_watermaps_is_running() {
|
|
[[ -n "$(wm_compose ps --quiet watermaps)" ]]
|
|
}
|
|
|
|
wm_restore_previous_route() {
|
|
rollback_restored_previous=false
|
|
if [[ -s "$backup_file" && -s "$backup_marker" ]] &&
|
|
wm_route_data_files_ready "$backup_file" "$backup_marker"; then
|
|
if ! wm_copy_route_atomically "$backup_file" "$route_file" ||
|
|
! wm_write_route_marker "$route_file" "$route_marker" ||
|
|
! wm_route_data_ready; then
|
|
rm -f "$route_file" "$route_marker"
|
|
return 1
|
|
fi
|
|
rollback_restored_previous=true
|
|
return 0
|
|
fi
|
|
|
|
rm -f "$route_file" "$route_marker"
|
|
return 1
|
|
}
|
|
|
|
wm_restart_after_restore() {
|
|
if ! wm_watermaps_is_running; then
|
|
wm_log "Watermaps läuft nicht; wiederhergestellte Routingdaten können noch nicht getestet werden."
|
|
return 1
|
|
fi
|
|
|
|
wm_compose restart watermaps
|
|
wm_wait_for_health watermaps 240 || return 1
|
|
if [[ "$rollback_restored_previous" == "true" ]]; then
|
|
wm_smoke_test_route
|
|
fi
|
|
}
|
|
|
|
wm_rollback_transaction() {
|
|
local restore_status=0
|
|
|
|
if ! wm_restore_previous_route; then
|
|
restore_status=1
|
|
fi
|
|
rm -f "$transaction_file"
|
|
transaction_active=false
|
|
|
|
if ! wm_restart_after_restore; then
|
|
return 1
|
|
fi
|
|
return "$restore_status"
|
|
}
|
|
|
|
wm_cleanup_on_exit() {
|
|
local status=$?
|
|
trap - EXIT HUP INT TERM
|
|
set +e
|
|
|
|
if [[ "$transaction_active" == "true" ]]; then
|
|
wm_log "Unvollständige Routingaktivierung wird zurückgerollt."
|
|
wm_rollback_transaction
|
|
fi
|
|
rm -f "$candidate_file" "$candidate_marker"
|
|
exit "$status"
|
|
}
|
|
|
|
trap wm_cleanup_on_exit EXIT
|
|
trap 'exit 130' HUP INT TERM
|
|
|
|
# A hard interruption cannot run shell traps. The durable transaction marker
|
|
# makes the next invocation restore the last validated index before proceeding.
|
|
if [[ -e "$transaction_file" ]]; then
|
|
wm_log "Unterbrochene Routingaktualisierung erkannt; letzter gültiger Stand wird wiederhergestellt."
|
|
if wm_restore_previous_route; then
|
|
wm_restart_after_restore ||
|
|
wm_die "Der wiederhergestellte Routingindex bestand den Routentest nicht."
|
|
else
|
|
wm_restart_after_restore ||
|
|
wm_log "Es existierte noch kein vorheriger Routingindex; aktiver Marker wurde entfernt."
|
|
fi
|
|
rm -f "$transaction_file"
|
|
fi
|
|
|
|
rm -f "$candidate_file" "$candidate_marker"
|
|
previous_ready=false
|
|
if wm_route_data_ready; then
|
|
previous_ready=true
|
|
if [[ "$force_rebuild" != "true" ]]; then
|
|
cp --reflink=auto "$route_file" "$candidate_file"
|
|
chmod 0644 "$candidate_file"
|
|
fi
|
|
fi
|
|
|
|
wm_log "Deutschland-/Niederlande-Routingdaten werden in einer Stagingdatei gebaut."
|
|
if ! wm_compose --profile maintenance run --rm \
|
|
--env "WATERMAPS_LOCAL_FAIRWAYS_PATH=$container_candidate" \
|
|
--env "WATERMAPS_ROUTE_MARKER_PATH=$container_candidate_marker" \
|
|
route-data; then
|
|
wm_die "Der Datenaufbau ist fehlgeschlagen; der aktive Index wurde nicht verändert."
|
|
fi
|
|
|
|
if ! wm_route_data_files_ready "$candidate_file" "$candidate_marker"; then
|
|
wm_die "Der neu gebaute Routingindex oder sein Bereitschaftsmarker ist ungültig."
|
|
fi
|
|
|
|
if [[ "$previous_ready" == "true" ]] && cmp --silent "$candidate_file" "$route_file"; then
|
|
wm_log "Geofabrik-Snapshots und Routingindex sind unverändert."
|
|
rm -f "$candidate_file" "$candidate_marker"
|
|
exit 0
|
|
fi
|
|
|
|
if [[ "$previous_ready" == "true" ]]; then
|
|
wm_copy_route_atomically "$route_file" "$backup_file"
|
|
wm_write_route_marker "$backup_file" "$backup_marker"
|
|
wm_route_data_files_ready "$backup_file" "$backup_marker" ||
|
|
wm_die "Der bisherige Routingindex konnte nicht sicher gesichert werden."
|
|
else
|
|
rm -f "$backup_file" "$backup_marker"
|
|
fi
|
|
|
|
temporary_transaction="$(mktemp "$WATERMAPS_RUNTIME_DIR/locks/.route-update-transaction.XXXXXX")"
|
|
{
|
|
printf 'started_at=%s\n' "$(date --utc +%Y-%m-%dT%H:%M:%SZ)"
|
|
printf 'had_previous=%s\n' "$previous_ready"
|
|
} >"$temporary_transaction"
|
|
chmod 0644 "$temporary_transaction"
|
|
mv -f "$temporary_transaction" "$transaction_file"
|
|
transaction_active=true
|
|
|
|
mv -f "$candidate_file" "$route_file"
|
|
rm -f "$candidate_marker"
|
|
wm_write_route_marker "$route_file" "$route_marker"
|
|
wm_route_data_ready ||
|
|
wm_die "Der aktivierte Routingindex besitzt keinen gültigen Bereitschaftsmarker."
|
|
|
|
wm_compose restart watermaps
|
|
if wm_wait_for_health watermaps 240 && wm_smoke_test_route; then
|
|
rm -f "$transaction_file"
|
|
transaction_active=false
|
|
rm -f "$backup_file" "$backup_marker"
|
|
wm_log "Routingdaten-Update wurde erfolgreich aktiviert."
|
|
exit 0
|
|
fi
|
|
|
|
wm_log "Der neue Routingindex bestand die Routentests nicht; Rollback wird ausgeführt."
|
|
if wm_rollback_transaction; then
|
|
rm -f "$backup_file" "$backup_marker"
|
|
wm_die "Neuer Routingindex verworfen; der vorherige, erneut getestete Index ist aktiv."
|
|
fi
|
|
|
|
if [[ "$rollback_restored_previous" == "true" ]]; then
|
|
wm_die "Rollback-Dateien wurden wiederhergestellt, bestanden aber den Routentest nicht."
|
|
fi
|
|
wm_die "Neuer Routingindex verworfen; es existierte noch kein vorheriger gültiger Index."
|