This is a tutorial for cowbuilder. See also qemubuilder.

Usage

Initialization

Create the base image:

sudo cowbuilder --create

And a new and shiny build image is created in /var/cache/pbuilder/base.cow/

Every day usage

Update the base image

sudo cowbuilder --update

Build a package:

sudo cowbuilder --build somepackage.dsc

Tips

Bash and SVN tips

Setup your .bashrc according to: http://upsilon.cc/~zack/blog/posts/2007/09/svn-cowbuilder/

Building your package for many distributions at once

cowbuilder is really handy to build your pet project for many distributions at once. If you have got an amd64 system, you can easily build a package for i386 and amd64 architectures and for say stable, sid and lucid.

sudo cowbuilder \
--create \
--basepath /var/cache/pbuilder/squeeze-i386/base.cow\
 --distribution squeeze\
 --debootstrapopts --arch --debootstrapopts i386

Creating an ubuntu base path is trickier because one must :

  1. Obtain ubuntu signing keys
  2. Use --keyring option to specific ubuntu signing keys
  3. add universe to complete creation of chroot because the cowdancer package is in universe.

$ wget http://archive.ubuntu.com/ubuntu/project/ubuntu-archive-keyring.gpg
$ sudo cp ubuntu-archive-keyring.gpg /usr/share/keyrings/
$ DIST=gutsy sudo cowbuilder --create \
--distribution gutsy \
--components "main universe" \
--basepath /var/cache/pbuilder/gutsy-amd64.cow \
--mirror http://apt:9999/ubuntu \
--debootstrapopts --keyring=/usr/share/keyrings/ubuntu-archive-keyring.gpg

BASEPATH="/var/cache/pbuilder/$NAME/base.cow/

sudo DIST=sid cowbuilder --update

dget -x http://ftp.de.debian.org/debian/pool/main/n/nano/nano_2.2.6-1.dsc
# For a Debian Squeeze on i386 target
sudo DIST=squeeze ARCH=i386 
# Ubuntu a Hardy on amd64 target
sudo DIST=hardy ARCH=amd64 cowbuilder --build nano_2.2.6-1.dsc

The result will be available in: /var/cache/pbuilder/squeeze-i386/result

Optionnal

set -e

RESULTDIR=$1
[ -d $RESULTDIR ] || mkdir $RESULTDIR

DISTLIST=$(ls -d /var/cache/pbuilder/*.cow)

for chrootdir in $DISTLIST
do
    sudo cowbuilder --update --basepath $chrootdir
    DIST=$(basename $chrootdir | cut -d'-' -f1)
    [ -d $RESULTDIR/$DIST ] || mkdir $RESULTDIR/$DIST
    DIST=$DIST pdebuild --pbuilder cowbuilder\
                        --buildresult $RESULTDIR/$DIST\
                        -- --basepath $chrootdir
done

( you shoud then add --mirror http://apt:9999/debian 

DIST=sid cowbuilder --login --save
apt-get install eatmydata

if [ -z "$LD_PRELOAD" ]; then
  LD_PRELOAD=/usr/lib/libeatmydata/libeatmydata.so
else
  LD_PRELOAD="$LD_PRELOAD":/usr/lib/libeatmydata/libeatmydata.so
fi

export LD_PRELOAD

Using with git-buildpackage

The above config can be adapted to work with the defaults of git-buildpackage:

-BASEPATH="/var/cache/pbuilder/$NAME/base.cow/"
+BASEPATH="/var/cache/pbuilder/base-$NAME.cow/"

Then the images can be created with:

DIST=sid ARCH=amd64 git-pbuilder create

And packages be built with:

DIST=sid ARCH=amd64 git-buildpackage --builder=git-pbuilder

A bug was opened to make sure the ARCH argument is coherent with the pbuilder way (ie. that it's optional), see: #646882

Troubleshooting

Slow copying and removing of the COW directory

What cowbuilder does is:

cp -al /var/cache/pbuilder/base.cow /tmp/new
rm -rf /tmp/new

Of course cowbuilder uses a different location than /tmp/new. You need to optimize those 2 commands on your computer. They should take around 0.2s each. If not, try to use the ext3 filesystem, for more details, see our benchmarks.