From d98897cdcf5f35ad54553f233d0ba74f30689f0a Mon Sep 17 00:00:00 2001 From: Pablo Carranza Velez Date: Fri, 20 Oct 2017 13:47:19 -0700 Subject: [PATCH] Ensure preloaded apps get the deviceApiKey in the env vars, and apps never get the provisioning key, and improve detection of cases when the device has been pre-provisioned It appears preloaded apps have been getting restarted because the "apiKey" configuration value was only available after provisioning succeeded. This change ensures the deviceApiKey that the device will use is injected into the env vars of preloaded apps, ensuring the app is not restarted (unless provisioning fails and the uuid and deviceApiKey are regenerated, but this should be rare). We also ensure that whenever an app's RESIN_API_KEY env var is populated, it is *always* done with the deviceApiKey and never with the provisioning apiKey. Closes #457 Change-Type: patch Signed-off-by: Pablo Carranza Velez --- src/application.coffee | 8 +++++--- src/bootstrap.coffee | 5 ++++- src/utils.coffee | 4 ++-- 3 files changed, 11 insertions(+), 6 deletions(-) diff --git a/src/application.coffee b/src/application.coffee index 16481345..8f208e9a 100644 --- a/src/application.coffee +++ b/src/application.coffee @@ -633,9 +633,9 @@ getRemoteState = (uuid, apiKey) -> throw err # TODO: Actually store and use app.environment and app.config separately -parseEnvAndFormatRemoteApps = (remoteApps, uuid, apiKey) -> +parseEnvAndFormatRemoteApps = (remoteApps, uuid, deviceApiKey) -> appsWithEnv = _.mapValues remoteApps, (app, appId) -> - utils.extendEnvVars(app.environment, uuid, appId, app.name, app.commit) + utils.extendEnvVars(app.environment, uuid, deviceApiKey, appId, app.name, app.commit) .then (env) -> app.config ?= {} return { @@ -716,7 +716,9 @@ application.update = update = (force, scheduled = false) -> .then -> utils.setConfig('name', local.name) if local.name != deviceName .then -> - parseEnvAndFormatRemoteApps(local.apps, uuid, apiKey) + utils.getConfig('deviceApiKey') + .then (deviceApiKey) -> + parseEnvAndFormatRemoteApps(local.apps, uuid, deviceApiKey) .then (remoteApps) -> localApps = formatLocalApps(apps) resourcesForUpdate = compareForUpdate(localApps, remoteApps) diff --git a/src/bootstrap.coffee b/src/bootstrap.coffee index 47191dd6..758a5c3a 100644 --- a/src/bootstrap.coffee +++ b/src/bootstrap.coffee @@ -40,7 +40,7 @@ loadPreloadedApps = -> fs.readFileAsync(appsPath, 'utf8') .then(JSON.parse) .map (app) -> - utils.extendEnvVars(app.env, userConfig.uuid, app.appId, app.name, app.commit) + utils.extendEnvVars(app.env, userConfig.uuid, userConfig.deviceApiKey, app.appId, app.name, app.commit) .then (extendedEnv) -> app.env = JSON.stringify(extendedEnv) _.merge(devConfig, app.config) @@ -135,6 +135,7 @@ bootstrap = -> # We use the provisioning/user `apiKey` if it still exists because if it does it means we were already registered # using that key and have to rely on the exchange key mechanism to swap the keys as appropriate later { key: 'apiKey', value: userConfig.apiKey ? userConfig.deviceApiKey } + { key: 'deviceApiKey', value: userConfig.deviceApiKey } { key: 'username', value: userConfig.username } { key: 'userId', value: userConfig.userId } { key: 'version', value: utils.supervisorVersion } @@ -202,6 +203,8 @@ bootstrapper.done = new Promise (resolve) -> delete userConfig.apiKey else userConfig.apiKey = userConfig.deviceApiKey + utils.setConfig('deviceApiKey', userConfig.deviceApiKey) + .then -> utils.setConfig('apiKey', userConfig.deviceApiKey) .then -> writeAndSyncFile(configPath, JSON.stringify(userConfig)) diff --git a/src/utils.coffee b/src/utils.coffee index 91701547..bebdf5b1 100644 --- a/src/utils.coffee +++ b/src/utils.coffee @@ -155,7 +155,7 @@ exports.setConfig = (key, value = null) -> .then (n) -> knex('config').insert({ key, value }) if n == 0 -exports.extendEnvVars = (env, uuid, appId, appName, commit) -> +exports.extendEnvVars = (env, uuid, apiKey, appId, appName, commit) -> host = '127.0.0.1' newEnv = RESIN_APP_ID: appId.toString() @@ -170,7 +170,7 @@ exports.extendEnvVars = (env, uuid, appId, appName, commit) -> RESIN_SUPERVISOR_PORT: config.listenPort RESIN_SUPERVISOR_API_KEY: exports.getOrGenerateSecret('api') RESIN_SUPERVISOR_VERSION: exports.supervisorVersion - RESIN_API_KEY: getConfig('apiKey') + RESIN_API_KEY: apiKey RESIN: '1' USER: 'root' if env?