set backup vars on object for acess and fix nedb backup #6481

Signed-off-by: si458 <simonsmith5521@gmail.com>

si458 committed Nov 5, 2024 at 16:05 UTC fc387ca4170ede49daeda9b068671d541c883cbd
1 file changed +49 -49
db.js
+49 -49
@@ -43,9 +43,9 @@ module.exports.CreateDB = function (parent, func) {
43 const BACKUPFAIL_ZIPCREATE = 0x0001;
44 const BACKUPFAIL_ZIPMODULE = 0x0010;
45 const BACKUPFAIL_DBDUMP = 0x0100;
46 - let backupStatus = 0x0;
47 - let newAutoBackupFile;
48 - let newDBDumpFile;
46 + obj.backupStatus = 0x0;
47 + obj.newAutoBackupFile = null;
48 + obj.newDBDumpFile = null;
49 obj.identifier = null;
50 obj.dbKey = null;
51 obj.dbRecordsEncryptKey = null;
@@ -3123,12 +3123,12 @@ module.exports.CreateDB = function (parent, func) {
3123
3124 const currentDate = new Date();
3125 const fileSuffix = currentDate.getFullYear() + '-' + padNumber(currentDate.getMonth() + 1, 2) + '-' + padNumber(currentDate.getDate(), 2) + '-' + padNumber(currentDate.getHours(), 2) + '-' + padNumber(currentDate.getMinutes(), 2);
3126 - const newAutoBackupFile = ((typeof parent.config.settings.autobackup.backupname == 'string') ? parent.config.settings.autobackup.backupname : 'meshcentral-autobackup-') + fileSuffix;
3126 + obj.newAutoBackupFile = ((typeof parent.config.settings.autobackup.backupname == 'string') ? parent.config.settings.autobackup.backupname : 'meshcentral-autobackup-') + fileSuffix;
3127
3128 r += 'DB Name: ' + dbname + '\r\n';
3129 r += 'DB Type: ' + DB_LIST[obj.databaseType] + '\r\n';
3130 r += 'BackupPath: ' + backupPath + '\r\n';
3131 - r += 'BackupFile: ' + newAutoBackupFile + '.zip\r\n';
3131 + r += 'BackupFile: ' + obj.newAutoBackupFile + '.zip\r\n';
3132
3133 if (parent.config.settings.autobackup == null) {
3134 r += 'No Settings/AutoBackup\r\n';
@@ -3146,7 +3146,7 @@ module.exports.CreateDB = function (parent, func) {
3146 if (parent.config.settings.autobackup.zippassword != null) {
3147 r += 'ZIP Password: ';
3148 if (typeof parent.config.settings.autobackup.zippassword != 'string') { r += 'Bad zippassword type, Backups will not be encrypted\r\n'; }
3149 - else if (parent.config.settings.autobackup.zippassword == "") { r += 'Blank, Backups will not be encrypted\r\n'; }
3149 + else if (parent.config.settings.autobackup.zippassword == "") { r += 'Blank zippassword, Backups will fail\r\n'; }
3150 else { r += 'Set\r\n'; }
3151 }
3152 if (parent.config.settings.autobackup.mongodumppath != null) {
@@ -3443,85 +3443,85 @@ module.exports.CreateDB = function (parent, func) {
3443 try { parent.fs.mkdirSync(backupPath); } catch (e) { }
3444 const currentDate = new Date();
3445 const fileSuffix = currentDate.getFullYear() + '-' + padNumber(currentDate.getMonth() + 1, 2) + '-' + padNumber(currentDate.getDate(), 2) + '-' + padNumber(currentDate.getHours(), 2) + '-' + padNumber(currentDate.getMinutes(), 2);
3446 - newAutoBackupFile = path.join(backupPath, ((typeof parent.config.settings.autobackup.backupname == 'string') ? parent.config.settings.autobackup.backupname : 'meshcentral-autobackup-') + fileSuffix + '.zip');
3446 + obj.newAutoBackupFile = path.join(backupPath, ((typeof parent.config.settings.autobackup.backupname == 'string') ? parent.config.settings.autobackup.backupname : 'meshcentral-autobackup-') + fileSuffix + '.zip');
3447
3448 if ((obj.databaseType == DB_MONGOJS) || (obj.databaseType == DB_MONGODB)) {
3449 // Perform a MongoDump in the datadir
3450 const dbname = (parent.args.mongodbname) ? (parent.args.mongodbname) : 'meshcentral';
3451 const dburl = parent.args.mongodb;
3452
3453 - //const newDBDumpFile = 'mongodump-' + fileSuffix;
3454 - newDBDumpFile = path.join(backupPath, (dbname + '-mongodump-' + fileSuffix + '.archive'));
3453 + //const obj.newDBDumpFile = 'mongodump-' + fileSuffix;
3454 + obj.newDBDumpFile = path.join(backupPath, (dbname + '-mongodump-' + fileSuffix + '.archive'));
3455
3456 var cmd = buildMongoDumpCommand();
3457 - cmd += (dburl) ? ' --archive=\"' + newDBDumpFile + '\"' :
3458 - ' --db=\"' + dbname + '\" --archive=\"' + newDBDumpFile + '\"';
3457 + cmd += (dburl) ? ' --archive=\"' + obj.newDBDumpFile + '\"' :
3458 + ' --db=\"' + dbname + '\" --archive=\"' + obj.newDBDumpFile + '\"';
3459
3460 const child_process = require('child_process');
3461 const dumpProcess = child_process.exec(
3462 cmd,
3463 { cwd: parent.parentpath },
3464 - (error)=> {if (error) {backupStatus |= BACKUPFAIL_DBDUMP; console.log('ERROR: Unable to perform MongoDB backup: ' + error + '\r\n'); obj.createBackupfile(func);}}
3464 + (error)=> {if (error) {obj.backupStatus |= BACKUPFAIL_DBDUMP; console.log('ERROR: Unable to perform MongoDB backup: ' + error + '\r\n'); obj.createBackupfile(func);}}
3465 );
3466 dumpProcess.on('exit', (code) => {
3467 - if (code != 0) {console.log(`Mongodump child process exited with code ${code}`); backupStatus |= BACKUPFAIL_DBDUMP;}
3467 + if (code != 0) {console.log(`Mongodump child process exited with code ${code}`); obj.backupStatus |= BACKUPFAIL_DBDUMP;}
3468 obj.createBackupfile(func);
3469 });
3470
3471 } else if ((obj.databaseType == DB_MARIADB) || (obj.databaseType == DB_MYSQL)) {
3472 // Perform a MySqlDump backup
3473 const newBackupFile = 'mysqldump-' + fileSuffix;
3474 - newDBDumpFile = path.join(backupPath, newBackupFile + '.sql');
3474 + obj.newDBDumpFile = path.join(backupPath, newBackupFile + '.sql');
3475
3476 var cmd = buildSqlDumpCommand();
3477 - cmd += ' --result-file=\"' + newDBDumpFile + '\"';
3477 + cmd += ' --result-file=\"' + obj.newDBDumpFile + '\"';
3478
3479 const child_process = require('child_process');
3480 const dumpProcess = child_process.exec(
3481 cmd,
3482 { cwd: parent.parentpath },
3483 - (error)=> {if (error) {backupStatus |= BACKUPFAIL_DBDUMP; console.log('ERROR: Unable to perform MySQL backup: ' + error + '\r\n'); obj.createBackupfile(func);}}
3483 + (error)=> {if (error) {obj.backupStatus |= BACKUPFAIL_DBDUMP; console.log('ERROR: Unable to perform MySQL backup: ' + error + '\r\n'); obj.createBackupfile(func);}}
3484 );
3485 dumpProcess.on('exit', (code) => {
3486 - if (code != 0) {console.log(`MySQLdump child process exited with code ${code}`); backupStatus |= BACKUPFAIL_DBDUMP;}
3486 + if (code != 0) {console.log(`MySQLdump child process exited with code ${code}`); obj.backupStatus |= BACKUPFAIL_DBDUMP;}
3487 obj.createBackupfile(func);
3488 });
3489
3490 } else if (obj.databaseType == DB_SQLITE) {
3491 //.db3 suffix to escape escape backupfile glob to exclude the sqlite db files
3492 - newDBDumpFile = path.join(backupPath, databaseName + '-sqlitedump-' + fileSuffix + '.db3');
3492 + obj.newDBDumpFile = path.join(backupPath, databaseName + '-sqlitedump-' + fileSuffix + '.db3');
3493 /*undocumented in node-sqlite3 API, check https://github.com/TryGhost/node-sqlite3/blob/593c9d498be2510d286349134537e3bf89401c4a/test/backup.test.js
3494 - var backup = obj.file.backup(newDBDumpFile);
3494 + var backup = obj.file.backup(obj.newDBDumpFile);
3495 backup.step(-1, function (err) {
3496 - if (err) { console.log('SQLite start-backup error: ' + err); backupStatus |=BACKUPFAIL_DBDUMP; obj.createBackupfile(func); };
3496 + if (err) { console.log('SQLite start-backup error: ' + err); obj.backupStatus |=BACKUPFAIL_DBDUMP; obj.createBackupfile(func); };
3497 backup.finish(function (err) {
3498 - if (err) { console.log('SQLite backup error: ' + err); backupStatus |=BACKUPFAIL_DBDUMP;};
3498 + if (err) { console.log('SQLite backup error: ' + err); obj.backupStatus |=BACKUPFAIL_DBDUMP;};
3499 obj.createBackupfile(func);
3500 });
3501 });
3502 */
3503 // do a VACUUM INTO in favor of the backup API to compress the export, see https://www.sqlite.org/backup.html
3504 - obj.file.exec('VACUUM INTO \'' + newDBDumpFile + '\'', function (err) {
3505 - if (err) { console.log('SQLite start-backup error: ' + err); backupStatus |=BACKUPFAIL_DBDUMP;};
3504 + obj.file.exec('VACUUM INTO \'' + obj.newDBDumpFile + '\'', function (err) {
3505 + if (err) { console.log('SQLite start-backup error: ' + err); obj.backupStatus |=BACKUPFAIL_DBDUMP;};
3506 //always finish/clean up
3507 obj.createBackupfile(func);
3508 });
3509 } else if (obj.databaseType == DB_POSTGRESQL) {
3510 // Perform a PostgresDump backup
3511 const newBackupFile = databaseName + '-pgdump-' + fileSuffix + '.sql';
3512 - newDBDumpFile = path.join(backupPath, newBackupFile);
3512 + obj.newDBDumpFile = path.join(backupPath, newBackupFile);
3513 let cmd = '"' + parent.config.settings.autobackup.pgdumppath + '"'
3514 + ' --dbname=postgresql://' + parent.config.settings.postgres.user + ":" +parent.config.settings.postgres.password
3515 + "@" + parent.config.settings.postgres.host + ":" + parent.config.settings.postgres.port + "/" + databaseName
3516 - + " --file=" + newDBDumpFile;
3516 + + " --file=" + obj.newDBDumpFile;
3517 const child_process = require('child_process');
3518 const dumpProcess = child_process.exec(
3519 cmd,
3520 { cwd: dataPath },
3521 - (error)=> {if (error) {backupStatus |= BACKUPFAIL_DBDUMP; console.log('ERROR: Unable to perform PostgreSQL dump: ' + error.message + '\r\n'); obj.createBackupfile(func);}}
3521 + (error)=> {if (error) {obj.backupStatus |= BACKUPFAIL_DBDUMP; console.log('ERROR: Unable to perform PostgreSQL dump: ' + error.message + '\r\n'); obj.createBackupfile(func);}}
3522 );
3523 dumpProcess.on('exit', (code) => {
3524 - if (code != 0) {console.log(`PostgreSQLdump child process exited with code: ` + code); backupStatus |= BACKUPFAIL_DBDUMP;}
3524 + if (code != 0) {console.log(`PostgreSQLdump child process exited with code: ` + code); obj.backupStatus |= BACKUPFAIL_DBDUMP;}
3525 obj.createBackupfile(func);
3526 });
3527 } else {
@@ -3544,7 +3544,7 @@ module.exports.CreateDB = function (parent, func) {
3544 archive = archiver.create('zip-encrypted', { zlib: { level: 9 }, encryptionMethod: 'aes256', password: parent.config.settings.autobackup.zippassword });
3545 if (func) { func('Creating encrypted ZIP'); }
3546 } catch (ex) { // registering encryption failed, do not fall back to non-encrypted, fail backup and skip old backup removal as a precaution to not lose any backups
3547 - backupStatus |= BACKUPFAIL_ZIPMODULE;
3547 + obj.backupStatus |= BACKUPFAIL_ZIPMODULE;
3548 if (func) { func('Zipencryptionmodule failed, aborting'); }
3549 console.log('Zipencryptionmodule failed, aborting');
3550 }
@@ -3553,17 +3553,17 @@ module.exports.CreateDB = function (parent, func) {
3553 archive = archiver('zip', { zlib: { level: 9 } });
3554 }
3555
3556 - //original behavior, just a filebackup if dbdump fails : (backupStatus == 0 || backupStatus == BACKUPFAIL_DBDUMP)
3557 - if (backupStatus == 0) {
3556 + //original behavior, just a filebackup if dbdump fails : (obj.backupStatus == 0 || obj.backupStatus == BACKUPFAIL_DBDUMP)
3557 + if (obj.backupStatus == 0) {
3558 // Zip the data directory with the dbdump|NeDB files
3559 - let output = parent.fs.createWriteStream(newAutoBackupFile);
3559 + let output = parent.fs.createWriteStream(obj.newAutoBackupFile);
3560 output.on('close', function () {
3561 - if (backupStatus == 0) {
3561 + if (obj.backupStatus == 0) {
3562 //remove dump archive file, because zipped and otherwise fills up
3563 if (obj.databaseType != DB_NEDB) {
3564 - try { parent.fs.unlink(newDBDumpFile, function () { }); } catch (ex) {console.log('Failed to clean up dbdump file')};
3564 + try { parent.fs.unlink(obj.newDBDumpFile, function () { }); } catch (ex) {console.log('Failed to clean up dbdump file')};
3565 };
3566 - obj.performCloudBackup(newAutoBackupFile, func);
3566 + obj.performCloudBackup(obj.newAutoBackupFile, func);
3567 // Remove old backups
3568 if (parent.config.settings.autobackup && (typeof parent.config.settings.autobackup.keeplastdaysbackup == 'number')) {
3569 let cutoffDate = new Date();
@@ -3589,19 +3589,19 @@ module.exports.CreateDB = function (parent, func) {
3589 console.log('Auto-backup completed.');
3590 if (func) { func('Auto-backup completed.'); };
3591 } else {
3592 - console.log('Zipbackup failed ('+ (+backupStatus).toString(16).slice(-4) + '), deleting incomplete backup: ' + newAutoBackupFile );
3593 - if (func) { func('Zipbackup failed ('+ (+backupStatus).toString(16).slice(-4) + '), deleting incomplete backup: ' + newAutoBackupFile) };
3594 - try { parent.fs.unlink(newAutoBackupFile, function () { }); parent.fs.unlink(newDBDumpFile, function () { }); } catch (ex) {console.log('Failed to delete incomplete backup files')};
3592 + console.log('Zipbackup failed ('+ (+obj.backupStatus).toString(16).slice(-4) + '), deleting incomplete backup: ' + obj.newAutoBackupFile );
3593 + if (func) { func('Zipbackup failed ('+ (+obj.backupStatus).toString(16).slice(-4) + '), deleting incomplete backup: ' + obj.newAutoBackupFile) };
3594 + try { parent.fs.unlink(obj.newAutoBackupFile, function () { }); parent.fs.unlink(obj.newDBDumpFile, function () { }); } catch (ex) {console.log('Failed to delete incomplete backup files')};
3595 };
3596 obj.performingBackup = false;
3597 - backupStatus = 0x0;
3597 + obj.backupStatus = 0x0;
3598 });
3599 output.on('end', function () { });
3600 output.on('error', function (err) {
3601 - if ((backupStatus & BACKUPFAIL_ZIPCREATE) == 0) {
3601 + if ((obj.backupStatus & BACKUPFAIL_ZIPCREATE) == 0) {
3602 console.log('Output error: ' + err);
3603 if (func) { func('Output error: ' + err); };
3604 - backupStatus |= BACKUPFAIL_ZIPCREATE;
3604 + obj.backupStatus |= BACKUPFAIL_ZIPCREATE;
3605 archive.abort();
3606 };
3607 });
@@ -3609,18 +3609,18 @@ module.exports.CreateDB = function (parent, func) {
3609 //if files added to the archiver object aren't reachable anymore (e.g. sqlite-journal files)
3610 //an ENOENT warning is given, but the archiver module has no option to/does not skip/resume
3611 //so the backup needs te be aborted as it otherwise leaves an incomplete zip and never 'ends'
3612 - if ((backupStatus & BACKUPFAIL_ZIPCREATE) == 0) {
3612 + if ((obj.backupStatus & BACKUPFAIL_ZIPCREATE) == 0) {
3613 console.log('Zip warning: ' + err);
3614 if (func) { func('Zip warning: ' + err); };
3615 - backupStatus |= BACKUPFAIL_ZIPCREATE;
3615 + obj.backupStatus |= BACKUPFAIL_ZIPCREATE;
3616 archive.abort();
3617 };
3618 });
3619 archive.on('error', function (err) {
3620 - if ((backupStatus & BACKUPFAIL_ZIPCREATE) == 0) {
3620 + if ((obj.backupStatus & BACKUPFAIL_ZIPCREATE) == 0) {
3621 console.log('Zip error: ' + err);
3622 if (func) { func('Zip error: ' + err); };
3623 - backupStatus |= BACKUPFAIL_ZIPCREATE;
3623 + obj.backupStatus |= BACKUPFAIL_ZIPCREATE;
3624 archive.abort();
3625 }
3626 });
@@ -3648,15 +3648,15 @@ module.exports.CreateDB = function (parent, func) {
3648 archive.directory(parent.recordpath, 'meshcentral-recordings');
3649 };
3650 //add dbdump to the root of the zip
3651 - archive.file(newDBDumpFile, { name: path.basename(newDBDumpFile) });
3651 + if (obj.newDBDumpFile != null) archive.file(obj.newDBDumpFile, { name: path.basename(obj.newDBDumpFile) });
3652 archive.finalize();
3653 } else {
3654 //failed somewhere before zipping
3655 - console.log('Backup failed ('+ (+backupStatus).toString(16).slice(-4) + ')');
3656 - if (func) { func('Backup failed ('+ (+backupStatus).toString(16).slice(-4) + ')') };
3655 + console.log('Backup failed ('+ (+obj.backupStatus).toString(16).slice(-4) + ')');
3656 + if (func) { func('Backup failed ('+ (+obj.backupStatus).toString(16).slice(-4) + ')') };
3657 //Just in case something's there
3658 - try { parent.fs.unlink(newDBDumpFile, function () { }); } catch (ex) { };
3659 - backupStatus = 0x0;
3658 + try { parent.fs.unlink(obj.newDBDumpFile, function () { }); } catch (ex) { };
3659 + obj.backupStatus = 0x0;
3660 obj.performingBackup = false;
3661 };
3662 };