merged with master
This commit is contained in:
commit
15d56c2bc7
|
|
@ -104,6 +104,10 @@ This installer will perform the following:
|
|||
|
||||
> **Creating your own ISO with this script on it:** Follow [ArchISO](https://wiki.archlinux.org/index.php/archiso)'s guide on how to create your own ISO or use a pre-built [guided ISO](https://hvornum.se/archiso/) to skip the python installation step, or to create auto-installing ISO templates. Further down are examples and cheat sheets on how to create different live ISO's.
|
||||
|
||||
## Unattended installation based on MAC address
|
||||
|
||||
Archinstall comes with a [unattended](examples/unattended.py) example which will look for a matching profile for the machine it is being run on, based on any local MAC address. For instance, if the machine that [unattended](examples/unattended.py) is run on has the MAC address `52:54:00:12:34:56` it will look for a profile called [profiles/52-54-00-12-34-56.py](profiles/52-54-00-12-34-56.py). If it's found, the unattended installation will commence and source that profile as it's installation proceedure.
|
||||
|
||||
# Help
|
||||
|
||||
Submit an issue on Github, or submit a post in the discord help channel.<br>
|
||||
|
|
|
|||
|
|
@ -70,7 +70,7 @@ class luks2():
|
|||
'--batch-mode',
|
||||
'--verbose',
|
||||
'--type', 'luks2',
|
||||
'--pbkdf', 'argon2i',
|
||||
'--pbkdf', 'argon2id',
|
||||
'--hash', hash_type,
|
||||
'--key-size', str(key_size),
|
||||
'--iter-time', str(iter_time),
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ def grab_url_data(path):
|
|||
response = urllib.request.urlopen(safe_path, context=ssl_context)
|
||||
return response.read()
|
||||
|
||||
def list_profiles(filter_irrelevant_macs=True, subpath=''):
|
||||
def list_profiles(filter_irrelevant_macs=True, subpath='', filter_top_level_profiles=False):
|
||||
# TODO: Grab from github page as well, not just local static files
|
||||
if filter_irrelevant_macs:
|
||||
local_macs = list_interfaces()
|
||||
|
|
@ -63,6 +63,11 @@ def list_profiles(filter_irrelevant_macs=True, subpath=''):
|
|||
|
||||
cache[profile[:-3]] = {'path' : os.path.join(storage["UPSTREAM_URL"]+subpath, profile), 'description' : profile_list[profile], 'tailored' : tailored}
|
||||
|
||||
if filter_top_level_profiles:
|
||||
for profile in list(cache.keys()):
|
||||
if Profile(None, profile).is_top_level_profile() is False:
|
||||
del(cache[profile])
|
||||
|
||||
return cache
|
||||
|
||||
class Script():
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import getpass, pathlib, os, shutil, re
|
||||
import sys, time, signal
|
||||
import sys, time, signal, ipaddress
|
||||
from .exceptions import *
|
||||
from .profiles import Profile
|
||||
from .locale_helpers import search_keyboard_layout
|
||||
|
|
@ -95,7 +95,7 @@ def print_large_list(options, padding=5, margin_bottom=0, separator=': '):
|
|||
print(f"{str(column): >{highest_index_number_length}}{separator}{options[column]}", end = spaces)
|
||||
print()
|
||||
|
||||
def ask_for_superuser_account(prompt='Create a required super-user with sudo privileges: ', forced=False):
|
||||
def ask_for_superuser_account(prompt='Username for required super-user with sudo privileges: ', forced=False):
|
||||
while 1:
|
||||
new_user = input(prompt).strip(' ')
|
||||
|
||||
|
|
@ -166,27 +166,56 @@ def ask_to_configure_network():
|
|||
# Optionally configure one network interface.
|
||||
#while 1:
|
||||
# {MAC: Ifname}
|
||||
interfaces = {'ISO-CONFIG' : 'Copy ISO network configuration to installation','NetworkManager':'Use NetworkManager to control and manage your internet connection', **list_interfaces()}
|
||||
interfaces = {
|
||||
'ISO-CONFIG' : 'Copy ISO network configuration to installation',
|
||||
'NetworkManager':'Use NetworkManager to control and manage your internet connection',
|
||||
**list_interfaces()
|
||||
}
|
||||
|
||||
nic = generic_select(interfaces.values(), "Select one network interface to configure (leave blank to skip): ")
|
||||
nic = generic_select(interfaces, "Select one network interface to configure (leave blank to skip): ")
|
||||
if nic and nic != 'Copy ISO network configuration to installation':
|
||||
if nic == 'Use NetworkManager to control and manage your internet connection':
|
||||
return {'nic': nic,'NetworkManager':True}
|
||||
mode = generic_select(['DHCP (auto detect)', 'IP (static)'], f"Select which mode to configure for {nic}: ")
|
||||
if mode == 'IP (static)':
|
||||
|
||||
# Current workaround:
|
||||
# For selecting modes without entering text within brackets,
|
||||
# printing out this part separate from options, passed in
|
||||
# `generic_select`
|
||||
modes = ['DHCP (auto detect)', 'IP (static)']
|
||||
for index, mode in enumerate(modes):
|
||||
print(f"{index}: {mode}")
|
||||
|
||||
mode = generic_select(['DHCP', 'IP'], f"Select which mode to configure for {nic} or leave blank for DHCP: ",
|
||||
options_output=False)
|
||||
if mode == 'IP':
|
||||
while 1:
|
||||
ip = input(f"Enter the IP and subnet for {nic} (example: 192.168.0.5/24): ").strip()
|
||||
if ip:
|
||||
# Implemented new check for correct IP/subnet input
|
||||
try:
|
||||
ipaddress.ip_interface(ip)
|
||||
break
|
||||
else:
|
||||
except ValueError:
|
||||
log(
|
||||
"You need to enter a valid IP in IP-config mode.",
|
||||
level=LOG_LEVELS.Warning,
|
||||
fg='red'
|
||||
)
|
||||
|
||||
if not len(gateway := input('Enter your gateway (router) IP address or leave blank for none: ').strip()):
|
||||
gateway = None
|
||||
# Implemented new check for correct gateway IP address
|
||||
while 1:
|
||||
gateway = input('Enter your gateway (router) IP address or leave blank for none: ').strip()
|
||||
try:
|
||||
if len(gateway) == 0:
|
||||
gateway = None
|
||||
else:
|
||||
ipaddress.ip_address(gateway)
|
||||
break
|
||||
except ValueError:
|
||||
log(
|
||||
"You need to enter a valid gateway (router) IP address.",
|
||||
level=LOG_LEVELS.Warning,
|
||||
fg='red'
|
||||
)
|
||||
|
||||
dns = None
|
||||
if len(dns_input := input('Enter your DNS servers (space separated, blank for none): ').strip()):
|
||||
|
|
@ -202,12 +231,13 @@ def ask_to_configure_network():
|
|||
|
||||
def ask_for_disk_layout():
|
||||
options = {
|
||||
'keep-existing' : 'Keep existing partition layout and select which ones to use where.',
|
||||
'format-all' : 'Format entire drive and setup a basic partition scheme.',
|
||||
'abort' : 'Abort the installation.'
|
||||
'keep-existing' : 'Keep existing partition layout and select which ones to use where',
|
||||
'format-all' : 'Format entire drive and setup a basic partition scheme',
|
||||
'abort' : 'Abort the installation'
|
||||
}
|
||||
|
||||
value = generic_select(options.values(), "Found partitions on the selected drive, (select by number) what you want to do: ")
|
||||
value = generic_select(options, "Found partitions on the selected drive, (select by number) what you want to do: ",
|
||||
allow_empty_input=False, sort=True)
|
||||
return next((key for key, val in options.items() if val == value), None)
|
||||
|
||||
def ask_for_main_filesystem_format():
|
||||
|
|
@ -218,40 +248,72 @@ def ask_for_main_filesystem_format():
|
|||
'f2fs' : 'f2fs'
|
||||
}
|
||||
|
||||
value = generic_select(options.values(), "Select which filesystem your main partition should use (by number or name): ")
|
||||
value = generic_select(options, "Select which filesystem your main partition should use (by number or name): ",
|
||||
allow_empty_input=False)
|
||||
return next((key for key, val in options.items() if val == value), None)
|
||||
|
||||
def generic_select(options, input_text="Select one of the above by index or absolute value: ", sort=True):
|
||||
def generic_select(options, input_text="Select one of the above by index or absolute value: ", allow_empty_input=True, options_output=True, sort=False):
|
||||
"""
|
||||
A generic select function that does not output anything
|
||||
other than the options and their indexes. As an example:
|
||||
|
||||
generic_select(["first", "second", "third option"])
|
||||
1: first
|
||||
2: second
|
||||
3: third option
|
||||
0: first
|
||||
1: second
|
||||
2: third option
|
||||
|
||||
When the user has entered the option correctly,
|
||||
this function returns an item from list, a string, or None
|
||||
"""
|
||||
|
||||
if type(options) == dict: options = list(options)
|
||||
if sort: options = sorted(list(options))
|
||||
if len(options) <= 0: raise RequirementError('generic_select() requires at least one option to operate.')
|
||||
|
||||
for index, option in enumerate(options):
|
||||
print(f"{index}: {option}")
|
||||
|
||||
selected_option = input(input_text)
|
||||
if len(selected_option.strip()) <= 0:
|
||||
return None
|
||||
elif selected_option.isdigit():
|
||||
selected_option = int(selected_option)
|
||||
if selected_option > len(options):
|
||||
raise RequirementError(f'Selected option "{selected_option}" is out of range')
|
||||
selected_option = options[selected_option]
|
||||
elif selected_option in options:
|
||||
pass # We gave a correct absolute value
|
||||
else:
|
||||
raise RequirementError(f'Selected option "{selected_option}" does not exist in available options: {options}')
|
||||
# Checking if options are different from `list` or `dict`
|
||||
if type(options) not in [list, dict]:
|
||||
log(f" * Generic select doesn't support ({type(options)}) as type of options * ", fg='red')
|
||||
log(" * If problem persists, please create an issue on https://github.com/archlinux/archinstall/issues * ", fg='yellow')
|
||||
raise RequirementError("generic_select() requires list or dictionary as options.")
|
||||
# To allow only `list` and `dict`, converting values of options here.
|
||||
# Therefore, now we can only provide the dictionary itself
|
||||
if type(options) == dict: options = list(options.values())
|
||||
if sort: options = sorted(options) # As we pass only list and dict (converted to list), we can skip converting to list
|
||||
if len(options) == 0:
|
||||
log(f" * Generic select didn't find any options to choose from * ", fg='red')
|
||||
log(" * If problem persists, please create an issue on https://github.com/archlinux/archinstall/issues * ", fg='yellow')
|
||||
raise RequirementError('generic_select() requires at least one option to proceed.')
|
||||
|
||||
|
||||
# Added ability to disable the output of options items,
|
||||
# if another function displays something different from this
|
||||
if options_output:
|
||||
for index, option in enumerate(options):
|
||||
print(f"{index}: {option}")
|
||||
|
||||
# The new changes introduce a single while loop for all inputs processed by this function
|
||||
# Now the try...except...else block handles validation for invalid input from the user
|
||||
while True:
|
||||
try:
|
||||
selected_option = input(input_text)
|
||||
if len(selected_option.strip()) == 0:
|
||||
# `allow_empty_input` parameter handles return of None on empty input, if necessary
|
||||
# Otherwise raise `RequirementError`
|
||||
if allow_empty_input:
|
||||
return None
|
||||
raise RequirementError('Please select an option to continue')
|
||||
# Replaced `isdigit` with` isnumeric` to discard all negative numbers
|
||||
elif selected_option.isnumeric():
|
||||
selected_option = int(selected_option)
|
||||
if selected_option >= len(options):
|
||||
raise RequirementError(f'Selected option "{selected_option}" is out of range')
|
||||
selected_option = options[selected_option]
|
||||
elif selected_option in options:
|
||||
break # We gave a correct absolute value
|
||||
else:
|
||||
raise RequirementError(f'Selected option "{selected_option}" does not exist in available options')
|
||||
except RequirementError as err:
|
||||
log(f" * {err} * ", fg='red')
|
||||
continue
|
||||
else:
|
||||
break
|
||||
|
||||
return selected_option
|
||||
|
||||
def select_disk(dict_o_disks):
|
||||
|
|
@ -269,18 +331,11 @@ def select_disk(dict_o_disks):
|
|||
if len(drives) >= 1:
|
||||
for index, drive in enumerate(drives):
|
||||
print(f"{index}: {drive} ({dict_o_disks[drive]['size'], dict_o_disks[drive].device, dict_o_disks[drive]['label']})")
|
||||
drive = input('Select one of the above disks (by number or full path) or write /mnt to skip partitioning: ')
|
||||
if drive.strip() == '/mnt':
|
||||
return None
|
||||
elif drive.isdigit():
|
||||
drive = int(drive)
|
||||
if drive >= len(drives):
|
||||
raise DiskError(f'Selected option "{drive}" is out of range')
|
||||
drive = dict_o_disks[drives[drive]]
|
||||
elif drive in dict_o_disks:
|
||||
drive = dict_o_disks[drive]
|
||||
else:
|
||||
raise DiskError(f'Selected drive does not exist: "{drive}"')
|
||||
drive = generic_select(drives, 'Select one of the above disks (by number or full path) or leave blank to skip partitioning: ',
|
||||
options_output=False)
|
||||
if not drive:
|
||||
return drive
|
||||
drive = dict_o_disks[drive]
|
||||
return drive
|
||||
|
||||
raise DiskError('select_disk() requires a non-empty dictionary of disks to select from.')
|
||||
|
|
@ -305,33 +360,22 @@ def select_profile(options):
|
|||
print(' -- The above list is a set of pre-programmed profiles. --')
|
||||
print(' -- They might make it easier to install things like desktop environments. --')
|
||||
print(' -- (Leave blank and hit enter to skip this step and continue) --')
|
||||
selected_profile = input('Enter a pre-programmed profile name if you want to install one: ')
|
||||
|
||||
if len(selected_profile.strip()) <= 0:
|
||||
return None
|
||||
|
||||
if selected_profile.isdigit() and (pos := int(selected_profile)) <= len(profiles)-1:
|
||||
selected_profile = profiles[pos]
|
||||
elif selected_profile in options:
|
||||
selected_profile = options[options.index(selected_profile)]
|
||||
else:
|
||||
RequirementError("Selected profile does not exist.")
|
||||
|
||||
return Profile(None, selected_profile)
|
||||
|
||||
raise RequirementError("Selecting profiles require a least one profile to be given as an option.")
|
||||
selected_profile = generic_select(profiles, 'Enter a pre-programmed profile name if you want to install one: ',
|
||||
options_output=False)
|
||||
if selected_profile:
|
||||
return Profile(None, selected_profile)
|
||||
else:
|
||||
raise RequirementError("Selecting profiles require a least one profile to be given as an option.")
|
||||
|
||||
def select_language(options, show_only_country_codes=True):
|
||||
"""
|
||||
Asks the user to select a language from the `options` dictionary parameter.
|
||||
Usually this is combined with :ref:`archinstall.list_keyboard_languages`.
|
||||
|
||||
:param options: A `dict` where keys are the language name, value should be a dict containing language information.
|
||||
:type options: dict
|
||||
|
||||
:param show_only_country_codes: Filters out languages that are not len(lang) == 2. This to limit the number of results from stuff like dvorak and x-latin1 alternatives.
|
||||
:type show_only_country_codes: bool
|
||||
|
||||
:return: The language/dictionary key of the selected language
|
||||
:rtype: str
|
||||
"""
|
||||
|
|
@ -346,37 +390,31 @@ def select_language(options, show_only_country_codes=True):
|
|||
for index, language in enumerate(languages):
|
||||
print(f"{index}: {language}")
|
||||
|
||||
print(' -- You can enter ? or help to search for more languages, or skip to use US layout --')
|
||||
selected_language = input('Select one of the above keyboard languages (by number or full name): ')
|
||||
|
||||
if len(selected_language.strip()) == 0:
|
||||
return DEFAULT_KEYBOARD_LANGUAGE
|
||||
elif selected_language.lower() in ('?', 'help'):
|
||||
while True:
|
||||
filter_string = input('Search for layout containing (example: "sv-"): ')
|
||||
new_options = list(search_keyboard_layout(filter_string))
|
||||
print(" -- You can choose a layout that isn't in this list, but whose name you know --")
|
||||
print(" -- Also, you can enter '?' or 'help' to search for more languages, or skip to use US layout --")
|
||||
|
||||
if len(new_options) <= 0:
|
||||
log(f"Search string '{filter_string}' yielded no results, please try another search or Ctrl+D to abort.", fg='yellow')
|
||||
while True:
|
||||
selected_language = input('Select one of the above keyboard languages (by name or full name): ')
|
||||
if not selected_language:
|
||||
return DEFAULT_KEYBOARD_LANGUAGE
|
||||
elif selected_language.lower() in ('?', 'help'):
|
||||
while True:
|
||||
filter_string = input('Search for layout containing (example: "sv-"): ')
|
||||
new_options = list(search_keyboard_layout(filter_string))
|
||||
if len(new_options) <= 0:
|
||||
log(f"Search string '{filter_string}' yielded no results, please try another search or Ctrl+D to abort.", fg='yellow')
|
||||
continue
|
||||
return select_language(new_options, show_only_country_codes=False)
|
||||
elif selected_language.isnumeric():
|
||||
selected_language = int(selected_language)
|
||||
if selected_language >= len(languages):
|
||||
log(' * Selected option is out of range * ', fg='red')
|
||||
continue
|
||||
|
||||
return select_language(new_options, show_only_country_codes=False)
|
||||
|
||||
elif selected_language.isdigit() and (pos := int(selected_language)) <= len(languages)-1:
|
||||
selected_language = languages[pos]
|
||||
return selected_language
|
||||
# I'm leaving "options" on purpose here.
|
||||
# Since languages possibly contains a filtered version of
|
||||
# all possible language layouts, and we might want to write
|
||||
# for instance sv-latin1 (if we know that exists) without having to
|
||||
# go through the search step.
|
||||
elif selected_language in options:
|
||||
selected_language = options[options.index(selected_language)]
|
||||
return selected_language
|
||||
else:
|
||||
raise RequirementError("Selected language does not exist.")
|
||||
|
||||
raise RequirementError("Selecting languages require a least one language to be given as an option.")
|
||||
return languages[selected_language]
|
||||
elif search_keyboard_layout(selected_language):
|
||||
return selected_language
|
||||
else:
|
||||
log(" * Given language wasn't found * ", fg='red')
|
||||
|
||||
def select_mirror_regions(mirrors, show_top_mirrors=True):
|
||||
"""
|
||||
|
|
@ -401,25 +439,20 @@ def select_mirror_regions(mirrors, show_top_mirrors=True):
|
|||
print_large_list(regions, margin_bottom=4)
|
||||
|
||||
print(' -- You can skip this step by leaving the option blank --')
|
||||
selected_mirror = input('Select one of the above regions to download packages from (by number or full name): ')
|
||||
if len(selected_mirror.strip()) == 0:
|
||||
selected_mirror = generic_select(regions, 'Select one of the above regions to download packages from (by number or full name): ',
|
||||
options_output=False)
|
||||
if not selected_mirror:
|
||||
# Returning back empty options which can be both used to
|
||||
# do "if x:" logic as well as do `x.get('mirror', {}).get('sub', None)` chaining
|
||||
return {}
|
||||
|
||||
elif selected_mirror.isdigit() and int(selected_mirror) <= len(regions)-1:
|
||||
# I'm leaving "mirrors" on purpose here.
|
||||
# Since region possibly contains a known region of
|
||||
# all possible regions, and we might want to write
|
||||
# for instance Sweden (if we know that exists) without having to
|
||||
# go through the search step.
|
||||
region = regions[int(selected_mirror)]
|
||||
selected_mirrors[region] = mirrors[region]
|
||||
elif selected_mirror in mirrors:
|
||||
selected_mirrors[selected_mirror] = mirrors[selected_mirror]
|
||||
else:
|
||||
raise RequirementError("Selected region does not exist.")
|
||||
# I'm leaving "mirrors" on purpose here.
|
||||
# Since region possibly contains a known region of
|
||||
# all possible regions, and we might want to write
|
||||
# for instance Sweden (if we know that exists) without having to
|
||||
# go through the search step.
|
||||
|
||||
selected_mirrors[selected_mirror] = mirrors[selected_mirror]
|
||||
return selected_mirrors
|
||||
|
||||
raise RequirementError("Selecting mirror region require a least one region to be given as an option.")
|
||||
|
|
|
|||
|
|
@ -77,7 +77,9 @@ def ask_user_questions():
|
|||
archinstall.log(f" ** The root would be a simple / and the boot partition /boot (as all paths are relative inside the installation). **")
|
||||
while True:
|
||||
# Select a partition
|
||||
partition = archinstall.generic_select(partition_mountpoints.keys(),
|
||||
# If we provide keys as options, it's better to convert them to list and sort before passing
|
||||
mountpoints_list = sorted(list(partition_mountpoints.keys()))
|
||||
partition = archinstall.generic_select(mountpoints_list,
|
||||
"Select a partition by number that you want to set a mount-point for (leave blank when done): ")
|
||||
if not partition:
|
||||
break
|
||||
|
|
@ -107,7 +109,7 @@ def ask_user_questions():
|
|||
# we have to check if we support it. We can do this by formatting /dev/null with the partitions filesystem.
|
||||
# There's a nice wrapper for this on the partition object itself that supports a path-override during .format()
|
||||
try:
|
||||
partition.format(new_filesystem, path='/dev/null', log_formating=False, allow_formatting=True)
|
||||
partition.format(new_filesystem, path='/dev/null', log_formatting=False, allow_formatting=True)
|
||||
except archinstall.UnknownFilesystemFormat:
|
||||
archinstall.log(f"Selected filesystem is not supported yet. If you want archinstall to support '{new_filesystem}', please create a issue-ticket suggesting it on github at https://github.com/archlinux/archinstall/issues.")
|
||||
archinstall.log(f"Until then, please enter another supported filesystem.")
|
||||
|
|
@ -163,7 +165,7 @@ def ask_user_questions():
|
|||
|
||||
# Ask for archinstall-specific profiles (such as desktop environments etc)
|
||||
if not archinstall.arguments.get('profile', None):
|
||||
archinstall.arguments['profile'] = archinstall.select_profile(filter(lambda profile: (Profile(None, profile).is_top_level_profile()), archinstall.list_profiles()))
|
||||
archinstall.arguments['profile'] = archinstall.select_profile(archinstall.list_profiles(filter_top_level_profiles=True))
|
||||
else:
|
||||
archinstall.arguments['profile'] = archinstall.list_profiles()[archinstall.arguments['profile']]
|
||||
|
||||
|
|
|
|||
|
|
@ -16,8 +16,9 @@ def _prep_function(*args, **kwargs):
|
|||
for more input before any other installer steps start.
|
||||
"""
|
||||
|
||||
supported_desktops = ['gnome', 'kde', 'awesome', 'sway', 'cinnamon', 'xfce4', 'lxqt', 'i3', 'budgie', 'mate', 'deepin']
|
||||
desktop = archinstall.generic_select(supported_desktops, 'Select your desired desktop environment: ')
|
||||
supported_desktops = ['gnome', 'kde', 'awesome', 'sway', 'cinnamon', 'xfce4', 'lxqt', 'i3', 'budgie', 'mate']
|
||||
desktop = archinstall.generic_select(supported_desktops, 'Select your desired desktop environment: ',
|
||||
allow_empty_input=False, sort=True)
|
||||
|
||||
# Temporarily store the selected desktop profile
|
||||
# in a session-safe location, since this module will get reloaded
|
||||
|
|
|
|||
|
|
@ -17,7 +17,8 @@ def _prep_function(*args, **kwargs):
|
|||
"""
|
||||
|
||||
supported_configurations = ['i3-wm', 'i3-gaps']
|
||||
desktop = archinstall.generic_select(supported_configurations, 'Select your desired configuration: ')
|
||||
desktop = archinstall.generic_select(supported_configurations, 'Select your desired configuration: ',
|
||||
allow_empty_input=False, sort=True)
|
||||
|
||||
# Temporarily store the selected desktop profile
|
||||
# in a session-safe location, since this module will get reloaded
|
||||
|
|
|
|||
|
|
@ -1,9 +1,80 @@
|
|||
# A system with "xorg" installed
|
||||
|
||||
import archinstall, os
|
||||
import os
|
||||
from archinstall import generic_select, sys_command, RequirementError
|
||||
|
||||
is_top_level_profile = True
|
||||
|
||||
AVAILABLE_DRIVERS = {
|
||||
# Sub-dicts are layer-2 options to be selected
|
||||
# and lists are a list of packages to be installed
|
||||
'AMD / ATI' : {
|
||||
'amd' : ['xf86-video-amdgpu'],
|
||||
'ati' : ['xf86-video-ati']
|
||||
},
|
||||
'intel' : ['xf86-video-intel'],
|
||||
'nvidia' : {
|
||||
'open source' : ['xf86-video-nouveau'],
|
||||
'proprietary' : ['nvidia']
|
||||
},
|
||||
'mesa' : ['mesa'],
|
||||
'fbdev' : ['xf86-video-fbdev'],
|
||||
'vesa' : ['xf86-video-vesa'],
|
||||
'vmware' : ['xf86-video-vmware']
|
||||
}
|
||||
|
||||
def select_driver(options):
|
||||
"""
|
||||
Some what convoluted function, which's job is simple.
|
||||
Select a graphics driver from a pre-defined set of popular options.
|
||||
|
||||
(The template xorg is for beginner users, not advanced, and should
|
||||
there for appeal to the general public first and edge cases later)
|
||||
"""
|
||||
drivers = sorted(list(options))
|
||||
|
||||
if len(drivers) >= 1:
|
||||
for index, driver in enumerate(drivers):
|
||||
print(f"{index}: {driver}")
|
||||
|
||||
print(' -- The above list are supported graphic card drivers. --')
|
||||
print(' -- You need to select (and read about) which one you need. --')
|
||||
|
||||
lspci = sys_command(f'/usr/bin/lspci')
|
||||
for line in lspci.trace_log.split(b'\r\n'):
|
||||
if b' vga ' in line.lower():
|
||||
if b'nvidia' in line.lower():
|
||||
print(' ** nvidia card detected, suggested driver: nvidia **')
|
||||
elif b'amd' in line.lower():
|
||||
print(' ** AMD card detected, suggested driver: AMD / ATI **')
|
||||
|
||||
selected_driver = generic_select(drivers, 'Select your graphics card driver: ',
|
||||
allow_empty_input=False, options_output=False)
|
||||
initial_option = selected_driver
|
||||
|
||||
# Disabled search for now, only a few profiles exist anyway
|
||||
#
|
||||
#print(' -- You can enter ? or help to search for more drivers --')
|
||||
#if selected_driver.lower() in ('?', 'help'):
|
||||
# filter_string = input('Search for layout containing (example: "sv-"): ')
|
||||
# new_options = search_keyboard_layout(filter_string)
|
||||
# return select_language(new_options)
|
||||
|
||||
selected_driver = options[selected_driver]
|
||||
|
||||
if type(selected_driver) == dict:
|
||||
driver_options = sorted(list(selected_driver))
|
||||
|
||||
driver_package_group = generic_select(driver_options, f'Which driver-type do you want for {initial_option}: ',
|
||||
allow_empty_input=False)
|
||||
driver_package_group = selected_driver[driver_package_group]
|
||||
|
||||
return driver_package_group
|
||||
|
||||
return selected_driver
|
||||
|
||||
raise RequirementError("Selecting drivers require a least one profile to be given as an option.")
|
||||
|
||||
def _prep_function(*args, **kwargs):
|
||||
"""
|
||||
Magic function called by the importing installer
|
||||
|
|
|
|||
Loading…
Reference in New Issue