Every snap updates automatically, and by default, the snapd daemon checks for updates 4 times a day. Each update check is called a refresh.
For snap developers, autonomous updates can occasionally cause issues. A snap may update while it’s being used for ongoing video playback, for example, or it may be providing a critical service for flying a drone.
In such cases, it can be beneficial to have greater control over when a snap is refreshed, and the impact that a refresh has on any dependent snaps.
Dependent snaps include those that:
- use an updated base snap
- consume data via a content interface from an updated snap
- run on Ubuntu Core when its kernel or gadget snaps are updated
For snap developers, the gate-auto-refresh hook, and its associated snapctl refresh commands, can be used to control when a snap is refreshed and how a refresh interacts with any dependent snaps.
This feature is currently considered experimental and requires an experimental feature-flag to be set before use:
$ sudo snap set system experimental.gate-auto-refresh-hook=true
Experimental refresh control also requires snapd version 2.53+ .
The gate-auto-refresh hook
The gate-auto-refresh hook is executed by snapd for every snap that will be updated with the next automatic refresh. It’s also executed for every snap that is dependent on a snap that will be updated.
This hook is capable of executing the snapctl refresh command with 3 specific arguments, hold
, proceed
and pending
:
snapctl refresh --hold
Requests that snapd does not refresh the calling snap, nor the snaps it depends upon, during the current automatic refresh. A snap can hold its own refresh for up to 90 days and other snaps for up to 48 hours. The command prints an error and returns a non-zero exit status if these deadlines are reached and the refresh can no longer be held.
snapctl refresh --proceed
Signals to snapd that a refresh can proceed for both the calling snap and the snaps it depends upon. This does not necessarily mean the update will happen, because they may be held by other snaps, and snapd only proceeds with auto-refresh after consulting gate-auto-refresh hooks of all potentially affected snaps.
snapctl refresh --pending
Checks whether the executing snap has a pending refresh, or will be affected by the refresh of its base snap.
The output from snapctl refresh --pending
includes the following details:
- pending: none, inhibited or ready
- channel: tracking-channel
- version: version (only if there is a pending refresh for the snap itself)
- revision: revision (only if there is a pending refresh for the snap itself)
- base: true or false (true if the snap is affected by refresh of its base snap)
- restart: true or false (true if refresh will cause system restart)
The pending output value is set to “none” if there is no pending refresh for the snap and the value is “ready” if there is a pending refresh. A pending value of “inhibited” indicates that the next refresh is inhibited because one or more of the snap’s applications are running. This currently requires the experimental refresh app awareness feature to be enabled (see below).
The snap-refresh-control interface
The snapctl refresh --proceed
command can be executed by a snapped application outside of the gate-auto-refresh hook if the snap has the snap-refresh-control
interface and the interface is connected. This enables the snap to trigger an auto-refresh outside of the normal auto-refresh schedule and should be used cautiously.
Please note that the “snapctl refresh” commands cannot be used from hooks other than gate-auto-refresh hook.
If the gate-auto-refresh-hook doesn’t invoke “snapctl refresh --proceed” or “snapctl refresh --hold” commands and exits with exit code 0, the refresh proceeds normally as if the hook didn’t exist (except for respecting “inhibited” status if refresh app awareness is in use).
If the hook fails with an error, snapd assumes “hold” as long as the maximum deadline hasn’t been reached.