Added locale helpers in terms of keyboard language/layout. archinstall.list_keyboard_languages(), archinstall.search_keyboard_layout() and archinstall.set_keyboard_language() work together to help listing, finding and setting a keyboard layout in terminals. Won't work for X-frontends, but will do for CLI installation methods. Added a language selector-helper-function with a crude search functionality. Added all this to the guided template.

This commit is contained in:
Anton Hvornum 2020-09-01 09:01:14 +02:00
parent e4b9ad9d37
commit 8f35f44939
4 changed files with 106 additions and 28 deletions

View File

@ -6,4 +6,5 @@ from .lib.installer import *
from .lib.profiles import * from .lib.profiles import *
from .lib.luks import * from .lib.luks import *
from .lib.mirrors import * from .lib.mirrors import *
from .lib.networking import * from .lib.networking import *
from .lib.locale_helpers import *

View File

@ -0,0 +1,29 @@
import os
from .exceptions import *
# from .general import sys_command
def list_keyboard_languages(layout='qwerty'):
locale_dir = '/usr/share/kbd/keymaps/'
if not os.path.isdir(locale_dir):
raise RequirementError(f'Directory containing locales does not excist: {locale_dir}')
for root, folders, files in os.walk(locale_dir):
# Since qwerty is under /i386/ but other layouts are
# in different spots, we'll need to filter the last foldername
# of the path to verify against the desired layout.
if os.path.basename(root) != layout:
continue
for file in files:
if os.path.splitext(file)[1] == '.gz':
yield file.strip('.gz').strip('.map')
def search_keyboard_layout(filter, layout='qwerty'):
for language in list_keyboard_languages(layout):
if filter.lower() in language.lower():
yield language
def set_keyboard_language(locale):
return os.system(f'loadkeys {locale}') == 0

View File

@ -1,8 +1,9 @@
from .exceptions import * from .exceptions import *
from .locale_helpers import search_keyboard_layout
def select_disk(dict_o_disks): def select_disk(dict_o_disks):
drives = sorted(list(dict_o_disks.keys())) drives = sorted(list(dict_o_disks.keys()))
if len(drives) > 1: if len(drives) >= 1:
for index, drive in enumerate(drives): for index, drive in enumerate(drives):
print(f"{index}: {drive} ({dict_o_disks[drive]['size'], dict_o_disks[drive].device, dict_o_disks[drive]['label']})") print(f"{index}: {drive} ({dict_o_disks[drive]['size'], dict_o_disks[drive].device, dict_o_disks[drive]['label']})")
drive = input('Select one of the above disks (by number or full path): ') drive = input('Select one of the above disks (by number or full path): ')
@ -14,4 +15,35 @@ def select_disk(dict_o_disks):
raise DiskError(f'Selected drive does not exist: "{drive}"') raise DiskError(f'Selected drive does not exist: "{drive}"')
return drive return drive
raise DiskError('select_disk() requires a non-empty dictionary of disks to select from.') raise DiskError('select_disk() requires a non-empty dictionary of disks to select from.')
def select_language(options, show_only_country_codes=True):
if show_only_country_codes:
languages = sorted([language for language in list(options) if len(language) == 2])
else:
languages = sorted(list(options))
if len(languages) >= 1:
for index, language in enumerate(languages):
print(f"{index}: {language}")
print(' -- You can enter ? or help to search for more languages --')
selected_language = input('Select one of the above keyboard languages (by number or full name): ')
if selected_language.lower() in ('?', 'help'):
filter_string = input('Search for layout containing (example: "sv-"): ')
new_options = search_keyboard_layout(filter_string)
return select_language(new_options, show_only_country_codes=False)
elif selected_language.isdigit() and (pos := int(selected_language)) <= len(languages)-1:
selected_language = languages[pos]
# I'm leaving "options" on purpose here.
# Since languages possibly contains a filtered version of
# all possible language layouts, and we might want to write
# for instance sv-latin1 (if we know that exists) without havnig to
# go through the search step.
elif selected_language in options:
selected_language = options[options.index(selected_language)]
else:
RequirementError("Selected language does not exist.")
return selected_language
raise RequirementError("Selecting languages require a least one language to be given as an option.")

View File

