@brownjohnf, I think @krix meant the disable-rolling-release-on-fleet.sh
script I mentioned in the 2nd comment in this thread. By the way, @brownjohnf, when you say “pinned versions”, is it the same functionality as the pin-devices-running-release.sh
script?
I was now looking at the implementation of those shell scripts and they are basically making a few queries to the balena API. By the way, for efficiency and flexibility, app developers should probably make the API queries directly in their programming language of choice, rather than running the shell scripts in child processes.
@CameronDiver wrote that he “would always recommend using staged releases instead of update locks for long lived locks,” and I’m pondering if there is a sequence of steps that minimise the need for update lock files (/tmp/balena/updates.lock
), while delivering everything the users are asking in this thread.
Generalising a bit, I understand that the needs are:
- A balena user app (based on end user input) controls when/if the app container(s) get updated. (An app update pushed to the cloud does not automatically trigger update on the device.)
- The app needs a way to know whether an update is available, to notify the device’s end user.
- The app needs a way to trigger immediate download of an update, if one is available. But this should not automatically cause the update to be applied, once the download finishes.
- The app needs a way to know whether an update download has finished.
- The app needs a way to apply the update immediately, after download has finished.
It looks like the disable-rolling-release-on-fleet.sh
and set-device-to-a-release.sh
scripts deliver on the first requirement. They make these API calls:
curl -X PATCH "https://api.$BASE_URL/v4/application($APP_ID)" -H "Authorization: Bearer $authToken" -H "Content-Type: application/json" --data-binary '{"should_track_latest_release":false}'
curl -X PATCH "https://api.$BASE_URL/v4/device($DEVICE_ID)" -H "Authorization: Bearer $authToken" -H "Content-Type: application/json" --data-binary '{"should_be_running__release":'$RELEASE_ID'}'
These calls set the should_track_latest_release
field in the Application
object and the should_be_running__release
field in the Device
object:
https://www.balena.io/docs/reference/api/resources/application/
https://www.balena.io/docs/reference/api/resources/device/
For the app to know whether an update is available, I’m thinking that the app could query the Release object:
https://www.balena.io/docs/reference/api/resources/release/
The Release object has fields like created_at
and several others that the app can compare with the release it is currently running. I assume this is sufficient for the app to decide that an update is available.
By the way, note that commit and release ID can be translated. Given a release ID, the Release object can be queried for the commit hash. Given a commit hash, the get-release-id.sh
script shows how to get a release ID:
curl "https://api.$BASE_URL/v4/release?\$select=id,commit&\$filter=belongs_to__application%20eq%20$APP_ID%20and%20commit%20eq%20'$COMMIT_HASH'%20and%20status%20eq%20'success'" -H "Authorization: Bearer $authToken" | jq '.d[0].id'
For the 3rd requirement, to trigger download of an update, the app could change the value of the Device.should_be_running__release
field to the desired release, and then use the supervisor /v1/update
API to trigger the download as @CameronDiver pointed out. But before that, if the app does not want the update to be automatically applied when download finishes, the app should create the /tmp/balena/updates.lock
update lock file – but only for the duration of the download.
For the 4th requirement, again as @CameronDiver pointed out in his answer, the /v2/applications/state
supervisor API could be used, to check for a status
value of “Downloaded”.
Finally, for the 5th requirement, the app would delete the update lock file and make another call to the supervisor /v1/update
API. This step is not needed if the lock file was not created in the first place.
Disclaimer: I have not tested these steps! This post is just some thinking and needs validation. If you can confirm or reject some of the steps/assumptions, please share.
@krix, if the lock file seems to be ignored, check perhaps if the Enable Lock Override option was selected in the web dashboard, device summary screen, or if the BALENA_SUPERVISOR_OVERRIDE_LOCK configuration variable was set to 1 in the device configuration screen, as described at the end of the update lock documentation page: https://www.balena.io/docs/learn/deploy/release-strategy/update-locking/