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:

  1. Gracefully stop the workload, if it is running

  2. Refresh the workload snap

  3. 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:

  1. 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

  2. If the snap revision has not changed, the charm code should start the workload

  3. 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