@ -1,6 +1,35 @@
import archinstall, getpass, time import archinstall, getpass, time
# Unmount and close previous runs def perform_installation(device, boot_partition):
"""
Performs the installation steps on a block device.
Only requirement is that the block devices are
formatted and setup prior to entering this function.
"""
with archinstall.Installer(device, boot_partition=boot_partition, hostname=hostname) as installation:
if installation.minimal_installation():
installation.add_bootloader()
if len(packages) and packages[0] != '':
installation.add_additional_packages(packages)
if len(profile.strip()):
installation.install_profile(profile)
for user, password in users.items():
sudo = False
if len(root_pw.strip()) == 0:
sudo = True
installation.user_create(user, password, sudo=sudo)
if root_pw:
installation.user_set_pw('root', root_pw)
if len(aur.strip()):
installation.add_AUR_support()
# Unmount and close previous runs (in case the installer is restarted)
archinstall.sys_command(f'umount -R /mnt', surpress_errors=True) archinstall.sys_command(f'umount -R /mnt', surpress_errors=True)
archinstall.sys_command(f'cryptsetup close /dev/mapper/luksloop', surpress_errors=True) archinstall.sys_command(f'cryptsetup close /dev/mapper/luksloop', surpress_errors=True)
@ -9,6 +38,10 @@ archinstall.sys_command(f'cryptsetup close /dev/mapper/luksloop', surpress_error
Not until we're satisfied with what we want to install Not until we're satisfied with what we want to install
will we continue with the actual installation steps. will we continue with the actual installation steps.
""" """
keyboard_language = archinstall.select_language(archinstall.list_keyboard_languages())
archinstall.set_keyboard_language(keyboard_language)
harddrive = archinstall.select_disk(archinstall.all_disks()) harddrive = archinstall.select_disk(archinstall.all_disks())
while (disk_password := getpass.getpass(prompt='Enter disk encryption password (leave blank for no encryption): ')): while (disk_password := getpass.getpass(prompt='Enter disk encryption password (leave blank for no encryption): ')):
disk_password_verification = getpass.getpass(prompt='And one more time for verification: ') disk_password_verification = getpass.getpass(prompt='And one more time for verification: ')
@ -16,6 +49,7 @@ while (disk_password := getpass.getpass(prompt='Enter disk encryption password (
archinstall.log(' * Passwords did not match * ', bg='black', fg='red') archinstall.log(' * Passwords did not match * ', bg='black', fg='red')
continue continue
break break
hostname = input('Desired hostname for the installation: ') hostname = input('Desired hostname for the installation: ')
if len(hostname) == 0: hostname = 'ArchInstall' if len(hostname) == 0: hostname = 'ArchInstall'
@ -69,30 +103,10 @@ time.sleep(1)
print(f' ! Formatting {harddrive} in 1...') print(f' ! Formatting {harddrive} in 1...')
time.sleep(1) time.sleep(1)
def perform_installation(device, boot_partition): """
with archinstall.Installer(device, boot_partition=boot_partition, hostname=hostname) as installation: Setup the blockdevice, filesystem (and optionally encryption).
if installation.minimal_installation(): Once that's done, we'll hand over to perform_installation()
installation.add_bootloader() """
if len(packages) and packages[0] != '':
installation.add_additional_packages(packages)
if len(profile.strip()):
installation.install_profile(profile)
for user, password in users.items():
sudo = False
if len(root_pw.strip()) == 0:
sudo = True
installation.user_create(user, password, sudo=sudo)
if root_pw:
installation.user_set_pw('root', root_pw)
if len(aur.strip()):
installation.add_AUR_support()
with archinstall.Filesystem(harddrive, archinstall.GPT) as fs: with archinstall.Filesystem(harddrive, archinstall.GPT) as fs:
# Use partitioning helper to set up the disk partitions. # Use partitioning helper to set up the disk partitions.
if disk_password: if disk_password:
@ -106,6 +120,8 @@ with archinstall.Filesystem(harddrive, archinstall.GPT) as fs:
if disk_password: if disk_password:
# First encrypt and unlock, then format the desired partition inside the encrypted part. # First encrypt and unlock, then format the desired partition inside the encrypted part.
# archinstall.luks2() encrypts the partition when entering the with context manager, and
# unlocks the drive so that it can be used as a normal block-device within archinstall.
with archinstall.luks2(harddrive.partition[1], 'luksloop', disk_password) as unlocked_device: with archinstall.luks2(harddrive.partition[1], 'luksloop', disk_password) as unlocked_device:
unlocked_device.format('btrfs') unlocked_device.format('btrfs')