xref: /freebsd/release/scripts/pkgbase-stage.lua (revision 07940d1d85eb338853fcba0697c6b9a96412a7f2)
1#!/usr/libexec/flua
2
3-- SPDX-License-Identifier: BSD-2-Clause
4--
5-- Copyright(c) 2025 The FreeBSD Foundation.
6--
7-- This software was developed by Isaac Freund <ifreund@freebsdfoundation.org>
8-- under sponsorship from the FreeBSD Foundation.
9
10-- Run a command using the OS shell and capture the stdout
11-- Strips exactly one trailing newline if present, does not strip any other whitespace.
12-- Asserts that the command exits cleanly
13local function capture(command)
14	local p = io.popen(command)
15	local output = p:read("*a")
16	assert(p:close())
17	-- Strip exactly one trailing newline from the output, if there is one
18	return output:match("(.-)\n$") or output
19end
20
21-- Returns a list of packages to be included in the given media
22local function select_packages(pkg, media, all_libcompats)
23	-- Note: if you update this list, you must also update the list in
24	-- usr.sbin/bsdinstall/scripts/pkgbase.in.
25	local kernel_packages = {
26		-- Most architectures use this
27		["FreeBSD-kernel-generic"] = true,
28		-- PowerPC uses either of these, depending on platform
29		["FreeBSD-kernel-generic64"] = true,
30		["FreeBSD-kernel-generic64le"] = true,
31	}
32
33	local components = {}
34	local rquery = capture(pkg .. "rquery -U -r FreeBSD-base %n")
35	for package in rquery:gmatch("[^\n]+") do
36		local set = package:match("^FreeBSD%-set%-(.*)$")
37		if set then
38			components[set] = package
39		elseif kernel_packages[package] then
40			components["kernel"] = package
41		elseif kernel_packages[package:match("(.*)%-dbg$")] then
42			components["kernel-dbg"] = package
43		elseif package == "pkg" then
44			components["pkg"] = package
45		end
46	end
47	assert(components["kernel"])
48	assert(components["base"])
49	assert(components["pkg"])
50
51	local selected = {}
52	if media == "disc" then
53		table.insert(selected, components["pkg"])
54		table.insert(selected, components["base"])
55		table.insert(selected, components["base-jail"])
56		table.insert(selected, components["kernel"])
57		table.insert(selected, components["kernel-dbg"])
58		table.insert(selected, components["src"])
59		table.insert(selected, components["tests"])
60		for compat in all_libcompats:gmatch("%S+") do
61			table.insert(selected, components["lib" .. compat])
62		end
63	else
64		assert(media == "dvd")
65		table.insert(selected, components["pkg"])
66		table.insert(selected, components["base"])
67		table.insert(selected, components["base-dbg"])
68		table.insert(selected, components["base-jail"])
69		table.insert(selected, components["base-jail-dbg"])
70		table.insert(selected, components["kernel"])
71		table.insert(selected, components["kernel-dbg"])
72		table.insert(selected, components["src"])
73		table.insert(selected, components["tests"])
74		for compat in all_libcompats:gmatch("%S+") do
75			table.insert(selected, components["lib" .. compat])
76			table.insert(selected, components["lib" .. compat .. "-dbg"])
77		end
78	end
79
80	return selected
81end
82
83local function main()
84	-- Determines package subset selected
85	local media = assert(arg[1])
86	assert(media == "disc" or media == "dvd")
87	-- Directory containing FreeBSD-base repository config
88	local repo_dir = assert(arg[2])
89	-- Directory to create new repository
90	local target = assert(arg[3])
91	-- Whitespace separated list of all libcompat names (e.g. "32")
92	local all_libcompats = assert(arg[4])
93	-- ABI of repository
94	local ABI = assert(arg[5])
95	-- pkgdb to use
96	local PKGDB = assert(arg[6])
97
98	local pkg = "pkg -o ASSUME_ALWAYS_YES=yes -o IGNORE_OSVERSION=yes " ..
99	    "-o ABI=" .. ABI .. " " ..
100	    "-o INSTALL_AS_USER=1 -o PKG_DBDIR=" .. PKGDB .. " -R " .. repo_dir .. " "
101
102	assert(os.execute(pkg .. "update"))
103
104	local packages = select_packages(pkg, media, all_libcompats)
105
106	assert(os.execute(pkg .. "fetch -d -o " .. target .. " " .. table.concat(packages, " ")))
107	assert(os.execute(pkg .. "repo " .. target))
108end
109
110main()
111