Website for pkgbase.live
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

5.1 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: 8
hw.byteorder: 1234
hw.physmem: 34089287680
hw.usermem: 26966597632
hw.pagesize: 4096
hw.floatingpoint: 1
hw.machine_arch: amd64
hw.realmem: 34359738368

It also comes with some 3T of storage:

~> % zfs list zpool0/poudriere
NAME               USED  AVAIL     REFER  MOUNTPOINT
zpool0/poudriere   238G  2.77T      104K  /poudriere

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:

ZPOOL=zpool0
ZROOTFS=/poudriere
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 that 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.

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 -create a -jail called 14-current-aarch64
  • for the arm64.aarch64 -architecture
  • and to build native-xtools cross compile tools
  • build a Pkg-Base set
  • -build the OS
  • fetch the source using the git -method via git+https
  • build the -version (branch) main
  • build using -KERNCONF "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 -update.


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.