Allow the supervisor to work in offline mode

A supervisorOfflineMode true-ish attribute in config.json will cause that:
* If unprovisioned, the supervisor won't try to provision on Resin
* The update cycle will not start as the device won't consider itself provisioned
* Logs will not be sent to pubnub
* Mixpanel events won't be tracked
* The device state won't be updated to the Resin API

This change will also make the Supervisor API work with an unprovisioned device.
This commit is contained in:
Pablo Carranza Velez 2016-07-23 01:17:00 -03:00
parent d652e13005
commit 98d9aca92d
7 changed files with 39 additions and 17 deletions

View File

@ -1,3 +1,4 @@
* Allow the supervisor to work in offline mode [Pablo]
* Fix duplicate logs issue [Kostas]
* **[Breaking]** Do not bind mount /run/dbus to /run/dbus [Pablo]
* Default to not bind mounting kmod if container distro can't be found [Pablo]

View File

@ -20,16 +20,17 @@ knex.init.then ->
utils.mixpanelProperties.uuid = uuid
api = require './api'
application = require('./application')(logsChannel)
application = require('./application')(logsChannel, bootstrap.offlineMode)
device = require './device'
console.log('Starting API server..')
apiServer = api(application).listen(config.listenPort)
apiServer.timeout = config.apiTimeout
bootstrap.done
.then ->
device.getOSVersion()
.then (osVersion) ->
console.log('Starting API server..')
apiServer = api(application).listen(config.listenPort)
apiServer.timeout = config.apiTimeout
# Let API know what version we are, and our api connection info.
console.log('Updating supervisor version and api info')
device.updateState(

View File

@ -703,10 +703,11 @@ application.initialize = ->
application.poll()
application.update()
module.exports = (logsChannel) ->
module.exports = (logsChannel, offlineMode) ->
logger.init(
dockerSocket: config.dockerSocket
pubnub: config.pubnub
channel: "device-#{logsChannel}-logs"
offlineMode: offlineMode
)
return application

View File

@ -64,12 +64,12 @@ bootstrap = ->
.tap ->
bootstrapper.doneBootstrapping()
readConfigAndEnsureUUID = ->
# Load config file
readConfig = ->
fs.readFileAsync(configPath, 'utf8')
.then(JSON.parse)
.then (configFromFile) ->
userConfig = configFromFile
readConfigAndEnsureUUID = ->
Promise.try ->
return userConfig.uuid if userConfig.uuid?
deviceRegister.generateUUID()
.then (uuid) ->
@ -84,6 +84,8 @@ readConfigAndEnsureUUID = ->
bootstrapOrRetry = ->
utils.mixpanelTrack('Device bootstrap')
# If we're in offline mode, we don't start the provisioning process so bootstrap.done will never fulfill
return if bootstrapper.offlineMode
bootstrap().catch (err) ->
utils.mixpanelTrack('Device bootstrap failed, retrying', { error: err, delay: config.bootstrapRetryDelay })
setTimeout(bootstrapOrRetry, config.bootstrapRetryDelay)
@ -95,10 +97,15 @@ bootstrapper.done = new Promise (resolve) ->
bootstrapper.bootstrapped = false
bootstrapper.startBootstrapping = ->
# Load config file
readConfig()
.then (configFromFile) ->
userConfig = configFromFile
bootstrapper.offlineMode = Boolean(userConfig.supervisorOfflineMode)
knex('config').select('value').where(key: 'uuid')
.then ([ uuid ]) ->
if uuid?.value
bootstrapper.doneBootstrapping()
bootstrapper.doneBootstrapping() if !bootstrapper.offlineMode
return uuid.value
console.log('New device detected. Bootstrapping..')
readConfigAndEnsureUUID()

View File

@ -9,6 +9,7 @@ configPath = '/boot/config.json'
request = Promise.promisifyAll(require('request'))
execAsync = Promise.promisify(require('child_process').exec)
fs = Promise.promisifyAll(require('fs'))
bootstrap = require './bootstrap'
exports.getID = do ->
deviceIdPromise = null
@ -17,6 +18,10 @@ exports.getID = do ->
deviceIdPromise ?= Promise.rejected()
# Only fetch the device id once (when successful, otherwise retry for each request)
deviceIdPromise = deviceIdPromise.catch ->
# Wait for bootstrapping to be done before querying the Resin API
# This will also block users of getID (like applyState below until this is resolved)
bootstrap.done
.then ->
Promise.all([
knex('config').select('value').where(key: 'apiKey')
knex('config').select('value').where(key: 'uuid')

View File

@ -23,6 +23,9 @@ publish = do ->
publishQueue = []
initialised.then (config) ->
if config.offlineMode
publish = _.noop
return
pubnub = PUBNUB.init(config.pubnub)
channel = config.channel

View File

@ -18,10 +18,14 @@ tagExtra = process.env.SUPERVISOR_TAG_EXTRA
version += '+' + tagExtra if !_.isEmpty(tagExtra)
exports.supervisorVersion = version
configJson = require('/boot/config.json')
if Boolean(configJson.supervisorOfflineMode)
mixpanelClient = mixpanel.init(config.mixpanelToken)
else
mixpanelClient = { track: _.noop }
exports.mixpanelProperties = mixpanelProperties =
username: require('/boot/config.json').username
username: configJson.username
exports.mixpanelTrack = (event, properties = {}) ->
# Allow passing in an error directly and having it assigned to the error property.