Hardware

As a tester I want to specify detailed hardware requirements for the guest on which the tests will be executed.

As part of the provision step it is possible to use the hardware key to specify additional requirements for the testing environment. This provides a generic and an extensible way to write down essential hardware requirements. For example one consistent way how to specify at least 2 GB of RAM for all supported provisioners.

Introduction

Individual requirements are provided as a simple key: value pairs, for example the minimum amount of memory, or the related information is grouped under a common parent, for example cores or model under the cpu key.

Comparison operators

The value part of the constraint follows the schema [operator] actual-value. The operator is optional, it may be any of the following: =, !=, >, >=, <, >=, ~ (regex match), and !~ (regex not matches). When operator is omitted, = is assumed.

Warning

Only =, !=, >, >=, < and <= operators are accepted for requirements that accept numeric values, e.g. cpu.cores or tpm.version.

Only = and != operators are accepted for flag-like requirements, e.g. virtualization.is-virtualized.

Only =, !, ~ and !~ operators are accepted for requirements that accept string values, e.g. cpu.model-name or virtualization.hypervisor.

Note

It is highly recommended to wrap values with single or double quotes, i.e. memory: '>= 8 GiB' rather than memory: >= 8 GiB. This should prevent any unexpected processing by parsers loading the fmf content. Without explicit quotes, some operators might lead to unexpected outcome.

# This...
memory: '8 GB'
# ... is the same as this:
memory: '= 8 GB'

# Optional operators at the start of the value
memory: '!= 8 GB'
memory: '> 8 GB'
memory: '>= 8 GB'
memory: '< 8 GB'
memory: '<= 8 GB'

Logic operators

When multiple environment requirements are provided the provision implementation should attempt to satisfy all of them. It is also possible to write this explicitly using the and operator containing a list of dictionaries with individual requirements. When the or operator is used, any of the alternatives provided in the list should be sufficient:

# By default exact value expected, these are equivalent:
cpu:
    model: 37
cpu:
    model: '= 37'

# Using advanced logic operators
and:
  - cpu:
        family: 15
  - or:
      - cpu:
            model: 65
      - cpu:
            model: 67
      - cpu:
            model: 69

Units

The pint library is used for processing various units, both decimal and binary prefixes can be used:

1 MB = 1 000 000 B
1 MiB = 1 048 576 B

Names and IDs

When looking for specific devices, it is often possible to request them either by their name or by some kind of ID. The specification follows a simple naming scheme when a property of a device can be expressed as a name as well as an ID:

  • keys with -name suffix represent human-comprehensible string names - model name, vendor name, microarchitecture code name, brand names, and so on. For example, Intel(R) Xeon(R) CPU E5-2670 v2 @ 2.50GHz would be a cpu.model-name requirement.

  • IDs are left without a suffix. IDs tend to be integers, or groups of integers. For example, 62 would be a cpu.model requirement.

Requirements given by a name can often make use of regular expression operators (~ and !~) while IDs can be used very reasonably with other comparison operators like >=.

Device and vendor IDs

Besides the names, provisioning infrastructures may support searching for devices by device and/or vendor ID. The ID namespace would be determined by the guest architecture, the buses and other specifications the guest HW is built from.

For example, probably the most common namespace would be the PCI ID Repository, collecting IDs and names of PCI devices, easy to encounter in both bare-metal and virtualized x86_64 guests. However, this ID database is not the only one in existence, and guest architecture may allow for additional device and vendor ID schemas.

Notes

The implementation for this common hardware key is in progress. Features under this section marked as implemented are already supported by the artemis plugin. Support in other provision plugins is on the way. Check individual plugin documentation for additional information on the hardware requirement support.

Note

Some plugins may require additional configuration. For example, Artemis can provision machines with disks of a particular size, but to do so, Artemis maintainers must configure disk sizes for various AWS / OpenStack / Azure flavors. The constraint is supported and implemented, but it will not deliver the required virtual machine when the plugin’s backend, the Artemis deployment, isn’t configured correctly.

