add backup targets table
This commit is contained in:
+80
-15
@@ -41,6 +41,8 @@ exports = module.exports = {
|
||||
getMountStatus,
|
||||
ensureMounted,
|
||||
|
||||
_addDefaultTarget: addDefaultTarget,
|
||||
|
||||
BACKUP_IDENTIFIER_BOX: 'box',
|
||||
BACKUP_IDENTIFIER_MAIL: 'mail',
|
||||
|
||||
@@ -71,9 +73,12 @@ const assert = require('assert'),
|
||||
settings = require('./settings.js'),
|
||||
storage = require('./storage.js'),
|
||||
tasks = require('./tasks.js'),
|
||||
uuid = require('uuid'),
|
||||
_ = require('./underscore.js');
|
||||
|
||||
const BACKUPS_FIELDS = [ 'id', 'remotePath', 'label', 'identifier', 'creationTime', 'packageVersion', 'type', 'dependsOnJson', 'state', 'manifestJson', 'format', 'preserveSecs', 'encryptionVersion', 'appConfigJson' ];
|
||||
const BACKUPS_FIELDS = [ 'id', 'remotePath', 'label', 'identifier', 'creationTime', 'packageVersion', 'type', 'dependsOnJson', 'state', 'manifestJson', 'format', 'preserveSecs', 'encryptionVersion', 'appConfigJson' ].join(',');
|
||||
|
||||
const BACKUP_TARGET_FIELDS = [ 'id', 'label', 'configJson', 'limitsJson', 'retentionJson', 'schedule', 'encryptionJson', 'format', 'priority', 'creationTime', 'ts' ].join(',');
|
||||
|
||||
function postProcess(result) {
|
||||
assert.strictEqual(typeof result, 'object');
|
||||
@@ -90,6 +95,26 @@ function postProcess(result) {
|
||||
return result;
|
||||
}
|
||||
|
||||
function postProcessTarget(result) {
|
||||
assert.strictEqual(typeof result, 'object');
|
||||
|
||||
result.config = result.configJson ? safe.JSON.parse(result.configJson) : {};
|
||||
delete result.configJson;
|
||||
|
||||
result.limits = result.limitsJson ? safe.JSON.parse(result.limitsJson) : {};
|
||||
delete result.limitsJson;
|
||||
|
||||
result.retention = result.retentionJson ? safe.JSON.parse(result.retentionJson) : {};
|
||||
delete result.retentionJson;
|
||||
|
||||
result.encryption = result.encryptionJson ? safe.JSON.parse(result.encryptionJson) : null;
|
||||
delete result.encryptionJson;
|
||||
|
||||
result.priority = !!result.priority;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
function removePrivateFields(backupConfig) {
|
||||
assert.strictEqual(typeof backupConfig, 'object');
|
||||
if (backupConfig.encryption) {
|
||||
@@ -403,11 +428,9 @@ async function ensureMounted() {
|
||||
}
|
||||
|
||||
async function getPolicy() {
|
||||
const result = await settings.getJson(settings.BACKUP_POLICY_KEY);
|
||||
return result || {
|
||||
retention: { keepWithinSecs: 2 * 24 * 60 * 60 }, // 2 days
|
||||
schedule: '00 00 23 * * *' // every day at 11pm
|
||||
};
|
||||
const results = await database.query(`SELECT ${BACKUP_TARGET_FIELDS} FROM backupTargets WHERE priority=?`, [ true ]);
|
||||
const result = postProcessTarget(results[0]);
|
||||
return { retention: result.retention, schedule: result.schedule };
|
||||
}
|
||||
|
||||
async function setPolicy(policy) {
|
||||
@@ -416,7 +439,8 @@ async function setPolicy(policy) {
|
||||
const error = await validatePolicy(policy);
|
||||
if (error) throw error;
|
||||
|
||||
await settings.setJson(settings.BACKUP_POLICY_KEY, policy);
|
||||
await updateTarget(policy);
|
||||
|
||||
await cron.handleBackupPolicyChanged(policy);
|
||||
}
|
||||
|
||||
@@ -435,19 +459,60 @@ function getRootPath(storageConfig, mountPath) {
|
||||
}
|
||||
}
|
||||
|
||||
async function updateTarget(data) {
|
||||
assert(data && typeof data === 'object');
|
||||
|
||||
const args = [];
|
||||
const fields = [];
|
||||
for (const k in data) {
|
||||
if (k === 'label' || k === 'schedule' || k === 'format' || k === 'priority') {
|
||||
fields.push(k + ' = ?');
|
||||
args.push(data[k]);
|
||||
} else if (k === 'config' || k === 'limits' || k === 'retention' || k === 'encryption') {
|
||||
fields.push(`${k}JSON = ?`);
|
||||
args.push(JSON.stringify(data[k]));
|
||||
}
|
||||
}
|
||||
args.push(true); // primary flag
|
||||
|
||||
const [updateError, result] = await safe(database.query('UPDATE backupTargets SET ' + fields.join(', ') + ' WHERE priority = ?', args));
|
||||
if (updateError) throw updateError;
|
||||
if (result.affectedRows !== 1) throw new BoxError(BoxError.NOT_FOUND, 'Target not found');
|
||||
}
|
||||
|
||||
async function addDefaultTarget() {
|
||||
const label = '', priority = true;
|
||||
const limits = null, encryption = null;
|
||||
const retention = { keepWithinSecs: 2 * 24 * 60 * 60 };
|
||||
const schedule = '00 00 23 * * *';;
|
||||
const config = { provider: 'filesystem', backupFolder: paths.DEFAULT_BACKUP_DIR };
|
||||
const format = 'tgz';
|
||||
|
||||
await database.query('INSERT INTO backupTargets (id, label, configJson, limitsJson, retentionJson, schedule, encryptionJson, format, priority) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)',
|
||||
[ `bc-${uuid.v4()}`, label, JSON.stringify(config), JSON.stringify(limits), JSON.stringify(retention), schedule, JSON.stringify(encryption), format, priority ]);
|
||||
}
|
||||
|
||||
async function getConfig() {
|
||||
const result = await settings.getJson(settings.BACKUP_STORAGE_KEY) || { provider: 'filesystem', backupFolder: paths.DEFAULT_BACKUP_DIR, format: 'tgz', encryption: null };
|
||||
const limits = await settings.getJson(settings.BACKUP_LIMITS_KEY);
|
||||
if (limits) result.limits = limits;
|
||||
result.rootPath = getRootPath(result, paths.MANAGED_BACKUP_MOUNT_DIR); // note: rootPath will be dynamic for managed mount providers during app import
|
||||
return result;
|
||||
const results = await database.query(`SELECT ${BACKUP_TARGET_FIELDS} FROM backupTargets WHERE priority=?`, [ true ]);
|
||||
const result = postProcessTarget(results[0]);
|
||||
|
||||
const config = result.config;
|
||||
config.format = result.format;
|
||||
config.encryption = result.encryption;
|
||||
config.rootPath = getRootPath(config, paths.MANAGED_BACKUP_MOUNT_DIR); // note: rootPath will be dynamic for managed mount providers during app import
|
||||
|
||||
return config;
|
||||
}
|
||||
|
||||
async function setConfig(backupConfig) {
|
||||
assert.strictEqual(typeof backupConfig, 'object');
|
||||
|
||||
await settings.setJson(settings.BACKUP_STORAGE_KEY, _.omit(backupConfig, ['limits']));
|
||||
await settings.setJson(settings.BACKUP_LIMITS_KEY, backupConfig.limits || null);
|
||||
await updateTarget({
|
||||
config: _.omit(backupConfig, ['limits', 'format', 'encryption']),
|
||||
format: backupConfig.format,
|
||||
encryption: backupConfig.encryption || null,
|
||||
limits: backupConfig.limits || null
|
||||
});
|
||||
}
|
||||
|
||||
async function setLimits(limits) {
|
||||
@@ -529,5 +594,5 @@ async function setStorage(storageConfig) {
|
||||
debug('setStorage: clearing backup cache');
|
||||
cleanupCacheFilesSync();
|
||||
|
||||
await settings.setJson(settings.BACKUP_STORAGE_KEY, storageConfig);
|
||||
await setConfig(storageConfig);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user