Send patches - preferably formatted by git format-patch - to patches at archlinux32 dot org.
summaryrefslogtreecommitdiff
path: root/archinstall/lib/menu/global_menu.py
diff options
context:
space:
mode:
Diffstat (limited to 'archinstall/lib/menu/global_menu.py')
-rw-r--r--archinstall/lib/menu/global_menu.py429
1 files changed, 0 insertions, 429 deletions
diff --git a/archinstall/lib/menu/global_menu.py b/archinstall/lib/menu/global_menu.py
deleted file mode 100644
index 7c5b153e..00000000
--- a/archinstall/lib/menu/global_menu.py
+++ /dev/null
@@ -1,429 +0,0 @@
-from __future__ import annotations
-
-from typing import Any, List, Optional, Union, Dict, TYPE_CHECKING
-
-import archinstall
-from ..disk.encryption import DiskEncryptionMenu
-from ..general import SysCommand, secret
-from ..hardware import has_uefi
-from ..menu import Menu
-from ..menu.abstract_menu import Selector, AbstractMenu
-from ..models import NetworkConfiguration
-from ..models.disk_encryption import DiskEncryption, EncryptionType
-from ..models.users import User
-from ..output import FormattedOutput
-from ..profiles import is_desktop_profile, Profile
-from ..storage import storage
-from ..user_interaction import add_number_of_parrallel_downloads
-from ..user_interaction import ask_additional_packages_to_install
-from ..user_interaction import ask_for_additional_users
-from ..user_interaction import ask_for_audio_selection
-from ..user_interaction import ask_for_bootloader
-from ..user_interaction import ask_for_swap
-from ..user_interaction import ask_hostname
-from ..user_interaction import ask_ntp
-from ..user_interaction import ask_to_configure_network
-from ..user_interaction import get_password, ask_for_a_timezone, save_config
-from ..user_interaction import select_additional_repositories
-from ..user_interaction import select_disk_layout
-from ..user_interaction import select_harddrives
-from ..user_interaction import select_kernel
-from ..user_interaction import select_language
-from ..user_interaction import select_locale_enc
-from ..user_interaction import select_locale_lang
-from ..user_interaction import select_mirror_regions
-from ..user_interaction import select_profile
-from ..user_interaction.partitioning_conf import current_partition_layout
-
-if TYPE_CHECKING:
- _: Any
-
-
-class GlobalMenu(AbstractMenu):
- def __init__(self,data_store):
- self._disk_check = True
- super().__init__(data_store=data_store, auto_cursor=True, preview_size=0.3)
-
- def _setup_selection_menu_options(self):
- # archinstall.Language will not use preset values
- self._menu_options['archinstall-language'] = \
- Selector(
- _('Archinstall language'),
- lambda x: self._select_archinstall_language(x),
- display_func=lambda x: x.display_name,
- default=self.translation_handler.get_language_by_abbr('en'))
- self._menu_options['keyboard-layout'] = \
- Selector(
- _('Keyboard layout'),
- lambda preset: select_language(preset),
- default='us')
- self._menu_options['mirror-region'] = \
- Selector(
- _('Mirror region'),
- lambda preset: select_mirror_regions(preset),
- display_func=lambda x: list(x.keys()) if x else '[]',
- default={})
- self._menu_options['sys-language'] = \
- Selector(
- _('Locale language'),
- lambda preset: select_locale_lang(preset),
- default='en_US')
- self._menu_options['sys-encoding'] = \
- Selector(
- _('Locale encoding'),
- lambda preset: select_locale_enc(preset),
- default='UTF-8')
- self._menu_options['harddrives'] = \
- Selector(
- _('Drive(s)'),
- lambda preset: self._select_harddrives(preset),
- display_func=lambda x: f'{len(x)} ' + str(_('Drive(s)')) if x is not None and len(x) > 0 else '',
- preview_func=self._prev_harddrives,
- )
- self._menu_options['disk_layouts'] = \
- Selector(
- _('Disk layout'),
- lambda preset: select_disk_layout(
- preset,
- storage['arguments'].get('harddrives', []),
- storage['arguments'].get('advanced', False)
- ),
- preview_func=self._prev_disk_layouts,
- display_func=lambda x: self._display_disk_layout(x),
- dependencies=['harddrives'])
- self._menu_options['disk_encryption'] = \
- Selector(
- _('Disk encryption'),
- lambda preset: self._disk_encryption(preset),
- preview_func=self._prev_disk_encryption,
- display_func=lambda x: self._display_disk_encryption(x),
- dependencies=['disk_layouts'])
- self._menu_options['swap'] = \
- Selector(
- _('Swap'),
- lambda preset: ask_for_swap(preset),
- default=True)
- self._menu_options['bootloader'] = \
- Selector(
- _('Bootloader'),
- lambda preset: ask_for_bootloader(storage['arguments'].get('advanced', False),preset),
- default="systemd-bootctl" if has_uefi() else "grub-install")
- self._menu_options['hostname'] = \
- Selector(
- _('Hostname'),
- ask_hostname,
- default='archlinux')
- # root password won't have preset value
- self._menu_options['!root-password'] = \
- Selector(
- _('Root password'),
- lambda preset:self._set_root_password(),
- display_func=lambda x: secret(x) if x else 'None')
- self._menu_options['!users'] = \
- Selector(
- _('User account'),
- lambda x: self._create_user_account(x),
- default={},
- display_func=lambda x: f'{len(x)} {_("User(s)")}' if len(x) > 0 else None,
- preview_func=self._prev_users)
- self._menu_options['profile'] = \
- Selector(
- _('Profile'),
- lambda preset: self._select_profile(preset),
- display_func=lambda x: x if x else 'None'
- )
- self._menu_options['audio'] = \
- Selector(
- _('Audio'),
- lambda preset: ask_for_audio_selection(is_desktop_profile(storage['arguments'].get('profile', None)),preset),
- display_func=lambda x: x if x else 'None',
- default=None
- )
-
- self._menu_options['parallel downloads'] = \
- Selector(
- _('Parallel Downloads'),
- add_number_of_parrallel_downloads,
- display_func=lambda x: x if x else '0',
- default=0
- )
-
- self._menu_options['kernels'] = \
- Selector(
- _('Kernels'),
- lambda preset: select_kernel(preset),
- default=['linux'])
- self._menu_options['packages'] = \
- Selector(
- _('Additional packages'),
- # lambda x: ask_additional_packages_to_install(storage['arguments'].get('packages', None)),
- ask_additional_packages_to_install,
- default=[])
- self._menu_options['additional-repositories'] = \
- Selector(
- _('Optional repositories'),
- select_additional_repositories,
- default=[])
- self._menu_options['nic'] = \
- Selector(
- _('Network configuration'),
- ask_to_configure_network,
- display_func=lambda x: self._display_network_conf(x),
- preview_func=self._prev_network_config,
- default={})
- self._menu_options['timezone'] = \
- Selector(
- _('Timezone'),
- lambda preset: ask_for_a_timezone(preset),
- default='UTC')
- self._menu_options['ntp'] = \
- Selector(
- _('Automatic time sync (NTP)'),
- lambda preset: self._select_ntp(preset),
- default=True)
- self._menu_options['__separator__'] = \
- Selector('')
- self._menu_options['save_config'] = \
- Selector(
- _('Save configuration'),
- lambda preset: save_config(self._data_store),
- no_store=True)
- self._menu_options['install'] = \
- Selector(
- self._install_text(),
- exec_func=lambda n,v: True if len(self._missing_configs()) == 0 else False,
- preview_func=self._prev_install_missing_config,
- no_store=True)
-
- self._menu_options['abort'] = Selector(_('Abort'), exec_func=lambda n,v:exit(1))
-
- def _update_install_text(self, name :Optional[str] = None, result :Any = None):
- text = self._install_text()
- self._menu_options['install'].update_description(text)
-
- def post_callback(self,name :Optional[str] = None ,result :Any = None):
- self._update_install_text(name, result)
-
- def _install_text(self):
- missing = len(self._missing_configs())
- if missing > 0:
- return _('Install ({} config(s) missing)').format(missing)
- return _('Install')
-
- def _display_network_conf(self, cur_value: Union[NetworkConfiguration, List[NetworkConfiguration]]) -> str:
- if not cur_value:
- return _('Not configured, unavailable unless setup manually')
- else:
- if isinstance(cur_value, list):
- return str(_('Configured {} interfaces')).format(len(cur_value))
- else:
- return str(cur_value)
-
- def _disk_encryption(self, preset: Optional[DiskEncryption]) -> Optional[DiskEncryption]:
- data_store: Dict[str, Any] = {}
-
- selector = self._menu_options['disk_layouts']
-
- if selector.has_selection():
- layouts: Dict[str, Dict[str, Any]] = selector.current_selection
- else:
- # this should not happen as the encryption menu has the disk layout as dependency
- raise ValueError('No disk layout specified')
-
- disk_encryption = DiskEncryptionMenu(data_store, preset, layouts).run()
- return disk_encryption
-
- def _prev_network_config(self) -> Optional[str]:
- selector = self._menu_options['nic']
- if selector.has_selection():
- ifaces = selector.current_selection
- if isinstance(ifaces, list):
- return FormattedOutput.as_table(ifaces)
- return None
-
- def _prev_harddrives(self) -> Optional[str]:
- selector = self._menu_options['harddrives']
- if selector.has_selection():
- drives = selector.current_selection
- return FormattedOutput.as_table(drives)
- return None
-
- def _prev_disk_layouts(self) -> Optional[str]:
- selector = self._menu_options['disk_layouts']
- if selector.has_selection():
- layouts: Dict[str, Dict[str, Any]] = selector.current_selection
-
- output = ''
- for device, layout in layouts.items():
- output += f'{_("Device")}: {device}\n\n'
- output += current_partition_layout(layout['partitions'], with_title=False)
- output += '\n\n'
-
- return output.rstrip()
-
- return None
-
- def _display_disk_layout(self, current_value: Optional[Dict[str, Any]]) -> str:
- if current_value:
- total_partitions = [entry['partitions'] for entry in current_value.values()]
- total_nr = sum([len(p) for p in total_partitions])
- return f'{total_nr} {_("Partitions")}'
- return ''
-
- def _prev_disk_encryption(self) -> Optional[str]:
- selector = self._menu_options['disk_encryption']
- if selector.has_selection():
- encryption: DiskEncryption = selector.current_selection
-
- enc_type = EncryptionType.type_to_text(encryption.encryption_type)
- output = str(_('Encryption type')) + f': {enc_type}\n'
- output += str(_('Password')) + f': {secret(encryption.encryption_password)}\n'
-
- if encryption.all_partitions:
- output += 'Partitions: {} selected'.format(len(encryption.all_partitions)) + '\n'
-
- if encryption.hsm_device:
- output += f'HSM: {encryption.hsm_device.manufacturer}'
-
- return output
-
- return None
-
- def _display_disk_encryption(self, current_value: Optional[DiskEncryption]) -> str:
- if current_value:
- return EncryptionType.type_to_text(current_value.encryption_type)
- return ''
-
- def _prev_install_missing_config(self) -> Optional[str]:
- if missing := self._missing_configs():
- text = str(_('Missing configurations:\n'))
- for m in missing:
- text += f'- {m}\n'
- return text[:-1] # remove last new line
- return None
-
- def _prev_users(self) -> Optional[str]:
- selector = self._menu_options['!users']
- if selector.has_selection():
- users: List[User] = selector.current_selection
- return FormattedOutput.as_table(users)
- return None
-
- def _missing_configs(self) -> List[str]:
- def check(s):
- return self._menu_options.get(s).has_selection()
-
- def has_superuser() -> bool:
- users = self._menu_options['!users'].current_selection
- return any([u.sudo for u in users])
-
- missing = []
- if not check('bootloader'):
- missing += ['Bootloader']
- if not check('hostname'):
- missing += ['Hostname']
- if not check('!root-password') and not has_superuser():
- missing += [str(_('Either root-password or at least 1 user with sudo privileges must be specified'))]
- if self._disk_check:
- if not check('harddrives'):
- missing += [str(_('Drive(s)'))]
- if check('harddrives'):
- if not self._menu_options['harddrives'].is_empty() and not check('disk_layouts'):
- missing += [str(_('Disk layout'))]
-
- return missing
-
- def _set_root_password(self) -> Optional[str]:
- prompt = str(_('Enter root password (leave blank to disable root): '))
- password = get_password(prompt=prompt)
- return password
-
- # def _select_encrypted_password(self) -> Optional[str]:
- # if passwd := get_password(prompt=str(_('Enter disk encryption password (leave blank for no encryption): '))):
- # return passwd
- # return None
-
- def _select_ntp(self, preset :bool = True) -> bool:
- ntp = ask_ntp(preset)
-
- value = str(ntp).lower()
- SysCommand(f'timedatectl set-ntp {value}')
-
- return ntp
-
- def _select_harddrives(self, old_harddrives: List[str] = []) -> List:
- harddrives = select_harddrives(old_harddrives)
-
- if harddrives is not None:
- if len(harddrives) == 0:
- prompt = _(
- "You decided to skip harddrive selection\nand will use whatever drive-setup is mounted at {} (experimental)\n"
- "WARNING: Archinstall won't check the suitability of this setup\n"
- "Do you wish to continue?"
- ).format(storage['MOUNT_POINT'])
-
- choice = Menu(prompt, Menu.yes_no(), default_option=Menu.yes(), skip=False).run()
-
- if choice.value == Menu.no():
- self._disk_check = True
- return self._select_harddrives(old_harddrives)
- else:
- self._disk_check = False
-
- # in case the harddrives got changed we have to reset the disk layout as well
- if old_harddrives != harddrives:
- self._menu_options['disk_layouts'].set_current_selection(None)
- storage['arguments']['disk_layouts'] = {}
-
- return harddrives
-
- def _select_profile(self, preset) -> Optional[Profile]:
- ret: Optional[Profile] = None
- profile = select_profile(preset)
-
- if profile is None:
- if any([
- archinstall.storage.get('profile_minimal', False),
- archinstall.storage.get('_selected_servers', None),
- archinstall.storage.get('_desktop_profile', None),
- archinstall.arguments.get('desktop-environment', None),
- archinstall.arguments.get('gfx_driver_packages', None)
- ]):
- return preset
- else: # ctrl+c was actioned and all profile settings have been reset
- return None
-
- servers = archinstall.storage.get('_selected_servers', [])
- desktop = archinstall.storage.get('_desktop_profile', None)
- desktop_env = archinstall.arguments.get('desktop-environment', None)
- gfx_driver = archinstall.arguments.get('gfx_driver_packages', None)
-
- # Check the potentially selected profiles preparations to get early checks if some additional questions are needed.
- if profile and profile.has_prep_function():
- namespace = f'{profile.namespace}.py'
- with profile.load_instructions(namespace=namespace) as imported:
- if imported._prep_function(servers=servers, desktop=desktop, desktop_env=desktop_env, gfx_driver=gfx_driver):
- ret = profile
-
- match ret.name:
- case 'minimal':
- reset = ['_selected_servers', '_desktop_profile', 'desktop-environment', 'gfx_driver_packages']
- case 'server':
- reset = ['_desktop_profile', 'desktop-environment']
- case 'desktop':
- reset = ['_selected_servers']
- case 'xorg':
- reset = ['_selected_servers', '_desktop_profile', 'desktop-environment']
-
- for r in reset:
- archinstall.storage[r] = None
- else:
- return self._select_profile(preset)
- elif profile:
- ret = profile
-
- return ret
-
- def _create_user_account(self, defined_users: List[User]) -> List[User]:
- users = ask_for_additional_users(defined_users=defined_users)
- return users