From c532344dcec15b86dba18d21a91ad25276fc1ffa Mon Sep 17 00:00:00 2001 From: Pablo Carranza Velez Date: Tue, 24 Oct 2017 14:27:18 -0700 Subject: [PATCH 1/2] If a device is already provisioned but the key exchange fails, retry it until it succeeds Change-Type: patch Signed-off-by: Pablo Carranza Velez --- src/bootstrap.coffee | 63 ++++++++++++++++++++++++++------------------ 1 file changed, 38 insertions(+), 25 deletions(-) diff --git a/src/bootstrap.coffee b/src/bootstrap.coffee index fffd3984..d35303c7 100644 --- a/src/bootstrap.coffee +++ b/src/bootstrap.coffee @@ -179,6 +179,42 @@ hasDeviceApiKeySupport = (osVersion) -> console.error('Unable to determine if device has deviceApiKey support', err, err.stack) false +exchangeKeyAndUpdateConfig = -> + # Only do a key exchange and delete the provisioning key if we're on a Resin OS version + # that supports using the deviceApiKey (2.0.2 and above) + # or if we're in a non-Resin OS (which is assumed to be updated enough). + # Otherwise VPN and other host services that use an API key will break. + # + # In other cases, we make the apiKey equal the deviceApiKey instead. + osRelease.getOSVersion(config.hostOSVersionPath) + .then (osVersion) -> + hasSupport = hasDeviceApiKeySupport(osVersion) + if hasSupport or userConfig.apiKey != userConfig.deviceApiKey + console.log('Attempting key exchange') + exchangeKey() + .then -> + console.log('Key exchange succeeded, starting to use deviceApiKey') + if hasSupport + 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)) + +exchangeKeyOrRetry = do -> + _failedExchanges = 0 + return -> + exchangeKeyAndUpdateConfig() + .catch (err) -> + console.error('Error exchanging API key, will retry', err, err.stack) + delay = Math.min((2 ** _failedExchanges) * config.bootstrapRetryDelay, 24 * 60 * 60 * 1000) + _failedExchanges += 1 + setTimeout(exchangeKeyOrRetry, delay) + return + bootstrapper.done = new Promise (resolve) -> bootstrapper.doneBootstrapping = -> bootstrapper.bootstrapped = true @@ -186,31 +222,8 @@ bootstrapper.done = new Promise (resolve) -> # If we're still using an old api key we can try to exchange it for a valid device key # This will only be the case when the supervisor/OS has been updated. if userConfig.apiKey? - # Only do a key exchange and delete the provisioning key if we're on a Resin OS version - # that supports using the deviceApiKey (2.0.2 and above) - # or if we're in a non-Resin OS (which is assumed to be updated enough). - # Otherwise VPN and other host services that use an API key will break. - # - # In other cases, we make the apiKey equal the deviceApiKey instead. - osRelease.getOSVersion(config.hostOSVersionPath) - .then (osVersion) -> - hasSupport = hasDeviceApiKeySupport(osVersion) - if hasSupport or userConfig.apiKey != userConfig.deviceApiKey - console.log('Attempting key exchange') - exchangeKey() - .then -> - console.log('Key exchange succeeded, starting to use deviceApiKey') - if hasSupport - 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)) - # We return immediately, and eventually the API key will be exchanged and replaced. - return + exchangeKeyOrRetry() + return bootstrapper.bootstrapped = false bootstrapper.startBootstrapping = -> From be6d44a09b78698d292a3bafe0bc52b7597a6e51 Mon Sep 17 00:00:00 2001 From: "resin-io-versionbot[bot]" Date: Mon, 30 Oct 2017 21:43:55 +0000 Subject: [PATCH 2/2] v6.3.8 --- CHANGELOG.md | 4 ++++ package.json | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index bfa4744e..4a236496 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,10 @@ All notable changes to this project will be documented in this file automatically by Versionist. DO NOT EDIT THIS FILE MANUALLY! This project adheres to [Semantic Versioning](http://semver.org/). +## v6.3.8 - 2017-10-30 + +* If a device is already provisioned but the key exchange fails, retry it until it succeeds #513 [Pablo Carranza Velez] + ## v6.3.7 - 2017-10-25 * Change the update retry to back off to the standard update check interval #515 [Pagan Gazzard] diff --git a/package.json b/package.json index 87c10b62..b3a1c034 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "resin-supervisor", "description": "This is resin.io's Supervisor, a program that runs on IoT devices and has the task of running user Apps (which are Docker containers), and updating them as Resin's API informs it to.", - "version": "6.3.7", + "version": "6.3.8", "license": "Apache-2.0", "repository": { "type": "git",