Add more update-related fields to the GET /v1/device endpoint

This commit is contained in:
Pablo Carranza Velez 2016-02-17 16:37:09 +00:00
parent d0c76aec0f
commit a4b08e389e
3 changed files with 15 additions and 10 deletions

View File

@ -411,15 +411,17 @@ $ curl -X POST --header "Content-Type:application/json" \
### GET /v1/device
Introduced in supervisor v1.6.
Returns the current device state, as reported to the Resin API.
Returns the current device state, as reported to the Resin API and with some extra fields added to allow control over pending/locked updates.
The state is a JSON object that contains some or all of the following:
* `api_port`: Port on which the supervisor is listening.
* `ip_address`: Space-separated list of IP addresses of the device.
* `status`: Status of the device regarding the app, as a string, i.e. "Stopping", "Starting", "Downloading", "Installing", "Idle".
* `download_progress`: Amount of the application image that has been downloaded, expressed as a percentage.
* `download_progress`: Amount of the application image that has been downloaded, expressed as a percentage. If the update has already been downloaded, this will be `null`.
* `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).
* `update_pending`: This one is not reported to the Resin API. It's a boolean that will be true if the supervisor has detected there is a pending update.
* `update_downloaded`: Not reported to the Resin API either. Boolean that will be true if a pending update has already been downloaded.
* `update_failed`: Not reported to the Resin API. Boolean that will be true if the supervisor has tried to apply a pending update but failed (i.e. if the app was locked, there was a network failure or anything else went wrong).
Other attributes may be added in the future, and some may be missing or null if they haven't been set yet.
@ -431,7 +433,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","update_pending":false}
{"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":true,"update_downloaded":false,"update_failed":false}
```
Remotely via the API proxy:

View File

@ -144,6 +144,7 @@ fetch = (app) ->
.then ->
logSystemEvent(logTypes.downloadAppSuccess, app)
device.updateState(status: 'Idle', download_progress: null)
device.setUpdateState(update_downloaded: true)
docker.getImage(app.imageId).inspectAsync()
.catch (err) ->
logSystemEvent(logTypes.downloadAppError, app, err)
@ -516,6 +517,8 @@ application.update = update = (force) ->
resourcesForUpdate = compareForUpdate(localApps, remoteApps, localAppEnvs, remoteAppEnvs)
{ toBeRemoved, toBeDownloaded, toBeInstalled, toBeUpdated, appsWithChangedEnvs, allAppIds } = resourcesForUpdate
if !_.isEmpty(toBeRemoved) or !_.isEmpty(toBeInstalled) or !_.isEmpty(toBeUpdated)
device.setUpdateState(update_pending: true)
# Run special functions against variables if remoteAppEnvs has the corresponding variable function mapping.
Promise.map appsWithChangedEnvs, (appId) ->
Promise.using lockUpdates(remoteApps[appId], force), ->
@ -578,13 +581,13 @@ application.update = update = (force) ->
throw new Error(joinErrorMessages(failures)) if failures.length > 0
.then ->
updateStatus.failed = 0
device.setUpdatePending(false)
device.setUpdateState(update_pending: false, update_downloaded: false, update_failed: 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)
device.setUpdateState(update_failed: true)
if updateStatus.state is UPDATE_REQUIRED
console.log('Updating failed, but there is already another update scheduled immediately: ', err)
return

View File

@ -132,7 +132,7 @@ do ->
applyPromise = Promise.resolve()
targetState = {}
actualState = {}
updatePending = false
updateState = { update_pending: false, update_failed: false, update_downloaded: false }
getStateDiff = ->
_.omit targetState, (value, key) ->
@ -167,13 +167,13 @@ do ->
# Check if any more state diffs have appeared whilst we've been processing this update.
applyState()
exports.setUpdatePending = (value) ->
updatePending = value
exports.setUpdateState = (value) ->
_.merge(updateState, value)
exports.getState = ->
fieldsToOmit = ['api_secret', 'logs_channel', 'provisioning_progress', 'provisioning_state']
state = _.omit(targetState, fieldsToOmit)
state.update_pending = updatePending
_.merge(state, updateState)
return state
# Calling this function updates the local device state, which is then used to synchronise