Skip to content

loader: add hidden boot menu option and fix verbose/mute interaction#385

Merged
ericbsd merged 8 commits into
stable/15from
ghostbsd/issues#312
Apr 29, 2026
Merged

loader: add hidden boot menu option and fix verbose/mute interaction#385
ericbsd merged 8 commits into
stable/15from
ghostbsd/issues#312

Conversation

@ericbsd
Copy link
Copy Markdown
Contributor

@ericbsd ericbsd commented Apr 21, 2026

Add loader_menu_hidden="YES" support to hide the boot menu during the autoboot countdown. Instead of drawing the full menu immediately, a minimal "Press any key for boot menu..." prompt is shown. Pressing any key reveals the menu; otherwise the system boots when the countdown expires. The countdown duration is controlled by autoboot_delay.

Also force boot_mute=NO when verbose boot is enabled from the menu, so that verbose output is not silenced by the default boot_mute="YES". Disabling verbose leaves boot_mute untouched per loader.conf.

Summary by Sourcery

Add support for hiding the boot menu during autoboot and ensure verbose boot output is not muted when enabled from the menu.

New Features:

  • Introduce a loader_menu_hidden option to hide the boot menu during the autoboot countdown, showing only a minimal prompt and revealing the full menu on keypress.

Bug Fixes:

  • Force boot_mute=NO when verbose boot is enabled so verbose output is not silenced by default mute settings.

Enhancements:

  • Adjust default autoboot_delay to shorten the default autoboot countdown.

Documentation:

  • Document the loader_menu_hidden configuration option and its interaction with the autoboot countdown in loader.conf.5.

Chores:

  • Enable loader_menu_hidden by default in loader.conf to use the hidden boot menu behavior out of the box.

Add loader_menu_hidden="YES" support to hide the boot menu during the
autoboot countdown. Instead of drawing the full menu immediately, a
minimal "Press any key for boot menu..." prompt is shown. Pressing any
key reveals the menu; otherwise the system boots when the countdown
expires. The countdown duration is controlled by autoboot_delay.

Also force boot_mute=NO when verbose boot is enabled from the menu, so
that verbose output is not silenced by the default boot_mute="YES".
Disabling verbose leaves boot_mute untouched per loader.conf.
@ericbsd ericbsd requested review from a team as code owners April 21, 2026 23:42
@sourcery-ai
Copy link
Copy Markdown

sourcery-ai Bot commented Apr 21, 2026

Reviewer's Guide

Implements a hidden boot menu countdown controlled by loader_menu_hidden and autoboot_delay, adds a minimal “Press any key for boot menu…” prompt with its own autoboot handler, updates loader.conf defaults and man page, and ensures enabling verbose boot also un-mutes boot output by forcing boot_mute=NO.

Sequence diagram for hidden boot menu autoboot flow

sequenceDiagram
    actor User
    participant Loader
    participant Menu
    participant Screen
    participant IO

    Loader->>Menu: menu.run()
    Menu->>Loader: loader.getenv(loader_menu_hidden)
    alt loader_menu_hidden == YES
        Menu->>Loader: loader.getenv(autoboot_delay)
        opt delay set
            Menu->>Menu: menu.autoboothidden(delay)
            loop countdown until timeout or keypress
                Menu->>Loader: loader.time()
                Menu->>Screen: setcursor(1,1) + printc("Press any key for boot menu... time ")
                Screen->>Screen: defcursor()
                Menu->>IO: io.ischar()
                alt key pressed
                    IO-->>Menu: getchar()
                    Menu->>Screen: clear prompt line
                    Screen->>Screen: defcursor()
                    alt ch == KEY_ENTER
                        Menu-->>Menu: return ch (Enter)
                    else other key
                        Menu-->>Menu: return ch
                    end
                else no key yet
                    Menu->>Loader: loader.delay(50000)
                end
            end
            alt key was pressed
                Menu-->>Loader: autoboot_key != nil
                Menu->>Menu: menu.draw(menu.default)
                Note over User,Menu: User now interacts with full boot menu (unchanged flow)
            else timeout
                Menu->>Loader: cli_execute_unparsed(menu_timeout_command or boot)
                Menu-->>Loader: return nil
            end
        end
    else loader_menu_hidden not YES
        Menu->>Menu: menu.draw(menu.default)
        Menu->>Loader: loader.getenv(autoboot_delay)
        opt delay set
            Menu->>Menu: menu.autoboot(delay)
            alt timeout
                Menu->>Loader: cli_execute_unparsed(menu_timeout_command or boot)
                Menu-->>Loader: return nil
            else key pressed
                Menu-->>Loader: autoboot_key != nil
                Note over User,Menu: User interacts with already visible boot menu (existing behavior)
            end
        end
    end
