@deinossrl/dgp-agent 1.5.6 → 1.5.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/index.mjs +152 -17
- package/package.json +1 -1
package/index.mjs
CHANGED
|
@@ -1770,24 +1770,93 @@ async function executePgDump(command) {
|
|
|
1770
1770
|
// Archivo de salida
|
|
1771
1771
|
pgDumpArgs.push(`--file=${localFilePath}`);
|
|
1772
1772
|
|
|
1773
|
-
//
|
|
1773
|
+
// Agregar --verbose para obtener información de progreso
|
|
1774
|
+
pgDumpArgs.push('--verbose');
|
|
1775
|
+
|
|
1776
|
+
// Ejecutar pg_dump usando spawn para capturar progreso en tiempo real
|
|
1774
1777
|
logCommand(`Ejecutando: pg_dump [conexión oculta]`);
|
|
1775
1778
|
await addCommandLog('command', 'Ejecutando pg_dump...');
|
|
1776
1779
|
|
|
1777
|
-
|
|
1778
|
-
|
|
1779
|
-
|
|
1780
|
-
|
|
1781
|
-
|
|
1780
|
+
// Usar spawn asíncrono para capturar progreso
|
|
1781
|
+
await new Promise((resolve, reject) => {
|
|
1782
|
+
const pgDumpProcess = spawn(pgDumpCmd, pgDumpArgs, {
|
|
1783
|
+
env: process.env,
|
|
1784
|
+
stdio: ['ignore', 'pipe', 'pipe'],
|
|
1785
|
+
});
|
|
1782
1786
|
|
|
1783
|
-
|
|
1784
|
-
|
|
1785
|
-
|
|
1787
|
+
let stderrBuffer = '';
|
|
1788
|
+
let stdoutBuffer = '';
|
|
1789
|
+
let lastLogTime = Date.now();
|
|
1790
|
+
let objectCount = 0;
|
|
1791
|
+
let totalEstimated = 0;
|
|
1792
|
+
|
|
1793
|
+
// Estimar total de objetos si se especificaron schemas/tables
|
|
1794
|
+
if (params.tables && params.tables.length > 0) {
|
|
1795
|
+
totalEstimated = params.tables.length;
|
|
1796
|
+
} else if (params.schemas && params.schemas.length > 0) {
|
|
1797
|
+
// Aproximado: ~20 objetos por schema (tablas, índices, secuencias, etc.)
|
|
1798
|
+
totalEstimated = params.schemas.length * 20;
|
|
1799
|
+
}
|
|
1786
1800
|
|
|
1787
|
-
|
|
1788
|
-
|
|
1789
|
-
|
|
1790
|
-
|
|
1801
|
+
// Capturar stderr (pg_dump envía progreso aquí con --verbose)
|
|
1802
|
+
pgDumpProcess.stderr.on('data', (data) => {
|
|
1803
|
+
const message = data.toString();
|
|
1804
|
+
stderrBuffer += message;
|
|
1805
|
+
|
|
1806
|
+
// Contar objetos procesados
|
|
1807
|
+
const lines = message.split('\n');
|
|
1808
|
+
for (const line of lines) {
|
|
1809
|
+
if (line.includes('processing') || line.includes('dumping data for table') || line.includes('creating') || line.includes('setting owner')) {
|
|
1810
|
+
objectCount++;
|
|
1811
|
+
}
|
|
1812
|
+
}
|
|
1813
|
+
|
|
1814
|
+
// Enviar log cada 2 segundos para no saturar
|
|
1815
|
+
const now = Date.now();
|
|
1816
|
+
if (now - lastLogTime > 2000) {
|
|
1817
|
+
const relevantLine = lines[lines.length - 1].trim();
|
|
1818
|
+
if (relevantLine && (relevantLine.includes('processing') || relevantLine.includes('dumping') || relevantLine.includes('table') || relevantLine.includes('creating'))) {
|
|
1819
|
+
let progressMsg = '';
|
|
1820
|
+
|
|
1821
|
+
// Si tenemos estimación, mostrar porcentaje
|
|
1822
|
+
if (totalEstimated > 0 && objectCount > 0) {
|
|
1823
|
+
const percentage = Math.min(Math.round((objectCount / totalEstimated) * 100), 100);
|
|
1824
|
+
progressMsg = `Progreso: ${percentage}% (${objectCount}/${totalEstimated}) - `;
|
|
1825
|
+
} else if (objectCount > 0) {
|
|
1826
|
+
progressMsg = `Objetos procesados: ${objectCount} - `;
|
|
1827
|
+
}
|
|
1828
|
+
|
|
1829
|
+
progressMsg += relevantLine.substring(0, 80);
|
|
1830
|
+
addCommandLog('info', progressMsg).catch(() => {});
|
|
1831
|
+
lastLogTime = now;
|
|
1832
|
+
}
|
|
1833
|
+
}
|
|
1834
|
+
});
|
|
1835
|
+
|
|
1836
|
+
// Capturar stdout (por si acaso)
|
|
1837
|
+
pgDumpProcess.stdout.on('data', (data) => {
|
|
1838
|
+
stdoutBuffer += data.toString();
|
|
1839
|
+
});
|
|
1840
|
+
|
|
1841
|
+
// Manejar errores del proceso
|
|
1842
|
+
pgDumpProcess.on('error', (error) => {
|
|
1843
|
+
reject(new Error(`Error ejecutando pg_dump: ${error.message}`));
|
|
1844
|
+
});
|
|
1845
|
+
|
|
1846
|
+
// Manejar finalización
|
|
1847
|
+
pgDumpProcess.on('close', (code) => {
|
|
1848
|
+
if (code !== 0) {
|
|
1849
|
+
const errorMsg = stderrBuffer || stdoutBuffer || 'Unknown error';
|
|
1850
|
+
reject(new Error(`pg_dump failed with code ${code}: ${errorMsg}`));
|
|
1851
|
+
} else {
|
|
1852
|
+
// Log final con total de objetos procesados
|
|
1853
|
+
if (objectCount > 0) {
|
|
1854
|
+
addCommandLog('success', `Backup completado: ${objectCount} objetos exportados`).catch(() => {});
|
|
1855
|
+
}
|
|
1856
|
+
resolve();
|
|
1857
|
+
}
|
|
1858
|
+
});
|
|
1859
|
+
});
|
|
1791
1860
|
|
|
1792
1861
|
// Verificar que el archivo se creó
|
|
1793
1862
|
if (!existsSync(localFilePath)) {
|
|
@@ -2177,9 +2246,35 @@ async function executePgRestore(command) {
|
|
|
2177
2246
|
pgRestoreArgs.push('--no-owner');
|
|
2178
2247
|
pgRestoreArgs.push('--no-privileges');
|
|
2179
2248
|
|
|
2249
|
+
// Agregar --verbose para obtener información de progreso
|
|
2250
|
+
pgRestoreArgs.push('--verbose');
|
|
2251
|
+
|
|
2180
2252
|
// Archivo de entrada
|
|
2181
2253
|
pgRestoreArgs.push(localFilePath);
|
|
2182
2254
|
|
|
2255
|
+
// CALCULAR TOTAL DE OBJETOS para el porcentaje
|
|
2256
|
+
let totalObjects = 0;
|
|
2257
|
+
try {
|
|
2258
|
+
const listResult = spawnSync(pgRestorePath, ['--list', localFilePath], {
|
|
2259
|
+
env: process.env,
|
|
2260
|
+
encoding: 'utf-8',
|
|
2261
|
+
stdio: 'pipe',
|
|
2262
|
+
});
|
|
2263
|
+
|
|
2264
|
+
if (listResult.status === 0 && listResult.stdout) {
|
|
2265
|
+
// Contar líneas que representan objetos (excluir comentarios y líneas vacías)
|
|
2266
|
+
const lines = listResult.stdout.split('\n').filter(line => {
|
|
2267
|
+
const trimmed = line.trim();
|
|
2268
|
+
return trimmed && !trimmed.startsWith(';') && /^\d+;/.test(trimmed);
|
|
2269
|
+
});
|
|
2270
|
+
totalObjects = lines.length;
|
|
2271
|
+
logInfo(`Total de objetos a restaurar: ${totalObjects}`);
|
|
2272
|
+
await addCommandLog('info', `Objetos a procesar: ${totalObjects}`);
|
|
2273
|
+
}
|
|
2274
|
+
} catch (e) {
|
|
2275
|
+
logInfo('No se pudo contar objetos, continuando sin porcentaje...');
|
|
2276
|
+
}
|
|
2277
|
+
|
|
2183
2278
|
// Ejecutar pg_restore con progreso en tiempo real
|
|
2184
2279
|
logCommand(`Ejecutando: pg_restore [conexión oculta]`);
|
|
2185
2280
|
await addCommandLog('command', 'Ejecutando pg_restore...');
|
|
@@ -2190,24 +2285,64 @@ async function executePgRestore(command) {
|
|
|
2190
2285
|
const result = await new Promise((resolve, reject) => {
|
|
2191
2286
|
const child = spawn(pgRestorePath, pgRestoreArgs, {
|
|
2192
2287
|
env: process.env,
|
|
2193
|
-
stdio: 'pipe',
|
|
2288
|
+
stdio: ['ignore', 'pipe', 'pipe'],
|
|
2194
2289
|
});
|
|
2195
2290
|
|
|
2196
2291
|
let stdout = '';
|
|
2197
2292
|
let stderr = '';
|
|
2293
|
+
let processedObjects = 0;
|
|
2294
|
+
let lastLogTime = Date.now();
|
|
2198
2295
|
|
|
2199
2296
|
child.stdout.on('data', (data) => {
|
|
2200
2297
|
stdout += data.toString();
|
|
2201
2298
|
});
|
|
2202
2299
|
|
|
2203
2300
|
child.stderr.on('data', (data) => {
|
|
2204
|
-
|
|
2301
|
+
const message = data.toString();
|
|
2302
|
+
stderr += message;
|
|
2303
|
+
|
|
2304
|
+
// Contar objetos procesados buscando patrones como "processing item" o nombres de tablas
|
|
2305
|
+
const lines = message.split('\n');
|
|
2306
|
+
for (const line of lines) {
|
|
2307
|
+
if (line.includes('processing') || line.includes('creating') || line.includes('restoring')) {
|
|
2308
|
+
processedObjects++;
|
|
2309
|
+
|
|
2310
|
+
// Enviar log cada 2 segundos para no saturar
|
|
2311
|
+
const now = Date.now();
|
|
2312
|
+
if (now - lastLogTime > 2000) {
|
|
2313
|
+
let progressMsg = '';
|
|
2314
|
+
|
|
2315
|
+
if (totalObjects > 0) {
|
|
2316
|
+
const percentage = Math.min(Math.round((processedObjects / totalObjects) * 100), 100);
|
|
2317
|
+
progressMsg = `Progreso: ${percentage}% (${processedObjects}/${totalObjects})`;
|
|
2318
|
+
} else {
|
|
2319
|
+
progressMsg = `Objetos procesados: ${processedObjects}`;
|
|
2320
|
+
}
|
|
2321
|
+
|
|
2322
|
+
// Agregar detalle de lo que se está procesando
|
|
2323
|
+
const relevantLine = line.substring(0, 100).trim();
|
|
2324
|
+
if (relevantLine) {
|
|
2325
|
+
progressMsg += ` - ${relevantLine}`;
|
|
2326
|
+
}
|
|
2327
|
+
|
|
2328
|
+
addCommandLog('info', progressMsg).catch(() => {});
|
|
2329
|
+
lastLogTime = now;
|
|
2330
|
+
}
|
|
2331
|
+
}
|
|
2332
|
+
}
|
|
2205
2333
|
});
|
|
2206
2334
|
|
|
2207
|
-
// Mostrar progreso cada 10 segundos
|
|
2335
|
+
// Mostrar progreso por tiempo cada 10 segundos como respaldo
|
|
2208
2336
|
progressInterval = setInterval(() => {
|
|
2209
2337
|
const elapsed = Math.floor((Date.now() - startTime) / 1000);
|
|
2210
|
-
|
|
2338
|
+
if (Date.now() - lastLogTime > 10000) { // Solo si no se ha logueado recientemente
|
|
2339
|
+
let msg = `Restaurando... (${elapsed}s transcurridos)`;
|
|
2340
|
+
if (totalObjects > 0 && processedObjects > 0) {
|
|
2341
|
+
const percentage = Math.min(Math.round((processedObjects / totalObjects) * 100), 100);
|
|
2342
|
+
msg += ` - ${percentage}%`;
|
|
2343
|
+
}
|
|
2344
|
+
logInfo(msg);
|
|
2345
|
+
}
|
|
2211
2346
|
}, 10000);
|
|
2212
2347
|
|
|
2213
2348
|
child.on('error', (error) => {
|