enhacements to the menu infraestructure (#978)

* Correct definition of btrfs standard layout

* Solve issue #936

* make ask_for_a_timezone as synonym to ask_timezone

* Some refining in GeneralMenu
secret is now a general function

* Revert "Some refining in GeneralMenu"

This reverts commit e6e131cb19.

* Activate load of preset values in GeneralMenu
Changed all select_functions definitions to the need of passing the preset value
Corrected problems at ask_to_configure_network, and management of preset values added

* minor glitches in menu processing, plus flake8 complains

* Changes to ask_to_configure_network following  @svartkanin code

* select_language adapted to preset value.
changes to the infraestructure to solve bugs

* functions adapted for preset values
* select_mirror_regions
* select_locale_lang
* select_locale_enc
* ask_for_swap

* Updated to preset values
* ask_for_bootloader
Won't use it
* set_root_password()

* Updated to preset values
* ask_for_audio_selection
* select_kernel
* ask_for_a_timezone

* Updated to use preset values
* select_ntp
* ask_ntp
* ask_for_swap
flake8 complains

* Adapted to preset values
* ask_additional_packages_to_install (from svartkanin)
* ask_to_configure_network (adapted from svartkanin version)

* Updated to preset values
* ask_hostname
* select_additional_repositories

* bug in nic conversion
_select_harddrives adapted to preset_menu
This commit is contained in:
Werner Llácer 2022-02-28 15:02:39 +01:00 committed by GitHub
parent 391699497d
commit f06aabb4d4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 141 additions and 77 deletions

View File

@ -204,7 +204,7 @@ def load_config():
if arguments.get('servers', None) is not None: if arguments.get('servers', None) is not None:
storage['_selected_servers'] = arguments.get('servers', None) storage['_selected_servers'] = arguments.get('servers', None)
if nic_config := arguments.get('nic', {}): if nic_config := arguments.get('nic', {}):
if nic_config.get('nic', '') == 'Copy ISO network configuration to installation': if isinstance(nic_config,str) or nic_config.get('nic', '') == 'Copy ISO network configuration to installation':
arguments['nic'] = {'type': 'iso_config'} arguments['nic'] = {'type': 'iso_config'}
elif 'NetworkManager' in nic_config: elif 'NetworkManager' in nic_config:
arguments['nic'] = {'type': 'network_manager', 'NetworkManager': True} arguments['nic'] = {'type': 'network_manager', 'NetworkManager': True}

View File

@ -84,8 +84,6 @@ class Menu(TerminalMenu):
self.skip = skip self.skip = skip
self.default_option = default_option self.default_option = default_option
self.multi = multi self.multi = multi
self.preselection(preset_values,cursor_index)
menu_title = f'\n{title}\n\n' menu_title = f'\n{title}\n\n'
if skip: if skip:
@ -97,6 +95,7 @@ class Menu(TerminalMenu):
default = f'{default_option} (default)' default = f'{default_option} (default)'
self.menu_options = [default] + [o for o in self.menu_options if default_option != o] self.menu_options = [default] + [o for o in self.menu_options if default_option != o]
self.preselection(preset_values,cursor_index)
cursor = "> " cursor = "> "
main_menu_cursor_style = ("fg_cyan", "bold") main_menu_cursor_style = ("fg_cyan", "bold")
main_menu_style = ("bg_blue", "fg_gray") main_menu_style = ("bg_blue", "fg_gray")
@ -154,22 +153,28 @@ class Menu(TerminalMenu):
def preselection(self,preset_values :list = [],cursor_index :int = None): def preselection(self,preset_values :list = [],cursor_index :int = None):
def from_preset_to_cursor(): def from_preset_to_cursor():
if preset_values: if preset_values:
if isinstance(preset_values,str): # if the value is not extant return 0 as cursor index
self.cursor_index = self.menu_options.index(preset_values) try:
else: # should return an error, but this is smoother if isinstance(preset_values,str):
self.cursor_index = self.menu_options.index(preset_values[0]) self.cursor_index = self.menu_options.index(self.preset_values)
else: # should return an error, but this is smoother
self.cursor_index = self.menu_options.index(self.preset_values[0])
except ValueError:
self.cursor_index = 0
self.cursor_index = cursor_index
if not preset_values:
self.preset_values = None
return
self.preset_values = preset_values self.preset_values = preset_values
self.cursor_index = cursor_index if self.default_option:
if preset_values and cursor_index is None:
from_preset_to_cursor()
if preset_values and not self.multi: # Not supported by the infraestructure
self.preset_values = None
from_preset_to_cursor()
if self.default_option and self.multi:
if isinstance(preset_values,str) and self.default_option == preset_values: if isinstance(preset_values,str) and self.default_option == preset_values:
self.preset_values = f"{preset_values} (default)" self.preset_values = f"{preset_values} (default)"
elif isinstance(preset_values,(list,tuple)) and self.default_option in preset_values: elif isinstance(preset_values,(list,tuple)) and self.default_option in preset_values:
idx = preset_values.index(self.default_option) idx = preset_values.index(self.default_option)
self.preset_values[idx] = f"{preset_values[idx]} (default)" self.preset_values[idx] = f"{preset_values[idx]} (default)"
if cursor_index is None or not self.multi:
from_preset_to_cursor()
if not self.multi: # Not supported by the infraestructure
self.preset_values = None

View File

@ -252,6 +252,7 @@ class GeneralMenu:
# we synch all the options just in case # we synch all the options just in case
for item in self.list_options(): for item in self.list_options():
self.synch(item) self.synch(item)
self.post_callback # as all the values can vary i have to exec this callback
cursor_pos = None cursor_pos = None
while True: while True:
# Before continuing, set the preferred keyboard layout/language in the current terminal. # Before continuing, set the preferred keyboard layout/language in the current terminal.
@ -278,7 +279,7 @@ class GeneralMenu:
Returns true if the menu shall continue, False if it has ended Returns true if the menu shall continue, False if it has ended
""" """
# find the selected option in our option list # find the selected option in our option list
option = [[k, v] for k, v in self._menu_options.items() if v.text.strip() == selection] option = [[k, v] for k, v in self._menu_options.items() if v.text.strip() == selection.strip()]
if len(option) != 1: if len(option) != 1:
raise ValueError(f'Selection not found: {selection}') raise ValueError(f'Selection not found: {selection}')
selector_name = option[0][0] selector_name = option[0][0]
@ -303,8 +304,8 @@ class GeneralMenu:
result = None result = None
if selector.func: if selector.func:
# TODO insert code to allow selector functions with preset value presel_val = self.option(selector_name).get_selection()
result = selector.func() result = selector.func(presel_val)
self._menu_options[selector_name].set_current_selection(result) self._menu_options[selector_name].set_current_selection(result)
self._data_store[selector_name] = result self._data_store[selector_name] = result
exec_ret_val = selector.exec_func(selector_name,result) if selector.exec_func else False exec_ret_val = selector.exec_func(selector_name,result) if selector.exec_func else False
@ -412,32 +413,33 @@ class GlobalMenu(GeneralMenu):
super().__init__(data_store=data_store, auto_cursor=True) super().__init__(data_store=data_store, auto_cursor=True)
def _setup_selection_menu_options(self): def _setup_selection_menu_options(self):
# archinstall.Language will not use preset values
self._menu_options['archinstall-language'] = \ self._menu_options['archinstall-language'] = \
Selector( Selector(
_('Select Archinstall language'), _('Select Archinstall language'),
lambda: self._select_archinstall_language('English'), lambda x: self._select_archinstall_language('English'),
default='English', default='English',
enabled=True) enabled=True)
self._menu_options['keyboard-layout'] = \ self._menu_options['keyboard-layout'] = \
Selector(_('Select keyboard layout'), lambda: select_language('us'), default='us') Selector(_('Select keyboard layout'), lambda preset: select_language('us',preset), default='us')
self._menu_options['mirror-region'] = \ self._menu_options['mirror-region'] = \
Selector( Selector(
_('Select mirror region'), _('Select mirror region'),
lambda: select_mirror_regions(), select_mirror_regions,
display_func=lambda x: list(x.keys()) if x else '[]', display_func=lambda x: list(x.keys()) if x else '[]',
default={}) default={})
self._menu_options['sys-language'] = \ self._menu_options['sys-language'] = \
Selector(_('Select locale language'), lambda: select_locale_lang('en_US'), default='en_US') Selector(_('Select locale language'), lambda preset: select_locale_lang('en_US',preset), default='en_US')
self._menu_options['sys-encoding'] = \ self._menu_options['sys-encoding'] = \
Selector(_('Select locale encoding'), lambda: select_locale_enc('utf-8'), default='utf-8') Selector(_('Select locale encoding'), lambda preset: select_locale_enc('utf-8',preset), default='utf-8')
self._menu_options['harddrives'] = \ self._menu_options['harddrives'] = \
Selector( Selector(
_('Select harddrives'), _('Select harddrives'),
lambda: self._select_harddrives()) self._select_harddrives)
self._menu_options['disk_layouts'] = \ self._menu_options['disk_layouts'] = \
Selector( Selector(
_('Select disk layout'), _('Select disk layout'),
lambda: select_disk_layout( lambda x: select_disk_layout(
storage['arguments'].get('harddrives', []), storage['arguments'].get('harddrives', []),
storage['arguments'].get('advanced', False) storage['arguments'].get('advanced', False)
), ),
@ -445,80 +447,82 @@ class GlobalMenu(GeneralMenu):
self._menu_options['!encryption-password'] = \ self._menu_options['!encryption-password'] = \
Selector( Selector(
_('Set encryption password'), _('Set encryption password'),
lambda: self._select_encrypted_password(), lambda x: self._select_encrypted_password(),
display_func=lambda x: secret(x) if x else 'None', display_func=lambda x: secret(x) if x else 'None',
dependencies=['harddrives']) dependencies=['harddrives'])
self._menu_options['swap'] = \ self._menu_options['swap'] = \
Selector( Selector(
_('Use swap'), _('Use swap'),
lambda: ask_for_swap(), lambda preset: ask_for_swap(preset),
default=True) default=True)
self._menu_options['bootloader'] = \ self._menu_options['bootloader'] = \
Selector( Selector(
_('Select bootloader'), _('Select bootloader'),
lambda: ask_for_bootloader(storage['arguments'].get('advanced', False)), lambda preset: ask_for_bootloader(storage['arguments'].get('advanced', False),preset),
default="systemd-bootctl" if has_uefi() else "grub-install") default="systemd-bootctl" if has_uefi() else "grub-install")
self._menu_options['hostname'] = \ self._menu_options['hostname'] = \
Selector( Selector(
_('Specify hostname'), _('Specify hostname'),
lambda: ask_hostname(), ask_hostname,
default='archlinux') default='archlinux')
# root password won't have preset value
self._menu_options['!root-password'] = \ self._menu_options['!root-password'] = \
Selector( Selector(
_('Set root password'), _('Set root password'),
lambda: self._set_root_password(), lambda preset:self._set_root_password(),
display_func=lambda x: secret(x) if x else 'None') display_func=lambda x: secret(x) if x else 'None')
self._menu_options['!superusers'] = \ self._menu_options['!superusers'] = \
Selector( Selector(
_('Specify superuser account'), _('Specify superuser account'),
lambda: self._create_superuser_account(), lambda x: self._create_superuser_account(),
dependencies_not=['!root-password'], dependencies_not=['!root-password'],
display_func=lambda x: list(x.keys()) if x else '') display_func=lambda x: list(x.keys()) if x else '')
self._menu_options['!users'] = \ self._menu_options['!users'] = \
Selector( Selector(
_('Specify user account'), _('Specify user account'),
lambda: self._create_user_account(), lambda x: self._create_user_account(),
default={}, default={},
display_func=lambda x: list(x.keys()) if x else '[]') display_func=lambda x: list(x.keys()) if x else '[]')
self._menu_options['profile'] = \ self._menu_options['profile'] = \
Selector( Selector(
_('Specify profile'), _('Specify profile'),
lambda: self._select_profile(), lambda x: self._select_profile(),
display_func=lambda x: x if x else 'None') display_func=lambda x: x if x else 'None')
self._menu_options['audio'] = \ self._menu_options['audio'] = \
Selector( Selector(
_('Select audio'), _('Select audio'),
lambda: ask_for_audio_selection(is_desktop_profile(storage['arguments'].get('profile', None)))) lambda preset: ask_for_audio_selection(is_desktop_profile(storage['arguments'].get('profile', None)),preset))
self._menu_options['kernels'] = \ self._menu_options['kernels'] = \
Selector( Selector(
_('Select kernels'), _('Select kernels'),
lambda: select_kernel(), lambda preset: select_kernel(preset),
default=['linux']) default=['linux'])
self._menu_options['packages'] = \ self._menu_options['packages'] = \
Selector( Selector(
_('Additional packages to install'), _('Additional packages to install'),
lambda: ask_additional_packages_to_install(storage['arguments'].get('packages', None)), # lambda x: ask_additional_packages_to_install(storage['arguments'].get('packages', None)),
ask_additional_packages_to_install,
default=[]) default=[])
self._menu_options['additional-repositories'] = \ self._menu_options['additional-repositories'] = \
Selector( Selector(
_('Additional repositories to enable'), _('Additional repositories to enable'),
lambda: select_additional_repositories(), select_additional_repositories,
default=[]) default=[])
self._menu_options['nic'] = \ self._menu_options['nic'] = \
Selector( Selector(
_('Configure network'), _('Configure network'),
lambda: ask_to_configure_network(), ask_to_configure_network,
display_func=lambda x: x if x else _('Not configured, unavailable unless setup manually'), display_func=lambda x: x if x else _('Not configured, unavailable unless setup manually'),
default={}) default={})
self._menu_options['timezone'] = \ self._menu_options['timezone'] = \
Selector( Selector(
_('Select timezone'), _('Select timezone'),
lambda: ask_for_a_timezone(), lambda preset: ask_for_a_timezone(preset),
default='UTC') default='UTC')
self._menu_options['ntp'] = \ self._menu_options['ntp'] = \
Selector( Selector(
_('Set automatic time sync (NTP)'), _('Set automatic time sync (NTP)'),
lambda: self._select_ntp(), lambda preset: self._select_ntp(preset),
default=True) default=True)
self._menu_options['install'] = \ self._menu_options['install'] = \
Selector( Selector(
@ -591,20 +595,20 @@ class GlobalMenu(GeneralMenu):
else: else:
return None return None
def _select_ntp(self) -> bool: def _select_ntp(self, preset :bool = True) -> bool:
ntp = ask_ntp() ntp = ask_ntp(preset)
value = str(ntp).lower() value = str(ntp).lower()
SysCommand(f'timedatectl set-ntp {value}') SysCommand(f'timedatectl set-ntp {value}')
return ntp return ntp
def _select_harddrives(self): def _select_harddrives(self, old_harddrives : list) -> list:
old_haddrives = storage['arguments'].get('harddrives', []) # old_haddrives = storage['arguments'].get('harddrives', [])
harddrives = select_harddrives() harddrives = select_harddrives(old_harddrives)
# in case the harddrives got changed we have to reset the disk layout as well # in case the harddrives got changed we have to reset the disk layout as well
if old_haddrives != harddrives: if old_harddrives != harddrives:
self._menu_options.get('disk_layouts').set_current_selection(None) self._menu_options.get('disk_layouts').set_current_selection(None)
storage['arguments']['disk_layouts'] = {} storage['arguments']['disk_layouts'] = {}

View File

@ -9,6 +9,7 @@ import signal
import sys import sys
import time import time
from collections.abc import Iterable from collections.abc import Iterable
from copy import copy
from typing import List, Any, Optional, Dict, Union, TYPE_CHECKING from typing import List, Any, Optional, Dict, Union, TYPE_CHECKING
# https://stackoverflow.com/a/39757388/929999 # https://stackoverflow.com/a/39757388/929999
@ -274,21 +275,29 @@ class MiniCurses:
return response return response
def ask_for_swap(): def ask_for_swap(preset :bool = True) -> bool:
if preset:
preset_val = 'yes'
else:
preset_val = 'no'
prompt = _('Would you like to use swap on zram?') prompt = _('Would you like to use swap on zram?')
choice = Menu(prompt, ['yes', 'no'], default_option='yes').run() choice = Menu(prompt, ['yes', 'no'], default_option='yes', preset_values=preset_val).run()
return False if choice == 'no' else True return False if choice == 'no' else True
def ask_ntp() -> bool: def ask_ntp(preset :bool = True) -> bool:
prompt = str(_('Would you like to use automatic time synchronization (NTP) with the default time servers?\n')) prompt = str(_('Would you like to use automatic time synchronization (NTP) with the default time servers?\n'))
prompt += str(_('Hardware time and other post-configuration steps might be required in order for NTP to work.\nFor more information, please check the Arch wiki')) prompt += str(_('Hardware time and other post-configuration steps might be required in order for NTP to work.\nFor more information, please check the Arch wiki'))
choice = Menu(prompt, ['yes', 'no'], skip=False, default_option='yes').run() if preset:
preset_val = 'yes'
else:
preset_val = 'no'
choice = Menu(prompt, ['yes', 'no'], skip=False, preset_values=preset_val, default_option='yes').run()
return False if choice == 'no' else True return False if choice == 'no' else True
def ask_hostname(): def ask_hostname(preset :str = None) -> str :
hostname = input(_('Desired hostname for the installation: ')).strip(' ') hostname = TextInput(_('Desired hostname for the installation: '),preset).run().strip(' ')
return hostname return hostname
@ -341,7 +350,7 @@ def ask_for_additional_users(prompt :str = '') -> tuple[dict[str, dict[str, str
return users, superusers return users, superusers
def ask_for_a_timezone() -> str: def ask_for_a_timezone(preset :str = None) -> str:
timezones = list_timezones() timezones = list_timezones()
default = 'UTC' default = 'UTC'
@ -349,18 +358,28 @@ def ask_for_a_timezone() -> str:
_('Select a timezone'), _('Select a timezone'),
list(timezones), list(timezones),
skip=False, skip=False,
preset_values=preset,
default_option=default default_option=default
).run() ).run()
return selected_tz return selected_tz
def ask_for_bootloader(advanced_options :bool = False) -> str: def ask_for_bootloader(advanced_options :bool = False, preset :str = None) -> str:
if preset == 'systemd-bootctl':
preset_val = 'systemd-boot' if advanced_options else 'no'
elif preset == 'grub-install':
preset_val = 'grub' if advanced_options else 'yes'
else:
preset_val = preset
bootloader = "systemd-bootctl" if has_uefi() else "grub-install" bootloader = "systemd-bootctl" if has_uefi() else "grub-install"
if has_uefi(): if has_uefi():
if not advanced_options: if not advanced_options:
bootloader_choice = Menu( bootloader_choice = Menu(
_('Would you like to use GRUB as a bootloader instead of systemd-boot?'), _('Would you like to use GRUB as a bootloader instead of systemd-boot?'),
['yes', 'no'], ['yes', 'no'],
preset_values=preset_val,
default_option='no' default_option='no'
).run() ).run()
@ -369,7 +388,7 @@ def ask_for_bootloader(advanced_options :bool = False) -> str:
else: else:
# We use the common names for the bootloader as the selection, and map it back to the expected values. # We use the common names for the bootloader as the selection, and map it back to the expected values.
choices = ['systemd-boot', 'grub', 'efistub'] choices = ['systemd-boot', 'grub', 'efistub']
selection = Menu(_('Choose a bootloader'), choices).run() selection = Menu(_('Choose a bootloader'), choices,preset_values=preset_val).run()
if selection != "": if selection != "":
if selection == 'systemd-boot': if selection == 'systemd-boot':
bootloader = 'systemd-bootctl' bootloader = 'systemd-bootctl'
@ -381,12 +400,13 @@ def ask_for_bootloader(advanced_options :bool = False) -> str:
return bootloader return bootloader
def ask_for_audio_selection(desktop :bool = True) -> str: def ask_for_audio_selection(desktop :bool = True, preset :str = None) -> str:
audio = 'pipewire' if desktop else 'none' audio = 'pipewire' if desktop else 'none'
choices = ['pipewire', 'pulseaudio'] if desktop else ['pipewire', 'pulseaudio', 'none'] choices = ['pipewire', 'pulseaudio'] if desktop else ['pipewire', 'pulseaudio', 'none']
selected_audio = Menu( selected_audio = Menu(
_('Choose an audio server'), _('Choose an audio server'),
choices, choices,
preset_values=preset,
default_option=audio, default_option=audio,
skip=False skip=False
).run() ).run()
@ -424,7 +444,7 @@ def ask_additional_packages_to_install(pre_set_packages :List[str] = []) -> List
return packages return packages
def ask_to_configure_network() -> Dict[str, Any]: def ask_to_configure_network(preset :Dict[str, Any] = {}) -> Dict[str, Any]:
# Optionally configure one network interface. # Optionally configure one network interface.
# while 1: # while 1:
# {MAC: Ifname} # {MAC: Ifname}
@ -433,12 +453,27 @@ def ask_to_configure_network() -> Dict[str, Any]:
'network_manager': str(_('Use NetworkManager (necessary to configure internet graphically in GNOME and KDE)')), 'network_manager': str(_('Use NetworkManager (necessary to configure internet graphically in GNOME and KDE)')),
**list_interfaces() **list_interfaces()
} }
# for this routine it's easier to set the cursor position rather than a preset value
cursor_idx = None
if preset:
if preset['type'] == 'iso_config':
cursor_idx = 0
elif preset['type'] == 'network_manager':
cursor_idx = 1
else:
try :
# let's hope order in dictionaries stay
cursor_idx = list(interfaces.values()).index(preset.get('type'))
except ValueError:
pass
nic = Menu(_('Select one network interface to configure'), list(interfaces.values())).run() nic = Menu(_('Select one network interface to configure'), interfaces.values(),cursor_index=cursor_idx).run()
if not nic: if not nic:
return {} return {}
# nic = network_manager_nt
if nic == interfaces['iso_config']: if nic == interfaces['iso_config']:
return {'type': 'iso_config'} return {'type': 'iso_config'}
elif nic == interfaces['network_manager']: elif nic == interfaces['network_manager']:
@ -448,16 +483,23 @@ def ask_to_configure_network() -> Dict[str, Any]:
# For selecting modes without entering text within brackets, # For selecting modes without entering text within brackets,
# printing out this part separate from options, passed in # printing out this part separate from options, passed in
# `generic_select` # `generic_select`
# we only keep data if it is the same nic as before
if preset.get('type') != nic:
preset_d = {'type': nic, 'dhcp': True, 'ip': None, 'gateway': None, 'dns': []}
else:
preset_d = copy(preset)
modes = ['DHCP (auto detect)', 'IP (static)'] modes = ['DHCP (auto detect)', 'IP (static)']
default_mode = 'DHCP (auto detect)' default_mode = 'DHCP (auto detect)'
cursor_idx = 0 if preset_d.get('dhcp',True) else 1
prompt = _('Select which mode to configure for "{}" or skip to use default mode "{}"').format(nic, default_mode) prompt = _('Select which mode to configure for "{}" or skip to use default mode "{}"').format(nic, default_mode)
mode = Menu(prompt, modes, default_option=default_mode).run() mode = Menu(prompt, modes, default_option=default_mode, cursor_index=cursor_idx).run()
# TODO preset values for ip and gateway
if mode == 'IP (static)': if mode == 'IP (static)':
while 1: while 1:
prompt = _('Enter the IP and subnet for {} (example: 192.168.0.5/24): ').format(nic) prompt = _('Enter the IP and subnet for {} (example: 192.168.0.5/24): ').format(nic)
ip = input(prompt).strip() ip = TextInput(prompt,preset_d.get('ip')).run().strip()
# Implemented new check for correct IP/subnet input # Implemented new check for correct IP/subnet input
try: try:
ipaddress.ip_interface(ip) ipaddress.ip_interface(ip)
@ -471,7 +513,7 @@ def ask_to_configure_network() -> Dict[str, Any]:
# Implemented new check for correct gateway IP address # Implemented new check for correct gateway IP address
while 1: while 1:
gateway = input(_('Enter your gateway (router) IP address or leave blank for none: ')).strip() gateway = TextInput(_('Enter your gateway (router) IP address or leave blank for none: '),preset_d.get('gateway')).run().strip()
try: try:
if len(gateway) == 0: if len(gateway) == 0:
gateway = None gateway = None
@ -486,7 +528,11 @@ def ask_to_configure_network() -> Dict[str, Any]:
) )
dns = None dns = None
dns_input = input(_('Enter your DNS servers (space separated, blank for none): ')).strip() if preset_d.get('dns'):
preset_d['dns'] = ' '.join(preset_d['dns'])
else:
preset_d['dns'] = None
dns_input = TextInput(_('Enter your DNS servers (space separated, blank for none): '),preset_d['dns']).run().strip()
if len(dns_input): if len(dns_input):
dns = dns_input.split(' ') dns = dns_input.split(' ')
@ -847,7 +893,7 @@ def select_profile() -> Optional[Profile]:
return None return None
def select_language(default_value :str) -> str: def select_language(default_value :str, preset_value :str = None) -> str:
""" """
Asks the user to select a language Asks the user to select a language
Usually this is combined with :ref:`archinstall.list_keyboard_languages`. Usually this is combined with :ref:`archinstall.list_keyboard_languages`.
@ -861,11 +907,11 @@ def select_language(default_value :str) -> str:
# allows for searching anyways # allows for searching anyways
sorted_kb_lang = sorted(sorted(list(kb_lang)), key=len) sorted_kb_lang = sorted(sorted(list(kb_lang)), key=len)
selected_lang = Menu(_('Select Keyboard layout'), sorted_kb_lang, default_option=default_value, sort=False).run() selected_lang = Menu(_('Select Keyboard layout'), sorted_kb_lang, default_option=default_value, preset_values=preset_value, sort=False).run()
return selected_lang return selected_lang
def select_mirror_regions() -> Dict[str, Any]: def select_mirror_regions(preset_values :Dict[str, Any] = {}) -> Dict[str, Any]:
""" """
Asks the user to select a mirror or region Asks the user to select a mirror or region
Usually this is combined with :ref:`archinstall.list_mirrors`. Usually this is combined with :ref:`archinstall.list_mirrors`.
@ -873,11 +919,15 @@ def select_mirror_regions() -> Dict[str, Any]:
:return: The dictionary information about a mirror/region. :return: The dictionary information about a mirror/region.
:rtype: dict :rtype: dict
""" """
if preset_values is None:
preselected = None
else:
preselected = list(preset_values.keys())
mirrors = list_mirrors() mirrors = list_mirrors()
selected_mirror = Menu( selected_mirror = Menu(
_('Select one of the regions to download packages from'), _('Select one of the regions to download packages from'),
list(mirrors.keys()), list(mirrors.keys()),
preset_values=preselected,
multi=True multi=True
).run() ).run()
@ -887,7 +937,7 @@ def select_mirror_regions() -> Dict[str, Any]:
return {} return {}
def select_harddrives() -> Optional[str]: def select_harddrives(preset : List[str] = []) -> List[str]:
""" """
Asks the user to select one or multiple hard drives Asks the user to select one or multiple hard drives
@ -896,10 +946,11 @@ def select_harddrives() -> Optional[str]:
""" """
hard_drives = all_blockdevices(partitions=False).values() hard_drives = all_blockdevices(partitions=False).values()
options = {f'{option}': option for option in hard_drives} options = {f'{option}': option for option in hard_drives}
preset_disks = {f'{option}':option for option in preset}
selected_harddrive = Menu( selected_harddrive = Menu(
_('Select one or more hard drives to use and configure'), _('Select one or more hard drives to use and configure'),
list(options.keys()), list(options.keys()),
preset_values=list(preset_disks.keys()),
multi=True multi=True
).run() ).run()
@ -943,7 +994,7 @@ def select_driver(options :Dict[str, Any] = AVAILABLE_GFX_DRIVERS, force_ask :bo
raise RequirementError("Selecting drivers require a least one profile to be given as an option.") raise RequirementError("Selecting drivers require a least one profile to be given as an option.")
def select_kernel() -> List[str]: def select_kernel(preset :List[str] = None) -> List[str]:
""" """
Asks the user to select a kernel for system. Asks the user to select a kernel for system.
@ -959,11 +1010,12 @@ def select_kernel() -> List[str]:
kernels, kernels,
sort=True, sort=True,
multi=True, multi=True,
preset_values=preset,
default_option=default_kernel default_option=default_kernel
).run() ).run()
return selected_kernels return selected_kernels
def select_additional_repositories() -> List[str]: def select_additional_repositories(preset :List[str]) -> List[str]:
""" """
Allows the user to select additional repositories (multilib, and testing) if desired. Allows the user to select additional repositories (multilib, and testing) if desired.
@ -978,6 +1030,7 @@ def select_additional_repositories() -> List[str]:
repositories, repositories,
sort=False, sort=False,
multi=True, multi=True,
preset_values=preset,
default_option=[] default_option=[]
).run() ).run()
@ -986,7 +1039,7 @@ def select_additional_repositories() -> List[str]:
return [] return []
def select_locale_lang(default): def select_locale_lang(default :str,preset :str = None) -> str :
locales = list_locales() locales = list_locales()
locale_lang = set([locale.split()[0] for locale in locales]) locale_lang = set([locale.split()[0] for locale in locales])
@ -994,13 +1047,14 @@ def select_locale_lang(default):
_('Choose which locale language to use'), _('Choose which locale language to use'),
locale_lang, locale_lang,
sort=True, sort=True,
preset_values=preset,
default_option=default default_option=default
).run() ).run()
return selected_locale return selected_locale
def select_locale_enc(default): def select_locale_enc(default :str,preset :str = None) -> str:
locales = list_locales() locales = list_locales()
locale_enc = set([locale.split()[1] for locale in locales]) locale_enc = set([locale.split()[1] for locale in locales])
@ -1008,6 +1062,7 @@ def select_locale_enc(default):
_('Choose which locale encoding to use'), _('Choose which locale encoding to use'),
locale_enc, locale_enc,
sort=True, sort=True,
preset_values=preset,
default_option=default default_option=default
).run() ).run()

