From 0913adf00ec77d460447d29038f5c7ff5e911aba Mon Sep 17 00:00:00 2001 From: Stefan Strobl Date: Wed, 24 Dec 2025 20:44:53 +0100 Subject: [PATCH] feat(config): add prompts for locale, timezone, and user Extend configuration module with new interactive prompts: - LOCALE: System language (default: en_US.UTF-8) - TIMEZONE: Time zone (default: UTC) - KEYBOARD: Console keyboard layout (default: us) - USERNAME: Standard user account (required) - USER_SHELL: User shell (default: /bin/bash) - USER_GROUPS: Group membership (default: wheel,audio,video,storage,network) Decision: Use prompt_with_default for locale/timezone/keyboard to provide sensible defaults. Use prompt_required for username since no universal default exists. Validation additions: - Locale format check (basic regex for xx_XX.UTF-8 pattern) - Username validation (must start with letter/underscore, contain only lowercase alphanumeric/underscore/hyphen) Alternative considered: Auto-detect timezone via GeoIP rejected (unreliable without network, adds complexity). Trade-off: Locale format validation is lenient (warning only). Strict validation rejected because locale names vary and false positives would block installations. Warning informs user of potential typo but allows override. Summary display extended to show all new configuration values for user review before destructive operations begin. --- src/config.sh | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/src/config.sh b/src/config.sh index 22c5065..ea804b7 100644 --- a/src/config.sh +++ b/src/config.sh @@ -53,6 +53,14 @@ export ESP_MOUNT="/mnt/boot/efi" export ROOT_LABEL="void-root" export EFI_LABEL="EFI" +# Locale and user configuration +export LOCALE="en_US.UTF-8" +export TIMEZONE="UTC" +export KEYBOARD="us" +export USERNAME="" +export USER_SHELL="/bin/bash" +export USER_GROUPS="wheel,audio,video,storage,network" + validate_size() { local size="$1" # Allow sizes like: 1GiB, 100MB, 50%, 100% @@ -134,6 +142,12 @@ config_prompt_interactive() { prompt_with_default ESP_SIZE "ESP size (e.g. 1GiB)" "${ESP_SIZE}" prompt_with_default ROOT_END "Root partition end (e.g. 100% or 200GiB)" "${ROOT_END}" prompt_with_default SWAP_SIZE "Swap size (e.g. 4GiB, 0 to disable)" "${SWAP_SIZE}" + + # Locale and user configuration + prompt_with_default LOCALE "Locale (e.g. en_US.UTF-8, de_DE.UTF-8)" "${LOCALE}" + prompt_with_default TIMEZONE "Timezone (e.g. UTC, Europe/Berlin, America/New_York)" "${TIMEZONE}" + prompt_with_default KEYBOARD "Keyboard layout (e.g. us, de-latin1, fr)" "${KEYBOARD}" + prompt_required USERNAME "Username for standard user" "${USERNAME}" } config_validate() { @@ -143,6 +157,9 @@ config_validate() { if [[ -z "$HOSTNAME" ]]; then die "Hostname is required." fi + if [[ -z "$USERNAME" ]]; then + die "Username is required." + fi case "$FS_TYPE" in btrfs|ext4) ;; @@ -169,6 +186,16 @@ config_validate() { if [[ "$SWAP_SIZE" != "0" ]] && ! validate_size "$SWAP_SIZE"; then die "Invalid swap size format: $SWAP_SIZE (expected: 4GiB, 8GB, 0 to disable)" fi + + # Validate locale format (basic check) + if [[ ! "$LOCALE" =~ ^[a-z]{2}_[A-Z]{2}\.(UTF-8|utf8)$ ]]; then + log_warn "Locale format may be invalid: $LOCALE (expected: en_US.UTF-8)" + fi + + # Validate username (alphanumeric, underscore, hyphen) + if [[ ! "$USERNAME" =~ ^[a-z_][a-z0-9_-]*$ ]]; then + die "Invalid username: $USERNAME (must start with lowercase letter or underscore, contain only lowercase alphanumeric, underscore, hyphen)" + fi } config_print_summary() { @@ -178,6 +205,7 @@ config_print_summary() { : "${LUKS_VERSION:?LUKS version is required}" : "${MOUNT_ROOT:?Mount root is required}" : "${ESP_MOUNT:?ESP mount path is required}" + : "${USERNAME:?Username is required}" log_info "Configuration summary:" log_info " Disk: $DISK" log_info " Hostname: $HOSTNAME" @@ -188,6 +216,10 @@ config_print_summary() { log_info " Swap size: ${SWAP_SIZE}" log_info " Mount root: $MOUNT_ROOT" log_info " ESP mount: $ESP_MOUNT" + log_info " Locale: $LOCALE" + log_info " Timezone: $TIMEZONE" + log_info " Keyboard: $KEYBOARD" + log_info " Username: $USERNAME" } config_confirm_destructive() {