From b90812ecce6b267b1f20dfdb0a10ffae97dca6e1 Mon Sep 17 00:00:00 2001 From: Qubasa Date: Mon, 5 May 2025 22:16:02 +0200 Subject: [PATCH] clan-cli: add test_create in clan_lib test folder --- .gitignore | 1 + pkgs/clan-app/shell.nix | 2 + pkgs/clan-cli/clan_cli/conftest.py | 16 - pkgs/clan-cli/clan_cli/machines/list.py | 74 +- pkgs/clan-cli/clan_cli/tests/root.py | 8 + pkgs/clan-cli/clan_lib/tests/__init__.py | 0 .../clan_lib/tests/assets/facter.json | 3397 +++++++++++++++++ pkgs/clan-cli/clan_lib/tests/test_create.py | 274 ++ pkgs/clan-cli/conftest.py | 22 + pkgs/clan-cli/default.nix | 55 +- pkgs/clan-cli/pyproject.toml | 2 +- 11 files changed, 3788 insertions(+), 63 deletions(-) create mode 100644 pkgs/clan-cli/clan_lib/tests/__init__.py create mode 100644 pkgs/clan-cli/clan_lib/tests/assets/facter.json create mode 100644 pkgs/clan-cli/clan_lib/tests/test_create.py create mode 100644 pkgs/clan-cli/conftest.py diff --git a/.gitignore b/.gitignore index 447544275..7b7836706 100644 --- a/.gitignore +++ b/.gitignore @@ -14,6 +14,7 @@ example_clan nixos.qcow2 **/*.glade~ /docs/out +/pkgs/clan-cli/clan_cli/select **/.local.env # MacOS stuff diff --git a/pkgs/clan-app/shell.nix b/pkgs/clan-app/shell.nix index 2dc2a373a..fa5cc6cae 100644 --- a/pkgs/clan-app/shell.nix +++ b/pkgs/clan-app/shell.nix @@ -29,6 +29,8 @@ mkShell { export GIT_ROOT=$(git rev-parse --show-toplevel) export PKG_ROOT=$GIT_ROOT/pkgs/clan-app + export CLAN_CORE_PATH="$GIT_ROOT" + # Add current package to PYTHONPATH export PYTHONPATH="$PKG_ROOT''${PYTHONPATH:+:$PYTHONPATH:}" diff --git a/pkgs/clan-cli/clan_cli/conftest.py b/pkgs/clan-cli/clan_cli/conftest.py index dd1238802..790ea9e06 100644 --- a/pkgs/clan-cli/clan_cli/conftest.py +++ b/pkgs/clan-cli/clan_cli/conftest.py @@ -1,9 +1,3 @@ -import pytest - -from clan_cli.custom_logger import setup_logging - -# collect_ignore = ["./nixpkgs"] - pytest_plugins = [ "clan_cli.tests.temporary_dir", "clan_cli.tests.root", @@ -19,13 +13,3 @@ pytest_plugins = [ "clan_cli.tests.stdout", "clan_cli.tests.nix_config", ] - - -# Executed on pytest session start -def pytest_sessionstart(session: pytest.Session) -> None: - # This function will be called once at the beginning of the test session - print("Starting pytest session") - # You can access the session config, items, testsfailed, etc. - print(f"Session config: {session.config}") - - setup_logging(level="INFO") diff --git a/pkgs/clan-cli/clan_cli/machines/list.py b/pkgs/clan-cli/clan_cli/machines/list.py index eefa30512..b34cb3dde 100644 --- a/pkgs/clan-cli/clan_cli/machines/list.py +++ b/pkgs/clan-cli/clan_cli/machines/list.py @@ -2,6 +2,7 @@ import argparse import json import logging import re +import time from dataclasses import dataclass from pathlib import Path from typing import Literal @@ -11,38 +12,38 @@ from clan_lib.api.disk import MachineDiskMatter from clan_lib.api.modules import parse_frontmatter from clan_lib.api.serde import dataclass_to_dict -from clan_cli.cmd import RunOpts, run_no_stdout +from clan_cli.cmd import RunOpts, run from clan_cli.completions import add_dynamic_completer, complete_tags from clan_cli.dirs import specific_machine_dir -from clan_cli.errors import ClanCmdError, ClanError +from clan_cli.errors import ClanError from clan_cli.inventory import ( - Machine, load_inventory_eval, patch_inventory_with, ) +from clan_cli.inventory.classes import Machine as InventoryMachine from clan_cli.machines.hardware import HardwareConfig -from clan_cli.nix import nix_eval, nix_shell +from clan_cli.nix import nix_eval from clan_cli.tags import list_nixos_machines_by_tags log = logging.getLogger(__name__) @API.register -def set_machine(flake_url: Path, machine_name: str, machine: Machine) -> None: +def set_machine(flake_url: Path, machine_name: str, machine: InventoryMachine) -> None: patch_inventory_with( flake_url, f"machines.{machine_name}", dataclass_to_dict(machine) ) @API.register -def list_inventory_machines(flake_url: str | Path) -> dict[str, Machine]: +def list_inventory_machines(flake_url: str | Path) -> dict[str, InventoryMachine]: inventory = load_inventory_eval(flake_url) return inventory.get("machines", {}) @dataclass class MachineDetails: - machine: Machine + machine: InventoryMachine hw_config: HardwareConfig | None = None disk_schema: MachineDiskMatter | None = None @@ -92,7 +93,7 @@ def list_nixos_machines(flake_url: str | Path) -> list[str]: ] ) - proc = run_no_stdout(cmd) + proc = run(cmd) try: res = proc.stdout.strip() @@ -106,53 +107,36 @@ def list_nixos_machines(flake_url: str | Path) -> list[str]: @dataclass class ConnectionOptions: - keyfile: str | None = None timeout: int = 2 + retries: int = 10 + + +from clan_cli.machines.machines import Machine @API.register def check_machine_online( - flake_url: str | Path, machine_name: str, opts: ConnectionOptions | None + machine: Machine, opts: ConnectionOptions | None = None ) -> Literal["Online", "Offline"]: - machine = load_inventory_eval(flake_url).get("machines", {}).get(machine_name) - if not machine: - msg = f"Machine {machine_name} not found in inventory" - raise ClanError(msg) - - hostname = machine.get("deploy", {}).get("targetHost") - + hostname = machine.target_host_address if not hostname: - msg = f"Machine {machine_name} does not specify a targetHost" + msg = f"Machine {machine.name} does not specify a targetHost" raise ClanError(msg) - timeout = opts.timeout if opts and opts.timeout else 20 + timeout = opts.timeout if opts and opts.timeout else 2 - cmd = nix_shell( - ["util-linux", *(["openssh"] if hostname else [])], - [ - "ssh", - *(["-i", f"{opts.keyfile}"] if opts and opts.keyfile else []), - # Disable strict host key checking - "-o", - "StrictHostKeyChecking=accept-new", - # Disable known hosts file - "-o", - "UserKnownHostsFile=/dev/null", - "-o", - f"ConnectTimeout={timeout}", - f"{hostname}", - "true", - "&> /dev/null", - ], - ) - try: - proc = run_no_stdout(cmd, RunOpts(needs_user_terminal=True)) - if proc.returncode != 0: - return "Offline" - except ClanCmdError: - return "Offline" - else: - return "Online" + for _ in range(opts.retries if opts and opts.retries else 10): + with machine.target_host() as target: + res = target.run( + ["true"], + RunOpts(timeout=timeout, check=False, needs_user_terminal=True), + ) + + if res.returncode == 0: + return "Online" + time.sleep(timeout) + + return "Offline" def list_command(args: argparse.Namespace) -> None: diff --git a/pkgs/clan-cli/clan_cli/tests/root.py b/pkgs/clan-cli/clan_cli/tests/root.py index 8caada40f..4d32eff0a 100644 --- a/pkgs/clan-cli/clan_cli/tests/root.py +++ b/pkgs/clan-cli/clan_cli/tests/root.py @@ -27,6 +27,14 @@ def test_root() -> Path: return TEST_ROOT +@pytest.fixture(scope="session") +def test_lib_root() -> Path: + """ + Root directory of the clan-lib tests + """ + return PROJECT_ROOT.parent / "clan_lib" / "tests" + + @pytest.fixture(scope="session") def clan_core() -> Path: """ diff --git a/pkgs/clan-cli/clan_lib/tests/__init__.py b/pkgs/clan-cli/clan_lib/tests/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/pkgs/clan-cli/clan_lib/tests/assets/facter.json b/pkgs/clan-cli/clan_lib/tests/assets/facter.json new file mode 100644 index 000000000..02af5bf4a --- /dev/null +++ b/pkgs/clan-cli/clan_lib/tests/assets/facter.json @@ -0,0 +1,3397 @@ +{ + "version": 1, + "system": "x86_64-linux", + "virtualisation": "microsoft", + "hardware": { + "bios": { + "apm_info": { + "supported": false, + "enabled": false, + "version": 0, + "sub_version": 0, + "bios_flags": 0 + }, + "vbe_info": { + "version": 0, + "video_memory": 0 + }, + "pnp": false, + "pnp_id": 0, + "lba_support": false, + "low_memory_size": 0, + "smbios_version": 768 + }, + "bridge": [ + { + "index": 6, + "attached_to": 0, + "class_list": ["pci", "bridge"], + "bus_type": { + "hex": "0004", + "name": "PCI", + "value": 4 + }, + "slot": { + "bus": 0, + "number": 3 + }, + "base_class": { + "hex": "0006", + "name": "Bridge", + "value": 6 + }, + "sub_class": { + "hex": "0004", + "name": "PCI bridge", + "value": 4 + }, + "pci_interface": { + "hex": "0000", + "name": "Normal decode", + "value": 0 + }, + "vendor": { + "hex": "1b36", + "value": 6966 + }, + "sub_vendor": { + "hex": "1b36", + "value": 6966 + }, + "device": { + "hex": "000c", + "value": 12 + }, + "sub_device": { + "hex": "0000", + "value": 0 + }, + "model": "PCI bridge", + "sysfs_id": "/devices/pci0000:00/0000:00:03.1", + "sysfs_bus_id": "0000:00:03.1", + "resources": [ + { + "type": "irq", + "base": 23, + "triggered": 0, + "enabled": true + }, + { + "type": "mem", + "base": 2204225536, + "range": 4096, + "enabled": true, + "access": "read_write", + "prefetch": "no" + } + ], + "detail": { + "function": 1, + "command": 1031, + "header_type": 1, + "secondary_bus": 11, + "irq": 23, + "prog_if": 0 + }, + "driver": "pcieport", + "drivers": ["pcieport"], + "module_alias": "pci:v00001B36d0000000Csv00001B36sd00000000bc06sc04i00" + }, + { + "index": 8, + "attached_to": 0, + "class_list": ["pci", "bridge"], + "bus_type": { + "hex": "0004", + "name": "PCI", + "value": 4 + }, + "slot": { + "bus": 0, + "number": 2 + }, + "base_class": { + "hex": "0006", + "name": "Bridge", + "value": 6 + }, + "sub_class": { + "hex": "0004", + "name": "PCI bridge", + "value": 4 + }, + "pci_interface": { + "hex": "0000", + "name": "Normal decode", + "value": 0 + }, + "vendor": { + "hex": "1b36", + "value": 6966 + }, + "sub_vendor": { + "hex": "1b36", + "value": 6966 + }, + "device": { + "hex": "000c", + "value": 12 + }, + "sub_device": { + "hex": "0000", + "value": 0 + }, + "model": "PCI bridge", + "sysfs_id": "/devices/pci0000:00/0000:00:02.7", + "sysfs_bus_id": "0000:00:02.7", + "resources": [ + { + "type": "irq", + "base": 22, + "triggered": 0, + "enabled": true + }, + { + "type": "mem", + "base": 2204233728, + "range": 4096, + "enabled": true, + "access": "read_write", + "prefetch": "no" + } + ], + "detail": { + "function": 7, + "command": 1031, + "header_type": 1, + "secondary_bus": 9, + "irq": 22, + "prog_if": 0 + }, + "driver": "pcieport", + "drivers": ["pcieport"], + "module_alias": "pci:v00001B36d0000000Csv00001B36sd00000000bc06sc04i00" + }, + { + "index": 9, + "attached_to": 0, + "class_list": ["pci", "bridge"], + "bus_type": { + "hex": "0004", + "name": "PCI", + "value": 4 + }, + "slot": { + "bus": 0, + "number": 31 + }, + "base_class": { + "hex": "0006", + "name": "Bridge", + "value": 6 + }, + "sub_class": { + "hex": "0001", + "name": "ISA bridge", + "value": 1 + }, + "vendor": { + "hex": "8086", + "name": "Intel Corporation", + "value": 32902 + }, + "sub_vendor": { + "hex": "1af4", + "value": 6900 + }, + "device": { + "hex": "2918", + "value": 10520 + }, + "sub_device": { + "hex": "1100", + "value": 4352 + }, + "revision": { + "hex": "0002", + "value": 2 + }, + "model": "Intel ISA bridge", + "sysfs_id": "/devices/pci0000:00/0000:00:1f.0", + "sysfs_bus_id": "0000:00:1f.0", + "detail": { + "function": 0, + "command": 7, + "header_type": 0, + "secondary_bus": 0, + "irq": 0, + "prog_if": 0 + }, + "driver": "lpc_ich", + "driver_module": "lpc_ich", + "drivers": ["lpc_ich"], + "driver_modules": ["lpc_ich"], + "module_alias": "pci:v00008086d00002918sv00001AF4sd00001100bc06sc01i00" + }, + { + "index": 10, + "attached_to": 0, + "class_list": ["pci", "bridge"], + "bus_type": { + "hex": "0004", + "name": "PCI", + "value": 4 + }, + "slot": { + "bus": 0, + "number": 2 + }, + "base_class": { + "hex": "0006", + "name": "Bridge", + "value": 6 + }, + "sub_class": { + "hex": "0004", + "name": "PCI bridge", + "value": 4 + }, + "pci_interface": { + "hex": "0000", + "name": "Normal decode", + "value": 0 + }, + "vendor": { + "hex": "1b36", + "value": 6966 + }, + "sub_vendor": { + "hex": "1b36", + "value": 6966 + }, + "device": { + "hex": "000c", + "value": 12 + }, + "sub_device": { + "hex": "0000", + "value": 0 + }, + "model": "PCI bridge", + "sysfs_id": "/devices/pci0000:00/0000:00:02.5", + "sysfs_bus_id": "0000:00:02.5", + "resources": [ + { + "type": "irq", + "base": 22, + "triggered": 0, + "enabled": true + }, + { + "type": "mem", + "base": 2204241920, + "range": 4096, + "enabled": true, + "access": "read_write", + "prefetch": "no" + } + ], + "detail": { + "function": 5, + "command": 1031, + "header_type": 1, + "secondary_bus": 7, + "irq": 22, + "prog_if": 0 + }, + "driver": "pcieport", + "drivers": ["pcieport"], + "module_alias": "pci:v00001B36d0000000Csv00001B36sd00000000bc06sc04i00" + }, + { + "index": 11, + "attached_to": 17, + "class_list": ["pci", "bridge"], + "bus_type": { + "hex": "0004", + "name": "PCI", + "value": 4 + }, + "slot": { + "bus": 2, + "number": 0 + }, + "base_class": { + "hex": "0006", + "name": "Bridge", + "value": 6 + }, + "sub_class": { + "hex": "0004", + "name": "PCI bridge", + "value": 4 + }, + "pci_interface": { + "hex": "0000", + "name": "Normal decode", + "value": 0 + }, + "vendor": { + "hex": "1b36", + "value": 6966 + }, + "device": { + "hex": "000e", + "value": 14 + }, + "model": "PCI bridge", + "sysfs_id": "/devices/pci0000:00/0000:00:02.1/0000:02:00.0", + "sysfs_bus_id": "0000:02:00.0", + "resources": [ + { + "type": "irq", + "base": 22, + "triggered": 0, + "enabled": true + }, + { + "type": "mem", + "base": 2199912448, + "range": 256, + "enabled": true, + "access": "read_write", + "prefetch": "no" + } + ], + "detail": { + "function": 0, + "command": 7, + "header_type": 1, + "secondary_bus": 3, + "irq": 22, + "prog_if": 0 + }, + "module_alias": "pci:v00001B36d0000000Esv00000000sd00000000bc06sc04i00" + }, + { + "index": 13, + "attached_to": 0, + "class_list": ["pci", "bridge"], + "bus_type": { + "hex": "0004", + "name": "PCI", + "value": 4 + }, + "slot": { + "bus": 0, + "number": 2 + }, + "base_class": { + "hex": "0006", + "name": "Bridge", + "value": 6 + }, + "sub_class": { + "hex": "0004", + "name": "PCI bridge", + "value": 4 + }, + "pci_interface": { + "hex": "0000", + "name": "Normal decode", + "value": 0 + }, + "vendor": { + "hex": "1b36", + "value": 6966 + }, + "sub_vendor": { + "hex": "1b36", + "value": 6966 + }, + "device": { + "hex": "000c", + "value": 12 + }, + "sub_device": { + "hex": "0000", + "value": 0 + }, + "model": "PCI bridge", + "sysfs_id": "/devices/pci0000:00/0000:00:02.3", + "sysfs_bus_id": "0000:00:02.3", + "resources": [ + { + "type": "irq", + "base": 22, + "triggered": 0, + "enabled": true + }, + { + "type": "mem", + "base": 2204250112, + "range": 4096, + "enabled": true, + "access": "read_write", + "prefetch": "no" + } + ], + "detail": { + "function": 3, + "command": 1031, + "header_type": 1, + "secondary_bus": 5, + "irq": 22, + "prog_if": 0 + }, + "driver": "pcieport", + "drivers": ["pcieport"], + "module_alias": "pci:v00001B36d0000000Csv00001B36sd00000000bc06sc04i00" + }, + { + "index": 14, + "attached_to": 0, + "class_list": ["pci", "bridge"], + "bus_type": { + "hex": "0004", + "name": "PCI", + "value": 4 + }, + "slot": { + "bus": 0, + "number": 4 + }, + "base_class": { + "hex": "0006", + "name": "Bridge", + "value": 6 + }, + "sub_class": { + "hex": "0004", + "name": "PCI bridge", + "value": 4 + }, + "pci_interface": { + "hex": "0000", + "name": "Normal decode", + "value": 0 + }, + "vendor": { + "hex": "1b36", + "value": 6966 + }, + "sub_vendor": { + "hex": "1b36", + "value": 6966 + }, + "device": { + "hex": "000c", + "value": 12 + }, + "sub_device": { + "hex": "0000", + "value": 0 + }, + "model": "PCI bridge", + "sysfs_id": "/devices/pci0000:00/0000:00:04.0", + "sysfs_bus_id": "0000:00:04.0", + "resources": [ + { + "type": "irq", + "base": 20, + "triggered": 0, + "enabled": true + }, + { + "type": "mem", + "base": 2204196864, + "range": 4096, + "enabled": true, + "access": "read_write", + "prefetch": "no" + } + ], + "detail": { + "function": 0, + "command": 1031, + "header_type": 1, + "secondary_bus": 18, + "irq": 20, + "prog_if": 0 + }, + "driver": "pcieport", + "drivers": ["pcieport"], + "module_alias": "pci:v00001B36d0000000Csv00001B36sd00000000bc06sc04i00" + }, + { + "index": 15, + "attached_to": 0, + "class_list": ["pci", "bridge"], + "bus_type": { + "hex": "0004", + "name": "PCI", + "value": 4 + }, + "slot": { + "bus": 0, + "number": 3 + }, + "base_class": { + "hex": "0006", + "name": "Bridge", + "value": 6 + }, + "sub_class": { + "hex": "0004", + "name": "PCI bridge", + "value": 4 + }, + "pci_interface": { + "hex": "0000", + "name": "Normal decode", + "value": 0 + }, + "vendor": { + "hex": "1b36", + "value": 6966 + }, + "sub_vendor": { + "hex": "1b36", + "value": 6966 + }, + "device": { + "hex": "000c", + "value": 12 + }, + "sub_device": { + "hex": "0000", + "value": 0 + }, + "model": "PCI bridge", + "sysfs_id": "/devices/pci0000:00/0000:00:03.6", + "sysfs_bus_id": "0000:00:03.6", + "resources": [ + { + "type": "irq", + "base": 23, + "triggered": 0, + "enabled": true + }, + { + "type": "mem", + "base": 2204205056, + "range": 4096, + "enabled": true, + "access": "read_write", + "prefetch": "no" + } + ], + "detail": { + "function": 6, + "command": 1031, + "header_type": 1, + "secondary_bus": 16, + "irq": 23, + "prog_if": 0 + }, + "driver": "pcieport", + "drivers": ["pcieport"], + "module_alias": "pci:v00001B36d0000000Csv00001B36sd00000000bc06sc04i00" + }, + { + "index": 17, + "attached_to": 0, + "class_list": ["pci", "bridge"], + "bus_type": { + "hex": "0004", + "name": "PCI", + "value": 4 + }, + "slot": { + "bus": 0, + "number": 2 + }, + "base_class": { + "hex": "0006", + "name": "Bridge", + "value": 6 + }, + "sub_class": { + "hex": "0004", + "name": "PCI bridge", + "value": 4 + }, + "pci_interface": { + "hex": "0000", + "name": "Normal decode", + "value": 0 + }, + "vendor": { + "hex": "1b36", + "value": 6966 + }, + "sub_vendor": { + "hex": "1b36", + "value": 6966 + }, + "device": { + "hex": "000c", + "value": 12 + }, + "sub_device": { + "hex": "0000", + "value": 0 + }, + "model": "PCI bridge", + "sysfs_id": "/devices/pci0000:00/0000:00:02.1", + "sysfs_bus_id": "0000:00:02.1", + "resources": [ + { + "type": "irq", + "base": 22, + "triggered": 0, + "enabled": true + }, + { + "type": "mem", + "base": 2204258304, + "range": 4096, + "enabled": true, + "access": "read_write", + "prefetch": "no" + } + ], + "detail": { + "function": 1, + "command": 1031, + "header_type": 1, + "secondary_bus": 2, + "irq": 22, + "prog_if": 0 + }, + "driver": "pcieport", + "drivers": ["pcieport"], + "module_alias": "pci:v00001B36d0000000Csv00001B36sd00000000bc06sc04i00" + }, + { + "index": 19, + "attached_to": 0, + "class_list": ["pci", "bridge"], + "bus_type": { + "hex": "0004", + "name": "PCI", + "value": 4 + }, + "slot": { + "bus": 0, + "number": 3 + }, + "base_class": { + "hex": "0006", + "name": "Bridge", + "value": 6 + }, + "sub_class": { + "hex": "0004", + "name": "PCI bridge", + "value": 4 + }, + "pci_interface": { + "hex": "0000", + "name": "Normal decode", + "value": 0 + }, + "vendor": { + "hex": "1b36", + "value": 6966 + }, + "sub_vendor": { + "hex": "1b36", + "value": 6966 + }, + "device": { + "hex": "000c", + "value": 12 + }, + "sub_device": { + "hex": "0000", + "value": 0 + }, + "model": "PCI bridge", + "sysfs_id": "/devices/pci0000:00/0000:00:03.4", + "sysfs_bus_id": "0000:00:03.4", + "resources": [ + { + "type": "irq", + "base": 23, + "triggered": 0, + "enabled": true + }, + { + "type": "mem", + "base": 2204213248, + "range": 4096, + "enabled": true, + "access": "read_write", + "prefetch": "no" + } + ], + "detail": { + "function": 4, + "command": 1031, + "header_type": 1, + "secondary_bus": 14, + "irq": 23, + "prog_if": 0 + }, + "driver": "pcieport", + "drivers": ["pcieport"], + "module_alias": "pci:v00001B36d0000000Csv00001B36sd00000000bc06sc04i00" + }, + { + "index": 21, + "attached_to": 0, + "class_list": ["pci", "bridge"], + "bus_type": { + "hex": "0004", + "name": "PCI", + "value": 4 + }, + "slot": { + "bus": 0, + "number": 3 + }, + "base_class": { + "hex": "0006", + "name": "Bridge", + "value": 6 + }, + "sub_class": { + "hex": "0004", + "name": "PCI bridge", + "value": 4 + }, + "pci_interface": { + "hex": "0000", + "name": "Normal decode", + "value": 0 + }, + "vendor": { + "hex": "1b36", + "value": 6966 + }, + "sub_vendor": { + "hex": "1b36", + "value": 6966 + }, + "device": { + "hex": "000c", + "value": 12 + }, + "sub_device": { + "hex": "0000", + "value": 0 + }, + "model": "PCI bridge", + "sysfs_id": "/devices/pci0000:00/0000:00:03.2", + "sysfs_bus_id": "0000:00:03.2", + "resources": [ + { + "type": "irq", + "base": 23, + "triggered": 0, + "enabled": true + }, + { + "type": "mem", + "base": 2204221440, + "range": 4096, + "enabled": true, + "access": "read_write", + "prefetch": "no" + } + ], + "detail": { + "function": 2, + "command": 1031, + "header_type": 1, + "secondary_bus": 12, + "irq": 23, + "prog_if": 0 + }, + "driver": "pcieport", + "drivers": ["pcieport"], + "module_alias": "pci:v00001B36d0000000Csv00001B36sd00000000bc06sc04i00" + }, + { + "index": 23, + "attached_to": 0, + "class_list": ["pci", "bridge"], + "bus_type": { + "hex": "0004", + "name": "PCI", + "value": 4 + }, + "slot": { + "bus": 0, + "number": 0 + }, + "base_class": { + "hex": "0006", + "name": "Bridge", + "value": 6 + }, + "sub_class": { + "hex": "0000", + "name": "Host bridge", + "value": 0 + }, + "vendor": { + "hex": "8086", + "name": "Intel Corporation", + "value": 32902 + }, + "sub_vendor": { + "hex": "1af4", + "value": 6900 + }, + "device": { + "hex": "29c0", + "value": 10688 + }, + "sub_device": { + "hex": "1100", + "value": 4352 + }, + "model": "Intel Host bridge", + "sysfs_id": "/devices/pci0000:00/0000:00:00.0", + "sysfs_bus_id": "0000:00:00.0", + "detail": { + "function": 0, + "command": 7, + "header_type": 0, + "secondary_bus": 0, + "irq": 0, + "prog_if": 0 + }, + "module_alias": "pci:v00008086d000029C0sv00001AF4sd00001100bc06sc00i00" + }, + { + "index": 25, + "attached_to": 0, + "class_list": ["pci", "bridge"], + "bus_type": { + "hex": "0004", + "name": "PCI", + "value": 4 + }, + "slot": { + "bus": 0, + "number": 3 + }, + "base_class": { + "hex": "0006", + "name": "Bridge", + "value": 6 + }, + "sub_class": { + "hex": "0004", + "name": "PCI bridge", + "value": 4 + }, + "pci_interface": { + "hex": "0000", + "name": "Normal decode", + "value": 0 + }, + "vendor": { + "hex": "1b36", + "value": 6966 + }, + "sub_vendor": { + "hex": "1b36", + "value": 6966 + }, + "device": { + "hex": "000c", + "value": 12 + }, + "sub_device": { + "hex": "0000", + "value": 0 + }, + "model": "PCI bridge", + "sysfs_id": "/devices/pci0000:00/0000:00:03.0", + "sysfs_bus_id": "0000:00:03.0", + "resources": [ + { + "type": "irq", + "base": 23, + "triggered": 0, + "enabled": true + }, + { + "type": "mem", + "base": 2204229632, + "range": 4096, + "enabled": true, + "access": "read_write", + "prefetch": "no" + } + ], + "detail": { + "function": 0, + "command": 1031, + "header_type": 1, + "secondary_bus": 10, + "irq": 23, + "prog_if": 0 + }, + "driver": "pcieport", + "drivers": ["pcieport"], + "module_alias": "pci:v00001B36d0000000Csv00001B36sd00000000bc06sc04i00" + }, + { + "index": 26, + "attached_to": 0, + "class_list": ["pci", "bridge"], + "bus_type": { + "hex": "0004", + "name": "PCI", + "value": 4 + }, + "slot": { + "bus": 0, + "number": 2 + }, + "base_class": { + "hex": "0006", + "name": "Bridge", + "value": 6 + }, + "sub_class": { + "hex": "0004", + "name": "PCI bridge", + "value": 4 + }, + "pci_interface": { + "hex": "0000", + "name": "Normal decode", + "value": 0 + }, + "vendor": { + "hex": "1b36", + "value": 6966 + }, + "sub_vendor": { + "hex": "1b36", + "value": 6966 + }, + "device": { + "hex": "000c", + "value": 12 + }, + "sub_device": { + "hex": "0000", + "value": 0 + }, + "model": "PCI bridge", + "sysfs_id": "/devices/pci0000:00/0000:00:02.6", + "sysfs_bus_id": "0000:00:02.6", + "resources": [ + { + "type": "irq", + "base": 22, + "triggered": 0, + "enabled": true + }, + { + "type": "mem", + "base": 2204237824, + "range": 4096, + "enabled": true, + "access": "read_write", + "prefetch": "no" + } + ], + "detail": { + "function": 6, + "command": 1031, + "header_type": 1, + "secondary_bus": 8, + "irq": 22, + "prog_if": 0 + }, + "driver": "pcieport", + "drivers": ["pcieport"], + "module_alias": "pci:v00001B36d0000000Csv00001B36sd00000000bc06sc04i00" + }, + { + "index": 27, + "attached_to": 0, + "class_list": ["pci", "bridge"], + "bus_type": { + "hex": "0004", + "name": "PCI", + "value": 4 + }, + "slot": { + "bus": 0, + "number": 2 + }, + "base_class": { + "hex": "0006", + "name": "Bridge", + "value": 6 + }, + "sub_class": { + "hex": "0004", + "name": "PCI bridge", + "value": 4 + }, + "pci_interface": { + "hex": "0000", + "name": "Normal decode", + "value": 0 + }, + "vendor": { + "hex": "1b36", + "value": 6966 + }, + "sub_vendor": { + "hex": "1b36", + "value": 6966 + }, + "device": { + "hex": "000c", + "value": 12 + }, + "sub_device": { + "hex": "0000", + "value": 0 + }, + "model": "PCI bridge", + "sysfs_id": "/devices/pci0000:00/0000:00:02.4", + "sysfs_bus_id": "0000:00:02.4", + "resources": [ + { + "type": "irq", + "base": 22, + "triggered": 0, + "enabled": true + }, + { + "type": "mem", + "base": 2204246016, + "range": 4096, + "enabled": true, + "access": "read_write", + "prefetch": "no" + } + ], + "detail": { + "function": 4, + "command": 1031, + "header_type": 1, + "secondary_bus": 6, + "irq": 22, + "prog_if": 0 + }, + "driver": "pcieport", + "drivers": ["pcieport"], + "module_alias": "pci:v00001B36d0000000Csv00001B36sd00000000bc06sc04i00" + }, + { + "index": 30, + "attached_to": 0, + "class_list": ["pci", "bridge"], + "bus_type": { + "hex": "0004", + "name": "PCI", + "value": 4 + }, + "slot": { + "bus": 0, + "number": 4 + }, + "base_class": { + "hex": "0006", + "name": "Bridge", + "value": 6 + }, + "sub_class": { + "hex": "0004", + "name": "PCI bridge", + "value": 4 + }, + "pci_interface": { + "hex": "0000", + "name": "Normal decode", + "value": 0 + }, + "vendor": { + "hex": "1b36", + "value": 6966 + }, + "sub_vendor": { + "hex": "1b36", + "value": 6966 + }, + "device": { + "hex": "000c", + "value": 12 + }, + "sub_device": { + "hex": "0000", + "value": 0 + }, + "model": "PCI bridge", + "sysfs_id": "/devices/pci0000:00/0000:00:04.1", + "sysfs_bus_id": "0000:00:04.1", + "resources": [ + { + "type": "irq", + "base": 20, + "triggered": 0, + "enabled": true + }, + { + "type": "mem", + "base": 2204192768, + "range": 4096, + "enabled": true, + "access": "read_write", + "prefetch": "no" + } + ], + "detail": { + "function": 1, + "command": 1031, + "header_type": 1, + "secondary_bus": 19, + "irq": 20, + "prog_if": 0 + }, + "driver": "pcieport", + "drivers": ["pcieport"], + "module_alias": "pci:v00001B36d0000000Csv00001B36sd00000000bc06sc04i00" + }, + { + "index": 31, + "attached_to": 0, + "class_list": ["pci", "bridge"], + "bus_type": { + "hex": "0004", + "name": "PCI", + "value": 4 + }, + "slot": { + "bus": 0, + "number": 3 + }, + "base_class": { + "hex": "0006", + "name": "Bridge", + "value": 6 + }, + "sub_class": { + "hex": "0004", + "name": "PCI bridge", + "value": 4 + }, + "pci_interface": { + "hex": "0000", + "name": "Normal decode", + "value": 0 + }, + "vendor": { + "hex": "1b36", + "value": 6966 + }, + "sub_vendor": { + "hex": "1b36", + "value": 6966 + }, + "device": { + "hex": "000c", + "value": 12 + }, + "sub_device": { + "hex": "0000", + "value": 0 + }, + "model": "PCI bridge", + "sysfs_id": "/devices/pci0000:00/0000:00:03.7", + "sysfs_bus_id": "0000:00:03.7", + "resources": [ + { + "type": "irq", + "base": 23, + "triggered": 0, + "enabled": true + }, + { + "type": "mem", + "base": 2204200960, + "range": 4096, + "enabled": true, + "access": "read_write", + "prefetch": "no" + } + ], + "detail": { + "function": 7, + "command": 1031, + "header_type": 1, + "secondary_bus": 17, + "irq": 23, + "prog_if": 0 + }, + "driver": "pcieport", + "drivers": ["pcieport"], + "module_alias": "pci:v00001B36d0000000Csv00001B36sd00000000bc06sc04i00" + }, + { + "index": 32, + "attached_to": 0, + "class_list": ["pci", "bridge"], + "bus_type": { + "hex": "0004", + "name": "PCI", + "value": 4 + }, + "slot": { + "bus": 0, + "number": 2 + }, + "base_class": { + "hex": "0006", + "name": "Bridge", + "value": 6 + }, + "sub_class": { + "hex": "0004", + "name": "PCI bridge", + "value": 4 + }, + "pci_interface": { + "hex": "0000", + "name": "Normal decode", + "value": 0 + }, + "vendor": { + "hex": "1b36", + "value": 6966 + }, + "sub_vendor": { + "hex": "1b36", + "value": 6966 + }, + "device": { + "hex": "000c", + "value": 12 + }, + "sub_device": { + "hex": "0000", + "value": 0 + }, + "model": "PCI bridge", + "sysfs_id": "/devices/pci0000:00/0000:00:02.2", + "sysfs_bus_id": "0000:00:02.2", + "resources": [ + { + "type": "irq", + "base": 22, + "triggered": 0, + "enabled": true + }, + { + "type": "mem", + "base": 2204254208, + "range": 4096, + "enabled": true, + "access": "read_write", + "prefetch": "no" + } + ], + "detail": { + "function": 2, + "command": 1031, + "header_type": 1, + "secondary_bus": 4, + "irq": 22, + "prog_if": 0 + }, + "driver": "pcieport", + "drivers": ["pcieport"], + "module_alias": "pci:v00001B36d0000000Csv00001B36sd00000000bc06sc04i00" + }, + { + "index": 33, + "attached_to": 0, + "class_list": ["pci", "bridge"], + "bus_type": { + "hex": "0004", + "name": "PCI", + "value": 4 + }, + "slot": { + "bus": 0, + "number": 3 + }, + "base_class": { + "hex": "0006", + "name": "Bridge", + "value": 6 + }, + "sub_class": { + "hex": "0004", + "name": "PCI bridge", + "value": 4 + }, + "pci_interface": { + "hex": "0000", + "name": "Normal decode", + "value": 0 + }, + "vendor": { + "hex": "1b36", + "value": 6966 + }, + "sub_vendor": { + "hex": "1b36", + "value": 6966 + }, + "device": { + "hex": "000c", + "value": 12 + }, + "sub_device": { + "hex": "0000", + "value": 0 + }, + "model": "PCI bridge", + "sysfs_id": "/devices/pci0000:00/0000:00:03.5", + "sysfs_bus_id": "0000:00:03.5", + "resources": [ + { + "type": "irq", + "base": 23, + "triggered": 0, + "enabled": true + }, + { + "type": "mem", + "base": 2204209152, + "range": 4096, + "enabled": true, + "access": "read_write", + "prefetch": "no" + } + ], + "detail": { + "function": 5, + "command": 1031, + "header_type": 1, + "secondary_bus": 15, + "irq": 23, + "prog_if": 0 + }, + "driver": "pcieport", + "drivers": ["pcieport"], + "module_alias": "pci:v00001B36d0000000Csv00001B36sd00000000bc06sc04i00" + }, + { + "index": 35, + "attached_to": 0, + "class_list": ["pci", "bridge"], + "bus_type": { + "hex": "0004", + "name": "PCI", + "value": 4 + }, + "slot": { + "bus": 0, + "number": 2 + }, + "base_class": { + "hex": "0006", + "name": "Bridge", + "value": 6 + }, + "sub_class": { + "hex": "0004", + "name": "PCI bridge", + "value": 4 + }, + "pci_interface": { + "hex": "0000", + "name": "Normal decode", + "value": 0 + }, + "vendor": { + "hex": "1b36", + "value": 6966 + }, + "sub_vendor": { + "hex": "1b36", + "value": 6966 + }, + "device": { + "hex": "000c", + "value": 12 + }, + "sub_device": { + "hex": "0000", + "value": 0 + }, + "model": "PCI bridge", + "sysfs_id": "/devices/pci0000:00/0000:00:02.0", + "sysfs_bus_id": "0000:00:02.0", + "resources": [ + { + "type": "irq", + "base": 22, + "triggered": 0, + "enabled": true + }, + { + "type": "mem", + "base": 2204262400, + "range": 4096, + "enabled": true, + "access": "read_write", + "prefetch": "no" + } + ], + "detail": { + "function": 0, + "command": 1031, + "header_type": 1, + "secondary_bus": 1, + "irq": 22, + "prog_if": 0 + }, + "driver": "pcieport", + "drivers": ["pcieport"], + "module_alias": "pci:v00001B36d0000000Csv00001B36sd00000000bc06sc04i00" + }, + { + "index": 36, + "attached_to": 0, + "class_list": ["pci", "bridge"], + "bus_type": { + "hex": "0004", + "name": "PCI", + "value": 4 + }, + "slot": { + "bus": 0, + "number": 3 + }, + "base_class": { + "hex": "0006", + "name": "Bridge", + "value": 6 + }, + "sub_class": { + "hex": "0004", + "name": "PCI bridge", + "value": 4 + }, + "pci_interface": { + "hex": "0000", + "name": "Normal decode", + "value": 0 + }, + "vendor": { + "hex": "1b36", + "value": 6966 + }, + "sub_vendor": { + "hex": "1b36", + "value": 6966 + }, + "device": { + "hex": "000c", + "value": 12 + }, + "sub_device": { + "hex": "0000", + "value": 0 + }, + "model": "PCI bridge", + "sysfs_id": "/devices/pci0000:00/0000:00:03.3", + "sysfs_bus_id": "0000:00:03.3", + "resources": [ + { + "type": "irq", + "base": 23, + "triggered": 0, + "enabled": true + }, + { + "type": "mem", + "base": 2204217344, + "range": 4096, + "enabled": true, + "access": "read_write", + "prefetch": "no" + } + ], + "detail": { + "function": 3, + "command": 1031, + "header_type": 1, + "secondary_bus": 13, + "irq": 23, + "prog_if": 0 + }, + "driver": "pcieport", + "drivers": ["pcieport"], + "module_alias": "pci:v00001B36d0000000Csv00001B36sd00000000bc06sc04i00" + } + ], + "cdrom": [ + { + "index": 42, + "attached_to": 7, + "class_list": ["cdrom", "scsi", "block_device"], + "bus_type": { + "hex": "0084", + "name": "SCSI", + "value": 132 + }, + "slot": { + "bus": 2, + "number": 0 + }, + "base_class": { + "hex": "0106", + "name": "Mass Storage Device", + "value": 262 + }, + "sub_class": { + "hex": "0002", + "name": "CD-ROM", + "value": 2 + }, + "pci_interface": { + "hex": "0003", + "name": "DVD", + "value": 3 + }, + "vendor": { + "hex": "0000", + "name": "QEMU", + "value": 0 + }, + "device": { + "hex": "0000", + "name": "QEMU DVD-ROM", + "value": 0 + }, + "revision": { + "hex": "0000", + "name": "2.5+", + "value": 0 + }, + "model": "QEMU DVD-ROM", + "sysfs_id": "/class/block/sr0", + "sysfs_bus_id": "2:0:0:0", + "sysfs_device_link": "/devices/pci0000:00/0000:00:1f.2/ata3/host2/target2:0:0/2:0:0:0", + "unix_device_name": "/dev/sr0", + "unix_device_number": { + "type": 98, + "major": 11, + "minor": 0, + "range": 1 + }, + "unix_device_names": [ + "/dev/cdrom", + "/dev/disk/by-diskseq/11", + "/dev/disk/by-id/ata-QEMU_DVD-ROM_QM00005", + "/dev/disk/by-path/pci-0000:00:1f.2-ata-3", + "/dev/disk/by-path/pci-0000:00:1f.2-ata-3.0", + "/dev/sr0" + ], + "unix_device_name2": "/dev/sg0", + "unix_device_number2": { + "type": 99, + "major": 21, + "minor": 0, + "range": 1 + }, + "driver": "ahci", + "driver_module": "ahci", + "drivers": ["ahci", "sr"], + "driver_modules": ["ahci", "sr_mod"] + } + ], + "cpu": [ + { + "architecture": "x86_64", + "vendor_name": "GenuineIntel", + "family": 6, + "model": 85, + "stepping": 4, + "features": [ + "fpu", + "vme", + "de", + "pse", + "tsc", + "msr", + "pae", + "mce", + "cx8", + "apic", + "sep", + "mtrr", + "pge", + "mca", + "cmov", + "pat", + "pse36", + "clflush", + "mmx", + "fxsr", + "sse", + "sse2", + "ht", + "syscall", + "nx", + "pdpe1gb", + "rdtscp", + "lm", + "constant_tsc", + "rep_good", + "nopl", + "xtopology", + "cpuid", + "tsc_known_freq", + "pni", + "pclmulqdq", + "ssse3", + "fma", + "cx16", + "pcid", + "sse4_1", + "sse4_2", + "x2apic", + "movbe", + "popcnt", + "tsc_deadline_timer", + "aes", + "xsave", + "avx", + "f16c", + "rdrand", + "hypervisor", + "lahf_lm", + "abm", + "cpuid_fault", + "pti", + "ssbd", + "ibrs", + "ibpb", + "fsgsbase", + "bmi1", + "avx2", + "smep", + "bmi2", + "erms", + "invpcid", + "avx512f", + "avx512dq", + "clwb", + "avx512cd", + "avx512bw", + "avx512vl", + "xsaveopt", + "arat", + "pku", + "ospke" + ], + "bugs": [ + "cpu_meltdown", + "spectre_v1", + "spectre_v2", + "spec_store_bypass", + "l1tf", + "mds", + "swapgs", + "itlb_multihit", + "mmio_stale_data", + "retbleed", + "gds", + "bhi" + ], + "bogo": 5187.8, + "cache": 16384, + "units": 2, + "physical_id": 0, + "siblings": 2, + "cores": 1, + "fpu": true, + "fpu_exception": true, + "cpuid_level": 13, + "write_protect": false, + "clflush_size": 64, + "cache_alignment": 64, + "address_sizes": { + "physical": 40, + "virtual": 48 + } + } + ], + "disk": [ + { + "index": 43, + "attached_to": 37, + "class_list": ["disk", "block_device"], + "base_class": { + "hex": "0106", + "name": "Mass Storage Device", + "value": 262 + }, + "sub_class": { + "hex": "0000", + "name": "Disk", + "value": 0 + }, + "model": "Disk", + "sysfs_id": "/class/block/vda", + "sysfs_bus_id": "virtio1", + "sysfs_device_link": "/devices/pci0000:00/0000:00:02.3/0000:05:00.0/virtio1", + "unix_device_name": "/dev/vda", + "unix_device_number": { + "type": 98, + "major": 253, + "minor": 0, + "range": 16 + }, + "unix_device_names": [ + "/dev/disk/by-diskseq/9", + "/dev/disk/by-path/pci-0000:05:00.0", + "/dev/disk/by-path/virtio-pci-0000:05:00.0", + "/dev/vda" + ], + "rom_id": "0x80", + "resources": [ + { + "type": "disk_geo", + "cylinders": 166440, + "heads": 16, + "sectors": 63, + "size": 0, + "geo_type": "logical" + }, + { + "type": "size", + "unit": "sectors", + "value_1": 167772160, + "value_2": 512 + } + ], + "driver": "virtio-pci", + "driver_module": "virtio_pci", + "drivers": ["virtio-pci", "virtio_blk"], + "driver_modules": ["virtio_blk", "virtio_pci"] + } + ], + "graphics_card": [ + { + "index": 12, + "attached_to": 0, + "class_list": ["graphics_card", "pci"], + "bus_type": { + "hex": "0004", + "name": "PCI", + "value": 4 + }, + "slot": { + "bus": 0, + "number": 1 + }, + "base_class": { + "hex": "0003", + "name": "Display controller", + "value": 3 + }, + "sub_class": { + "hex": "0000", + "name": "VGA compatible controller", + "value": 0 + }, + "pci_interface": { + "hex": "0000", + "name": "VGA", + "value": 0 + }, + "vendor": { + "hex": "1234", + "value": 4660 + }, + "sub_vendor": { + "hex": "1af4", + "value": 6900 + }, + "device": { + "hex": "1111", + "value": 4369 + }, + "sub_device": { + "hex": "1100", + "value": 4352 + }, + "revision": { + "hex": "0002", + "value": 2 + }, + "model": "VGA compatible controller", + "sysfs_id": "/devices/pci0000:00/0000:00:01.0", + "sysfs_bus_id": "0000:00:01.0", + "resources": [ + { + "type": "mem", + "base": 2147483648, + "range": 16777216, + "enabled": true, + "access": "read_only", + "prefetch": "no" + }, + { + "type": "mem", + "base": 2204266496, + "range": 4096, + "enabled": true, + "access": "read_write", + "prefetch": "no" + }, + { + "type": "mem", + "base": 786432, + "range": 131072, + "enabled": false, + "access": "read_write", + "prefetch": "no" + } + ], + "detail": { + "function": 0, + "command": 3, + "header_type": 0, + "secondary_bus": 0, + "irq": 0, + "prog_if": 0 + }, + "driver": "bochs-drm", + "driver_module": "bochs", + "drivers": ["bochs-drm"], + "driver_modules": ["bochs"], + "module_alias": "pci:v00001234d00001111sv00001AF4sd00001100bc03sc00i00" + } + ], + "hub": [ + { + "index": 44, + "attached_to": 34, + "class_list": ["usb", "hub"], + "bus_type": { + "hex": "0086", + "name": "USB", + "value": 134 + }, + "slot": { + "bus": 0, + "number": 0 + }, + "base_class": { + "hex": "010a", + "name": "Hub", + "value": 266 + }, + "vendor": { + "hex": "1d6b", + "name": "Linux 6.12.10 xhci-hcd", + "value": 7531 + }, + "device": { + "hex": "0002", + "name": "xHCI Host Controller", + "value": 2 + }, + "revision": { + "hex": "0000", + "name": "6.12", + "value": 0 + }, + "serial": "0000:04:00.0", + "model": "Linux 6.12.10 xhci-hcd xHCI Host Controller", + "sysfs_id": "/devices/pci0000:00/0000:00:02.2/0000:04:00.0/usb1/1-0:1.0", + "sysfs_bus_id": "1-0:1.0", + "resources": [ + { + "type": "baud", + "speed": 480000000, + "bits": 0, + "stop_bits": 0, + "parity": 0, + "handshake": 0 + } + ], + "detail": { + "device_class": { + "hex": "0009", + "name": "hub", + "value": 9 + }, + "device_subclass": { + "hex": "0000", + "name": "per_interface", + "value": 0 + }, + "device_protocol": 1, + "interface_class": { + "hex": "0009", + "name": "hub", + "value": 9 + }, + "interface_subclass": { + "hex": "0000", + "name": "per_interface", + "value": 0 + }, + "interface_protocol": 0, + "interface_number": 0, + "interface_alternate_setting": 0 + }, + "hotplug": "usb", + "driver": "hub", + "drivers": ["hub"], + "module_alias": "usb:v1D6Bp0002d0612dc09dsc00dp01ic09isc00ip00in00" + }, + { + "index": 46, + "attached_to": 34, + "class_list": ["usb", "hub"], + "bus_type": { + "hex": "0086", + "name": "USB", + "value": 134 + }, + "slot": { + "bus": 0, + "number": 0 + }, + "base_class": { + "hex": "010a", + "name": "Hub", + "value": 266 + }, + "vendor": { + "hex": "1d6b", + "name": "Linux 6.12.10 xhci-hcd", + "value": 7531 + }, + "device": { + "hex": "0003", + "name": "xHCI Host Controller", + "value": 3 + }, + "revision": { + "hex": "0000", + "name": "6.12", + "value": 0 + }, + "serial": "0000:04:00.0", + "model": "Linux 6.12.10 xhci-hcd xHCI Host Controller", + "sysfs_id": "/devices/pci0000:00/0000:00:02.2/0000:04:00.0/usb2/2-0:1.0", + "sysfs_bus_id": "2-0:1.0", + "detail": { + "device_class": { + "hex": "0009", + "name": "hub", + "value": 9 + }, + "device_subclass": { + "hex": "0000", + "name": "per_interface", + "value": 0 + }, + "device_protocol": 3, + "interface_class": { + "hex": "0009", + "name": "hub", + "value": 9 + }, + "interface_subclass": { + "hex": "0000", + "name": "per_interface", + "value": 0 + }, + "interface_protocol": 0, + "interface_number": 0, + "interface_alternate_setting": 0 + }, + "hotplug": "usb", + "driver": "hub", + "drivers": ["hub"], + "module_alias": "usb:v1D6Bp0003d0612dc09dsc00dp03ic09isc00ip00in00" + } + ], + "memory": [ + { + "index": 5, + "attached_to": 0, + "class_list": ["memory"], + "base_class": { + "hex": "0101", + "name": "Internally Used Class", + "value": 257 + }, + "sub_class": { + "hex": "0002", + "name": "Main Memory", + "value": 2 + }, + "model": "Main Memory", + "resources": [ + { + "type": "mem", + "base": 0, + "range": 4104536064, + "enabled": true, + "access": "read_write", + "prefetch": "unknown" + }, + { + "type": "phys_mem", + "range": 4026531840 + } + ] + } + ], + "monitor": [ + { + "index": 41, + "attached_to": 12, + "class_list": ["monitor"], + "base_class": { + "hex": "0100", + "name": "Monitor", + "value": 256 + }, + "sub_class": { + "hex": "0002", + "name": "LCD Monitor", + "value": 2 + }, + "vendor": { + "hex": "4914", + "value": 18708 + }, + "device": { + "hex": "1234", + "name": "QEMU Monitor", + "value": 4660 + }, + "serial": "0", + "model": "QEMU Monitor", + "resources": [ + { + "type": "monitor", + "width": 1024, + "height": 768, + "vertical_frequency": 60, + "interlaced": false + }, + { + "type": "monitor", + "width": 1280, + "height": 800, + "vertical_frequency": 60, + "interlaced": false + }, + { + "type": "monitor", + "width": 1600, + "height": 1200, + "vertical_frequency": 60, + "interlaced": false + }, + { + "type": "monitor", + "width": 1920, + "height": 1080, + "vertical_frequency": 60, + "interlaced": false + }, + { + "type": "monitor", + "width": 2048, + "height": 1152, + "vertical_frequency": 60, + "interlaced": false + }, + { + "type": "monitor", + "width": 640, + "height": 480, + "vertical_frequency": 60, + "interlaced": false + }, + { + "type": "monitor", + "width": 800, + "height": 600, + "vertical_frequency": 60, + "interlaced": false + }, + { + "type": "size", + "unit": "mm", + "value_1": 325, + "value_2": 203 + } + ], + "detail": { + "manufacture_year": 2014, + "manufacture_week": 42, + "vertical_sync": { + "min": 50, + "max": 125 + }, + "horizontal_sync": { + "min": 30, + "max": 160 + }, + "horizontal_sync_timings": { + "disp": 1280, + "sync_start": 1600, + "sync_end": 1638, + "total": 1728 + }, + "vertical_sync_timings": { + "disp": 800, + "sync_start": 804, + "sync_end": 808, + "total": 828 + }, + "clock": 107300, + "width": 1280, + "height": 800, + "width_millimetres": 325, + "height_millimetres": 203, + "horizontal_flag": 45, + "vertical_flag": 45, + "vendor": "", + "name": "QEMU Monitor" + }, + "driver_info": { + "type": "display", + "width": 2048, + "height": 1152, + "vertical_sync": { + "min": 50, + "max": 125 + }, + "horizontal_sync": { + "min": 30, + "max": 160 + }, + "bandwidth": 0, + "horizontal_sync_timings": { + "disp": 1280, + "sync_start": 1600, + "sync_end": 1638, + "total": 1728 + }, + "vertical_sync_timings": { + "disp": 800, + "sync_start": 804, + "sync_end": 808, + "total": 828 + }, + "horizontal_flag": 45, + "vertical_flag": 45 + } + } + ], + "mouse": [ + { + "index": 45, + "attached_to": 44, + "class_list": ["mouse", "usb"], + "bus_type": { + "hex": "0086", + "name": "USB", + "value": 134 + }, + "slot": { + "bus": 0, + "number": 0 + }, + "base_class": { + "hex": "0105", + "name": "Mouse", + "value": 261 + }, + "sub_class": { + "hex": "0003", + "name": "USB Mouse", + "value": 3 + }, + "vendor": { + "hex": "0627", + "name": "QEMU", + "value": 1575 + }, + "device": { + "hex": "0001", + "name": "QEMU USB Tablet", + "value": 1 + }, + "serial": "28754-0000:00:02.2:00.0-1", + "compat_vendor": "Unknown", + "compat_device": "Generic USB Mouse", + "model": "QEMU USB Tablet", + "sysfs_id": "/devices/pci0000:00/0000:00:02.2/0000:04:00.0/usb1/1-1/1-1:1.0", + "sysfs_bus_id": "1-1:1.0", + "unix_device_name": "/dev/input/mice", + "unix_device_number": { + "type": 99, + "major": 13, + "minor": 63, + "range": 1 + }, + "unix_device_names": ["/dev/input/mice"], + "unix_device_name2": "/dev/input/mouse0", + "unix_device_number2": { + "type": 99, + "major": 13, + "minor": 32, + "range": 1 + }, + "resources": [ + { + "type": "baud", + "speed": 480000000, + "bits": 0, + "stop_bits": 0, + "parity": 0, + "handshake": 0 + } + ], + "detail": { + "device_class": { + "hex": "0000", + "name": "per_interface", + "value": 0 + }, + "device_subclass": { + "hex": "0000", + "name": "per_interface", + "value": 0 + }, + "device_protocol": 0, + "interface_class": { + "hex": "0003", + "name": "hid", + "value": 3 + }, + "interface_subclass": { + "hex": "0000", + "name": "per_interface", + "value": 0 + }, + "interface_protocol": 0, + "interface_number": 0, + "interface_alternate_setting": 0 + }, + "hotplug": "usb", + "driver": "usbhid", + "driver_module": "usbhid", + "drivers": ["usbhid"], + "driver_modules": ["usbhid"], + "driver_info": { + "type": "mouse", + "db_entry_0": ["explorerps/2", "exps2"], + "xf86": "explorerps/2", + "gpm": "exps2", + "buttons": -1, + "wheels": -1 + }, + "module_alias": "usb:v0627p0001d0000dc00dsc00dp00ic03isc00ip00in00" + } + ], + "network_controller": [ + { + "index": 39, + "attached_to": 16, + "class_list": ["network_controller"], + "bus_type": { + "hex": "008f", + "name": "Virtio", + "value": 143 + }, + "slot": { + "bus": 0, + "number": 0 + }, + "base_class": { + "hex": "0002", + "name": "Network controller", + "value": 2 + }, + "sub_class": { + "hex": "0000", + "name": "Ethernet controller", + "value": 0 + }, + "vendor": "Virtio", + "device": "Ethernet Card 0", + "model": "Virtio Ethernet Card 0", + "sysfs_id": "/devices/pci0000:00/0000:00:02.0/0000:01:00.0/virtio0", + "sysfs_bus_id": "virtio0", + "unix_device_name": "enp1s0", + "unix_device_names": ["enp1s0"], + "resources": [ + { + "type": "hwaddr", + "address": 53 + }, + { + "type": "phwaddr", + "address": 53 + } + ], + "driver": "virtio_net", + "driver_module": "virtio_net", + "drivers": ["virtio_net"], + "driver_modules": ["virtio_net"], + "module_alias": "virtio:d00000001v00001AF4" + } + ], + "network_interface": [ + { + "index": 47, + "attached_to": 0, + "class_list": ["network_interface"], + "base_class": { + "hex": "0107", + "name": "Network Interface", + "value": 263 + }, + "sub_class": { + "hex": "0000", + "name": "Loopback", + "value": 0 + }, + "model": "Loopback network interface", + "sysfs_id": "/class/net/lo", + "unix_device_name": "lo", + "unix_device_names": ["lo"] + }, + { + "index": 48, + "attached_to": 39, + "class_list": ["network_interface"], + "base_class": { + "hex": "0107", + "name": "Network Interface", + "value": 263 + }, + "sub_class": { + "hex": "0001", + "name": "Ethernet", + "value": 1 + }, + "model": "Ethernet network interface", + "sysfs_id": "/class/net/enp1s0", + "sysfs_device_link": "/devices/pci0000:00/0000:00:02.0/0000:01:00.0/virtio0", + "unix_device_name": "enp1s0", + "unix_device_names": ["enp1s0"], + "resources": [ + { + "type": "hwaddr", + "address": 53 + }, + { + "type": "phwaddr", + "address": 53 + } + ], + "driver": "virtio_net", + "driver_module": "virtio_net", + "drivers": ["virtio_net"], + "driver_modules": ["virtio_net"] + } + ], + "pci": [ + { + "index": 16, + "attached_to": 35, + "class_list": ["pci", "unknown"], + "bus_type": { + "hex": "0004", + "name": "PCI", + "value": 4 + }, + "slot": { + "bus": 1, + "number": 0 + }, + "base_class": { + "hex": "0002", + "name": "Network controller", + "value": 2 + }, + "sub_class": { + "hex": "0000", + "name": "Ethernet controller", + "value": 0 + }, + "vendor": { + "hex": "1af4", + "value": 6900 + }, + "sub_vendor": { + "hex": "1af4", + "value": 6900 + }, + "device": { + "hex": "1041", + "value": 4161 + }, + "sub_device": { + "hex": "1100", + "value": 4352 + }, + "revision": { + "hex": "0001", + "value": 1 + }, + "model": "Ethernet controller", + "sysfs_id": "/devices/pci0000:00/0000:00:02.0/0000:01:00.0", + "sysfs_bus_id": "0000:01:00.0", + "resources": [ + { + "type": "irq", + "base": 22, + "triggered": 0, + "enabled": true + }, + { + "type": "mem", + "base": 2202009600, + "range": 4096, + "enabled": true, + "access": "read_write", + "prefetch": "no" + }, + { + "type": "mem", + "base": 34359738368, + "range": 16384, + "enabled": true, + "access": "read_only", + "prefetch": "no" + } + ], + "detail": { + "function": 0, + "command": 1031, + "header_type": 0, + "secondary_bus": 0, + "irq": 22, + "prog_if": 0 + }, + "driver": "virtio-pci", + "driver_module": "virtio_pci", + "drivers": ["virtio-pci"], + "driver_modules": ["virtio_pci"], + "module_alias": "pci:v00001AF4d00001041sv00001AF4sd00001100bc02sc00i00" + }, + { + "index": 20, + "attached_to": 10, + "class_list": ["pci", "unknown"], + "bus_type": { + "hex": "0004", + "name": "PCI", + "value": 4 + }, + "slot": { + "bus": 7, + "number": 0 + }, + "base_class": { + "hex": "0000", + "name": "Unclassified device", + "value": 0 + }, + "sub_class": { + "hex": "00ff", + "value": 255 + }, + "vendor": { + "hex": "1af4", + "value": 6900 + }, + "sub_vendor": { + "hex": "1af4", + "value": 6900 + }, + "device": { + "hex": "1044", + "value": 4164 + }, + "sub_device": { + "hex": "1100", + "value": 4352 + }, + "revision": { + "hex": "0001", + "value": 1 + }, + "model": "Unclassified device", + "sysfs_id": "/devices/pci0000:00/0000:00:02.5/0000:07:00.0", + "sysfs_bus_id": "0000:07:00.0", + "resources": [ + { + "type": "irq", + "base": 22, + "triggered": 0, + "enabled": true + }, + { + "type": "mem", + "base": 2189426688, + "range": 4096, + "enabled": true, + "access": "read_write", + "prefetch": "no" + }, + { + "type": "mem", + "base": 34362884096, + "range": 16384, + "enabled": true, + "access": "read_only", + "prefetch": "no" + } + ], + "detail": { + "function": 0, + "command": 1031, + "header_type": 0, + "secondary_bus": 0, + "irq": 22, + "prog_if": 0 + }, + "driver": "virtio-pci", + "driver_module": "virtio_pci", + "drivers": ["virtio-pci"], + "driver_modules": ["virtio_pci"], + "module_alias": "pci:v00001AF4d00001044sv00001AF4sd00001100bc00scFFi00" + }, + { + "index": 22, + "attached_to": 0, + "class_list": ["pci", "unknown"], + "bus_type": { + "hex": "0004", + "name": "PCI", + "value": 4 + }, + "slot": { + "bus": 0, + "number": 31 + }, + "base_class": { + "hex": "000c", + "name": "Serial bus controller", + "value": 12 + }, + "sub_class": { + "hex": "0005", + "name": "SMBus", + "value": 5 + }, + "vendor": { + "hex": "8086", + "name": "Intel Corporation", + "value": 32902 + }, + "sub_vendor": { + "hex": "1af4", + "value": 6900 + }, + "device": { + "hex": "2930", + "value": 10544 + }, + "sub_device": { + "hex": "1100", + "value": 4352 + }, + "revision": { + "hex": "0002", + "value": 2 + }, + "model": "Intel SMBus", + "sysfs_id": "/devices/pci0000:00/0000:00:1f.3", + "sysfs_bus_id": "0000:00:1f.3", + "resources": [ + { + "type": "io", + "base": 24576, + "range": 64, + "enabled": true, + "access": "read_write" + }, + { + "type": "irq", + "base": 16, + "triggered": 0, + "enabled": true + } + ], + "detail": { + "function": 3, + "command": 3, + "header_type": 0, + "secondary_bus": 0, + "irq": 16, + "prog_if": 0 + }, + "driver": "i801_smbus", + "driver_module": "i2c_i801", + "drivers": ["i801_smbus"], + "driver_modules": ["i2c_i801"], + "module_alias": "pci:v00008086d00002930sv00001AF4sd00001100bc0Csc05i00" + }, + { + "index": 24, + "attached_to": 27, + "class_list": ["pci", "unknown"], + "bus_type": { + "hex": "0004", + "name": "PCI", + "value": 4 + }, + "slot": { + "bus": 6, + "number": 0 + }, + "base_class": { + "hex": "0000", + "name": "Unclassified device", + "value": 0 + }, + "sub_class": { + "hex": "00ff", + "value": 255 + }, + "vendor": { + "hex": "1af4", + "value": 6900 + }, + "sub_vendor": { + "hex": "1af4", + "value": 6900 + }, + "device": { + "hex": "1045", + "value": 4165 + }, + "sub_device": { + "hex": "1100", + "value": 4352 + }, + "revision": { + "hex": "0001", + "value": 1 + }, + "model": "Unclassified device", + "sysfs_id": "/devices/pci0000:00/0000:00:02.4/0000:06:00.0", + "sysfs_bus_id": "0000:06:00.0", + "resources": [ + { + "type": "irq", + "base": 22, + "triggered": 0, + "enabled": true + }, + { + "type": "mem", + "base": 34361835520, + "range": 16384, + "enabled": true, + "access": "read_only", + "prefetch": "no" + } + ], + "detail": { + "function": 0, + "command": 7, + "header_type": 0, + "secondary_bus": 0, + "irq": 22, + "prog_if": 0 + }, + "driver": "virtio-pci", + "driver_module": "virtio_pci", + "drivers": ["virtio-pci"], + "driver_modules": ["virtio_pci"], + "module_alias": "pci:v00001AF4d00001045sv00001AF4sd00001100bc00scFFi00" + }, + { + "index": 28, + "attached_to": 13, + "class_list": ["pci", "unknown"], + "bus_type": { + "hex": "0004", + "name": "PCI", + "value": 4 + }, + "slot": { + "bus": 5, + "number": 0 + }, + "base_class": { + "hex": "0001", + "name": "Mass storage controller", + "value": 1 + }, + "sub_class": { + "hex": "0000", + "name": "SCSI storage controller", + "value": 0 + }, + "vendor": { + "hex": "1af4", + "value": 6900 + }, + "sub_vendor": { + "hex": "1af4", + "value": 6900 + }, + "device": { + "hex": "1042", + "value": 4162 + }, + "sub_device": { + "hex": "1100", + "value": 4352 + }, + "revision": { + "hex": "0001", + "value": 1 + }, + "model": "SCSI storage controller", + "sysfs_id": "/devices/pci0000:00/0000:00:02.3/0000:05:00.0", + "sysfs_bus_id": "0000:05:00.0", + "resources": [ + { + "type": "irq", + "base": 22, + "triggered": 0, + "enabled": true + }, + { + "type": "mem", + "base": 2193620992, + "range": 4096, + "enabled": true, + "access": "read_write", + "prefetch": "no" + }, + { + "type": "mem", + "base": 34360786944, + "range": 16384, + "enabled": true, + "access": "read_only", + "prefetch": "no" + } + ], + "detail": { + "function": 0, + "command": 1031, + "header_type": 0, + "secondary_bus": 0, + "irq": 22, + "prog_if": 0 + }, + "driver": "virtio-pci", + "driver_module": "virtio_pci", + "drivers": ["virtio-pci"], + "driver_modules": ["virtio_pci"], + "module_alias": "pci:v00001AF4d00001042sv00001AF4sd00001100bc01sc00i00" + }, + { + "index": 29, + "attached_to": 11, + "class_list": ["pci", "unknown"], + "bus_type": { + "hex": "0004", + "name": "PCI", + "value": 4 + }, + "slot": { + "bus": 3, + "number": 1 + }, + "base_class": { + "hex": "0008", + "name": "Generic system peripheral", + "value": 8 + }, + "sub_class": { + "hex": "0080", + "name": "System peripheral", + "value": 128 + }, + "vendor": { + "hex": "8086", + "name": "Intel Corporation", + "value": 32902 + }, + "sub_vendor": { + "hex": "1af4", + "value": 6900 + }, + "device": { + "hex": "25ab", + "value": 9643 + }, + "sub_device": { + "hex": "1100", + "value": 4352 + }, + "model": "Intel System peripheral", + "sysfs_id": "/devices/pci0000:00/0000:00:02.1/0000:02:00.0/0000:03:01.0", + "sysfs_bus_id": "0000:03:01.0", + "resources": [ + { + "type": "mem", + "base": 2197815296, + "range": 16, + "enabled": true, + "access": "read_write", + "prefetch": "no" + } + ], + "detail": { + "function": 0, + "command": 3, + "header_type": 0, + "secondary_bus": 0, + "irq": 0, + "prog_if": 0 + }, + "driver": "i6300ESB timer", + "driver_module": "i6300esb", + "drivers": ["i6300ESB timer"], + "driver_modules": ["i6300esb"], + "module_alias": "pci:v00008086d000025ABsv00001AF4sd00001100bc08sc80i00" + } + ], + "sound": [ + { + "index": 18, + "attached_to": 0, + "class_list": ["sound", "pci"], + "bus_type": { + "hex": "0004", + "name": "PCI", + "value": 4 + }, + "slot": { + "bus": 0, + "number": 27 + }, + "base_class": { + "hex": "0004", + "name": "Multimedia controller", + "value": 4 + }, + "sub_class": { + "hex": "0003", + "value": 3 + }, + "vendor": { + "hex": "8086", + "name": "Intel Corporation", + "value": 32902 + }, + "sub_vendor": { + "hex": "1af4", + "value": 6900 + }, + "device": { + "hex": "293e", + "value": 10558 + }, + "sub_device": { + "hex": "1100", + "value": 4352 + }, + "revision": { + "hex": "0003", + "value": 3 + }, + "model": "Intel Multimedia controller", + "sysfs_id": "/devices/pci0000:00/0000:00:1b.0", + "sysfs_bus_id": "0000:00:1b.0", + "resources": [ + { + "type": "irq", + "base": 56, + "triggered": 0, + "enabled": true + }, + { + "type": "mem", + "base": 2204172288, + "range": 16384, + "enabled": true, + "access": "read_write", + "prefetch": "no" + } + ], + "detail": { + "function": 0, + "command": 1031, + "header_type": 0, + "secondary_bus": 0, + "irq": 56, + "prog_if": 0 + }, + "driver": "snd_hda_intel", + "driver_module": "snd_hda_intel", + "drivers": ["snd_hda_intel"], + "driver_modules": ["snd_hda_intel"], + "module_alias": "pci:v00008086d0000293Esv00001AF4sd00001100bc04sc03i00" + } + ], + "storage_controller": [ + { + "index": 7, + "attached_to": 0, + "class_list": ["storage_controller", "pci"], + "bus_type": { + "hex": "0004", + "name": "PCI", + "value": 4 + }, + "slot": { + "bus": 0, + "number": 31 + }, + "base_class": { + "hex": "0001", + "name": "Mass storage controller", + "value": 1 + }, + "sub_class": { + "hex": "0006", + "value": 6 + }, + "pci_interface": { + "hex": "0001", + "value": 1 + }, + "vendor": { + "hex": "8086", + "name": "Intel Corporation", + "value": 32902 + }, + "sub_vendor": { + "hex": "1af4", + "value": 6900 + }, + "device": { + "hex": "2922", + "value": 10530 + }, + "sub_device": { + "hex": "1100", + "value": 4352 + }, + "revision": { + "hex": "0002", + "value": 2 + }, + "model": "Intel Mass storage controller", + "sysfs_id": "/devices/pci0000:00/0000:00:1f.2", + "sysfs_bus_id": "0000:00:1f.2", + "resources": [ + { + "type": "io", + "base": 24640, + "range": 32, + "enabled": true, + "access": "read_write" + }, + { + "type": "irq", + "base": 53, + "triggered": 0, + "enabled": true + }, + { + "type": "mem", + "base": 2204188672, + "range": 4096, + "enabled": true, + "access": "read_write", + "prefetch": "no" + } + ], + "detail": { + "function": 2, + "command": 1031, + "header_type": 0, + "secondary_bus": 0, + "irq": 53, + "prog_if": 1 + }, + "driver": "ahci", + "driver_module": "ahci", + "drivers": ["ahci"], + "driver_modules": ["ahci"], + "module_alias": "pci:v00008086d00002922sv00001AF4sd00001100bc01sc06i01" + }, + { + "index": 37, + "attached_to": 28, + "class_list": ["storage_controller"], + "bus_type": { + "hex": "008f", + "name": "Virtio", + "value": 143 + }, + "slot": { + "bus": 0, + "number": 0 + }, + "base_class": { + "hex": "0001", + "name": "Mass storage controller", + "value": 1 + }, + "sub_class": { + "hex": "0080", + "name": "Storage controller", + "value": 128 + }, + "vendor": "Virtio", + "device": "Storage 0", + "model": "Virtio Storage 0", + "sysfs_id": "/devices/pci0000:00/0000:00:02.3/0000:05:00.0/virtio1", + "sysfs_bus_id": "virtio1", + "driver": "virtio_blk", + "driver_module": "virtio_blk", + "drivers": ["virtio_blk"], + "driver_modules": ["virtio_blk"], + "module_alias": "virtio:d00000002v00001AF4" + } + ], + "system": { + "form_factor": "desktop" + }, + "unknown": [ + { + "index": 38, + "attached_to": 24, + "class_list": ["unknown"], + "base_class": { + "hex": "0000", + "name": "Unclassified device", + "value": 0 + }, + "sub_class": { + "hex": "0000", + "name": "Unclassified device", + "value": 0 + }, + "vendor": "Virtio", + "device": "", + "model": "Virtio Unclassified device", + "sysfs_id": "/devices/pci0000:00/0000:00:02.4/0000:06:00.0/virtio2", + "sysfs_bus_id": "virtio2", + "driver": "virtio_balloon", + "driver_module": "virtio_balloon", + "drivers": ["virtio_balloon"], + "driver_modules": ["virtio_balloon"], + "module_alias": "virtio:d00000005v00001AF4" + }, + { + "index": 40, + "attached_to": 20, + "class_list": ["unknown"], + "base_class": { + "hex": "0000", + "name": "Unclassified device", + "value": 0 + }, + "sub_class": { + "hex": "0000", + "name": "Unclassified device", + "value": 0 + }, + "vendor": "Virtio", + "device": "", + "model": "Virtio Unclassified device", + "sysfs_id": "/devices/pci0000:00/0000:00:02.5/0000:07:00.0/virtio3", + "sysfs_bus_id": "virtio3", + "driver": "virtio_rng", + "driver_module": "virtio_rng", + "drivers": ["virtio_rng"], + "driver_modules": ["virtio_rng"], + "module_alias": "virtio:d00000004v00001AF4" + } + ], + "usb_controller": [ + { + "index": 34, + "attached_to": 32, + "class_list": ["usb_controller", "pci"], + "bus_type": { + "hex": "0004", + "name": "PCI", + "value": 4 + }, + "slot": { + "bus": 4, + "number": 0 + }, + "base_class": { + "hex": "000c", + "name": "Serial bus controller", + "value": 12 + }, + "sub_class": { + "hex": "0003", + "name": "USB Controller", + "value": 3 + }, + "pci_interface": { + "hex": "0030", + "value": 48 + }, + "vendor": { + "hex": "1b36", + "value": 6966 + }, + "sub_vendor": { + "hex": "1af4", + "value": 6900 + }, + "device": { + "hex": "000d", + "value": 13 + }, + "sub_device": { + "hex": "1100", + "value": 4352 + }, + "revision": { + "hex": "0001", + "value": 1 + }, + "model": "USB Controller", + "sysfs_id": "/devices/pci0000:00/0000:00:02.2/0000:04:00.0", + "sysfs_bus_id": "0000:04:00.0", + "resources": [ + { + "type": "irq", + "base": 22, + "triggered": 0, + "enabled": true + }, + { + "type": "mem", + "base": 2195718144, + "range": 16384, + "enabled": true, + "access": "read_write", + "prefetch": "no" + } + ], + "detail": { + "function": 0, + "command": 1031, + "header_type": 0, + "secondary_bus": 0, + "irq": 22, + "prog_if": 48 + }, + "driver": "xhci_hcd", + "driver_module": "xhci_pci", + "drivers": ["xhci_hcd"], + "driver_modules": ["xhci_pci"], + "module_alias": "pci:v00001B36d0000000Dsv00001AF4sd00001100bc0Csc03i30" + } + ] + }, + "smbios": { + "bios": { + "handle": 0, + "vendor": "Vultr", + "version": "", + "date": "", + "features": null, + "start_address": "0xe8000", + "rom_size": 65536 + }, + "chassis": { + "handle": 768, + "manufacturer": "QEMU", + "version": "pc-q35-8.2", + "chassis_type": { + "hex": "0001", + "name": "Other", + "value": 1 + }, + "lock_present": false, + "bootup_state": { + "hex": "0003", + "name": "Safe", + "value": 3 + }, + "power_state": { + "hex": "0003", + "name": "Safe", + "value": 3 + }, + "thermal_state": { + "hex": "0003", + "name": "Safe", + "value": 3 + }, + "security_state": { + "hex": "0002", + "name": "Unknown", + "value": 2 + }, + "oem": "0x0" + }, + "memory_array": [ + { + "handle": 4096, + "location": { + "hex": "0001", + "name": "Other", + "value": 1 + }, + "usage": { + "hex": "0003", + "name": "System memory", + "value": 3 + }, + "ecc": { + "hex": "0006", + "name": "Multi-bit", + "value": 6 + }, + "max_size": 4194304, + "error_handle": 65534, + "slots": 1 + } + ], + "memory_array_mapped_address": [ + { + "handle": 4864, + "array_handle": 4096, + "start_address": 0, + "end_address": 2147483648, + "part_width": 1 + }, + { + "handle": 4865, + "array_handle": 4096, + "start_address": 4294967296, + "end_address": 6442450944, + "part_width": 1 + } + ], + "memory_device": [ + { + "handle": 4352, + "location": "DIMM 0", + "bank_location": "", + "manufacturer": "QEMU", + "part_number": "", + "array_handle": 4096, + "error_handle": 65534, + "width": 0, + "ecc_bits": 0, + "size": 4194304, + "form_factor": { + "hex": "0009", + "name": "DIMM", + "value": 9 + }, + "set": 0, + "memory_type": { + "hex": "0007", + "name": "RAM", + "value": 7 + }, + "memory_type_details": ["Other"], + "speed": 0 + } + ], + "processor": [ + { + "handle": 1024, + "socket": "CPU 0", + "socket_type": { + "hex": "0001", + "name": "Other", + "value": 1 + }, + "socket_populated": true, + "manufacturer": "QEMU", + "version": "pc-q35-8.2", + "part": "", + "processor_type": { + "hex": "0003", + "name": "CPU", + "value": 3 + }, + "processor_family": { + "hex": "0001", + "name": "Other", + "value": 1 + }, + "processor_status": { + "hex": "0001", + "name": "Enabled", + "value": 1 + }, + "clock_ext": 0, + "clock_max": 2000, + "cache_handle_l1": 0, + "cache_handle_l2": 0, + "cache_handle_l3": 0 + } + ], + "system": { + "handle": 256, + "manufacturer": "Vultr", + "product": "VC2", + "version": "pc-q35-8.2", + "wake_up": { + "hex": "0006", + "name": "Power Switch", + "value": 6 + } + } + } +} diff --git a/pkgs/clan-cli/clan_lib/tests/test_create.py b/pkgs/clan-cli/clan_lib/tests/test_create.py new file mode 100644 index 000000000..05f6522a7 --- /dev/null +++ b/pkgs/clan-cli/clan_lib/tests/test_create.py @@ -0,0 +1,274 @@ +import json +import logging +import shutil +import sys +from dataclasses import dataclass +from pathlib import Path +from typing import Any + +import clan_cli.clan.create +import pytest +from clan_cli.cmd import RunOpts, run +from clan_cli.dirs import specific_machine_dir +from clan_cli.errors import ClanError +from clan_cli.flake import Flake +from clan_cli.inventory import patch_inventory_with +from clan_cli.inventory.classes import Machine as InventoryMachine +from clan_cli.inventory.classes import MachineDeploy +from clan_cli.machines.create import CreateOptions as ClanCreateOptions +from clan_cli.machines.create import create_machine +from clan_cli.machines.list import check_machine_online +from clan_cli.machines.machines import Machine +from clan_cli.nix import nix_command +from clan_cli.secrets.key import generate_key +from clan_cli.secrets.sops import maybe_get_admin_public_key +from clan_cli.secrets.users import add_user +from clan_cli.ssh.host import Host +from clan_cli.ssh.host_key import HostKeyCheck +from clan_cli.vars.generate import generate_vars_for_machine, get_generators_closure + +from clan_lib.api.disk import hw_main_disk_options, set_machine_disk_schema + +log = logging.getLogger(__name__) + + +@dataclass +class InventoryWrapper: + services: dict[str, Any] + + +@dataclass +class InvSSHKeyEntry: + username: str + ssh_pubkey_txt: str + + +@dataclass +class SSHKeyPair: + private: Path + public: Path + + +def create_base_inventory(ssh_keys_pairs: list[SSHKeyPair]) -> InventoryWrapper: + ssh_keys = [ + InvSSHKeyEntry("nixos-anywhere", ssh_keys_pairs[0].public.read_text()), + ] + for num, ssh_key in enumerate(ssh_keys_pairs[1:]): + ssh_keys.append(InvSSHKeyEntry(f"user_{num}", ssh_key.public.read_text())) + + """Create the base inventory structure.""" + inventory: dict[str, Any] = { + "sshd": { + "someid": { + "roles": { + "server": { + "tags": ["all"], + "config": {}, + } + } + } + }, + "state-version": { + "someid": { + "roles": { + "default": { + "tags": ["all"], + } + } + } + }, + "admin": { + "someid": { + "roles": { + "default": { + "tags": ["all"], + "config": { + "allowedKeys": { + key.username: key.ssh_pubkey_txt for key in ssh_keys + }, + }, + }, + } + } + }, + } + + return InventoryWrapper(services=inventory) + + +# TODO: We need a way to calculate the narHash of the current clan-core +# and substitute it in a pregenerated flake.lock +def fix_flake_inputs(clan_dir: Path, clan_core_dir: Path) -> None: + flake_nix = clan_dir / "flake.nix" + assert flake_nix.exists() + clan_dir_flake = Flake(str(clan_dir)) + clan_dir_flake.invalidate_cache() + content = flake_nix.read_text() + content = content.replace( + "https://git.clan.lol/clan/clan-core/archive/main.tar.gz", + f"path://{clan_core_dir}", + ) + flake_nix.write_text(content) + + run(nix_command(["flake", "update"]), RunOpts(cwd=clan_dir)) + + +@pytest.mark.with_core +@pytest.mark.skipif(sys.platform == "darwin", reason="sshd fails to start on darwin") +def test_clan_create_api( + temporary_home: Path, test_lib_root: Path, clan_core: Path, hosts: list[Host] +) -> None: + host_ip = hosts[0].host + host_user = hosts[0].user + vm_name = "test-clan" + clan_core_dir_var = str(clan_core) + priv_key_var = hosts[0].private_key + ssh_port_var = str(hosts[0].port) + + assert priv_key_var is not None + private_key = Path(priv_key_var).expanduser() + + assert host_user is not None + + assert private_key.exists() + assert private_key.is_file() + + public_key = Path(f"{private_key}.pub") + assert public_key.exists() + assert public_key.is_file() + + dest_clan_dir = Path("~/new-clan").expanduser() + + # ===== CREATE CLAN ====== + # TODO: We need to generate a lock file for the templates + clan_cli.clan.create.create_clan( + clan_cli.clan.create.CreateOptions( + template_name="minimal", dest=dest_clan_dir, update_clan=False + ) + ) + assert dest_clan_dir.is_dir() + assert (dest_clan_dir / "flake.nix").is_file() + + clan_core_dir = Path(clan_core_dir_var) + # TODO: We need a way to generate the lock file for the templates + fix_flake_inputs(dest_clan_dir, clan_core_dir) + + # ===== CREATE SOPS KEY ====== + sops_key = maybe_get_admin_public_key() + if sops_key is None: + # TODO: In the UI we need a view for this + sops_key = generate_key() + else: + msg = "SOPS key already exists, please remove it before running this test" + raise ClanError(msg) + + # TODO: This needs to be exposed in the UI and we need a view for this + add_user( + dest_clan_dir, + name="testuser", + keys=[sops_key], + force=False, + ) + + # ===== CREATE MACHINE/s ====== + clan_dir_flake = Flake(str(dest_clan_dir)) + machines: list[Machine] = [] + + host = Host(user=host_user, host=host_ip, port=int(ssh_port_var)) + # TODO: We need to merge Host and Machine class these duplicate targetHost stuff is a nightmare + inv_machine = InventoryMachine( + name=vm_name, deploy=MachineDeploy(targetHost=f"{host.target}:{ssh_port_var}") + ) + create_machine( + ClanCreateOptions( + clan_dir_flake, inv_machine, target_host=f"{host.target}:{ssh_port_var}" + ) + ) + + machine = Machine( + name=vm_name, + flake=clan_dir_flake, + host_key_check=HostKeyCheck.NONE, + private_key=private_key, + ) + machines.append(machine) + assert len(machines) == 1 + + # Invalidate cache because of new machine creation + clan_dir_flake.invalidate_cache() + + result = check_machine_online(machine) + assert result == "Online", f"Machine {machine.name} is not online" + + ssh_keys = [ + SSHKeyPair( + private=private_key, + public=public_key, + ) + ] + + # ===== CREATE BASE INVENTORY ====== + inventory = create_base_inventory(ssh_keys) + patch_inventory_with(dest_clan_dir, "services", inventory.services) + + # Invalidate cache because of new inventory + clan_dir_flake.invalidate_cache() + + generators = get_generators_closure(machine.name, dest_clan_dir) + all_prompt_values = {} + for generator in generators: + prompt_values = {} + for prompt in generator.prompts: + var_id = f"{generator.name}/{prompt.name}" + if generator.name == "root-password" and prompt.name == "password": + prompt_values[prompt.name] = "terraform" + else: + msg = f"Prompt {var_id} not handled in test, please fix it" + raise ClanError(msg) + all_prompt_values[generator.name] = prompt_values + + generate_vars_for_machine( + machine.name, + generators=[gen.name for gen in generators], + base_dir=dest_clan_dir, + all_prompt_values=all_prompt_values, + ) + + clan_dir_flake.invalidate_cache() + + # ===== Select Disko Config ====== + facter_json = test_lib_root / "assets" / "facter.json" + assert facter_json.exists(), f"Source facter file not found: {facter_json}" + + dest_dir = specific_machine_dir(clan_dir_flake.path, machine.name) + # specific_machine_dir should create the directory, but ensure it exists just in case + dest_dir.mkdir(parents=True, exist_ok=True) + + dest_facter_path = dest_dir / "facter.json" + + # Copy the file + shutil.copy(facter_json, dest_facter_path) + assert dest_facter_path.exists(), ( + f"Failed to copy facter file to {dest_facter_path}" + ) + + # ===== Create Disko Config ====== + facter_path = ( + specific_machine_dir(clan_dir_flake.path, machine.name) / "facter.json" + ) + with facter_path.open("r") as f: + facter_report = json.load(f) + + disk_devs = hw_main_disk_options(facter_report) + + assert disk_devs is not None + + placeholders = {"mainDisk": disk_devs[0]} + set_machine_disk_schema( + clan_dir_flake.path, machine.name, "single-disk", placeholders + ) + clan_dir_flake.invalidate_cache() + + with pytest.raises(ClanError) as exc_info: + machine.build_nix("config.system.build.toplevel") + assert "nixos-system-test-clan" in str(exc_info.value) diff --git a/pkgs/clan-cli/conftest.py b/pkgs/clan-cli/conftest.py new file mode 100644 index 000000000..378797ef8 --- /dev/null +++ b/pkgs/clan-cli/conftest.py @@ -0,0 +1,22 @@ +import pytest +from clan_cli.custom_logger import setup_logging + +# Every fixture registered here will be available in clan_cli and clan_lib +pytest_plugins = [ + "clan_cli.tests.temporary_dir", + "clan_cli.tests.root", + "clan_cli.tests.sshd", + "clan_cli.tests.hosts", + "clan_cli.tests.command", + "clan_cli.tests.ports", +] + + +# Executed on pytest session start +def pytest_sessionstart(session: pytest.Session) -> None: + # This function will be called once at the beginning of the test session + print("Starting pytest session") + # You can access the session config, items, testsfailed, etc. + print(f"Session config: {session.config}") + + setup_logging(level="INFO") diff --git a/pkgs/clan-cli/default.nix b/pkgs/clan-cli/default.nix index 53d06a5bd..29436ff2f 100644 --- a/pkgs/clan-cli/default.nix +++ b/pkgs/clan-cli/default.nix @@ -48,7 +48,7 @@ let && !(stdenv.hostPlatform.system == "aarch64-linux" && attr == "age-plugin-se") ) (lib.genAttrs deps (name: pkgs.${name})); testRuntimeDependenciesMap = generateRuntimeDependenciesMap allDependencies; - testRuntimeDependencies = lib.attrValues testRuntimeDependenciesMap; + testRuntimeDependencies = (lib.attrValues testRuntimeDependenciesMap); bundledRuntimeDependenciesMap = generateRuntimeDependenciesMap includedRuntimeDeps; bundledRuntimeDependencies = lib.attrValues bundledRuntimeDependenciesMap; @@ -215,6 +215,59 @@ pythonRuntime.pkgs.buildPythonApplication { python -m pytest -m "not impure and with_core" ./clan_cli -n $jobs touch $out ''; + } + // { + # disabled on macOS until we fix all remaining issues + clan-lib-pytest = + runCommand "clan-lib-pytest" + { + nativeBuildInputs = testDependencies; + buildInputs = [ + pkgs.bash + pkgs.coreutils + pkgs.nix + + ]; + closureInfo = pkgs.closureInfo { + rootPaths = [ + templateDerivation + pkgs.bash + pkgs.coreutils + pkgs.jq.dev + pkgs.stdenv + pkgs.stdenvNoCC + pkgs.openssh + pkgs.shellcheck-minimal + pkgs.mkpasswd + pkgs.xkcdpass + nix-select + ]; + }; + } + '' + set -euo pipefail + cp -r ${source} ./src + chmod +w -R ./src + cd ./src + + export CLAN_CORE_PATH=${clan-core-path} + export NIX_STATE_DIR=$TMPDIR/nix + export IN_NIX_SANDBOX=1 + export PYTHONWARNINGS=error + export CLAN_TEST_STORE=$TMPDIR/store + # required to prevent concurrent 'nix flake lock' operations + export LOCK_NIX=$TMPDIR/nix_lock + mkdir -p "$CLAN_TEST_STORE/nix/store" + mkdir -p "$CLAN_TEST_STORE/nix/var/nix/gcroots" + xargs cp --recursive --target "$CLAN_TEST_STORE/nix/store" < "$closureInfo/store-paths" + nix-store --load-db --store "$CLAN_TEST_STORE" < "$closureInfo/registration" + + # limit build cores to 4 + jobs="$((NIX_BUILD_CORES>4 ? 4 : NIX_BUILD_CORES))" + + python -m pytest -m "with_core" ./clan_lib -n $jobs + touch $out + ''; }; passthru.nixpkgs = nixpkgs'; diff --git a/pkgs/clan-cli/pyproject.toml b/pkgs/clan-cli/pyproject.toml index 2d4cc5d63..4573fc525 100644 --- a/pkgs/clan-cli/pyproject.toml +++ b/pkgs/clan-cli/pyproject.toml @@ -29,7 +29,7 @@ clan_cli = [ ] [tool.pytest.ini_options] -testpaths = ["tests", "clan_cli"] +testpaths = ["tests", "clan_cli", "clan_lib"] faulthandler_timeout = 240 log_level = "DEBUG" log_format = "%(message)s"