Add migration lock
This commit is contained in:
+25
-7
@@ -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) {
|
||||
|
||||
@@ -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');
|
||||
|
||||
@@ -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) {
|
||||
|
||||
Reference in New Issue
Block a user