diff --git a/src/backupformat.js b/src/backupformat.js index eca13d9b2..b7a163790 100644 --- a/src/backupformat.js +++ b/src/backupformat.js @@ -1,12 +1,15 @@ 'use strict'; exports = module.exports = { - api + api, }; -const BoxError = require('./boxerror.js'); +const assert = require('assert'), + BoxError = require('./boxerror.js'); function api(format) { + assert.strictEqual(typeof format, 'string'); + switch (format) { case 'tgz': return require('./backupformat/tgz.js'); case 'rsync': return require('./backupformat/rsync.js'); diff --git a/src/backupformat/rsync.js b/src/backupformat/rsync.js index 6c00aef11..1964e2276 100644 --- a/src/backupformat/rsync.js +++ b/src/backupformat/rsync.js @@ -3,6 +3,7 @@ exports = module.exports = { download, upload, + getFileExtension, _saveFsMetadata: saveFsMetadata, _restoreFsMetadata: restoreFsMetadata @@ -274,3 +275,9 @@ async function upload(backupTarget, remotePath, dataLayout, progressCallback) { await saveFsMetadata(dataLayout, `${dataLayout.localRoot()}/fsmetadata.json`); await sync(backupTarget, remotePath, dataLayout, progressCallback); } + +function getFileExtension(encryption) { + assert.strictEqual(typeof encryption, 'boolean'); + + return ''; +} diff --git a/src/backupformat/tgz.js b/src/backupformat/tgz.js index 72fa3f724..b2f37c32a 100644 --- a/src/backupformat/tgz.js +++ b/src/backupformat/tgz.js @@ -254,9 +254,16 @@ async function upload(backupTarget, remotePath, dataLayout, progressCallback) { }); } +function getFileExtension(encryption) { + assert.strictEqual(typeof encryption, 'boolean'); + + return encryption ? '.tar.gz.enc' : '.tar.gz'; +} + exports = module.exports = { download, upload, + getFileExtension, // exported for testing _EnsureFileSizeStream: EnsureFileSizeStream diff --git a/src/backuptargets.js b/src/backuptargets.js index 125f8a3e2..db06b653d 100644 --- a/src/backuptargets.js +++ b/src/backuptargets.js @@ -32,7 +32,7 @@ exports = module.exports = { storageApi, - getBackupFilePath + getBackupFilePath, }; const assert = require('assert'), diff --git a/src/backuptask.js b/src/backuptask.js index 18007abbe..779d0d95b 100644 --- a/src/backuptask.js +++ b/src/backuptask.js @@ -34,6 +34,14 @@ const apps = require('./apps.js'), const BACKUP_UPLOAD_CMD = path.join(__dirname, 'scripts/backupupload.js'); +function addFileExtension(backupTarget, remotePath) { + assert.strictEqual(typeof backupTarget, 'object'); + assert.strictEqual(typeof remotePath, 'string'); + + const ext = backupFormat.api(backupTarget.format).getFileExtension(!!backupTarget.encyption); + return remotePath + ext; +} + async function checkPreconditions(backupTarget, dataLayout) { assert.strictEqual(typeof backupTarget, 'object'); assert(dataLayout instanceof DataLayout, 'dataLayout must be a DataLayout'); @@ -179,11 +187,13 @@ async function uploadBoxSnapshot(backupTarget, progressCallback) { await snapshotBox(progressCallback); + const remotePath = addFileExtension(backupTarget, `snapshot/box`); + const boxDataDir = safe.fs.realpathSync(paths.BOX_DATA_DIR); if (!boxDataDir) throw new BoxError(BoxError.FS_ERROR, `Error resolving boxdata: ${safe.error.message}`); const uploadConfig = { - remotePath: 'snapshot/box', + remotePath, backupTarget, dataLayout: new DataLayout(boxDataDir, []), progressTag: 'box' @@ -225,7 +235,7 @@ async function rotateBoxBackup(backupTarget, tag, options, dependsOn, progressCa assert(Array.isArray(dependsOn)); assert.strictEqual(typeof progressCallback, 'function'); - const remotePath = `${tag}/box_v${constants.VERSION}`; + const remotePath = addFileExtension(backupTarget, `${tag}/box_v${constants.VERSION}`); debug(`rotateBoxBackup: rotating to id ${remotePath}`); @@ -244,7 +254,8 @@ async function rotateBoxBackup(backupTarget, tag, options, dependsOn, progressCa }; const id = await backups.add(data); - const [error] = await safe(copy(backupTarget, 'snapshot/box', remotePath, progressCallback)); + const snapshotPath = addFileExtension(backupTarget, 'snapshot/box'); + const [error] = await safe(copy(backupTarget, snapshotPath, remotePath, progressCallback)); const state = error ? backups.BACKUP_STATE_ERROR : backups.BACKUP_STATE_NORMAL; await backups.setState(id, state); if (error) throw error; @@ -271,7 +282,7 @@ async function rotateAppBackup(backupTarget, app, tag, options, progressCallback assert.strictEqual(typeof progressCallback, 'function'); const manifest = app.manifest; - const remotePath = `${tag}/app_${app.fqdn}_v${manifest.version}`; + const remotePath = addFileExtension(backupTarget, `${tag}/app_${app.fqdn}_v${manifest.version}`); debug(`rotateAppBackup: rotating ${app.fqdn} to path ${remotePath}`); @@ -290,7 +301,8 @@ async function rotateAppBackup(backupTarget, app, tag, options, progressCallback }; const id = await backups.add(data); - const [error] = await safe(copy(backupTarget, `snapshot/app_${app.id}`, remotePath, progressCallback)); + const snapshotPath = addFileExtension(backupTarget, `snapshot/app_${app.id}`); + const [error] = await safe(copy(backupTarget, snapshotPath, remotePath, progressCallback)); const state = error ? backups.BACKUP_STATE_ERROR : backups.BACKUP_STATE_NORMAL; await backups.setState(id, state); if (error) throw error; @@ -337,7 +349,7 @@ async function uploadAppSnapshot(backupTarget, app, progressCallback) { await snapshotApp(app, progressCallback); - const remotePath = `snapshot/app_${app.id}`; + const remotePath = addFileExtension(backupTarget, `snapshot/app_${app.id}`); const appDataDir = safe.fs.realpathSync(path.join(paths.APPS_DATA_DIR, app.id)); if (!appDataDir) throw new BoxError(BoxError.FS_ERROR, `Error resolving appsdata: ${safe.error.message}`); @@ -382,11 +394,13 @@ async function uploadMailSnapshot(backupTarget, progressCallback) { assert.strictEqual(typeof backupTarget, 'object'); assert.strictEqual(typeof progressCallback, 'function'); + const remotePath = addFileExtension(backupTarget, 'snapshot/mail'); + const mailDataDir = safe.fs.realpathSync(paths.MAIL_DATA_DIR); if (!mailDataDir) throw new BoxError(BoxError.FS_ERROR, `Error resolving maildata: ${safe.error.message}`); const uploadConfig = { - remotePath: 'snapshot/mail', + remotePath, backupTarget, dataLayout: new DataLayout(mailDataDir, []), progressTag: 'mail' @@ -409,7 +423,7 @@ async function rotateMailBackup(backupTarget, tag, options, progressCallback) { assert.strictEqual(typeof options, 'object'); assert.strictEqual(typeof progressCallback, 'function'); - const remotePath = `${tag}/mail_v${constants.VERSION}`; + const remotePath = addFileExtension(backupTarget, `${tag}/mail_v${constants.VERSION}`); debug(`rotateMailBackup: rotating to ${remotePath}`); @@ -428,7 +442,8 @@ async function rotateMailBackup(backupTarget, tag, options, progressCallback) { }; const id = await backups.add(data); - const [error] = await safe(copy(backupTarget, 'snapshot/mail', remotePath, progressCallback)); + const snapshotPath = addFileExtension(backupTarget, 'snapshot/mail'); + const [error] = await safe(copy(backupTarget, snapshotPath, remotePath, progressCallback)); const state = error ? backups.BACKUP_STATE_ERROR : backups.BACKUP_STATE_NORMAL; await backups.setState(id, state); if (error) throw error; diff --git a/src/test/backuptask-test.js b/src/test/backuptask-test.js index 220e8cbd4..408d380d8 100644 --- a/src/test/backuptask-test.js +++ b/src/test/backuptask-test.js @@ -70,7 +70,7 @@ describe('backuptask', function () { const result = await createBackup(defaultBackupTarget); expect(fs.statSync(path.join(backupConfig.backupFolder, 'snapshot/box.tar.gz')).nlink).to.be(2); // hard linked to a rotated backup - expect(fs.statSync(path.join(backupConfig.backupFolder, `${result.remotePath}.tar.gz`)).nlink).to.be(2); + expect(fs.statSync(path.join(backupConfig.backupFolder, result.remotePath)).nlink).to.be(2); backupInfo1 = result; }); @@ -84,8 +84,8 @@ describe('backuptask', function () { const result = await createBackup(defaultBackupTarget); expect(fs.statSync(path.join(backupConfig.backupFolder, 'snapshot/box.tar.gz')).nlink).to.be(2); // hard linked to a rotated backup - expect(fs.statSync(path.join(backupConfig.backupFolder, `${result.remotePath}.tar.gz`)).nlink).to.be(2); // hard linked to new backup - expect(fs.statSync(path.join(backupConfig.backupFolder, `${backupInfo1.remotePath}.tar.gz`)).nlink).to.be(1); // not hard linked anymore + expect(fs.statSync(path.join(backupConfig.backupFolder, result.remotePath)).nlink).to.be(2); // hard linked to new backup + expect(fs.statSync(path.join(backupConfig.backupFolder, backupInfo1.remotePath)).nlink).to.be(1); // not hard linked anymore }); it('cleanup', function () {