Add migration lock

This commit is contained in:
Girish Ramakrishnan
2015-07-16 11:38:55 -07:00
parent d4365f7748
commit 85a2b09cf2
3 changed files with 31 additions and 12 deletions
+25 -7
View File
@@ -364,8 +364,24 @@ function migrate(size, region, callback) {
assert.strictEqual(typeof region, 'string');
assert.strictEqual(typeof callback, 'function');
backup(function (error, restoreKey) {
if (error) return callback(error);
var error = locker.lock(locker.OP_MIGRATE);
if (error) return callback(new CloudronError(CloudronError.BAD_STATE, error.message));
function unlock(error) {
if (error) {
debug('Failed to migrate', error);
locker.unlock(locker.OP_MIGRATE);
} else {
debug('Migration initiated successfully');
// do not unlock; cloudron is migrating
}
return;
}
// initiate the migration in the background
backupBoxAndApps(function (error, restoreKey) {
if (error) return unlock(error);
debug('migrate: size %s region %s restoreKey %s', size, region, restoreKey);
@@ -374,14 +390,16 @@ function migrate(size, region, callback) {
.query({ token: config.token() })
.send({ size: size, region: region, restoreKey: restoreKey })
.end(function (error, result) {
if (error) return callback(error);
if (result.status === 409) return callback(new CloudronError(CloudronError.BAD_STATE));
if (result.status === 404) return callback(new CloudronError(CloudronError.NOT_FOUND));
if (result.status !== 202) return callback(new CloudronError(CloudronError.EXTERNAL_ERROR, util.format('%s %j', result.status, result.body)));
if (error) return unlock(error);
if (result.status === 409) return unlock(new CloudronError(CloudronError.BAD_STATE));
if (result.status === 404) return unlock(new CloudronError(CloudronError.NOT_FOUND));
if (result.status !== 202) return unlock(new CloudronError(CloudronError.EXTERNAL_ERROR, util.format('%s %j', result.status, result.body)));
return callback(null);
return unlock(null);
});
});
callback(null);
}
function update(boxUpdateInfo, callback) {
+2
View File
@@ -12,9 +12,11 @@ function Locker() {
}
util.inherits(Locker, EventEmitter);
// these are mutually exclusive operations
Locker.prototype.OP_BOX_UPDATE = 'box_update';
Locker.prototype.OP_FULL_BACKUP = 'full_backup';
Locker.prototype.OP_APPTASK = 'apptask';
Locker.prototype.OP_MIGRATE = 'migrate';
Locker.prototype.lock = function (operation) {
assert.strictEqual(typeof operation, 'string');
+4 -5
View File
@@ -148,12 +148,11 @@ function migrate(req, res, next) {
debug('Migration requested', req.body.size, req.body.region);
cloudron.migrate(req.body.size, req.body.region, function (error) {
if (error) return console.error('Migration failed.', error);
debug('Migration successfully triggered');
});
if (error && error.reason === CloudronError.BAD_STATE) return next(new HttpError(409, error.message));
if (error) return next(new HttpError(500, error));
// do not wait for migrate() to callback. The migration will first do a backup, which can take very long
next(new HttpSuccess(202, {}));
next(new HttpSuccess(202, {}));
});
}
function setCertificate(req, res, next) {