diff --git a/src/backuptask.js b/src/backuptask.js index 0cdff58d5..791b86abb 100644 --- a/src/backuptask.js +++ b/src/backuptask.js @@ -418,36 +418,35 @@ function upload(remotePath, format, dataLayoutString, progressCallback, callback const dataLayout = DataLayout.fromString(dataLayoutString); - getBackupConfig(function (error, backupConfig) { + getBackupConfig(async function (error, backupConfig) { if (error) return callback(error); - storage.api(backupConfig.provider).checkPreconditions(backupConfig, dataLayout, function (error) { - if (error) return callback(error); + const [preconditionError] = await safe(storage.api(backupConfig.provider).checkPreconditions(backupConfig, dataLayout)); + if (preconditionError) return callback(preconditionError); - if (format === 'tgz') { - async.retry({ times: 5, interval: 20000 }, function (retryCallback) { - retryCallback = once(retryCallback); // protect again upload() erroring much later after tar stream error + if (format === 'tgz') { + async.retry({ times: 5, interval: 20000 }, function (retryCallback) { + retryCallback = once(retryCallback); // protect again upload() erroring much later after tar stream error - tarPack(dataLayout, backupConfig.encryption, function (error, tarStream) { - if (error) return retryCallback(error); + tarPack(dataLayout, backupConfig.encryption, function (error, tarStream) { + if (error) return retryCallback(error); - tarStream.on('progress', function (progress) { - const transferred = Math.round(progress.transferred/1024/1024), speed = Math.round(progress.speed/1024/1024); - if (!transferred && !speed) return progressCallback({ message: 'Uploading backup' }); // 0M@0MBps looks wrong - progressCallback({ message: `Uploading backup ${transferred}M@${speed}MBps` }); - }); - tarStream.on('error', retryCallback); // already returns BoxError - - storage.api(backupConfig.provider).upload(backupConfig, storage.getBackupFilePath(backupConfig, remotePath, format), tarStream, retryCallback); + tarStream.on('progress', function (progress) { + const transferred = Math.round(progress.transferred/1024/1024), speed = Math.round(progress.speed/1024/1024); + if (!transferred && !speed) return progressCallback({ message: 'Uploading backup' }); // 0M@0MBps looks wrong + progressCallback({ message: `Uploading backup ${transferred}M@${speed}MBps` }); }); - }, callback); - } else { - async.series([ - saveFsMetadata.bind(null, dataLayout, `${dataLayout.localRoot()}/fsmetadata.json`), - sync.bind(null, backupConfig, remotePath, dataLayout, progressCallback) - ], callback); - } - }); + tarStream.on('error', retryCallback); // already returns BoxError + + storage.api(backupConfig.provider).upload(backupConfig, storage.getBackupFilePath(backupConfig, remotePath, format), tarStream, retryCallback); + }); + }, callback); + } else { + async.series([ + saveFsMetadata.bind(null, dataLayout, `${dataLayout.localRoot()}/fsmetadata.json`), + sync.bind(null, backupConfig, remotePath, dataLayout, progressCallback) + ], callback); + } }); } diff --git a/src/storage/filesystem.js b/src/storage/filesystem.js index 637dce44d..3d25de419 100644 --- a/src/storage/filesystem.js +++ b/src/storage/filesystem.js @@ -63,35 +63,32 @@ function getRootPath(apiConfig) { } // the du call in the function below requires root -async function checkPreconditions(apiConfig, dataLayout, callback) { +async function checkPreconditions(apiConfig, dataLayout) { assert.strictEqual(typeof apiConfig, 'object'); assert(dataLayout instanceof DataLayout, 'dataLayout must be a DataLayout'); - assert.strictEqual(typeof callback, 'function'); let used = 0; for (let localPath of dataLayout.localPaths()) { debug(`checkPreconditions: getting disk usage of ${localPath}`); let result = safe.child_process.execSync(`du -Dsb ${localPath}`, { encoding: 'utf8' }); - if (!result) return callback(new BoxError(BoxError.FS_ERROR, `du error: ${safe.error.message}`)); + if (!result) throw new BoxError(BoxError.FS_ERROR, `du error: ${safe.error.message}`); used += parseInt(result, 10); } debug(`checkPreconditions: ${used} bytes`); const [error, result] = await safe(df.file(getRootPath(apiConfig))); - if (error) return callback(new BoxError(BoxError.FS_ERROR, `Error when checking for disk space: ${error.message}`)); + if (error) throw new BoxError(BoxError.FS_ERROR, `Error when checking for disk space: ${error.message}`); // Check filesystem is mounted so we don't write into the actual folder on disk if (apiConfig.provider === PROVIDER_SSHFS || apiConfig.provider === PROVIDER_CIFS || apiConfig.provider === PROVIDER_NFS || apiConfig.provider === PROVIDER_EXT4) { - if (result.mountpoint !== paths.MANAGED_BACKUP_MOUNT_DIR) return callback(new BoxError(BoxError.FS_ERROR, 'Backup target is not mounted')); + if (result.mountpoint !== paths.MANAGED_BACKUP_MOUNT_DIR) throw new BoxError(BoxError.FS_ERROR, 'Backup target is not mounted'); } else if (apiConfig.provider === PROVIDER_MOUNTPOINT) { - if (result.mountpoint === '/') return callback(new BoxError(BoxError.FS_ERROR, `${apiConfig.backupFolder} is not mounted`)); + if (result.mountpoint === '/') throw new BoxError(BoxError.FS_ERROR, `${apiConfig.backupFolder} is not mounted`); } const needed = 0.6 * used + (1024 * 1024 * 1024); // check if there is atleast 1GB left afterwards. aim for 60% because rsync/tgz won't need full 100% - if (result.available <= needed) return callback(new BoxError(BoxError.FS_ERROR, `Not enough disk space for backup. Needed: ${prettyBytes(needed)} Available: ${prettyBytes(result.available)}`)); - - callback(null); + if (result.available <= needed) throw new BoxError(BoxError.FS_ERROR, `Not enough disk space for backup. Needed: ${prettyBytes(needed)} Available: ${prettyBytes(result.available)}`); } function hasChownSupportSync(apiConfig) { diff --git a/src/storage/gcs.js b/src/storage/gcs.js index 462eb122c..d66cc1773 100644 --- a/src/storage/gcs.js +++ b/src/storage/gcs.js @@ -70,12 +70,9 @@ function getRootPath(apiConfig) { return apiConfig.prefix; } -function checkPreconditions(apiConfig, dataLayout, callback) { +async function checkPreconditions(apiConfig, dataLayout) { assert.strictEqual(typeof apiConfig, 'object'); assert(dataLayout instanceof DataLayout, 'dataLayout must be a DataLayout'); - assert.strictEqual(typeof callback, 'function'); - - callback(null); } function upload(apiConfig, backupFilePath, sourceStream, callback) { diff --git a/src/storage/interface.js b/src/storage/interface.js index 353f5b30b..8bb9949d0 100644 --- a/src/storage/interface.js +++ b/src/storage/interface.js @@ -34,7 +34,7 @@ exports = module.exports = { injectPrivateFields }; -var assert = require('assert'), +const assert = require('assert'), BoxError = require('../boxerror.js'), DataLayout = require('../datalayout.js'), EventEmitter = require('events'); @@ -56,12 +56,9 @@ function getRootPath(apiConfig) { return '/'; } -function checkPreconditions(apiConfig, dataLayout, callback) { +async function checkPreconditions(apiConfig, dataLayout) { assert.strictEqual(typeof apiConfig, 'object'); assert(dataLayout instanceof DataLayout, 'dataLayout must be a DataLayout'); - assert.strictEqual(typeof callback, 'function'); - - callback(null); } function upload(apiConfig, backupFilePath, sourceStream, callback) { diff --git a/src/storage/noop.js b/src/storage/noop.js index d3a10ca82..772d2b1d5 100644 --- a/src/storage/noop.js +++ b/src/storage/noop.js @@ -22,7 +22,7 @@ exports = module.exports = { injectPrivateFields }; -var assert = require('assert'), +const assert = require('assert'), BoxError = require('../boxerror.js'), DataLayout = require('../datalayout.js'), debug = require('debug')('box:storage/noop'), @@ -33,12 +33,9 @@ function getRootPath(apiConfig) { return ''; } -function checkPreconditions(apiConfig, dataLayout, callback) { +async function checkPreconditions(apiConfig, dataLayout) { assert.strictEqual(typeof apiConfig, 'object'); assert(dataLayout instanceof DataLayout, 'dataLayout must be a DataLayout'); - assert.strictEqual(typeof callback, 'function'); - - callback(null); } function upload(apiConfig, backupFilePath, sourceStream, callback) { diff --git a/src/storage/s3.js b/src/storage/s3.js index fa2e3fac2..7f953c0be 100644 --- a/src/storage/s3.js +++ b/src/storage/s3.js @@ -98,12 +98,9 @@ function getRootPath(apiConfig) { return apiConfig.prefix; } -function checkPreconditions(apiConfig, dataLayout, callback) { +async function checkPreconditions(apiConfig, dataLayout) { assert.strictEqual(typeof apiConfig, 'object'); assert(dataLayout instanceof DataLayout, 'dataLayout must be a DataLayout'); - assert.strictEqual(typeof callback, 'function'); - - callback(null); } function upload(apiConfig, backupFilePath, sourceStream, callback) {