UNPKG

iobroker.backitup

Version:

ioBroker.backitup allows you to backup and restore your ioBroker installation and other systems, such as databases, Zigbee, scripts and many more.

134 lines (120 loc) 4.81 kB
const fs = require('node:fs'); const path = require('node:path'); function replaySqlite(options, fileNameSQlite, log, callback) { const { exec } = require('node:child_process'); if (options && options.filePth && fs.existsSync(options.filePth)) { try { fs.unlinkSync(options.filePth); log.debug('old sqlite db deleted!'); } catch (e) { log.debug(`sqlite db cannot deleted: ${e}`); callback && callback(e); } } const cmdRestore = `${options.exe ? options.exe : 'sqlite3'} ${options.filePth} < ${fileNameSQlite}`; try { exec(cmdRestore, (error, stdout, stderr) => { if (error) log.error(stderr); return callback && callback(error); }); } catch (e) { // ignore errors } } function restore(options, fileName, log, adapter, callback) { const fileNameSQlite = path.join(options.backupDir, `sqlite_restore_backupiobroker.sql`); log.debug('Start sqlite Restore ...'); // stop sql-Adapter before Restore let startAfterRestore = false; let enabledInstances = []; adapter.getObjectView('system', 'instance', { startkey: 'system.adapter.sql.', endkey: 'system.adapter.sql.\u9999' }, async (err, instances) => { let resultInstances = []; if (!err && instances && instances.rows) { instances.rows.forEach(row => { resultInstances.push({ id: row.id.replace('system.adapter.', ''), config: row.value.native.type }) }); for (let i = 0; i < resultInstances.length; i++) { let _id = resultInstances[i].id; // Stop sql Instances adapter.getForeignObject(`system.adapter.${_id}`, (err, obj) => { if (obj?.common?.enabled) { adapter.setForeignState(`system.adapter.${_id}.alive`, false); log.debug(`${_id} is stopped`); enabledInstances.push(_id); startAfterRestore = true; } }); } } else { log.debug('Could not retrieve sql instances!'); } }); let timer = setInterval(() => { if (fs.existsSync(fileNameSQlite)) { const stats = fs.statSync(fileNameSQlite); const fileSize = Math.floor(stats.size / (1024 * 1024)); log.debug(`Extract sqlite Backup file ${fileSize}MB so far...`); } else { log.debug(`Something is wrong with "${fileNameSQlite}".`); } }, 10000); const decompress = require('../targz').decompress; try { decompress({ src: fileName, dest: options.backupDir, tar: { map: header => { header.name = `sqlite_restore_backupiobroker.sql`; return header; } } }, (err, stdout, stderr) => { clearInterval(timer); if (err) { log.error(err); if (callback) { log.error('sqlite Restore not completed'); callback(err, stderr); callback = null; } } else { replaySqlite(options, fileNameSQlite, log, err => { // Start sql Instances if (startAfterRestore) { enabledInstances.forEach(enabledInstance => { adapter.getForeignObject(`system.adapter.${enabledInstance}`, (err, obj) => { if (obj && !obj.common?.enabled) { adapter.setForeignState(`system.adapter.${enabledInstance}.alive`, true); log.debug(`${enabledInstance} started`); } }); }); } // delete sqlite file if (fs.existsSync(fileNameSQlite)) { try { fs.unlinkSync(fileNameSQlite); } catch (e) { log.debug(`${fileNameSQlite} cannot deleted ...`); } } if (callback) { log.debug('sqlite Restore completed successfully'); callback(null, 'sqlite restore done'); callback = null; } }); } }); } catch (err) { if (callback) { callback(err); callback = null; } } } module.exports = { restore, isStop: false, };