Skip to content

Commit

Permalink
Add --include-dkms option to listing drivers
Browse files Browse the repository at this point in the history
(LP: #2090924)

Signed-off-by: Kuba Pawlak <[email protected]>
  • Loading branch information
ktpawlak committed Dec 4, 2024
1 parent 68f773f commit c6311b9
Show file tree
Hide file tree
Showing 2 changed files with 68 additions and 31 deletions.
32 changes: 24 additions & 8 deletions UbuntuDrivers/detect.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
import apt_pkg

from UbuntuDrivers import kerneldetection
from functools import cmp_to_key

system_architecture = ''
lookup_cache = {}
Expand Down Expand Up @@ -1010,12 +1011,14 @@ def system_device_drivers(apt_cache=None, sys_path=None, freeonly=False):
return result


def get_desktop_package_list(apt_cache, sys_path=None, free_only=False, include_oem=True, driver_string=''):
def get_desktop_package_list(
apt_cache, sys_path=None, free_only=False, include_oem=True,
driver_string='', include_dkms=False, recommended=False):
'''Return the list of packages that should be installed'''
packages = system_driver_packages(
apt_cache, sys_path, freeonly=free_only,
include_oem=include_oem)
packages = auto_install_filter(packages, driver_string)
packages = auto_install_filter(packages, driver_string, get_recommended=False)
if not packages:
logging.debug('No drivers found for installation.')
return packages
Expand All @@ -1025,13 +1028,15 @@ def get_desktop_package_list(apt_cache, sys_path=None, free_only=False, include_

# ignore packages which are already installed
to_install = []
for p in packages:
for p, _ in sorted(packages.items(),
key=cmp_to_key(lambda left, right: _cmp_gfx_alternatives(left[0], right[0])),
reverse=True):
package_obj = apt_cache[p]
if not package_obj.current_ver:
to_install.append(p)

candidate = depcache.get_candidate_ver(package_obj)
records.lookup(candidate.file_list[0])
to_install.append(p)

# See if runtimepm is supported
if records['runtimepm']:
Expand All @@ -1048,13 +1053,18 @@ def get_desktop_package_list(apt_cache, sys_path=None, free_only=False, include_
try:
modules_package = get_linux_modules_metapackage(apt_cache, p)
if modules_package and not apt_cache[modules_package].current_ver:
if not include_dkms and "dkms" in modules_package:
continue
to_install.remove(p)
to_install.append(modules_package)

lrm_meta = get_userspace_lrm_meta(apt_cache, p)
if lrm_meta and not apt_cache[lrm_meta].current_ver:
# Add the lrm meta and drop the non lrm one
to_install.append(lrm_meta)
to_install.remove(p)
if recommended:
break;
except KeyError:
pass

Expand Down Expand Up @@ -1125,7 +1135,7 @@ def _process_driver_string(string):
return driver


def gpgpu_install_filter(packages, drivers_str):
def gpgpu_install_filter(packages, drivers_str, get_recommended=True):
drivers = []
allow = []
result = {}
Expand Down Expand Up @@ -1218,14 +1228,17 @@ def gpgpu_install_filter(packages, drivers_str):
result[p] = packages[p]
else:
# print('before recommended: %s' % packages[p])
if packages[p].get('recommended'):
if get_recommended:
if packages[p].get('recommended'):
result[p] = packages[p]
else:
result[p] = packages[p]
# print('Found "recommended" flavour in %s' % (packages[p]))
break
return result


def auto_install_filter(packages, drivers_str=''):
def auto_install_filter(packages, drivers_str='', get_recommended=True):
'''Get packages which are appropriate for automatic installation.
Return the subset of the given list of packages which are appropriate for
Expand All @@ -1249,7 +1262,10 @@ def auto_install_filter(packages, drivers_str=''):

result = {}
for p in allow:
if 'recommended' not in packages[p] or packages[p]['recommended']:
if get_recommended:
if 'recommended' not in packages[p] or packages[p]['recommended']:
result[p] = packages[p]
else:
result[p] = packages[p]
return result

Expand Down
67 changes: 44 additions & 23 deletions ubuntu-drivers
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,8 @@ class Config(object):
self.package_list = ''
self.install_oem_meta = True
self.driver_string = ''
self.include_dkms = False
self.recommended = False

pass_config = click.make_pass_decorator(Config, ensure=True)

Expand Down Expand Up @@ -173,7 +175,8 @@ def command_install(args):

to_install = UbuntuDrivers.detect.get_desktop_package_list(cache, sys_path,
free_only=args.free_only, include_oem=args.install_oem_meta,
driver_string=args.driver_string)
driver_string=args.driver_string, include_dkms=args.include_dkms,
recommended=args.recommended)

if not to_install:
print('All the available drivers are already installed.')
Expand Down Expand Up @@ -258,31 +261,42 @@ def install_gpgpu(args):
return 1

packages = UbuntuDrivers.detect.system_gpgpu_driver_packages(cache, sys_path)
packages = UbuntuDrivers.detect.gpgpu_install_filter(packages, args.driver_string)
packages = UbuntuDrivers.detect.gpgpu_install_filter(packages, args.driver_string, get_recommended=False)
if not packages:
print('No drivers found for installation.')
return not_found_exit_status

# ignore packages which are already installed
to_install = []
for p in packages:
for p, _ in sorted(packages.items(),
key=cmp_to_key(lambda left, right:
UbuntuDrivers.detect._cmp_gfx_alternatives_gpgpu(left[0], right[0])),
reverse=True):
candidate = packages[p].get('metapackage')
print(candidate)
if candidate and not cache[candidate].current_ver:
to_install.append(candidate)
print(candidate)

if candidate:
# Add the matching linux modules package
modules_package = UbuntuDrivers.detect.get_linux_modules_metapackage(cache, candidate)
print(modules_package)
if modules_package and not cache[modules_package].current_ver:
to_install.append(modules_package)

lrm_meta = UbuntuDrivers.detect.get_userspace_lrm_meta(cache, p)
if lrm_meta and not apt_cache[lrm_meta].current_ver:
# Add the lrm meta and drop the non lrm one
to_install.append(lrm_meta)
to_install.remove(p)
if candidate:
# Add the matching linux modules package
modules_package = UbuntuDrivers.detect.get_linux_modules_metapackage(cache, candidate)
print(modules_package)
if modules_package and not cache[modules_package].current_ver:
if not args.include_dkms and "dkms" in modules_package:
print('selected driver is DKMS only but \"--include-dkms\" was not supplied, aborting.')
return 0

to_install.append(p)
to_install.append(modules_package)

lrm_meta = UbuntuDrivers.detect.get_userspace_lrm_meta(cache, p)
if lrm_meta and not cache[lrm_meta].current_ver:
# Add the lrm meta and drop the non lrm one
to_install.append(lrm_meta)
to_install.remove(p)

if args.recommended:
break

if not to_install:
print('All the available drivers are already installed.')
Expand Down Expand Up @@ -396,13 +410,18 @@ def greet(config, gpgpu, free_only, package_list, no_oem, **kwargs):
@click.option('--free-only', is_flag=True, help='Only consider free packages')
@click.option('--package-list', nargs=1, metavar='PATH', help='Create file with list of installed packages (in install mode)')
@click.option('--no-oem', is_flag=True, metavar='install_oem_meta', help='Do not include OEM enablement packages (these enable an external archive)')
@click.option('--include-dkms', is_flag=True, help='Also consider DKMS packages')
@pass_config
def install(config, **kwargs):
'''Install a driver [driver[:version][,driver[:version]]]'''
if kwargs.get('gpgpu'):
config.gpgpu = True
if kwargs.get('free_only'):
config.free_only = True
if kwargs.get("include_dkms"):
config.include_dkms = True
if kwargs.get("recommended"):
config.recommended = True

# if kwargs.get('package_list'):
# config.package_list = kwargs.get('package_list')
Expand Down Expand Up @@ -436,18 +455,23 @@ def autoinstall(config, **kwargs):
if kwargs.get('driver'):
config.driver_string = ''.join(kwargs.get('driver'))

if kwargs.get("recommended"):
config.recommended = True

command_install(config)

@greet.command()
@click.argument('list', nargs=-1)
@click.option('--gpgpu', is_flag=True, help='Install drivers for use in a headless (aka General Purpose GPU) environment. This results in a smaller installation footprint by not installing packages that are only useful in graphical environments.')
@click.option('--recommended', is_flag=True, help='Only show the recommended driver packages')
@click.option('--free-only', is_flag=True, help='Only consider free packages')
@click.option('--include-dkms', is_flag=True, help='Also consider DKMS packages')
@pass_config
def list(config, **kwargs):
'''Show all driver packages which apply to the current system.'''
apt_pkg.init_config()
apt_pkg.init_system()
include_dkms = kwargs.get("include_dkms")

try:
cache = apt_pkg.Cache(None)
Expand All @@ -463,23 +487,20 @@ def list(config, **kwargs):
sys_path=sys_path, freeonly=config.free_only, include_oem=config.install_oem_meta)
sort_func = UbuntuDrivers.detect._cmp_gfx_alternatives

if kwargs.get('recommended'):
if kwargs.get('gpgpu'):
packages = UbuntuDrivers.detect.gpgpu_install_filter(packages, '')
else:
packages = UbuntuDrivers.detect.auto_install_filter(packages, '')

for package, info in sorted(packages.items(), key=cmp_to_key(lambda left, right: sort_func(left[0], right[0])), reverse=True):
try:
linux_modules = UbuntuDrivers.detect.get_linux_modules_metapackage(cache, package)
if (not linux_modules and package.find('dkms') != -1):
if (not linux_modules and "dkms" in package and include_dkms):
linux_modules = package

if linux_modules:
if not include_dkms and "dkms" in linux_modules:
continue
if kwargs.get('recommended'):
# This is just a space separated two item line
# Such as "nvidia-headless-no-dkms-470-server linux-modules-nvidia-470-server-generic"
print('%s %s' % (package, linux_modules))
break
else:
print('%s, (kernel modules provided by %s)' % (package, linux_modules))
else:
Expand Down

0 comments on commit c6311b9

Please sign in to comment.