31 lines
1.4 KiB
TypeScript
31 lines
1.4 KiB
TypeScript
/** Back up the shared PostgreSQL container before migrating development. */
|
|
import { SQL } from 'bun';
|
|
|
|
const connection = process.env.DB_URL || process.env.DATABASE_URL;
|
|
if (!connection) throw new Error('DB_URL or DATABASE_URL is required');
|
|
const sql = new SQL(connection, { max: 1 });
|
|
let databaseName: string;
|
|
try {
|
|
const [row] = await sql`SELECT current_database() AS name`;
|
|
databaseName = row.name;
|
|
if (!['vash_dev', 'vash_esports_dev'].includes(databaseName))
|
|
throw new Error('Refusing to migrate a non-development database');
|
|
} finally {
|
|
await sql.end();
|
|
}
|
|
|
|
const container = process.env.POSTGRES_CONTAINER || 'postgres-db-1';
|
|
if (!/^[a-zA-Z0-9_.-]+$/.test(container)) throw new Error('Invalid POSTGRES_CONTAINER');
|
|
const host = process.env.DB_BACKUP_SSH || 'ai@localhost';
|
|
if (!/^[a-zA-Z0-9_.@-]+$/.test(host)) throw new Error('Invalid DB_BACKUP_SSH');
|
|
const backup = `/home/ai/esports-${databaseName}-before-migration-${Date.now()}.dump`;
|
|
const remote = `umask 077 && docker exec -i ${container} pg_dump -U postgres -d ${databaseName} -Fc > ${backup} && docker exec -i ${container} pg_restore -l < ${backup} >/dev/null && test -s ${backup}`;
|
|
const job = Bun.spawn(['ssh', '-o', 'BatchMode=yes', host, remote], {
|
|
stdout: 'inherit',
|
|
stderr: 'inherit'
|
|
});
|
|
if ((await job.exited) !== 0)
|
|
throw new Error('Backup failed or could not be verified; migration was not run');
|
|
console.log(`Verified development backup on ${host}: ${backup}`);
|
|
await import('./migrate');
|