pbuilder + unionfs

Jani Monoses jani.monoses at gmail.com
Sat Mar 18 13:23:59 GMT 2006


Hello all

here's a patch against the scripts in /usr/lib/pbuilder (did not bother
with making a normal debdiff/package yet) which makes pbuilder use 
unionfs if available and told to do so (as in the .pbuilderrc attached)
If you're running dapper unionfs is supported by the kernel.
I also attach the wrapper script I use to do dapper builds, can easily 
be modified for other distros, it is based on what ships with pbuilder.

I have tested create/update/build/login/execute and seem to work fine so 
far. And fast too, since there's no untarring at start and tarring at 
the end.

It works like this: create makes a debootstrap image but instead of 
tarring it up it just leaves it as a plain chrootable directory. If
you do not want to debootstrap because it takes too much to download
just unpack an existing pbuilder chroot and set the 
PBUILDER_UNIONFS_ORIGDIR var to point to it, it should work.

Update works directly on this original dir.
The rest of the commands create a unionfs stack with this directory as 
the read only component and a new r/w dir in which the work happens.
When finished the r/w dir is removed while the original is untouched.
Quite a few paraller runs seem to work fine without problems.

There may be option combinations which are not handled, the only one I 
work with is using the system aptcache and that seems to be fine. Warns 
on create because of existing links but that's all.

How to test:

apply the patch in /usr/lib/pbuilder
set PBUILDER_UNIONFS=yes and PBUILDER_UNIONFS_ORIGDIR=/path/to/chroot
either by using ~/.pbuilderrc or from the command line. It should not
affect your existing pbuilder tar image at all.

if you test it let me know if you find any problems

thanks
Jani
-------------- next part --------------
#!/bin/sh
# script from Jamin W. Collins  BTS: #255165
# name this script 'pbuilder-woody', 'pbuilder-sid', 'pbuilder-sarge', 'pbuilder-experimental' etc.
OPERATION=$1
DISTRIBUTION=`basename $0 | cut -f2 -d '-'`
PROCEED=false
MIRRORSITE=http://archive.ubuntu.com/ubuntu/
BASE_DIR="$HOME/hack/ubuntu/pbuilder"
OTHERMIRROR="deb http://archive.ubuntu.com/ubuntu dapper universe"
APTCACHE=/var/cache/apt/archives

if [ $OPERATION = "build" ];then
	echo $2 | grep -q "dsc$" || exit 1
fi

case $OPERATION in
   create|update|build|clean|login|execute )
      PROCEED=true
      ;;
esac

if ( $PROCEED == true ) then
   shift 
   sudo pbuilder $OPERATION \
      --basetgz $BASE_DIR/$DISTRIBUTION-base.tgz \
      --distribution $DISTRIBUTION \
      --mirror $MIRRORSITE \
      --aptcache "$APTCACHE" \
      --othermirror "$OTHERMIRROR" \
      --buildresult $BASE_DIR/result $@
else
   echo "Invalid command..."
   echo "Valid commands are:"
   echo "   create"
   echo "   update"
   echo "   build"
   echo "   clean"
   echo "   login"
   echo "   execute"
   exit 1
fi
-------------- next part --------------
PBUILDER_UNIONFS=yes
PBUILDER_UNIONFS_ORIGDIR=/var/cache/pbuilder/dapper-universe

-------------- next part --------------
diff -rN -u old-pbuilder/pbuilder-buildpackage new-pbuilder/pbuilder-buildpackage
--- old-pbuilder/pbuilder-buildpackage	2006-03-18 14:26:28.000000000 +0200
+++ new-pbuilder/pbuilder-buildpackage	2006-03-18 14:26:28.000000000 +0200
@@ -77,6 +77,9 @@
 trap umountproc_cleanbuildplace exit
 createbuilduser
 
+echo "Creating temporary package build dir"
+echo "(mkdir -p /tmp/buildd)" | $CHROOTEXEC $SUTOUSER
+
 echo "Copying source file"
 copydsc "$PACKAGENAME" "$BUILDPLACE/tmp/buildd"
 
@@ -141,6 +144,12 @@
 BUILDRESULTUID="${BUILDRESULTUID:-${SUDO_UID:-0}}"
 BUILDRESULTGID="${BUILDRESULTGID:-${SUDO_GID:-0}}"
 
