Skip to content

Commit

Permalink
Add the iommu specification for hardware (#3100)
Browse files Browse the repository at this point in the history
Fixes #2392

Signed-off-by: Han Han <[email protected]>
Co-authored-by: Petr Šplíchal <[email protected]>
  • Loading branch information
qiankehan and psss authored Oct 1, 2024
1 parent 2b223e1 commit d7686b4
Show file tree
Hide file tree
Showing 7 changed files with 113 additions and 4 deletions.
5 changes: 5 additions & 0 deletions docs/releases.rst
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,11 @@ The ``tmt try`` command now supports the new
new :ref:`/stories/cli/try/option/install` option backed by the
:ref:`prepare/feature</plugins/prepare/install>` plugin.

The new key :ref:`/spec/hardware/iommu` allowing to provision a
guest with the `Input–output memory management unit` has been
added into the :ref:`/spec/hardware` specification and implemented
in the :ref:`/plugins/provision/beaker` provision plugin.


tmt-1.36.1
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Expand Down
32 changes: 32 additions & 0 deletions spec/hardware/iommu.fmf
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
summary: |
Select or provision a guest with the `Input–output memory management unit`.

description: |
.. code-block::

iommu:
# Boolean, whether the guest supports IOMMU
is-supported: true|false
# String, the model name for IOMMU
model-name: "virtio"|"intel"|"smmuv3"|...

.. versionadded:: 1.37

.. versionchanged:: 1.37
``beaker`` plugin supports ``iommu``

example:
- |
# Require a guest that supports IOMMU
iommu:
is-supported: true

- |
# Require a guest with the IOMMU of virtio model
iommu:
is-supported: true
model-name: virtio

link:
- implemented-by: /tmt/steps/provision/mrack.py
note: "``iommu.is-supported`` only"
17 changes: 17 additions & 0 deletions tests/unit/provision/mrack/test_hw.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
_parse_cpu,
_parse_disk,
_parse_hostname,
_parse_iommu,
_parse_location,
_parse_memory,
_parse_system,
Expand Down Expand Up @@ -788,6 +789,22 @@ def test_zcrypt_mode(root_logger: Logger) -> None:
}


def test_iommu_is_supported(root_logger: Logger) -> None:

for value in True, False:

result = _CONSTRAINT_TRANSFORMERS['iommu.is_supported'](
_parse_iommu({"is-supported": value}), root_logger)

assert result.to_mrack() == {
'key_value': {
'_key': 'VIRT_IOMMU',
'_op': '==',
'_value': str(int(value))
}
}


def test_location_lab_controller(root_logger: Logger) -> None:

result = _CONSTRAINT_TRANSFORMERS['location.lab_controller'](
Expand Down
8 changes: 4 additions & 4 deletions tests/unit/test_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -1742,7 +1742,7 @@ def test_jira_link_test_only(self, mock_config_tree, mock_add_simple_link) -> No
logger=self.logger)
result = mock_add_simple_link.call_args.args[1]
assert 'https://tmt.testing-farm.io/?' in result['url']
assert 'test-url=https%3A%2F%2Fgithub.com%2Fteemtee%2Ftmt' in result['url']
assert 'test-url=https%3A%2F%2Fgithub.com%2F' in result['url']
assert '&test-name=%2Ftmp%2Ftest' in result['url']
assert '&test-path=%2Ftests%2Funit%2Ftmp' in result['url']

Expand All @@ -1760,15 +1760,15 @@ def test_jira_link_test_plan_story(self, mock_config_tree, mock_add_simple_link)
result = mock_add_simple_link.call_args.args[1]
assert 'https://tmt.testing-farm.io/?' in result['url']

assert 'test-url=https%3A%2F%2Fgithub.com%2Fteemtee%2Ftmt' in result['url']
assert 'test-url=https%3A%2F%2Fgithub.com%2F' in result['url']
assert '&test-name=%2Ftmp%2Ftest' in result['url']
assert '&test-path=%2Ftests%2Funit%2Ftmp' in result['url']

