5.2 KiB
title | author | lang |
---|---|---|
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.
Prerequisites
There are two bottlenecks with providing this service:
- Storage
- CPU
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/
Note: The 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.
Signing Packages
poudriere allows us to sign packages, by supplying a key via PKG_REPO_SIGNING_KEY
.
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 src.conf
:
PKG_FORMAT="tzst"
WITHOUT_CLEAN="YES"
WITH_REPRODUCIBLE_BUILD="YES"
and src-env.conf
:
WITH_META_MODE="YES"
if you want to take advantage of META_MODE
, you'll also have to kldload(8)
filemon(4)
, and persist it via rc.conf(5)
:
kld_list="filemon"
Building sets
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
-c
reate a-j
ail called14-current-aarch64
- for the
arm64.aarch64
-a
rchitecture - and to build native
-x
tools cross compile tools - build a Pkg
-B
ase set -b
uild the OS- fetch the source using the
git
-m
ethod viagit+https
- build the
-v
ersion (branch)main
- build using
-K
ERNCONF"GENERIC GENERIC-MMCCAM GENERIC-NODEBUG GENERIC-MMCCAM-NODEBUG"
Updating sets
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[4]
set -l arch (uname -m)
set -l jarch $powder[5]
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 -u
pdate.
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.