diff --git a/src/apps.js b/src/apps.js index 6ad34c518..2c2ecb78e 100644 --- a/src/apps.js +++ b/src/apps.js @@ -1400,24 +1400,32 @@ function repair(appId, data, auditSource, callback) { const appError = app.error || {}; // repair can always be called const newState = appError.installationState ? appError.installationState : exports.ISTATE_PENDING_CONFIGURE; + debug(`Repairing app with error: ${JSON.stringify(error)} and state: ${newState}`); - let values = _.pick(data, 'location', 'domain', 'alternateDomains'); // FIXME: validate + let values = _.pick(data, 'location', 'domain', 'alternateDomains'); - tasks.get(appError.taskId || '', function (error, task) { - let args = !error ? task.args[1] : {}; // the first argument is the app id - if ('backupId' in data) { - args.restoreConfig = data.backupId ? { backupId: data.backupId, backupFormat: data.backupFormat, oldManifest: app.manifest } : null; // when null, apptask simply reinstalls - } - if ('overwriteDns' in data) args.overwriteDns = data.overwriteDns; + const locations = (values.location ? [ { subdomain: values.location, domain: values.domain } ] : []).concat(values.alternateDomains || []); + validateLocations(locations, function (error, domainObjectMap) { + if (error) return callback(error); - // create a new task instead of updating the old one, since it helps tracking - addTask(appId, newState, { args, values, requiredState: null }, function (error, result) { - if (error) return callback(error); + tasks.get(appError.taskId || '', function (error, task) { + let args = !error ? task.args[1] : {}; // pick args for the failed task. the first argument is the app id - eventlog.add(eventlog.ACTION_APP_REPAIR, auditSource, { taskId: result.taskId, app, newState }); + if ('backupId' in data) { + 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; - callback(null, { taskId: result.taskId }); + // create a new task instead of updating the old one, since it helps tracking + addTask(appId, newState, { args, values, requiredState: null }, function (error, result) { + if (error && error.reason === AppsError.ALREADY_EXISTS) error = getDuplicateErrorDetails(error.message, locations, domainObjectMap, { /* portBindings */}); + if (error) return callback(error); + + eventlog.add(eventlog.ACTION_APP_REPAIR, auditSource, { taskId: result.taskId, app, newState }); + + callback(null, { taskId: result.taskId }); + }); }); }); });