Use a closure for device state and also report in GET /v1/device whether there's a pending update

This commit is contained in:
Pablo Carranza Velez 2016-02-15 21:09:55 +00:00
parent 670f318c39
commit d0c76aec0f
3 changed files with 20 additions and 11 deletions

View File

@ -419,6 +419,7 @@ The state is a JSON object that contains some or all of the following:
* `download_progress`: Amount of the application image that has been downloaded, expressed as a percentage.
* `os_version`: Version of the host OS running on the device.
* `supervisor_version`: Version of the supervisor running on the device.
* `update_pending`: This one is not reported to the Resin API. It's a boolean that will be true if the supervisor has tried to update the app, but failed (for example, if the update lock was set).
Other attributes may be added in the future, and some may be missing or null if they haven't been set yet.
@ -430,7 +431,7 @@ $ curl -X GET --header "Content-Type:application/json" \
```
Response:
```json
{"api_port":48484,"ip_address":"192.168.0.114 10.42.0.3","status":"Downloading","download_progress":84,"os_version":"Resin OS 1.0.4 (fido)","supervisor_version":"1.6.0"}
{"api_port":48484,"ip_address":"192.168.0.114 10.42.0.3","status":"Downloading","download_progress":84,"os_version":"Resin OS 1.0.4 (fido)","supervisor_version":"1.6.0","update_pending":false}
```
Remotely via the API proxy:

View File

@ -578,11 +578,13 @@ application.update = update = (force) ->
throw new Error(joinErrorMessages(failures)) if failures.length > 0
.then ->
updateStatus.failed = 0
device.setUpdatePending(false)
# We cleanup here as we want a point when we have a consistent apps/images state, rather than potentially at a
# point where we might clean up an image we still want.
dockerUtils.cleanupContainersAndImages()
.catch (err) ->
updateStatus.failed++
device.setUpdatePending(true)
if updateStatus.state is UPDATE_REQUIRED
console.log('Updating failed, but there is already another update scheduled immediately: ', err)
return

View File

@ -128,17 +128,11 @@ exports.getDeviceType = do ->
throw new Error('Device type not specified in config file')
return configFromFile.deviceType
targetState = {}
exports.getState = ->
fieldsToOmit = ['api_secret', 'logs_channel', 'provisioning_progress', 'provisioning_state']
return _.omit(targetState, fieldsToOmit)
# Calling this function updates the local device state, which is then used to synchronise
# the remote device state, repeating any failed updates until successfully synchronised.
# This function will also optimise updates by merging multiple updates and only sending the latest state.
exports.updateState = do ->
do ->
applyPromise = Promise.resolve()
targetState = {}
actualState = {}
updatePending = false
getStateDiff = ->
_.omit targetState, (value, key) ->
@ -173,7 +167,19 @@ exports.updateState = do ->
# Check if any more state diffs have appeared whilst we've been processing this update.
applyState()
return (updatedState = {}, retry = false) ->
exports.setUpdatePending = (value) ->
updatePending = value
exports.getState = ->
fieldsToOmit = ['api_secret', 'logs_channel', 'provisioning_progress', 'provisioning_state']
state = _.omit(targetState, fieldsToOmit)
state.update_pending = updatePending
return state
# Calling this function updates the local device state, which is then used to synchronise
# the remote device state, repeating any failed updates until successfully synchronised.
# This function will also optimise updates by merging multiple updates and only sending the latest state.
exports.updateState = (updatedState = {}, retry = false) ->
# Remove any updates that match the last we successfully sent.
_.merge(targetState, updatedState)