Merge "[ops-sunbeam] Allow post-init to throw status exceptions" into main
This commit is contained in:
@@ -25,6 +25,9 @@ from typing import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
import ops_sunbeam.tracing as sunbeam_tracing
|
import ops_sunbeam.tracing as sunbeam_tracing
|
||||||
|
from ops_sunbeam.guard import (
|
||||||
|
BaseStatusExceptionError,
|
||||||
|
)
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
from ops_sunbeam.charm import (
|
from ops_sunbeam.charm import (
|
||||||
@@ -101,5 +104,20 @@ class PostInitMeta(type):
|
|||||||
def __call__(cls, *args, **kw):
|
def __call__(cls, *args, **kw):
|
||||||
"""Call __post_init__ after __init__."""
|
"""Call __post_init__ after __init__."""
|
||||||
instance = super().__call__(*args, **kw)
|
instance = super().__call__(*args, **kw)
|
||||||
instance.__post_init__()
|
try:
|
||||||
|
instance.__post_init__()
|
||||||
|
except BaseStatusExceptionError as e:
|
||||||
|
# Allow post init to raise an ops_sunbeam status
|
||||||
|
# exception without causing the charm to error.
|
||||||
|
# This status will be collected and set on the
|
||||||
|
# unit.
|
||||||
|
# import here to avoid circular import
|
||||||
|
from ops_sunbeam.charm import (
|
||||||
|
OSBaseOperatorCharm,
|
||||||
|
)
|
||||||
|
|
||||||
|
if isinstance(instance, OSBaseOperatorCharm):
|
||||||
|
instance.status.set(e.to_status())
|
||||||
|
else:
|
||||||
|
raise e
|
||||||
return instance
|
return instance
|
||||||
|
@@ -20,9 +20,11 @@ from contextlib import (
|
|||||||
contextmanager,
|
contextmanager,
|
||||||
)
|
)
|
||||||
|
|
||||||
from ops.model import (
|
from ops import (
|
||||||
|
ActiveStatus,
|
||||||
BlockedStatus,
|
BlockedStatus,
|
||||||
MaintenanceStatus,
|
MaintenanceStatus,
|
||||||
|
StatusBase,
|
||||||
WaitingStatus,
|
WaitingStatus,
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -43,27 +45,33 @@ class GuardExceptionError(Exception):
|
|||||||
class BaseStatusExceptionError(Exception):
|
class BaseStatusExceptionError(Exception):
|
||||||
"""Charm is blocked."""
|
"""Charm is blocked."""
|
||||||
|
|
||||||
def __init__(self, msg):
|
status_type: type[StatusBase] = ActiveStatus
|
||||||
|
|
||||||
|
def __init__(self, msg: str):
|
||||||
|
super().__init__(msg)
|
||||||
self.msg = msg
|
self.msg = msg
|
||||||
super().__init__(self.msg)
|
|
||||||
|
def to_status(self):
|
||||||
|
"""Convert the exception to an ops status."""
|
||||||
|
return self.status_type(self.msg)
|
||||||
|
|
||||||
|
|
||||||
class BlockedExceptionError(BaseStatusExceptionError):
|
class BlockedExceptionError(BaseStatusExceptionError):
|
||||||
"""Charm is blocked."""
|
"""Charm is blocked."""
|
||||||
|
|
||||||
pass
|
status_type = BlockedStatus
|
||||||
|
|
||||||
|
|
||||||
class MaintenanceExceptionError(BaseStatusExceptionError):
|
class MaintenanceExceptionError(BaseStatusExceptionError):
|
||||||
"""Charm is performing maintenance."""
|
"""Charm is performing maintenance."""
|
||||||
|
|
||||||
pass
|
status_type = MaintenanceStatus
|
||||||
|
|
||||||
|
|
||||||
class WaitingExceptionError(BaseStatusExceptionError):
|
class WaitingExceptionError(BaseStatusExceptionError):
|
||||||
"""Charm is waiting."""
|
"""Charm is waiting."""
|
||||||
|
|
||||||
pass
|
status_type = WaitingStatus
|
||||||
|
|
||||||
|
|
||||||
@contextmanager
|
@contextmanager
|
||||||
@@ -103,19 +111,19 @@ def guard(
|
|||||||
logger.warning(
|
logger.warning(
|
||||||
"Charm is blocked in section '%s' due to '%s'", section, str(e)
|
"Charm is blocked in section '%s' due to '%s'", section, str(e)
|
||||||
)
|
)
|
||||||
charm.status.set(BlockedStatus(e.msg))
|
charm.status.set(e.to_status())
|
||||||
except WaitingExceptionError as e:
|
except WaitingExceptionError as e:
|
||||||
logger.warning(
|
logger.warning(
|
||||||
"Charm is waiting in section '%s' due to '%s'", section, str(e)
|
"Charm is waiting in section '%s' due to '%s'", section, str(e)
|
||||||
)
|
)
|
||||||
charm.status.set(WaitingStatus(e.msg))
|
charm.status.set(e.to_status())
|
||||||
except MaintenanceExceptionError as e:
|
except MaintenanceExceptionError as e:
|
||||||
logger.warning(
|
logger.warning(
|
||||||
"Charm performing maintenance in section '%s' due to '%s'",
|
"Charm performing maintenance in section '%s' due to '%s'",
|
||||||
section,
|
section,
|
||||||
str(e),
|
str(e),
|
||||||
)
|
)
|
||||||
charm.status.set(MaintenanceStatus(e.msg))
|
charm.status.set(e.to_status())
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
# something else went wrong
|
# something else went wrong
|
||||||
if handle_exception:
|
if handle_exception:
|
||||||
|
Reference in New Issue
Block a user