menu.lua8
Bootloader dynamic menu module
Overview
menu.lua contains the main functionality required to build a dynamic menu system. It also contains definitions for the built-in menus, some of which are influenced by loader(8) environment variables.
Before hooking into the functionality provided by menu.lua, it must be included with a statement such as the following:
local menu = require("menu")
Menu definitions
Menus are represented in menu.lua as a table. That table must contain an entries key.
If the value of the entries key is itself a table, then each value in this table defines a single entry in this menu. See MENU ITEM DEFINITIONS for the structure of each entry.
entries may also be a function. This function must return a table, each value of which defines a single entry in this menu. See MENU ITEM DEFINITIONS.
Menu item definitions
The following keys may be defined for a menu item:
entry_type-
The type of this menu entry. See MENU ITEM TYPES.
carousel_id-
A unique string id for this carousel. A carousel is a menu entry that rotates through a selection of items. Used for storage of the carousel's current setting.
visible-
A lambda that returns true if this menu item should be visible and false if it should not be visible.
items-
A table (or a lambda that returns a table) of the possible choices for this carousel.
name-
A string (or a lambda that returns a string) containing the current name of this item.
func-
The function executed when this entry is selected. Every type except for
core.MENU_SEPARATORmay have afunc. submenu-
The submenu menu definition to draw when this entry is selected.
alias-
A table of case-sensitive aliases for this menu entry. All menu entries that can be selected may have any number of
aliasentries.
entry_type is the only required key for every entry type. name is required for all entry types except for core.MENU_SEPARATOR.
Menu item types
The menu item type constants are defined in core.lua(8). The following types are available:
core.MENU_RETURN-
Return to the parent menu. If the current menu is the default menu,
menu.luawill exit the menu and begin the autoboot sequence (if applicable). This type of menu entry may executefunc, when selected, and has aname. core.MENU_ENTRY-
A normal menu entry that executes
funcwhen selected, and has aname. core.MENU_SEPARATOR-
A menu entry that serves as a separator. It may have a
name. core.MENU_SUBMENU-
A menu entry that opens
submenuwhen selected. It may have aname. core.MENU_CAROUSEL_ENTRY-
A menu entry that rotates through
itemslike a carousel.funcis executed when selected, and the callback is passed the choice index, name of the current choice, and the table of choices.
Exported menus
The following menus are exported by menu.lua:
menu.default-
The default menu to draw. Set to
menu.welcomeby default. menu.welcome-
The welcome menu. Contains single and multi user boot options, as well as entries to access other menus.
menu.boot_options-
The "Boot Options" menu.
menu.boot_environments-
The "Boot Environments" menu. This menu is only visible if the system is booted on a ZFS partition and more than one boot environment was detected at boot.
Examples
To replace the default boot menu with a simple boot menu:
local core = require("core")
local menu = require("menu")
menu.default = {
entries = {
{
entry_type = core.MENU_ENTRY,
name = "Boot",
func = core.boot,
},
{
entry_type = core.MENU_CAROUSEL_ENTRY,
carousel_id = "unique_boot_entry_name",
items = {"NO", "YES"},
name = function(_, choice, _)
return "Option: " .. choice
end,
func = function(_, _, _)
loader.setenv("some_envvar", "some_value")
end,
},
},
}
To add another option to the welcome menu:
local core = require("core")
local menu = require("menu")
local my_entry = {
entry_type = core.MENU_ENTRY,
name = "Fancy Boot",
func = core.boot,
},
local stock_entries = menu.welcome.entries
function menu.welcome.entries()
local ents = stock_entries()
ents[#ents + 1] = my_entry
return ents
end
To create a vendor submenu or other vendor menu option, override menu.welcome.all_entires.vendor like so:
local core = require("core")
local menu = require("menu")
-- Fill in with vendor specific entries
local vendor_options = {
entries = {
...
},
}
local welcome_entries = menu.welcome.all_entries
welcome_entries.vendor = {
entry_type = core.MENU_SUBMENU,
name = color.highlight("V") .. "endor Options",
submenu = vendor_options,
alias = {"v", "V"},
visible = function()
return true
end,
}
In the above example, vendor_options is a local variable that defines the vendor submenu.
To add an additional option, change the menu.boot_options.entries array. The following illustrates this concept:
-- This is a silly example that rotates local_option through the values
-- 0 to 4. local_option would still need to be used elsewhere.
local local_option = 0
-- The `entries` of a menu may either be a table or a function. In this
-- example we're augmenting a menu that just has a static table, but if we
-- wanted to be more robust then we would need to instead check the type
-- of `stock_options` here to determine our next move.
--
-- If `entries` is a table, then the stock menu system won't be changing it
-- so we can just add our menu option as we do below.
--
-- If `entries` is a function, then we would need to provide a new function to
-- replace `entries` that does a core.deepCopyTable() of the result and adds
-- the below item to it. The deep copy is necessary to avoid duplicating our
-- new menu item and allowing the menu to alter its behavior however it pleases.
local stock_options = menu.boot_options.entries
stock_options[#stock_options + 1] = {
entry_type = core.MENU_ENTRY,
name = function()
return color.highlight('L') ..
"ocal Option : " .. local_option
end,
func = function()
local_option = (local_option + 1) % 5
end,
alias= {"l", "L"}
}
Releases
22 releases since FreeBSD 11.3-RELEASE; the text changed 10 times.