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.

128 lines (110 loc) 5.1 kB
'use strict'; const fs = require('node:fs'); const _fs = require('node:fs').promises; const getDate = require('../tools').getDate; const path = require('node:path'); async function command(options, log, callback) { log.debug('Start SQLite3 Backup ...'); // stop sql-Adapter before Backup let startAfterBackup = false; let enabledInstances = []; let resultInstances = []; const instances = await options.adapter.getObjectViewAsync('system', 'instance', { startkey: 'system.adapter.sql.', endkey: 'system.adapter.sql.\u9999' }) .catch(err => log.error(err)); if (instances && instances.rows) { instances.rows.forEach(async 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; const obj = await options.adapter.getForeignObjectAsync(`system.adapter.${_id}`) .catch(err => log.error(err)); if (obj?.common?.enabled) { await options.adapter.setForeignStateAsync(`system.adapter.${_id}.alive`, false) .then(() => log.debug(`${_id} is stopped`)) .catch(err => log.error(err)); enabledInstances.push(_id); startAfterBackup = true; } } } else { log.warn('Could not retrieve sql instances!'); } const nameSuffix = options.hostType === 'Slave' && options.slaveSuffix ? options.slaveSuffix : options.hostType !== 'Slave' && options.nameSuffix ? options.nameSuffix : ''; const fileName = path.join(options.backupDir, `sqlite_${getDate()}${nameSuffix ? `_${nameSuffix}` : ''}_backupiobroker.tar.gz`); const fileNameSQlite = path.join(options.backupDir, `sqlite_${getDate()}_backupiobroker.sql`); options.context.fileNames.push(fileName); let timer = setInterval(async () => { if (fs.existsSync(fileName)) { const stats = fs.statSync(fileName); const fileSize = Math.floor(stats.size / (1024 * 1024)); log.debug(`Packed ${fileSize}MB so far...`); } }, 10000); const compress = require('../targz').compress; const child_process = require('node:child_process'); try { child_process.exec(`${options.exe ? options.exe : 'sqlite3'} ${options.filePth} .dump > ${fileNameSQlite}`, async (error) => { if (error) { clearInterval(timer); options.context.errors.sqlite = error.toString(); error && log.error(error); if (callback) { callback(error); } } else { compress({ src: fileNameSQlite, dest: fileName, tar: { map: header => { header.name = fileNameSQlite.split('/').pop(); return header; } } }, async (err, stdout, stderr) => { clearInterval(timer); if (err) { options.context.errors.sqlite = err.toString(); stderr && log.error(stderr); if (callback) { callback(err, stderr); } } else { // Start sql Instances if (startAfterBackup) { for (let i = 0; i < enabledInstances.length; i++) { await options.adapter.setForeignStateAsync(`system.adapter.${enabledInstances[i]}.alive`, true) .then(() => log.debug(`${enabledInstances[i]} started`)) .catch(err => log.error(`${enabledInstances[i]} not started: ${err}`)); } } log.debug(`Backup created: ${fileName}`); options.context.done.push('sqlite'); options.context.types.push('sqlite'); if (fs.existsSync(fileNameSQlite)) { try { await _fs.unlink(fileNameSQlite); log.debug('sqlite File deleted!'); } catch (e) { log.warn(`sqlite File cannot deleted: ${e}`); callback && callback(err); } } if (callback) { callback(null, stdout); callback = null; } } }); } }); } catch (err) { clearInterval(timer); callback && callback(err); callback = null; } } module.exports = { command, ignoreErrors: true };