From 6576c0927f201f2d3c8d69e7a9dd0d0e4e81917c Mon Sep 17 00:00:00 2001 From: Ashish Choubey Date: Wed, 29 Apr 2026 19:25:19 +0530 Subject: [PATCH] keyboard: Don't crash if setxkbmap query fails or returns unexpected output build_kb_lists() ran the live session's `setxkbmap -query` output through `awk` and then `.split()`-unpacked the result into exactly two names. Any deviation from "exactly 2 whitespace-separated tokens" raised ValueError: too many values to unpack (expected 2) and aborted the installer before it could draw the keyboard page. The most likely real-world trigger on a live ISO is `setxkbmap` failing (missing binary, or an environment where the X-protocol query can't run), in which case `subprocess.getoutput` returns the shell error text (`sh: 1: setxkbmap: not found`) -- five tokens, instant crash. Parse line-by-line instead, and fall back to leaving the locals at None when the query is unhelpful. The existing `except NameError` blocks at the pre-selection sites already handle "couldn't determine current model/layout" gracefully -- the user just picks from the list. Closes #176. --- usr/lib/live-installer/main.py | 23 ++++++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) diff --git a/usr/lib/live-installer/main.py b/usr/lib/live-installer/main.py index 78c711a1..10ef0113 100644 --- a/usr/lib/live-installer/main.py +++ b/usr/lib/live-installer/main.py @@ -747,9 +747,26 @@ def build_lang_list(self): def build_kb_lists(self): ''' Do some xml kung-fu and load the keyboard stuffs ''' - # Determine the layouts in use - (keyboard_geom, - self.setup.keyboard_layout) = subprocess.getoutput("setxkbmap -query | awk '/^(model|layout)/{print $2}'").split() + # Best-effort detection of the live session's current keyboard model + # and layout. If setxkbmap is unavailable or returns unexpected output + # (e.g. a shell error, or an environment where the X-protocol query + # fails), leave these as None so the dropdowns simply aren't + # pre-selected -- the downstream "except NameError" blocks already + # handle that gracefully. Crashing the installer here is much worse + # than asking the user to pick from the list. + keyboard_geom = None + self.setup.keyboard_layout = None + try: + for line in subprocess.getoutput("setxkbmap -query").splitlines(): + parts = line.split() + if len(parts) < 2: + continue + if parts[0] == "model:": + keyboard_geom = parts[1] + elif parts[0] == "layout:": + self.setup.keyboard_layout = parts[1] + except Exception: + pass # Build the models from collections import defaultdict def _ListStore_factory():