diff --git a/src/cloudron.js b/src/cloudron.js index d8743f640..1b107bf3b 100644 --- a/src/cloudron.js +++ b/src/cloudron.js @@ -72,14 +72,15 @@ function uninitialize(callback) { ], callback); } -function onActivated(callback) { +function onActivated(options, callback) { + assert.strictEqual(options, 'object'); assert.strictEqual(typeof callback, 'function'); // Starting the platform after a user is available means: // 1. mail bounces can now be sent to the cloudron owner // 2. the restore code path can run without sudo (since mail/ is non-root) async.series([ - platform.start, + platform.start.bind(null, options), cron.startJobs, function checkBackupConfiguration(done) { backups.checkConfiguration(function (error, message) { @@ -147,7 +148,7 @@ function runStartupTasks() { return reverseProxy.writeDefaultConfig({ activated: false }, callback); } - onActivated(callback); + onActivated({}, callback); }); } ]; diff --git a/src/platform.js b/src/platform.js index 9a94801a6..2d88ee153 100644 --- a/src/platform.js +++ b/src/platform.js @@ -23,7 +23,8 @@ const apps = require('./apps.js'), tasks = require('./tasks.js'), _ = require('underscore'); -function start(callback) { +function start(options, callback) { + assert.strictEqual(typeof options, 'object'); assert.strictEqual(typeof callback, 'function'); if (process.env.BOX_ENV === 'test' && !process.env.TEST_CREATE_INFRA) return callback(); @@ -52,7 +53,7 @@ function start(callback) { async.series([ (next) => { if (existingInfra.version !== infra.version) removeAllContainers(next); else next(); }, - markApps.bind(null, existingInfra), // mark app state before we start addons. this gives the db import logic a chance to mark an app as errored + markApps.bind(null, existingInfra, options), // mark app state before we start addons. this gives the db import logic a chance to mark an app as errored services.startServices.bind(null, existingInfra), fs.writeFile.bind(fs, paths.INFRA_VERSION_FILE, JSON.stringify(infra, null, 4)) ], function (error) { @@ -118,10 +119,14 @@ function removeAllContainers(callback) { ], callback); } -function markApps(existingInfra, callback) { +function markApps(existingInfra, options, callback) { + assert.strictEqual(typeof existingInfra, 'object'); + assert.strictEqual(typeof options, 'object'); + assert.strictEqual(typeof callback, 'function'); + if (existingInfra.version === 'none') { // cloudron is being restored from backup debug('markApps: restoring installed apps'); - apps.restoreInstalledApps(callback); + apps.restoreInstalledApps(options, callback); } else if (existingInfra.version !== infra.version) { debug('markApps: reconfiguring installed apps'); reverseProxy.removeAppConfigs(); // should we change the cert location, nginx will not start diff --git a/src/provision.js b/src/provision.js index a1190c477..e90597c69 100644 --- a/src/provision.js +++ b/src/provision.js @@ -149,16 +149,17 @@ function activate(username, password, email, displayName, ip, auditSource, callb expires: result.expires }); - setImmediate(cloudron.onActivated.bind(null, NOOP_CALLBACK)); // hack for now to not block the above http response + setImmediate(cloudron.onActivated.bind(null, {}, NOOP_CALLBACK)); // hack for now to not block the above http response }); }); } -function restore(backupConfig, backupId, version, sysinfoConfig, auditSource, callback) { +function restore(backupConfig, backupId, version, sysinfoConfig, options, auditSource, callback) { assert.strictEqual(typeof backupConfig, 'object'); assert.strictEqual(typeof backupId, 'string'); assert.strictEqual(typeof version, 'string'); assert.strictEqual(typeof sysinfoConfig, 'object'); + assert.strictEqual(typeof options, 'object'); assert.strictEqual(typeof auditSource, 'object'); assert.strictEqual(typeof callback, 'function'); @@ -203,7 +204,10 @@ function restore(backupConfig, backupId, version, sysinfoConfig, auditSource, ca (done) => { const adminDomain = settings.adminDomain(); // load this fresh from after the backup.restore async.series([ - cloudron.setupDnsAndCert.bind(null, constants.ADMIN_LOCATION, adminDomain, auditSource, (progress) => setProgress('restore', progress.message, NOOP_CALLBACK)), + (next) => { + if (options.skipDnsSetup) return next(); + cloudron.setupDnsAndCert(constants.ADMIN_LOCATION, adminDomain, auditSource, (progress) => setProgress('restore', progress.message, NOOP_CALLBACK), next); + }, cloudron.setDashboardDomain.bind(null, adminDomain, auditSource) ], done); }, @@ -213,7 +217,7 @@ function restore(backupConfig, backupId, version, sysinfoConfig, auditSource, ca gProvisionStatus.restore.active = false; gProvisionStatus.restore.errorMessage = error ? error.message : ''; - if (!error) cloudron.onActivated(NOOP_CALLBACK); + if (!error) cloudron.onActivated(options, NOOP_CALLBACK); }); }); }); diff --git a/src/routes/provision.js b/src/routes/provision.js index 41c6721bb..a29a626ca 100644 --- a/src/routes/provision.js +++ b/src/routes/provision.js @@ -111,7 +111,7 @@ function restore(req, res, next) { if (!req.body.backupConfig || typeof req.body.backupConfig !== 'object') return next(new HttpError(400, 'backupConfig is required')); - var backupConfig = req.body.backupConfig; + const backupConfig = req.body.backupConfig; if (typeof backupConfig.provider !== 'string') return next(new HttpError(400, 'provider is required')); if ('password' in backupConfig && typeof backupConfig.password !== 'string') return next(new HttpError(400, 'password must be a string')); if (typeof backupConfig.format !== 'string') return next(new HttpError(400, 'format must be a string')); @@ -121,8 +121,13 @@ function restore(req, res, next) { if (typeof req.body.version !== 'string') return next(new HttpError(400, 'version must be a string')); if ('sysinfoConfig' in req.body && typeof req.body.sysinfoConfig !== 'object') return next(new HttpError(400, 'sysinfoConfig must be an object')); + if ('skipDnsSetup' in req.body && typeof req.body.skipDnsSetup !== 'boolean') return next(new HttpError(400, 'skipDnsSetup must be a boolean')); - provision.restore(backupConfig, req.body.backupId, req.body.version, req.body.sysinfoConfig || { provider: 'generic' }, auditSource.fromRequest(req), function (error) { + const options = { + skipDnsSetup: req.body.skipDnsSetup || false + }; + + provision.restore(backupConfig, req.body.backupId, req.body.version, req.body.sysinfoConfig || { provider: 'generic' }, options, auditSource.fromRequest(req), function (error) { if (error) return next(BoxError.toHttpError(error)); next(new HttpSuccess(200, {}));