27. Set status
During every Juju event, the charm code must ensure that the app and unit status are up-to-date and that the most relevant information is displayed in the status.
charm-refresh has 4 categories of statuses:
-
App status when KubernetesJujuAppNotTrusted is raised
-
app_status_higher_priority -
unit_status_higher_priority -
unit_status_lower_priority
Higher priority status
#1-#3 have higher priority than any other status set by the charm code or charm code dependencies.
These statuses are automatically set by charm-refresh.
While app_status_higher_priority is not None or while KubernetesJujuAppNotTrusted is raised, the charm code must not set the app status.
While unit_status_higher_priority is not None, the charm code must not set the unit status.
| charm-refresh may set a status even while a refresh is not in progress |
These statuses are not cleared by charm-refresh.
The charm code must clear the status (replace it with another status) within the same Juju event when these conditions are met:
-
App status:
app_status_higher_priorityis None and KubernetesJujuAppNotTrusted is not raised -
Unit status:
unit_status_higher_priorityis None
| "Within the same Juju event" includes Juju events that the charm code may not currently observe |
Lower priority status
#4 has lower priority that any other status with a message set by the charm code or charm code dependencies.
These statuses are not set by charm-refresh.
The charm code must check in every Juju event if this status should be set.
| "Every Juju event" includes Juju events that the charm code may not currently observe |
|
For statuses with a message that are set at all times (for example, the PostgreSQL charm sets an active status with the message "Primary" on the primary unit), consider making an exception and treating these statuses the same as statuses without a message. In other words, consider giving #4 higher priority than a status with a message that is set at all times |
Implementation
|
ops' collect status event must not be used. If it is used, ops will override higher priority refresh statuses with (lower priority) charm code statuses. For example, if a charm code component sets a blocked status and the higher priority refresh status is a maintenance status, ops will incorrectly display the charm code status instead of the refresh status |
class PostgreSQLCharm(ops.CharmBase):
refresh: charm_refresh.Common
@staticmethod
def _prioritize_statuses_by_type(
statuses: list[ops.StatusBase]
) -> ops.StatusBase:
status_priority = (
ops.BlockedStatus,
ops.MaintenanceStatus,
ops.WaitingStatus,
ops.ActiveStatus,
)
for status_type in status_priority:
for status in statuses:
if isinstance(status, status_type):
return status
return ops.ActiveStatus()
def _determine_app_status(self) -> ops.StatusBase:
if self.refresh.app_status_higher_priority:
return self.refresh.app_status_higher_priority (1)
charm_statuses = []
for endpoint in (self._database_provides, self._async_replication):
if status := endpoint.status:
charm_statuses.append(status)
return self._prioritize_statuses_by_type(charm_statuses)
def _determine_unit_status(self) -> ops.StatusBase:
if self.refresh.unit_status_higher_priority:
return self.refresh.unit_status_higher_priority (1)
charm_statuses = []
if status := self._workload.status:
charm_statuses.append(status)
charm_status = self._prioritize_statuses_by_type(charm_statuses)
refresh_lower_priority = self.refresh.unit_status_lower_priority(
workload_is_running=self._workload.is_running (2)
)
if charm_status.message == "" and refresh_lower_priority: (3)
return refresh_lower_priority
return charm_status
def set_status(self) -> None:
if self.unit.is_leader():
self.app.status = self._determine_app_status()
self.unit.status = self._determine_unit_status()
def __init__(self, *args):
# [...]
# Observe all events (except custom events)
for bound_event in self.on.events().values():
if bound_event.event_type == ops.CollectStatusEvent:
continue
self.framework.observe(bound_event, self.reconcile) (4)
# [...]
def reconcile(self, event):
# [...]
self.set_status() (4)
| 1 | If charm-refresh reports a higher priority status, ensure that it is not overridden by another status |
| 2 | When querying unit_status_lower_priority, inform charm-refresh whether the workload is running |
| 3 | Only set unit_status_lower_priority if there is no other unit status with a message to display |
| 4 | Set the app and unit status at the end of every Juju event to ensure that the statuses are up-to-date |