Skip to content

Commit b27eafe

Browse files
Add upgrade UnitState enum (#134)
1 parent cecb229 commit b27eafe

File tree

4 files changed

+28
-14
lines changed

4 files changed

+28
-14
lines changed

src/abstract_charm.py

+3-3
Original file line numberDiff line numberDiff line change
@@ -254,7 +254,7 @@ def reconcile(self, event=None) -> None: # noqa: C901
254254
# Run before checking `self._upgrade.is_compatible` in case incompatible upgrade was
255255
# forced & completed on all units.
256256
self._upgrade.set_versions_in_app_databag()
257-
if self._upgrade.unit_state == "restarting": # Kubernetes only
257+
if self._upgrade.unit_state is upgrade.UnitState.RESTARTING: # Kubernetes only
258258
if not self._upgrade.is_compatible:
259259
logger.info(
260260
"Upgrade incompatible. If you accept potential *data loss* and *downtime*, you can continue with `resume-upgrade force=true`"
@@ -268,7 +268,7 @@ def reconcile(self, event=None) -> None: # noqa: C901
268268
if not self._upgrade.is_compatible:
269269
self.set_status(event=event)
270270
return
271-
if self._upgrade.unit_state == "outdated":
271+
if self._upgrade.unit_state is upgrade.UnitState.OUTDATED:
272272
if self._upgrade.authorized:
273273
self._upgrade.upgrade_unit(
274274
event=event,
@@ -330,7 +330,7 @@ def reconcile(self, event=None) -> None: # noqa: C901
330330
# Empty waiting status means we're waiting for database requires relation before
331331
# starting workload
332332
if not workload_.status or workload_.status == ops.WaitingStatus():
333-
self._upgrade.unit_state = "healthy"
333+
self._upgrade.unit_state = upgrade.UnitState.HEALTHY
334334
if self._unit_lifecycle.authorized_leader:
335335
self._upgrade.reconcile_partition()
336336
self.set_status(event=event)

src/machine_charm.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -165,7 +165,7 @@ def _on_force_upgrade_action(self, event: ops.ActionEvent) -> None:
165165
logger.debug(f"Force upgrade event failed: {message}")
166166
event.fail(message)
167167
return
168-
if self._upgrade.unit_state != "outdated":
168+
if self._upgrade.unit_state is not upgrade.UnitState.OUTDATED:
169169
message = "Unit already upgraded"
170170
logger.debug(f"Force upgrade event failed: {message}")
171171
event.fail(message)

src/machine_upgrade.py

+9-6
Original file line numberDiff line numberDiff line change
@@ -27,18 +27,18 @@ class Upgrade(upgrade.Upgrade):
2727
"""In-place upgrades on machines"""
2828

2929
@property
30-
def unit_state(self) -> typing.Optional[str]:
30+
def unit_state(self) -> typing.Optional[upgrade.UnitState]:
3131
if (
3232
self._unit_workload_container_version is not None
3333
and self._unit_workload_container_version != self._app_workload_container_version
3434
):
3535
logger.debug("Unit upgrade state: outdated")
36-
return "outdated"
36+
return upgrade.UnitState.OUTDATED
3737
return super().unit_state
3838

3939
@unit_state.setter
40-
def unit_state(self, value: str) -> None:
41-
if value == "healthy":
40+
def unit_state(self, value: upgrade.UnitState) -> None:
41+
if value is upgrade.UnitState.HEALTHY:
4242
# Set snap revision on first install
4343
self._unit_workload_container_version = snap.REVISION
4444
self._unit_workload_version = self._current_versions["workload"]
@@ -146,10 +146,13 @@ def authorized(self) -> bool:
146146
logger.debug(f"Second unit authorized to upgrade if {self.upgrade_resumed=}")
147147
return self.upgrade_resumed
148148
return True
149+
state = self._peer_relation.data[unit].get("state")
150+
if state:
151+
state = upgrade.UnitState(state)
149152
if (
150153
self._unit_workload_container_versions.get(unit.name)
151154
!= self._app_workload_container_version
152-
or self._peer_relation.data[unit].get("state") != "healthy"
155+
or state is not upgrade.UnitState.HEALTHY
153156
):
154157
# Waiting for higher number units to upgrade
155158
return False
@@ -164,7 +167,7 @@ def upgrade_unit(
164167
exporter_config: "relations.cos.ExporterConfig",
165168
) -> None:
166169
logger.debug(f"Upgrading {self.authorized=}")
167-
self.unit_state = "upgrading"
170+
self.unit_state = upgrade.UnitState.UPGRADING
168171
workload_.upgrade(event=event, unit=self._unit, tls=tls, exporter_config=exporter_config)
169172
self._unit_workload_container_version = snap.REVISION
170173
self._unit_workload_version = self._current_versions["workload"]

src/upgrade.py

+15-4
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99

1010
import abc
1111
import copy
12+
import enum
1213
import json
1314
import logging
1415
import pathlib
@@ -34,6 +35,15 @@ class PeerRelationNotReady(Exception):
3435
"""Upgrade peer relation not available (to this unit)"""
3536

3637

38+
class UnitState(str, enum.Enum):
39+
"""Unit upgrade state"""
40+
41+
HEALTHY = "healthy"
42+
RESTARTING = "restarting" # Kubernetes only
43+
UPGRADING = "upgrading" # Machines only
44+
OUTDATED = "outdated" # Machines only
45+
46+
3747
class Upgrade(abc.ABC):
3848
"""In-place upgrades"""
3949

@@ -55,13 +65,14 @@ def __init__(self, charm_: ops.CharmBase) -> None:
5565
self._current_versions[version] = pathlib.Path(file_name).read_text().strip()
5666

5767
@property
58-
def unit_state(self) -> typing.Optional[str]:
68+
def unit_state(self) -> typing.Optional[UnitState]:
5969
"""Unit upgrade state"""
60-
return self._unit_databag.get("state")
70+
if state := self._unit_databag.get("state"):
71+
return UnitState(state)
6172

6273
@unit_state.setter
63-
def unit_state(self, value: str) -> None:
64-
self._unit_databag["state"] = value
74+
def unit_state(self, value: UnitState) -> None:
75+
self._unit_databag["state"] = value.value
6576

6677
@property
6778
def is_compatible(self) -> bool:

0 commit comments

Comments
 (0)