[nova-k8s/placement-k8s] Add placement interface
nova-scheduler errors out if placement service is not available even if the container healthchecks shows active. Add placement integration in nova-k8s to ensure placement is defined in the bundle/tf plan Add ServiceReadinessProviderHandler in placement-k8s and corresponding RequiresHandler in nova-k8s. Fixes: #2097327 Change-Id: Ica072b98c4668c6248702ca680b2885c4d542e23
This commit is contained in:
parent
e07819a9d9
commit
f218d87642
@ -10,6 +10,7 @@ external-libraries:
|
|||||||
- charms.tempo_k8s.v1.charm_tracing
|
- charms.tempo_k8s.v1.charm_tracing
|
||||||
internal-libraries:
|
internal-libraries:
|
||||||
- charms.keystone_k8s.v1.identity_service
|
- charms.keystone_k8s.v1.identity_service
|
||||||
|
- charms.sunbeam_libs.v0.service_readiness
|
||||||
templates:
|
templates:
|
||||||
- parts/section-database
|
- parts/section-database
|
||||||
- parts/database-connection
|
- parts/database-connection
|
||||||
|
@ -93,6 +93,8 @@ requires:
|
|||||||
interface: rabbitmq
|
interface: rabbitmq
|
||||||
identity-service:
|
identity-service:
|
||||||
interface: keystone
|
interface: keystone
|
||||||
|
placement:
|
||||||
|
interface: placement
|
||||||
cloud-compute:
|
cloud-compute:
|
||||||
interface: nova-compute
|
interface: nova-compute
|
||||||
optional: true
|
optional: true
|
||||||
|
@ -543,6 +543,13 @@ class NovaOperatorCharm(sunbeam_charm.OSBaseOperatorAPICharm):
|
|||||||
[NOVA_API_INGRESS_NAME, NOVA_SPICEPROXY_INGRESS_NAME],
|
[NOVA_API_INGRESS_NAME, NOVA_SPICEPROXY_INGRESS_NAME],
|
||||||
)
|
)
|
||||||
handlers.append(self.traefik_route_internal)
|
handlers.append(self.traefik_route_internal)
|
||||||
|
self.placement_svc = sunbeam_rhandlers.ServiceReadinessRequiresHandler(
|
||||||
|
self,
|
||||||
|
"placement",
|
||||||
|
self.configure_charm,
|
||||||
|
"placement" in self.mandatory_relations,
|
||||||
|
)
|
||||||
|
handlers.append(self.placement_svc)
|
||||||
|
|
||||||
return handlers
|
return handlers
|
||||||
|
|
||||||
|
@ -94,6 +94,10 @@ class TestNovaOperatorCharm(test_utils.CharmTestCase):
|
|||||||
app_data={"external_host": "dummy-ip", "scheme": "http"},
|
app_data={"external_host": "dummy-ip", "scheme": "http"},
|
||||||
)
|
)
|
||||||
|
|
||||||
|
def add_placement_relation(self, harness: Harness) -> None:
|
||||||
|
"""Add placement relation."""
|
||||||
|
harness.add_relation("placement", "nova", app_data={"ready": "true"})
|
||||||
|
|
||||||
def add_db_relation(self, harness: Harness, name: str) -> str:
|
def add_db_relation(self, harness: Harness, name: str) -> str:
|
||||||
"""Add db relation."""
|
"""Add db relation."""
|
||||||
rel_id = harness.add_relation(name, "mysql")
|
rel_id = harness.add_relation(name, "mysql")
|
||||||
@ -117,6 +121,7 @@ class TestNovaOperatorCharm(test_utils.CharmTestCase):
|
|||||||
# this adds all the default/common relations
|
# this adds all the default/common relations
|
||||||
test_utils.add_all_relations(self.harness)
|
test_utils.add_all_relations(self.harness)
|
||||||
self.add_complete_ingress_relation(self.harness)
|
self.add_complete_ingress_relation(self.harness)
|
||||||
|
self.add_placement_relation(self.harness)
|
||||||
|
|
||||||
# but nova has some extra db relations, so add them manually here
|
# but nova has some extra db relations, so add them manually here
|
||||||
rel_id = self.add_db_relation(self.harness, "api-database")
|
rel_id = self.add_db_relation(self.harness, "api-database")
|
||||||
|
@ -8,6 +8,7 @@ external-libraries:
|
|||||||
- charms.tempo_k8s.v1.charm_tracing
|
- charms.tempo_k8s.v1.charm_tracing
|
||||||
internal-libraries:
|
internal-libraries:
|
||||||
- charms.keystone_k8s.v1.identity_service
|
- charms.keystone_k8s.v1.identity_service
|
||||||
|
- charms.sunbeam_libs.v0.service_readiness
|
||||||
templates:
|
templates:
|
||||||
- parts/database-connection
|
- parts/database-connection
|
||||||
- parts/database-connection-settings
|
- parts/database-connection-settings
|
||||||
|
@ -30,7 +30,11 @@ import ops.pebble
|
|||||||
import ops_sunbeam.charm as sunbeam_charm
|
import ops_sunbeam.charm as sunbeam_charm
|
||||||
import ops_sunbeam.container_handlers as sunbeam_chandlers
|
import ops_sunbeam.container_handlers as sunbeam_chandlers
|
||||||
import ops_sunbeam.core as sunbeam_core
|
import ops_sunbeam.core as sunbeam_core
|
||||||
|
import ops_sunbeam.relation_handlers as sunbeam_rhandlers
|
||||||
import ops_sunbeam.tracing as sunbeam_tracing
|
import ops_sunbeam.tracing as sunbeam_tracing
|
||||||
|
from ops.charm import (
|
||||||
|
RelationEvent,
|
||||||
|
)
|
||||||
from ops.framework import (
|
from ops.framework import (
|
||||||
StoredState,
|
StoredState,
|
||||||
)
|
)
|
||||||
@ -86,6 +90,44 @@ class PlacementOperatorCharm(sunbeam_charm.OSBaseOperatorAPICharm):
|
|||||||
)
|
)
|
||||||
]
|
]
|
||||||
|
|
||||||
|
def get_relation_handlers(
|
||||||
|
self, handlers: list[sunbeam_rhandlers.RelationHandler] | None = None
|
||||||
|
) -> list[sunbeam_rhandlers.RelationHandler]:
|
||||||
|
"""Relation handlers for the service."""
|
||||||
|
handlers = handlers or []
|
||||||
|
self.svc_ready_handler = (
|
||||||
|
sunbeam_rhandlers.ServiceReadinessProviderHandler(
|
||||||
|
self,
|
||||||
|
"placement",
|
||||||
|
self.handle_readiness_request_from_event,
|
||||||
|
)
|
||||||
|
)
|
||||||
|
handlers.append(self.svc_ready_handler)
|
||||||
|
|
||||||
|
handlers = super().get_relation_handlers(handlers)
|
||||||
|
return 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 placement related units."""
|
||||||
|
logger.debug(
|
||||||
|
"Set service readiness on all connected placement relations"
|
||||||
|
)
|
||||||
|
for relation in self.framework.model.relations["placement"]:
|
||||||
|
self.svc_ready_handler.interface.set_service_status(relation, True)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def container_configs(self) -> List[sunbeam_core.ContainerConfigFile]:
|
def container_configs(self) -> List[sunbeam_core.ContainerConfigFile]:
|
||||||
"""Container configurations for the operator."""
|
"""Container configurations for the operator."""
|
||||||
|
@ -418,6 +418,8 @@ relations:
|
|||||||
- nova:traefik-route-internal
|
- nova:traefik-route-internal
|
||||||
- - keystone:send-ca-cert
|
- - keystone:send-ca-cert
|
||||||
- nova:receive-ca-cert
|
- nova:receive-ca-cert
|
||||||
|
- - placement:placement
|
||||||
|
- nova:placement
|
||||||
|
|
||||||
- - mysql:database
|
- - mysql:database
|
||||||
- placement:database
|
- placement:database
|
||||||
|
@ -188,6 +188,8 @@ relations:
|
|||||||
- nova:traefik-route-internal
|
- nova:traefik-route-internal
|
||||||
- - keystone:send-ca-cert
|
- - keystone:send-ca-cert
|
||||||
- nova:receive-ca-cert
|
- nova:receive-ca-cert
|
||||||
|
- - placement:placement
|
||||||
|
- nova:placement
|
||||||
|
|
||||||
- - mysql:database
|
- - mysql:database
|
||||||
- placement:database
|
- placement:database
|
||||||
|
@ -183,6 +183,8 @@ relations:
|
|||||||
- nova:traefik-route-internal
|
- nova:traefik-route-internal
|
||||||
- - keystone:send-ca-cert
|
- - keystone:send-ca-cert
|
||||||
- nova:receive-ca-cert
|
- nova:receive-ca-cert
|
||||||
|
- - placement:placement
|
||||||
|
- nova:placement
|
||||||
|
|
||||||
- - mysql:database
|
- - mysql:database
|
||||||
- placement:database
|
- placement:database
|
||||||
|
Loading…
x
Reference in New Issue
Block a user