ubuntu-drivers: add method to list OEM meta-packages

The ubuntu_drivers.list_drivers() method currently returns names of
drivers + name of OEM meta-packages.

We now define a new method to be used for the OEM meta-packages only.

For now, the has-drivers, no-drivers, run-drivers debug flags affect the
presence of the OEM meta-packages as well. Going forward, we should
define dry-run directives controlling drivers & OEM independently.

Signed-off-by: Olivier Gayot <olivier.gayot@canonical.com>
This commit is contained in:
Olivier Gayot 2023-06-07 16:03:08 +02:00
parent 919ca5ebd4
commit e657b7e0e7
2 changed files with 59 additions and 0 deletions

View File

@ -135,6 +135,25 @@ nvidia-driver-510 linux-modules-nvidia-510-generic-hwe-20.04
self.assertEqual(drivers, ["nvidia-driver-510"])
@patch("subiquity.server.ubuntu_drivers.run_curtin_command")
async def test_list_oem(self, mock_run_curtin_command):
# Make sure this gets decoded as utf-8.
mock_run_curtin_command.return_value = Mock(stdout=b"""\
oem-somerville-tentacool-meta
""")
drivers = await self.ubuntu_drivers.list_oem(
root_dir="/target",
context="listing OEM meta-packages")
mock_run_curtin_command.assert_called_once_with(
self.app, "listing OEM meta-packages",
"in-target", "-t", "/target",
"--",
"ubuntu-drivers", "list-oem",
capture=True, private_mounts=True)
self.assertEqual(drivers, ["oem-somerville-tentacool-meta"])
class TestUbuntuDriversRunDriversInterface(unittest.IsolatedAsyncioTestCase):
def setUp(self):

View File

@ -37,6 +37,9 @@ class UbuntuDriversInterface(ABC):
def __init__(self, app, gpgpu: bool) -> None:
self.app = app
self.list_oem_cmd = [
"ubuntu-drivers", "list-oem",
]
self.list_drivers_cmd = [
"ubuntu-drivers", "list",
"--recommended",
@ -56,6 +59,10 @@ class UbuntuDriversInterface(ABC):
async def list_drivers(self, root_dir: str, context) -> List[str]:
pass
@abstractmethod
async def list_oem(self, root_dir: str, context) -> List[str]:
pass
async def install_drivers(self, root_dir: str, context) -> None:
await run_curtin_command(
self.app, context,
@ -78,6 +85,18 @@ class UbuntuDriversInterface(ABC):
return drivers
def _oem_metapackages_from_output(self, output: str) -> List[str]:
""" Parse the output of ubuntu-drivers list-oem and return a list of
packages. """
metapackages: List[str] = []
# Packages are listed one per line.
for line in [x.strip() for x in output.split("\n")]:
if not line:
continue
metapackages.append(line)
return metapackages
class UbuntuDriversClientInterface(UbuntuDriversInterface):
""" UbuntuDrivers interface that uses the ubuntu-drivers command from the
@ -105,12 +124,24 @@ class UbuntuDriversClientInterface(UbuntuDriversInterface):
# output.
return self._drivers_from_output(result.stdout.decode("utf-8"))
async def list_oem(self, root_dir: str, context) -> List[str]:
result = await run_curtin_command(
self.app, context,
"in-target", "-t", root_dir, "--", *self.list_oem_cmd,
capture=True, private_mounts=True)
# Currently we have no way to specify universal_newlines=True or
# encoding="utf-8" to run_curtin_command so we need to decode the
# output.
return self._oem_metapackages_from_output(
result.stdout.decode("utf-8"))
class UbuntuDriversHasDriversInterface(UbuntuDriversInterface):
""" A dry-run implementation of ubuntu-drivers that returns a hard-coded
list of drivers. """
gpgpu_drivers: List[str] = ["nvidia-driver-470-server"]
not_gpgpu_drivers: List[str] = ["nvidia-driver-510"]
oem_metapackages: List[str] = ["oem-somerville-tentacool-meta"]
def __init__(self, app, gpgpu: bool) -> None:
super().__init__(app, gpgpu)
@ -122,6 +153,9 @@ class UbuntuDriversHasDriversInterface(UbuntuDriversInterface):
async def list_drivers(self, root_dir: str, context) -> List[str]:
return self.drivers
async def list_oem(self, root_dir: str, context) -> List[str]:
return self.oem_metapackages
class UbuntuDriversNoDriversInterface(UbuntuDriversHasDriversInterface):
""" A dry-run implementation of ubuntu-drivers that returns a hard-coded
@ -129,6 +163,7 @@ class UbuntuDriversNoDriversInterface(UbuntuDriversHasDriversInterface):
gpgpu_drivers: List[str] = []
not_gpgpu_drivers: List[str] = []
oem_metapackages: List[str] = []
class UbuntuDriversRunDriversInterface(UbuntuDriversInterface):
@ -150,6 +185,11 @@ class UbuntuDriversRunDriversInterface(UbuntuDriversInterface):
result = await arun_command(self.list_drivers_cmd)
return self._drivers_from_output(result.stdout)
async def list_oem(self, root_dir: str, context) -> List[str]:
# We run the command locally - ignoring the root_dir.
result = await arun_command(self.list_oem_cmd)
return self._oem_metapackages_from_output(result.stdout)
def get_ubuntu_drivers_interface(app) -> UbuntuDriversInterface:
is_server = app.base_model.source.current.variant == "server"