Note

Some plugins may support requirements that are impossible to satisfy, e.g. the local plugin can support the cpu.family requirement, but it is hard-locked to the CPU of one’s own machine.

When facing impossible requirements, plugins will emit a warning reporting this situation to the user, but in general, plugins will try to continue provisioning the guest.

Examples:

# Use the artemis plugin to provision the latest Fedora on
# a guest with the x86_64 architecture and 8 GB of memory
provision:
    how: artemis
    image: fedora
    hardware:
        arch: x86_64
        memory: 8 GB

arch

Select or provision a guest with a given CPU architecture.

Note

This is a draft, the story is not implemented yet.

# String, any of well-known short architecture names.
arch: "aarch64"|"i386"|"ppc64"|"ppc64le"|"s390x"|"x86_64"|...

Warning

This field is not supported under hardware. It is planned to be supported in the future. Use the arch field of specific provision plugins to select the architecture. If this field is used in Testing Farm’s hardware requirements the request will abort.

Examples:

# Require a good old x86_64 box
arch: x86_64

Status: idea

boot

Select or provision a guest with requested boot properties.

boot:
  # String, a boot method the guest must boot with.
  method: "bios"|"uefi"

Examples:

# Require a guest with a UEFI boot method.
boot:
    method: uefi
# Require a guest without a legacy BIOS.
boot:
    method: "!= bios"

Status: implemented

compatible

Select or provision a guest compatible with given areas.

compatible:
  # List of strings, any of distro names.
  distro:
    - distro1
    - distro2
      ...

See the context dimension definitions for the list of supported values of the distro items.

Examples:

# Select a guest compatible with both rhel-8 and rhel-9
compatible:
    distro:
      - rhel-8
      - rhel-9

Status: implemented

cpu

Select or provision a guest with given CPU properties.

cpu:
    # Integer or string, number of CPU sockets in the system.
   sockets: 1|">= 1"

   # Integer or string, number of CPU cores in the system.
   cores: 4|">= 4"

   # Integer or string, number of CPU threads in the system.
   threads: 8|">= 8"

   # Integer or string, number of CPU cores per socket.
   cores-per-socket: 4|">= 4"

   # Integer or string, number of CPU threads per core.
   threads-per-core: 2|">= 2"

   # Integer or string, total number of logical CPUs.
   processors: 8|">= 8"

   # String, CPU family name.
   family-name: Comet Lake

   # Integer or string, CPU family.
   family: 6|">= 6"

   # String, CPU model name.
   model-name: Intel(R) Core(TM) i7-10610U CPU @ 1.80GHz

   # Integer or string, CPU model.
   model: 142|">= 142"

   # String, CPU vendor name.
   vendor-name: GenuineIntel

   # Number or string, an ID of CPU vendor.
   vendor: 1234|"> 1234"

   # Integer or string, CPU stepping.
   stepping: 10|">= 10"

   # List of strings, CPU flags as reported
   # Field applies an implicit "and" to listed flags, all items of the
   # list must match.
   # Items may contain a nested operator, "=" and "!=" are only two allowed.
   flag:
     - flag1
     - flag2
     - "= flag3"
     - "!= flag4"
       ...

See e.g. https://virtual-dba.com/blog/sockets-cores-and-threads/ for the socket, core and thread distinction.

See e.g. https://en.wikichip.org/wiki/WikiChip for information on family, model, stepping and corresponding names. /proc/cpuinfo and lscpu are also useful resources.

Changed in version 1.33: beaker plugin supports cpu.cores

Changed in version 1.31: beaker plugin supports cpu.flag

Changed in version 1.30: artemis plugin supports cpu.flag with Artemis 0.0.67

Changed in version 1.27: beaker plugin supports cpu.model and cpu.processors

Examples:

