Add support for masakarimonitors
* Add new interface service-ready to check for service readiness of remote application. * Create a placeholder charm sunbeam-libs to place all the common libraries. The charm and the libraries need not be published to charmhub since at this point of time they are used internally by sunbeam. * Add provider to service-ready in masakari-k8s * Add requirer to service-ready in openstack-hypervisor and enable/disable snap option masakari.enable based on service-ready relation. Change-Id: I99feccee2c871fc5a581fdea6f45a541efc2a968
This commit is contained in:
parent
bd137e4c39
commit
0bdc19c4ea
@ -9,6 +9,7 @@ external-libraries:
|
||||
- charms.tempo_k8s.v1.charm_tracing
|
||||
internal-libraries:
|
||||
- charms.keystone_k8s.v1.identity_service
|
||||
- charms.sunbeam_libs.v0.service_readiness
|
||||
templates:
|
||||
- parts/database-connection
|
||||
- parts/database-connection-settings
|
||||
|
@ -98,6 +98,10 @@ requires:
|
||||
limit: 1
|
||||
optional: true
|
||||
|
||||
provides:
|
||||
masakari-service:
|
||||
interface: service-ready
|
||||
|
||||
peers:
|
||||
peers:
|
||||
interface: masakari-peer
|
||||
|
@ -41,6 +41,9 @@ from charms.consul_k8s.v0.consul_cluster import (
|
||||
from ops import (
|
||||
main,
|
||||
)
|
||||
from ops.charm import (
|
||||
RelationEvent,
|
||||
)
|
||||
from ops.model import (
|
||||
BlockedStatus,
|
||||
)
|
||||
@ -362,6 +365,15 @@ class MasakariOperatorCharm(sunbeam_charm.OSBaseOperatorAPICharm):
|
||||
)
|
||||
handlers.append(self.consul_storage)
|
||||
|
||||
self.svc_ready_handler = (
|
||||
sunbeam_rhandlers.ServiceReadinessProviderHandler(
|
||||
self,
|
||||
"masakari-service",
|
||||
self.handle_readiness_request_from_event,
|
||||
)
|
||||
)
|
||||
handlers.append(self.svc_ready_handler)
|
||||
|
||||
handlers = super().get_relation_handlers(handlers)
|
||||
return handlers
|
||||
|
||||
@ -399,6 +411,27 @@ class MasakariOperatorCharm(sunbeam_charm.OSBaseOperatorAPICharm):
|
||||
)
|
||||
return pebble_handlers
|
||||
|
||||
def post_config_setup(self):
|
||||
"""Configuration steps after services have been setup."""
|
||||
super().post_config_setup()
|
||||
self.set_readiness_on_related_units()
|
||||
|
||||
def handle_readiness_request_from_event(
|
||||
self, event: RelationEvent
|
||||
) -> None:
|
||||
"""Set service readiness in relation data."""
|
||||
self.svc_ready_handler.interface.set_service_status(
|
||||
event.relation, self.bootstrapped()
|
||||
)
|
||||
|
||||
def set_readiness_on_related_units(self) -> None:
|
||||
"""Set service readiness on masakari-service related units."""
|
||||
logger.debug(
|
||||
"Set service readiness on all connected masakari-service relations"
|
||||
)
|
||||
for relation in self.framework.model.relations["masakari-service"]:
|
||||
self.svc_ready_handler.interface.set_service_status(relation, True)
|
||||
|
||||
@property
|
||||
def service_name(self):
|
||||
"""Service name."""
|
||||
|
@ -15,3 +15,4 @@ internal-libraries:
|
||||
- charms.cinder_ceph_k8s.v0.ceph_access
|
||||
- charms.ceilometer_k8s.v0.ceilometer_service
|
||||
- charms.nova_k8s.v0.nova_service
|
||||
- charms.sunbeam_libs.v0.service_readiness
|
||||
|
@ -80,6 +80,8 @@ requires:
|
||||
optional: true
|
||||
nova-service:
|
||||
interface: nova
|
||||
masakari-service:
|
||||
interface: service-ready
|
||||
tracing:
|
||||
interface: tracing
|
||||
optional: true
|
||||
|
@ -292,6 +292,16 @@ class HypervisorOperatorCharm(sunbeam_charm.OSBaseOperatorCharm):
|
||||
mandatory="certificates" in self.mandatory_relations,
|
||||
)
|
||||
handlers.append(self.certs)
|
||||
if self.can_add_handler("masakari-service", handlers):
|
||||
self.masakari_svc = (
|
||||
sunbeam_rhandlers.ServiceReadinessRequiresHandler(
|
||||
self,
|
||||
"masakari-service",
|
||||
self.configure_charm,
|
||||
"masakari-service" in self.mandatory_relations,
|
||||
)
|
||||
)
|
||||
handlers.append(self.masakari_svc)
|
||||
handlers = super().get_relation_handlers(handlers)
|
||||
return handlers
|
||||
|
||||
@ -468,6 +478,7 @@ class HypervisorOperatorCharm(sunbeam_charm.OSBaseOperatorCharm):
|
||||
snap_data.update(self._handle_ceilometer_service(contexts))
|
||||
snap_data.update(self._handle_nova_service(contexts))
|
||||
snap_data.update(self._handle_receive_ca_cert(contexts))
|
||||
snap_data.update(self._handle_masakari_service(contexts))
|
||||
|
||||
self.set_snap_data(snap_data)
|
||||
self.ensure_services_running()
|
||||
@ -518,6 +529,15 @@ class HypervisorOperatorCharm(sunbeam_charm.OSBaseOperatorCharm):
|
||||
|
||||
return {}
|
||||
|
||||
def _handle_masakari_service(
|
||||
self, contexts: sunbeam_core.OPSCharmContexts
|
||||
) -> dict:
|
||||
try:
|
||||
return {"masakari.enable": contexts.masakari_service.service_ready}
|
||||
except AttributeError:
|
||||
logger.info("masakari_service relation not integrated")
|
||||
return {"masakari.enable": False}
|
||||
|
||||
def _handle_receive_ca_cert(
|
||||
self, context: sunbeam_core.OPSCharmContexts
|
||||
) -> dict:
|
||||
|
@ -162,6 +162,7 @@ class TestCharm(test_utils.CharmTestCase):
|
||||
"rabbitmq.url": "rabbit://hypervisor:rabbit.pass@10.0.0.13:5672/openstack",
|
||||
"telemetry.enable": False,
|
||||
"ca.bundle": None,
|
||||
"masakari.enable": False,
|
||||
}
|
||||
hypervisor_snap_mock.set.assert_any_call(expect_settings, typed=True)
|
||||
|
||||
@ -195,6 +196,13 @@ class TestCharm(test_utils.CharmTestCase):
|
||||
},
|
||||
)
|
||||
|
||||
# Add masakari-service relation
|
||||
self.harness.add_relation(
|
||||
"masakari-service",
|
||||
"masakari",
|
||||
app_data={"ready": "true"},
|
||||
)
|
||||
|
||||
self.get_local_ip_by_default_route.return_value = "10.0.0.10"
|
||||
hypervisor_snap_mock = MagicMock()
|
||||
hypervisor_snap_mock.present = False
|
||||
@ -266,5 +274,6 @@ class TestCharm(test_utils.CharmTestCase):
|
||||
"telemetry.enable": True,
|
||||
"telemetry.publisher-secret": "FAKE_SECRET",
|
||||
"ca.bundle": None,
|
||||
"masakari.enable": True,
|
||||
}
|
||||
hypervisor_snap_mock.set.assert_any_call(expect_settings, typed=True)
|
||||
|
3
charms/sunbeam-libs/.sunbeam-build.yaml
Normal file
3
charms/sunbeam-libs/.sunbeam-build.yaml
Normal file
@ -0,0 +1,3 @@
|
||||
external-libraries: []
|
||||
internal-libraries: []
|
||||
templates: []
|
25
charms/sunbeam-libs/charmcraft.yaml
Normal file
25
charms/sunbeam-libs/charmcraft.yaml
Normal file
@ -0,0 +1,25 @@
|
||||
type: charm
|
||||
title: Sunbeam common libraries
|
||||
name: sunbeam-libs
|
||||
summary: Sunbeam common libraries
|
||||
description: |
|
||||
Placeholder for the common libraries used in Sunbeam.
|
||||
assumes:
|
||||
- k8s-api
|
||||
links:
|
||||
source: https://opendev.org/openstack/sunbeam-charms
|
||||
issues: https://bugs.launchpad.net/sunbeam-charms
|
||||
|
||||
base: ubuntu@24.04
|
||||
platforms:
|
||||
amd64:
|
||||
|
||||
containers:
|
||||
placeholder:
|
||||
resource: placeholder-image
|
||||
|
||||
resources:
|
||||
placeholder-image:
|
||||
description: OCI image for placeholder
|
||||
type: oci-image
|
||||
upstream-source: busybox
|
@ -0,0 +1,203 @@
|
||||
"""Service Provides and Requires module.
|
||||
|
||||
The interface `service-ready` is to inform that remote service is ready.
|
||||
This library contains the Requires and Provides classes for handling
|
||||
the service-ready interface.
|
||||
|
||||
Import `ServiceReadinessRequirer` in your charm, with the charm object and the
|
||||
relation name:
|
||||
- self
|
||||
- "service"
|
||||
|
||||
Two events are also available to respond to:
|
||||
- readiness_changed
|
||||
- goneaway
|
||||
|
||||
A basic example showing the usage of this relation follows:
|
||||
|
||||
```
|
||||
from charms.masakari_k8s.v0.service_readiness import (
|
||||
ServiceReadinessRequirer
|
||||
)
|
||||
|
||||
class ServiceClientCharm(CharmBase):
|
||||
def __init__(self, *args):
|
||||
super().__init__(*args)
|
||||
# Service Requires
|
||||
self._svc = ServiceReadinessRequirer(
|
||||
self, "service",
|
||||
)
|
||||
self.framework.observe(
|
||||
self._svc.on.readiness_changed,
|
||||
self._on_service_readiness_changed
|
||||
)
|
||||
self.framework.observe(
|
||||
self._svc.on.goneaway,
|
||||
self._on_service_goneaway
|
||||
)
|
||||
|
||||
def _on_service_readiness_changed(self, event):
|
||||
'''React to the service readiness changed event.
|
||||
|
||||
This event happens when service relation is added to the
|
||||
model and relation data is changed.
|
||||
'''
|
||||
# Do something with the configuration provided by relation.
|
||||
pass
|
||||
|
||||
def _on_service_goneaway(self, event):
|
||||
'''React to the Service goneaway event.
|
||||
|
||||
This event happens when service relation is removed.
|
||||
'''
|
||||
# Service Relation has goneaway.
|
||||
pass
|
||||
```
|
||||
"""
|
||||
|
||||
|
||||
import json
|
||||
import logging
|
||||
|
||||
from ops.charm import (
|
||||
CharmBase,
|
||||
RelationBrokenEvent,
|
||||
RelationChangedEvent,
|
||||
RelationEvent,
|
||||
)
|
||||
from ops.framework import (
|
||||
EventSource,
|
||||
Object,
|
||||
ObjectEvents,
|
||||
)
|
||||
from ops.model import (
|
||||
Relation,
|
||||
)
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
# The unique Charmhub library identifier, never change it
|
||||
LIBID = "706872aa869c11ef9444175192825660"
|
||||
|
||||
# Increment this major API version when introducing breaking changes
|
||||
LIBAPI = 0
|
||||
|
||||
# Increment this PATCH version before using `charmcraft publish-lib` or reset
|
||||
# to 0 if you are raising the major API version
|
||||
LIBPATCH = 1
|
||||
|
||||
|
||||
class ServiceReadinessRequestEvent(RelationEvent):
|
||||
"""ServiceReadinessRequest Event."""
|
||||
|
||||
pass
|
||||
|
||||
|
||||
class ServiceReadinessProviderEvents(ObjectEvents):
|
||||
"""Events class for `on`."""
|
||||
|
||||
service_readiness = EventSource(ServiceReadinessRequestEvent)
|
||||
|
||||
|
||||
class ServiceReadinessProvider(Object):
|
||||
"""ServiceReadinessProvider class."""
|
||||
|
||||
on = ServiceReadinessProviderEvents()
|
||||
|
||||
def __init__(self, charm: CharmBase, relation_name: str):
|
||||
super().__init__(charm, relation_name)
|
||||
self.charm = charm
|
||||
self.relation_name = relation_name
|
||||
self.framework.observe(
|
||||
self.charm.on[relation_name].relation_changed,
|
||||
self._on_relation_changed,
|
||||
)
|
||||
|
||||
def _on_relation_changed(self, event: RelationChangedEvent):
|
||||
"""Handle service relation changed."""
|
||||
logging.debug(f"Service relation changed for relation {self.relation_name}")
|
||||
self.on.service_readiness.emit(event.relation)
|
||||
|
||||
def set_service_status(self, relation: Relation, is_ready: bool) -> None:
|
||||
"""Set service readiness status on the relation."""
|
||||
if not self.charm.unit.is_leader():
|
||||
logging.debug("Not a leader unit, skipping setting ready status")
|
||||
return
|
||||
|
||||
logging.debug(
|
||||
f"Setting ready status on relation {relation.app.name} "
|
||||
f"{relation.name}/{relation.id}"
|
||||
)
|
||||
relation.data[self.charm.app]["ready"] = json.dumps(is_ready)
|
||||
|
||||
|
||||
class ServiceReadinessChangedEvent(RelationEvent):
|
||||
"""ServiceReadinessChanged Event."""
|
||||
|
||||
pass
|
||||
|
||||
|
||||
class ServiceGoneAwayEvent(RelationEvent):
|
||||
"""ServiceGoneAway Event."""
|
||||
|
||||
pass
|
||||
|
||||
|
||||
class ServiceReadinessRequirerEvents(ObjectEvents):
|
||||
"""Events class for `on`."""
|
||||
|
||||
readiness_changed = EventSource(ServiceReadinessChangedEvent)
|
||||
goneaway = EventSource(ServiceGoneAwayEvent)
|
||||
|
||||
|
||||
class ServiceReadinessRequirer(Object):
|
||||
"""ServiceReadinessRequirer class."""
|
||||
|
||||
on = ServiceReadinessRequirerEvents()
|
||||
|
||||
def __init__(self, charm: CharmBase, relation_name: str):
|
||||
super().__init__(charm, relation_name)
|
||||
self.charm = charm
|
||||
self.relation_name = relation_name
|
||||
self.framework.observe(
|
||||
self.charm.on[relation_name].relation_changed,
|
||||
self._on_relation_changed,
|
||||
)
|
||||
self.framework.observe(
|
||||
self.charm.on[relation_name].relation_broken,
|
||||
self._on_relation_broken,
|
||||
)
|
||||
|
||||
def _on_relation_changed(self, event: RelationChangedEvent):
|
||||
"""Handle Service relation changed."""
|
||||
logging.debug(f"service readiness data changed for relation {self.relation_name}")
|
||||
self.on.readiness_changed.emit(event.relation)
|
||||
|
||||
def _on_relation_broken(self, event: RelationBrokenEvent):
|
||||
"""Handle Service relation broken."""
|
||||
logging.debug(f"service readiness relation broken for {self.relation_name}")
|
||||
self.on.goneaway.emit(event.relation)
|
||||
|
||||
@property
|
||||
def _service_rel(self) -> Relation | None:
|
||||
"""The service relation."""
|
||||
return self.framework.model.get_relation(self.relation_name)
|
||||
|
||||
def get_remote_app_data(self, key: str) -> str | None:
|
||||
"""Return the value for the given key from remote app data."""
|
||||
if self._service_rel:
|
||||
data = self._service_rel.data[
|
||||
self._service_rel.app
|
||||
]
|
||||
return data.get(key)
|
||||
|
||||
return None
|
||||
|
||||
@property
|
||||
def service_ready(self) -> bool:
|
||||
"""Return if service is ready or not."""
|
||||
is_ready = self.get_remote_app_data("ready")
|
||||
if is_ready:
|
||||
return json.loads(is_ready)
|
||||
|
||||
return False
|
36
charms/sunbeam-libs/src/charm.py
Executable file
36
charms/sunbeam-libs/src/charm.py
Executable file
@ -0,0 +1,36 @@
|
||||
#!/usr/bin/env python3
|
||||
# Copyright 2024 Canonical Ltd.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
"""sunbeam-libs Charm.
|
||||
|
||||
This charm is a placeholder for sunbeam common libraries.
|
||||
"""
|
||||
|
||||
import ops_sunbeam.charm as sunbeam_charm
|
||||
from ops import (
|
||||
main,
|
||||
)
|
||||
|
||||
|
||||
class SunbeamLibsCharm(sunbeam_charm.OSBaseOperatorCharmK8S):
|
||||
"""Placeholder charm for Sunbeam common libs."""
|
||||
|
||||
@property
|
||||
def service_name(self):
|
||||
"""Service name."""
|
||||
return "placeholder"
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main(SunbeamLibsCharm)
|
17
charms/sunbeam-libs/tests/unit/__init__.py
Normal file
17
charms/sunbeam-libs/tests/unit/__init__.py
Normal file
@ -0,0 +1,17 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
# Copyright 2024 Canonical Ltd.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
"""Unit tests for sunbeam-libs."""
|
59
charms/sunbeam-libs/tests/unit/test_charm.py
Normal file
59
charms/sunbeam-libs/tests/unit/test_charm.py
Normal file
@ -0,0 +1,59 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
# Copyright 2024 Canonical Ltd.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
"""Tests for sunbeam-libs charm."""
|
||||
|
||||
import charm
|
||||
import ops_sunbeam.test_utils as test_utils
|
||||
|
||||
|
||||
class _SunbeamLibsCharm(charm.SunbeamLibsCharm):
|
||||
"""Dummy class to satisfy reading proper charmcraft file."""
|
||||
|
||||
def __init__(self, framework):
|
||||
self.seen_events = []
|
||||
super().__init__(framework)
|
||||
|
||||
def _log_event(self, event):
|
||||
self.seen_events.append(type(event).__name__)
|
||||
|
||||
def configure_charm(self, event):
|
||||
super().configure_charm(event)
|
||||
self._log_event(event)
|
||||
|
||||
|
||||
class TestSunbeamLibsCharm(test_utils.CharmTestCase):
|
||||
"""Class for testing sunbeam-libs charm."""
|
||||
|
||||
def setUp(self):
|
||||
"""Run setup for unit tests."""
|
||||
super().setUp(charm, [])
|
||||
self.harness = test_utils.get_harness(
|
||||
_SunbeamLibsCharm,
|
||||
container_calls=self.container_calls,
|
||||
)
|
||||
|
||||
self.addCleanup(self.harness.cleanup)
|
||||
|
||||
def test_pebble_ready_handler(self):
|
||||
"""Test Pebble ready event is captured."""
|
||||
self.harness.begin()
|
||||
self.assertEqual(self.harness.charm.seen_events, [])
|
||||
test_utils.set_all_pebbles_ready(self.harness)
|
||||
self.assertEqual(
|
||||
self.harness.charm.seen_events,
|
||||
["PebbleReadyEvent"],
|
||||
)
|
@ -57,6 +57,7 @@ if typing.TYPE_CHECKING:
|
||||
import charms.loki_k8s.v1.loki_push_api as loki_push_api
|
||||
import charms.nova_k8s.v0.nova_service as nova_service
|
||||
import charms.rabbitmq_k8s.v0.rabbitmq as rabbitmq
|
||||
import charms.sunbeam_libs.v0.service_readiness as service_readiness
|
||||
import charms.tempo_k8s.v2.tracing as tracing
|
||||
import charms.tls_certificates_interface.v3.tls_certificates as tls_certificates
|
||||
import charms.traefik_k8s.v2.ingress as ingress
|
||||
@ -2450,3 +2451,137 @@ class GnocchiServiceRequiresHandler(RelationHandler):
|
||||
def ready(self) -> bool:
|
||||
"""Whether handler is ready for use."""
|
||||
return self.interface.service_ready
|
||||
|
||||
|
||||
@sunbeam_tracing.trace_type
|
||||
class ServiceReadinessRequiresHandler(RelationHandler):
|
||||
"""Handle service-ready relation on the requires side."""
|
||||
|
||||
interface: "service_readiness.ServiceReadinessRequirer"
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
charm: "OSBaseOperatorCharm",
|
||||
relation_name: str,
|
||||
callback_f: Callable,
|
||||
mandatory: bool = False,
|
||||
):
|
||||
"""Create a new service-ready requirer handler.
|
||||
|
||||
Create a new ServiceReadinessRequiresHandler that handles initial
|
||||
events from the relation and invokes the provided callbacks based on
|
||||
the event raised.
|
||||
|
||||
:param charm: the Charm class the handler is for
|
||||
:type charm: ops.charm.CharmBase
|
||||
:param relation_name: the relation the handler is bound to
|
||||
:type relation_name: str
|
||||
:param callback_f: the function to call when the nodes are connected
|
||||
:type callback_f: Callable
|
||||
:param mandatory: If the relation is mandatory to proceed with
|
||||
configuring charm
|
||||
:type mandatory: bool
|
||||
"""
|
||||
super().__init__(charm, relation_name, callback_f, mandatory)
|
||||
|
||||
def setup_event_handler(self) -> ops.framework.Object:
|
||||
"""Configure event handlers for service-ready relation."""
|
||||
import charms.sunbeam_libs.v0.service_readiness as service_readiness
|
||||
|
||||
logger.debug(
|
||||
f"Setting up service-ready event handler for {self.relation_name}"
|
||||
)
|
||||
svc = sunbeam_tracing.trace_type(
|
||||
service_readiness.ServiceReadinessRequirer
|
||||
)(
|
||||
self.charm,
|
||||
self.relation_name,
|
||||
)
|
||||
self.framework.observe(
|
||||
svc.on.readiness_changed,
|
||||
self._on_remote_service_readiness_changed,
|
||||
)
|
||||
self.framework.observe(
|
||||
svc.on.goneaway,
|
||||
self._on_remote_service_goneaway,
|
||||
)
|
||||
return svc
|
||||
|
||||
def _on_remote_service_readiness_changed(
|
||||
self, event: ops.framework.EventBase
|
||||
) -> None:
|
||||
"""Handle config_changed event."""
|
||||
logger.debug(
|
||||
f"Remote service readiness changed event received for relation {self.relation_name}"
|
||||
)
|
||||
self.callback_f(event)
|
||||
|
||||
def _on_remote_service_goneaway(
|
||||
self, event: ops.framework.EventBase
|
||||
) -> None:
|
||||
"""Handle gone_away event."""
|
||||
logger.debug(
|
||||
"Remote service gone away event received for relation {self.relation_name}"
|
||||
)
|
||||
self.callback_f(event)
|
||||
if self.mandatory:
|
||||
self.status.set(BlockedStatus("integration missing"))
|
||||
|
||||
@property
|
||||
def ready(self) -> bool:
|
||||
"""Whether handler is ready for use."""
|
||||
return self.interface.service_ready
|
||||
|
||||
|
||||
@sunbeam_tracing.trace_type
|
||||
class ServiceReadinessProviderHandler(RelationHandler):
|
||||
"""Handler for service-readiness relation on provider side."""
|
||||
|
||||
interface: "service_readiness.ServiceReadinessProvider"
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
charm: "OSBaseOperatorCharm",
|
||||
relation_name: str,
|
||||
callback_f: Callable,
|
||||
):
|
||||
"""Create a new service-readiness provider handler.
|
||||
|
||||
Create a new ServiceReadinessProvidesHandler that updates service
|
||||
readiness on the related units.
|
||||
|
||||
:param charm: the Charm class the handler is for
|
||||
:type charm: ops.charm.CharmBase
|
||||
:param relation_name: the relation the handler is bound to
|
||||
:type relation_name: str
|
||||
:param callback_f: the function to call when the nodes are connected
|
||||
:type callback_f: Callable
|
||||
"""
|
||||
super().__init__(charm, relation_name, callback_f)
|
||||
|
||||
def setup_event_handler(self):
|
||||
"""Configure event handlers for service-readiness relation."""
|
||||
import charms.sunbeam_libs.v0.service_readiness as service_readiness
|
||||
|
||||
logger.debug(f"Setting up event handler for {self.relation_name}")
|
||||
|
||||
svc = sunbeam_tracing.trace_type(
|
||||
service_readiness.ServiceReadinessProvider
|
||||
)(
|
||||
self.charm,
|
||||
self.relation_name,
|
||||
)
|
||||
self.framework.observe(
|
||||
svc.on.service_readiness,
|
||||
self._on_service_readiness,
|
||||
)
|
||||
return svc
|
||||
|
||||
def _on_service_readiness(self, event: ops.framework.EventBase) -> None:
|
||||
"""Handle service readiness request event."""
|
||||
self.callback_f(event)
|
||||
|
||||
@property
|
||||
def ready(self) -> bool:
|
||||
"""Report if relation is ready."""
|
||||
return True
|
||||
|
Loading…
Reference in New Issue
Block a user