feature/integracion-cloudrestore-targets
This commit is contained in:
8
scripts/docker-entrypoint.sh
Normal file
8
scripts/docker-entrypoint.sh
Normal file
@@ -0,0 +1,8 @@
|
||||
#!/bin/sh
|
||||
set -e
|
||||
|
||||
echo "Panel — verificando dependencias de base de datos..."
|
||||
node /app/scripts/wait-for-a24c-schema.js
|
||||
|
||||
echo "Panel — iniciando servidor HTTPS..."
|
||||
exec node /app/server.js
|
||||
98
scripts/wait-for-a24c-schema.js
Normal file
98
scripts/wait-for-a24c-schema.js
Normal file
@@ -0,0 +1,98 @@
|
||||
/**
|
||||
* Espera a que PostgreSQL responda y que el esquema CloudRestore (Alembic a24c)
|
||||
* esté aplicado antes de arrancar el panel HTTPS.
|
||||
*/
|
||||
import { fileURLToPath } from 'url';
|
||||
import pg from 'pg';
|
||||
|
||||
const { Pool } = pg;
|
||||
|
||||
const REQUIRED_TABLES = ['restore_targets', 'cloudrestore_status', 'restore_job_logs'];
|
||||
|
||||
function envInt(name, fallback) {
|
||||
const raw = process.env[name];
|
||||
if (!raw) return fallback;
|
||||
const n = Number.parseInt(raw, 10);
|
||||
return Number.isFinite(n) && n > 0 ? n : fallback;
|
||||
}
|
||||
|
||||
function poolConfig() {
|
||||
return {
|
||||
host: process.env.DB_POSTGRES_HOST || 'localhost',
|
||||
port: Number.parseInt(process.env.DB_POSTGRES_PORT || '5432', 10),
|
||||
database: process.env.DB_POSTGRES_DB || 'a24c',
|
||||
user: process.env.DB_POSTGRES_USER || 'postgres',
|
||||
password: process.env.DB_POSTGRES_PASS || 'postgres',
|
||||
max: 1,
|
||||
connectionTimeoutMillis: 5000,
|
||||
};
|
||||
}
|
||||
|
||||
async function postgresReady(pool) {
|
||||
await pool.query('SELECT 1');
|
||||
}
|
||||
|
||||
async function tablesReady(pool) {
|
||||
const r = await pool.query(
|
||||
`
|
||||
SELECT table_name
|
||||
FROM information_schema.tables
|
||||
WHERE table_schema = 'a24c'
|
||||
AND table_name = ANY($1::text[])
|
||||
`,
|
||||
[REQUIRED_TABLES]
|
||||
);
|
||||
return r.rows.length === REQUIRED_TABLES.length;
|
||||
}
|
||||
|
||||
function sleep(ms) {
|
||||
return new Promise((resolve) => setTimeout(resolve, ms));
|
||||
}
|
||||
|
||||
export async function waitForA24cSchema() {
|
||||
const maxAttempts = envInt('A24C_SCHEMA_WAIT_ATTEMPTS', 60);
|
||||
const intervalMs = envInt('A24C_SCHEMA_WAIT_INTERVAL_MS', 2000);
|
||||
const pool = new Pool(poolConfig());
|
||||
|
||||
console.log('==========================================');
|
||||
console.log('Panel — esperando esquema a24c (CloudRestore)');
|
||||
console.log(` host: ${poolConfig().host}:${poolConfig().port}`);
|
||||
console.log(` db: ${poolConfig().database}`);
|
||||
console.log('==========================================');
|
||||
|
||||
try {
|
||||
for (let attempt = 1; attempt <= maxAttempts; attempt++) {
|
||||
try {
|
||||
await postgresReady(pool);
|
||||
if (await tablesReady(pool)) {
|
||||
console.log('✓ PostgreSQL y esquema CloudRestore listos');
|
||||
return;
|
||||
}
|
||||
console.log(
|
||||
` intento ${attempt}/${maxAttempts}: tablas CRA pendientes (levanta a24c-backend si aún no corre)`
|
||||
);
|
||||
} catch (err) {
|
||||
const msg = err instanceof Error ? err.message : String(err);
|
||||
console.log(` intento ${attempt}/${maxAttempts}: ${msg}`);
|
||||
}
|
||||
|
||||
if (attempt < maxAttempts) {
|
||||
await sleep(intervalMs);
|
||||
}
|
||||
}
|
||||
|
||||
throw new Error(
|
||||
'Timeout esperando esquema CloudRestore. Orden recomendado: ' +
|
||||
'a24c-postgres → a24c-backend (alembic upgrade head) → panel'
|
||||
);
|
||||
} finally {
|
||||
await pool.end();
|
||||
}
|
||||
}
|
||||
|
||||
if (process.argv[1] === fileURLToPath(import.meta.url)) {
|
||||
waitForA24cSchema().catch((err) => {
|
||||
console.error('❌', err instanceof Error ? err.message : err);
|
||||
process.exit(1);
|
||||
});
|
||||
}
|
||||
Reference in New Issue
Block a user