Loading

Class diagram for updated menu and core modules

classDiagram
    class menu {
        +run() nil
        +autoboot(delay) nil
        +autoboothidden(delay) nil
    }

    class core {
        +setVerbose(verbose) nil
    }

    class loader {
        +getenv(name) string
        +setenv(name, value) nil
        +unsetenv(name) nil
        +time() number
        +delay(microseconds) nil
    }

    class screen {
        +setcursor(col, row) nil
        +defcursor() nil
    }

    class io {
        +ischar() boolean
        +getchar() number
    }

    class cli {
        +cli_execute_unparsed(command) nil
    }

    class core_keys {
        <<enumeration>>
        KEY_ENTER
    }

    menu --> loader : uses
    menu --> screen : uses
    menu --> io : uses
    menu --> cli : uses
    menu --> core_keys : compares

    core --> loader : sets env vars
Loading

File-Level Changes

Change Details Files
Add support for a hidden boot menu countdown with a minimal prompt that reveals the full menu on keypress or boots automatically on timeout.
  • Gate initial menu drawing in menu.run() on the loader_menu_hidden environment variable.
  • When loader_menu_hidden=YES, call a new autoboot handler that shows a single-line prompt instead of drawing the full menu, and only draw the full menu if a key is pressed.
  • Preserve existing visible-menu autoboot behavior when loader_menu_hidden is not enabled.
stand/lua/menu.lua
Introduce a dedicated hidden-menu autoboot implementation that shows a one-line prompt and executes the autoboot command on timeout.
  • Implement menu.autoboothidden(delay) to render a countdown-style single-line prompt, polling for keypresses without drawing the full menu.
  • On keypress, clear the prompt and return the pressed key (treating Enter like other keys) so the caller can proceed to draw the full menu.
  • On timeout, execute the configured menu_timeout_command (defaulting to boot) and return nil to signal that autoboot occurred.
stand/lua/menu.lua
Document and default-enable the loader_menu_hidden behavior and adjust the default autoboot delay.
  • Add loader_menu_hidden to loader.conf.5 with a description of the hidden menu behavior and its interaction with autoboot_delay.
  • Add loader_menu_hidden="YES" to the sample loader.conf defaults with a brief comment on its behavior.
  • Change the default autoboot_delay from 5 to 2 seconds in loader.conf.
stand/defaults/loader.conf.5
stand/defaults/loader.conf
Ensure enabling verbose boot from the menu also un-mutes boot output so verbose logs are not suppressed.
  • Update core.setVerbose(true) to set boot_mute=NO alongside boot_verbose=YES, ensuring verbose output is audible/visible even when the default is boot_mute="YES".
  • Leave boot_mute untouched when disabling verbose mode to respect loader.conf defaults.
stand/lua/core.lua

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

@github-actions
Copy link
Copy Markdown

github-actions Bot commented Apr 21, 2026

Thank you for taking the time to contribute to FreeBSD!
There is an issue that needs to be fixed:

Please review CONTRIBUTING.md, then update and push your branch again.

