Guest post by Scott Sturdivant.
Maintaining custom ports and integrating them into your build process doesn't need to be difficult. The documentation surrounding this process however is either non-existent, or lacking in its clarity. At the end of the day, it really is as simple as maintaining a repository whose structure matches the ports tree layout, then managing that repository and the standard ports tree with portshaker, and finally handing the end result off to poudriere.
Your Custom Repository
For this example, we'll assume a git repo is used and that you're already
familiar with how to build FreeBSD ports. We'll also assume that we
have but a single port that we're maintaining and that it is called
The hierarchy of your repo should simply be
category/myport. We'll refer to
this repo simply as
Portshaker is the tool responsible for taking multiple ports sources and then
merging them down into a single target. In our case, we have two sources: our
git repo (
myport, and the standard FreeBSD ports tree.
We aim to merge this down into a single ports tree that poudriere will then use
for its builds.
To configure portshaker, add the following to the
# vim:set syntax=sh: # $Id: portshaker.conf.sample 116 2008-09-30 16:15:02Z romain.tartiere $ #---[ Base directory for mirrored Ports Trees ]--- mirror_base_dir="/var/cache/portshaker" #---[ Directories where to merge ports ]--- ports_trees="default" use_zfs="no" poudriere_ports_mountpoint="/usr/local/poudriere/ports" default_poudriere_tree="default" default_merge_from="freebsd myrepo"
Some key points here are that the two items listed in for the
default_merge_from argument need to have scripts present in the
/usr/local/etc/portshaker.d directory. Further more, the combination of the
default_poudriere_tree needs to be a ports
tree that is then registered with poudriere.
Next, we need to tell portshaker how to go off and fetch our two types of ports
myrepo. For the
freebsd ports tree, create
/usr/local/etc/portshaker.d/freebsd with the following contents and make it
#!/bin/sh . /usr/local/share/portshaker/portshaker.subr method="portsnap" run_portshaker_command $*
Next, create a similar script to handle our repository containing our custom
/usr/local/etc/portshaker.d/myrepo should contain the following and
similarly be executable:
#!/bin/sh . /usr/local/share/portshaker/portshaker.subr method="git" git_clone_uri="http://github.com/scott.sturdivant/packaging.git" git_branch="master" run_portshaker_command $*
Obviously replace the
git_branch variables to reflect
your actual configuration. For more information about the values and what they
can contain, consult
Now, portshaker should be all set. Execute
portshaker -U to update your
merge_from ports trees (
myrepo). You'll see the standard
portsnap fetch and extract process as well as a git clone. After a good
bit of time, these will both be present in the
directory. Go ahead and merge them together by executing
Hooray! You now have
/usr/local/poudriere/ports/default/ports that is a
combination of the normal ports tree and your custom one.
We're effectively complete with configuring portshaker. Whenever your port is
updated, just re-run
portshaker -U and
portshaker -M to grab the latest
changes and perform the merge.
Poudriere is a good tool for building ports. We will use it to handle our
merged directory. Begin by configuring poudriere
NO_ZFS=yes FREEBSD_HOST=ftp://ftp.freebsd.org RESOLV_CONF=/etc/resolv.conf BASEFS=/usr/local/poudriere USE_PORTLINT=no USE_TMPFS=yes DISTFILES_CACHE=/usr/ports/distfiles CHECK_CHANGED_OPTIONS=yes
Really there's nothing here that is specific to the problem at hand, so feel free to consult the provided configuration file to tune it to your needs.
Now, the step that is specific is to set poudriere up with a ports tree that
it does not manage, specifically our resultant merged directory. If you
man poudriere, it specifies that for the
ports subcommand, there is
-m method switch which controls the methodology used to create the ports
tree. By default, it is portsnap. This is confusing as in our case, we do not
want poudriere to actually do anything. We want it to just use an existing
path. Fortunately, there is a way!
The poudriere wiki has an entry for using the system ports tree, so we adopt it for our needs by executing:
poudriere ports -c -F -f none -M /usr/local/poudriere/ports/default \ -p default
If you've consulted the poudriere manpage, you'll see that the
switches both reference ZFS in their help. As we're not using ZFS, it's not
clear how they will behave. However, in conjunction with the custom mountpoint
-M /usr/local/poudriere/ports/default), we ultimately wind up with what we
want, a ports tree that poudriere can use, but does not manage:
# poudriere ports -l PORTSTREE METHOD PATH default - /usr/local/poudriere/ports/default
Note that this resulting PATH is the combination of the
default_poudriere_tree variables present in
/usr/local/etc/portshaker.conf configuration file.
Building software from your custom ports tree
Go ahead and create your jail(s) like you normally would (i.e.
poudriere -c -j 92amd64 -V 9.2-RELEASE -a amd64) and any other configuration
you would like, and then go ahead and build
poudriere bulk -j 92amd64 -p default category/myport. Success!