|How did she do it?!||Mina Galić||en|
So you wanna build your own PkgBase packages and serve them from your own repo? Here's how I did it.
There are two bottlenecks with providing this service:
The more powerful the machine, the faster your build times will be. And the bigger your storage, the more package sets and history you'll be able to provide.
This is what the machine I have been provided for this project looks like:
~> % sysctl hw | head hw.machine: amd64 hw.model: Intel(R) Core(TM) i7-7700 CPU @ 3.60GHz hw.ncpu: 6 hw.byteorder: 1234 hw.physmem: 8547110912 hw.usermem: 5163855872 hw.pagesize: 4096 hw.floatingpoint: 1 hw.machine_arch: amd64 hw.realmem: 8589934592
It also comes with about 1T of storage:
~> % zfs list zroot NAME USED AVAIL REFER MOUNTPOINT zroot 381G 603G 192K /zroot
Setting up Poudriere
Setting up poudriere, we'll need
poudriere-devel, as it comes with a bunch of fixes for PkgBase.
For building package sets for other platforms than the host, you'll also need to install
qemu-user-static, and enable the service.
The essence of my
poudriere.conf looks like this:
NO_ZFS=yes FREEBSD_HOST=https://download.FreeBSD.org GIT_BASEURL="git.freebsd.org/src.git" RESOLV_CONF=/etc/resolv.conf BASEFS=/poudriere USE_TMPFS=yes PKG_REPO_SIGNING_KEY=/usr/share/keys/pkg/repo.key PARALLEL_JOBS=6 TIMESTAMP_LOGS=yes URL_BASE=https://alpha.pkgbase.live/
PARALLEL_JOBS setting is tuned down from the default
hw.ncpu, because we're sharing this server and we're also running a webserver serving the packages.
Note: We are chosing to not use ZFS (
NO_ZFS=yes). Even tho this makes creation and destruction of poudriere jails a little slower, it will make migrating this setup from jail to bhyve to hardware and back a lot easier.
poudriere allows us to sign packages, by supplying a key via
That key only needs to live on the build host, not in the "jails" we're building.
That is because when building PkgBase, we're not actually building in a jail.
Preparing the build
We can set some important options in
PKG_FORMAT="tzst" WITHOUT_CLEAN="YES" WITH_REPRODUCIBLE_BUILD="YES"
if you want to take advantage of
META_MODE, you'll also have to
filemon(4), and persist it via
The way I create PkgBase sets with poudriere is generally like this:
~> % poudriere jail -c -j 14-current-aarch64 \ -x -a arm64.aarch64 \ -B -b -m git+https \ -v main \ -K "GENERIC GENERIC-MMCCAM GENERIC-NODEBUG GENERIC-MMCCAM-NODEBUG"
Let's break this down:
- We instruct poudriere to
- for the
- and to build native
-xtools cross compile tools
- build a Pkg
-build the OS
- fetch the source using the
- build the
- build using
"GENERIC GENERIC-MMCCAM GENERIC-NODEBUG GENERIC-MMCCAM-NODEBUG"
I use a
fish script to update my package sets:
#!/usr/bin/env fish set -l basedir (readlink -f (dirname (status filename))) for j in (poudriere jail -qnl | awk "!/^iso-/ && /$argv/") echo "=============================================================" echo " Preparing to update $j..." echo "=============================================================" set -l powder (string split ' ' (poudriere jail -ql | grep "^$j ")) set -l src_path "$powder[-1]/usr/src" git -C $src_path pull --ff-only set -l cur_hash (git -C $src_path show-ref --abbrev --heads --hash) set -l rec_hash $powder set -l arch (uname -m) set -l jarch $powder set -l xarch (test "$arch" = "$jarch"; or echo "-x") if test "$cur_hash" = "$rec_hash" echo "=============================================================" echo " Skipping update of $j: already up-to-date" echo "=============================================================" continue end set -l poudriere_update "time poudriere jail -u $xarch -j $j" if not eval $poudriere_update echo "=============================================================" echo " Failed to update $j :(" echo "=============================================================" break end echo "=============================================================" echo " Successfully updated $j !!" echo "=============================================================" end
What this does is to compare the git hash after pulling with what poudriere has stored. We skip if there's no need to update.
Similarly, we compare the architecture and if the jail's doesn't match that of the host, we add
-x to the
That's all folks.
If you have questions about replicating my setup, I'll be happy to edit this Howto to make it more complete.