mirror of
https://github.com/gadgethd/ukmesh.git
synced 2026-09-01 17:08:17 +00:00
Consolidates the stacked backend, privacy, network-intelligence, frontend, operations, mobile, and owner-cache changes after resolving main conflicts and passing the full CI suite.
98 lines
4.3 KiB
Bash
Executable File
98 lines
4.3 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
set -Eeuo pipefail
|
|
|
|
cd "$(dirname "$0")/.."
|
|
|
|
MODE="${1:-audit}"
|
|
PSQL=(docker compose exec -T timescaledb psql -U "${POSTGRES_USER:-meshcore}" -d "${POSTGRES_DB:-meshcore}" -v ON_ERROR_STOP=1 -X)
|
|
LEGACY_SQL="'teesside','northeast'"
|
|
RUN_ID="${NETWORK_UNIFICATION_RUN_ID:-network-unification-$(date -u +%Y%m%dT%H%M%SZ)}"
|
|
|
|
if [[ ! "$RUN_ID" =~ ^[A-Za-z0-9._:-]+$ ]]; then
|
|
printf 'Unsafe NETWORK_UNIFICATION_RUN_ID: %s\n' "$RUN_ID" >&2
|
|
exit 2
|
|
fi
|
|
|
|
log() { printf '[%s] %s\n' "$(date -Is)" "$*"; }
|
|
scalar() { "${PSQL[@]}" -qAt -c "$1" | tr -d '[:space:]'; }
|
|
|
|
audit() {
|
|
log 'network-label counts'
|
|
"${PSQL[@]}" <<'SQL'
|
|
SELECT 'nodes' AS relation, network, COUNT(*) FROM nodes GROUP BY network
|
|
UNION ALL SELECT 'node_status_samples', network, COUNT(*) FROM node_status_samples GROUP BY network
|
|
UNION ALL SELECT 'packets', network, COUNT(*) FROM packets GROUP BY network
|
|
UNION ALL SELECT 'node_network_sightings', network, COUNT(*) FROM node_network_sightings GROUP BY network
|
|
UNION ALL SELECT 'path_prefix_priors', network, COUNT(*) FROM path_prefix_priors GROUP BY network
|
|
ORDER BY 1, 2;
|
|
SQL
|
|
log 'recent legacy-writer activity'
|
|
"${PSQL[@]}" -c "SELECT network, MAX(time) AS latest, COUNT(*) AS packets_15m FROM packets WHERE network IN (${LEGACY_SQL}) AND time > NOW() - INTERVAL '15 minutes' GROUP BY network ORDER BY network;"
|
|
}
|
|
|
|
verify() {
|
|
local remaining
|
|
remaining="$(scalar "SELECT (SELECT COUNT(*) FROM nodes WHERE network IN (${LEGACY_SQL})) + (SELECT COUNT(*) FROM node_status_samples WHERE network IN (${LEGACY_SQL})) + (SELECT COUNT(*) FROM packets WHERE network IN (${LEGACY_SQL})) + (SELECT COUNT(*) FROM node_network_sightings WHERE network IN (${LEGACY_SQL}));")"
|
|
audit
|
|
if [[ "$remaining" != '0' ]]; then
|
|
log "ERROR: ${remaining} authoritative rows still use legacy production labels"
|
|
return 1
|
|
fi
|
|
log 'verification passed: authoritative production labels are unified'
|
|
}
|
|
|
|
relabel_status_batches() {
|
|
local batch_size="${NETWORK_UNIFICATION_STATUS_BATCH_SIZE:-50000}"
|
|
local changed=1 total=0
|
|
while [[ "$changed" -gt 0 ]]; do
|
|
changed="$(scalar "WITH batch AS MATERIALIZED (SELECT ctid FROM node_status_samples WHERE network IN (${LEGACY_SQL}) LIMIT ${batch_size}), changed AS (UPDATE node_status_samples target SET network = 'ukmesh' FROM batch WHERE target.ctid = batch.ctid RETURNING 1) SELECT COUNT(*) FROM changed;")"
|
|
total=$((total + changed))
|
|
log "node_status_samples relabelled=${total} last_batch=${changed}"
|
|
done
|
|
}
|
|
|
|
mark_failed() {
|
|
local status=$?
|
|
trap - ERR
|
|
"${PSQL[@]}" -qAt -c "UPDATE network_unification_runs SET status='failed', detail=jsonb_build_object('exit_status', ${status}) WHERE run_id='${RUN_ID//\'/\'\'}';" >/dev/null || true
|
|
exit "$status"
|
|
}
|
|
|
|
apply() {
|
|
if [[ "${CONFIRM_NETWORK_UNIFICATION:-}" != 'ukmesh' ]]; then
|
|
log 'ERROR: set CONFIRM_NETWORK_UNIFICATION=ukmesh for the irreversible apply step'
|
|
return 2
|
|
fi
|
|
if [[ -z "${BACKUP_REFERENCE:-}" ]]; then
|
|
log 'ERROR: BACKUP_REFERENCE must identify a verified pre-cutover database snapshot'
|
|
return 2
|
|
fi
|
|
local active_legacy
|
|
active_legacy="$(scalar "SELECT COUNT(*) FROM packets WHERE network IN (${LEGACY_SQL}) AND time > NOW() - INTERVAL '15 minutes';")"
|
|
if [[ "$active_legacy" != '0' ]]; then
|
|
log "ERROR: ${active_legacy} legacy-labelled packets arrived in the last 15 minutes; update/stop legacy writers first"
|
|
return 3
|
|
fi
|
|
|
|
trap mark_failed ERR
|
|
"${PSQL[@]}" -qAt -c "INSERT INTO network_unification_runs (run_id,status,backup_reference) VALUES ('${RUN_ID//\'/\'\'}','running','${BACKUP_REFERENCE//\'/\'\'}') ON CONFLICT (run_id) DO UPDATE SET status='running';"
|
|
audit
|
|
log 'applying small-table and derived-table cutover'
|
|
"${PSQL[@]}" -f scripts/unify-networks-migration.sql
|
|
log 'relabeling node status history in bounded commits'
|
|
relabel_status_batches
|
|
log 'relabeling packet chunks with compression-state preservation'
|
|
scripts/relabel-packets-per-chunk.sh
|
|
verify
|
|
"${PSQL[@]}" -qAt -c "UPDATE network_unification_runs SET status='completed', completed_at=NOW(), detail=jsonb_build_object('verified_at', NOW()) WHERE run_id='${RUN_ID//\'/\'\'}';"
|
|
trap - ERR
|
|
log "cutover complete run_id=${RUN_ID}"
|
|
}
|
|
|
|
case "$MODE" in
|
|
audit) audit ;;
|
|
verify) verify ;;
|
|
apply) apply ;;
|
|
*) printf 'Usage: %s [audit|apply|verify]\n' "$0" >&2; exit 2 ;;
|
|
esac
|