Merge pull request #1696 from ogayot/umockdev
ubuntu-drivers: add ability to run ubuntu-drivers in dry-run with umockdev
This commit is contained in:
commit
fa29b9088b
|
@ -3,6 +3,7 @@ cloud-init
|
||||||
curl
|
curl
|
||||||
fuseiso
|
fuseiso
|
||||||
gettext
|
gettext
|
||||||
|
gir1.2-umockdev-1.0
|
||||||
git
|
git
|
||||||
isolinux
|
isolinux
|
||||||
jq
|
jq
|
||||||
|
@ -25,6 +26,7 @@ python3-coverage
|
||||||
python3-dev
|
python3-dev
|
||||||
python3-distutils-extra
|
python3-distutils-extra
|
||||||
python3-flake8
|
python3-flake8
|
||||||
|
python3-gi
|
||||||
python3-jsonschema
|
python3-jsonschema
|
||||||
python3-more-itertools
|
python3-more-itertools
|
||||||
python3-mypy
|
python3-mypy
|
||||||
|
@ -44,4 +46,6 @@ python3-urwid
|
||||||
python3-wheel
|
python3-wheel
|
||||||
python3-yaml
|
python3-yaml
|
||||||
ssh-import-id
|
ssh-import-id
|
||||||
|
ubuntu-drivers-common
|
||||||
|
umockdev
|
||||||
xorriso
|
xorriso
|
||||||
|
|
|
@ -0,0 +1,11 @@
|
||||||
|
devices:
|
||||||
|
# This is the SMBus from the XPS 9230
|
||||||
|
# 0000:00:1f.4 SMBus [0c05]: Intel Corporation Alder Lake PCH-P SMBus Host Controller [8086:51a3] (rev 01)
|
||||||
|
- modalias: 'pci:v00008086d000051A3sv00001028sd00000AF3bc0Csc05i00'
|
||||||
|
vendor: '0x8086'
|
||||||
|
device: '0x51A3'
|
||||||
|
# This is a fake NVIDIA GPU
|
||||||
|
- modalias: 'pci:v000010DEd00001E36sv0000deadbeefsd0000deadbeefbc03scdeadbeefideadbeef'
|
||||||
|
vendor: '0x10DE'
|
||||||
|
device: '0x1E36'
|
||||||
|
|
|
@ -0,0 +1,32 @@
|
||||||
|
devices:
|
||||||
|
# List was extracted on focal:
|
||||||
|
# == /sys/devices/pci0000:00/0000:00:14.0/usb3/3-9/3-9:1.0 ==
|
||||||
|
# modalias : usb:v27C6p63BCd0100dcEFdsc00dp00icFFisc00ip00in00
|
||||||
|
# vendor : Shenzhen Goodix Technology Co.,Ltd.
|
||||||
|
# driver : oem-fix-fpr-goodix-deletestoredfp - third-party free
|
||||||
|
#
|
||||||
|
# == /sys/devices/pci0000:00/0000:00:1f.4 ==
|
||||||
|
# modalias : pci:v00008086d000051A3sv00001028sd00000AF3bc0Csc05i00
|
||||||
|
# vendor : Intel Corporation
|
||||||
|
# driver : oem-somerville-tentacool-meta - third-party free
|
||||||
|
#
|
||||||
|
# == /sys/devices/pci0000:00/0000:00:05.0 ==
|
||||||
|
# modalias : pci:v00008086d0000465Dsv00001028sd00000AF3bc04sc80i00
|
||||||
|
# vendor : Intel Corporation
|
||||||
|
# driver : libcamhal-ipu6ep0 - third-party free
|
||||||
|
# driver : oem-fix-cam-intel-mipi-ipu6ep - third-party free
|
||||||
|
#
|
||||||
|
# == /sys/devices/virtual/dmi/id ==
|
||||||
|
# modalias : dmi:bvnDellInc.:bvr2.2.1:bd04/17/2023:br2.2:svnDellInc.:pnXPS9320:pvr:rvnDellInc.:rn:rvr:cvnDellInc.:ct10:cvr:sku0AF3:
|
||||||
|
# driver : oem-release - third-party free
|
||||||
|
# driver : oem-somerville-meta - third-party free
|
||||||
|
- modalias: 'usb:v27C6p63BCd0100dcEFdsc00dp00icFFisc00ip00in00'
|
||||||
|
vendor: '0x27C6'
|
||||||
|
device: '0x63BC'
|
||||||
|
- modalias: 'pci:v00008086d000051A3sv00001028sd00000AF3bc0Csc05i00'
|
||||||
|
vendor: '0x8086'
|
||||||
|
device: '0x51A3'
|
||||||
|
- modalias: 'pci:v00008086d0000465Dsv00001028sd00000AF3bc04sc80i00'
|
||||||
|
vendor: '0x8086'
|
||||||
|
device: '0x465D'
|
||||||
|
- modalias: 'dmi:bvnDellInc.:bvr2.2.1:bd04/17/2023:br2.2:svnDellInc.:pnXPS9320:pvr:rvnDellInc.:rn:rvr:cvnDellInc.:ct10:cvr:sku0AF3:'
|
|
@ -0,0 +1,54 @@
|
||||||
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
|
''' Read a YAML file passed as the --config argument and execute the command
|
||||||
|
supplied in a testbed configured with UMockdev. '''
|
||||||
|
|
||||||
|
import argparse
|
||||||
|
import os
|
||||||
|
from typing import Dict, TextIO
|
||||||
|
|
||||||
|
import gi
|
||||||
|
import yaml
|
||||||
|
|
||||||
|
try:
|
||||||
|
gi.require_version('UMockdev', '1.0')
|
||||||
|
except ValueError as exc:
|
||||||
|
raise RuntimeError('Package gir1.2-umockdev-1.0 is required') from exc
|
||||||
|
|
||||||
|
from gi.repository import UMockdev
|
||||||
|
|
||||||
|
|
||||||
|
def main() -> None:
|
||||||
|
parser = argparse.ArgumentParser()
|
||||||
|
|
||||||
|
parser.add_argument('--config', type=argparse.FileType(), required=True)
|
||||||
|
parser.add_argument('command', help='Command to execute')
|
||||||
|
parser.add_argument('args', nargs='*',
|
||||||
|
help='Command arguments')
|
||||||
|
|
||||||
|
args = parser.parse_args()
|
||||||
|
|
||||||
|
data = yaml.safe_load(args.config)
|
||||||
|
|
||||||
|
testbed = UMockdev.Testbed.new()
|
||||||
|
|
||||||
|
for idx, dev in enumerate(data['devices']):
|
||||||
|
subsystem = dev['modalias'].split(':', maxsplit=1)[0]
|
||||||
|
name = f'dev{idx}'
|
||||||
|
parent = None
|
||||||
|
attrs: List[str] = []
|
||||||
|
properties: List[str] = []
|
||||||
|
|
||||||
|
# dev is a dict, but add_device expects a list [key1, value1, key2,
|
||||||
|
# value2, ...], a bit like a Perl's hash in LIST context.
|
||||||
|
for key, value in dev.items():
|
||||||
|
attrs.extend([key, value])
|
||||||
|
|
||||||
|
testbed.add_device(subsystem, name, parent, attrs, properties)
|
||||||
|
|
||||||
|
os.execvp('umockdev-wrapper',
|
||||||
|
['umockdev-wrapper', args.command] + args.args)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
main()
|
|
@ -13,7 +13,7 @@
|
||||||
# You should have received a copy of the GNU Affero General Public License
|
# You should have received a copy of the GNU Affero General Public License
|
||||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
from typing import List, TypedDict
|
from typing import List, Optional, TypedDict
|
||||||
import yaml
|
import yaml
|
||||||
|
|
||||||
import attr
|
import attr
|
||||||
|
@ -77,6 +77,11 @@ class DRConfig:
|
||||||
{"username": "sisyphus", "strategy": "failure"},
|
{"username": "sisyphus", "strategy": "failure"},
|
||||||
]
|
]
|
||||||
|
|
||||||
|
# If running ubuntu-drivers on the host, supply a file to
|
||||||
|
# umockdev-wrapper.py
|
||||||
|
ubuntu_drivers_run_on_host_umockdev: Optional[str] = \
|
||||||
|
"examples/umockdev/dell-certified+nvidia.yaml"
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def load(cls, stream):
|
def load(cls, stream):
|
||||||
data = yaml.safe_load(stream)
|
data = yaml.safe_load(stream)
|
||||||
|
|
|
@ -19,6 +19,7 @@ from unittest.mock import patch, AsyncMock, Mock
|
||||||
|
|
||||||
from subiquitycore.tests.mocks import make_app
|
from subiquitycore.tests.mocks import make_app
|
||||||
|
|
||||||
|
from subiquity.server.dryrun import DRConfig
|
||||||
from subiquity.server.ubuntu_drivers import (
|
from subiquity.server.ubuntu_drivers import (
|
||||||
UbuntuDriversInterface,
|
UbuntuDriversInterface,
|
||||||
UbuntuDriversClientInterface,
|
UbuntuDriversClientInterface,
|
||||||
|
@ -158,9 +159,39 @@ oem-somerville-tentacool-meta
|
||||||
class TestUbuntuDriversRunDriversInterface(unittest.IsolatedAsyncioTestCase):
|
class TestUbuntuDriversRunDriversInterface(unittest.IsolatedAsyncioTestCase):
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
self.app = make_app()
|
self.app = make_app()
|
||||||
|
self.app.dr_cfg = DRConfig()
|
||||||
|
self.app.dr_cfg.ubuntu_drivers_run_on_host_umockdev = None
|
||||||
self.ubuntu_drivers = UbuntuDriversRunDriversInterface(
|
self.ubuntu_drivers = UbuntuDriversRunDriversInterface(
|
||||||
self.app, gpgpu=False)
|
self.app, gpgpu=False)
|
||||||
|
|
||||||
|
def test_init_no_umockdev(self):
|
||||||
|
self.app.dr_cfg.ubuntu_drivers_run_on_host_umockdev = None
|
||||||
|
ubuntu_drivers = UbuntuDriversRunDriversInterface(
|
||||||
|
self.app, gpgpu=False)
|
||||||
|
self.assertEqual(ubuntu_drivers.list_oem_cmd,
|
||||||
|
["ubuntu-drivers", "list-oem"])
|
||||||
|
self.assertEqual(ubuntu_drivers.list_drivers_cmd[0:2],
|
||||||
|
["ubuntu-drivers", "list"])
|
||||||
|
self.assertEqual(ubuntu_drivers.install_drivers_cmd[0:2],
|
||||||
|
["ubuntu-drivers", "install"])
|
||||||
|
|
||||||
|
def test_init_with_umockdev(self):
|
||||||
|
self.app.dr_cfg.ubuntu_drivers_run_on_host_umockdev = "/xps.yaml"
|
||||||
|
ubuntu_drivers = UbuntuDriversRunDriversInterface(
|
||||||
|
self.app, gpgpu=False)
|
||||||
|
self.assertEqual(ubuntu_drivers.list_oem_cmd,
|
||||||
|
["scripts/umockdev-wrapper.py",
|
||||||
|
"--config", "/xps.yaml", "--",
|
||||||
|
"ubuntu-drivers", "list-oem"])
|
||||||
|
self.assertEqual(ubuntu_drivers.list_drivers_cmd[0:6],
|
||||||
|
["scripts/umockdev-wrapper.py",
|
||||||
|
"--config", "/xps.yaml", "--",
|
||||||
|
"ubuntu-drivers", "list"])
|
||||||
|
self.assertEqual(ubuntu_drivers.install_drivers_cmd[0:6],
|
||||||
|
["scripts/umockdev-wrapper.py",
|
||||||
|
"--config", "/xps.yaml", "--",
|
||||||
|
"ubuntu-drivers", "install"])
|
||||||
|
|
||||||
@patch("subiquity.server.ubuntu_drivers.arun_command")
|
@patch("subiquity.server.ubuntu_drivers.arun_command")
|
||||||
async def test_ensure_cmd_exists(self, mock_arun_command):
|
async def test_ensure_cmd_exists(self, mock_arun_command):
|
||||||
await self.ubuntu_drivers.ensure_cmd_exists("/target")
|
await self.ubuntu_drivers.ensure_cmd_exists("/target")
|
||||||
|
|
|
@ -169,6 +169,28 @@ class UbuntuDriversNoDriversInterface(UbuntuDriversHasDriversInterface):
|
||||||
class UbuntuDriversRunDriversInterface(UbuntuDriversInterface):
|
class UbuntuDriversRunDriversInterface(UbuntuDriversInterface):
|
||||||
""" A dry-run implementation of ubuntu-drivers that actually runs the
|
""" A dry-run implementation of ubuntu-drivers that actually runs the
|
||||||
ubuntu-drivers command but locally. """
|
ubuntu-drivers command but locally. """
|
||||||
|
|
||||||
|
def __init__(self, app, gpgpu: bool) -> None:
|
||||||
|
super().__init__(app, gpgpu)
|
||||||
|
|
||||||
|
if app.dr_cfg.ubuntu_drivers_run_on_host_umockdev is None:
|
||||||
|
return
|
||||||
|
|
||||||
|
self.list_oem_cmd = [
|
||||||
|
"scripts/umockdev-wrapper.py",
|
||||||
|
"--config", app.dr_cfg.ubuntu_drivers_run_on_host_umockdev,
|
||||||
|
"--"] + self.list_oem_cmd
|
||||||
|
|
||||||
|
self.list_drivers_cmd = [
|
||||||
|
"scripts/umockdev-wrapper.py",
|
||||||
|
"--config", app.dr_cfg.ubuntu_drivers_run_on_host_umockdev,
|
||||||
|
"--"] + self.list_drivers_cmd
|
||||||
|
|
||||||
|
self.install_drivers_cmd = [
|
||||||
|
"scripts/umockdev-wrapper.py",
|
||||||
|
"--config", app.dr_cfg.ubuntu_drivers_run_on_host_umockdev,
|
||||||
|
"--"] + self.install_drivers_cmd
|
||||||
|
|
||||||
async def ensure_cmd_exists(self, root_dir: str) -> None:
|
async def ensure_cmd_exists(self, root_dir: str) -> None:
|
||||||
# TODO This does not tell us if the "--recommended" option is
|
# TODO This does not tell us if the "--recommended" option is
|
||||||
# available.
|
# available.
|
||||||
|
|
Loading…
Reference in New Issue