Subject: Re: efficient updating with binary packages?
To: Thomas Klausner <>
From: Greg Troxel <>
List: tech-pkg
Date: 11/05/2004 09:18:15
I use this (embedded in a much larger script to update a machine
pretty completely with a new build). 

I can't use pkg_chk because it wants /usr/pkgsrc, and I don't have
that on my 20 testbed machines - they just run binaries.  So I used
pkg_chk to generate a list of binary packges from the config file.

I have tried to have the required package list be sorted, but even
with the patch I posted to pkg_chk it seems to be off - pango shows up
after gtk2+.  So I first remove all out-of-date packages and then add.
This seems to work ok, where ok means I run the script that rsyncs
over the contents of RELEASEDIR, binary packges, and the contents of
/usr/sinew (my project's code, not in pkgsrc or base system), and
replaces kernel, userland, packages and my code and reboots, and I
don't need to do anything more per machine.  It would be nice if
pkg_chk could export the needed database to a file, and have an option
to use the database.

I needed to creat a big /tmp mostly because some package are huge.
Because I add packages in order, pkg_add won't have to add
dependencies so only one has to fit.  Also, pkg_chk is invoked for
each package, rather than with multiple - it seems to not clean up
each instmp dir as it is no longer, but on exit.

# Update/install packages from a required list.
update-packages () {
    # enable swapping to ensure mfs /tmp has room
    /etc/rc.d/swap1 start
    # symlink this into /n0 yourself if you don't like /usr
    mkdir -p /usr/tmp
    export PKG_TMPDIR=/usr/tmp
    cd /foo-staging/binary/packages

    # use provided tag, or figure it out from installed packages
    if [ "$1" = "" ]; then
	if [ -f /usr/pkg/bin/cvsps ]; then
	elif [ -f /usr/pkg/bin/gnome-session ]; then
    # :- apparently does not work with positional parameters
     # fresh installs may not have /var/db/pkg
    mkdir -p /var/db/pkg
    # First, recursively remove all mismatches.
    for i in `cat ${PREFIX}/etc/PACKAGES-${SUFFIX}`; do
	pkg=`basename $i .tgz`;
	if [ -f $pkg.tgz ]; then
	    pnover=`echo $pkg | sed 's/\(.*\)-.*/\1/'`
	    pexisting=`pkg-version $pnover`
	    if [ "$pexisting" != "" -a "$pexisting" != "$pkg" ]; then
		echo MISMATCH/removing $pkg /$pnover/ /$pexisting/
		pkg_delete -r $pnover
    # Loop through, and add
    for i in `cat ${PREFIX}/etc/PACKAGES-${SUFFIX}`; do
	pkg=`basename $i .tgz`;
	if [ -f $pkg.tgz ]; then
	    pnover=`echo $pkg | sed 's/\(.*\)-.*/\1/'`
	    pexisting=`pkg-version $pnover`

	    if [ "$pexisting" = "" ]; then
		 # no package installed
		echo MISSING/adding $pkg /$pnover/ /$pexisting/
		pkg_add $pkg
	    elif [ "$pexisting" = "$pkg" ]; then
		# already installed - be quiet
		true || echo OK $pkg
		 # other version installed
		echo MISMATCH/updating $pkg /$pnover/ /$pexisting/
		pkg_add -u $pkg
	    echo "SPURIOUS $pkg - ignoring"

        Greg Troxel <>