24. (Machines only) Implement CharmSpecific.refresh_snap
This page only applies to machine charms.
refresh_snap method signature
def refresh_snap(
self,
*,
snap_name: str,
snap_revision: str,
refresh: charm_refresh.Machines,
) -> None:
refresh_snap must:
-
Gracefully stop the workload, if it is running
-
Refresh the workload snap
-
Immediately call
refresh.update_snap_revision()
refresh.update_snap_revision() must be called immediately after the snap is refreshed.
It should be the next line of code after the snap refresh—no other code should run in between
|
If refreshing the snap (#2) fails:
-
The charm code must not retry the snap refresh. refresh_snap will be called again by charm-refresh if the snap refresh should be retried
Why?
In case the user rolls back
-
If the snap revision has not changed, the charm code should start the workload
-
The charm code must raise an uncaught exception to ensure the unit receives another Juju event
Example refresh_snap
@dataclasses.dataclass(eq=False)
class MachinesPostgreSQLRefresh(charm_refresh.CharmSpecificMachines):
def refresh_snap(
self,
*,
snap_name: str,
snap_revision: str,
refresh: charm_refresh.Machines,
) -> None:
gracefully_shutdown_workload_service()
revision_before_refresh = snap_.revision
assert snap_revision != revision_before_refresh
try:
snap_.ensure(revision=snap_revision)
except (snap.SnapError, snap.SnapAPIError):
logger.exception("Snap refresh failed")
if snap_.revision == revision_before_refresh:
start_workload_service()
raise
else:
refresh.update_snap_revision()
raise
else:
refresh.update_snap_revision()
# TODO (1)
1 | 25. Allow next unit to refresh provides instructions for implementing the second part of refresh_snap |
The implementation of refresh_snap may require you to 22. Add CharmSpecific fields |