Skip to content

Commit

Permalink
f
Browse files Browse the repository at this point in the history
  • Loading branch information
jscotka committed Nov 14, 2024
1 parent b5bc8f5 commit 6beadaa
Showing 1 changed file with 84 additions and 27 deletions.
111 changes: 84 additions & 27 deletions tmt/steps/provision/mrack.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
from collections.abc import Mapping
from contextlib import suppress
from functools import wraps
from threading import Lock
from typing import TYPE_CHECKING, Any, Callable, Optional, TypedDict, Union, cast

import tmt
Expand Down Expand Up @@ -76,9 +77,81 @@
DEFAULT_API_SESSION_REFRESH = 3600


def get_bkr_transformer_cls(logger: tmt.log.Logger) -> Callable:
class SingletonMeta(type):
_instances = {}
_lock: Lock = Lock()

def __call__(cls, *args, **kwargs):
with cls._lock:
if cls not in cls._instances:
instance = super().__call__(*args, **kwargs)
cls._instances[cls] = instance
return cls._instances[cls]


class MrackModule(metaclass=SingletonMeta):
_logger = None
_mrack_fixed = False

_mrack = None
_mrack_providers = None
_mrack_providers_beaker = None
_mrack_errors = None
_mrack_context = None
_mrack_transformers_beaker = None
_is_mrack_fixed = False

def init(self, logger: tmt.log.Logger) -> None:
self._logger = logger
self._mrack: mrack = import_mrack(logger=logger)
self._mrack_context: mrack.context = import_mrack_context(logger=logger)
self._mrack_errors: mrack.errors = import_mrack_errors(logger=logger)
self._mrack_providers: mrack.providers = import_mrack_providers(logger=logger)
self._mrack_providers_beaker = import_mrack_providers_beaker(logger=logger)
self._mrack_transformer_beaker = import_mrack_transformers_beaker(logger=logger)

def fix_handlers(self, workdir: Any, name: str) -> None:
# hack: remove mrack stdout and move the logfile to /tmp
if not self._is_mrack_fixed:
self._is_mrack_fixed = True
self.mrack.logger.removeHandler(self.mrack.console_handler)
self.mrack.logger.removeHandler(self.mrack.file_handler)
with suppress(OSError):
os.remove("mrack.log")

logging.FileHandler(str(f"{workdir}/{name}-mrack.log"))
providers = self.providers.providers
providers.register(
self._mrack_providers_beaker.PROVISIONER_KEY,
self._mrack_providers_beaker.BeakerProvider)

@property
def mrack(self):
return self._mrack

@property
def context(self):
return self._mrack_context

@property
def errors(self):
return self._mrack_errors

@property
def providers(self):
return self._mrack_providers

@property
def providers_beaker(self):
return self._mrack_providers_beaker

class TmtBeakerTransformer(import_mrack_transformers_beaker(logger=logger).BeakerTransformer):
@property
def mrack_transformers_beaker(self):
return self._mrack_transformer_beaker


def get_bkr_transformer_cls(logger: tmt.log.Logger) -> Callable:
class TmtBeakerTransformer(MrackModule().mrack_transformers_beaker.BeakerTransformer):
def _translate_tmt_hw(self, hw: tmt.hardware.Hardware) -> dict[str, Any]:
""" Return hw requirements from given hw dictionary """

Expand Down Expand Up @@ -912,7 +985,7 @@ class BeakerAPI:
# req is a requirement passed to Beaker mrack provisioner
mrack_requirement: dict[str, Any] = {}
dsp_name: str = "Beaker"

mrack_module = MrackModule()
# wrapping around the __init__ with async wrapper does mangle the method
# and mypy complains as it no longer returns None but the coroutine

Expand All @@ -921,17 +994,15 @@ class BeakerAPI:
async def __init__(self, guest: 'GuestBeaker', logger: tmt.log.Logger) -> None:
""" Initialize the API class with defaults and load the config """
self._guest = guest

# use global context class
global_context = import_mrack_context(logger).global_context
erorrs = import_mrack_errors(logger)
global_context = self.mrack_module.context.global_context
erorrs = self.mrack_module.errors
mrack_config_locations = [
Path(__file__).parent / "mrack/mrack.conf",
Path("/etc/tmt/mrack.conf"),
Path("~/.mrack/mrack.conf").expanduser(),
Path.cwd() / "mrack.conf"
]

mrack_config: Optional[Path] = None

for potential_location in mrack_config_locations:
Expand Down Expand Up @@ -1023,29 +1094,13 @@ class GuestBeaker(tmt.steps.provision.GuestSsh):
_api_timestamp: Optional[datetime.datetime] = None
is_mrack_handlers_fixed = False

def mrack_fix_handlers(self, workdir: Any, name: str, logger: tmt.log.Logger) -> None:
mrack = import_mrack(logger)
# hack: remove mrack stdout and move the logfile to /tmp
mrack.logger.removeHandler(mrack.console_handler)
mrack.logger.removeHandler(mrack.file_handler)
provisioner_key = import_mrack_providers_beaker(logger).PROVISIONER_KEY
beaker_provider = import_mrack_providers_beaker(logger).BeakerProvider
with suppress(OSError):
os.remove("mrack.log")

logging.FileHandler(str(f"{workdir}/{name}-mrack.log"))
providers = import_mrack_providers(logger).providers
providers.register(provisioner_key, beaker_provider)

@property
def api(self) -> BeakerAPI:
""" Create BeakerAPI leveraging mrack """

def _construct_api() -> tuple[BeakerAPI, datetime.datetime]:
assert self.parent is not None
if not self.is_mrack_handlers_fixed:
self.mrack_fix_handlers(self.parent.workdir, self.parent.name, self._logger)

MrackModule().fix_handlers(self.parent.workdir, self.parent.name)
return BeakerAPI(self, self._logger), datetime.datetime.now(datetime.timezone.utc)

if self._api is None:
Expand Down Expand Up @@ -1084,7 +1139,7 @@ def is_ready(self) -> bool:
return True
return False

except import_mrack_errors(self._logger).MrackError:
except MrackModule().errors.MrackError:
return False

def _create(self, tmt_name: str) -> None:
Expand All @@ -1099,8 +1154,10 @@ def _create(self, tmt_name: str) -> None:
name=f'{self.image}-{self.arch}',
whiteboard=self.whiteboard or tmt_name,
beaker_job_owner=self.beaker_job_owner)

provisioning_error = import_mrack_errors(self._logger).ProvisioningError
mrack_module = MrackModule()
# initialize module and logger inside mrack module as this is fist usage
mrack_module.init(self._logger)
provisioning_error = mrack_module.errors.ProvisioningError
try:
response = self.api.create(data)
except provisioning_error as exc:
Expand Down

0 comments on commit 6beadaa

Please sign in to comment.