diff --git a/migrations/20200512172301-settings-backup-encryption.js b/migrations/20200512172301-settings-backup-encryption.js index dc3697188..961e01df9 100644 --- a/migrations/20200512172301-settings-backup-encryption.js +++ b/migrations/20200512172301-settings-backup-encryption.js @@ -1,6 +1,6 @@ 'use strict'; -const backups = require('../src/backups.js'), +const backupTargets = require('../src/backuptargets.js'), fs = require('fs'); exports.up = function(db, callback) { @@ -9,8 +9,8 @@ exports.up = function(db, callback) { var backupConfig = JSON.parse(results[0].value); if (backupConfig.key) { - backupConfig.encryption = backups.generateEncryptionKeysSync(backupConfig.key); - backups.cleanupCacheFilesSync(); + backupConfig.encryption = backupTargets.generateEncryptionKeysSync(backupConfig.key); + backupTargets.cleanupCacheFilesSync(); fs.writeFileSync('/home/yellowtent/platformdata/BACKUP_PASSWORD', 'This file contains your Cloudron backup password.\nBefore Cloudron v5.2, this was saved in the database.' + diff --git a/src/apps.js b/src/apps.js index 504a3e513..862b9d708 100644 --- a/src/apps.js +++ b/src/apps.js @@ -152,7 +152,7 @@ const appTaskManager = require('./apptaskmanager.js'), archives = require('./archives.js'), assert = require('assert'), backupListing = require('./backuplisting.js'), - backups = require('./backups.js'), + backupTargets = require('./backuptargets.js'), BoxError = require('./boxerror.js'), constants = require('./constants.js'), { CronTime } = require('cron'), @@ -1259,7 +1259,7 @@ async function scheduleTask(appId, installationState, taskId, auditSource) { assert.strictEqual(typeof taskId, 'string'); assert.strictEqual(typeof auditSource, 'object'); - const backupConfig = await backups.getConfig(); + const backupConfig = await backupTargets.getConfig(); let memoryLimit = 400; if (installationState === exports.ISTATE_PENDING_CLONE || installationState === exports.ISTATE_PENDING_RESTORE @@ -2359,19 +2359,19 @@ async function importApp(app, data, auditSource) { let restoreConfig; if (data.remotePath) { // if not provided, we import in-place - error = backups.validateFormat(backupFormat); + error = backupTargets.validateFormat(backupFormat); if (error) throw error; if ('password' in backupConfig) { - backupConfig.encryption = backups.generateEncryptionKeysSync(backupConfig.password); + backupConfig.encryption = backupTargets.generateEncryptionKeysSync(backupConfig.password); delete backupConfig.password; } else { backupConfig.encryption = null; } - await backups.setupManagedStorage(backupConfig, `/mnt/appimport-${app.id}`); // this validates mountOptions . this is not cleaned up, it's fine - backupConfig.rootPath = backups.getRootPath(backupConfig, `/mnt/appimport-${app.id}`); - error = await backups.testStorage(Object.assign({ mountPath: `/mnt/appimport-${app.id}` }, backupConfig)); // this validates provider and it's api options. requires mountPath + await backupTargets.setupManagedStorage(backupConfig, `/mnt/appimport-${app.id}`); // this validates mountOptions . this is not cleaned up, it's fine + backupConfig.rootPath = backupTargets.getRootPath(backupConfig, `/mnt/appimport-${app.id}`); + error = await backupTargets.testStorage(Object.assign({ mountPath: `/mnt/appimport-${app.id}` }, backupConfig)); // this validates provider and it's api options. requires mountPath if (error) throw error; restoreConfig = { remotePath, backupFormat, backupConfig }; @@ -2780,7 +2780,7 @@ async function backup(app, auditSource) { const taskId = await tasks.add(`${tasks.TASK_APP_BACKUP_PREFIX}${app.id}`, [ app.id, { snapshotOnly: false } ]); - const backupConfig = await backups.getConfig(); + const backupConfig = await backupTargets.getConfig(); const memoryLimit = backupConfig.limits?.memoryLimit ? Math.max(backupConfig.limits.memoryLimit/1024/1024, 1024) : 1024; // background @@ -2830,7 +2830,7 @@ async function getBackupDownloadStream(app, backupId) { if (backup.identifier !== app.id) throw new BoxError(BoxError.NOT_FOUND, 'Backup not found'); // some other app's backup if (backup.format !== 'tgz') throw new BoxError(BoxError.BAD_STATE, 'only tgz backups can be downloaded'); - const backupConfig = await backups.getConfig(); + const backupConfig = await backupTargets.getConfig(); const ps = new PassThrough(); diff --git a/src/apptask.js b/src/apptask.js index 26895a719..f699f497d 100644 --- a/src/apptask.js +++ b/src/apptask.js @@ -15,7 +15,7 @@ const apps = require('./apps.js'), appstore = require('./appstore.js'), assert = require('assert'), AuditSource = require('./auditsource.js'), - backups = require('./backups.js'), + backupTargets = require('./backuptargets.js'), backuptask = require('./backuptask.js'), BoxError = require('./boxerror.js'), constants = require('./constants.js'), @@ -332,9 +332,9 @@ async function installCommand(app, args, progressCallback) { await services.setupAddons(app, app.manifest.addons); await services.clearAddons(app, app.manifest.addons); const backupConfig = restoreConfig.backupConfig; - const mountObject = await backups.setupManagedStorage(backupConfig, `/mnt/appimport-${app.id}`); + const mountObject = await backupTargets.setupManagedStorage(backupConfig, `/mnt/appimport-${app.id}`); if (mountObject) await progressCallback({ percent: 70, message: 'Setting up mount for importing' }); - backupConfig.rootPath = backups.getRootPath(backupConfig, `/mnt/appimport-${app.id}`); + backupConfig.rootPath = backupTargets.getRootPath(backupConfig, `/mnt/appimport-${app.id}`); await backuptask.downloadApp(app, restoreConfig, (progress) => { progressCallback({ percent: 75, message: progress.message }); }); await apps.loadConfig(app); if (mountObject) await mounts.removeMount(mountObject); diff --git a/src/backupcleaner.js b/src/backupcleaner.js index 0a59782d2..913f69ecb 100644 --- a/src/backupcleaner.js +++ b/src/backupcleaner.js @@ -13,7 +13,7 @@ const apps = require('./apps.js'), assert = require('assert'), backupFormat = require('./backupformat.js'), backupListing = require('./backuplisting.js'), - backups = require('./backups.js'), + backupTargets = require('./backuptargets.js'), constants = require('./constants.js'), debug = require('debug')('box:backupcleaner'), moment = require('moment'), @@ -183,7 +183,7 @@ async function cleanupBoxBackups(backupConfig, retention, progressCallback) { let referencedBackupIds = []; const removedBoxBackupPaths = []; - // We need to fetch all box backups to be able to compile a list of all referenced app backups. + // We need to fetch all box backups to be able to compile a list of all referenced app backupTargets. // Otherwise if we miss some app backups, they will get purged! // 100000 here should be seen as infinity const boxBackups = await backupListing.getByTypePaged(backupListing.BACKUP_TYPE_BOX, 1, 100000); @@ -271,7 +271,7 @@ async function cleanupSnapshots(backupConfig) { safe.fs.unlinkSync(path.join(paths.BACKUP_INFO_DIR, `${appId}.sync.cache`)); safe.fs.unlinkSync(path.join(paths.BACKUP_INFO_DIR, `${appId}.sync.cache.new`)); - await safe(backups.setSnapshotInfo(appId, null /* info */), { debug }); + await safe(backupTargets.setSnapshotInfo(appId, null /* info */), { debug }); debug(`cleanupSnapshots: cleaned up snapshot of app ${appId}`); } @@ -281,11 +281,11 @@ async function cleanupSnapshots(backupConfig) { async function run(progressCallback) { assert.strictEqual(typeof progressCallback, 'function'); - const backupConfig = await backups.getConfig(); - const { retention } = await backups.getPolicy(); + const backupConfig = await backupTargets.getConfig(); + const { retention } = await backupTargets.getPolicy(); debug(`run: retention is ${JSON.stringify(retention)}`); - const status = await backups.ensureMounted(); + const status = await backupTargets.ensureMounted(); debug(`run: mount point status is ${JSON.stringify(status)}`); if (status.state !== 'active') throw new BoxError(BoxError.MOUNT_ERROR, `Backup endpoint is not mounted: ${status.message}`); diff --git a/src/backups.js b/src/backuptargets.js similarity index 98% rename from src/backups.js rename to src/backuptargets.js index d3be0f843..94de7edf0 100644 --- a/src/backups.js +++ b/src/backuptargets.js @@ -35,17 +35,6 @@ exports = module.exports = { ensureMounted, _addDefaultTarget: addDefaultTarget, - - BACKUP_IDENTIFIER_BOX: 'box', - BACKUP_IDENTIFIER_MAIL: 'mail', - - BACKUP_TYPE_APP: 'app', - BACKUP_TYPE_BOX: 'box', - BACKUP_TYPE_MAIL: 'mail', - - BACKUP_STATE_NORMAL: 'normal', // should rename to created to avoid listing in UI? - BACKUP_STATE_CREATING: 'creating', - BACKUP_STATE_ERROR: 'error', }; const assert = require('assert'), diff --git a/src/backuptask.js b/src/backuptask.js index 5d4eed79c..64c7b2d6d 100644 --- a/src/backuptask.js +++ b/src/backuptask.js @@ -19,7 +19,7 @@ const apps = require('./apps.js'), assert = require('assert'), backupFormat = require('./backupformat.js'), backupListing = require('./backuplisting.js'), - backups = require('./backups.js'), + backupTargets = require('./backuptargets.js'), BoxError = require('./boxerror.js'), constants = require('./constants.js'), DataLayout = require('./datalayout.js'), @@ -41,7 +41,7 @@ async function checkPreconditions(backupConfig, dataLayout) { assert(dataLayout instanceof DataLayout, 'dataLayout must be a DataLayout'); // check mount status before uploading - const status = await backups.ensureMounted(); + const status = await backupTargets.ensureMounted(); debug(`checkPreconditions: mount point status is ${JSON.stringify(status)}`); if (status.state !== 'active') throw new BoxError(BoxError.MOUNT_ERROR, `Backup endpoint is not active: ${status.message}`); @@ -73,7 +73,7 @@ async function upload(remotePath, format, dataLayoutString, progressCallback) { debug(`upload: path ${remotePath} format ${format} dataLayout ${dataLayoutString}`); const dataLayout = DataLayout.fromString(dataLayoutString); - const backupConfig = await backups.getConfig(); + const backupConfig = await backupTargets.getConfig(); await checkPreconditions(backupConfig, dataLayout); @@ -121,7 +121,7 @@ async function downloadApp(app, restoreConfig, progressCallback) { const dataLayout = new DataLayout(appDataDir, app.storageVolumeId ? [{ localDir: await apps.getStorageDir(app), remoteDir: 'data' }] : []); const startTime = new Date(); - const backupConfig = restoreConfig.backupConfig || await backups.getConfig(); + const backupConfig = restoreConfig.backupConfig || await backupTargets.getConfig(); await download(backupConfig, restoreConfig.remotePath, restoreConfig.backupFormat, dataLayout, progressCallback); debug('downloadApp: time: %s', (new Date() - startTime)/1000); @@ -197,7 +197,7 @@ async function uploadBoxSnapshot(backupConfig, progressCallback) { debug(`uploadBoxSnapshot: took ${(new Date() - startTime)/1000} seconds`); - await backups.setSnapshotInfo('box', { timestamp: new Date().toISOString(), format: backupConfig.format }); + await backupTargets.setSnapshotInfo('box', { timestamp: new Date().toISOString(), format: backupConfig.format }); } async function copy(backupConfig, srcRemotePath, destRemotePath, progressCallback) { @@ -258,7 +258,7 @@ async function backupBox(dependsOn, tag, options, progressCallback) { assert.strictEqual(typeof options, 'object'); assert.strictEqual(typeof progressCallback, 'function'); - const backupConfig = await backups.getConfig(); + const backupConfig = await backupTargets.getConfig(); await uploadBoxSnapshot(backupConfig, progressCallback); return await rotateBoxBackup(backupConfig, tag, options, dependsOn, progressCallback); @@ -271,7 +271,7 @@ async function rotateAppBackup(backupConfig, app, tag, options, progressCallback assert.strictEqual(typeof options, 'object'); assert.strictEqual(typeof progressCallback, 'function'); - const snapshotInfo = backups.getSnapshotInfo(app.id); + const snapshotInfo = backupTargets.getSnapshotInfo(app.id); const manifest = snapshotInfo.restoreConfig ? snapshotInfo.restoreConfig.manifest : snapshotInfo.manifest; // compat const remotePath = `${tag}/app_${app.fqdn}_v${manifest.version}`; @@ -359,7 +359,7 @@ async function uploadAppSnapshot(backupConfig, app, progressCallback) { debug(`uploadAppSnapshot: ${app.fqdn} uploaded to ${remotePath}. ${(new Date() - startTime)/1000} seconds`); - await backups.setSnapshotInfo(app.id, { timestamp: new Date().toISOString(), manifest: app.manifest, format: backupConfig.format }); + await backupTargets.setSnapshotInfo(app.id, { timestamp: new Date().toISOString(), manifest: app.manifest, format: backupConfig.format }); } async function backupAppWithTag(app, tag, options, progressCallback) { @@ -375,7 +375,7 @@ async function backupAppWithTag(app, tag, options, progressCallback) { return results[0].id; } - const backupConfig = await backups.getConfig(); + const backupConfig = await backupTargets.getConfig(); await uploadAppSnapshot(backupConfig, app, progressCallback); return await rotateAppBackup(backupConfig, app, tag, options, progressCallback); @@ -403,7 +403,7 @@ async function uploadMailSnapshot(backupConfig, progressCallback) { debug(`uploadMailSnapshot: took ${(new Date() - startTime)/1000} seconds`); - await backups.setSnapshotInfo('mail', { timestamp: new Date().toISOString(), format: backupConfig.format }); + await backupTargets.setSnapshotInfo('mail', { timestamp: new Date().toISOString(), format: backupConfig.format }); } async function rotateMailBackup(backupConfig, tag, options, progressCallback) { @@ -445,7 +445,7 @@ async function backupMailWithTag(tag, options, progressCallback) { debug(`backupMailWithTag: backing up mail with tag ${tag}`); - const backupConfig = await backups.getConfig(); + const backupConfig = await backupTargets.getConfig(); await uploadMailSnapshot(backupConfig, progressCallback); return await rotateMailBackup(backupConfig, tag, options, progressCallback); } diff --git a/src/cron.js b/src/cron.js index 776886dc5..6e278de0b 100644 --- a/src/cron.js +++ b/src/cron.js @@ -24,7 +24,7 @@ const appHealthMonitor = require('./apphealthmonitor.js'), assert = require('assert'), appstore = require('./appstore.js'), AuditSource = require('./auditsource.js'), - backups = require('./backups.js'), + backupTargets = require('./backuptargets.js'), cloudron = require('./cloudron.js'), constants = require('./constants.js'), { CronJob } = require('cron'), @@ -149,7 +149,7 @@ async function startJobs() { gJobs.cleanupBackups = CronJob.from({ cronTime: DEFAULT_CLEANUP_BACKUPS_PATTERN, - onTick: async () => await safe(backups.startCleanupTask(AuditSource.CRON), { debug }), + onTick: async () => await safe(backupTargets.startCleanupTask(AuditSource.CRON), { debug }), start: true }); @@ -203,7 +203,7 @@ async function startJobs() { start: true }); - await handleBackupPolicyChanged(await backups.getPolicy()); + await handleBackupPolicyChanged(await backupTargets.getPolicy()); await handleAutoupdatePatternChanged(await updater.getAutoupdatePattern()); await handleDynamicDnsChanged(await network.getDynamicDns()); await handleExternalLdapChanged(await externalLdap.getConfig()); @@ -221,7 +221,7 @@ async function handleBackupPolicyChanged(value) { gJobs.backup = CronJob.from({ cronTime: value.schedule, - onTick: async () => await safe(backups.startBackupTask(AuditSource.CRON), { debug }), + onTick: async () => await safe(backupTargets.startBackupTask(AuditSource.CRON), { debug }), start: true, timeZone: tz }); diff --git a/src/provision.js b/src/provision.js index 1ab26b292..6e9b1c265 100644 --- a/src/provision.js +++ b/src/provision.js @@ -9,7 +9,7 @@ exports = module.exports = { const appstore = require('./appstore.js'), assert = require('assert'), - backups = require('./backups.js'), + backupTargets = require('./backuptargets.js'), backupListing = require('./backuplisting.js'), backuptask = require('./backuptask.js'), BoxError = require('./boxerror.js'), @@ -181,7 +181,7 @@ async function restoreTask(backupConfig, remotePath, ipv4Config, ipv6Config, opt try { setProgress('restore', 'Downloading box backup'); - backupConfig.rootPath = backups.getRootPath(backupConfig, paths.MANAGED_BACKUP_MOUNT_DIR); + backupConfig.rootPath = backupTargets.getRootPath(backupConfig, paths.MANAGED_BACKUP_MOUNT_DIR); await backuptask.restore(backupConfig, remotePath, (progress) => setProgress('restore', progress.message)); setProgress('restore', 'Downloading mail backup'); @@ -204,7 +204,7 @@ async function restoreTask(backupConfig, remotePath, ipv4Config, ipv6Config, opt await dashboard.setupLocation(location.subdomain, location.domain, auditSource); delete backupConfig.rootPath; - await backups.setConfig(backupConfig); + await backupTargets.setConfig(backupConfig); await eventlog.add(eventlog.ACTION_RESTORE, auditSource, { remotePath }); setImmediate(() => safe(platform.onActivated({ skipDnsSetup: options.skipDnsSetup }), { debug })); @@ -235,18 +235,18 @@ async function restore(backupConfig, remotePath, version, ipv4Config, ipv6Config const activated = await users.isActivated(); if (activated) throw new BoxError(BoxError.CONFLICT, 'Already activated. Restore with a fresh Cloudron installation.'); - let error = backups.validateFormat(backupConfig.format); + let error = backupTargets.validateFormat(backupConfig.format); if (error) throw error; if ('password' in backupConfig) { - backupConfig.encryption = backups.generateEncryptionKeysSync(backupConfig.password); + backupConfig.encryption = backupTargets.generateEncryptionKeysSync(backupConfig.password); delete backupConfig.password; } else { backupConfig.encryption = null; } - await backups.setupManagedStorage(backupConfig, paths.MANAGED_BACKUP_MOUNT_DIR); // this validates mountOptions - error = await backups.testStorage(Object.assign({ mountPath: paths.MANAGED_BACKUP_MOUNT_DIR }, backupConfig)); // this validates provider and it's api options. requires mountPath + await backupTargets.setupManagedStorage(backupConfig, paths.MANAGED_BACKUP_MOUNT_DIR); // this validates mountOptions + error = await backupTargets.testStorage(Object.assign({ mountPath: paths.MANAGED_BACKUP_MOUNT_DIR }, backupConfig)); // this validates provider and it's api options. requires mountPath if (error) throw error; error = await network.testIPv4Config(ipv4Config); diff --git a/src/routes/backups.js b/src/routes/backuptargets.js similarity index 86% rename from src/routes/backups.js rename to src/routes/backuptargets.js index daf4f2012..f1f405307 100644 --- a/src/routes/backups.js +++ b/src/routes/backuptargets.js @@ -16,44 +16,44 @@ exports = module.exports = { const assert = require('assert'), AuditSource = require('../auditsource.js'), - backups = require('../backups.js'), + backupTargets = require('../backuptargets.js'), BoxError = require('../boxerror.js'), HttpError = require('@cloudron/connect-lastmile').HttpError, HttpSuccess = require('@cloudron/connect-lastmile').HttpSuccess, safe = require('safetydance'); async function create(req, res, next) { - const [error, taskId] = await safe(backups.startBackupTask(AuditSource.fromRequest(req))); + const [error, taskId] = await safe(backupTargets.startBackupTask(AuditSource.fromRequest(req))); if (error) return next(BoxError.toHttpError(error)); next(new HttpSuccess(202, { taskId })); } async function cleanup(req, res, next) { - const [error, taskId] = await safe(backups.startCleanupTask(AuditSource.fromRequest(req))); + const [error, taskId] = await safe(backupTargets.startCleanupTask(AuditSource.fromRequest(req))); if (error) return next(BoxError.toHttpError(error)); next(new HttpSuccess(202, { taskId })); } async function remount(req, res, next) { - const [error] = await safe(backups.remount()); + const [error] = await safe(backupTargets.remount()); if (error) return next(BoxError.toHttpError(error)); next(new HttpSuccess(202, {})); } async function getMountStatus(req, res, next) { - const [error, mountStatus] = await safe(backups.getMountStatus()); + const [error, mountStatus] = await safe(backupTargets.getMountStatus()); if (error) return next(BoxError.toHttpError(error)); next(new HttpSuccess(200, mountStatus)); } async function getConfig(req, res, next) { - const [error, backupConfig] = await safe(backups.getConfig()); + const [error, backupConfig] = await safe(backupTargets.getConfig()); if (error) return next(BoxError.toHttpError(error)); - next(new HttpSuccess(200, backups.removePrivateFields(backupConfig))); + next(new HttpSuccess(200, backupTargets.removePrivateFields(backupConfig))); } async function setLimits(req, res, next) { @@ -84,7 +84,7 @@ async function setLimits(req, res, next) { if ('memoryLimit' in limits && typeof limits.memoryLimit !== 'number') return next(new HttpError(400, 'memoryLimit must be a positive integer')); - const [error] = await safe(backups.setLimits(req.body)); + const [error] = await safe(backupTargets.setLimits(req.body)); if (error) return next(BoxError.toHttpError(error)); next(new HttpSuccess(200, {})); @@ -113,14 +113,14 @@ async function setStorage(req, res, next) { // testing the backup using put/del takes a bit of time at times req.clearTimeout(); - const [error] = await safe(backups.setStorage(req.body)); + const [error] = await safe(backupTargets.setStorage(req.body)); if (error) return next(BoxError.toHttpError(error)); next(new HttpSuccess(200, {})); } async function getPolicy(req, res, next) { - const [error, policy] = await safe(backups.getPolicy()); + const [error, policy] = await safe(backupTargets.getPolicy()); if (error) return next(BoxError.toHttpError(error)); next(new HttpSuccess(200, { policy })); @@ -132,7 +132,7 @@ async function setPolicy(req, res, next) { if (typeof req.body.schedule !== 'string') return next(new HttpError(400, 'schedule is required')); if (!req.body.retention || typeof req.body.retention !== 'object') return next(new HttpError(400, 'retention is required')); - const [error] = await safe(backups.setPolicy(req.body)); + const [error] = await safe(backupTargets.setPolicy(req.body)); if (error) return next(BoxError.toHttpError(error)); next(new HttpSuccess(200, {})); diff --git a/src/routes/index.js b/src/routes/index.js index a190a3b34..954d6c3bb 100644 --- a/src/routes/index.js +++ b/src/routes/index.js @@ -9,7 +9,7 @@ exports = module.exports = { archives: require('./archives.js'), auth: require('./auth.js'), backupListing: require('./backuplisting.js'), - backups: require('./backups.js'), + backupTargets: require('./backuptargets.js'), branding: require('./branding.js'), cloudron: require('./cloudron.js'), dashboard: require('./dashboard.js'), diff --git a/src/routes/test/backups-test.js b/src/routes/test/backups-test.js index 9645d1195..0bea58a45 100644 --- a/src/routes/test/backups-test.js +++ b/src/routes/test/backups-test.js @@ -5,7 +5,7 @@ 'use strict'; -const backups = require('../../backups.js'), +const backupTargets = require('../../backuptargets.js'), common = require('./common.js'), expect = require('expect.js'), superagent = require('@cloudron/superagent'); @@ -111,7 +111,7 @@ describe('Backups API', function () { describe('backup_config', function () { // keep in sync with defaults in settings.js - let defaultConfig = { + const defaultConfig = { provider: 'filesystem', backupFolder: '/var/backups', format: 'tgz', @@ -127,7 +127,7 @@ describe('Backups API', function () { }); it('cannot set backup_config without provider', async function () { - let tmp = JSON.parse(JSON.stringify(defaultConfig)); + const tmp = JSON.parse(JSON.stringify(defaultConfig)); delete tmp.provider; const response = await superagent.post(`${serverUrl}/api/v1/backups/config`) @@ -139,7 +139,7 @@ describe('Backups API', function () { }); it('cannot set backup_config with invalid provider', async function () { - let tmp = JSON.parse(JSON.stringify(defaultConfig)); + const tmp = JSON.parse(JSON.stringify(defaultConfig)); tmp.provider = 'invalid provider'; const response = await superagent.post(`${serverUrl}/api/v1/backups/config`) @@ -151,7 +151,7 @@ describe('Backups API', function () { }); it('cannot set backup_config without format', async function () { - let tmp = JSON.parse(JSON.stringify(defaultConfig)); + const tmp = JSON.parse(JSON.stringify(defaultConfig)); delete tmp.format; const response = await superagent.post(`${serverUrl}/api/v1/backups/config`) @@ -163,7 +163,7 @@ describe('Backups API', function () { }); it('cannot set backup_config with invalid format', async function () { - let tmp = JSON.parse(JSON.stringify(defaultConfig)); + const tmp = JSON.parse(JSON.stringify(defaultConfig)); tmp.format = 'invalid format'; const response = await superagent.post(`${serverUrl}/api/v1/backups/config`) @@ -175,7 +175,7 @@ describe('Backups API', function () { }); it('cannot set backup_config with invalid password', async function () { - let tmp = JSON.parse(JSON.stringify(defaultConfig)); + const tmp = JSON.parse(JSON.stringify(defaultConfig)); tmp.password = 1234; const response = await superagent.post(`${serverUrl}/api/v1/backups/config`) @@ -187,7 +187,7 @@ describe('Backups API', function () { }); it('cannot set backup_config with invalid syncConcurrency', async function () { - let tmp = JSON.parse(JSON.stringify(defaultConfig)); + const tmp = JSON.parse(JSON.stringify(defaultConfig)); tmp.limits = { syncConcurrency: 'not a number' }; const response = await superagent.post(`${serverUrl}/api/v1/backups/config`) @@ -199,7 +199,7 @@ describe('Backups API', function () { }); it('cannot set backup_config with invalid syncConcurrency', async function () { - let tmp = JSON.parse(JSON.stringify(defaultConfig)); + const tmp = JSON.parse(JSON.stringify(defaultConfig)); tmp.limits = { syncConcurrency: 0 }; const response = await superagent.post(`${serverUrl}/api/v1/backups/config`) @@ -211,7 +211,7 @@ describe('Backups API', function () { }); it('cannot set backup_config with invalid acceptSelfSignedCerts', async function () { - let tmp = JSON.parse(JSON.stringify(defaultConfig)); + const tmp = JSON.parse(JSON.stringify(defaultConfig)); tmp.acceptSelfSignedCerts = 'not a boolean'; const response = await superagent.post(`${serverUrl}/api/v1/backups/config`) @@ -223,7 +223,7 @@ describe('Backups API', function () { }); it('can set backup_config', async function () { - let tmp = JSON.parse(JSON.stringify(defaultConfig)); + const tmp = JSON.parse(JSON.stringify(defaultConfig)); tmp.format = 'rsync'; tmp.backupFolder = BACKUP_FOLDER; tmp.limits = { copyConcurrency: 34 }; @@ -247,7 +247,7 @@ describe('Backups API', function () { describe('create', function () { before(async function () { - await backups.setStorage({ + await backupTargets.setStorage({ provider: 'filesystem', backupFolder: '/tmp/backups', format: 'tgz', @@ -282,7 +282,7 @@ describe('Backups API', function () { const response = await superagent.get(`${serverUrl}/api/v1/backups`) .query({ access_token: owner.token }); expect(response.status).to.equal(200); - expect(response.body.backups.length).to.be(1); + expect(response.body.backupTargets.length).to.be(1); }); }); @@ -293,7 +293,7 @@ describe('Backups API', function () { const response = await superagent.get(`${serverUrl}/api/v1/backups`) .query({ access_token: owner.token }); expect(response.status).to.equal(200); - expect(response.body.backups.length).to.be(1); + expect(response.body.backupTargets.length).to.be(1); someBackup = response.body.backups[0]; }); diff --git a/src/routes/test/common.js b/src/routes/test/common.js index e7ccf03b8..7f3596309 100644 --- a/src/routes/test/common.js +++ b/src/routes/test/common.js @@ -2,7 +2,7 @@ const apps = require('../../apps.js'), appstore = require('../../appstore.js'), - backups = require('../../backups.js'), + backupTargets = require('../../backuptargets.js'), debug = require('debug')('box:test/common'), constants = require('../../constants.js'), database = require('../../database.js'), @@ -115,7 +115,7 @@ async function setupServer() { await database.initialize(); await database._clear(); await appstore._setApiServerOrigin(exports.mockApiServerOrigin); - await backups._addDefaultTarget(); + await backupTargets._addDefaultTarget(); await oidcServer.stop(); await server.start(); debug('Set up server complete'); diff --git a/src/server.js b/src/server.js index 4f406e669..8a0d45890 100644 --- a/src/server.js +++ b/src/server.js @@ -155,15 +155,15 @@ async function initializeExpressSync() { router.get ('/api/v1/backups', token, authorizeAdmin, routes.backupListing.list); router.post('/api/v1/backups/:backupId', json, token, authorizeAdmin, routes.backupListing.update); - router.get ('/api/v1/backups/mount_status', token, authorizeAdmin, routes.backups.getMountStatus); - router.post('/api/v1/backups/create', token, authorizeAdmin, routes.backups.create); - router.post('/api/v1/backups/cleanup', json, token, authorizeAdmin, routes.backups.cleanup); - router.post('/api/v1/backups/remount', json, token, authorizeAdmin, routes.backups.remount); - router.get ('/api/v1/backups/config', token, authorizeAdmin, routes.backups.getConfig); - router.post('/api/v1/backups/config/storage', json, token, authorizeOwner, routes.backups.setStorage); - router.post('/api/v1/backups/config/limits', json, token, authorizeOwner, routes.backups.setLimits); - router.get ('/api/v1/backups/policy', token, authorizeAdmin, routes.backups.getPolicy); - router.post('/api/v1/backups/policy', json, token, authorizeOwner, routes.backups.setPolicy); + router.get ('/api/v1/backups/mount_status', token, authorizeAdmin, routes.backupTargets.getMountStatus); + router.post('/api/v1/backups/create', token, authorizeAdmin, routes.backupTargets.create); + router.post('/api/v1/backups/cleanup', json, token, authorizeAdmin, routes.backupTargets.cleanup); + router.post('/api/v1/backups/remount', json, token, authorizeAdmin, routes.backupTargets.remount); + router.get ('/api/v1/backups/config', token, authorizeAdmin, routes.backupTargets.getConfig); + router.post('/api/v1/backups/config/storage', json, token, authorizeOwner, routes.backupTargets.setStorage); + router.post('/api/v1/backups/config/limits', json, token, authorizeOwner, routes.backupTargets.setLimits); + router.get ('/api/v1/backups/policy', token, authorizeAdmin, routes.backupTargets.getPolicy); + router.post('/api/v1/backups/policy', json, token, authorizeOwner, routes.backupTargets.setPolicy); // app archive routes router.get ('/api/v1/archives', token, authorizeAdmin, routes.archives.list); diff --git a/src/system.js b/src/system.js index 05e972299..6c7679a52 100644 --- a/src/system.js +++ b/src/system.js @@ -20,7 +20,7 @@ exports = module.exports = { const apps = require('./apps.js'), assert = require('assert'), { AsyncTask } = require('./asynctask.js'), - backups = require('./backups.js'), + backupTargets = require('./backuptargets.js'), BoxError = require('./boxerror.js'), debug = require('debug')('box:system'), df = require('./df.js'), @@ -125,7 +125,7 @@ async function getFilesystems() { filesystems[diskInfo.filesystem].contents.push(stdPath); } - const backupConfig = await backups.getConfig(); + const backupConfig = await backupTargets.getConfig(); if (backupConfig.provider === 'filesystem') { const [, dfResult] = await safe(df.file(backupConfig.backupFolder)); const filesystem = dfResult?.filesystem || rootDisk.filesystem; diff --git a/src/test/backupcleaner-test.js b/src/test/backupcleaner-test.js index 49d3a7594..da233fd23 100644 --- a/src/test/backupcleaner-test.js +++ b/src/test/backupcleaner-test.js @@ -9,7 +9,7 @@ const archives = require('../archives.js'), backupCleaner = require('../backupcleaner.js'), backupListing = require('../backuplisting.js'), - backups = require('../backups.js'), + backupTargets = require('../backuptargets.js'), common = require('./common.js'), expect = require('expect.js'), moment = require('moment'), @@ -232,11 +232,11 @@ describe('backup cleaner', function () { backupFolder: '/tmp/someplace', format: 'tgz' })); - await backups.setPolicy({ retention: { keepWithinSecs: 1 }, schedule: '00 00 23 * * *' }); + await backupTargets.setPolicy({ retention: { keepWithinSecs: 1 }, schedule: '00 00 23 * * *' }); }); async function cleanupBackups() { - const taskId = await backups.startCleanupTask({ username: 'test' }); + const taskId = await backupTargets.startCleanupTask({ username: 'test' }); console.log('started task', taskId); diff --git a/src/test/backups-test.js b/src/test/backups-test.js index b0e7d73dc..15335382b 100644 --- a/src/test/backups-test.js +++ b/src/test/backups-test.js @@ -7,7 +7,7 @@ 'use strict'; const backupListing = require('../backuplisting.js'), - backups = require('../backups.js'), + backupTargets = require('../backuptargets.js'), BoxError = require('../boxerror.js'), common = require('./common.js'), expect = require('expect.js'), @@ -123,37 +123,37 @@ describe('backups', function () { describe('config and policy', function () { it('can get backup config', async function () { - const backupConfig = await backups.getConfig(); + const backupConfig = await backupTargets.getConfig(); expect(backupConfig.provider).to.be('filesystem'); expect(backupConfig.backupFolder).to.be('/var/backups'); }); it('can set backup config', async function () { - let backupConfig = await backups.getConfig(); + let backupConfig = await backupTargets.getConfig(); backupConfig = Object.assign({}, backupConfig, { backupFolder: '/tmp/backups' }); - await backups.setConfig(backupConfig); + await backupTargets.setConfig(backupConfig); - const newBackupConfig = await backups.getConfig(); + const newBackupConfig = await backupTargets.getConfig(); expect(newBackupConfig.backupFolder).to.be('/tmp/backups'); }); it('cannot set backup policy with invalid schedule', async function () { - const [error] = await safe(backups.setPolicy({ schedule: '', retention: { keepWithinSecs: 1 }})); + const [error] = await safe(backupTargets.setPolicy({ schedule: '', retention: { keepWithinSecs: 1 }})); expect(error.reason).to.be(BoxError.BAD_FIELD); }); it('cannot set backup policy with missing retention', async function () { - const [error] = await safe(backups.setPolicy({ schedule: '00 * * * * *'})); + const [error] = await safe(backupTargets.setPolicy({ schedule: '00 * * * * *'})); expect(error.reason).to.be(BoxError.BAD_FIELD); }); it('cannot set backup policy with invalid retention', async function () { - const [error] = await safe(backups.setPolicy({ schedule: '00 * * * * *', retention: { keepWhenever: 4 }})); + const [error] = await safe(backupTargets.setPolicy({ schedule: '00 * * * * *', retention: { keepWhenever: 4 }})); expect(error.reason).to.be(BoxError.BAD_FIELD); }); it('can set valid backup policy', async function () { - await backups.setPolicy({ schedule: '00 00 2,23 * * 0,1,2', retention: { keepWithinSecs: 1 }}); + await backupTargets.setPolicy({ schedule: '00 00 2,23 * * 0,1,2', retention: { keepWithinSecs: 1 }}); }); }); }); diff --git a/src/test/backuptask-test.js b/src/test/backuptask-test.js index 11bc53770..90f95e92c 100644 --- a/src/test/backuptask-test.js +++ b/src/test/backuptask-test.js @@ -7,7 +7,7 @@ 'use strict'; const backupListing = require('../backuplisting.js'), - backups = require('../backups.js'), + backupTargets = require('../backuptargets.js'), common = require('./common.js'), expect = require('expect.js'), fs = require('fs'), @@ -34,11 +34,11 @@ describe('backuptask', function () { before(async function () { fs.rmSync(backupConfig.backupFolder, { recursive: true, force: true }); - await backups.setStorage(backupConfig); + await backupTargets.setStorage(backupConfig); }); async function createBackup() { - const taskId = await backups.startBackupTask({ username: 'test' }); + const taskId = await backupTargets.startBackupTask({ username: 'test' }); while (true) { await timers.setTimeout(1000); diff --git a/src/test/common.js b/src/test/common.js index c43f126da..63f920987 100644 --- a/src/test/common.js +++ b/src/test/common.js @@ -2,7 +2,7 @@ const apps = require('../apps.js'), appstore = require('../appstore.js'), - backups = require('../backups.js'), + backupTargets = require('../backuptargets.js'), constants = require('../constants.js'), cron = require('../cron.js'), dashboard = require('../dashboard.js'), @@ -220,7 +220,7 @@ async function databaseSetup() { await database._clear(); await appstore._setApiServerOrigin(exports.mockApiServerOrigin); await dashboard._setLocation(constants.DASHBOARD_SUBDOMAIN, exports.dashboardDomain); - exports.defaultBackupTarget.id = await backups._addDefaultTarget(); + exports.defaultBackupTarget.id = await backupTargets._addDefaultTarget(); } async function domainSetup() { diff --git a/src/test/storage-test.js b/src/test/storage-test.js index 2d32c92ba..736d8d285 100644 --- a/src/test/storage-test.js +++ b/src/test/storage-test.js @@ -6,7 +6,7 @@ 'use strict'; -const backups = require('../backups.js'), +const backupTargets = require('../backuptargets.js'), BoxError = require('../boxerror.js'), common = require('./common.js'), execSync = require('child_process').execSync, @@ -54,12 +54,12 @@ describe('Storage', function () { it('fails to set backup storage for bad folder', async function () { const tmp = Object.assign({}, gBackupConfig, { backupFolder: '/root/oof' }); - const [error] = await safe(backups.setStorage(tmp)); + const [error] = await safe(backupTargets.setStorage(tmp)); expect(error.reason).to.equal(BoxError.BAD_FIELD); }); it('succeeds to set backup storage', async function () { - await backups.setStorage(gBackupConfig); + await backupTargets.setStorage(gBackupConfig); expect(fs.existsSync(path.join(gBackupConfig.backupFolder, 'snapshot'))).to.be(true); // auto-created }); diff --git a/src/updater.js b/src/updater.js index 97c7b13ca..82dc5e85a 100644 --- a/src/updater.js +++ b/src/updater.js @@ -23,7 +23,7 @@ const apps = require('./apps.js'), assert = require('assert'), AuditSource = require('./auditsource.js'), BoxError = require('./boxerror.js'), - backups = require('./backups.js'), + backupTargets = require('./backuptargets.js'), backuptask = require('./backuptask.js'), constants = require('./constants.js'), cron = require('./cron.js'), @@ -223,7 +223,7 @@ async function startBoxUpdateTask(options, auditSource) { const [error] = await safe(locks.acquire(locks.TYPE_BOX_UPDATE_TASK)); if (error) throw new BoxError(BoxError.BAD_STATE, `Another update task is in progress: ${error.message}`); - const backupConfig = await backups.getConfig(); + const backupConfig = await backupTargets.getConfig(); const memoryLimit = backupConfig.limits?.memoryLimit ? Math.max(backupConfig.limits.memoryLimit/1024/1024, 400) : 400; const taskId = await tasks.add(tasks.TASK_BOX_UPDATE, [ boxUpdateInfo, options ]);