+#With unionfs the BUILDPLACE is unmounted at this stage
+#so take the built packages from the RW overlay
+if [ "$PBUILDER_UNIONFS" = "yes" ];then
+       BUILDPLACE=$BUILDPLACE-rw
+fi
+
 if [ -d "${BUILDRESULT}" ]; then
     chown "${BUILDRESULTUID}:${BUILDRESULTGID}" "${BUILDPLACE}"/tmp/buildd/*
     chgrp "${BUILDRESULTGID}" "${BUILDPLACE}"/tmp/buildd/*
diff -rN -u old-pbuilder/pbuilder-createbuildenv new-pbuilder/pbuilder-createbuildenv
--- old-pbuilder/pbuilder-createbuildenv	2006-03-18 14:26:28.000000000 +0200
+++ new-pbuilder/pbuilder-createbuildenv	2006-03-18 14:26:28.000000000 +0200
@@ -70,8 +70,6 @@
 echo " -> debootstrap finished"
 loadhooks
 
-mkdir -p "$BUILDPLACE/tmp/buildd"
-
 copy_local_configuration
 installaptlines
 
diff -rN -u old-pbuilder/pbuilder-modules new-pbuilder/pbuilder-modules
--- old-pbuilder/pbuilder-modules	2006-03-18 14:26:28.000000000 +0200
+++ new-pbuilder/pbuilder-modules	2006-03-18 14:26:28.000000000 +0200
@@ -129,6 +129,10 @@
     for mnt in $BINDMOUNTS; do
 	umount_one "$mnt"
     done
+    if [ "$PBUILDER_UNIONFS" = "yes" -a "$PBCURRENTCOMMANDLINEOPERATION" != "update" -a "$PBCURRENTCOMMANDLINEOPERATION" != "create" ];then
+	echo Unmounting the Unionfs
+	umount $BUILDPLACE
+    fi
 }
 
 
@@ -198,6 +202,11 @@
 	echo " -> Aborting with an error";
     fi
     if [ "${INTERNAL_BUILD_UML}" != "yes" ]; then
+	if [ "$PBUILDER_UNIONFS" = "yes" ]; then
+		if [ -d "$BUILDPLACE" -a "$PBCURRENTCOMMANDLINEOPERATION" = "update" ];then
+			rm $BUILDPLACE $BUILDPLACE-rw
+		fi
+	fi
 	if [ -d "$BUILDPLACE" ]; then 
 	    echo " -> cleaning the build env "
 	    clean_subdirectories "$BUILDPLACE"
@@ -280,21 +289,31 @@
 	    echo "E: failed to build the directory to chroot"
 	    exit 1
 	fi
-	echo " -> extracting base tarball [${BASETGZ}]"
-	if [ ! -f "$BASETGZ" ]; then
-	    echo "E: failed to find $BASETGZ, have you done <pbuilder create> to create your base tarball yet?"
-	    exit 1
-	fi
-	if ! (cd "$BUILDPLACE" && tar xfzp "$BASETGZ"); then
-	    echo "E: failed to extract $BASETGZ to $BUILDPLACE"
-	    exit 1
+	if [ "$PBUILDER_UNIONFS" = "yes" ];then
+		if [ "$PBCURRENTCOMMANDLINEOPERATION" = "update" ];then
+			rmdir $BUILDPLACE
+			ln -s $PBUILDER_UNIONFS_ORIGDIR $BUILDPLACE
+			ln -s $PBUILDER_UNIONFS_ORIGDIR $BUILDPLACE-rw
+		else
+			mkdir -p $BUILDPLACE-rw/var/cache/apt/archives
+			mount -t unionfs -o dirs=$BUILDPLACE-rw=rw:$PBUILDER_UNIONFS_ORIGDIR=ro none $BUILDPLACE
+		fi
+	else
+		echo " -> extracting base tarball [${BASETGZ}]"
+		if [ ! -f "$BASETGZ" ]; then
+		    echo "E: failed to find $BASETGZ, have you done <pbuilder create> to create your base tarball yet?"
+		    exit 1
+		fi
+		if ! (cd "$BUILDPLACE" && tar xfzp "$BASETGZ"); then
+		    echo "E: failed to extract $BASETGZ to $BUILDPLACE"
+		    exit 1
+		fi
 	fi
 	echo " -> creating local configuration"
 	hostname -f > "$BUILDPLACE/etc/mailname"
     fi
     copy_local_configuration
     mountproc
-    mkdir -p "$BUILDPLACE/tmp/buildd"
     
     if [ "$OVERRIDE_APTLINES" = "yes" ]; then
 	installaptlines
@@ -303,6 +322,11 @@
 
 
 function recover_aptcache() {
+    if [ "$PBUILDER_UNIONFS" = "yes" -a "$PBCURRENTCOMMANDLINEOPERATION" != "update" -a "$PBCURRENTCOMMANDLINEOPERATION" != "create" ];then
+	BPAPTCACHE=$BUILDPLACE-rw/var/cache/apt/archives
+    else
+	BPAPTCACHE=$BUILDPLACE/var/cache/apt/archives
+    fi
     local doit
     # recover the aptcache archive
     if [ -n "$APTCACHE" ]; then
@@ -314,12 +338,17 @@
 	echo "Obtaining the cached apt archive contents"
 	find "$APTCACHE" -maxdepth 1 -name \*.deb | \
 	    while read A ; do
-	    $doit "$A" "$BUILDPLACE/var/cache/apt/archives/" || true
-	done
+		$doit "$A" "$BPAPTCACHE" || true
+	    done
     fi
 }
 
 function save_aptcache() {
+    if [ "$PBUILDER_UNIONFS" = "yes" -a "$PBCURRENTCOMMANDLINEOPERATION" != "update" -a "$PBCURRENTCOMMANDLINEOPERATION" != "create" ];then
+	BPAPTCACHE=$BUILDPLACE-rw/var/cache/apt/archives
+    else
+	BPAPTCACHE=$BUILDPLACE/var/cache/apt/archives
+    fi
     # save the current aptcache archive
     # it is safe to call this function several times.
     local doit
@@ -331,7 +360,7 @@
 	else
 	    doit=cp
 	fi
-	find "$BUILDPLACE/var/cache/apt/archives/" -maxdepth 1 -name \*.deb | \
+	find "$BPAPTCACHE" -maxdepth 1 -name \*.deb | \
 	    while read A ;do
 	    if [ ! -f "$APTCACHE/"$(basename "$A") -a -f "$A" ]; then
 		echo " -> new cache content "$(basename "$A")" added"
@@ -348,17 +377,24 @@
 	    echo "Error: unexpected error in chdir to $BUILDPLACE" >&2
 	    exit 1;
 	fi
-	while test -f "${BASETGZ}.tmp"; do
-	    echo "  -> Someone else has lock over ${BASETGZ}.tmp, waiting"
-	    sleep 10s
-	done
-	echo " -> creating base tarball [${BASETGZ}]"
-	if ! tar cfz "${BASETGZ}.tmp" * ; then
-	    echo " -> failed building base tarball"
-	    rm -f "${BASETGZ}.tmp"
-	    exit 1;
+	if [ "$PBUILDER_UNIONFS" = "yes" ];then 
+		if [ "$PBCURRENTCOMMANDLINEOPERATION" = "create" ];then
+			echo "Renaming debootstrapped directory to $PBUILDER_UNIONFS_ORIGDIR"
+			mv $BUILDPLACE $PBUILDER_UNIONFS_ORIGDIR
+		fi
+	else	
+		while test -f "${BASETGZ}.tmp"; do
+		    echo "  -> Someone else has lock over ${BASETGZ}.tmp, waiting"
+		    sleep 10s
+		done
+		echo " -> creating base tarball [${BASETGZ}]"
+		if ! tar cfz "${BASETGZ}.tmp" * ; then
+		    echo " -> failed building base tarball"
+		    rm -f "${BASETGZ}.tmp"
+		    exit 1;
+		fi
+		mv "${BASETGZ}.tmp" "${BASETGZ}"
 	fi
-	mv "${BASETGZ}.tmp" "${BASETGZ}"
     )
 }
 



More information about the Ubuntu-motu mailing list