repack-freebsd-iso
Adds custom files to a FreeBSD installer ISO by appending a second ISO9660 session, without rebuilding the image from scratch.
Shell · GitHub
Why
Rebuilding a multi-gigabyte FreeBSD release ISO from scratch just to add
an unattended-install config or a custom package set means re-reading and
re-writing every file on the disc. ISO9660 was designed for
write-once/append-only optical media, though, and has a native concept of
sessions -- a disc can hold several independent volume descriptors and
directory trees, with the last one written being the one any reader
(kernel loopback driver, mount, an installer) follows.
repack.sh exploits that instead of editing the image: it appends a
second session containing only the new or changed files, and publishes a
merged directory tree that points everything else back at the unmodified
data already on the original image. See the
multisession mechanism writeup
for the full explanation, including how far the same trick carries to
other OS installers (Debian preseed, RHEL kickstart, Windows Setup).
Features
- No full rebuild -- reuses every unchanged file's on-disk extent instead of re-reading and re-writing it; only new or replaced files are written into the appended session.
- Download and verify -- can fetch a FreeBSD release ISO directly and
check its SHA-512 checksum before repacking, or repack a local
.iso/.iso.xzfile. - Unattended installer config -- grafts
/etc/installerconfig, whichbsdinstallreads at boot to drive a scripted install. - Custom distribution set -- packages files listed in a
custom.mtreemanifest intocustom.txzand grafts it into/usr/freebsd-dist,bsdinstall's default distribution directory, so it installs alongsidebase.txzandkernel.txz.
Quick start
git clone https://github.com/hackagadget/repack-freebsd-iso.git
cd repack-freebsd-iso
# download FreeBSD 15.1 amd64 dvd1, verify its checksum, and repack it
./repack.sh -d
Or repack a local image instead of downloading one:
Both produce new.iso in the current directory, leaving the input image
untouched.
Usage
repack.sh (-d [-r RELEASE] [-m MACHINE] [-a MACHINE_ARCH] [-t VARIANT]
| <xz-compressed or plain ISO image>)
| Flag | Description | Default |
|---|---|---|
-d |
Download a release image instead of repacking a local one | |
-r RELEASE |
FreeBSD release to download | 15.1 |
-m MACHINE |
Target machine: amd64, arm64, powerpc, riscv |
amd64 |
-a MACHINE_ARCH |
Machine architecture, e.g. aarch64 for arm64 |
|
-t VARIANT |
Image variant: bootonly, disc1, dvd1 (availability varies by machine) |
dvd1 |
What gets grafted depends on which inputs sit next to the script when it runs:
| Input | Grafted to | Condition |
|---|---|---|
installerconfig.txt |
/etc/installerconfig |
file exists and is non-empty |
files/custom.mtree |
/usr/freebsd-dist/custom.txz |
file exists and is non-empty |
If neither is present, the script exits with ERROR: Nothing to graft.
Prerequisites
sh, realpath, file, xz, tar, awk, fetch, sha512sum,
isoinfo, and growisofs -- the last two typically come from
cdrtools/dvd+rw-tools or the equivalent package on your system.