assert '&plan-url=https%3A%2F%2Fgithub.com%2Fteemtee%2Ftmt' in result['url']
assert '&plan-url=https%3A%2F%2Fgithub.com%2F' in result['url']
assert '&plan-name=%2Ftmp%2Fplan' in result['url']
assert '&plan-path=%2Ftests%2Funit%2Ftmp' in result['url']

assert '&story-url=https%3A%2F%2Fgithub.com%2Fteemtee%2Ftmt' in result['url']
assert '&story-url=https%3A%2F%2Fgithub.com%2F' in result['url']
assert '&story-name=%2Ftmp%2Fstory' in result['url']
assert '&story-path=%2Ftests%2Funit%2Ftmp' in result['url']

Expand Down
22 changes: 22 additions & 0 deletions tmt/hardware.py
Original file line number Diff line number Diff line change
Expand Up @@ -1333,6 +1333,25 @@ def _parse_zcrypt(spec: Spec) -> BaseConstraint:
return group


@ungroupify
def _parse_iommu(spec: Spec) -> BaseConstraint:
"""
Parse constraints related to the ``iommu`` HW requirement.
:param spec: raw constraint block specification.
:returns: block representation as :py:class:`BaseConstraint` or one of its subclasses.
"""

group = And()

group.constraints += _parse_flag_constraints(spec,
'iommu',
('is-supported',))
group.constraints += _parse_text_constraints(spec, 'iommu', ('model-name',))

return group


@ungroupify
def _parse_location(spec: Spec) -> BaseConstraint:
"""
Expand Down Expand Up @@ -1428,6 +1447,9 @@ def _parse_generic_spec(spec: Spec) -> BaseConstraint:
if 'zcrypt' in spec:
group.constraints += [_parse_zcrypt(spec['zcrypt'])]

if 'iommu' in spec:
group.constraints += [_parse_iommu(spec['iommu'])]

return group


Expand Down
17 changes: 17 additions & 0 deletions tmt/schemas/provision/hardware.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -355,6 +355,20 @@ definitions:
# empty `boot`.
minProperties: 1

# Hw requirements `iommu` block
iommu:
type: object

properties:
is-supported:
type: boolean

model-name:
type: string

additionalProperties: false
minProperties: 1

# HW requirements: basic block
block:
type: object
Expand Down Expand Up @@ -405,6 +419,9 @@ definitions:
virtualization:
"$ref": "#/definitions/virtualization"

iommu:
"$ref": "#/definitions/iommu"

additionalProperties: false

# enforce at least one property - we don't care which one, but we don't want
Expand Down
16 changes: 16 additions & 0 deletions tmt/steps/provision/mrack.py
Original file line number Diff line number Diff line change
Expand Up @@ -512,6 +512,21 @@ def _transform_zcrypt_mode(
children=[MrackHWKeyValue('ZCRYPT_MODE', beaker_operator, actual_value)])


def _transform_iommu_is_supported(
constraint: tmt.hardware.FlagConstraint,
logger: tmt.log.Logger) -> MrackBaseHWElement:

test = (constraint.operator, constraint.value)

if test in [(tmt.hardware.Operator.EQ, True), (tmt.hardware.Operator.NEQ, False)]:
return MrackHWKeyValue('VIRT_IOMMU', '==', '1')

if test in [(tmt.hardware.Operator.EQ, False), (tmt.hardware.Operator.NEQ, True)]:
return MrackHWKeyValue('VIRT_IOMMU', '==', '0')

return _transform_unsupported(constraint, logger)


def _transform_location_lab_controller(
constraint: tmt.hardware.TextConstraint,
logger: tmt.log.Logger) -> MrackBaseHWElement:
Expand Down Expand Up @@ -573,6 +588,7 @@ def _transform_system_numa_nodes(
'zcrypt.adapter': _transform_zcrypt_adapter, # type: ignore[dict-item]
'zcrypt.mode': _transform_zcrypt_mode, # type: ignore[dict-item]
'system.numa_nodes': _transform_system_numa_nodes, # type: ignore[dict-item]
'iommu.is_supported': _transform_iommu_is_supported, # type: ignore[dict-item]
}


Expand Down

0 comments on commit d7686b4

Please sign in to comment.