# Request a rather stronger guest.
cpu:
    processors: ">= 16"
# Request a CPU of a specific model set.
cpu:
    model-name: "~ Intel(R) Core(TM) i7-.+"
# Request a CPU with AVX support
cpu:
    flag:
      - avx
      - avx2
# Request a CPU with more than 4 cores.
cpu:
    cores: ">= 4"

Status: implemented

device

Select or provision a guest with a given device.

Note

This is a draft, the story is not implemented yet.

This is a generalization of various device-like requirements like gpu or network. It provides a generic way for requesting devices for which tmt defines no special HW requirements. The specialized requirements are recommended, as they express the desired guest properties in a more explicit way.

device:
    # String, a network device name.
    device-name: "A Generic Ethernet Card"

    # Number or string, a network device ID.
    device: 1234|"> 1234"

    # String, a name of the device vendor.
    vendor-name: "A Well-Known Device Manufacturer"

    # Number or string, an ID of the device vendor.
    vendor: 1234|"> 1234"

    # String, name of the kernel driver module for the device.
    driver: noveau

New in version 1.29.

Examples:

# Request a guest with a Thunderbolt controller
device:
    device-name: "~ Intel Corporation .* Thunderbolt 3"
    driver: thundebolt

Status: idea

disk

Select or provision a guest with a given disk storage.

# A list of dictionaries, each describing one disk storage.
disk:
    # Number or string, the amount of storage requested.
    # Bytes are assumed when no unit is specified.
  - size: 1234|">= 512 GiB"

    # String, disk model requested.
  - model-name: "well-known disk model"

    # String, disk driver requested.
  - driver: "well-known disk driver"

The Guest Topology Format may include the following fields in its description of the actual guest hardware:

# String, path to the block device representing this disk.
block-device: "/dev/vda"

Changed in version 1.32: Added driver and model-name into specification.

Changed in version 1.34: Added block-device into specification.

Examples:

# Require a disk big enough for testing
disk:
  - size: 500 GB
# Require a disk with specified model
disk:
  - model-name: 'PERC H310'
# Require a disk with specified driver
disk:
  - driver: mpt3sas
# Multiple disks can be requested as well
disk:
  - size: '>= 2 GB'
  - model-name: 'PERC H310'
  - driver: '~ sas.*'
# Guest topology exposing details about the actual disks
disk:
  - size: 21474836480
    model-name: PERC H310
    driver: megaraid_sas
    block-device: /dev/sda

  - size: 21474836480
    model-name: PERC H310
    driver: megaraid_sas
    block-device: /dev/sdb

Status: implemented

gpu

Select or provision a guest with a given GPU properties.

Note

This is a draft, the story is not implemented yet.

gpu:
    # String, a network device name.
    device-name: "A Generic Graphics Card"

    # Number or string, a network device ID.
    device: 1234|"> 1234"

    # String, a name of the device vendor.
    vendor-name: "A Well-Known GPU Manufacturer"

    # Number or string, an ID of the device vendor.
    vendor: 1234|"> 1234"

    # String, name of the kernel driver module for the device.
    driver: a_generic_vga_driver

New in version 1.29.

Examples:

# Request a guest with particular GPU
gpu:
    # By the device name...
    device-name: C51 [GeForce 6150 LE]
    # ... or by its ID.
    device: 0241
    driver: nouveau
# Request a guest with any NVIDIA GPU
gpu:
    vendor-name: NVIDIA

Status: idea

hostname

Select a guest with a specific hostname.

# String, the hostname requested.
hostname: foo.bar.com

Examples:

# Choose machine with given hostname
hostname: kvm-01.lab.us-east-2.company.com
# Hostname matching a regular expression
hostname: "~ kvm-01.*"
# Hostname not matching a regular expression
hostname: "!~ kvm-01.*"

Status: implemented

location

Select or provision a guest from a particular location.

Note

This is a draft, the story is not implemented yet.