@ghostbsd-bot ghostbsd-bot moved this to In Review in Development Tracker Apr 21, 2026
@ericbsd ericbsd linked an issue Apr 21, 2026 that may be closed by this pull request
Copy link
Copy Markdown

@sourcery-ai sourcery-ai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey - I've found 1 issue, and left some high level feedback:

  • The new loader_menu_hidden handling duplicates the autoboot flow; consider factoring shared logic between menu.autoboot and menu.autoboothidden so future behavior changes don’t need to be updated in two places.
  • autoboothidden() hardcodes a width of 79 characters when clearing the prompt; if the loader can run in different terminal sizes, it may be safer to derive the width from the screen API or a shared constant.
  • loader_menu_hidden only treats the string "YES" (case-insensitive) as enabled; if other truthy values (e.g., "true", "1") are used elsewhere in loader.conf, you may want to align this check with existing config parsing conventions.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- The new loader_menu_hidden handling duplicates the autoboot flow; consider factoring shared logic between menu.autoboot and menu.autoboothidden so future behavior changes don’t need to be updated in two places.
- autoboothidden() hardcodes a width of 79 characters when clearing the prompt; if the loader can run in different terminal sizes, it may be safer to derive the width from the screen API or a shared constant.
- loader_menu_hidden only treats the string "YES" (case-insensitive) as enabled; if other truthy values (e.g., "true", "1") are used elsewhere in loader.conf, you may want to align this check with existing config parsing conventions.

## Individual Comments

### Comment 1
<location path="stand/lua/menu.lua" line_range="595-604" />
<code_context>
 	return nil
 end

+function menu.autoboothidden(delay)
+	local endtime = loader.time() + delay
+	local time
+	local last
+	repeat
+		time = endtime - loader.time()
+		if last == nil or last ~= time then
+			last = time
+			screen.setcursor(1, 1)
+			printc("Press any key for boot menu... " .. time .. " ")
+			screen.defcursor()
+		end
+		if io.ischar() then
+			local ch = io.getchar()
+			screen.setcursor(1, 1)
</code_context>
<issue_to_address>
**issue (bug_risk):** Handling of ENTER vs other keys in `autoboothidden` contradicts the prompt and documented "any key" behavior.

Currently ENTER bypasses the menu and immediately runs the timeout command, while any other key shows the menu. This contradicts the "Press any key for boot menu..." text and manpage. Either handle ENTER like any other key (so it shows the menu), or adjust the prompt/docs to clarify that ENTER will boot immediately instead of revealing the menu.
</issue_to_address>

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

Comment thread stand/lua/menu.lua Outdated
ericbsd and others added 7 commits April 21, 2026 21:09
LIBKRB5PROFILE referenced the undefined variable LIBPROFILEDIR instead
of LIBKRB5PROFILEDIR (defined on the preceding line), causing the linker
to fail to find libkrb5profile.a when building libkrb5.so.  This left
all profile_* symbols missing from the version script, producing a cascade
of "version script assignment of 'krb5_3_MIT' to symbol ... failed: symbol
not defined" errors during buildworld
  FreeBSD 15.0 requires UCL metadata files for custom packages in
  release/packages/ucl/. Add ghostbsd-cert-all.ucl to enable package
  creation for the GhostBSD repository certificate.

  Fixes package creation failure in pkgbase build.
  Without ssl in SUBDIR, the ghostbsd-cert package has no files
  to install. This was fixed on releng/15.0 but not carried over.
The gfx-glogo.lua file was outdated I did bring up to date.
@ericbsd ericbsd merged commit 3a8717c into stable/15 Apr 29, 2026
3 checks passed
@ericbsd ericbsd deleted the ghostbsd/issues#312 branch April 29, 2026 01:46
@github-project-automation github-project-automation Bot moved this from In Review to Done in Development Tracker Apr 29, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

Hidden Boot Menu with Keypress Reveal

2 participants