Merge branch 'fix/backups_restore_dev' into 'main'

Fix/backups restore dev

See merge request jjimenez/safekat!879
This commit is contained in:
Ignacio Martinez Navajas
2025-07-14 12:23:24 +00:00

View File

@ -54,10 +54,10 @@ class Backups extends BaseController
} }
// === 2. Backups remotos en SFTP === // === 2. Backups remotos en SFTP ===
$sftpHost = getenv('HIDRIVE_HOST'); $sftpHost = getenv('HIDRIVE_BK_HOST');
$sftpUser = getenv('HIDRIVE_USER'); $sftpUser = getenv('HIDRIVE_BK_USER');
$sftpPass = getenv('HIDRIVE_PASS'); $sftpPass = getenv('HIDRIVE_BK_PASS');
$remoteDir = '/users/erp2019/backups_erp/'; $remoteDir = getenv('HIDRIVE_BK_PATH_ROOT');
$sftp = new SFTP($sftpHost); $sftp = new SFTP($sftpHost);
if ($sftp->login($sftpUser, $sftpPass)) { if ($sftp->login($sftpUser, $sftpPass)) {
@ -269,9 +269,10 @@ class Backups extends BaseController
} }
if (!empty($remotePath)) { if (!empty($remotePath)) {
$sftpHost = getenv('HIDRIVE_HOST'); $sftpHost = getenv('HIDRIVE_BK_HOST');
$sftpUser = getenv('HIDRIVE_USER'); $sftpUser = getenv('HIDRIVE_BK_USER');
$sftpPass = getenv('HIDRIVE_PASS'); $sftpPass = getenv('HIDRIVE_BK_PASS');
$sftp = new SFTP($sftpHost); $sftp = new SFTP($sftpHost);
@ -307,10 +308,10 @@ class Backups extends BaseController
} }
// También se puede intentar buscar en el SFTP si quieres // También se puede intentar buscar en el SFTP si quieres
$sftpHost = getenv('HIDRIVE_HOST'); $sftpHost = getenv('HIDRIVE_BK_HOST');
$sftpUser = getenv('HIDRIVE_USER'); $sftpUser = getenv('HIDRIVE_BK_USER');
$sftpPass = getenv('HIDRIVE_PASS'); $sftpPass = getenv('HIDRIVE_BK_PASS');
$remotePath = '/users/erp2019/backups_erp/' . $filename; $remotePath = getenv('HIDRIVE_BK_PATH_ROOT') . $filename;
$sftp = new SFTP($sftpHost); $sftp = new SFTP($sftpHost);
if ($sftp->login($sftpUser, $sftpPass)) { if ($sftp->login($sftpUser, $sftpPass)) {
@ -379,6 +380,7 @@ class Backups extends BaseController
public function restoreLocal($file) public function restoreLocal($file)
{ {
$path = WRITEPATH . 'backups/' . $file; $path = WRITEPATH . 'backups/' . $file;
if (!file_exists($path)) { if (!file_exists($path)) {
throw new \CodeIgniter\Exceptions\PageNotFoundException("Backup no encontrado."); throw new \CodeIgniter\Exceptions\PageNotFoundException("Backup no encontrado.");
} }
@ -399,21 +401,37 @@ class Backups extends BaseController
$sqlFile = $sqlFiles[0]; $sqlFile = $sqlFiles[0];
$dbConfig = config('Database')->default; // === Verificar que el archivo SQL existe y tiene contenido
$host = $dbConfig['hostname']; if (!file_exists($sqlFile)) {
$username = $dbConfig['username']; throw new \RuntimeException("Archivo SQL no encontrado.");
$password = $dbConfig['password'];
$database = $dbConfig['database'];
$cmd = "mysql -h {$host} -u{$username} -p'{$password}' {$database} < {$sqlFile}";
system($cmd, $retval);
if ($retval !== 0) {
throw new \RuntimeException("Error al restaurar la base de datos. Código: $retval");
} }
array_map('unlink', glob($extractPath . '*')); if (filesize($sqlFile) === 0) {
rmdir($extractPath); throw new \RuntimeException("El archivo SQL está vacío.");
}
// === Configuración de base de datos
$dbConfig = config('Database')->default;
$host = escapeshellarg($dbConfig['hostname']);
$username = escapeshellarg($dbConfig['username']);
$password = escapeshellarg($dbConfig['password']);
$database = escapeshellarg($dbConfig['database']);
// === Construcción del comando con stderr redirigido
$cmd = "mysql -h $host -u $username -p$password $database -e \"source $sqlFile\" 2>&1";
// === Ejecutar y capturar la salida
exec($cmd, $output, $retval);
// === Verificar resultado
if ($retval !== 0) {
throw new \RuntimeException("Error al restaurar la base de datos:\n" . implode("\n", $output));
}
// === Limpieza
helper('filesystem');
delete_files($extractPath, true); // elimina contenido
rmdir($extractPath); // elimina el directorio
return redirect()->to(route_to('backupsList'))->with('message', 'Backup restaurado correctamente (vía sistema).'); return redirect()->to(route_to('backupsList'))->with('message', 'Backup restaurado correctamente (vía sistema).');
} else { } else {
@ -424,60 +442,82 @@ class Backups extends BaseController
public function restoreRemote($filename) public function restoreRemote($filename)
{ {
helper('filesystem'); helper('filesystem');
// Buscar el backup en la base de datos $entorno = getenv('SK_ENVIRONMENT');
if ($entorno === 'development') {
// Construir ruta remota directamente
$remotePath = '/users/erp2019/backups_erp/' . $filename;
$localPath = WRITEPATH . 'backups/' . $filename;
$sftpHost = getenv('HIDRIVE_BK_HOST');
$sftpUser = getenv('HIDRIVE_BK_USER');
$sftpPass = getenv('HIDRIVE_BK_PASS');
$sftp = new SFTP($sftpHost);
if (!$sftp->login($sftpUser, $sftpPass)) {
return redirect()->to(route_to('backupsList'))->with('error', 'No se pudo autenticar en el servidor SFTP.');
}
$fileContents = $sftp->get($remotePath);
if ($fileContents === false) {
return redirect()->to(route_to('backupsList'))->with('error', 'No se pudo descargar el archivo remoto.');
}
if (write_file($localPath, $fileContents) === false) {
return redirect()->to(route_to('backupsList'))->with('error', 'No se pudo guardar el archivo localmente.');
}
// Restaurar directamente
return $this->restoreLocal($filename);
}
// Producción: flujo normal con base de datos
$backup = $this->backupModel->where('filename', $filename)->first(); $backup = $this->backupModel->where('filename', $filename)->first();
if (!$backup || empty($backup['path_remote'])) { if (!$backup || empty($backup['path_remote'])) {
return redirect()->to(route_to('backupsList'))->with('error', 'Backup remoto no encontrado en la base de datos.'); return redirect()->to(route_to('backupsList'))->with('error', 'Backup remoto no encontrado en la base de datos.');
} }
// Parámetros SFTP
$sftpHost = getenv('HIDRIVE_HOST');
$sftpUser = getenv('HIDRIVE_USER');
$sftpPass = getenv('HIDRIVE_PASS');
$remotePath = $backup['path_remote']; $remotePath = $backup['path_remote'];
$localPath = WRITEPATH . 'backups/' . $filename; $localPath = WRITEPATH . 'backups/' . $filename;
// Conectar al SFTP $sftpHost = getenv('HIDRIVE_BK_HOST');
$sftp = new SFTP($sftpHost); $sftpUser = getenv('HIDRIVE_BK_USER');
$sftpPass = getenv('HIDRIVE_BK_PASS');
$sftp = new SFTP($sftpHost);
if (!$sftp->login($sftpUser, $sftpPass)) { if (!$sftp->login($sftpUser, $sftpPass)) {
return redirect()->to(route_to('backupsList'))->with('error', 'No se pudo autenticar en el servidor SFTP.'); return redirect()->to(route_to('backupsList'))->with('error', 'No se pudo autenticar en el servidor SFTP.');
} }
// Descargar el archivo
$fileContents = $sftp->get($remotePath); $fileContents = $sftp->get($remotePath);
if ($fileContents === false) { if ($fileContents === false) {
return redirect()->to(route_to('backupsList'))->with('error', 'No se pudo descargar el archivo remoto.'); return redirect()->to(route_to('backupsList'))->with('error', 'No se pudo descargar el archivo remoto.');
} }
// Guardar localmente
if (write_file($localPath, $fileContents) === false) { if (write_file($localPath, $fileContents) === false) {
return redirect()->to(route_to('backupsList'))->with('error', 'No se pudo guardar el archivo localmente.'); return redirect()->to(route_to('backupsList'))->with('error', 'No se pudo guardar el archivo localmente.');
} }
// Actualizar la base de datos para marcar el archivo como local $this->backupModel->update($backup['id'], ['path_local' => $localPath]);
$this->backupModel->update($backup['id'], [
'path_local' => $localPath,
]);
// Restaurar usando el método local
return $this->restoreLocal($filename); return $this->restoreLocal($filename);
} }
private function sendToSFTP($localPath, $remoteFilename) private function sendToSFTP($localPath, $remoteFilename)
{ {
$sftpHost = getenv('HIDRIVE_HOST'); $sftpHost = getenv('HIDRIVE_BK_HOST');
$sftpUser = getenv('HIDRIVE_USER'); $sftpUser = getenv('HIDRIVE_BK_USER');
$sftpPass = getenv('HIDRIVE_PASS'); $sftpPass = getenv('HIDRIVE_BK_PASS');
$remotePath = '/users/erp2019/backups_erp/' . $remoteFilename; $remotePath = getenv('HIDRIVE_BK_PATH_ROOT') . $remoteFilename;
$sftp = new SFTP($sftpHost); $sftp = new SFTP($sftpHost);