git: 3c3dd6296612 - main - bsdinstall: add pkgbase component selection dialog
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Thu, 22 May 2025 19:02:48 UTC
The branch main has been updated by emaste:
URL: https://cgit.FreeBSD.org/src/commit/?id=3c3dd62966123b424657983d9a4d173f675ad8c7
commit 3c3dd62966123b424657983d9a4d173f675ad8c7
Author: Isaac Freund <ifreund@freebsdfoundation.org>
AuthorDate: 2025-05-05 17:44:20 +0000
Commit: Ed Maste <emaste@FreeBSD.org>
CommitDate: 2025-05-22 18:59:47 +0000
bsdinstall: add pkgbase component selection dialog
This matches the style of the component selection dialog for traditional
tarball-based installations. The only difference is that there is
currently no ports component offered when using pkgbase.
Sponsored by: The FreeBSD Foundation
Differential Revision: https://reviews.freebsd.org/D50178
---
usr.sbin/bsdinstall/scripts/pkgbase.in | 132 +++++++++++++++++++++++++++++----
1 file changed, 118 insertions(+), 14 deletions(-)
diff --git a/usr.sbin/bsdinstall/scripts/pkgbase.in b/usr.sbin/bsdinstall/scripts/pkgbase.in
index 7faeee40647b..eaed23a19548 100755
--- a/usr.sbin/bsdinstall/scripts/pkgbase.in
+++ b/usr.sbin/bsdinstall/scripts/pkgbase.in
@@ -7,6 +7,9 @@
-- This software was developed by Isaac Freund <ifreund@freebsdfoundation.org>
-- under sponsorship from the FreeBSD Foundation.
+local sys_wait = require("posix.sys.wait")
+local unistd = require("posix.unistd")
+
local all_libcompats <const> = "%%_ALL_libcompats%%"
-- Run a command using the OS shell and capture the stdout
@@ -38,20 +41,122 @@ local function append_list(list, other)
end
end
--- Returns a list of pkgbase packages equivalent to the default base.txz and kernel.txz
+-- Read from the given fd until EOF
+-- Returns all the data read as a single string
+local function read_all(fd)
+ local ret = ""
+ repeat
+ local buffer = assert(unistd.read(fd, 1024))
+ ret = ret .. buffer
+ until buffer == ""
+ return ret
+end
+
+-- Run bsddialog with the given argument list
+-- Returns the exit code and stderr output of bsddialog
+local function bsddialog(args)
+ local r, w = assert(unistd.pipe())
+
+ local pid = assert(unistd.fork())
+ if pid == 0 then
+ assert(unistd.close(r))
+ assert(unistd.dup2(w, 2))
+ assert(unistd.execp("bsddialog", args))
+ unistd._exit()
+ end
+ assert(unistd.close(w))
+
+ local output = read_all(r)
+ assert(unistd.close(r))
+
+ local _, _, exit_code = assert(sys_wait.wait(pid))
+ return exit_code, output
+end
+
+-- Creates a dialog for component selection mirroring the
+-- traditional tarball component selection dialog.
+local function select_components(components, options)
+ local descriptions = {
+ kernel_dbg = "Kernel debug info",
+ base_dbg = "Base system debug info",
+ src = "System source tree",
+ tests = "Test suite",
+ lib32 = "32-bit compatibility libraries",
+ lib32_dbg = "32-bit compatibility libraries debug info",
+ }
+ local defaults = {
+ kernel_dbg = "on",
+ base_dbg = "off",
+ src = "off",
+ tests = "off",
+ lib32 = "on",
+ lib32_dbg = "off",
+ }
+
+ -- Sorting the components is necessary to ensure that the ordering is
+ -- consistent in the UI.
+ local sorted_components = {}
+ for component, _ in pairs(components) do
+ table.insert(sorted_components, component)
+ end
+ table.sort(sorted_components)
+
+ local checklist_items = {}
+ for _, component in ipairs(sorted_components) do
+ if component ~= "base" and component ~= "kernel" and
+ not (component == "kernel_dbg" and options.no_kernel) and
+ #components[component] > 0 then
+ local description = descriptions[component] or "''"
+ local default = defaults[component] or "off"
+ table.insert(checklist_items, component)
+ table.insert(checklist_items, description)
+ table.insert(checklist_items, default)
+ end
+ end
+
+ local bsddialog_args = {
+ "--backtitle", "FreeBSD Installer",
+ "--title", "Select System Components",
+ "--nocancel",
+ "--disable-esc",
+ "--separate-output",
+ "--checklist", "Choose optional system components to install:",
+ "0", "0", "0", -- autosize
+ }
+ append_list(bsddialog_args, checklist_items)
+
+ local exit_code, output = bsddialog(bsddialog_args)
+ -- This should only be possible if bsddialog is killed by a signal
+ -- or buggy, we disable the cancel option and esc key.
+ -- If this does happen, there's not much we can do except exit with a
+ -- hopefully useful stack trace.
+ assert(exit_code == 0)
+
+ local selected = {"base"}
+ if not options.no_kernel then
+ table.insert(selected, "kernel")
+ end
+ for component in output:gmatch("[^\n]+") do
+ table.insert(selected, component)
+ end
+
+ return selected
+end
+
+-- Returns a list of pkgbase packages selected by the user
local function select_packages(pkg, options)
local components = {
- ["kernel"] = {},
- ["kernel-dbg"] = {},
- ["base"] = {},
- ["base-dbg"] = {},
- ["src"] = {},
- ["tests"] = {},
+ kernel = {},
+ kernel_dbg = {},
+ base = {},
+ base_dbg = {},
+ src = {},
+ tests = {},
}
for compat in all_libcompats:gmatch("%S+") do
components["lib" .. compat] = {}
- components["lib" .. compat .. "-dbg"] = {}
+ components["lib" .. compat .. "_dbg"] = {}
end
local rquery = capture(pkg .. "rquery -U -r FreeBSD-base %n")
@@ -65,15 +170,15 @@ local function select_packages(pkg, options)
if package == "FreeBSD-kernel-generic" then
table.insert(components["kernel"], package)
elseif package == "FreeBSD-kernel-generic-dbg" then
- table.insert(components["kernel-dbg"], package)
+ table.insert(components["kernel_dbg"], package)
end
elseif package:match(".*%-dbg$") then
- table.insert(components["base-dbg"], package)
+ table.insert(components["base_dbg"], package)
else
local found = false
for compat in all_libcompats:gmatch("%S+") do
if package:match(".*%-dbg%-lib" .. compat .. "$") then
- table.insert(components["lib" .. compat .. "-dbg"], package)
+ table.insert(components["lib" .. compat .. "_dbg"], package)
found = true
break
elseif package:match(".*%-lib" .. compat .. "$") then
@@ -94,9 +199,8 @@ local function select_packages(pkg, options)
assert(#components["base"] > 0)
local selected = {}
- append_list(selected, components["base"])
- if not options.no_kernel then
- append_list(selected, components["kernel"])
+ for _, component in ipairs(select_components(components, options)) do
+ append_list(selected, components[component])
end
return selected