View File

@ -156,26 +156,26 @@ class SetupMenu(archinstall.GeneralMenu):
self.set_option('archinstall-language', self.set_option('archinstall-language',
archinstall.Selector( archinstall.Selector(
_('Select Archinstall language'), _('Select Archinstall language'),
lambda: self._select_archinstall_language('English'), lambda x: self._select_archinstall_language('English'),
default='English', default='English',
enabled=True)) enabled=True))
self.set_option('ntp', self.set_option('ntp',
archinstall.Selector( archinstall.Selector(
'Activate NTP', 'Activate NTP',
lambda: select_activate_NTP(), lambda x: select_activate_NTP(),
default='Y', default='Y',
enabled=True)) enabled=True))
self.set_option('mode', self.set_option('mode',
archinstall.Selector( archinstall.Selector(
'Excution mode', 'Excution mode',
lambda: select_mode(), lambda x : select_mode(),
default='full', default='full',
enabled=True)) enabled=True))
for item in ['LC_ALL','LC_CTYPE','LC_NUMERIC','LC_TIME','LC_MESSAGES','LC_COLLATE']: for item in ['LC_ALL','LC_CTYPE','LC_NUMERIC','LC_TIME','LC_MESSAGES','LC_COLLATE']:
self.set_option(item, self.set_option(item,
archinstall.Selector( archinstall.Selector(
f'{get_locale_mode_text(item)} locale', f'{get_locale_mode_text(item)} locale',
lambda item=item: select_installed_locale(item), # the parmeter is needed for the lambda in the loop lambda x,item=item: select_installed_locale(item), # the parmeter is needed for the lambda in the loop
enabled=True, enabled=True,
dependencies_not=['LC_ALL'] if item != 'LC_ALL' else [])) dependencies_not=['LC_ALL'] if item != 'LC_ALL' else []))
self.option('LC_ALL').set_enabled(True) self.option('LC_ALL').set_enabled(True)