Skip to content

Commit 21cd834

Browse files
committed
Testsuite: T9214: make GRUB console-select navigation non-fatal on auto-boot race
Commit 7c33698 ("Testsuite: T9214: fix GRUB auto-boot race in console-select navigation") narrowed the race between GRUB's own auto-boot countdown and this script's post-install "Boot options" navigation, but did not close it: the countdown is timed from when GRUB itself draws the menu, not from when this script's regex match on the menu banner returns, so under host load GRUB can still auto-boot before we react. When that happens, the subsequent child.expect('Select console type', ...) blocks for the full timeout waiting for a submenu that was never entered, then raises and aborts the test even though the default entry already booted a working serial console (the installer always answers 'S' to the console-type prompt). Wrap the submenu navigation in a try/except so losing this race just logs a warning and falls through instead of crashing, letting the already-auto-booted default entry carry on into the login wait that already tolerates this case.
1 parent aeb3483 commit 21cd834

1 file changed

Lines changed: 53 additions & 36 deletions

File tree

scripts/check-qemu-install

Lines changed: 53 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -547,7 +547,7 @@ def toggleUEFISecureBoot(c):
547547
UEFIKeyPress(c, KEY_DOWN)
548548
UEFIKeyPress(c, KEY_RETURN)
549549

550-
def BOOTLOADERchooseSerialConsole(child, live: bool) -> None:
550+
def BOOTLOADERchooseSerialConsole(child, live: bool, log=None) -> None:
551551
""" Select GRUB boot entry that uses the serial console. This differs
552552
between a LIVE ISO image and an already installed system. """
553553
BOOTLOADER_TMO = 40
@@ -596,39 +596,56 @@ def BOOTLOADERchooseSerialConsole(child, live: bool) -> None:
596596
# Wait for GRUB
597597
child.expect(GRUB_STRING, timeout=BOOTLOADER_TMO)
598598

599-
# Unlike the live ISO menus (10s timeout), the installed system's
600-
# top-level menu auto-boots its default entry after ~BOOTLOADER_LOAD_TMO
601-
# seconds - the same delay this script would otherwise sleep before
602-
# sending any key. Under host load that leaves no margin: GRUB can
603-
# auto-boot before "Boot options" is ever selected. Send the first
604-
# navigation key immediately to cancel the countdown, then give the
605-
# screen time to settle.
606-
# Select GRUB serial console
607-
# Boot options
608-
child.send(KEY_DOWN)
609-
time.sleep(BOOTLOADER_LOAD_TMO)
610-
child.send(KEY_RETURN)
611-
time.sleep(BOOTLOADER_SLEEP)
612-
# GRUB submenus never time out on their own, so confirm we actually
613-
# landed on this submenu before navigating further - otherwise a
614-
# dropped keypress leaves the VM stuck here until the login wait
615-
# elsewhere expires
616-
child.expect('Select console type', timeout=BOOTLOADER_TMO)
617-
618-
# Select console type
619-
child.send(KEY_DOWN)
620-
time.sleep(BOOTLOADER_SLEEP)
621-
child.send(KEY_RETURN)
622-
time.sleep(BOOTLOADER_SLEEP)
623-
child.expect(r'ttyS \(serial\)', timeout=BOOTLOADER_TMO)
624-
625-
# *ttyS (serial)
626-
child.send(KEY_DOWN)
627-
time.sleep(BOOTLOADER_SLEEP)
628-
child.send(KEY_RETURN)
629-
time.sleep(BOOTLOADER_SLEEP)
630-
# Boot
631-
child.send(KEY_RETURN)
599+
# The installed system's top-level menu auto-boots its default
600+
# entry after ~BOOTLOADER_LOAD_TMO seconds, timed from when GRUB
601+
# itself draws the menu - not from when this script's regex match
602+
# on GRUB_STRING returns. Under host load the menu text can reach
603+
# us well after that internal countdown already started, so there
604+
# is no reliable amount of "send a key fast enough" that wins this
605+
# race every time.
606+
#
607+
# That's fine to lose: the installer always answers 'S' (serial)
608+
# to "What console should be used by default?", so the default
609+
# entry GRUB auto-boots already targets the right console.
610+
# waitForLogin()/loginVM(), called after this function returns,
611+
# already tolerate landing straight on the GRUB countdown or the
612+
# login prompt. So treat this submenu navigation as best-effort:
613+
# if we don't land in "Boot options" in time, stop navigating and
614+
# let the default entry (which is already auto-booting) carry on,
615+
# instead of raising and aborting the whole test.
616+
try:
617+
# Select GRUB serial console
618+
# Boot options
619+
child.send(KEY_DOWN)
620+
time.sleep(BOOTLOADER_LOAD_TMO)
621+
child.send(KEY_RETURN)
622+
time.sleep(BOOTLOADER_SLEEP)
623+
# GRUB submenus never time out on their own, so confirm we actually
624+
# landed on this submenu before navigating further - otherwise a
625+
# dropped keypress leaves the VM stuck here until the login wait
626+
# elsewhere expires
627+
child.expect('Select console type', timeout=BOOTLOADER_TMO)
628+
629+
# Select console type
630+
child.send(KEY_DOWN)
631+
time.sleep(BOOTLOADER_SLEEP)
632+
child.send(KEY_RETURN)
633+
time.sleep(BOOTLOADER_SLEEP)
634+
child.expect(r'ttyS \(serial\)', timeout=BOOTLOADER_TMO)
635+
636+
# *ttyS (serial)
637+
child.send(KEY_DOWN)
638+
time.sleep(BOOTLOADER_SLEEP)
639+
child.send(KEY_RETURN)
640+
time.sleep(BOOTLOADER_SLEEP)
641+
# Boot
642+
child.send(KEY_RETURN)
643+
except pexpect.TIMEOUT:
644+
if log is not None:
645+
log.warning('GRUB auto-booted the default entry before "Boot '
646+
'options" navigation completed; continuing since '
647+
'the default entry already boots the serial '
648+
'console selected during install')
632649

633650
return None
634651

@@ -904,7 +921,7 @@ try:
904921
log.info('Disable UEFI Secure Boot for initial installation')
905922
toggleUEFISecureBoot(c)
906923

907-
BOOTLOADERchooseSerialConsole(c, live=(not args.cloud_init))
924+
BOOTLOADERchooseSerialConsole(c, live=(not args.cloud_init), log=log)
908925
loginVM(c, log)
909926

910927
#################################################
@@ -1070,7 +1087,7 @@ try:
10701087
# Booting installed system
10711088
#################################################
10721089
log.info('Booting installed system')
1073-
BOOTLOADERchooseSerialConsole(c, live=False)
1090+
BOOTLOADERchooseSerialConsole(c, live=False, log=log)
10741091

10751092
#################################################
10761093
# Logging into VyOS system

0 commit comments

Comments
 (0)