Skip to content

Commit

Permalink
rename _normalize_user_data,and add doc
Browse files Browse the repository at this point in the history
  • Loading branch information
skycastlelily committed Sep 28, 2024
1 parent 21822b9 commit 6d49a21
Show file tree
Hide file tree
Showing 3 changed files with 54 additions and 36 deletions.
6 changes: 3 additions & 3 deletions tmt/steps/provision/artemis.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,9 @@
from tmt.utils import (
ProvisionError,
UpdatableMessage,
_normalize_user_data,
dict_to_yaml,
field,
normalize_value_optional_string_dict,
retry_session,
)

Expand Down Expand Up @@ -154,14 +154,14 @@ class ArtemisGuestData(tmt.steps.provision.GuestSshData):
metavar='KEY=VALUE',
help='Optional data to attach to guest.',
multiple=True,
normalize=_normalize_user_data)
normalize=normalize_value_optional_string_dict)
kickstart: dict[str, str] = field(
default_factory=dict,
option='--kickstart',
metavar='KEY=VALUE',
help='Optional Beaker kickstart to use when provisioning the guest.',
multiple=True,
normalize=_normalize_user_data)
normalize=normalize_value_optional_string_dict)

log_type: list[str] = field(
default_factory=list,
Expand Down
8 changes: 3 additions & 5 deletions tmt/steps/provision/mrack.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@
ProvisionError,
ShellScript,
UpdatableMessage,
_normalize_user_data,
field,
)

Expand Down Expand Up @@ -683,8 +682,6 @@ def _translate_tmt_hw(self, hw: tmt.hardware.Hardware) -> dict[str, Any]:

def create_host_requirement(self, host: CreateJobParameters) -> dict[str, Any]:
""" Create single input for Beaker provisioner """

host["beaker"]["ks_append"] = host.get('kickstart')
req: dict[str, Any] = super().create_host_requirement(dataclasses.asdict(host))

if host.hardware and host.hardware.constraint:
Expand Down Expand Up @@ -778,7 +775,7 @@ class BeakerGuestData(tmt.steps.provision.GuestSshData):
metavar='KEY=VALUE',
help='Optional Beaker kickstart to use when provisioning the guest.',
multiple=True,
normalize=_normalize_user_data)
normalize=tmt.utils.normalize_value_optional_string_dict)

beaker_job_owner: Optional[str] = field(
default=None,
Expand Down Expand Up @@ -823,6 +820,7 @@ class CreateJobParameters:
hardware: Optional[tmt.hardware.Hardware]
whiteboard: Optional[str]
beaker_job_owner: Optional[str]
beaker: dict[str, str]
group: str = 'linux'


Expand Down Expand Up @@ -1001,7 +999,7 @@ 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,
kickstart=self.kickstart)
beaker={'ks_append': self.kickstart})

try:
response = self.api.create(data)
Expand Down
76 changes: 48 additions & 28 deletions tmt/utils/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -74,34 +74,6 @@
from tmt._compat.typing import Self, TypeAlias


def _normalize_user_data(
key_address: str,
raw_value: Any,
logger: tmt.log.Logger) -> dict[str, str]:
if isinstance(raw_value, dict):
return {
str(key).strip(): str(value).strip() for key, value in raw_value.items()
}

if isinstance(raw_value, (list, tuple)):
user_data = {}

for datum in raw_value:
try:
key, value = datum.split('=', 1)

except ValueError as exc:
raise tmt.utils.NormalizationError(
key_address, datum, 'a KEY=VALUE string') from exc

user_data[key.strip()] = value.strip()

return user_data

raise tmt.utils.NormalizationError(
key_address, value, 'a dictionary or a list of KEY=VALUE strings')


def configure_optional_constant(default: Optional[int], envvar: str) -> Optional[int]:
"""
Deduce the actual value of a global constant which may be left unset.
Expand Down Expand Up @@ -5417,6 +5389,54 @@ def normalize_shell_script(
raise NormalizationError(key_address, value, 'a string')


def normalize_value_optional_string_dict(
key_address: str,
raw_value: Any,
logger: tmt.log.Logger) -> dict[str, str]:
"""
Normalize a dict-or-list-or-tuple input value.
The input value could be specified in two ways:
* Dict, or
* List/tuple contains ``KEY=VALUE`` strings.
The acceptable formats are:
.. code-block:: python
{'metadata': 'no_autopart', 'script': 'autopart --type lvm' }
['metadata=no_autopart', 'script=autopart --type lvm']
('metadata=no_autopart', 'script=autopart --type lvm')
:param raw_value: dict, or list, or tuple.
"""

if isinstance(raw_value, dict):
return {
str(key).strip(): str(value).strip() for key, value in raw_value.items()
}

if isinstance(raw_value, (list, tuple)):
user_data = {}

for datum in raw_value:
try:
key, value = datum.split('=', 1)

except ValueError as exc:
raise tmt.utils.NormalizationError(
key_address, datum, 'a KEY=VALUE string') from exc

user_data[key.strip()] = value.strip()

return user_data

raise tmt.utils.NormalizationError(
key_address, value, 'a dictionary or a list of KEY=VALUE strings')


class NormalizeKeysMixin(_CommonBase):
"""
Mixin adding support for loading fmf keys into object attributes.
Expand Down

0 comments on commit 6d49a21

Please sign in to comment.