diff --git a/src/backups.js b/src/backups.js index 7e15b8e30..cebb9fbad 100644 --- a/src/backups.js +++ b/src/backups.js @@ -813,18 +813,24 @@ function cleanupAppBackups(backupConfig, referencedAppBackups, callback) { debug('cleanupAppBackups: removing %s', backup.id); var removeFunc = backup.format ==='tgz' ? api(backupConfig.provider).remove : api(backupConfig.provider).removeDir; + var backupFilePath = getBackupFilePath(backupConfig, backup.id, backup.format); - removeFunc(backupConfig, getBackupFilePath(backupConfig, backup.id, backup.format), function (error) { + removeFunc(backupConfig, backupFilePath, function (error) { if (error) { debug('cleanupAppBackups: error removing backup %j : %s', backup, error.message); iteratorDone(); } - backupdb.del(backup.id, function (error) { - if (error) debug('cleanupAppBackups: error removing from database', error); - else debug('cleanupAppBackups: removed %s', backup.id); + // prune empty directory + api(backupConfig.provider).remove(backupConfig, path.dirname(backupFilePath), function (error) { + if (error) debug('cleanupAppBackups: unable to remove backup directory %j : %s', backup, error.message); - iteratorDone(); + backupdb.del(backup.id, function (error) { + if (error) debug('cleanupAppBackups: error removing from database', error); + else debug('cleanupAppBackups: removed %s', backup.id); + + iteratorDone(); + }); }); }); }, function () { @@ -874,9 +880,14 @@ function cleanupBoxBackups(backupConfig, callback) { // TODO: assumes all backups have the same format var filePaths = [].concat(backup.id, backup.dependsOn).map(function (id) { return getBackupFilePath(backupConfig, id, backup.format); }); - var removeFunc = backup.format ==='tgz' ? api(backupConfig.provider).remove : api(backupConfig.provider).removeDir; + async.eachSeries(filePaths, function (filePath, next) { + var removeFunc = backup.format ==='tgz' ? api(backupConfig.provider).remove : api(backupConfig.provider).removeDir; - async.eachSeries(filePaths, removeFunc.bind(null, backupConfig), function (error) { + async.series([ + removeFunc.bind(null, backupConfig, filePath), + api(backupConfig.provider).remove.bind(null, backupConfig, path.dirname(filePath)) + ], next); + }, function (error) { if (error) { debug('cleanupBoxBackups: error removing backup %j : %s', backup, error.message); iteratorDone(); diff --git a/src/storage/filesystem.js b/src/storage/filesystem.js index 1be8bc235..6123ac35b 100644 --- a/src/storage/filesystem.js +++ b/src/storage/filesystem.js @@ -116,9 +116,14 @@ function remove(apiConfig, filename, callback) { assert.strictEqual(typeof filename, 'string'); assert.strictEqual(typeof callback, 'function'); - safe.fs.unlinkSync(filename); + var stat = safe.fs.statSync(filename); + if (!stat) return callback(); - safe.fs.rmdirSync(path.dirname(filename)); // try to cleanup empty directories + if (stat.isFile()) { + safe.fs.unlinkSync(filename); + } else if (stat.isDirectory()) { + safe.fs.rmdirSync(path.dirname(filename)); + } callback(); } @@ -131,8 +136,6 @@ function removeDir(apiConfig, pathPrefix, callback) { shell.exec('removeDir', '/bin/rm', [ '-rf', pathPrefix ], { }, function (error) { if (error) return callback(new BackupsError(BackupsError.EXTERNAL_ERROR, error.message)); - safe.fs.rmdirSync(path.dirname(pathPrefix)); // try to cleanup empty directories - callback(); }); }