Compare commits
19
Commits
No files matched your search
@@ -711,17 +711,17 @@ drive_provision_owner() {
|
|||||||
log "Driving the deferred-provisioning first-boot setup"
|
log "Driving the deferred-provisioning first-boot setup"
|
||||||
|
|
||||||
# Deferred provisioning defers the keyboard step to first boot; it comes before the user form.
|
# Deferred provisioning defers the keyboard step to first boot; it comes before the user form.
|
||||||
# Pick English (UK) (one row below the preselected English (US), which leads
|
# Pick English (UK) (one row above the preselected English (US)) so the
|
||||||
# the list) so the verifier can prove the deferred step applied a non-default
|
# verifier can prove the deferred step applied a non-default layout — UK
|
||||||
# layout — UK leaves every letter identical to US, so the typed password (sent
|
# leaves every letter identical to US, so the typed password (sent as raw
|
||||||
# as raw keycodes) still matches the literal one the harness pipes to sudo.
|
# keycodes) still matches the literal one the harness pipes to sudo.
|
||||||
# A greeter (animated logo + tagline) opens first boot; Return begins.
|
# A greeter (animated logo + tagline) opens first boot; Return begins.
|
||||||
wait_for_screen "Opinionated" 600
|
wait_for_screen "Opinionated" 600
|
||||||
capture_console "success-provision-00-greeter"
|
capture_console "success-provision-00-greeter"
|
||||||
press ret
|
press ret
|
||||||
|
|
||||||
wait_for_screen "keyboard layout" 120
|
wait_for_screen "keyboard layout" 120
|
||||||
press down
|
press up
|
||||||
capture_console "success-provision-01-keyboard-layout-uk"
|
capture_console "success-provision-01-keyboard-layout-uk"
|
||||||
press ret
|
press ret
|
||||||
|
|
||||||
|
|||||||
@@ -139,7 +139,6 @@ sed -i -E '/^(linux|broadcom-wl)$/d' "$build_cache_dir/packages.x86_64"
|
|||||||
# pulls the published omarchy* from the network mirror like any other package.
|
# pulls the published omarchy* from the network mirror like any other package.
|
||||||
if [[ -d /omarchy-source ]]; then
|
if [[ -d /omarchy-source ]]; then
|
||||||
base_pkg_lists=(/omarchy-source/install/omarchy-base.packages /omarchy-source/install/omarchy-other.packages)
|
base_pkg_lists=(/omarchy-source/install/omarchy-base.packages /omarchy-source/install/omarchy-other.packages)
|
||||||
setup_form=/omarchy-source/install/provisioning/setup-form.sh
|
|
||||||
else
|
else
|
||||||
# Pull the same package lists out of the freshly-downloaded Omarchy runtime
|
# Pull the same package lists out of the freshly-downloaded Omarchy runtime
|
||||||
# package so we don't need a local checkout in the non-local-source path.
|
# package so we don't need a local checkout in the non-local-source path.
|
||||||
@@ -155,37 +154,12 @@ else
|
|||||||
mkdir -p /tmp/omarchy-pkglists
|
mkdir -p /tmp/omarchy-pkglists
|
||||||
bsdtar -xf "$omarchy_pkg" -C /tmp/omarchy-pkglists usr/share/omarchy/install/omarchy-base.packages usr/share/omarchy/install/omarchy-other.packages
|
bsdtar -xf "$omarchy_pkg" -C /tmp/omarchy-pkglists usr/share/omarchy/install/omarchy-base.packages usr/share/omarchy/install/omarchy-other.packages
|
||||||
base_pkg_lists=(/tmp/omarchy-pkglists/usr/share/omarchy/install/omarchy-base.packages /tmp/omarchy-pkglists/usr/share/omarchy/install/omarchy-other.packages)
|
base_pkg_lists=(/tmp/omarchy-pkglists/usr/share/omarchy/install/omarchy-base.packages /tmp/omarchy-pkglists/usr/share/omarchy/install/omarchy-other.packages)
|
||||||
# Extracted on its own, tolerating a miss: bsdtar exits non-zero for a member
|
|
||||||
# it can't find, so asking for this alongside the package lists would abort the
|
|
||||||
# build here (set -e) with a bare "Not found in archive" instead of the
|
|
||||||
# actionable error below.
|
|
||||||
bsdtar -xf "$omarchy_pkg" -C /tmp/omarchy-pkglists usr/share/omarchy/install/provisioning/setup-form.sh 2>/dev/null || true
|
|
||||||
setup_form=/tmp/omarchy-pkglists/usr/share/omarchy/install/provisioning/setup-form.sh
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
mkdir -p "$build_cache_dir/airootfs/usr/share/omarchy-iso"
|
mkdir -p "$build_cache_dir/airootfs/usr/share/omarchy-iso"
|
||||||
cp "${base_pkg_lists[0]}" "$build_cache_dir/airootfs/usr/share/omarchy-iso/omarchy-base.packages"
|
cp "${base_pkg_lists[0]}" "$build_cache_dir/airootfs/usr/share/omarchy-iso/omarchy-base.packages"
|
||||||
cp "${base_pkg_lists[1]}" "$build_cache_dir/airootfs/usr/share/omarchy-iso/omarchy-other.packages"
|
cp "${base_pkg_lists[1]}" "$build_cache_dir/airootfs/usr/share/omarchy-iso/omarchy-other.packages"
|
||||||
|
|
||||||
# The configurator's setup form comes from the runtime this ISO bundles, so the
|
|
||||||
# installer and the first-boot setup that finishes a deferred install can never
|
|
||||||
# disagree. A runtime predating the split ships no such file, which would leave
|
|
||||||
# the configurator with no prompts at all.
|
|
||||||
if [[ ! -f $setup_form ]]; then
|
|
||||||
if [[ -d /omarchy-source ]]; then
|
|
||||||
echo "ERROR: the --local-source checkout ships no install/provisioning/setup-form.sh" >&2
|
|
||||||
remedy="Update the checkout to a revision carrying the shared setup form."
|
|
||||||
else
|
|
||||||
echo "ERROR: $OMARCHY_RUNTIME_PACKAGE does not ship install/provisioning/setup-form.sh" >&2
|
|
||||||
remedy="Publish a runtime carrying the shared setup form, or build with --local-source against a checkout that has it."
|
|
||||||
fi
|
|
||||||
echo " The configurator sources its prompts from that file, so this ISO" >&2
|
|
||||||
echo " would boot into an installer with no questions to ask." >&2
|
|
||||||
echo " $remedy" >&2
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
cp "$setup_form" "$build_cache_dir/airootfs/usr/share/omarchy-iso/setup-form.sh"
|
|
||||||
|
|
||||||
# Collect every package we want available in the offline mirror.
|
# Collect every package we want available in the offline mirror.
|
||||||
declare -a all_packages
|
declare -a all_packages
|
||||||
mapfile -t all_packages < <(
|
mapfile -t all_packages < <(
|
||||||
|
|||||||
@@ -9,21 +9,6 @@ OMARCHY_SETTINGS_PACKAGE="${OMARCHY_SETTINGS_PACKAGE:-omarchy-settings}"
|
|||||||
|
|
||||||
LOGO_PATH="$OMARCHY_PATH/logo.txt"
|
LOGO_PATH="$OMARCHY_PATH/logo.txt"
|
||||||
|
|
||||||
# The setup form — keyboard, account, hostname, and timezone questions, plus the
|
|
||||||
# rules their answers are checked against — shared verbatim with the first-boot
|
|
||||||
# owner setup that finishes a deferred install. build-iso.sh vendors it out of
|
|
||||||
# the runtime package this ISO bundles, so the two can never offer different
|
|
||||||
# layouts or accept different usernames. On the ISO that vendored copy is what
|
|
||||||
# loads; a dry run outside the ISO falls back to the omarchy checkout
|
|
||||||
# bin/omarchy-iso-configurator already points OMARCHY_PATH at.
|
|
||||||
SETUP_FORM="${SETUP_FORM:-/usr/share/omarchy-iso/setup-form.sh}"
|
|
||||||
[[ -r $SETUP_FORM ]] || SETUP_FORM="$OMARCHY_PATH/install/provisioning/setup-form.sh"
|
|
||||||
if [[ ! -r $SETUP_FORM ]]; then
|
|
||||||
echo "ERROR: shared setup form not found at $SETUP_FORM" >&2
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
source "$SETUP_FORM"
|
|
||||||
|
|
||||||
LOGO_WIDTH=$(awk '{ if (length > max) max = length } END { print max+0 }' "$LOGO_PATH")
|
LOGO_WIDTH=$(awk '{ if (length > max) max = length } END { print max+0 }' "$LOGO_PATH")
|
||||||
|
|
||||||
export GUM_CONFIRM_PROMPT_FOREGROUND="6"
|
export GUM_CONFIRM_PROMPT_FOREGROUND="6"
|
||||||
@@ -192,32 +177,76 @@ keyboard_form() {
|
|||||||
# screen is the hidden entry into deferred provisioning; $1 is "true" only for that first
|
# screen is the hidden entry into deferred provisioning; $1 is "true" only for that first
|
||||||
# invocation, so the review-loop re-edit can't flip a user install into it.
|
# invocation, so the review-loop re-edit can't flip a user install into it.
|
||||||
local allow_defer_provisioning="${1:-false}"
|
local allow_defer_provisioning="${1:-false}"
|
||||||
local status
|
clear_logo
|
||||||
|
echo
|
||||||
|
say "Let's setup your machine..."
|
||||||
|
if $allow_defer_provisioning; then
|
||||||
|
say --foreground 8 "Press Ctrl+C to prepare this machine for another owner."
|
||||||
|
fi
|
||||||
|
echo
|
||||||
|
|
||||||
while true; do
|
keyboards=$'Azerbaijani|azerty
|
||||||
clear_logo
|
Belarusian|by
|
||||||
echo
|
Belgian|be-latin1
|
||||||
say "Let's setup your machine..."
|
Bulgarian|bg-cp1251
|
||||||
if $allow_defer_provisioning; then
|
Croatian|croat
|
||||||
say --foreground 8 "Press Ctrl+C to prepare this machine for another owner."
|
Czech|cz
|
||||||
|
Danish|dk-latin1
|
||||||
|
Dutch|nl
|
||||||
|
English (UK)|uk
|
||||||
|
English (US)|us
|
||||||
|
English (US, Dvorak)|dvorak
|
||||||
|
English (US, Colemak)|colemak
|
||||||
|
Estonian|et
|
||||||
|
Finnish|fi
|
||||||
|
French|fr
|
||||||
|
French (Canada)|cf
|
||||||
|
French (Switzerland)|fr_CH
|
||||||
|
Georgian|ge
|
||||||
|
German|de
|
||||||
|
German (Switzerland)|de_CH-latin1
|
||||||
|
Greek|gr
|
||||||
|
Hebrew|il
|
||||||
|
Hungarian|hu
|
||||||
|
Icelandic|is-latin1
|
||||||
|
Irish|ie
|
||||||
|
Italian|it
|
||||||
|
Japanese|jp106
|
||||||
|
Kazakh|kazakh
|
||||||
|
Kyrgyz|kyrgyz
|
||||||
|
Lao|la-latin1
|
||||||
|
Latvian|lv
|
||||||
|
Lithuanian|lt
|
||||||
|
Macedonian|mk-utf
|
||||||
|
Norwegian|no-latin1
|
||||||
|
Polish|pl
|
||||||
|
Portuguese|pt-latin1
|
||||||
|
Portuguese (Brazil)|br-abnt2
|
||||||
|
Romanian|ro
|
||||||
|
Russian|ru
|
||||||
|
Serbian|sr-latin
|
||||||
|
Slovak|sk-qwertz
|
||||||
|
Slovenian|slovene
|
||||||
|
Spanish|es
|
||||||
|
Spanish (Latin American)|la-latin1
|
||||||
|
Swedish|sv-latin1
|
||||||
|
Tajik|tj_alt-UTF8
|
||||||
|
Turkish|trq
|
||||||
|
Ukrainian|ua'
|
||||||
|
choice=$(printf '%s\n' "$keyboards" | cut -d'|' -f1 | gum choose --height 10 --selected "English (US)" --header "Select keyboard layout")
|
||||||
|
local status=$?
|
||||||
|
|
||||||
|
if $allow_defer_provisioning && (( status == 130 )); then
|
||||||
|
if confirm_prepare_for_another_owner; then
|
||||||
|
defer_provisioning=true
|
||||||
|
return 0
|
||||||
fi
|
fi
|
||||||
echo
|
keyboard_form true # declined: back to the keyboard picker
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
(( status == 0 )) || abort
|
||||||
|
|
||||||
omarchy_prompt_keyboard && status=0 || status=$?
|
keyboard=$(printf '%s\n' "$keyboards" | awk -F'|' -v c="$choice" '$1==c{print $2; exit}')
|
||||||
((status == 0)) && break
|
|
||||||
|
|
||||||
# Esc means "back", and nothing precedes the first screen, so re-ask.
|
|
||||||
((status == OMARCHY_FORM_BACK)) && continue
|
|
||||||
|
|
||||||
if $allow_defer_provisioning && ((status == OMARCHY_FORM_SIGNAL)); then
|
|
||||||
if confirm_prepare_for_another_owner; then
|
|
||||||
defer_provisioning=true
|
|
||||||
return 0
|
|
||||||
fi
|
|
||||||
continue # declined: back to the keyboard picker
|
|
||||||
fi
|
|
||||||
abort
|
|
||||||
done
|
|
||||||
|
|
||||||
# Only attempt to load keyboard layout if we're on a real console
|
# Only attempt to load keyboard layout if we're on a real console
|
||||||
# loadkeys only works on Linux virtual consoles (tty), not in terminal emulators
|
# loadkeys only works on Linux virtual consoles (tty), not in terminal emulators
|
||||||
@@ -246,34 +275,66 @@ confirm_prepare_for_another_owner() {
|
|||||||
user_form() {
|
user_form() {
|
||||||
step "Let's setup your user account..."
|
step "Let's setup your user account..."
|
||||||
|
|
||||||
# Each prompt reports 0 (set), OMARCHY_FORM_BACK (Esc), or OMARCHY_FORM_SIGNAL
|
while true; do
|
||||||
# (Ctrl+C). Both non-zero cases unwind to user_step, which decides what they
|
username=$(gum input --placeholder "Alphanumeric without spaces (like dhh)" --prompt.foreground="#845DF9" --prompt "Username> ") || abort
|
||||||
# mean here; the form itself never aborts.
|
|
||||||
omarchy_prompt_username || return $?
|
|
||||||
omarchy_prompt_password || return $?
|
|
||||||
|
|
||||||
# Hash the password with SHA-512 crypt ($6$), which is what openssl passwd offers
|
if [[ "$username" =~ ^[a-z_][a-z0-9_-]*[$]?$ ]]; then
|
||||||
|
if [[ "$username" =~ ^(root|bin|daemon|mail|ftp|http|nobody|dbus|systemd-coredump|systemd-network|systemd-oom|systemd-journal-remote|systemd-resolve|systemd-timesync|tss|uuidd|alpm|git|avahi|cups|lp|_talkd|polkitd|rtkit|qemu|brltty|gluster|rpc|libvirt-qemu|pcscd|nvidia-persistenced|sddm)$ ]] ; then
|
||||||
|
notice "Username is reserved for system" 1
|
||||||
|
else
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
notice "Username must be alphanumeric with no spaces" 1
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
while true; do
|
||||||
|
password=$(gum input --placeholder "Used for user + root, and disk encryption when enabled" --prompt.foreground="#845DF9" --password --prompt "Password> ") || abort
|
||||||
|
password_confirmation=$(gum input --placeholder "Must match the password you just typed" --prompt.foreground="#845DF9" --password --prompt "Confirm> ") || abort
|
||||||
|
|
||||||
|
if [[ -n "$password" && "$password" == "$password_confirmation" ]]; then
|
||||||
|
break
|
||||||
|
elif [[ -z "$password" ]]; then
|
||||||
|
notice "Your password can't be blank!" 1
|
||||||
|
else
|
||||||
|
notice "Passwords didn't match!" 1
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
# Hash the password using yescrypt
|
||||||
password_hash=$(printf '%s' "$password" | openssl passwd -6 -stdin)
|
password_hash=$(printf '%s' "$password" | openssl passwd -6 -stdin)
|
||||||
|
|
||||||
omarchy_prompt_identity || return $?
|
full_name=$(gum input --placeholder "Used for git authentication (hit return to skip)" --prompt.foreground="#845DF9" --prompt "Full name> ")
|
||||||
omarchy_prompt_hostname || return $?
|
email_address=$(gum input --placeholder "Used for git authentication (hit return to skip)" --prompt.foreground="#845DF9" --prompt "Email address> ")
|
||||||
omarchy_prompt_timezone || return $?
|
|
||||||
|
while true; do
|
||||||
|
hostname=$(gum input --placeholder "Letters, digits, and dashes (or return for 'omarchy')" --prompt.foreground="#845DF9" --prompt "Hostname> ")
|
||||||
|
|
||||||
|
if [[ "$hostname" =~ ^[A-Za-z0-9]([A-Za-z0-9-]{0,61}[A-Za-z0-9])?$ ]]; then
|
||||||
|
break
|
||||||
|
elif [[ -z $hostname ]]; then
|
||||||
|
hostname="omarchy"
|
||||||
|
break
|
||||||
|
else
|
||||||
|
notice "Hostname must be 1-63 letters, digits, or dashes, and cannot start or end with a dash" 1
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
# Pick timezone
|
||||||
|
geo_guessed_timezone=$(tzupdate -p 2>/dev/null)
|
||||||
|
|
||||||
|
if [[ -n $geo_guessed_timezone ]]; then
|
||||||
|
timezone=$(timedatectl list-timezones | gum choose --height 10 --selected "$geo_guessed_timezone" --header "Timezone") || abort
|
||||||
|
else
|
||||||
|
timezone=$(timedatectl list-timezones | gum filter --height 10 --header "Timezone") || abort
|
||||||
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
user_step() {
|
user_step() {
|
||||||
local status
|
user_form
|
||||||
|
|
||||||
while true; do
|
while true; do
|
||||||
user_form && status=0 || status=$?
|
|
||||||
if ((status != 0)); then
|
|
||||||
# Esc unwinds to the start of the form. Ctrl+C has no side channel in the
|
|
||||||
# user step (only the keyboard and disk screens give it a meaning), so it
|
|
||||||
# keeps its long-standing behaviour of ending the install.
|
|
||||||
((status == OMARCHY_FORM_BACK)) || abort
|
|
||||||
keyboard_form
|
|
||||||
continue
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Add manual padding since gum table -p doesn't respect padding
|
# Add manual padding since gum table -p doesn't respect padding
|
||||||
echo -e "Field,Value
|
echo -e "Field,Value
|
||||||
Username,$username
|
Username,$username
|
||||||
@@ -290,6 +351,7 @@ Keyboard,$keyboard" |
|
|||||||
break
|
break
|
||||||
else
|
else
|
||||||
keyboard_form
|
keyboard_form
|
||||||
|
user_form
|
||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
}
|
}
|
||||||
@@ -507,9 +569,8 @@ run_partition_decide() {
|
|||||||
bl_part=$(detect_bitlocker || true)
|
bl_part=$(detect_bitlocker || true)
|
||||||
if [[ -n "$bl_part" ]]; then
|
if [[ -n "$bl_part" ]]; then
|
||||||
say --foreground 1 "BitLocker signature detected on $bl_part."
|
say --foreground 1 "BitLocker signature detected on $bl_part."
|
||||||
say "Turn BitLocker off in Windows and wait for the drive to finish decrypting, then try again."
|
say "Suspend or disable BitLocker in Windows before installing alongside it."
|
||||||
say "Suspending BitLocker is not enough — the drive stays encrypted."
|
abort "Aborted: BitLocker is active on this disk."
|
||||||
abort "Aborted: BitLocker is enabled on this disk."
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Omarchy always creates its own dedicated ESP in free space and never
|
# Omarchy always creates its own dedicated ESP in free space and never
|
||||||
|
|||||||
@@ -18,9 +18,8 @@ from pathlib import Path
|
|||||||
def configure_keyboard(target: Path, language: str) -> bool:
|
def configure_keyboard(target: Path, language: str) -> bool:
|
||||||
"""Write the console keymap into a mounted target without booting it.
|
"""Write the console keymap into a mounted target without booting it.
|
||||||
|
|
||||||
Returns False for layouts localectl doesn't know, matching archinstall:
|
Returns False for layouts localectl doesn't know (the configurator offers
|
||||||
warn and keep the default. Every layout the configurator offers is known;
|
two, ba and khmer), matching archinstall: warn and keep the default.
|
||||||
the guard is for the kb_layout an autoinstall drive can name freely.
|
|
||||||
"""
|
"""
|
||||||
if not language.strip():
|
if not language.strip():
|
||||||
return True
|
return True
|
||||||
|
|||||||
+14
-30
@@ -14,30 +14,14 @@ KEYBOARD = importlib.util.module_from_spec(SPEC)
|
|||||||
assert SPEC.loader
|
assert SPEC.loader
|
||||||
SPEC.loader.exec_module(KEYBOARD)
|
SPEC.loader.exec_module(KEYBOARD)
|
||||||
|
|
||||||
# The layout list lives in the Omarchy runtime now, shared verbatim with the
|
CONFIGURATOR = (ROOT / "configs/airootfs/root/configurator").read_text()
|
||||||
# first-boot owner setup; build-iso.sh vendors it onto the ISO. Read it from
|
KEYBOARD_BLOCK = re.search(r"keyboards=\$'(.*?)'\n choice=", CONFIGURATOR, re.DOTALL)
|
||||||
# wherever this checkout can see a runtime, and skip the coverage test rather
|
assert KEYBOARD_BLOCK
|
||||||
# than fail when none is around (a bare CI checkout of just this repo).
|
SUPPORTED_KEYMAPS = [
|
||||||
SETUP_FORM_CANDIDATES = (
|
line.split("|", 1)[1]
|
||||||
Path("/omarchy-source/install/provisioning/setup-form.sh"),
|
for line in KEYBOARD_BLOCK.group(1).splitlines()
|
||||||
ROOT.parent / "omarchy/install/provisioning/setup-form.sh",
|
]
|
||||||
Path("/usr/share/omarchy/install/provisioning/setup-form.sh"),
|
UNSUPPORTED_KEYMAPS = {"ba", "khmer"}
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
def supported_keymaps():
|
|
||||||
for candidate in SETUP_FORM_CANDIDATES:
|
|
||||||
if not candidate.is_file():
|
|
||||||
continue
|
|
||||||
block = re.search(
|
|
||||||
r"OMARCHY_KEYBOARD_LAYOUTS=\$'(.*?)'\n", candidate.read_text(), re.DOTALL
|
|
||||||
)
|
|
||||||
assert block, f"no layout list in {candidate}"
|
|
||||||
return [line.split("|", 1)[1] for line in block.group(1).splitlines()]
|
|
||||||
return None
|
|
||||||
|
|
||||||
|
|
||||||
SUPPORTED_KEYMAPS = supported_keymaps()
|
|
||||||
|
|
||||||
|
|
||||||
class KeyboardConfigurationTest(unittest.TestCase):
|
class KeyboardConfigurationTest(unittest.TestCase):
|
||||||
@@ -61,15 +45,15 @@ class KeyboardConfigurationTest(unittest.TestCase):
|
|||||||
self.assertEqual(lines.count("FONT=default8x16"), 1)
|
self.assertEqual(lines.count("FONT=default8x16"), 1)
|
||||||
|
|
||||||
def test_all_configurator_keymaps_are_known_to_localectl(self):
|
def test_all_configurator_keymaps_are_known_to_localectl(self):
|
||||||
if SUPPORTED_KEYMAPS is None:
|
|
||||||
self.skipTest("no Omarchy runtime checkout to read the layout list from")
|
|
||||||
for keymap in SUPPORTED_KEYMAPS:
|
for keymap in SUPPORTED_KEYMAPS:
|
||||||
with self.subTest(keymap=keymap), tempfile.TemporaryDirectory() as directory:
|
with self.subTest(keymap=keymap), tempfile.TemporaryDirectory() as directory:
|
||||||
target = self.target(directory)
|
target = self.target(directory)
|
||||||
self.assertTrue(KEYBOARD.configure_keyboard(target, keymap))
|
configured = KEYBOARD.configure_keyboard(target, keymap)
|
||||||
lines = (target / "etc/vconsole.conf").read_text().splitlines()
|
self.assertEqual(configured, keymap not in UNSUPPORTED_KEYMAPS)
|
||||||
self.assertIn(f"KEYMAP={keymap}", lines)
|
if configured:
|
||||||
self.assertEqual(lines.count("FONT=default8x16"), 1)
|
lines = (target / "etc/vconsole.conf").read_text().splitlines()
|
||||||
|
self.assertIn(f"KEYMAP={keymap}", lines)
|
||||||
|
self.assertEqual(lines.count("FONT=default8x16"), 1)
|
||||||
|
|
||||||
def test_unknown_and_empty_keymaps_match_archinstall_behavior(self):
|
def test_unknown_and_empty_keymaps_match_archinstall_behavior(self):
|
||||||
for keymap, expected in (("definitely-not-a-keymap", False), ("", True)):
|
for keymap, expected in (("definitely-not-a-keymap", False), ("", True)):
|
||||||
|
|||||||
Reference in new issue
Block a user