Move locales and cleanup menu (#1814)
* Cleanup imports and unused code * Cleanup imports and unused code * Update build check * Keep deprecation exception * Simplify logging * Move locale into new sub-menu --------- Co-authored-by: Daniel Girtler <girtler.daniel@gmail.com>
This commit is contained in:
parent
5276d95339
commit
06eadb31d4
|
|
@ -213,8 +213,7 @@ def load_config():
|
||||||
"""
|
"""
|
||||||
from .lib.models import NetworkConfiguration
|
from .lib.models import NetworkConfiguration
|
||||||
|
|
||||||
arguments.setdefault('sys-language', 'en_US')
|
arguments['locale_config'] = locale.LocaleConfiguration.parse_arg(arguments)
|
||||||
arguments.setdefault('sys-encoding', 'utf-8')
|
|
||||||
|
|
||||||
if (archinstall_lang := arguments.get('archinstall-language', None)) is not None:
|
if (archinstall_lang := arguments.get('archinstall-language', None)) is not None:
|
||||||
arguments['archinstall-language'] = TranslationHandler().get_language_by_name(archinstall_lang)
|
arguments['archinstall-language'] = TranslationHandler().get_language_by_name(archinstall_lang)
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@ from __future__ import annotations
|
||||||
from enum import Enum, auto
|
from enum import Enum, auto
|
||||||
from typing import List, Optional, Any, Dict, TYPE_CHECKING, TypeVar
|
from typing import List, Optional, Any, Dict, TYPE_CHECKING, TypeVar
|
||||||
|
|
||||||
from archinstall.lib.output import FormattedOutput
|
from archinstall.lib.utils.util import format_cols
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
from archinstall.lib.installer import Installer
|
from archinstall.lib.installer import Installer
|
||||||
|
|
@ -185,17 +185,6 @@ class Profile:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
def packages_text(self) -> str:
|
def packages_text(self) -> str:
|
||||||
text = str(_('Installed packages')) + ':\n'
|
header = str(_('Installed packages'))
|
||||||
|
output = format_cols(self.packages, header)
|
||||||
nr_packages = len(self.packages)
|
return output
|
||||||
if nr_packages <= 5:
|
|
||||||
col = 1
|
|
||||||
elif nr_packages <= 10:
|
|
||||||
col = 2
|
|
||||||
elif nr_packages <= 15:
|
|
||||||
col = 3
|
|
||||||
else:
|
|
||||||
col = 4
|
|
||||||
|
|
||||||
text += FormattedOutput.as_columns(self.packages, col)
|
|
||||||
return text
|
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,7 @@ from typing import Any, List, Optional, Union, Dict, TYPE_CHECKING
|
||||||
|
|
||||||
from . import disk
|
from . import disk
|
||||||
from .general import secret
|
from .general import secret
|
||||||
|
from .locale.locale_menu import LocaleConfiguration, LocaleMenu
|
||||||
from .menu import Selector, AbstractMenu
|
from .menu import Selector, AbstractMenu
|
||||||
from .mirrors import MirrorConfiguration, MirrorMenu
|
from .mirrors import MirrorConfiguration, MirrorMenu
|
||||||
from .models import NetworkConfiguration
|
from .models import NetworkConfiguration
|
||||||
|
|
@ -24,9 +25,7 @@ from .interactions import ask_to_configure_network
|
||||||
from .interactions import get_password, ask_for_a_timezone
|
from .interactions import get_password, ask_for_a_timezone
|
||||||
from .interactions import select_additional_repositories
|
from .interactions import select_additional_repositories
|
||||||
from .interactions import select_kernel
|
from .interactions import select_kernel
|
||||||
from .interactions import select_language
|
from .utils.util import format_cols
|
||||||
from .interactions import select_locale_enc
|
|
||||||
from .interactions import select_locale_lang
|
|
||||||
from .interactions import ask_ntp
|
from .interactions import ask_ntp
|
||||||
from .interactions.disk_conf import select_disk_config
|
from .interactions.disk_conf import select_disk_config
|
||||||
|
|
||||||
|
|
@ -36,6 +35,7 @@ if TYPE_CHECKING:
|
||||||
|
|
||||||
class GlobalMenu(AbstractMenu):
|
class GlobalMenu(AbstractMenu):
|
||||||
def __init__(self, data_store: Dict[str, Any]):
|
def __init__(self, data_store: Dict[str, Any]):
|
||||||
|
self._defined_text = str(_('Defined'))
|
||||||
super().__init__(data_store=data_store, auto_cursor=True, preview_size=0.3)
|
super().__init__(data_store=data_store, auto_cursor=True, preview_size=0.3)
|
||||||
|
|
||||||
def setup_selection_menu_options(self):
|
def setup_selection_menu_options(self):
|
||||||
|
|
@ -46,28 +46,19 @@ class GlobalMenu(AbstractMenu):
|
||||||
lambda x: self._select_archinstall_language(x),
|
lambda x: self._select_archinstall_language(x),
|
||||||
display_func=lambda x: x.display_name,
|
display_func=lambda x: x.display_name,
|
||||||
default=self.translation_handler.get_language_by_abbr('en'))
|
default=self.translation_handler.get_language_by_abbr('en'))
|
||||||
self._menu_options['keyboard-layout'] = \
|
self._menu_options['locale_config'] = \
|
||||||
Selector(
|
Selector(
|
||||||
_('Keyboard layout'),
|
_('Locales'),
|
||||||
lambda preset: select_language(preset),
|
lambda preset: self._locale_selection(preset),
|
||||||
default='us')
|
preview_func=self._prev_locale,
|
||||||
|
display_func=lambda x: self._defined_text if x else '')
|
||||||
self._menu_options['mirror_config'] = \
|
self._menu_options['mirror_config'] = \
|
||||||
Selector(
|
Selector(
|
||||||
_('Mirrors'),
|
_('Mirrors'),
|
||||||
lambda preset: self._mirror_configuration(preset),
|
lambda preset: self._mirror_configuration(preset),
|
||||||
display_func=lambda x: str(_('Defined')) if x else '',
|
display_func=lambda x: self._defined_text if x else '',
|
||||||
preview_func=self._prev_mirror_config
|
preview_func=self._prev_mirror_config
|
||||||
)
|
)
|
||||||
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['disk_config'] = \
|
self._menu_options['disk_config'] = \
|
||||||
Selector(
|
Selector(
|
||||||
_('Disk configuration'),
|
_('Disk configuration'),
|
||||||
|
|
@ -103,32 +94,32 @@ class GlobalMenu(AbstractMenu):
|
||||||
Selector(
|
Selector(
|
||||||
_('Root password'),
|
_('Root password'),
|
||||||
lambda preset: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 '')
|
||||||
self._menu_options['!users'] = \
|
self._menu_options['!users'] = \
|
||||||
Selector(
|
Selector(
|
||||||
_('User account'),
|
_('User account'),
|
||||||
lambda x: self._create_user_account(x),
|
lambda x: self._create_user_account(x),
|
||||||
default=[],
|
default=[],
|
||||||
display_func=lambda x: f'{len(x)} {_("User(s)")}' if len(x) > 0 else None,
|
display_func=lambda x: f'{len(x)} {_("User(s)")}' if len(x) > 0 else '',
|
||||||
preview_func=self._prev_users)
|
preview_func=self._prev_users)
|
||||||
self._menu_options['profile_config'] = \
|
self._menu_options['profile_config'] = \
|
||||||
Selector(
|
Selector(
|
||||||
_('Profile'),
|
_('Profile'),
|
||||||
lambda preset: self._select_profile(preset),
|
lambda preset: self._select_profile(preset),
|
||||||
display_func=lambda x: x.profile.name if x else 'None',
|
display_func=lambda x: x.profile.name if x else '',
|
||||||
preview_func=self._prev_profile
|
preview_func=self._prev_profile
|
||||||
)
|
)
|
||||||
self._menu_options['audio'] = \
|
self._menu_options['audio'] = \
|
||||||
Selector(
|
Selector(
|
||||||
_('Audio'),
|
_('Audio'),
|
||||||
lambda preset: self._select_audio(preset),
|
lambda preset: self._select_audio(preset),
|
||||||
display_func=lambda x: x if x else 'None',
|
display_func=lambda x: x if x else '',
|
||||||
default=None
|
default=None
|
||||||
)
|
)
|
||||||
self._menu_options['parallel downloads'] = \
|
self._menu_options['parallel downloads'] = \
|
||||||
Selector(
|
Selector(
|
||||||
_('Parallel Downloads'),
|
_('Parallel Downloads'),
|
||||||
add_number_of_parrallel_downloads,
|
lambda preset: add_number_of_parrallel_downloads(preset),
|
||||||
display_func=lambda x: x if x else '0',
|
display_func=lambda x: x if x else '0',
|
||||||
default=0
|
default=0
|
||||||
)
|
)
|
||||||
|
|
@ -141,19 +132,20 @@ class GlobalMenu(AbstractMenu):
|
||||||
self._menu_options['packages'] = \
|
self._menu_options['packages'] = \
|
||||||
Selector(
|
Selector(
|
||||||
_('Additional packages'),
|
_('Additional packages'),
|
||||||
# lambda x: ask_additional_packages_to_install(storage['arguments'].get('packages', None)),
|
lambda preset: ask_additional_packages_to_install(preset),
|
||||||
ask_additional_packages_to_install,
|
display_func=lambda x: self._defined_text if x else '',
|
||||||
|
preview_func=self._prev_additional_pkgs,
|
||||||
default=[])
|
default=[])
|
||||||
self._menu_options['additional-repositories'] = \
|
self._menu_options['additional-repositories'] = \
|
||||||
Selector(
|
Selector(
|
||||||
_('Optional repositories'),
|
_('Optional repositories'),
|
||||||
select_additional_repositories,
|
lambda preset: select_additional_repositories(preset),
|
||||||
display_func=lambda x: ', '.join(x) if x else None,
|
display_func=lambda x: ', '.join(x) if x else None,
|
||||||
default=[])
|
default=[])
|
||||||
self._menu_options['nic'] = \
|
self._menu_options['nic'] = \
|
||||||
Selector(
|
Selector(
|
||||||
_('Network configuration'),
|
_('Network configuration'),
|
||||||
ask_to_configure_network,
|
lambda preset: ask_to_configure_network(preset),
|
||||||
display_func=lambda x: self._display_network_conf(x),
|
display_func=lambda x: self._display_network_conf(x),
|
||||||
preview_func=self._prev_network_config,
|
preview_func=self._prev_network_config,
|
||||||
default={})
|
default={})
|
||||||
|
|
@ -177,12 +169,37 @@ class GlobalMenu(AbstractMenu):
|
||||||
self._menu_options['install'] = \
|
self._menu_options['install'] = \
|
||||||
Selector(
|
Selector(
|
||||||
self._install_text(),
|
self._install_text(),
|
||||||
exec_func=lambda n,v: True if len(self._missing_configs()) == 0 else False,
|
exec_func=lambda n, v: True if len(self._missing_configs()) == 0 else False,
|
||||||
preview_func=self._prev_install_missing_config,
|
preview_func=self._prev_install_missing_config,
|
||||||
no_store=True)
|
no_store=True)
|
||||||
|
|
||||||
self._menu_options['abort'] = Selector(_('Abort'), exec_func=lambda n,v:exit(1))
|
self._menu_options['abort'] = Selector(_('Abort'), exec_func=lambda n,v:exit(1))
|
||||||
|
|
||||||
|
def _missing_configs(self) -> List[str]:
|
||||||
|
def check(s):
|
||||||
|
return self._menu_options.get(s).has_selection()
|
||||||
|
|
||||||
|
def has_superuser() -> bool:
|
||||||
|
sel = self._menu_options['!users']
|
||||||
|
if sel.current_selection:
|
||||||
|
return any([u.sudo for u in sel.current_selection])
|
||||||
|
return False
|
||||||
|
|
||||||
|
mandatory_fields = dict(filter(lambda x: x[1].is_mandatory(), self._menu_options.items()))
|
||||||
|
missing = set()
|
||||||
|
|
||||||
|
for key, selector in mandatory_fields.items():
|
||||||
|
if key in ['!root-password', '!users']:
|
||||||
|
if not check('!root-password') and not has_superuser():
|
||||||
|
missing.add(
|
||||||
|
str(_('Either root-password or at least 1 user with sudo privileges must be specified'))
|
||||||
|
)
|
||||||
|
elif key == 'disk_config':
|
||||||
|
if not check('disk_config'):
|
||||||
|
missing.add(self._menu_options['disk_config'].description)
|
||||||
|
|
||||||
|
return list(missing)
|
||||||
|
|
||||||
def _update_install_text(self, name: str, value: str):
|
def _update_install_text(self, name: str, value: str):
|
||||||
text = self._install_text()
|
text = self._install_text()
|
||||||
self._menu_options['install'].update_description(text)
|
self._menu_options['install'].update_description(text)
|
||||||
|
|
@ -216,6 +233,21 @@ class GlobalMenu(AbstractMenu):
|
||||||
disk_encryption = disk.DiskEncryptionMenu(mods, data_store, preset=preset).run()
|
disk_encryption = disk.DiskEncryptionMenu(mods, data_store, preset=preset).run()
|
||||||
return disk_encryption
|
return disk_encryption
|
||||||
|
|
||||||
|
def _locale_selection(self, preset: LocaleConfiguration) -> LocaleConfiguration:
|
||||||
|
data_store: Dict[str, Any] = {}
|
||||||
|
locale_config = LocaleMenu(data_store, preset).run()
|
||||||
|
return locale_config
|
||||||
|
|
||||||
|
def _prev_locale(self) -> Optional[str]:
|
||||||
|
selector = self._menu_options['locale_config']
|
||||||
|
if selector.has_selection():
|
||||||
|
config: LocaleConfiguration = selector.current_selection # type: ignore
|
||||||
|
output = '{}: {}\n'.format(str(_('Keyboard layout')), config.kb_layout)
|
||||||
|
output += '{}: {}\n'.format(str(_('Locale language')), config.sys_lang)
|
||||||
|
output += '{}: {}'.format(str(_('Locale encoding')), config.sys_enc)
|
||||||
|
return output
|
||||||
|
return None
|
||||||
|
|
||||||
def _prev_network_config(self) -> Optional[str]:
|
def _prev_network_config(self) -> Optional[str]:
|
||||||
selector = self._menu_options['nic']
|
selector = self._menu_options['nic']
|
||||||
if selector.has_selection():
|
if selector.has_selection():
|
||||||
|
|
@ -224,6 +256,13 @@ class GlobalMenu(AbstractMenu):
|
||||||
return FormattedOutput.as_table(ifaces)
|
return FormattedOutput.as_table(ifaces)
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
def _prev_additional_pkgs(self):
|
||||||
|
selector = self._menu_options['packages']
|
||||||
|
if selector.has_selection():
|
||||||
|
packages: List[str] = selector.current_selection
|
||||||
|
return format_cols(packages, None)
|
||||||
|
return None
|
||||||
|
|
||||||
def _prev_disk_layouts(self) -> Optional[str]:
|
def _prev_disk_layouts(self) -> Optional[str]:
|
||||||
selector = self._menu_options['disk_config']
|
selector = self._menu_options['disk_config']
|
||||||
disk_layout_conf: Optional[disk.DiskLayoutConfiguration] = selector.current_selection
|
disk_layout_conf: Optional[disk.DiskLayoutConfiguration] = selector.current_selection
|
||||||
|
|
|
||||||
|
|
@ -3,9 +3,9 @@ from functools import cached_property
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from typing import Optional, Dict, List
|
from typing import Optional, Dict, List
|
||||||
|
|
||||||
|
from .exceptions import SysCallError
|
||||||
from .general import SysCommand
|
from .general import SysCommand
|
||||||
from .networking import list_interfaces, enrich_iface_types
|
from .networking import list_interfaces, enrich_iface_types
|
||||||
from .exceptions import SysCallError
|
|
||||||
from .output import debug
|
from .output import debug
|
||||||
|
|
||||||
AVAILABLE_GFX_DRIVERS = {
|
AVAILABLE_GFX_DRIVERS = {
|
||||||
|
|
|
||||||
|
|
@ -12,6 +12,7 @@ from . import disk
|
||||||
from .exceptions import DiskError, ServiceException, RequirementError, HardwareIncompatibilityError, SysCallError
|
from .exceptions import DiskError, ServiceException, RequirementError, HardwareIncompatibilityError, SysCallError
|
||||||
from .general import SysCommand
|
from .general import SysCommand
|
||||||
from .hardware import SysInfo
|
from .hardware import SysInfo
|
||||||
|
from .locale import LocaleConfiguration
|
||||||
from .locale import verify_keyboard_layout, verify_x11_keyboard_layout
|
from .locale import verify_keyboard_layout, verify_x11_keyboard_layout
|
||||||
from .luks import Luks2
|
from .luks import Luks2
|
||||||
from .mirrors import use_mirrors, MirrorConfiguration, add_custom_mirrors
|
from .mirrors import use_mirrors, MirrorConfiguration, add_custom_mirrors
|
||||||
|
|
@ -457,37 +458,36 @@ class Installer:
|
||||||
with open(f'{self.target}/etc/hostname', 'w') as fh:
|
with open(f'{self.target}/etc/hostname', 'w') as fh:
|
||||||
fh.write(hostname + '\n')
|
fh.write(hostname + '\n')
|
||||||
|
|
||||||
def set_locale(self, locale :str, encoding :str = 'UTF-8', *args :str, **kwargs :str) -> bool:
|
def set_locale(self, locale_config: LocaleConfiguration):
|
||||||
if not len(locale):
|
|
||||||
return True
|
|
||||||
|
|
||||||
modifier = ''
|
modifier = ''
|
||||||
|
lang = locale_config.sys_lang
|
||||||
|
encoding = locale_config.sys_enc
|
||||||
|
|
||||||
# This is a temporary patch to fix #1200
|
# This is a temporary patch to fix #1200
|
||||||
if '.' in locale:
|
if '.' in locale_config.sys_lang:
|
||||||
locale, potential_encoding = locale.split('.', 1)
|
lang, potential_encoding = locale_config.sys_lang.split('.', 1)
|
||||||
|
|
||||||
# Override encoding if encoding is set to the default parameter
|
# Override encoding if encoding is set to the default parameter
|
||||||
# and the "found" encoding differs.
|
# and the "found" encoding differs.
|
||||||
if encoding == 'UTF-8' and encoding != potential_encoding:
|
if locale_config.sys_enc == 'UTF-8' and locale_config.sys_enc != potential_encoding:
|
||||||
encoding = potential_encoding
|
encoding = potential_encoding
|
||||||
|
|
||||||
# Make sure we extract the modifier, that way we can put it in if needed.
|
# Make sure we extract the modifier, that way we can put it in if needed.
|
||||||
if '@' in locale:
|
if '@' in locale_config.sys_lang:
|
||||||
locale, modifier = locale.split('@', 1)
|
lang, modifier = locale_config.sys_lang.split('@', 1)
|
||||||
modifier = f"@{modifier}"
|
modifier = f"@{modifier}"
|
||||||
# - End patch
|
# - End patch
|
||||||
|
|
||||||
with open(f'{self.target}/etc/locale.gen', 'a') as fh:
|
with open(f'{self.target}/etc/locale.gen', 'a') as fh:
|
||||||
fh.write(f'{locale}.{encoding}{modifier} {encoding}\n')
|
fh.write(f'{lang}.{encoding}{modifier} {encoding}\n')
|
||||||
|
|
||||||
with open(f'{self.target}/etc/locale.conf', 'w') as fh:
|
with open(f'{self.target}/etc/locale.conf', 'w') as fh:
|
||||||
fh.write(f'LANG={locale}.{encoding}{modifier}\n')
|
fh.write(f'LANG={lang}.{encoding}{modifier}\n')
|
||||||
|
|
||||||
try:
|
try:
|
||||||
SysCommand(f'/usr/bin/arch-chroot {self.target} locale-gen')
|
SysCommand(f'/usr/bin/arch-chroot {self.target} locale-gen')
|
||||||
return True
|
except SysCallError as e:
|
||||||
except SysCallError:
|
error(f'Failed to run locale-gen on target: {e}')
|
||||||
return False
|
|
||||||
|
|
||||||
def set_timezone(self, zone :str, *args :str, **kwargs :str) -> bool:
|
def set_timezone(self, zone :str, *args :str, **kwargs :str) -> bool:
|
||||||
if not zone:
|
if not zone:
|
||||||
|
|
@ -620,7 +620,7 @@ class Installer:
|
||||||
|
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def mkinitcpio(self, *flags :str) -> bool:
|
def mkinitcpio(self, flags: List[str], locale_config: LocaleConfiguration) -> bool:
|
||||||
for plugin in plugins.values():
|
for plugin in plugins.values():
|
||||||
if hasattr(plugin, 'on_mkinitcpio'):
|
if hasattr(plugin, 'on_mkinitcpio'):
|
||||||
# Allow plugins to override the usage of mkinitcpio altogether.
|
# Allow plugins to override the usage of mkinitcpio altogether.
|
||||||
|
|
@ -630,7 +630,7 @@ class Installer:
|
||||||
# mkinitcpio will error out if there's no vconsole.
|
# mkinitcpio will error out if there's no vconsole.
|
||||||
if (vconsole := Path(f"{self.target}/etc/vconsole.conf")).exists() is False:
|
if (vconsole := Path(f"{self.target}/etc/vconsole.conf")).exists() is False:
|
||||||
with vconsole.open('w') as fh:
|
with vconsole.open('w') as fh:
|
||||||
fh.write(f"KEYMAP={storage['arguments']['keyboard-layout']}\n")
|
fh.write(f"KEYMAP={locale_config.kb_layout}\n")
|
||||||
|
|
||||||
with open(f'{self.target}/etc/mkinitcpio.conf', 'w') as mkinit:
|
with open(f'{self.target}/etc/mkinitcpio.conf', 'w') as mkinit:
|
||||||
mkinit.write(f"MODULES=({' '.join(self.modules)})\n")
|
mkinit.write(f"MODULES=({' '.join(self.modules)})\n")
|
||||||
|
|
@ -658,7 +658,7 @@ class Installer:
|
||||||
testing: bool = False,
|
testing: bool = False,
|
||||||
multilib: bool = False,
|
multilib: bool = False,
|
||||||
hostname: str = 'archinstall',
|
hostname: str = 'archinstall',
|
||||||
locales: List[str] = ['en_US.UTF-8 UTF-8']
|
locale_config: LocaleConfiguration = LocaleConfiguration.default()
|
||||||
):
|
):
|
||||||
for mod in self._disk_config.device_modifications:
|
for mod in self._disk_config.device_modifications:
|
||||||
for part in mod.partitions:
|
for part in mod.partitions:
|
||||||
|
|
@ -734,12 +734,12 @@ class Installer:
|
||||||
# sys_command(f'/usr/bin/arch-chroot {self.target} ln -s /usr/share/zoneinfo/{localtime} /etc/localtime')
|
# sys_command(f'/usr/bin/arch-chroot {self.target} ln -s /usr/share/zoneinfo/{localtime} /etc/localtime')
|
||||||
# sys_command('/usr/bin/arch-chroot /mnt hwclock --hctosys --localtime')
|
# sys_command('/usr/bin/arch-chroot /mnt hwclock --hctosys --localtime')
|
||||||
self.set_hostname(hostname)
|
self.set_hostname(hostname)
|
||||||
self.set_locale(*locales[0].split())
|
self.set_locale(locale_config)
|
||||||
|
|
||||||
# TODO: Use python functions for this
|
# TODO: Use python functions for this
|
||||||
SysCommand(f'/usr/bin/arch-chroot {self.target} chmod 700 /root')
|
SysCommand(f'/usr/bin/arch-chroot {self.target} chmod 700 /root')
|
||||||
|
|
||||||
self.mkinitcpio('-P')
|
self.mkinitcpio(['-P'], locale_config)
|
||||||
|
|
||||||
self.helper_flags['base'] = True
|
self.helper_flags['base'] = True
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,3 @@
|
||||||
from .locale_conf import select_locale_lang, select_locale_enc
|
|
||||||
from .manage_users_conf import UserList, ask_for_additional_users
|
from .manage_users_conf import UserList, ask_for_additional_users
|
||||||
from .network_conf import ManualNetworkConfig, ask_to_configure_network
|
from .network_conf import ManualNetworkConfig, ask_to_configure_network
|
||||||
from .utils import get_password
|
from .utils import get_password
|
||||||
|
|
@ -10,7 +9,7 @@ from .disk_conf import (
|
||||||
)
|
)
|
||||||
|
|
||||||
from .general_conf import (
|
from .general_conf import (
|
||||||
ask_ntp, ask_hostname, ask_for_a_timezone, ask_for_audio_selection, select_language,
|
ask_ntp, ask_hostname, ask_for_a_timezone, ask_for_audio_selection,
|
||||||
select_archinstall_language, ask_additional_packages_to_install,
|
select_archinstall_language, ask_additional_packages_to_install,
|
||||||
add_number_of_parrallel_downloads, select_additional_repositories
|
add_number_of_parrallel_downloads, select_additional_repositories
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@ from __future__ import annotations
|
||||||
import pathlib
|
import pathlib
|
||||||
from typing import List, Any, Optional, TYPE_CHECKING
|
from typing import List, Any, Optional, TYPE_CHECKING
|
||||||
|
|
||||||
from ..locale import list_keyboard_languages, list_timezones
|
from ..locale import list_timezones, list_keyboard_languages
|
||||||
from ..menu import MenuSelectionType, Menu, TextInput
|
from ..menu import MenuSelectionType, Menu, TextInput
|
||||||
from ..output import warn
|
from ..output import warn
|
||||||
from ..packages.packages import validate_package_list
|
from ..packages.packages import validate_package_list
|
||||||
|
|
@ -119,18 +119,18 @@ def select_archinstall_language(languages: List[Language], preset: Language) ->
|
||||||
raise ValueError('Language selection not handled')
|
raise ValueError('Language selection not handled')
|
||||||
|
|
||||||
|
|
||||||
def ask_additional_packages_to_install(pre_set_packages: List[str] = []) -> List[str]:
|
def ask_additional_packages_to_install(preset: List[str] = []) -> List[str]:
|
||||||
# Additional packages (with some light weight error handling for invalid package names)
|
# Additional packages (with some light weight error handling for invalid package names)
|
||||||
print(_('Only packages such as base, base-devel, linux, linux-firmware, efibootmgr and optional profile packages are installed.'))
|
print(_('Only packages such as base, base-devel, linux, linux-firmware, efibootmgr and optional profile packages are installed.'))
|
||||||
print(_('If you desire a web browser, such as firefox or chromium, you may specify it in the following prompt.'))
|
print(_('If you desire a web browser, such as firefox or chromium, you may specify it in the following prompt.'))
|
||||||
|
|
||||||
def read_packages(already_defined: list = []) -> list:
|
def read_packages(p: List = []) -> list:
|
||||||
display = ' '.join(already_defined)
|
display = ' '.join(p)
|
||||||
input_packages = TextInput(_('Write additional packages to install (space separated, leave blank to skip): '), display).run().strip()
|
input_packages = TextInput(_('Write additional packages to install (space separated, leave blank to skip): '), display).run().strip()
|
||||||
return input_packages.split() if input_packages else []
|
return input_packages.split() if input_packages else []
|
||||||
|
|
||||||
pre_set_packages = pre_set_packages if pre_set_packages else []
|
preset = preset if preset else []
|
||||||
packages = read_packages(pre_set_packages)
|
packages = read_packages(preset)
|
||||||
|
|
||||||
if not storage['arguments']['offline'] and not storage['arguments']['no_pkg_lookups']:
|
if not storage['arguments']['offline'] and not storage['arguments']['no_pkg_lookups']:
|
||||||
while True:
|
while True:
|
||||||
|
|
|
||||||
|
|
@ -1,43 +0,0 @@
|
||||||
from typing import Any, TYPE_CHECKING, Optional
|
|
||||||
|
|
||||||
from ..locale import list_locales
|
|
||||||
from ..menu import Menu, MenuSelectionType
|
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
|
||||||
_: Any
|
|
||||||
|
|
||||||
|
|
||||||
def select_locale_lang(preset: Optional[str] = None) -> Optional[str]:
|
|
||||||
locales = list_locales()
|
|
||||||
locale_lang = set([locale.split()[0] for locale in locales])
|
|
||||||
|
|
||||||
choice = Menu(
|
|
||||||
_('Choose which locale language to use'),
|
|
||||||
list(locale_lang),
|
|
||||||
sort=True,
|
|
||||||
preset_values=preset
|
|
||||||
).run()
|
|
||||||
|
|
||||||
match choice.type_:
|
|
||||||
case MenuSelectionType.Selection: return choice.single_value
|
|
||||||
case MenuSelectionType.Skip: return preset
|
|
||||||
|
|
||||||
return None
|
|
||||||
|
|
||||||
|
|
||||||
def select_locale_enc(preset: Optional[str] = None) -> Optional[str]:
|
|
||||||
locales = list_locales()
|
|
||||||
locale_enc = set([locale.split()[1] for locale in locales])
|
|
||||||
|
|
||||||
choice = Menu(
|
|
||||||
_('Choose which locale encoding to use'),
|
|
||||||
list(locale_enc),
|
|
||||||
sort=True,
|
|
||||||
preset_values=preset
|
|
||||||
).run()
|
|
||||||
|
|
||||||
match choice.type_:
|
|
||||||
case MenuSelectionType.Selection: return choice.single_value
|
|
||||||
case MenuSelectionType.Skip: return preset
|
|
||||||
|
|
||||||
return None
|
|
||||||
|
|
@ -29,14 +29,14 @@ def select_kernel(preset: List[str] = []) -> List[str]:
|
||||||
sort=True,
|
sort=True,
|
||||||
multi=True,
|
multi=True,
|
||||||
preset_values=preset,
|
preset_values=preset,
|
||||||
allow_reset=True,
|
|
||||||
allow_reset_warning_msg=warning
|
allow_reset_warning_msg=warning
|
||||||
).run()
|
).run()
|
||||||
|
|
||||||
match choice.type_:
|
match choice.type_:
|
||||||
case MenuSelectionType.Skip: return preset
|
case MenuSelectionType.Skip: return preset
|
||||||
case MenuSelectionType.Reset: return []
|
case MenuSelectionType.Selection: return choice.single_value
|
||||||
case MenuSelectionType.Selection: return choice.value # type: ignore
|
|
||||||
|
return []
|
||||||
|
|
||||||
|
|
||||||
def ask_for_bootloader(preset: Bootloader) -> Bootloader:
|
def ask_for_bootloader(preset: Bootloader) -> Bootloader:
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,6 @@
|
||||||
|
from .locale_menu import LocaleConfiguration
|
||||||
|
from .locale import (
|
||||||
|
list_keyboard_languages, list_locales, list_x11_keyboard_languages,
|
||||||
|
verify_keyboard_layout, verify_x11_keyboard_layout, set_kb_layout,
|
||||||
|
list_timezones
|
||||||
|
)
|
||||||
|
|
@ -0,0 +1,68 @@
|
||||||
|
from typing import Iterator, List
|
||||||
|
|
||||||
|
from ..exceptions import ServiceException, SysCallError
|
||||||
|
from ..general import SysCommand
|
||||||
|
from ..output import error
|
||||||
|
|
||||||
|
|
||||||
|
def list_keyboard_languages() -> Iterator[str]:
|
||||||
|
for line in SysCommand("localectl --no-pager list-keymaps", environment_vars={'SYSTEMD_COLORS': '0'}):
|
||||||
|
yield line.decode('UTF-8').strip()
|
||||||
|
|
||||||
|
|
||||||
|
def list_locales() -> List[str]:
|
||||||
|
with open('/etc/locale.gen', 'r') as fp:
|
||||||
|
locales = []
|
||||||
|
# before the list of locales begins there's an empty line with a '#' in front
|
||||||
|
# so we'll collect the localels from bottom up and halt when we're donw
|
||||||
|
entries = fp.readlines()
|
||||||
|
entries.reverse()
|
||||||
|
|
||||||
|
for entry in entries:
|
||||||
|
text = entry.replace('#', '').strip()
|
||||||
|
if text == '':
|
||||||
|
break
|
||||||
|
locales.append(text)
|
||||||
|
|
||||||
|
locales.reverse()
|
||||||
|
return locales
|
||||||
|
|
||||||
|
|
||||||
|
def list_x11_keyboard_languages() -> Iterator[str]:
|
||||||
|
for line in SysCommand("localectl --no-pager list-x11-keymap-layouts", environment_vars={'SYSTEMD_COLORS': '0'}):
|
||||||
|
yield line.decode('UTF-8').strip()
|
||||||
|
|
||||||
|
|
||||||
|
def verify_keyboard_layout(layout :str) -> bool:
|
||||||
|
for language in list_keyboard_languages():
|
||||||
|
if layout.lower() == language.lower():
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
def verify_x11_keyboard_layout(layout :str) -> bool:
|
||||||
|
for language in list_x11_keyboard_languages():
|
||||||
|
if layout.lower() == language.lower():
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
def set_kb_layout(locale :str) -> bool:
|
||||||
|
if len(locale.strip()):
|
||||||
|
if not verify_keyboard_layout(locale):
|
||||||
|
error(f"Invalid keyboard locale specified: {locale}")
|
||||||
|
return False
|
||||||
|
|
||||||
|
try:
|
||||||
|
SysCommand(f'localectl set-keymap {locale}')
|
||||||
|
except SysCallError as err:
|
||||||
|
raise ServiceException(f"Unable to set locale '{locale}' for console: {err}")
|
||||||
|
|
||||||
|
return True
|
||||||
|
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
def list_timezones() -> Iterator[str]:
|
||||||
|
for line in SysCommand("timedatectl --no-pager list-timezones", environment_vars={'SYSTEMD_COLORS': '0'}):
|
||||||
|
yield line.decode('UTF-8').strip()
|
||||||
|
|
@ -0,0 +1,155 @@
|
||||||
|
from dataclasses import dataclass
|
||||||
|
from typing import Dict, Any, TYPE_CHECKING, Optional
|
||||||
|
|
||||||
|
from .locale import set_kb_layout, list_keyboard_languages, list_locales
|
||||||
|
from ..menu import Selector, AbstractSubMenu, MenuSelectionType, Menu
|
||||||
|
|
||||||
|
if TYPE_CHECKING:
|
||||||
|
_: Any
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class LocaleConfiguration:
|
||||||
|
kb_layout: str
|
||||||
|
sys_lang: str
|
||||||
|
sys_enc: str
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def default() -> 'LocaleConfiguration':
|
||||||
|
return LocaleConfiguration('us', 'en_US', 'UTF-8')
|
||||||
|
|
||||||
|
def json(self) -> Dict[str, str]:
|
||||||
|
return {
|
||||||
|
'kb_layout': self.kb_layout,
|
||||||
|
'sys_lang': self.sys_lang,
|
||||||
|
'sys_enc': self.sys_enc
|
||||||
|
}
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def _load_config(cls, config: 'LocaleConfiguration', args: Dict[str, Any]) -> 'LocaleConfiguration':
|
||||||
|
if 'sys_lang' in args:
|
||||||
|
config.sys_lang = args['sys_lang']
|
||||||
|
if 'sys_enc' in args:
|
||||||
|
config.sys_enc = args['sys_enc']
|
||||||
|
if 'kb_layout' in args:
|
||||||
|
config.kb_layout = args['kb_layout']
|
||||||
|
|
||||||
|
return config
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def parse_arg(cls, args: Dict[str, Any]) -> 'LocaleConfiguration':
|
||||||
|
default = cls.default()
|
||||||
|
|
||||||
|
if 'locale_config' in args:
|
||||||
|
default = cls._load_config(default, args['locale_config'])
|
||||||
|
else:
|
||||||
|
default = cls._load_config(default, args)
|
||||||
|
|
||||||
|
return default
|
||||||
|
|
||||||
|
|
||||||
|
class LocaleMenu(AbstractSubMenu):
|
||||||
|
def __init__(
|
||||||
|
self,
|
||||||
|
data_store: Dict[str, Any],
|
||||||
|
locele_conf: LocaleConfiguration
|
||||||
|
):
|
||||||
|
self._preset = locele_conf
|
||||||
|
super().__init__(data_store=data_store)
|
||||||
|
|
||||||
|
def setup_selection_menu_options(self):
|
||||||
|
self._menu_options['keyboard-layout'] = \
|
||||||
|
Selector(
|
||||||
|
_('Keyboard layout'),
|
||||||
|
lambda preset: self._select_kb_layout(preset),
|
||||||
|
default='us',
|
||||||
|
enabled=True)
|
||||||
|
self._menu_options['sys-language'] = \
|
||||||
|
Selector(
|
||||||
|
_('Locale language'),
|
||||||
|
lambda preset: select_locale_lang(preset),
|
||||||
|
default='en_US',
|
||||||
|
enabled=True)
|
||||||
|
self._menu_options['sys-encoding'] = \
|
||||||
|
Selector(
|
||||||
|
_('Locale encoding'),
|
||||||
|
lambda preset: select_locale_enc(preset),
|
||||||
|
default='UTF-8',
|
||||||
|
enabled=True)
|
||||||
|
|
||||||
|
def run(self, allow_reset: bool = True) -> LocaleConfiguration:
|
||||||
|
super().run(allow_reset=allow_reset)
|
||||||
|
|
||||||
|
return LocaleConfiguration(
|
||||||
|
self._data_store['keyboard-layout'],
|
||||||
|
self._data_store['sys-language'],
|
||||||
|
self._data_store['sys-encoding']
|
||||||
|
)
|
||||||
|
|
||||||
|
def _select_kb_layout(self, preset: Optional[str]) -> Optional[str]:
|
||||||
|
kb_lang = select_kb_layout(preset)
|
||||||
|
if kb_lang:
|
||||||
|
set_kb_layout(kb_lang)
|
||||||
|
return kb_lang
|
||||||
|
|
||||||
|
|
||||||
|
def select_locale_lang(preset: Optional[str] = None) -> Optional[str]:
|
||||||
|
locales = list_locales()
|
||||||
|
locale_lang = set([locale.split()[0] for locale in locales])
|
||||||
|
|
||||||
|
choice = Menu(
|
||||||
|
_('Choose which locale language to use'),
|
||||||
|
list(locale_lang),
|
||||||
|
sort=True,
|
||||||
|
preset_values=preset
|
||||||
|
).run()
|
||||||
|
|
||||||
|
match choice.type_:
|
||||||
|
case MenuSelectionType.Selection: return choice.single_value
|
||||||
|
case MenuSelectionType.Skip: return preset
|
||||||
|
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
|
def select_locale_enc(preset: Optional[str] = None) -> Optional[str]:
|
||||||
|
locales = list_locales()
|
||||||
|
locale_enc = set([locale.split()[1] for locale in locales])
|
||||||
|
|
||||||
|
choice = Menu(
|
||||||
|
_('Choose which locale encoding to use'),
|
||||||
|
list(locale_enc),
|
||||||
|
sort=True,
|
||||||
|
preset_values=preset
|
||||||
|
).run()
|
||||||
|
|
||||||
|
match choice.type_:
|
||||||
|
case MenuSelectionType.Selection: return choice.single_value
|
||||||
|
case MenuSelectionType.Skip: return preset
|
||||||
|
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
|
def select_kb_layout(preset: Optional[str] = None) -> Optional[str]:
|
||||||
|
"""
|
||||||
|
Asks the user to select a language
|
||||||
|
Usually this is combined with :ref:`archinstall.list_keyboard_languages`.
|
||||||
|
|
||||||
|
:return: The language/dictionary key of the selected language
|
||||||
|
:rtype: str
|
||||||
|
"""
|
||||||
|
kb_lang = list_keyboard_languages()
|
||||||
|
# sort alphabetically and then by length
|
||||||
|
sorted_kb_lang = sorted(sorted(list(kb_lang)), key=len)
|
||||||
|
|
||||||
|
choice = Menu(
|
||||||
|
_('Select keyboard layout'),
|
||||||
|
sorted_kb_lang,
|
||||||
|
preset_values=preset,
|
||||||
|
sort=False
|
||||||
|
).run()
|
||||||
|
|
||||||
|
match choice.type_:
|
||||||
|
case MenuSelectionType.Skip: return preset
|
||||||
|
case MenuSelectionType.Selection: return choice.single_value
|
||||||
|
|
||||||
|
return None
|
||||||
|
|
@ -3,7 +3,6 @@ from __future__ import annotations
|
||||||
from typing import Callable, Any, List, Iterator, Tuple, Optional, Dict, TYPE_CHECKING
|
from typing import Callable, Any, List, Iterator, Tuple, Optional, Dict, TYPE_CHECKING
|
||||||
|
|
||||||
from .menu import Menu, MenuSelectionType
|
from .menu import Menu, MenuSelectionType
|
||||||
from ..locale import set_keyboard_language
|
|
||||||
from ..output import error
|
from ..output import error
|
||||||
from ..translationhandler import TranslationHandler, Language
|
from ..translationhandler import TranslationHandler, Language
|
||||||
|
|
||||||
|
|
@ -130,7 +129,7 @@ class Selector:
|
||||||
if current:
|
if current:
|
||||||
padding += 5
|
padding += 5
|
||||||
description = str(self._description).ljust(padding, ' ')
|
description = str(self._description).ljust(padding, ' ')
|
||||||
current = str(_('set: {}').format(current))
|
current = current
|
||||||
else:
|
else:
|
||||||
description = self._description
|
description = self._description
|
||||||
current = ''
|
current = ''
|
||||||
|
|
@ -243,31 +242,6 @@ class AbstractMenu:
|
||||||
elif selector is not None and selector.has_selection():
|
elif selector is not None and selector.has_selection():
|
||||||
self._data_store[selector_name] = selector.current_selection
|
self._data_store[selector_name] = selector.current_selection
|
||||||
|
|
||||||
def _missing_configs(self) -> List[str]:
|
|
||||||
def check(s):
|
|
||||||
return self._menu_options.get(s).has_selection()
|
|
||||||
|
|
||||||
def has_superuser() -> bool:
|
|
||||||
sel = self._menu_options['!users']
|
|
||||||
if sel.current_selection:
|
|
||||||
return any([u.sudo for u in sel.current_selection])
|
|
||||||
return False
|
|
||||||
|
|
||||||
mandatory_fields = dict(filter(lambda x: x[1].is_mandatory(), self._menu_options.items()))
|
|
||||||
missing = set()
|
|
||||||
|
|
||||||
for key, selector in mandatory_fields.items():
|
|
||||||
if key in ['!root-password', '!users']:
|
|
||||||
if not check('!root-password') and not has_superuser():
|
|
||||||
missing.add(
|
|
||||||
str(_('Either root-password or at least 1 user with sudo privileges must be specified'))
|
|
||||||
)
|
|
||||||
elif key == 'disk_config':
|
|
||||||
if not check('disk_config'):
|
|
||||||
missing.add(self._menu_options['disk_config'].description)
|
|
||||||
|
|
||||||
return list(missing)
|
|
||||||
|
|
||||||
def setup_selection_menu_options(self):
|
def setup_selection_menu_options(self):
|
||||||
""" Define the menu options.
|
""" Define the menu options.
|
||||||
Menu options can be defined here in a subclass or done per program calling self.set_option()
|
Menu options can be defined here in a subclass or done per program calling self.set_option()
|
||||||
|
|
@ -328,9 +302,6 @@ class AbstractMenu:
|
||||||
cursor_pos = None
|
cursor_pos = None
|
||||||
|
|
||||||
while True:
|
while True:
|
||||||
# Before continuing, set the preferred keyboard layout/language in the current terminal.
|
|
||||||
# This will just help the user with the next following questions.
|
|
||||||
self._set_kb_language()
|
|
||||||
enabled_menus = self._menus_to_enable()
|
enabled_menus = self._menus_to_enable()
|
||||||
|
|
||||||
padding = self._get_menu_text_padding(list(enabled_menus.values()))
|
padding = self._get_menu_text_padding(list(enabled_menus.values()))
|
||||||
|
|
@ -425,13 +396,6 @@ class AbstractMenu:
|
||||||
|
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def _set_kb_language(self):
|
|
||||||
""" general for ArchInstall"""
|
|
||||||
# Before continuing, set the preferred keyboard layout/language in the current terminal.
|
|
||||||
# This will just help the user with the next following questions.
|
|
||||||
if self._data_store.get('keyboard-layout', None) and len(self._data_store['keyboard-layout']):
|
|
||||||
set_keyboard_language(self._data_store['keyboard-layout'])
|
|
||||||
|
|
||||||
def _verify_selection_enabled(self, selection_name: str) -> bool:
|
def _verify_selection_enabled(self, selection_name: str) -> bool:
|
||||||
""" general """
|
""" general """
|
||||||
if selection := self._menu_options.get(selection_name, None):
|
if selection := self._menu_options.get(selection_name, None):
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from typing import Any, TYPE_CHECKING, Optional
|
from typing import Any, TYPE_CHECKING, Optional, List
|
||||||
|
|
||||||
|
from ..output import FormattedOutput
|
||||||
from ..output import info
|
from ..output import info
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
|
|
@ -28,3 +29,23 @@ def is_subpath(first: Path, second: Path):
|
||||||
return True
|
return True
|
||||||
except ValueError:
|
except ValueError:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
def format_cols(items: List[str], header: Optional[str]) -> str:
|
||||||
|
if header:
|
||||||
|
text = f'{header}:\n'
|
||||||
|
else:
|
||||||
|
text = ''
|
||||||
|
|
||||||
|
nr_items = len(items)
|
||||||
|
if nr_items <= 5:
|
||||||
|
col = 1
|
||||||
|
elif nr_items <= 10:
|
||||||
|
col = 2
|
||||||
|
elif nr_items <= 15:
|
||||||
|
col = 3
|
||||||
|
else:
|
||||||
|
col = 4
|
||||||
|
|
||||||
|
text += FormattedOutput.as_columns(items, col)
|
||||||
|
return text
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@ from typing import Any, TYPE_CHECKING
|
||||||
import archinstall
|
import archinstall
|
||||||
from archinstall import info, debug
|
from archinstall import info, debug
|
||||||
from archinstall import SysInfo
|
from archinstall import SysInfo
|
||||||
|
from archinstall.lib import locale
|
||||||
from archinstall.lib import disk
|
from archinstall.lib import disk
|
||||||
from archinstall.lib.global_menu import GlobalMenu
|
from archinstall.lib.global_menu import GlobalMenu
|
||||||
from archinstall.default_profiles.applications.pipewire import PipewireProfile
|
from archinstall.default_profiles.applications.pipewire import PipewireProfile
|
||||||
|
|
@ -42,14 +43,10 @@ def ask_user_questions():
|
||||||
|
|
||||||
global_menu.enable('archinstall-language')
|
global_menu.enable('archinstall-language')
|
||||||
|
|
||||||
global_menu.enable('keyboard-layout')
|
|
||||||
|
|
||||||
# Set which region to download packages from during the installation
|
# Set which region to download packages from during the installation
|
||||||
global_menu.enable('mirror_config')
|
global_menu.enable('mirror_config')
|
||||||
|
|
||||||
global_menu.enable('sys-language')
|
global_menu.enable('locale_config')
|
||||||
|
|
||||||
global_menu.enable('sys-encoding')
|
|
||||||
|
|
||||||
global_menu.enable('disk_config', mandatory=True)
|
global_menu.enable('disk_config', mandatory=True)
|
||||||
|
|
||||||
|
|
@ -76,7 +73,7 @@ def ask_user_questions():
|
||||||
global_menu.enable('audio')
|
global_menu.enable('audio')
|
||||||
|
|
||||||
# Ask for preferred kernel:
|
# Ask for preferred kernel:
|
||||||
global_menu.enable('kernels')
|
global_menu.enable('kernels', mandatory=True)
|
||||||
|
|
||||||
global_menu.enable('packages')
|
global_menu.enable('packages')
|
||||||
|
|
||||||
|
|
@ -114,9 +111,7 @@ def perform_installation(mountpoint: Path):
|
||||||
# Retrieve list of additional repositories and set boolean values appropriately
|
# Retrieve list of additional repositories and set boolean values appropriately
|
||||||
enable_testing = 'testing' in archinstall.arguments.get('additional-repositories', [])
|
enable_testing = 'testing' in archinstall.arguments.get('additional-repositories', [])
|
||||||
enable_multilib = 'multilib' in archinstall.arguments.get('additional-repositories', [])
|
enable_multilib = 'multilib' in archinstall.arguments.get('additional-repositories', [])
|
||||||
|
locale_config: locale.LocaleConfiguration = archinstall.arguments['locale_config']
|
||||||
locale = f"{archinstall.arguments.get('sys-language', 'en_US')} {archinstall.arguments.get('sys-encoding', 'UTF-8').upper()}"
|
|
||||||
|
|
||||||
disk_encryption: disk.DiskEncryption = archinstall.arguments.get('disk_encryption', None)
|
disk_encryption: disk.DiskEncryption = archinstall.arguments.get('disk_encryption', None)
|
||||||
|
|
||||||
with Installer(
|
with Installer(
|
||||||
|
|
@ -147,7 +142,7 @@ def perform_installation(mountpoint: Path):
|
||||||
testing=enable_testing,
|
testing=enable_testing,
|
||||||
multilib=enable_multilib,
|
multilib=enable_multilib,
|
||||||
hostname=archinstall.arguments.get('hostname', 'archlinux'),
|
hostname=archinstall.arguments.get('hostname', 'archlinux'),
|
||||||
locales=[locale]
|
locale_config=locale_config
|
||||||
)
|
)
|
||||||
|
|
||||||
if mirror_config := archinstall.arguments.get('mirror_config', None):
|
if mirror_config := archinstall.arguments.get('mirror_config', None):
|
||||||
|
|
@ -210,7 +205,7 @@ def perform_installation(mountpoint: Path):
|
||||||
|
|
||||||
# This step must be after profile installs to allow profiles_bck to install language pre-requisits.
|
# This step must be after profile installs to allow profiles_bck to install language pre-requisits.
|
||||||
# After which, this step will set the language both for console and x11 if x11 was installed for instance.
|
# After which, this step will set the language both for console and x11 if x11 was installed for instance.
|
||||||
installation.set_keyboard_language(archinstall.arguments['keyboard-layout'])
|
installation.set_keyboard_language(locale_config.kb_layout)
|
||||||
|
|
||||||
if profile_config := archinstall.arguments.get('profile_config', None):
|
if profile_config := archinstall.arguments.get('profile_config', None):
|
||||||
profile_config.profile.post_install(installation)
|
profile_config.profile.post_install(installation)
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,7 @@ from archinstall import SysInfo, info, debug
|
||||||
from archinstall.lib import mirrors
|
from archinstall.lib import mirrors
|
||||||
from archinstall.lib import models
|
from archinstall.lib import models
|
||||||
from archinstall.lib import disk
|
from archinstall.lib import disk
|
||||||
|
from archinstall.lib import locale
|
||||||
from archinstall.lib.networking import check_mirror_reachable
|
from archinstall.lib.networking import check_mirror_reachable
|
||||||
from archinstall.lib.profile.profiles_handler import profile_handler
|
from archinstall.lib.profile.profiles_handler import profile_handler
|
||||||
from archinstall.lib import menu
|
from archinstall.lib import menu
|
||||||
|
|
@ -92,14 +93,14 @@ class SwissMainMenu(GlobalMenu):
|
||||||
match self._execution_mode:
|
match self._execution_mode:
|
||||||
case ExecutionMode.Full | ExecutionMode.Lineal:
|
case ExecutionMode.Full | ExecutionMode.Lineal:
|
||||||
options_list = [
|
options_list = [
|
||||||
'keyboard-layout', 'mirror_config', 'disk_config',
|
'mirror_config', 'disk_config',
|
||||||
'disk_encryption', 'swap', 'bootloader', 'hostname', '!root-password',
|
'disk_encryption', 'swap', 'bootloader', 'hostname', '!root-password',
|
||||||
'!users', 'profile_config', 'audio', 'kernels', 'packages', 'additional-repositories', 'nic',
|
'!users', 'profile_config', 'audio', 'kernels', 'packages', 'additional-repositories', 'nic',
|
||||||
'timezone', 'ntp'
|
'timezone', 'ntp'
|
||||||
]
|
]
|
||||||
|
|
||||||
if archinstall.arguments.get('advanced', False):
|
if archinstall.arguments.get('advanced', False):
|
||||||
options_list.extend(['sys-language', 'sys-encoding'])
|
options_list.extend(['locale_config'])
|
||||||
|
|
||||||
mandatory_list = ['disk_config', 'bootloader', 'hostname']
|
mandatory_list = ['disk_config', 'bootloader', 'hostname']
|
||||||
case ExecutionMode.Only_HD:
|
case ExecutionMode.Only_HD:
|
||||||
|
|
@ -107,7 +108,7 @@ class SwissMainMenu(GlobalMenu):
|
||||||
mandatory_list = ['disk_config']
|
mandatory_list = ['disk_config']
|
||||||
case ExecutionMode.Only_OS:
|
case ExecutionMode.Only_OS:
|
||||||
options_list = [
|
options_list = [
|
||||||
'keyboard-layout', 'mirror_config','bootloader', 'hostname',
|
'mirror_config','bootloader', 'hostname',
|
||||||
'!root-password', '!users', 'profile_config', 'audio', 'kernels',
|
'!root-password', '!users', 'profile_config', 'audio', 'kernels',
|
||||||
'packages', 'additional-repositories', 'nic', 'timezone', 'ntp'
|
'packages', 'additional-repositories', 'nic', 'timezone', 'ntp'
|
||||||
]
|
]
|
||||||
|
|
@ -115,7 +116,7 @@ class SwissMainMenu(GlobalMenu):
|
||||||
mandatory_list = ['hostname']
|
mandatory_list = ['hostname']
|
||||||
|
|
||||||
if archinstall.arguments.get('advanced', False):
|
if archinstall.arguments.get('advanced', False):
|
||||||
options_list += ['sys-language','sys-encoding']
|
options_list += ['locale_config']
|
||||||
case ExecutionMode.Minimal:
|
case ExecutionMode.Minimal:
|
||||||
pass
|
pass
|
||||||
case _:
|
case _:
|
||||||
|
|
@ -176,8 +177,7 @@ def perform_installation(mountpoint: Path, exec_mode: ExecutionMode):
|
||||||
|
|
||||||
enable_testing = 'testing' in archinstall.arguments.get('additional-repositories', [])
|
enable_testing = 'testing' in archinstall.arguments.get('additional-repositories', [])
|
||||||
enable_multilib = 'multilib' in archinstall.arguments.get('additional-repositories', [])
|
enable_multilib = 'multilib' in archinstall.arguments.get('additional-repositories', [])
|
||||||
|
locale_config: locale.LocaleConfiguration = archinstall.arguments['locale_config']
|
||||||
locale = f"{archinstall.arguments.get('sys-language', 'en_US')} {archinstall.arguments.get('sys-encoding', 'UTF-8').upper()}"
|
|
||||||
|
|
||||||
with Installer(
|
with Installer(
|
||||||
mountpoint,
|
mountpoint,
|
||||||
|
|
@ -206,7 +206,7 @@ def perform_installation(mountpoint: Path, exec_mode: ExecutionMode):
|
||||||
testing=enable_testing,
|
testing=enable_testing,
|
||||||
multilib=enable_multilib,
|
multilib=enable_multilib,
|
||||||
hostname=archinstall.arguments.get('hostname', 'archlinux'),
|
hostname=archinstall.arguments.get('hostname', 'archlinux'),
|
||||||
locales=[locale]
|
locale_config=locale_config
|
||||||
)
|
)
|
||||||
|
|
||||||
if mirror_config := archinstall.arguments.get('mirror_config', None):
|
if mirror_config := archinstall.arguments.get('mirror_config', None):
|
||||||
|
|
@ -263,7 +263,7 @@ def perform_installation(mountpoint: Path, exec_mode: ExecutionMode):
|
||||||
|
|
||||||
# This step must be after profile installs to allow profiles_bck to install language pre-requisits.
|
# This step must be after profile installs to allow profiles_bck to install language pre-requisits.
|
||||||
# After which, this step will set the language both for console and x11 if x11 was installed for instance.
|
# After which, this step will set the language both for console and x11 if x11 was installed for instance.
|
||||||
installation.set_keyboard_language(archinstall.arguments['keyboard-layout'])
|
installation.set_keyboard_language(locale_config.kb_layout)
|
||||||
|
|
||||||
if profile_config := archinstall.arguments.get('profile_config', None):
|
if profile_config := archinstall.arguments.get('profile_config', None):
|
||||||
profile_config.profile.post_install(installation)
|
profile_config.profile.post_install(installation)
|
||||||
|
|
|
||||||
|
|
@ -10,6 +10,7 @@ from archinstall.default_profiles.applications.pipewire import PipewireProfile
|
||||||
from archinstall import disk
|
from archinstall import disk
|
||||||
from archinstall import menu
|
from archinstall import menu
|
||||||
from archinstall import models
|
from archinstall import models
|
||||||
|
from archinstall import locale
|
||||||
from archinstall import info, debug
|
from archinstall import info, debug
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
|
|
@ -21,14 +22,10 @@ def ask_user_questions():
|
||||||
|
|
||||||
global_menu.enable('archinstall-language')
|
global_menu.enable('archinstall-language')
|
||||||
|
|
||||||
global_menu.enable('keyboard-layout')
|
|
||||||
|
|
||||||
# Set which region to download packages from during the installation
|
# Set which region to download packages from during the installation
|
||||||
global_menu.enable('mirror_config')
|
global_menu.enable('mirror_config')
|
||||||
|
|
||||||
global_menu.enable('sys-language')
|
global_menu.enable('locale_config')
|
||||||
|
|
||||||
global_menu.enable('sys-encoding')
|
|
||||||
|
|
||||||
global_menu.enable('disk_config', mandatory=True)
|
global_menu.enable('disk_config', mandatory=True)
|
||||||
|
|
||||||
|
|
@ -55,7 +52,7 @@ def ask_user_questions():
|
||||||
global_menu.enable('audio')
|
global_menu.enable('audio')
|
||||||
|
|
||||||
# Ask for preferred kernel:
|
# Ask for preferred kernel:
|
||||||
global_menu.enable('kernels')
|
global_menu.enable('kernels', mandatory=True)
|
||||||
|
|
||||||
global_menu.enable('packages')
|
global_menu.enable('packages')
|
||||||
|
|
||||||
|
|
@ -93,9 +90,7 @@ def perform_installation(mountpoint: Path):
|
||||||
# Retrieve list of additional repositories and set boolean values appropriately
|
# Retrieve list of additional repositories and set boolean values appropriately
|
||||||
enable_testing = 'testing' in archinstall.arguments.get('additional-repositories', [])
|
enable_testing = 'testing' in archinstall.arguments.get('additional-repositories', [])
|
||||||
enable_multilib = 'multilib' in archinstall.arguments.get('additional-repositories', [])
|
enable_multilib = 'multilib' in archinstall.arguments.get('additional-repositories', [])
|
||||||
|
locale_config: locale.LocaleConfiguration = archinstall.arguments['locale_config']
|
||||||
locale = f"{archinstall.arguments.get('sys-language', 'en_US')} {archinstall.arguments.get('sys-encoding', 'UTF-8').upper()}"
|
|
||||||
|
|
||||||
disk_encryption: disk.DiskEncryption = archinstall.arguments.get('disk_encryption', None)
|
disk_encryption: disk.DiskEncryption = archinstall.arguments.get('disk_encryption', None)
|
||||||
|
|
||||||
with Installer(
|
with Installer(
|
||||||
|
|
@ -126,7 +121,7 @@ def perform_installation(mountpoint: Path):
|
||||||
testing=enable_testing,
|
testing=enable_testing,
|
||||||
multilib=enable_multilib,
|
multilib=enable_multilib,
|
||||||
hostname=archinstall.arguments.get('hostname', 'archlinux'),
|
hostname=archinstall.arguments.get('hostname', 'archlinux'),
|
||||||
locales=[locale]
|
locale_config=locale_config
|
||||||
)
|
)
|
||||||
|
|
||||||
if mirror_config := archinstall.arguments.get('mirror_config', None):
|
if mirror_config := archinstall.arguments.get('mirror_config', None):
|
||||||
|
|
@ -189,7 +184,7 @@ def perform_installation(mountpoint: Path):
|
||||||
|
|
||||||
# This step must be after profile installs to allow profiles_bck to install language pre-requisits.
|
# This step must be after profile installs to allow profiles_bck to install language pre-requisits.
|
||||||
# After which, this step will set the language both for console and x11 if x11 was installed for instance.
|
# After which, this step will set the language both for console and x11 if x11 was installed for instance.
|
||||||
installation.set_keyboard_language(archinstall.arguments['keyboard-layout'])
|
installation.set_keyboard_language(locale_config.kb_layout)
|
||||||
|
|
||||||
if profile_config := archinstall.arguments.get('profile_config', None):
|
if profile_config := archinstall.arguments.get('profile_config', None):
|
||||||
profile_config.profile.post_install(installation)
|
profile_config.profile.post_install(installation)
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue