diff --git a/ops/charm.py b/ops/charm.py index bf00b30ef..b1c726269 100755 --- a/ops/charm.py +++ b/ops/charm.py @@ -711,6 +711,38 @@ class PebbleReadyEvent(WorkloadEvent): """ +# TODO(benhoyt): should these class names have a "Pebble" prefix? +class PebbleNoticeEvent(WorkloadEvent): + def __init__(self, handle: 'Handle', workload: 'model.Container', notice_type: str, notice_key: str): + super().__init__(handle, workload) + self._notice_type = notice_type + self._notice_key = notice_key + + def snapshot(self) -> Dict[str, Any]: + d = super().snapshot() + d['notice_type'] = self._notice_type + d['notice_key'] = self._notice_key + return d + + def restore(self, snapshot: Dict[str, Any]): + self._notice_type = snapshot.pop('notice_type') + self._notice_key = snapshot.pop('notice_key') + super().restore(snapshot) + + @property + def notice(self) -> model.Notice: + # TODO(benhoyt): should probably use notice-get hook tool, but only lazily if + # attributes other than type or key are accessed? + return model.Notice(type=self._notice_type, key=self._notice_key) + + +class PebbleCustomNoticeEvent(PebbleNoticeEvent): + pass + +class PebbleChangeUpdatedEvent(PebbleNoticeEvent): + pass + + class SecretEvent(HookEvent): """Base class for all secret events.""" @@ -1083,6 +1115,8 @@ def __init__(self, framework: Framework): for container_name in self.framework.meta.containers: container_name = container_name.replace('-', '_') self.on.define_event(f"{container_name}_pebble_ready", PebbleReadyEvent) + self.on.define_event(f"{container_name}_pebble_change_updated", PebbleChangeUpdatedEvent) + self.on.define_event(f"{container_name}_pebble_custom_notice", PebbleCustomNoticeEvent) @property def app(self) -> model.Application: diff --git a/ops/main.py b/ops/main.py index 40948d44f..dbf653af8 100755 --- a/ops/main.py +++ b/ops/main.py @@ -153,7 +153,12 @@ def _get_event_args(charm: 'ops.charm.CharmBase', if issubclass(event_type, ops.charm.WorkloadEvent): workload_name = os.environ['JUJU_WORKLOAD_NAME'] container = model.unit.get_container(workload_name) - return [container], {} + args: List[Any] = [container] + if issubclass(event_type, ops.charm.PebbleNoticeEvent): + notice_type = os.environ['JUJU_NOTICE_TYPE'] + notice_key = os.environ['JUJU_NOTICE_KEY'] + args.extend([notice_type, notice_key]) + return args, {} elif issubclass(event_type, ops.charm.SecretEvent): args: List[Any] = [ os.environ['JUJU_SECRET_ID'], diff --git a/ops/model.py b/ops/model.py index 12dd2bece..43d467c6b 100644 --- a/ops/model.py +++ b/ops/model.py @@ -1082,6 +1082,15 @@ def __repr__(self): ).format(self=self) +# TODO(benhoyt): where should this go in the file? +@dataclasses.dataclass(frozen=True) +class Notice: + type: str + key: str + + # TODO(benhoyt): add other attributes got using notice-get hook tool + + class Secret: """Represents a single secret in the model.