Make schedule task take the command as arg

This commit is contained in:
Girish Ramakrishnan
2019-09-23 14:17:12 -07:00
parent 890a7cfb37
commit b401c3d930

View File

@@ -622,21 +622,20 @@ function mailboxNameForLocation(location, manifest) {
return (location ? location : manifest.title.toLowerCase().replace(/[^a-zA-Z0-9]/g, '')) + '.app';
}
function scheduleTask(appId, args, values, callback) {
function scheduleTask(appId, installationState, task, callback) {
assert.strictEqual(typeof appId, 'string');
assert.strictEqual(typeof args, 'object');
assert.strictEqual(typeof values, 'object');
assert.strictEqual(typeof installationState, 'string');
assert.strictEqual(typeof task, 'object'); // { args, values }
assert.strictEqual(typeof callback, 'function');
assert(values.installationState);
const { args, values } = task;
tasks.add(tasks.TASK_APP, [ appId, args ], function (error, taskId) {
if (error) return callback(new AppsError(AppsError.INTERNAL_ERROR, error));
values.error = null;
values.taskId = taskId;
appdb.setTask(appId, values, function (error) {
appdb.setTask(appId, _.extend({ installationState, taskId }, values), function (error) {
if (error && error.reason === DatabaseError.ALREADY_EXISTS) return callback(new AppsError(AppsError.ALREADY_EXISTS, error.message));
if (error && error.reason === DatabaseError.NOT_FOUND) return callback(new AppsError(AppsError.BAD_STATE, 'Another task is scheduled for this app')); // could be because app went away OR a taskId exists
if (error) return callback(new AppsError(AppsError.INTERNAL_ERROR, error));
@@ -805,8 +804,12 @@ function install(data, user, auditSource, callback) {
}
const restoreConfig = backupId ? { backupId: backupId, backupFormat: backupFormat } : null;
const task = {
args: { restoreConfig, overwriteDns },
values: { }
};
scheduleTask(appId, { restoreConfig, overwriteDns }, { installationState: exports.ISTATE_PENDING_INSTALL }, function (error, result) {
scheduleTask(appId, exports.ISTATE_PENDING_INSTALL, task, function (error, result) {
if (error) return callback(error);
const newApp = _.extend({ fqdn: domains.fqdn(location, domainObject) }, data, { appStoreId, manifest, location, domain, portBindings });
@@ -929,7 +932,11 @@ function setMemoryLimit(appId, memoryLimit, auditSource, callback) {
error = validateMemoryLimit(app.manifest, memoryLimit);
if (error) return callback(error);
scheduleTask(appId, {}, { installationState: exports.ISTATE_PENDING_RESIZE, memoryLimit: memoryLimit }, function (error, result) {
const task = {
args: {},
values: { memoryLimit }
};
scheduleTask(appId, exports.ISTATE_PENDING_RESIZE, task, function (error, result) {
if (error) return callback(error);
eventlog.add(eventlog.ACTION_APP_CONFIGURE, auditSource, { appId: appId, app: app, memoryLimit: memoryLimit, taskId: result.taskId });
@@ -954,7 +961,11 @@ function setEnvironment(appId, env, auditSource, callback) {
error = validateEnv(env);
if (error) return callback(error);
scheduleTask(appId, {}, { installationState: exports.ISTATE_PENDING_RECREATE_CONTAINER, env: env }, function (error, result) {
const task = {
args: {},
values: { env }
};
scheduleTask(appId, exports.ISTATE_PENDING_RECREATE_CONTAINER, task, function (error, result) {
if (error) return callback(error);
eventlog.add(eventlog.ACTION_APP_CONFIGURE, auditSource, { appId: appId, app: app, env: env, taskId: result.taskId });
@@ -979,7 +990,11 @@ function setDebugMode(appId, debugMode, auditSource, callback) {
error = validateDebugMode(debugMode);
if (error) return callback(error);
scheduleTask(appId, {}, { installationState: exports.ISTATE_PENDING_DEBUG, debugMode: debugMode }, function (error, result) {
const task = {
args: {},
values: { debugMode }
};
scheduleTask(appId, exports.ISTATE_PENDING_DEBUG, task, function (error, result) {
if (error) return callback(error);
eventlog.add(eventlog.ACTION_APP_CONFIGURE, auditSource, { appId: appId, app: app, debugMode: debugMode, taskId: result.taskId });
@@ -1008,7 +1023,11 @@ function setMailbox(appId, mailboxName, auditSource, callback) {
mailboxName = mailboxNameForLocation(app.location, app.manifest);
}
scheduleTask(appId, {}, { installationState: exports.ISTATE_PENDING_RECREATE_CONTAINER, mailboxName: mailboxName }, function (error, result) {
const task = {
args: {},
values: { mailboxName }
};
scheduleTask(appId, exports.ISTATE_PENDING_RECREATE_CONTAINER, task, function (error, result) {
if (error) return callback(error);
eventlog.add(eventlog.ACTION_APP_CONFIGURE, auditSource, { appId: appId, app: app, mailboxName: mailboxName, taskId: result.taskId });
@@ -1127,7 +1146,6 @@ function setLocation(appId, data, auditSource, callback) {
if (error) return callback(error);
let values = {
installationState: exports.ISTATE_PENDING_LOCATION_CHANGE,
// these are intentionally reset, if not set
portBindings: null,
alternateDomains: []
@@ -1158,11 +1176,14 @@ function setLocation(appId, data, auditSource, callback) {
error = domains.validateHostname(values.location, domainObject);
if (error) return callback(new AppsError(AppsError.BAD_FIELD, 'Bad location: ' + error.message, { field: 'location' }));
const args = {
oldConfig: _.pick(app, 'location', 'domain', 'fqdn', 'alternateDomains', 'portBindings'),
overwriteDns: !!data.overwriteDns
const task = {
args: {
oldConfig: _.pick(app, 'location', 'domain', 'fqdn', 'alternateDomains', 'portBindings'),
overwriteDns: !!data.overwriteDns
},
values
};
scheduleTask(appId, args, values, function (error, result) {
scheduleTask(appId, exports.ISTATE_PENDING_LOCATION_CHANGE, task, function (error, result) {
if (error && error.reason === AppsError.ALREADY_EXISTS) error = getDuplicateErrorDetails(error.message, values.location, domainObject, data.portBindings, app.alternateDomains);
if (error) return callback(error);
@@ -1189,7 +1210,11 @@ function setDataDir(appId, dataDir, auditSource, callback) {
error = validateDataDir(dataDir);
if (error) return callback(error);
scheduleTask(appId, { oldDataDir: app.dataDir }, { installationState: exports.ISTATE_PENDING_DATA_DIR_MIGRATION, dataDir: dataDir }, function (error, result) {
const task = {
args: { oldDataDir: app.dataDir },
values: { dataDir: dataDir }
};
scheduleTask(appId, exports.ISTATE_PENDING_DATA_DIR_MIGRATION, task, function (error, result) {
if (error) return callback(error);
eventlog.add(eventlog.ACTION_APP_CONFIGURE, auditSource, { appId: appId, app: app, dataDir: dataDir, taskId: result.taskId });
@@ -1265,7 +1290,11 @@ function update(appId, data, auditSource, callback) {
updateConfig.memoryLimit = updateConfig.manifest.memoryLimit;
}
scheduleTask(appId, { updateConfig: updateConfig }, { installationState: exports.ISTATE_PENDING_UPDATE }, function (error, result) {
const task = {
args: { updateConfig },
values: {}
};
scheduleTask(appId, exports.ISTATE_PENDING_UPDATE, task, function (error, result) {
if (error) return callback(error);
eventlog.add(eventlog.ACTION_APP_UPDATE, auditSource, { appId: appId, toManifest: manifest, fromManifest: app.manifest, force: data.force, app: app, taskId: result.taskId });
@@ -1350,13 +1379,12 @@ function repair(appId, data, auditSource, callback) {
debug(`Repairing app with error: ${JSON.stringify(error)} and state: ${newState}`);
let values = _.pick(data, 'location', 'domain', 'alternateDomains'); // FIXME: validate
values.installationState = newState;
let args = appError.task ? appError.task.args : {};
args.restoreConfig = data.backupId ? { backupId: data.backupId, backupFormat: data.backupFormat, oldManifest: app.manifest } : null; // when null, apptask simply reinstalls
args.overwriteDns = 'overwriteDns' in data ? data.overwriteDns : false;
scheduleTask(appId, args, values, function (error, result) {
scheduleTask(appId, newState, { args, values }, function (error, result) {
if (error) return callback(error);
eventlog.add(eventlog.ACTION_APP_REPAIR, auditSource, { taskId: result.taskId, app, newState });
@@ -1394,13 +1422,18 @@ function restore(appId, data, auditSource, callback) {
error = checkManifestConstraints(backupInfo.manifest);
if (error) return callback(error);
let values = {
installationState: exports.ISTATE_PENDING_RESTORE,
manifest: backupInfo.manifest
};
const restoreConfig = data.backupId ? { backupId: data.backupId, backupFormat: backupInfo.format, oldManifest: app.manifest } : null; // when null, apptask simply reinstalls
scheduleTask(appId, { restoreConfig, overwriteDns: true }, values, function (error, result) {
const task = {
args: {
restoreConfig,
overwriteDns: true
},
values: {
manifest: backupInfo.manifest
}
};
scheduleTask(appId, exports.ISTATE_PENDING_RESTORE, task, function (error, result) {
if (error) return callback(error);
eventlog.add(eventlog.ACTION_APP_RESTORE, auditSource, { app: app, backupId: backupInfo.id, fromManifest: app.manifest, toManifest: backupInfo.manifest, taskId: result.taskId });
@@ -1509,8 +1542,11 @@ function clone(appId, data, user, auditSource, callback) {
if (error) return callback(error);
const restoreConfig = { backupId: backupId, backupFormat: backupInfo.format };
scheduleTask(newAppId, { restoreConfig, overwriteDns }, { installationState: exports.ISTATE_PENDING_CLONE }, function (error, result) {
const task = {
args: { restoreConfig, overwriteDns },
values: {}
};
scheduleTask(newAppId, exports.ISTATE_PENDING_CLONE, task, function (error, result) {
if (error) return callback(error);
const newApp = _.extend({}, data, { appStoreId, manifest, location, domain, portBindings });
@@ -1545,7 +1581,11 @@ function uninstall(appId, auditSource, callback) {
if (error && error.reason === AppstoreError.EXTERNAL_ERROR) return callback(new AppsError(AppsError.EXTERNAL_ERROR, error.message));
if (error) return callback(new AppsError(AppsError.INTERNAL_ERROR, error));
scheduleTask(appId, { /* args */ }, { installationState: exports.ISTATE_PENDING_UNINSTALL }, function (error, result) {
const task = {
args: {},
values: {}
};
scheduleTask(appId, exports.ISTATE_PENDING_UNINSTALL, task, function (error, result) {
if (error) return callback(error);
eventlog.add(eventlog.ACTION_APP_UNINSTALL, auditSource, { appId: appId, app: app, taskId: result.taskId });
@@ -1568,7 +1608,15 @@ function start(appId, callback) {
error = checkAppState(app, exports.ISTATE_PENDING_START);
if (error) return callback(error);
scheduleTask(appId, { /* args */ }, { installationState: exports.ISTATE_PENDING_START, runState: exports.RSTATE_RUNNING }, callback);
const task = {
args: {},
values: { runState: exports.RSTATE_RUNNING }
};
scheduleTask(appId, exports.ISTATE_PENDING_START, task, function (error, result) {
if (error) return callback(error);
callback(null, { taskId: result.taskId });
});
});
}
@@ -1584,7 +1632,15 @@ function stop(appId, callback) {
error = checkAppState(app, exports.ISTATE_PENDING_STOP);
if (error) return callback(error);
scheduleTask(appId, { /* args */ }, { installationState: exports.ISTATE_PENDING_STOP, runState: exports.RSTATE_STOPPED }, callback);
const task = {
args: {},
values: { runState: exports.RSTATE_STOPPED }
};
scheduleTask(appId, exports.ISTATE_PENDING_STOP, task, function (error, result) {
if (error) return callback(error);
callback(null, { taskId: result.taskId });
});
});
}
@@ -1730,7 +1786,11 @@ function backup(appId, callback) {
error = checkAppState(app, exports.ISTATE_PENDING_BACKUP);
if (error) return callback(error);
scheduleTask(appId, { /* args */ }, { installationState: exports.ISTATE_PENDING_BACKUP }, (error, result) => {
const task = {
args: {},
values: {}
};
scheduleTask(appId, exports.ISTATE_PENDING_BACKUP, task, (error, result) => {
if (error) return callback(error);
callback(null, { taskId: result.taskId });
@@ -1773,7 +1833,11 @@ function restoreInstalledApps(callback) {
appdb.update(app.id, { taskId: null, error: null }, function (error) { // clear any stale taskId
if (error) debug(`Error marking ${app.fqdn} for restore: ${JSON.stringify(error)}`);
scheduleTask(app.id, { restoreConfig, overwriteDns: true }, { installationState: exports.ISTATE_PENDING_RESTORE }, () => iteratorDone()); // always succeed
const task = {
args: { restoreConfig, overwriteDns: true },
values: {}
};
scheduleTask(app.id, exports.ISTATE_PENDING_RESTORE, task, () => iteratorDone()); // always succeed
});
});
}, callback);
@@ -1794,7 +1858,11 @@ function configureInstalledApps(callback) {
if (error) debug(`Error marking ${app.fqdn} for reconfigure: ${JSON.stringify(error)}`);
const oldConfig = _.pick(app, 'location', 'domain', 'fqdn', 'alternateDomains', 'portBindings');
scheduleTask(app.id, { oldConfig }, { installationState: exports.ISTATE_PENDING_CONFIGURE }, () => iteratorDone()); // always succeed
const task = {
args: { oldConfig },
values: {}
};
scheduleTask(app.id, exports.ISTATE_PENDING_CONFIGURE, task, () => iteratorDone()); // always succeed
});
}, callback);
});