diff --git a/src/apps.js b/src/apps.js index 6a837abed..1dd631d3e 100644 --- a/src/apps.js +++ b/src/apps.js @@ -30,6 +30,7 @@ exports = module.exports = { setMailbox: setMailbox, setLocation: setLocation, setDataDir: setDataDir, + repair: repair, restore: restore, clone: clone, @@ -66,12 +67,13 @@ exports = module.exports = { // installation codes (keep in sync in UI) ISTATE_PENDING_INSTALL: 'pending_install', // installs and fresh reinstalls ISTATE_PENDING_CLONE: 'pending_clone', // clone - ISTATE_PENDING_CONFIGURE: 'pending_configure', // config (location, port) changes and on infra update + ISTATE_PENDING_CONFIGURE: 'pending_configure', // infra update ISTATE_PENDING_RECREATE_CONTAINER: 'pending_recreate_container', // env change or addon change ISTATE_PENDING_LOCATION_CHANGE: 'pending_location_change', ISTATE_PENDING_DATA_DIR_MIGRATION: 'pending_data_dir_migration', ISTATE_PENDING_RESIZE: 'pending_resize', ISTATE_PENDING_DEBUG: 'pending_debug', + ISTATE_PENDING_REPAIR: 'pending_repair', ISTATE_PENDING_UNINSTALL: 'pending_uninstall', // uninstallation ISTATE_PENDING_RESTORE: 'pending_restore', // restore to previous backup or on upgrade ISTATE_PENDING_UPDATE: 'pending_update', // update from installed state preserving data @@ -1295,6 +1297,23 @@ function getLogs(appId, options, callback) { }); } +function repair(appId, data, auditSource, callback) { + assert.strictEqual(typeof appId, 'string'); + assert.strictEqual(typeof data, 'object'); + assert.strictEqual(typeof auditSource, 'object'); + assert.strictEqual(typeof callback, 'function'); + + debug('Will repair app with id:%s', appId); + + scheduleTask(appId, { /* task args */ }, { installationState: exports.ISTATE_PENDING_REPAIR }, function (error, result) { + if (error) return callback(error); + + eventlog.add(eventlog.ACTION_APP_REPAIR, auditSource, { taskId: result.taskId }); + + callback(null, { taskId: result.taskId }); + }); +} + function restore(appId, data, auditSource, callback) { assert.strictEqual(typeof appId, 'string'); assert.strictEqual(typeof data, 'object'); diff --git a/src/apptask.js b/src/apptask.js index b7d3e8267..44d215692 100644 --- a/src/apptask.js +++ b/src/apptask.js @@ -1029,7 +1029,9 @@ function run(appId, args, progressCallback, callback) { switch (app.installationState) { case apps.ISTATE_PENDING_INSTALL: return install(app, args, progressCallback, callback); - case apps.ISTATE_PENDING_CONFIGURE: return configure(app, args.oldConfig, progressCallback, callback); + case apps.ISTATE_PENDING_CONFIGURE: + case apps.ISTATE_PENDING_REPAIR: + return configure(app, args.oldConfig, progressCallback, callback); case apps.ISTATE_PENDING_RECREATE_CONTAINER: case apps.ISTATE_PENDING_RESIZE: case apps.ISTATE_PENDING_DEBUG: diff --git a/src/eventlog.js b/src/eventlog.js index a13d12e2b..022d8eaff 100644 --- a/src/eventlog.js +++ b/src/eventlog.js @@ -13,6 +13,7 @@ exports = module.exports = { ACTION_ACTIVATE: 'cloudron.activate', ACTION_APP_CLONE: 'app.clone', ACTION_APP_CONFIGURE: 'app.configure', + ACTION_APP_REPAIR: 'app.repair', ACTION_APP_INSTALL: 'app.install', ACTION_APP_RESTORE: 'app.restore', ACTION_APP_UNINSTALL: 'app.uninstall', diff --git a/src/routes/apps.js b/src/routes/apps.js index 7e8ae72bd..164dd6a72 100644 --- a/src/routes/apps.js +++ b/src/routes/apps.js @@ -12,6 +12,7 @@ exports = module.exports = { getLogs: getLogs, getLogStream: getLogStream, listBackups: listBackups, + repairApp: repairApp, setAccessRestriction: setAccessRestriction, setLabel: setLabel, @@ -361,6 +362,19 @@ function setDataDir(req, res, next) { }); } +function repairApp(req, res, next) { + assert.strictEqual(typeof req.body, 'object'); + assert.strictEqual(typeof req.params.id, 'string'); + + debug('Repair app id:%s', req.params.id); + + apps.repair(req.params.id, {}, auditSource.fromRequest(req), function (error, result) { + if (error) return next(toHttpError(error)); + + next(new HttpSuccess(202, { taskId: result.taskId })); + }); +} + function restoreApp(req, res, next) { assert.strictEqual(typeof req.body, 'object'); assert.strictEqual(typeof req.params.id, 'string'); diff --git a/src/server.js b/src/server.js index 509fa7f45..20dcc1285 100644 --- a/src/server.js +++ b/src/server.js @@ -254,6 +254,7 @@ function initializeExpressSync() { router.post('/api/v1/apps/:id/configure/env', appsManageScope, routes.apps.setEnvironment); router.post('/api/v1/apps/:id/configure/data_dir', appsManageScope, routes.apps.setDataDir); router.post('/api/v1/apps/:id/configure/location', appsManageScope, routes.apps.setLocation); + router.post('/api/v1/apps/:id/configure/repair', appsManageScope, routes.apps.repairApp); router.post('/api/v1/apps/:id/update', appsManageScope, routes.apps.updateApp); router.post('/api/v1/apps/:id/restore', appsManageScope, routes.apps.restoreApp);