@deinossrl/dgp-agent 1.4.43 → 1.4.44
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/CHANGELOG.md +15 -0
- package/index.mjs +206 -2
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,20 @@
|
|
|
1
1
|
# Changelog - DGP Agent
|
|
2
2
|
|
|
3
|
+
## [1.4.44] - 2026-01-12
|
|
4
|
+
|
|
5
|
+
### Added
|
|
6
|
+
- Búsqueda automática de pg_dump en ubicaciones comunes de Windows
|
|
7
|
+
- Descarga e instalación automática de PostgreSQL binaries si no se encuentra pg_dump
|
|
8
|
+
- Los binarios se guardan en ~/.dgp-agent/bin/ para reutilización
|
|
9
|
+
- Soporte para instalación portable sin requerir PostgreSQL completo
|
|
10
|
+
|
|
11
|
+
### Changed
|
|
12
|
+
- executePgDump ahora busca/instala pg_dump automáticamente antes de ejecutar
|
|
13
|
+
- Mejor experiencia de usuario: funciona sin configuración manual
|
|
14
|
+
|
|
15
|
+
### Fixed
|
|
16
|
+
- Error "pg_dump not found" en Windows ahora se resuelve automáticamente
|
|
17
|
+
|
|
3
18
|
## [1.4.43] - 2026-01-12
|
|
4
19
|
|
|
5
20
|
### Fixed
|
package/index.mjs
CHANGED
|
@@ -44,6 +44,7 @@ const AGENT_VERSION = packageJson.version;
|
|
|
44
44
|
const CONFIG_DIR = join(homedir(), '.dgp-agent');
|
|
45
45
|
const CONFIG_FILE = join(CONFIG_DIR, 'config.json');
|
|
46
46
|
const PID_FILE = join(CONFIG_DIR, 'agent.pid');
|
|
47
|
+
const BIN_DIR = join(CONFIG_DIR, 'bin');
|
|
47
48
|
|
|
48
49
|
/**
|
|
49
50
|
* Mata al agente anterior si existe
|
|
@@ -1421,6 +1422,205 @@ async function executeDeploy(command) {
|
|
|
1421
1422
|
}
|
|
1422
1423
|
}
|
|
1423
1424
|
|
|
1425
|
+
/**
|
|
1426
|
+
* Busca pg_dump en el sistema o lo descarga automáticamente
|
|
1427
|
+
* @returns {Promise<string>} Ruta al ejecutable pg_dump
|
|
1428
|
+
*/
|
|
1429
|
+
async function findOrInstallPgDump() {
|
|
1430
|
+
const isWindows = process.platform === 'win32';
|
|
1431
|
+
const executableName = isWindows ? 'pg_dump.exe' : 'pg_dump';
|
|
1432
|
+
|
|
1433
|
+
// 1. Verificar si ya está en nuestro BIN_DIR
|
|
1434
|
+
const localPgDump = join(BIN_DIR, executableName);
|
|
1435
|
+
if (existsSync(localPgDump)) {
|
|
1436
|
+
return localPgDump;
|
|
1437
|
+
}
|
|
1438
|
+
|
|
1439
|
+
// 2. Buscar en PATH
|
|
1440
|
+
try {
|
|
1441
|
+
const checkCmd = isWindows ? 'where pg_dump' : 'which pg_dump';
|
|
1442
|
+
const output = execSync(checkCmd, { encoding: 'utf-8' }).trim();
|
|
1443
|
+
if (output) {
|
|
1444
|
+
logSuccess(`pg_dump encontrado en PATH: ${output}`);
|
|
1445
|
+
return output.split('\n')[0]; // Primera línea si hay múltiples
|
|
1446
|
+
}
|
|
1447
|
+
} catch (e) {
|
|
1448
|
+
// No está en PATH, continuar buscando
|
|
1449
|
+
}
|
|
1450
|
+
|
|
1451
|
+
// 3. Buscar en ubicaciones comunes de Windows
|
|
1452
|
+
if (isWindows) {
|
|
1453
|
+
const commonPaths = [
|
|
1454
|
+
'C:\\Program Files\\PostgreSQL',
|
|
1455
|
+
'C:\\Program Files (x86)\\PostgreSQL',
|
|
1456
|
+
];
|
|
1457
|
+
|
|
1458
|
+
for (const basePath of commonPaths) {
|
|
1459
|
+
if (existsSync(basePath)) {
|
|
1460
|
+
// Buscar en todas las versiones (16, 15, 14, etc.)
|
|
1461
|
+
try {
|
|
1462
|
+
const versions = execSync(`dir "${basePath}" /b`, { encoding: 'utf-8' })
|
|
1463
|
+
.trim()
|
|
1464
|
+
.split('\n')
|
|
1465
|
+
.filter(v => /^\d+$/.test(v.trim()))
|
|
1466
|
+
.sort((a, b) => parseInt(b) - parseInt(a)); // Mayor a menor
|
|
1467
|
+
|
|
1468
|
+
for (const version of versions) {
|
|
1469
|
+
const pgDumpPath = join(basePath, version.trim(), 'bin', 'pg_dump.exe');
|
|
1470
|
+
if (existsSync(pgDumpPath)) {
|
|
1471
|
+
logSuccess(`pg_dump encontrado: ${pgDumpPath}`);
|
|
1472
|
+
return pgDumpPath;
|
|
1473
|
+
}
|
|
1474
|
+
}
|
|
1475
|
+
} catch (e) {
|
|
1476
|
+
// Ignorar errores de dir
|
|
1477
|
+
}
|
|
1478
|
+
}
|
|
1479
|
+
}
|
|
1480
|
+
}
|
|
1481
|
+
|
|
1482
|
+
// 4. Si no se encontró, descargar binarios portables
|
|
1483
|
+
logInfo('pg_dump no encontrado. Descargando binarios de PostgreSQL...');
|
|
1484
|
+
|
|
1485
|
+
if (!existsSync(BIN_DIR)) {
|
|
1486
|
+
mkdirSync(BIN_DIR, { recursive: true });
|
|
1487
|
+
}
|
|
1488
|
+
|
|
1489
|
+
const downloadPgDump = async () => {
|
|
1490
|
+
if (isWindows) {
|
|
1491
|
+
// Descargar binaries de PostgreSQL para Windows
|
|
1492
|
+
// Usamos la versión portable de PostgreSQL 16
|
|
1493
|
+
const zipUrl = 'https://get.enterprisedb.com/postgresql/postgresql-16.1-1-windows-x64-binaries.zip';
|
|
1494
|
+
const zipPath = join(BIN_DIR, 'postgresql-binaries.zip');
|
|
1495
|
+
|
|
1496
|
+
logInfo('Descargando PostgreSQL binaries...');
|
|
1497
|
+
logInfo('Esto puede tomar unos minutos (80 MB)...');
|
|
1498
|
+
|
|
1499
|
+
return new Promise((resolve, reject) => {
|
|
1500
|
+
const file = createWriteStream(zipPath);
|
|
1501
|
+
https.get(zipUrl, (response) => {
|
|
1502
|
+
if (response.statusCode === 302 || response.statusCode === 301) {
|
|
1503
|
+
// Seguir redirect
|
|
1504
|
+
https.get(response.headers.location, (redirectResponse) => {
|
|
1505
|
+
redirectResponse.pipe(file);
|
|
1506
|
+
file.on('finish', () => {
|
|
1507
|
+
file.close();
|
|
1508
|
+
logInfo('Descarga completada. Extrayendo...');
|
|
1509
|
+
|
|
1510
|
+
// Extraer solo pg_dump.exe y sus DLLs necesarias
|
|
1511
|
+
try {
|
|
1512
|
+
// Usar PowerShell para extraer el zip
|
|
1513
|
+
const extractCmd = `powershell -command "Expand-Archive -Path '${zipPath}' -DestinationPath '${BIN_DIR}' -Force"`;
|
|
1514
|
+
execSync(extractCmd);
|
|
1515
|
+
|
|
1516
|
+
// Los binarios estarán en BIN_DIR/pgsql/bin/
|
|
1517
|
+
const extractedPgDump = join(BIN_DIR, 'pgsql', 'bin', 'pg_dump.exe');
|
|
1518
|
+
|
|
1519
|
+
if (existsSync(extractedPgDump)) {
|
|
1520
|
+
// Copiar pg_dump.exe y DLLs necesarias al BIN_DIR raíz
|
|
1521
|
+
const binSrcDir = join(BIN_DIR, 'pgsql', 'bin');
|
|
1522
|
+
const essentialFiles = [
|
|
1523
|
+
'pg_dump.exe',
|
|
1524
|
+
'libpq.dll',
|
|
1525
|
+
'libiconv-2.dll',
|
|
1526
|
+
'libintl-9.dll',
|
|
1527
|
+
'libssl-3-x64.dll',
|
|
1528
|
+
'libcrypto-3-x64.dll',
|
|
1529
|
+
'zlib1.dll',
|
|
1530
|
+
];
|
|
1531
|
+
|
|
1532
|
+
for (const file of essentialFiles) {
|
|
1533
|
+
const src = join(binSrcDir, file);
|
|
1534
|
+
const dest = join(BIN_DIR, file);
|
|
1535
|
+
if (existsSync(src)) {
|
|
1536
|
+
execSync(`copy "${src}" "${dest}"`, { shell: 'cmd.exe' });
|
|
1537
|
+
}
|
|
1538
|
+
}
|
|
1539
|
+
|
|
1540
|
+
// Limpiar archivos temporales
|
|
1541
|
+
unlinkSync(zipPath);
|
|
1542
|
+
// Opcional: eliminar carpeta pgsql si queremos ahorrar espacio
|
|
1543
|
+
// execSync(`rmdir /s /q "${join(BIN_DIR, 'pgsql')}"`, { shell: 'cmd.exe' });
|
|
1544
|
+
|
|
1545
|
+
logSuccess('pg_dump instalado correctamente');
|
|
1546
|
+
resolve(localPgDump);
|
|
1547
|
+
} else {
|
|
1548
|
+
reject(new Error('No se pudo extraer pg_dump del archivo'));
|
|
1549
|
+
}
|
|
1550
|
+
} catch (extractError) {
|
|
1551
|
+
reject(new Error(`Error al extraer: ${extractError.message}`));
|
|
1552
|
+
}
|
|
1553
|
+
});
|
|
1554
|
+
}).on('error', reject);
|
|
1555
|
+
} else {
|
|
1556
|
+
response.pipe(file);
|
|
1557
|
+
file.on('finish', () => {
|
|
1558
|
+
file.close();
|
|
1559
|
+
logInfo('Descarga completada. Extrayendo...');
|
|
1560
|
+
|
|
1561
|
+
try {
|
|
1562
|
+
const extractCmd = `powershell -command "Expand-Archive -Path '${zipPath}' -DestinationPath '${BIN_DIR}' -Force"`;
|
|
1563
|
+
execSync(extractCmd);
|
|
1564
|
+
|
|
1565
|
+
const extractedPgDump = join(BIN_DIR, 'pgsql', 'bin', 'pg_dump.exe');
|
|
1566
|
+
|
|
1567
|
+
if (existsSync(extractedPgDump)) {
|
|
1568
|
+
const binSrcDir = join(BIN_DIR, 'pgsql', 'bin');
|
|
1569
|
+
const essentialFiles = [
|
|
1570
|
+
'pg_dump.exe',
|
|
1571
|
+
'libpq.dll',
|
|
1572
|
+
'libiconv-2.dll',
|
|
1573
|
+
'libintl-9.dll',
|
|
1574
|
+
'libssl-3-x64.dll',
|
|
1575
|
+
'libcrypto-3-x64.dll',
|
|
1576
|
+
'zlib1.dll',
|
|
1577
|
+
];
|
|
1578
|
+
|
|
1579
|
+
for (const file of essentialFiles) {
|
|
1580
|
+
const src = join(binSrcDir, file);
|
|
1581
|
+
const dest = join(BIN_DIR, file);
|
|
1582
|
+
if (existsSync(src)) {
|
|
1583
|
+
execSync(`copy "${src}" "${dest}"`, { shell: 'cmd.exe' });
|
|
1584
|
+
}
|
|
1585
|
+
}
|
|
1586
|
+
|
|
1587
|
+
unlinkSync(zipPath);
|
|
1588
|
+
|
|
1589
|
+
logSuccess('pg_dump instalado correctamente');
|
|
1590
|
+
resolve(localPgDump);
|
|
1591
|
+
} else {
|
|
1592
|
+
reject(new Error('No se pudo extraer pg_dump del archivo'));
|
|
1593
|
+
}
|
|
1594
|
+
} catch (extractError) {
|
|
1595
|
+
reject(new Error(`Error al extraer: ${extractError.message}`));
|
|
1596
|
+
}
|
|
1597
|
+
});
|
|
1598
|
+
}
|
|
1599
|
+
}).on('error', (err) => {
|
|
1600
|
+
unlinkSync(zipPath);
|
|
1601
|
+
reject(err);
|
|
1602
|
+
});
|
|
1603
|
+
|
|
1604
|
+
file.on('error', (err) => {
|
|
1605
|
+
unlinkSync(zipPath);
|
|
1606
|
+
reject(err);
|
|
1607
|
+
});
|
|
1608
|
+
});
|
|
1609
|
+
} else {
|
|
1610
|
+
// En Linux/Mac, intentar instalar via package manager
|
|
1611
|
+
throw new Error('pg_dump no encontrado. Por favor instala PostgreSQL: sudo apt-get install postgresql-client (Debian/Ubuntu) o brew install postgresql (Mac)');
|
|
1612
|
+
}
|
|
1613
|
+
};
|
|
1614
|
+
|
|
1615
|
+
await downloadPgDump();
|
|
1616
|
+
|
|
1617
|
+
if (existsSync(localPgDump)) {
|
|
1618
|
+
return localPgDump;
|
|
1619
|
+
} else {
|
|
1620
|
+
throw new Error('No se pudo instalar pg_dump automáticamente');
|
|
1621
|
+
}
|
|
1622
|
+
}
|
|
1623
|
+
|
|
1424
1624
|
/**
|
|
1425
1625
|
* Ejecuta pg_dump para crear backup de PostgreSQL
|
|
1426
1626
|
*/
|
|
@@ -1459,8 +1659,12 @@ async function executePgDump(command) {
|
|
|
1459
1659
|
const fileName = `backup_${environmentId}_${timestamp}.${extension}`;
|
|
1460
1660
|
localFilePath = join(backupsDir, fileName);
|
|
1461
1661
|
|
|
1462
|
-
//
|
|
1463
|
-
|
|
1662
|
+
// Buscar o instalar pg_dump
|
|
1663
|
+
await addCommandLog('info', 'Buscando pg_dump...');
|
|
1664
|
+
const pgDumpCmd = await findOrInstallPgDump();
|
|
1665
|
+
await addCommandLog('success', `Usando pg_dump: ${pgDumpCmd}`);
|
|
1666
|
+
|
|
1667
|
+
// Construir argumentos
|
|
1464
1668
|
const pgDumpArgs = [];
|
|
1465
1669
|
|
|
1466
1670
|
// Configurar conexión según tipo
|