freebsd-ports/Tools/portbuild/scripts/pdispatch
Mark Linimon 2e131db722 Generalize the packge building scripts to be able to be run on more than
one 'head' node, rather than just pointyhat itself.

Constants are factored out into installation-specific files known as
portbuild/conf/server.conf and portbuild/conf/client.conf.  There is
only one server.conf file.  Individual <arch> directories may have
their own client.conf files, or may symlink to ../conf/client.conf.

Feature safe:	yes
2010-06-25 23:27:16 +00:00

197 lines
6.5 KiB
Bash
Executable file

#!/bin/sh
# $FreeBSD$
#
# pdispatch <arch> <branch> <buildid> <host> <command> <package.tbz> [<args> ...]
#
# server-side script to dispatch the job to a host via the ptimeout script.
pb=/var/portbuild
arch=$1
branch=$2
buildid=$3
host=$4
command=$5
shift 5
pbab=${pb}/${arch}/${branch}
. ${pb}/conf/server.conf
. ${pb}/${arch}/portbuild.conf
. ${pb}/scripts/buildenv
timeout=${PDISPATCH_TIMEOUT}
loglength=${PDISPATCH_LOGLENGTH}
hdrlength=${PDISPATCH_HDRLENGTH}
buildid=$(resolve ${pb} ${arch} ${branch} ${buildid})
if [ -z "${buildid}" ]; then
echo "Invalid build ID ${buildid}"
exit 1
fi
builddir=${pbab}/builds/${buildid}
buildenv ${pb} ${arch} ${branch} ${builddir}
# XXX needed still?
unset DISPLAY
# Allow override by HPN-SSH for performance
if [ -z "${ssh_cmd}" ]; then
ssh_cmd=ssh
fi
if [ -z "${scp_cmd}" ]; then
scp_cmd=scp
fi
pkgname=$(basename $1 ${PKGSUFFIX})
if [ -z "${pkgname}" ]; then
echo "null packagename"
exit 1
fi
args=${1+"$@"}
flags=""
clean=1
if [ "x$NOCLEAN" != "x" ]; then
flags="${flags} -noclean"
clean=0
fi
if [ "x$NO_RESTRICTED" != "x" ]; then
flags="${flags} -norestr"
fi
if [ "x$NOPLISTCHECK" != "x" ]; then
flags="${flags} -noplistcheck"
fi
if [ "x$NO_DISTFILES" = "x" ]; then
flags="${flags} -distfiles"
fi
if [ "x$FETCH_ORIGINAL" != "x" ]; then
flags="${flags} -fetch-original"
fi
if [ "x$TRYBROKEN" != "x" ]; then
flags="${flags} -trybroken"
fi
chroot=
. ${pb}/${arch}/portbuild.conf
test -f ${pb}/${arch}/portbuild.${host} && . ${pb}/${arch}/portbuild.${host}
chrootdata=$(${ssh_cmd} -a -n ${client_user}@${host} ${sudo_cmd} ${pb}/scripts/claim-chroot ${arch} ${branch} ${buildid} ${pkgname} 2>&1)
if [ -z "${chrootdata}" ]; then
echo "Failed to claim chroot on ${host}"
exit 254
fi
case "${chrootdata}" in
*/var/portbuild/scripts/claim-chroot*)
# Error executing script, assume system is booting
chrootdata="wait boot"
;;
esac
# echo "Got ${chrootdata} from ${host}"
set -- ${chrootdata}
if [ $# -ge 2 ]; then
case $1 in
chroot)
chroot=$2
;;
setup)
echo "Setting up ${arch}/${branch} build ID ${buildid} on ${host}"
# Run in the background so we can potentially
# claim a slot on another machine. In
# practise I think we often end up trying
# again on the same machine though.
# Make sure to close stdin/stderr in the child
# or make will hang until the child process
# exits
${pb}/scripts/dosetupnode ${arch} ${branch} ${buildid} ${host} > /tmp/setupnode.$$ 2>&1 &
exit 253
;;
error)
echo "Error reported by ${host}: $2"
;;
wait)
echo "Waiting for setup of ${host} to finish"
;;
esac
shift 2
fi
if [ -z "${chroot}" ]; then
exit 254
fi
. ${pb}/${arch}/portbuild.conf
test -f ${pb}/${arch}/portbuild.${host} && . ${pb}/${arch}/portbuild.${host}
rm -f ${builddir}/logs/${pkgname}.log ${builddir}/logs/${pkgname}.log.bz2
rm -f ${builddir}/errors/${pkgname}.log ${builddir}/errors/${pkgname}.log.bz2
${pb}/scripts/ptimeout.host $timeout ${ssh_cmd} -a -n ${client_user}@${host} ${sudo_cmd} ${command} ${arch} ${branch} ${buildid} ${chroot} ${flags} \"$ED\" \"$PD\" \"$FD\" \"$BD\" \"$RD\" ${args} 2>&1
error=$?
# Pull in the results of the build from the client
${scp_cmd} ${client_user}@${host}:${chroot}/tmp/${pkgname}.log ${builddir}/logs/${pkgname}.log
(${ssh_cmd} -a -n ${client_user}@${host} test -f ${chroot}/tmp/work.tbz ) && ${scp_cmd} ${client_user}@${host}:${chroot}/tmp/work.tbz ${builddir}/wrkdirs/${pkgname}.tbz
# XXX Set dirty flag if any of the scp's fail
mkdir -p ${builddir}/distfiles/.pbtmp/${pkgname}
${ssh_cmd} -a -n ${client_user}@${host} tar -C ${chroot}/tmp/distfiles -cf - . | \
tar --unlink -C ${builddir}/distfiles/.pbtmp/${pkgname} -xvf - && \
touch ${builddir}/distfiles/.pbtmp/${pkgname}/.done
if [ "${error}" = 0 ]; then
${ssh_cmd} -a -n ${client_user}@${host} tar -C ${chroot}/tmp -cf - packages | \
tar --unlink -C ${builddir} -xvf -
# XXX why is this needed?
test -f ${builddir}/packages/All/${pkgname}${PKGSUFFIX} && \
touch ${builddir}/packages/All/${pkgname}${PKGSUFFIX}
if [ -f ${builddir}/errors/${pkgname}.log ]; then
rm -f ${builddir}/errors/${pkgname}.log
# Force rebuild of html page to remove this package from list
touch ${builddir}/errors/.force
fi
lockf -k ${pbab}/failure.lock ${pb}/scripts/buildsuccess ${arch} ${branch} ${buildid} ${pkgname}
log=${builddir}/logs/$pkgname.log
if grep -q "even though it is marked BROKEN" ${log}; then
echo | mail -s "${pkgname} BROKEN but built on ${arch} ${branch}" ${mailto}
fi
if grep -q "^list of .*file" ${log}; then
buildlogdir=$(realpath ${builddir}/logs/)
baselogdir=$(basename ${buildlogdir})
(sed -e '/^build started/,$d' $log;echo;echo "For the full build log, see"; echo; echo " http://${MASTER_URL}/errorlogs/${arch}-errorlogs/${baselogdir}/$(basename $log)";echo;sed -e '1,/^=== Checking filesystem state/d' $log) | mail -s "${pkgname} pkg-plist errors on ${arch} ${branch}" ${mailto}
fi
else
log=${builddir}/errors/${pkgname}.log
${scp_cmd} ${client_user}@${host}:${chroot}/tmp/${pkgname}.log ${log} || (echo ${chroot}@${host}; ${ssh_cmd} -a -n ${client_user}@${host} ls -laR ${chroot}/tmp) | mail -s "${pkgname} logfile not found" ${mailto}
if ! grep -q "even though it is marked BROKEN" ${log}; then
buildlogdir=$(realpath ${builddir}/logs/)
baselogdir=$(basename ${buildlogdir})
if [ $(wc -l ${log} | awk '{print $1}') -le $((loglength + hdrlength)) ]; then
(echo "You can also find this build log at"; echo; echo " http://${MASTER_URL}/errorlogs/${arch}-errorlogs/${baselogdir}/$(basename $log)";echo;cat ${log}) | mail -s "${pkgname} failed on ${arch} ${branch}" ${mailto}
else
(echo "Excerpt from the build log at"; echo; echo " http://${MASTER_URL}/errorlogs/${arch}-errorlogs/${baselogdir}/$(basename $log)";echo;sed -e '/^build started/,$d' $log;echo;echo " [... lines trimmed ...]";echo;tail -${loglength} ${log}) | mail -s "${pkgname} failed on ${arch} ${branch}" ${mailto}
fi
fi
lockf -k ${pbab}/failure.lock ${pb}/scripts/buildfailure ${arch} ${branch} ${buildid} ${pkgname}
fi
${ssh_cmd} -a -n ${client_user}@${host} ${sudo_cmd} ${pb}/scripts/clean-chroot ${arch} ${branch} ${buildid} ${chroot} ${clean}
# XXX Set a dirty variable earlier and check here
if grep -q "^build of .*ended at" ${builddir}/logs/${pkgname}.log; then
exit ${error}
else
echo "Build of ${pkgname} in ${host}:/${chroot} failed uncleanly"
exit 254
fi