f8a634d336
* Catch up to build ID directory changes * Improved support for ZFS builds * Improved robustness * Report status verbosely to the caller; whether we succeeded in claiming a chroot, whether the caller needs to first set up the client, or whether a setup is in progress. * If we discover that the client has not been set up either because it freshly booted and newfs'ed its filesystem, or because a particular build has not yet been encountered, atomically claim a cookie and report this to the caller to act on
159 lines
4.1 KiB
Bash
Executable file
159 lines
4.1 KiB
Bash
Executable file
#!/bin/sh
|
|
|
|
# usage: claim-chroot ${arch} ${branch} ${pkgname} ${buildid}
|
|
|
|
# Care needs to be taken with the output of this script, it cannot
|
|
# output anything except space-separated pairs of "keyword value".
|
|
#
|
|
# Keywords:
|
|
# chroot : successfully claimed a chroot
|
|
# setup : we own the rights to setup the build env
|
|
# wait : someone else is setting up the build env
|
|
|
|
# In case of other error, just exit.
|
|
|
|
# XXX if the setupnode process was a single process invocation we
|
|
# could use a lockf lock, and be able to tell if the setup process was
|
|
# still running or died prematurely
|
|
|
|
pb=/var/portbuild
|
|
|
|
usage () {
|
|
echo "usage: claim-chroot arch branch buildid"
|
|
exit 1
|
|
}
|
|
|
|
if [ $# -ne 4 ]; then
|
|
usage
|
|
fi
|
|
|
|
arch=$1
|
|
branch=$2
|
|
buildid=$3
|
|
pkgname=$4
|
|
shift 4
|
|
|
|
# If client has just rebooted it may not have any files yet
|
|
|
|
if [ ! -f /tmp/.boot_finished ]; then
|
|
echo "wait boot"
|
|
exit 1
|
|
fi
|
|
|
|
# Do we need to set up the client after cold boot?
|
|
#
|
|
# NB: mkdir is being used as an atomic test-and-set operation to
|
|
# provide mutual exclusion against other callers, since we only want
|
|
# one of them to perform setup
|
|
|
|
builddir=${pb}/${arch}/${branch}/builds/${buildid}
|
|
|
|
# Is the build environment populated? Again we only want a single
|
|
# instance to gain setup rights if not.
|
|
if (mkdir /tmp/.setup-${buildid} 2> /dev/null); then
|
|
# The buildenv is not set up, tell the caller to do it
|
|
echo "setup ${builddir}"
|
|
exit 1
|
|
fi
|
|
|
|
if [ ! -f ${builddir}/.ready ]; then
|
|
# The buildenv is still being set up
|
|
echo "wait ${builddir}"
|
|
exit 1
|
|
fi
|
|
|
|
. ${pb}/${arch}/portbuild.conf
|
|
. ${pb}/${arch}/portbuild.$(hostname)
|
|
. ${pb}/scripts/buildenv
|
|
|
|
buildenv ${pb} ${arch} ${branch} ${builddir}
|
|
|
|
buildroot=${scratchdir}
|
|
pkgname=${pkgname%.${PKGSUFFIX}}
|
|
|
|
chrootdir=${buildroot}/${branch}/${buildid}/chroot
|
|
|
|
# Perform initial sanity checks
|
|
|
|
# Check squid is running
|
|
if [ ! -z "${squid_dir}" ]; then
|
|
/usr/local/sbin/squid -k check 2> /dev/null
|
|
status=$?
|
|
if [ "${status}" != "0" ]; then
|
|
touch ${scratchdir}/.squid
|
|
/usr/local/etc/rc.d/squid start > /dev/null &
|
|
echo "error squid"
|
|
exit 1
|
|
else
|
|
rm -f ${scratchdir}/.squid
|
|
fi
|
|
fi
|
|
|
|
# Check for enough disk space
|
|
df=$(df -k ${scratchdir} | tail -1 | awk '{print $4}')
|
|
|
|
if [ ${df} -lt 102400 ]; then
|
|
touch ${scratchdir}/.disk
|
|
echo "error disk"
|
|
exit 1
|
|
else
|
|
rm -f ${scratchdir}/.disk
|
|
fi
|
|
|
|
found=0
|
|
# Look for pre-existing chroot directories that are populated and unused
|
|
for dir in ${chrootdir}/*; do
|
|
if [ -f ${dir}/.ready -o -f ${dir}/.dirty ]; then
|
|
# Atomically claim the directory
|
|
mkdir ${dir}/used 2>/dev/null || continue
|
|
touch ${dir}/used/${pkgname}
|
|
if [ -f ${dir}/.dirty ]; then
|
|
${pb}/scripts/clean-chroot ${arch} ${branch} ${buildid} ${dir} 2 >/dev/null 2>/dev/null &
|
|
continue
|
|
fi
|
|
found=1
|
|
chroot=${dir}
|
|
break
|
|
fi
|
|
done
|
|
|
|
chrootnum=$$
|
|
# If we didn't find a pre-existing directory, create and claim a new one.
|
|
while [ ${found} != 1 ]; do
|
|
if [ "${use_zfs}" = "1" ]; then
|
|
chroot=${chrootdir}/${chrootnum}
|
|
# XXX deal with failure
|
|
zfs clone ${scratchdir#/}/${branch}/${buildid}/world@base ${chroot#/}
|
|
mkdir ${chroot}/used
|
|
elif [ "${use_md_swap}" = "1" ]; then
|
|
unit=$(mdconfig -a -t swap -s ${md_size})
|
|
newfs /dev/${unit} > /dev/null
|
|
chrootnum=$(echo ${unit} | sed 's,md,,')
|
|
chroot=${chrootdir}/${chrootnum}
|
|
mkdir -p ${chroot}/used 2>/dev/null || continue
|
|
# Need to make sure that used/ is also present after mounting
|
|
# the fresh md so as to not leave open any races
|
|
mount -o async /dev/${unit} ${chroot}/used
|
|
mkdir ${chroot}/used/used
|
|
touch ${chroot}/used/used/${pkgname}
|
|
umount -f ${chroot}/used
|
|
mount -o async /dev/${unit} ${chroot}/
|
|
touch ${chroot}/.notready
|
|
else
|
|
chrootnum=$(($chrootnum+1))
|
|
chroot=${chrootdir}/${chrootnum}
|
|
mkdir -p ${chrootdir} 2> /dev/null || continue
|
|
mkdir ${chroot} 2>/dev/null || continue
|
|
mkdir ${chroot}/used 2>/dev/null || continue
|
|
touch ${chroot}/.notready
|
|
fi
|
|
if [ "${use_tmpfs}" = "1" ]; then
|
|
mount -t tmpfs -o "size=${tmpfs_size}" foo ${chroot}
|
|
mkdir ${chroot}/used 2>/dev/null || echo "ERROR: mkdir race"
|
|
touch ${chroot}/.notready
|
|
fi
|
|
touch ${chroot}/used/${pkgname}
|
|
found=1
|
|
done
|
|
|
|
echo "chroot ${chroot}"
|