Skip to content

Commit

Permalink
Merge branch 'main' into OPENG-2205
Browse files Browse the repository at this point in the history
  • Loading branch information
michaeldmitry authored Aug 28, 2024
2 parents 5c4e4ae + 5cc1b6d commit a3400f0
Showing 1 changed file with 51 additions and 25 deletions.
76 changes: 51 additions & 25 deletions src/cosl/coordinated_workers/coordinator.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
import re
import shutil
import socket
from dataclasses import dataclass
from functools import partial
from typing import (
Any,
Expand All @@ -31,7 +32,11 @@

import cosl
from cosl.coordinated_workers.interface import ClusterProvider
from cosl.coordinated_workers.nginx import Nginx, NginxMappingOverrides, NginxPrometheusExporter
from cosl.coordinated_workers.nginx import (
Nginx,
NginxMappingOverrides,
NginxPrometheusExporter,
)
from cosl.helpers import check_libs_installed

check_libs_installed(
Expand Down Expand Up @@ -70,23 +75,46 @@ class S3NotFoundError(Exception):
"""Raised when the s3 integration is not present or not ready."""


class ClusterRolesConfig(Protocol):
class ClusterRolesConfigError(Exception):
"""Raised when the ClusterRolesConfig instance is not properly configured."""


@dataclass
class ClusterRolesConfig:
"""Worker roles and deployment requirements."""

roles: Iterable[str]
"""The union of enabled roles for the application."""
meta_roles: Mapping[str, Iterable[str]]
"""Meta roles are composed of non-meta roles (default: all)."""
minimal_deployment: Iterable[str]
"""The minimal set of roles that need to be allocated for the deployment to be considered consistent."""
recommended_deployment: Dict[str, int]
"""The set of roles that need to be allocated for the deployment to be considered robust according to the official recommendations/guidelines.."""

def __post_init__(self):
"""Ensure the various role specifications are consistent with one another."""
are_meta_keys_valid = set(self.meta_roles.keys()).issubset(self.roles)
are_meta_values_valid = all(
set(meta_value).issubset(self.roles) for meta_value in self.meta_roles.values()
)
is_minimal_valid = set(self.minimal_deployment).issubset(self.roles)
is_recommended_valid = set(self.recommended_deployment).issubset(self.roles)
if not all(
[
are_meta_keys_valid,
are_meta_values_valid,
is_minimal_valid,
is_recommended_valid,
]
):
raise ClusterRolesConfigError(
"Invalid ClusterRolesConfig: The configuration is not coherent."
)

def validate_roles_config(roles_config: ClusterRolesConfig) -> None:
"""Assert that all the used roles have been defined."""
roles = set(roles_config.roles)
assert set(roles_config.meta_roles.keys()).issubset(roles)
for role_set in roles_config.meta_roles.values():
assert set(role_set).issubset(roles)
assert set(roles_config.minimal_deployment).issubset(roles)
assert set(roles_config.recommended_deployment.keys()).issubset(roles)
def is_coherent_with(self, cluster_roles: Iterable[str]) -> bool:
"""Returns True if the provided roles satisfy the minimal deployment spec; False otherwise."""
return set(self.minimal_deployment).issubset(set(cluster_roles))


def validate_container_name(
Expand Down Expand Up @@ -187,7 +215,6 @@ def __init__(

self._endpoints = endpoints

validate_roles_config(roles_config)
validate_container_name(container_name, resources_requests)
self.roles_config = roles_config

Expand Down Expand Up @@ -247,7 +274,9 @@ def __init__(
)

self.tracing = TracingEndpointRequirer(
self._charm, relation_name=self._endpoints["tracing"], protocols=["otlp_http"]
self._charm,
relation_name=self._endpoints["tracing"],
protocols=["otlp_http"],
)

# Resources patch
Expand Down Expand Up @@ -311,10 +340,12 @@ def __init__(

# logging
self.framework.observe(
self._logging.on.loki_push_api_endpoint_joined, self._on_loki_relation_changed
self._logging.on.loki_push_api_endpoint_joined,
self._on_loki_relation_changed,
)
self.framework.observe(
self._logging.on.loki_push_api_endpoint_departed, self._on_loki_relation_changed
self._logging.on.loki_push_api_endpoint_departed,
self._on_loki_relation_changed,
)

# tls
Expand All @@ -333,15 +364,7 @@ def is_coherent(self) -> bool:
if manual_coherency_checker := self._is_coherent:
return manual_coherency_checker(self.cluster, self.roles_config)

rc = self.roles_config
minimal_deployment = set(rc.minimal_deployment)
cluster = self.cluster
roles = cluster.gather_roles()

# Whether the roles list makes up a coherent mimir deployment.
is_coherent = set(roles.keys()).issuperset(minimal_deployment)

return is_coherent
return self.roles_config.is_coherent_with(self.cluster.gather_roles().keys())

@property
def missing_roles(self) -> Set[str]:
Expand Down Expand Up @@ -375,7 +398,7 @@ def is_recommended(self) -> Optional[bool]:

@property
def can_handle_events(self) -> bool:
"""Check whether the coordinaator should handle events."""
"""Check whether the coordinator should handle events."""
return self.cluster.has_workers and self.is_coherent and self.s3_ready

@property
Expand Down Expand Up @@ -493,7 +516,10 @@ def _workers_scrape_jobs(self) -> List[Dict[str, Any]]:
"relabel_configs": [
{"target_label": "juju_charm", "replacement": worker["charm_name"]},
{"target_label": "juju_unit", "replacement": worker["unit"]},
{"target_label": "juju_application", "replacement": worker["application"]},
{
"target_label": "juju_application",
"replacement": worker["application"],
},
{"target_label": "juju_model", "replacement": self.model.name},
{"target_label": "juju_model_uuid", "replacement": self.model.uuid},
],
Expand Down

0 comments on commit a3400f0

Please sign in to comment.