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["kernel"]) 56 table.insert(selected, components["kernel-dbg"]) 57 table.insert(selected, components["src"]) 58 table.insert(selected, components["tests"]) 59 for compat in all_libcompats:gmatch("%S+") do 60 table.insert(selected, components["lib" .. compat]) 61 end 62 else 63 assert(media == "dvd") 64 table.insert(selected, components["pkg"]) 65 table.insert(selected, components["base"]) 66 table.insert(selected, components["base-dbg"]) 67 table.insert(selected, components["kernel"]) 68 table.insert(selected, components["kernel-dbg"]) 69 table.insert(selected, components["src"]) 70 table.insert(selected, components["tests"]) 71 for compat in all_libcompats:gmatch("%S+") do 72 table.insert(selected, components["lib" .. compat]) 73 table.insert(selected, components["lib" .. compat .. "-dbg"]) 74 end 75 end 76 77 return selected 78end 79 80local function main() 81 -- Determines package subset selected 82 local media = assert(arg[1]) 83 assert(media == "disc" or media == "dvd") 84 -- Directory containing FreeBSD-base repository config 85 local repo_dir = assert(arg[2]) 86 -- Directory to create new repository 87 local target = assert(arg[3]) 88 -- Whitespace separated list of all libcompat names (e.g. "32") 89 local all_libcompats = assert(arg[4]) 90 -- ABI of repository 91 local ABI = assert(arg[5]) 92 -- pkgdb to use 93 local PKGDB = assert(arg[6]) 94 95 local pkg = "pkg -o ASSUME_ALWAYS_YES=yes -o IGNORE_OSVERSION=yes " .. 96 "-o ABI=" .. ABI .. " " .. 97 "-o INSTALL_AS_USER=1 -o PKG_DBDIR=" .. PKGDB .. " -R " .. repo_dir .. " " 98 99 assert(os.execute(pkg .. "update")) 100 101 local packages = select_packages(pkg, media, all_libcompats) 102 103 assert(os.execute(pkg .. "fetch -d -o " .. target .. " " .. table.concat(packages, " "))) 104 assert(os.execute(pkg .. "repo " .. target)) 105end 106 107main() 108