2026-07-25 00:18:48 -03:00
# services/cassandra/migration-jobs/db-copy-veles-to-cassandra-job.yaml
# Suspended by default. Unsuspend after cassandra-postgres is ready and before
# enabling generator/retention workers. This copies from Veles to Cassandra and
# verifies table sets, row counts, and per-table content hashes.
apiVersion : batch/v1
kind : Job
metadata :
2026-07-25 01:23:06 -03:00
name : cassandra-db-copy-from-veles-3
2026-07-25 00:18:48 -03:00
namespace : cassandra
spec :
2026-07-25 01:26:55 -03:00
suspend : true
2026-07-25 00:18:48 -03:00
backoffLimit : 0
ttlSecondsAfterFinished : 86400
template :
metadata :
annotations :
vault.hashicorp.com/agent-inject : "true"
vault.hashicorp.com/agent-init-first : "true"
vault.hashicorp.com/agent-pre-populate-only : "true"
vault.hashicorp.com/role : "cassandra-migration"
vault.hashicorp.com/agent-inject-secret-source-db.sh : "kv/data/atlas/veles/veles-db"
vault.hashicorp.com/agent-inject-template-source-db.sh : |
{{- with secret "kv/data/atlas/veles/veles-db" }}
export SOURCE_DATABASE_URL="{{ .Data.data.DATABASE_URL }}"
{{- end }}
vault.hashicorp.com/agent-inject-secret-target-db.sh : "kv/data/atlas/cassandra/cassandra-db"
vault.hashicorp.com/agent-inject-template-target-db.sh : |
{{- with secret "kv/data/atlas/cassandra/cassandra-db" }}
export TARGET_DATABASE_URL="{{ .Data.data.DATABASE_URL }}"
{{- end }}
spec :
serviceAccountName : cassandra-db-migration
restartPolicy : Never
nodeSelector :
cassandra.bstein.dev/node-pool : oceanus
kubernetes.io/arch : amd64
tolerations :
- key : veles.bstein.dev/simulation
operator : Equal
value : "true"
effect : NoSchedule
containers :
- name : copy-and-verify
image : postgres:15
command : [ "/bin/bash" , "-c" ]
args :
- |
set -euo pipefail
. /vault/secrets/source-db.sh
. /vault/secrets/target-db.sh
: "${SOURCE_DATABASE_URL:?missing source database url}"
: "${TARGET_DATABASE_URL:?missing target database url}"
export PGCONNECT_TIMEOUT=10
for attempt in $(seq 1 60); do
if pg_isready -d "${SOURCE_DATABASE_URL}" >/dev/null 2>&1 \
&& pg_isready -d "${TARGET_DATABASE_URL}" >/dev/null 2>&1; then
break
fi
if [ "${attempt}" = "60" ]; then
echo "source or target database did not become ready" >&2
exit 1
fi
sleep 5
done
dump_path=/tmp/veles-to-cassandra.dump
pg_dump --format=custom --no-owner --no-acl \
--dbname="${SOURCE_DATABASE_URL}" \
--file="${dump_path}"
2026-07-25 01:23:06 -03:00
psql -X --set=ON_ERROR_STOP=1 --dbname="${TARGET_DATABASE_URL}" \
--command="DROP SCHEMA IF EXISTS public CASCADE; CREATE SCHEMA public; GRANT ALL ON SCHEMA public TO cassandra; GRANT ALL ON SCHEMA public TO public;"
pg_restore --no-owner --no-acl \
2026-07-25 00:18:48 -03:00
--dbname="${TARGET_DATABASE_URL}" \
"${dump_path}"
table_sql="select schemaname || E'\t' || tablename from pg_tables where schemaname not in ('pg_catalog','information_schema') order by 1"
psql -XAt --dbname="${SOURCE_DATABASE_URL}" --command="${table_sql}" > /tmp/source.tables
psql -XAt --dbname="${TARGET_DATABASE_URL}" --command="${table_sql}" > /tmp/target.tables
diff -u /tmp/source.tables /tmp/target.tables
checksum_sql() {
schema="$1"
table="$2"
printf '%s\n' \
"SELECT format(" \
" 'select count(*)::text || E''\t'' || coalesce(md5(string_agg(md5(row_to_json(t)::text), '''' order by md5(row_to_json(t)::text))), md5('''')) from %I.%I t'," \
" :'schema'," \
" :'table'" \
")\\gexec" > /tmp/checksum.sql
psql -XAt --set=ON_ERROR_STOP=1 \
--set=schema="${schema}" \
--set=table="${table}" \
--dbname="$3" \
--file=/tmp/checksum.sql
}
failures=0
while IFS="$(printf '\t')" read -r schema table; do
[ -n "${schema}" ] || continue
source_sum="$(checksum_sql "${schema}" "${table}" "${SOURCE_DATABASE_URL}")"
target_sum="$(checksum_sql "${schema}" "${table}" "${TARGET_DATABASE_URL}")"
if [ "${source_sum}" != "${target_sum}" ]; then
echo "checksum mismatch for ${schema}.${table}: source=${source_sum} target=${target_sum}" >&2
failures=$((failures + 1))
else
echo "verified ${schema}.${table}: ${source_sum}"
fi
done < /tmp/source.tables
if [ "${failures}" -ne 0 ]; then
echo "database copy integrity verification failed for ${failures} table(s)" >&2
exit 1
fi
echo "database copy integrity verification passed"
resources :
requests :
cpu : 500m
memory : 1Gi
limits :
cpu : "2"
memory : 4Gi