diff --git a/src/backupcleaner.js b/src/backupcleaner.js index 8be282440..b46764b7b 100644 --- a/src/backupcleaner.js +++ b/src/backupcleaner.js @@ -20,7 +20,6 @@ const apps = require('./apps.js'), safe = require('safetydance'), settings = require('./settings.js'), storage = require('./storage.js'), - util = require('util'), _ = require('underscore'); function applyBackupRetentionPolicy(allBackups, policy, referencedBackupIds) { @@ -211,8 +210,7 @@ async function cleanupMissingBackups(backupConfig, progressCallback) { assert.strictEqual(typeof progressCallback, 'function'); const perPage = 1000; - let missingBackupPaths = []; - const backupExists = util.promisify(storage.api(backupConfig.provider).exists); + const missingBackupPaths = []; if (constants.TEST) return missingBackupPaths; @@ -224,7 +222,7 @@ async function cleanupMissingBackups(backupConfig, progressCallback) { let backupFilePath = storage.getBackupFilePath(backupConfig, backup.remotePath, backup.format); if (backup.format === 'rsync') backupFilePath = backupFilePath + '/'; // add trailing slash to indicate directory - const [existsError, exists] = await safe(backupExists(backupConfig, backupFilePath)); + const [existsError, exists] = await safe(storage.api(backupConfig.provider).exists(backupConfig, backupFilePath)); if (existsError || exists) continue; await progressCallback({ message: `Removing missing backup ${backup.remotePath}`}); diff --git a/src/storage/filesystem.js b/src/storage/filesystem.js index 7d2dab69c..ccb114cdc 100644 --- a/src/storage/filesystem.js +++ b/src/storage/filesystem.js @@ -159,18 +159,17 @@ function download(apiConfig, sourceFilePath, callback) { callback(null, fileStream); } -function exists(apiConfig, sourceFilePath, callback) { +async function exists(apiConfig, sourceFilePath) { assert.strictEqual(typeof apiConfig, 'object'); assert.strictEqual(typeof sourceFilePath, 'string'); - assert.strictEqual(typeof callback, 'function'); // do not use existsSync because it does not return EPERM etc if (!safe.fs.statSync(sourceFilePath)) { - if (safe.error && safe.error.code === 'ENOENT') return callback(null, false); - if (safe.error) return callback(new BoxError(BoxError.EXTERNAL_ERROR, `Exists ${sourceFilePath}: ${safe.error.message}`)); + if (safe.error && safe.error.code === 'ENOENT') return false; + if (safe.error) throw new BoxError(BoxError.EXTERNAL_ERROR, `Exists ${sourceFilePath}: ${safe.error.message}`); } - callback(null, true); + return true; } function listDir(apiConfig, dir, batchSize, iteratorCallback, callback) { diff --git a/src/storage/gcs.js b/src/storage/gcs.js index 595d11966..d8247a704 100644 --- a/src/storage/gcs.js +++ b/src/storage/gcs.js @@ -102,21 +102,19 @@ function upload(apiConfig, backupFilePath, sourceStream, callback) { sourceStream.pipe(uploadStream); } -function exists(apiConfig, backupFilePath, callback) { +async function exists(apiConfig, backupFilePath) { assert.strictEqual(typeof apiConfig, 'object'); assert.strictEqual(typeof backupFilePath, 'string'); - assert.strictEqual(typeof callback, 'function'); const bucket = getBucket(apiConfig); if (!backupFilePath.endsWith('/')) { const file = bucket.file(backupFilePath); - file.getMetadata(function (error) { - if (error && error.code === 404) return callback(null, false); - if (error) return callback(new BoxError(BoxError.EXTERNAL_ERROR, error.message)); + const [error] = await safe(file.getMetadata()); + if (error && error.code === 404) return false; + if (error) throw new BoxError(BoxError.EXTERNAL_ERROR, error.message); - callback(null, true); - }); + return true; } else { const query = { prefix: backupFilePath, @@ -124,11 +122,10 @@ function exists(apiConfig, backupFilePath, callback) { autoPaginate: true }; - bucket.getFiles(query, function (error, files) { - if (error) return callback(error); + const [error, files] = await safe(bucket.getFiles(query)); + if (error) throw new BoxError(BoxError.EXTERNAL_ERROR, error.message); - callback(null, files.length !== 0); - }); + return files.length !== 0; } } diff --git a/src/storage/interface.js b/src/storage/interface.js index 67304af24..19d959b56 100644 --- a/src/storage/interface.js +++ b/src/storage/interface.js @@ -73,12 +73,11 @@ function upload(apiConfig, backupFilePath, sourceStream, callback) { callback(new BoxError(BoxError.NOT_IMPLEMENTED, 'upload is not implemented')); } -function exists(apiConfig, backupFilePath, callback) { +async function exists(apiConfig, backupFilePath) { assert.strictEqual(typeof apiConfig, 'object'); assert.strictEqual(typeof backupFilePath, 'string'); - assert.strictEqual(typeof callback, 'function'); - callback(new BoxError(BoxError.NOT_IMPLEMENTED, 'exists is not implemented')); + throw new BoxError(BoxError.NOT_IMPLEMENTED, 'exists is not implemented'); } function download(apiConfig, backupFilePath, callback) { diff --git a/src/storage/noop.js b/src/storage/noop.js index 6fc586d84..b80c1eecd 100644 --- a/src/storage/noop.js +++ b/src/storage/noop.js @@ -49,14 +49,13 @@ function upload(apiConfig, backupFilePath, sourceStream, callback) { callback(null); } -function exists(apiConfig, backupFilePath, callback) { +async function exists(apiConfig, backupFilePath) { assert.strictEqual(typeof apiConfig, 'object'); assert.strictEqual(typeof backupFilePath, 'string'); - assert.strictEqual(typeof callback, 'function'); - debug('exists: %s', backupFilePath); + debug(`exists: ${backupFilePath}`); - callback(null, false); + return false; } function download(apiConfig, backupFilePath, callback) { diff --git a/src/storage/s3.js b/src/storage/s3.js index a103cf411..e59189951 100644 --- a/src/storage/s3.js +++ b/src/storage/s3.js @@ -138,10 +138,9 @@ function upload(apiConfig, backupFilePath, sourceStream, callback) { }); } -function exists(apiConfig, backupFilePath, callback) { +async function exists(apiConfig, backupFilePath) { assert.strictEqual(typeof apiConfig, 'object'); assert.strictEqual(typeof backupFilePath, 'string'); - assert.strictEqual(typeof callback, 'function'); const credentials = getS3Config(apiConfig); @@ -153,13 +152,12 @@ function exists(apiConfig, backupFilePath, callback) { Key: backupFilePath }; - s3.headObject(params, function (error) { - if (!Object.keys(this.httpResponse.headers).some(h => h.startsWith('x-amz'))) return callback(new BoxError(BoxError.EXTERNAL_ERROR, 'not a s3 endpoint')); - if (error && S3_NOT_FOUND(error)) return callback(null, false); - if (error) return callback(new BoxError(BoxError.EXTERNAL_ERROR, `Error headObject ${backupFilePath}. Message: ${error.message} HTTP Code: ${error.code}`)); + const [error] = await safe(s3.headObject(params).promise()); + if (!Object.keys(this.httpResponse.headers).some(h => h.startsWith('x-amz'))) throw new BoxError(BoxError.EXTERNAL_ERROR, 'not a s3 endpoint'); + if (error && S3_NOT_FOUND(error)) return false; + if (error) throw new BoxError(BoxError.EXTERNAL_ERROR, `Error headObject ${backupFilePath}. Message: ${error.message} HTTP Code: ${error.code}`); - callback(null, true); - }); + return true; } else { // list dir contents const listParams = { Bucket: apiConfig.bucket, @@ -167,11 +165,10 @@ function exists(apiConfig, backupFilePath, callback) { MaxKeys: 1 }; - s3.listObjects(listParams, function (error, listData) { - if (error) return callback(new BoxError(BoxError.EXTERNAL_ERROR, `Error listing objects ${backupFilePath}. Message: ${error.message} HTTP Code: ${error.code}`)); + const [error, listData] = await safe(s3.listObjects(listParams).promise()); + if (error) throw new BoxError(BoxError.EXTERNAL_ERROR, `Error listing objects ${backupFilePath}. Message: ${error.message} HTTP Code: ${error.code}`); - callback(null, listData.Contents.length !== 0); - }); + return listData.Contents.length !== 0; } }