diff --git a/UbuntuDrivers/detect.py b/UbuntuDrivers/detect.py index 4909ef1..aee0731 100644 --- a/UbuntuDrivers/detect.py +++ b/UbuntuDrivers/detect.py @@ -19,6 +19,7 @@ import apt_pkg from UbuntuDrivers import kerneldetection +from functools import cmp_to_key system_architecture = '' lookup_cache = {} @@ -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 @@ -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']: @@ -1048,6 +1053,9 @@ 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) @@ -1055,6 +1063,8 @@ def get_desktop_package_list(apt_cache, sys_path=None, free_only=False, include_ # 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 @@ -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 = {} @@ -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 @@ -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 diff --git a/ubuntu-drivers b/ubuntu-drivers index 38a3a35..eb06941 100755 --- a/ubuntu-drivers +++ b/ubuntu-drivers @@ -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) @@ -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.') @@ -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.') @@ -396,6 +410,7 @@ 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]]]''' @@ -403,6 +418,10 @@ def install(config, **kwargs): 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') @@ -436,6 +455,9 @@ 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() @@ -443,11 +465,13 @@ def autoinstall(config, **kwargs): @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) @@ -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: