Propagate error messages from backuptask into box code

This commit is contained in:
Girish Ramakrishnan
2017-04-21 14:07:10 -07:00
parent 0aea7cc347
commit 6c8b9b8799
4 changed files with 49 additions and 19 deletions
+34 -13
View File
@@ -35,13 +35,13 @@ var addons = require('./addons.js'),
debug = require('debug')('box:backups'),
eventlog = require('./eventlog.js'),
filesystem = require('./storage/filesystem.js'),
fs = require('fs'),
locker = require('./locker.js'),
mailer = require('./mailer.js'),
path = require('path'),
paths = require('./paths.js'),
progress = require('./progress.js'),
s3 = require('./storage/s3.js'),
safe = require('safetydance'),
shell = require('./shell.js'),
settings = require('./settings.js'),
SettingsError = require('./settings.js').SettingsError,
@@ -166,6 +166,23 @@ function copyLastBackup(app, manifest, prefix, callback) {
});
}
function runBackupTask(backupId, appId, callback) {
assert.strictEqual(typeof backupId, 'string');
assert(appId === null || typeof backupId === 'string');
assert.strictEqual(typeof callback, 'function');
shell.sudo('backup' + (appId ? 'App' : 'Box'), [ NODE_CMD, BACKUPTASK_CMD, backupId ].concat(appId ? [ appId ] : [ ]), function (error) {
if (error && (error.code === null /* signal */ || (error.code !== 0 && error.code !== 50))) { // backuptask crashed
return callback(new BackupsError(BackupsError.INTERNAL_ERROR, 'backuptask crashed'));
} else if (error && error.code === 50) { // exited with error
var result = safe.fs.readFileSync(paths.BACKUP_RESULT_FILE, 'utf8') || safe.error.message;
return callback(new BackupsError(BackupsError.EXTERNAL_ERROR, result));
}
callback();
});
}
function backupBoxWithAppBackupIds(appBackupIds, prefix, callback) {
assert(Array.isArray(appBackupIds));
assert.strictEqual(typeof prefix, 'string');
@@ -180,8 +197,8 @@ function backupBoxWithAppBackupIds(appBackupIds, prefix, callback) {
shell.exec('backupBox', '/bin/bash', mysqlDumpArgs, function (error) {
if (error) return callback(new BackupsError(BackupsError.INTERNAL_ERROR, error));
shell.sudo('backupBox', [ NODE_CMD, BACKUPTASK_CMD, backupId ], function (error) {
if (error) return callback(new BackupsError(BackupsError.INTERNAL_ERROR, error));
runBackupTask(backupId, null /* appId */, function (error) {
if (error) return callback(error);
debug('backupBoxWithAppBackupIds: success');
@@ -220,19 +237,23 @@ function createNewAppBackup(app, manifest, prefix, callback) {
var restoreConfig = apps.getAppConfig(app);
restoreConfig.manifest = manifest;
async.series([
fs.writeFile.bind(null, path.join(paths.APPS_DATA_DIR, app.id + '/config.json'), JSON.stringify(restoreConfig)),
addons.backupAddons.bind(null, app, manifest.addons),
shell.sudo.bind(null, 'backupApp', [ NODE_CMD, BACKUPTASK_CMD, backupId, app.id ])
], function (error) {
if (error) return callback(new BackupsError(BackupsError.INTERNAL_ERROR, error));
if (!safe.fs.writeFileSync(path.join(paths.APPS_DATA_DIR, app.id + '/config.json'), JSON.stringify(restoreConfig))) {
return callback(new BackupsError(BackupsError.EXTERNAL_ERROR, 'Error creating config.json: ' + safe.error.message));
}
debugApp(app, 'createNewAppBackup: %s done', backupId);
addons.backupAddons(app, manifest.addons, function (error) {
if (error) return callback(new BackupsError(BackupsError.EXTERNAL_ERROR, error.message));
backupdb.add({ id: backupId, version: manifest.version, type: backupdb.BACKUP_TYPE_APP, dependsOn: [ ], restoreConfig: restoreConfig }, function (error) {
if (error) return callback(new BackupsError(BackupsError.INTERNAL_ERROR, error));
runBackupTask(backupId, app.id, function (error) {
if (error) return callback(new BackupsError(BackupsError.EXTERNAL_ERROR, error.message));
callback(null, backupId);
debugApp(app, 'createNewAppBackup: %s done', backupId);
backupdb.add({ id: backupId, version: manifest.version, type: backupdb.BACKUP_TYPE_APP, dependsOn: [ ], restoreConfig: restoreConfig }, function (error) {
if (error) return callback(new BackupsError(BackupsError.INTERNAL_ERROR, error));
callback(null, backupId);
});
});
});
}
+8 -5
View File
@@ -10,14 +10,15 @@ require('debug').formatArgs = function formatArgs(args) {
};
var assert = require('assert'),
BackupsError = require('./backups.js').BackupsError,
caas = require('./storage/caas.js'),
database = require('./database.js'),
debug = require('debug')('box:backuptask'),
filesystem = require('./storage/filesystem.js'),
path = require('path'),
paths = require('./paths.js'),
filesystem = require('./storage/filesystem.js'),
caas = require('./storage/caas.js'),
s3 = require('./storage/s3.js'),
BackupsError = require('./backups.js').BackupsError,
safe = require('safetydance'),
settings = require('./settings.js');
function api(provider) {
@@ -90,9 +91,11 @@ initialize(function (error) {
if (error) throw error;
function resultHandler(error) {
if (error) debug('Backuptask completed with error', error);
if (error) debug('completed with error', error);
debug('Backuptask completed');
debug('completed');
safe.fs.writeFileSync(paths.BACKUP_RESULT_FILE, error ? error.message : '');
// https://nodejs.org/api/process.html are exit codes used by node. apps.js uses the value below
// to check apptask crashes
+1
View File
@@ -7,6 +7,7 @@ var config = require('./config.js'),
exports = module.exports = {
CLOUDRON_DEFAULT_AVATAR_FILE: path.join(__dirname + '/../assets/avatar.png'),
INFRA_VERSION_FILE: path.join(config.baseDir(), 'platformdata/INFRA_VERSION'),
BACKUP_RESULT_FILE: path.join(config.baseDir(), 'platformdata/backupresult'),
OLD_DATA_DIR: path.join(config.baseDir(), 'data'),
PLATFORM_DATA_DIR: path.join(config.baseDir(), 'platformdata'),
+6 -1
View File
@@ -50,8 +50,12 @@ function exec(tag, file, args, callback) {
cp.on('exit', function (code, signal) {
if (code || signal) debug(tag + ' code: %s, signal: %s', code, signal);
if (code === 0) return callback();
callback(code === 0 ? null : new Error(util.format(tag + ' exited with error %s signal %s', code, signal)));
var e = new Error(util.format(tag + ' exited with error %s signal %s', code, signal));
e.code = code;
e.signal = signal;
callback(e);
});
cp.on('error', function (error) {
@@ -70,6 +74,7 @@ function sudo(tag, args, callback) {
// -S makes sudo read stdin for password
var cp = exec(tag, SUDO, [ '-S' ].concat(args), callback);
cp.stdin.end();
return cp;
}
function sudoSync(tag, cmd, callback) {