location:
    # String, which labcontroller to use or to avoid.
    # Note: this field is consumed by Beaker and Artemis plugins only.
    lab-controller: "lab-01.foo.bar.com"

Changed in version 1.33: Added location.lab-controller into specification.

Examples:

# Select a system that is not managed by deprecated lab controllers
location:
    lab-controller: "!~ deprecated-lab-.*.foo.bar.com"

Status: idea

memory

Select or provision a guest with the desired amount of memory.

# Number or string, the amount of memory requested.
# Bytes are assumed when no unit is specified.
memory: 1234|"2 GiB"

Examples:

# Require an exact amount of memory
memory: 8 GB
# Pick a guest with at least 8 GB
memory: ">= 8 GB"

Status: implemented

network

Select or provision a guest with given network devices.

# A list of dictionaries, each describing one network device.
network:
    # String, a network device type.
  - type: "eth"|"bridge"|"ipip"|...

    # String, a network device name.
    device-name: "A Generic Ethernet Card"

    # Number or string, a network device ID.
    device: 1234|"> 1234"

    # String, a name of the device vendor.
    vendor-name: "A Well-Known Device Manufacturer"

    # Number or string, an ID of the device vendor.
    vendor: 1234|"> 1234"

    # String, name of the kernel driver module for the device.
    driver: a_generic_nic_driver

Changed in version 1.29: Added missing device and vendor into specification.

Examples:

# Select by vendor and device name
network:
  - type: eth
    vendor-name: ~ ^Broadcom
    device-name: ~ ^NetXtreme II BCM

Status: implemented

system

Select or provision a guest with given system properties.

Note

This is a draft, the story is not implemented yet.

system:
    # Number or string, an ID of the device vendor.
    vendor: 1234|"> 1234"

    # String, a name of the device vendor.
    vendor-name: "A Well-Known Device Manufacturer"

    # Integer or string, system model ID.
    model: 1234|"> 1234"

    # String, system model name.
    model-name: ProLiant DL385 Gen10

    # Integer or string, required number of NUMA nodes.
    numa-nodes: 2|">= 2"

Examples:

# Select any system by a given vendor
system:
    vendor-name: "~ HPE"
# Select any HPE system with enough NUMA nodes.
system:
    vendor-name: "~ HPE"
    numa-nodes: ">= 4"

Status: idea

tpm

Select or provision a guest with the Trusted Platform Module.

tpm:
    # String, TPM version requested.
    version: "x.y"

Changed in version 1.32: virtual plugin supports tpm.version

Examples:

# Require a presence of TPM of a specific version.
tpm:
    version: "2.0"

Status: implemented

virtualization

Select or provision a guest with requested virtualization properties.

Changed in version 1.33: beaker plugin supports virtualization.hypervisor

Changed in version 1.31: beaker plugin supports virtualization.is-virtualized

virtualization:
    # String, any of well-known hypervisor names.
    hypervisor: "hyperv"|"powerkvm"|"kvm"|"xen"|"nitro"|...

    # Boolean, whether the guest itself is virtualized or not.
    is-virtualized: true|false

    # Boolean, whether the guest supports hardware-assisted
    # virtualization.
    is-supported: true|false

Examples:

# Require a guest which supports virtualization
virtualization:
    is-supported: true
# Require a bare-metal guest
virtualization:
    is-virtualized: false
# Ask for a virtualized guest on top of a kvm hypervisor
virtualization:
    is-virtualized: true
    hypervisor: kvm

Status: implemented

zcrypt

Select or provision a guest with the System z cryptographic adapter.

zcrypt:
    # String, adapter requested.
    adapter: "x"
    # String, mode requested.
    mode: "y"

New in version 1.31.

Changed in version 1.32: beaker plugin supports zcrypt

Examples:

# Require a presence of CEX8C adapter in the CCA mode
zcrypt:
    adapter: "CEX8C"
    mode: "CCA"

Status: implemented