To simplify server management I create “meta” packages in FreeBSD ports that can generate a package with only dependencies on other packages. This allows to me to just install this 1 package on the target server and have it pull in all of the packages that I want on there. I assign each server specific “roles” and only install 1 or 2 packages per server depending on which roles they fulfill. The roles may be one of “dev”, “web”, “ports-dev”, “jail”, etc. This ensures that all servers fulfilling specific roles will always have the proper packages installed. For some applications, I use a dedicated jail with a meta package that only pulls in the required dependencies for that application to run. For instance, on a PHP application jail, the meta package may pull in nginx, php, eaccelerator, git, etc.
To create meta packages, define a port that requires the actual ports that should be installed. Then build packages for those meta ports.
This meta port will install git, cscope and vim. Which dependencies those pull in do not matter here.
PORTNAME= local-dev-meta
PORTVERSION= 20130719
CATEGORIES= local
MASTER_SITES= # none
DISTFILES= # none
EXTRACT_ONLY= # none
MAINTAINER= local@localdomain.com
COMMENT= Meta port for dev packages
NO_BUILD= yes
NO_WRKSUBDIR= yes
RUN_DEPENDS+= git>0:${PORTSDIR}/devel/git
RUN_DEPENDS+= cscope>0:${PORTSDIR}/devel/cscope
RUN_DEPENDS+= vim-lite>0:${PORTSDIR}/editors/vim-lite
do-install: build
@${DO_NADA}
.include <bsd.port.mk>
Note the RUN_DEPENDS line is depending on package names, not binary names. Any version will satisfy the dependency.
Development meta port
The local category must be defined.
VALID_CATEGORIES+= local
Poudriere is a tool to build and test packages for FreeBSD. There is a detailed guide on creating pkgng repositories on the poudriere site, so I will only cover it briefly here.
Install poudriere on your build machine:
root@build# make -C /usr/ports/ports-mgmt/poudriere install clean
Configure poudriere:
root@build# cat >> /usr/local/etc/poudriere.conf
BASEFS=/poudriere
ZPOOL=tank
# Directory where the CCACHE_DIR is in the host
CCACHE_DIR=/usr/ccache
# Directory to store distfiles on the host
DISTFILES_CACHE=/mnt/distfiles
^D
root@build# mkdir /usr/local/etc/poudriere.d
root@build# cat >> /usr/local/etc/poudriere.d/make.conf
WITH_PKGNG= yes
^D
Create a jail and import your existing /usr/ports tree as system:
# Create jail
root@build# poudriere jail -c -j 83amd64 -v 8.3-RELEASE -a amd64
...
# Add system's /usr/ports into poudriere
root@build# poudriere ports -c -F -f none -M /usr/ports -p system
...
Pick options for your meta package and dependencies:
root@build# poudriere options -p system local/dev-meta
Now build the packages from the meta port using the system ports tree:
root@build# poudriere bulk -j 83amd64 -p system local/dev-meta
====>> Creating the reference jail... done
====>> Mounting system devices for 83amd64-system
====>> Mounting ports/packages/distfiles
====>> Mounting ccache from: /usr/ccache
====>> Mounting packages from: /poudriere/data/packages/83amd64-system
====>> Mounting /var/db/ports from: /usr/local/etc/poudriere.d/options
====>> Logs: /poudriere/data/logs/bulk/83amd64-system/2013-07-21_14h14m27s
====>> Appending to make.conf: /usr/local/etc/poudriere.d/make.conf
/etc/resolv.conf -> /poudriere/data/build/83amd64-system/ref/etc/resolv.conf
====>> Starting jail 83amd64-system
====>> Calculating ports order and dependencies
====>> pkg package missing, skipping sanity
====>> Cleaning the build queue
====>> Building 53 packages using 14 builders
====>> Starting/Cloning builders
====>> [01] Starting build of ports-mgmt/pkg
[...]
====>> Creating pkgng repository
Generating repository catalog in /packages: done!
====>> Cleaning up
====>> Umounting file systems
====>> Built ports: ports-mgmt/pkg devel/ccache textproc/xmlcatmgr archivers/unzip lang/perl5.14 net/p5-Socket textproc/iso8879 textproc/xmlcharent converters/libiconv devel/gettext devel/m4 devel/libtool net/p5-IO-Socket-IP security/libgpg-error security/p5-Net-SSLeay textproc/docbook-410 textproc/docbook-420 textproc/docbook-430 textproc/docbook-440 textproc/docbook-450 textproc/docbook-500 textproc/docbook-sk textproc/docbook-xml textproc/docbook-xml-430 textproc/docbook-xml-440 devel/bison devel/boehm-gc devel/gmake textproc/docbook-xml-450 devel/pkgconf security/ca_root_nss security/p5-IO-Socket-SSL misc/getopt print/libpaper security/libgcrypt shells/bash textproc/docbook textproc/docbook-xsl textproc/libxml2 textproc/libxslt www/w3m ftp/curl lang/p5-Error lang/python27 mail/p5-Net-SMTP-SSL textproc/asciidoc textproc/expat2 textproc/xmlto devel/cscope devel/cvsps devel/git editors/vim-lite local/dev-meta
====>> [83amd64-system] 53 packages built, 0 failures, 0 ignored, 0 skipped
====>> Logs: /poudriere/data/logs/bulk/83amd64-system/2013-07-21_14h14m27s
The /poudriere/data/packages/83amd64-system directory now contains the pkgng repository that needs to be served. This can be done over NFS, Samba, HTTP, FTP, etc. It is best to serve the /poudriere/data/packages directory and create symlinks of the ABI name to the target. The ABI is a pkgng feature defined as OS:REL:ARCH:BITS. For instance, this build would be freebsd:8:x86:64.
root@build# ln -s 83amd64-system /poudriere/data/packages/freebsd:8:x86:64
The repository is now ready for use on the target servers.
On the target server, the appropriate meta packages just need to be installed now.
First bootstrap the system with pkg if needed.
root@dev# mkdir -p /usr/local/etc
root@dev# echo 'PACKAGESITE=http://packages.domain.com/${ABI}' > /usr/local/etc/pkg.conf
root@dev# pkg -v
The package management tool is not yet installed on your system.
Do you want to fetch and install it now? [y/N]: y
Bootstrapping pkg please wait
Installing pkg-1.1.4... done
If you are upgrading from the old package format, first run:
# pkg2ng
1.1.4
Now the local/dev-meta
package can be installed:
root@dev# pkg install local/dev-meta
digests.txz 100% 57KB 57.1KB/s 57.1KB/s 00:00
packagesite.txz 100% 323KB 323.3KB/s 323.3KB/s 00:00
Incremental update completed, 0 packages processed:
0 packages updated, 0 removed and 53 added.
The following 42 packages will be installed:
Installing libiconv: 1.14_1
Installing xproto: 7.0.24
Installing renderproto: 0.11.1
Installing libXdmcp: 1.1.1
Installing libXau: 1.0.8
Installing pkgconf: 0.9.2_1
Installing libpthread-stubs: 0.3_3
Installing kbproto: 1.0.6
Installing expat: 2.0.1_2
Installing freetype2: 2.4.12_1
Installing tcl: 8.5.14_1
Installing openssl: 1.0.1_8
Installing db42: 4.2.52_5
Installing perl: 5.14.4
Installing pcre: 8.33
Installing libssh2: 1.4.3_1,2
Installing ca_root_nss: 3.15.1
Installing p5-Net-SMTP-SSL: 1.01_1
Installing p5-Error: 0.17020
Installing curl: 7.31.0
Installing sqlite3: 3.7.17_1
Installing p5-Term-ReadKey: 2.30
Installing cvsps: 2.1_1
Installing cscope: 15.8a
Installing gettext: 0.18.3
Installing libxml2: 2.8.0_2
Installing fontconfig: 2.9.0,1
Installing gdbm: 1.10
Installing python27: 2.7.5_1
Installing vim-lite: 7.3.1314_2
Installing libxcb: 1.9.1
Installing libX11: 1.6.0,1
Installing apr: 1.4.8.1.5.2
Installing apache22-worker-mpm: 2.2.25
Installing libXrender: 0.9.8
Installing libXft: 2.3.1
Installing serf: 1.2.1_1
Installing subversion: 1.8.0_3
Installing p5-subversion: 1.8.0_3
Installing tk: 8.5.14_1
Installing git: 1.8.3.3_1
Installing local-dev-meta: 20130719
The installation will require 433 MB more space
53 MB to be downloaded
Proceed with installing packages [y/N]: y
...
Only 2 packages were directly installed, so only those 2 show as non-automatic and will not be removed by pkg autoremove
:
root@dev# pkg query -e '%a = 0' '%o'
ports-mgmt/pkg
local/dev-meta
This simplifies maintenance of the server and ensures all servers using this meta package will have the same packages installed on them. When needing to add or remove a dependency from the meta package, just update the /usr/ports/local/dev-meta/Makefile on the build server, bump the PORTREVISION or PORTVERSION and then rebuild with poudriere bulk
. Once that is completed, run pkg upgrade
and pkg autoremove
on the target servers. This will install new dependencies, upgrading existing, and then remove any that are no longer needed on on that server.