Index: projects/portbuild/scripts/claim-chroot =================================================================== --- projects/portbuild/scripts/claim-chroot (revision 221183) +++ projects/portbuild/scripts/claim-chroot (revision 221184) @@ -1,164 +1,164 @@ #!/bin/sh # client-side script to claim a chroot # 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 pbd=${PORTBUILD_DATA:-/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=${pbd}/${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 . ${pbd}/${arch}/client.conf . ${pbd}/${arch}/common.conf . ${pbd}/${arch}/portbuild.conf . ${pbd}/${arch}/portbuild.$(hostname) 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 - ${builddir}/scripts/clean-chroot ${arch} ${branch} ${buildid} ${dir} 2 >/dev/null 2>/dev/null & + /tmp/${buildid}/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}) if [ -z "${unit}" ]; then echo "error mdconfig" exit 1 fi 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}" Index: projects/portbuild/scripts/dosetupnode =================================================================== --- projects/portbuild/scripts/dosetupnode (revision 221183) +++ projects/portbuild/scripts/dosetupnode (revision 221184) @@ -1,193 +1,199 @@ #!/bin/sh # $FreeBSD: ports/Tools/portbuild/scripts/dosetupnode,v 1.17 2011/01/23 02:26:14 linimon Exp $ # server-side script to set up an individual client # XXX Use a worker pool that only runs N setups at once to avoid # raping the server. Hard to do in shell? # -norsync|-nocopy : Don't copy files, just clean up builds # # -force : force file copying/extraction even if it appears it is # up-to-date # # NB: branch or buildid might be "-" to specify only to set up the # scripts/ and ${arch}/ directories (e.g. after client reboot) # configurable variables pbc=${PORTBUILD_CHECKOUT:-/var/portbuild} pbd=${PORTBUILD_DATA:-/var/portbuild} arch=$1 branch=$2 buildid=$3 nodelist=$4 shift 4 . ${pbc}/conf/server.conf if [ -f ${pbd}/${arch}/portbuild.conf ]; then . ${pbd}/${arch}/portbuild.conf else echo "Invalid arch ${arch}" exit 1 fi . ${pbc}/scripts/buildenv # Check for non-fatal rsync errors checkerror() { error=$? case $error in 0) return 0 ;; 23) echo "Continuing..." return 0 ;; *) echo "Aborting..." return 1 ;; esac } setup() { node=$1 echo "setting up of $node started at $(date)" . ${pbd}/${arch}/portbuild.conf . ${pbd}/${arch}/portbuild.${node} + if [ "${buildid}" != "-" ]; then + rsync ${rsync_gzip} -e "${ssh_cmd}" -r -l -p --delete ${pbc}/scripts ${pbc}/sources \ + ${client_user}@${node}:/tmp/${buildid}/ + checkerror $? || (echo "Copying scripts to ${node} failed"; return 1) + fi + cmdpath=$(cat ${pbc}/scripts/setupnode | ssh -a ${client_user}@${node} 't=$(mktemp -t setupnode); cat >$t; echo $t; chmod 755 $t') case ${cmdpath} in /tmp/*) ;; *) echo "Failed to scp claim-chroot to ${host}."; return 1;; esac client_setup="${ssh_cmd} -n ${client_user}@${node} ${cmdpath} ${pbd} ${arch} ${branch} ${buildid} ${scratchdir} \"${portsmd5}\" \"${srcmd5}\" \"${bindistmd5}\"" args="${nocopy} ${force}" ${client_setup} pre-copy ${args} || (echo "pre-copy for ${node} failed"; return 1) if [ "${norsync}" -eq 0 ]; then # client.conf and common.conf can be symlinks outside this dir, so # copy the actual files rsync ${rsync_gzip} -e "${ssh_cmd}" -r -L -p --delete ${pbd}/${arch}/*.conf \ ${client_user}@${node}:${pbd}/${arch} checkerror $? || (echo "copying *.conf to ${node} failed"; return 1) # portbuild.* can be symlinks outside this dir, so copy the actual # files rsync ${rsync_gzip} -e "${ssh_cmd}" -r -L -p --delete ${pbd}/${arch}/portbuild* \ ${client_user}@${node}:${pbd}/${arch} checkerror $? || (echo "copying portbuild* files to ${node} failed"; return 1) if [ -f "${pbd}/${arch}/clients/bindist-${node}.tar" ]; then rsync ${rsync_gzip} -e "${ssh_cmd}" -r -L -p --delete \ ${pbd}/${arch}/clients/bindist-${node}.tar \ ${client_user}@${node}:${pbd}/${arch}/clients/ checkerror $? || (echo "Copying bindist-${node}.tar to ${node} failed"; return 1) else echo "Host customization file not found: ${pbd}/${arch}/clients/bindist-${node}.tar" return 1 fi if [ "${buildid}" != "-" ]; then rsync ${rsync_gzip} -e "${ssh_cmd}" -r -l -p --delete ${pbc}/scripts ${pbc}/sources \ ${client_user}@${node}:${builddir}/ checkerror $? || (echo "Copying scripts to ${node} failed"; return 1) rsync ${rsync_gzip} -e "${ssh_cmd}" -r -L -p \ ${builddir}/ports-${buildid}.tbz \ ${builddir}/ports-${buildid}.tbz.md5 \ ${builddir}/src-${buildid}.tbz \ ${builddir}/src-${buildid}.tbz.md5 \ ${builddir}/bindist.tbz \ ${builddir}/bindist.tbz.md5 \ ${client_user}@${node}:${builddir}/ checkerror $? || (echo "Copying build tarballs to ${node} failed"; return 1) fi fi ${client_setup} post-copy ${args} || (echo "post-copy for ${node} failed"; return 1) if [ "${queue}" -eq 1 ]; then jobs=$(python ${pbc}/qmanager/qclient jobs | grep "${node}" | grep "${arch}/${branch}/${buildid} package" | awk '{print $1}' | tail +1) for j in ${jobs}; do python ${pbc}/qmanager/qclient release $j done fi if [ "${full}" -eq 1 ]; then ${ssh_cmd} ${client_user}@${node} ${sudo_cmd} rm -rf ${pbd}/${arch}/${branch}/builds/${buildid}/.ready ${pbd}/${arch}/${branch}/builds/${buildid} /tmp/.setup-${buildid} fi echo "setting up of $node ended at $(date)" } pbab=${pbd}/${arch}/${branch} norsync=0 queue=0 full=0 while [ $# -ge 1 ]; do case $1 in -norsync|-nocopy) norsync=1 nocopy=-nocopy ;; -queue) queue=1 ;; -force) force=-force ;; -full) full=1 ;; esac shift done if [ "${norsync}" -eq 0 ]; then if [ "${branch}" != "-" -a "${buildid}" != "-" ]; then buildid=$(resolve ${pbd} ${arch} ${branch} ${buildid}) if [ -z "${buildid}" ]; then echo "Invalid build ID ${buildid}" exit 1 fi builddir=${pbab}/builds/${buildid} if [ ! -f ${builddir}/ports-${buildid}.tbz.md5 ]; then echo "ports-${buildid}.tbz.md5 not found" exit 1 else portsmd5=$(awk '{print $4}' ${builddir}/ports-${buildid}.tbz.md5) fi if [ ! -f ${builddir}/src-${buildid}.tbz.md5 ]; then echo "src-${buildid}.tbz.md5 not found" exit 1 else srcmd5=$(awk '{print $4}' ${builddir}/src-${buildid}.tbz.md5) fi if [ ! -f ${builddir}/bindist.tbz.md5 ]; then echo "bindist.tbz.md5 not found" exit 1 else bindistmd5=$(awk '{print $4}' ${builddir}/bindist.tbz.md5) fi fi fi if [ "${nodelist}" = "all" ]; then nodelist=$(cat ${pbd}/${arch}/mlist) fi for node in ${nodelist}; do setup ${node} & done wait Index: projects/portbuild/scripts/pdispatch =================================================================== --- projects/portbuild/scripts/pdispatch (revision 221183) +++ projects/portbuild/scripts/pdispatch (revision 221184) @@ -1,210 +1,210 @@ #!/bin/sh # $FreeBSD: ports/Tools/portbuild/scripts/pdispatch,v 1.40 2011/01/26 10:41:53 linimon Exp $ # # pdispatch [ ...] # # server-side script to dispatch the job to a host via the ptimeout script. pbc=${PORTBUILD_CHECKOUT:-/var/portbuild} pbd=${PORTBUILD_DATA:-/var/portbuild} arch=$1 branch=$2 buildid=$3 host=$4 command=$5 shift 5 pbab=${pbd}/${arch}/${branch} . ${pbc}/conf/server.conf . ${pbc}/conf/common.conf . ${pbd}/${arch}/portbuild.conf . ${pbc}/scripts/buildenv timeout=${PDISPATCH_TIMEOUT} loglength=${PDISPATCH_LOGLENGTH} hdrlength=${PDISPATCH_HDRLENGTH} buildid=$(resolve ${pbd} ${arch} ${branch} ${buildid}) if [ -z "${buildid}" ]; then echo "Invalid build ID ${buildid}" exit 1 fi builddir=${pbab}/builds/${buildid} buildenv ${pbd} ${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= . ${pbd}/${arch}/portbuild.conf test -f ${pbd}/${arch}/portbuild.${host} && . ${pbd}/${arch}/portbuild.${host} # Upload scripts/claim-chroot as per-build scripts aren't in place yet. cmdpath=$(cat ${pbc}/scripts/claim-chroot | ssh -a ${client_user}@${host} 't=$(mktemp -t claim-chroot); cat >$t; echo $t; chmod 755 $t') case ${cmdpath} in /tmp/*) ;; *) echo "Failed to scp claim-chroot to ${host}."; exit 254;; esac chrootdata=$(${ssh_cmd} -a -n ${client_user}@${host} ${sudo_cmd} ${cmdpath} ${arch} ${branch} ${buildid} ${pkgname} 2>&1) ${ssh_cmd} -a ${client_user}@${host} "rm -f ${cmdpath}" if [ -z "${chrootdata}" ]; then echo "Failed to claim chroot on ${host}" exit 254 fi case "${chrootdata}" in *${cmdpath}*) # 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 ${pbc}/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 . ${pbd}/${arch}/portbuild.conf test -f ${pbd}/${arch}/portbuild.${host} && . ${pbd}/${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 ${builddir}/ptimeout $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 --exclude ${chroot}/tmp/distfiles/RESTRICTED -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 ${pbc}/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} result=$? if [ $result -ne 0 ]; then (echo ${chroot}@${host}; ${ssh_cmd} -a -n ${client_user}@${host} ls -laR ${chroot}/tmp) | mail -s "${pkgname} logfile not found" ${mailto} else 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 ${pbc}/scripts/buildfailure ${arch} ${branch} ${buildid} ${pkgname} fi fi -${ssh_cmd} -a -n ${client_user}@${host} ${sudo_cmd} ${builddir}/scripts/clean-chroot ${arch} ${branch} ${buildid} ${chroot} ${clean} +${ssh_cmd} -a -n ${client_user}@${host} ${sudo_cmd} /tmp/${buildid}/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 255 fi Index: projects/portbuild/scripts/portbuild =================================================================== --- projects/portbuild/scripts/portbuild (revision 221183) +++ projects/portbuild/scripts/portbuild (revision 221184) @@ -1,345 +1,345 @@ #!/bin/sh # $FreeBSD: ports/Tools/portbuild/scripts/portbuild,v 1.65 2011/01/23 02:39:54 linimon Exp $ # client-side script to do all the work surrounding an individual package # build, and then the package build itself # note: unredirected 'echo' output goes to the journal file # usage: $0 ARCH BRANCH BUILDID CHROOT [-noclean] [-norestr] [-noplistcheck] [-distfiles] [-fetch-original] [-trybroken] PKGNAME.tgz DIRNAME [DEPENDENCY.tgz ...] pbd=${PORTBUILD_DATA:-/var/portbuild} mount_fs() { fs=$1 mntpt=$2 master=$3 if [ ${disconnected} = 1 ]; then mount -t nullfs -r ${fs} ${mntpt} else mount_nfs -o ro -3 -i ${master}:${fs} ${mntpt} fi } copypkg() { pbd=$1 host=$2 from=$3 to=$4 http_proxy=$5 if [ ${host} = $(hostname) ]; then cp ${pbd}/${arch}/${branch}/packages/All/${from} ${to} else if [ ! -z "${http_proxy}" ]; then env HTTP_PROXY=${http_proxy} fetch -m -o ${to} http://${host}/errorlogs/${arch}-${branch}-packages-latest/All/${from} else fetch -m -o ${to} http://${host}/errorlogs/${arch}-${branch}-packages-latest/All/${from} fi fi } bailout() { chroot=$1 clean=$2 error=$3 pkgname=$4 echo -n "$pkgname failed unexpectedly on $(hostname) at " date exit $error } arch=$1 branch=$2 buildid=$3 chroot=$4 shift 4 # Default niceness value nice=0 . ${pbd}/${arch}/client.conf . ${pbd}/${arch}/common.conf # note: should NOT need anything from server.conf . ${pbd}/${arch}/portbuild.conf . ${pbd}/${arch}/portbuild.$(hostname) . ${pbd}/scripts/buildenv buildroot=${scratchdir} error=0 clean=1 if [ "x$1" = "x-noclean" ]; then clean=0 shift fi norestr=0 if [ "x$1" = "x-norestr" ]; then norestr=1 # consumed by bsd.port.mk export NO_RESTRICTED=1 shift fi noplistcheck=0 if [ "x$1" = "x-noplistcheck" ]; then noplistcheck=1 # consumed by buildscript directly export NOPLISTCHECK=1 shift fi nodistfiles=1 if [ "x$1" = "x-distfiles" ]; then # consumed by buildscript via make(1) export ALWAYS_KEEP_DISTFILES=1 nodistfiles=0 shift fi if [ "x$1" = "x-fetch-original" ]; then # consumed by buildscript via make(1) export FETCH_ORIGINAL=1 shift fi if [ "x$1" = "x-trybroken" ]; then # consumed by bsd.port.mk export TRYBROKEN=1 shift fi ED=$1 PD=$2 FD=$3 BD=$4 RD=$5 builddir=${pbd}/${arch}/${branch}/builds/${buildid} buildenv.common # Want to use the /etc/make.conf in the chroot unset __MAKE_CONF # set overrides for make.conf export BACKUP_FTP_SITE=${CLIENT_BACKUP_FTP_SITE} pkgname=$(basename $6 ${PKGSUFFIX}) dirname=$7 shift 2 echo $pkgname echo $dirname # set overrides for bsd.port.mk variables export WRKDIRPREFIX=${CLIENT_WRKDIRPREFIX} export DISTDIR=${CLIENT_DISTDIR} export LOCALBASE=${LOCALBASE} export PACKAGES=${CLIENT_PACKAGES_LOCATION} export SRC_BASE=${CLIENT_SRCBASE} # to catch missing dependencies #export DEPENDS_TARGET=/usr/bin/true # don't pass -j, -k etc. to sub-makes unset MAKEFLAGS unset PORTSDIR # wait 2 hours before killing build with no output export BUILD_TIMEOUT=${CLIENT_BUILD_TIMEOUT} # prevent runaway processes ulimit -f ${CLIENT_ULIMIT_F} ulimit -t ${CLIENT_ULIMIT_T} # directories to clean cleandirs="${LOCALBASE} /compat /var/db/pkg" export FTP_TIMEOUT=${CLIENT_FTP_TIMEOUT} export HTTP_TIMEOUT=${CLIENT_HTTP_TIMEOUT} export PATH=/sbin:/bin:/usr/sbin:/usr/bin:${LOCALBASE}/sbin:${LOCALBASE}/bin export MALLOC_OPTIONS=${CLIENT_MALLOC_OPTIONS} echo "building ${pkgname} in ${chroot}" bindist=${buildroot}/${branch}/${buildid}/tarballs/bindist.tar bindistlocal=${buildroot}/${branch}/${buildid}/tarballs/bindist-$(hostname).tar if [ -f ${chroot}/.notready ]; then tar -C ${chroot} -xpf ${bindist} if [ -f ${bindistlocal} ]; then tar -C ${chroot} -xpf ${bindistlocal} fi # to be able to run certain kernel-dependent binaries # inside the chroot area cp -p /rescue/mount /rescue/umount ${chroot}/sbin cp -p /rescue/ps ${chroot}/bin rm ${chroot}/.notready touch ${chroot}/.ready fi if [ "${use_jail}" = "1" ]; then # Figure out jail IP addr chrootpid=$(basename ${chroot}) ipbase=$((${chrootpid}+2)) ip1=$(($ipbase /(256*256))) ip2=$((($ipbase - ($ip1*256*256)) /256)) ip3=$((($ipbase - ($ip1*256*256) - ($ip2*256)))) fi trap "bailout ${chroot} ${clean} ${error} ${pkgname}" 1 2 3 9 10 11 15 rm -rf ${chroot}/tmp/* cd ${chroot}/tmp mkdir -p depends distfiles packages echo "building ${pkgname} on $(hostname)" | tee ${chroot}/tmp/${pkgname}.log echo "in directory ${chroot}" | tee -a ${chroot}/tmp/${pkgname}.log # intentionally set up ${PORTSDIR} with symlink to catch broken ports mkdir -p ${chroot}/a/ports rm -rf ${chroot}/usr/ports # Don't build in a world-writable standard directory because some ports # hardcode this path and try to load things from it at runtime, which is # bad for user security rm -rf ${chroot}/${WRKDIRPREFIX} mkdir -p ${chroot}/${WRKDIRPREFIX} # pick up value from /portbuild.conf if [ ! -z "${ccache_dir}" ]; then mkdir -p ${chroot}/root/.ccache/ if [ "${ccache_dir_nfs}" = "1" ]; then mount_nfs -o rw -T -3 ${ccache_dir} ${chroot}/root/.ccache/ else mount -o rw -t nullfs ${ccache_dir} ${chroot}/root/.ccache/ fi fi mount_fs ${builddir}/ports ${chroot}/a/ports ${CLIENT_NFS_MASTER} ln -sf ../a/ports ${chroot}/usr/ports mkdir -p ${chroot}/usr/src mount_fs ${builddir}/src ${chroot}${CLIENT_SRCBASE} ${CLIENT_NFS_MASTER} # set overrides for uname buildenv.client ${chroot}${CLIENT_SRCBASE} mount -t devfs foo ${chroot}/dev umount -f ${chroot}/compat/linux/proc > /dev/null 2>&1 # just in case... for dir in ${cleandirs}; do if ! rm -rf ${chroot}${dir} >/dev/null 2>&1; then chflags -R noschg ${chroot}${dir} rm -rf ${chroot}${dir} >/dev/null 2>&1 fi done rm -rf ${chroot}/var/db/pkg/* mtree -deU -f ${chroot}/usr/src/etc/mtree/BSD.root.dist -p ${chroot} \ >/dev/null 2>&1 mtree -deU -f ${chroot}/usr/src/etc/mtree/BSD.var.dist -p ${chroot}/var \ >/dev/null 2>&1 mtree -deU -f ${chroot}/usr/src/etc/mtree/BSD.usr.dist -p ${chroot}/usr \ >/dev/null 2>&1 mkdir -p ${chroot}${LOCALBASE} mtree -deU -f ${chroot}/a/ports/Templates/BSD.local.dist -p ${chroot}${LOCALBASE} \ >/dev/null 2>&1 for i in ${ARCHS_REQUIRING_LINPROCFS}; do if [ ${i} = ${arch} ]; then # JDK ports need linprocfs :( mkdir -p ${chroot}/compat/linux/proc mount -t linprocfs linprocfs ${chroot}/compat/linux/proc break fi done _ldconfig_dirs="/lib /usr/lib /usr/lib/compat" ldconfig_dirs="" for i in ${_ldconfig_dirs}; do if [ -d ${chroot}/${i} ]; then ldconfig_dirs="${ldconfig_dirs} ${i}" fi done chroot ${chroot} /sbin/ldconfig ${ldconfig_dirs} for i in ${ARCHS_REQUIRING_AOUT_COMPAT}; do if [ ${i} = ${arch} ]; then chroot ${chroot} /sbin/ldconfig -aout /usr/lib/aout /usr/lib/compat/aout break fi done set x $ED $FD $PD $BD $RD shift 1 while [ $# -gt 0 ]; do # XXX MCL more hard-coding if [ ! -f ${chroot}/tmp/depends/$1 ]; then echo "copying package $1 for ${pkgname}" copypkg ${pbd} ${CLIENT_UPLOAD_HOST} $1 ${chroot}/tmp/depends "${http_proxy}" # Test for copy failure and bail # XXX MCL more hard-coding if [ ! -f ${chroot}/tmp/depends/$1 ]; then echo "ERROR: Couldn't copy $1" | tee -a ${chroot}/tmp/${pkgname}.log bailout ${chroot} ${clean} 255 ${pkgname} fi fi shift done -cp -p ${builddir}/scripts/buildscript ${chroot} -cp -p ${builddir}/sources/pnohang.c ${chroot} +cp -p /tmp/${buildid}/scripts/buildscript ${chroot} +cp -p /tmp/${buildid}/sources/pnohang.c ${chroot} # phase 0, compile pnohang chroot ${chroot} /usr/bin/gcc -o /pnohang -Wall /pnohang.c 2>&1 | tee -a ${chroot}/tmp/${pkgname}.log if [ $? -ne 0 ]; then error=255 fi if [ "${error}" = 0 ]; then # phase 1, make checksum # Needs to be chroot not jail so that port can be fetched chroot ${chroot} /buildscript ${dirname} 1 "$ED" "$PD" "$FD" "$BD" "$RD" 2>&1 | tee -a ${chroot}/tmp/${pkgname}.log if [ -f ${chroot}/tmp/status ]; then error=$(cat ${chroot}/tmp/status) else error=255 fi fi if [ "${error}" = 0 ]; then # make checksum succeeded # phase 2, make package ln -sf ${pkgname}.log2 ${chroot}/tmp/make.log if [ "${use_jail}" = 1 ]; then ifconfig lo0 alias 127.${ip1}.${ip2}.${ip3}/32 jail -J ${chroot}/tmp/jail.id ${chroot} jail-${chrootpid} 127.${ip1}.${ip2}.${ip3} /usr/bin/env JAIL_ADDR=127.${ip1}.${ip2}.${ip3} HTTP_PROXY=${http_proxy} /usr/bin/nice -n $nice /buildscript ${dirname} 2 "$ED" "$PD" "$FD" "$BD" "$RD" > ${chroot}/tmp/${pkgname}.log2 2>&1 ifconfig lo0 delete 127.${ip1}.${ip2}.${ip3} else chroot ${chroot} /usr/bin/nice -n ${nice} /buildscript ${dirname} 2 "$ED" "$PD" "$FD" "$BD" "$RD" > ${chroot}/tmp/${pkgname}.log2 2>&1 fi grep pnohang ${chroot}/tmp/${pkgname}.log2 cat ${chroot}/tmp/${pkgname}.log2 >> ${chroot}/tmp/${pkgname}.log rm ${chroot}/tmp/${pkgname}.log2 error=$(cat ${chroot}/tmp/status) fi rm -rf ${chroot}/${WRKDIRPREFIX} # Record build completion time for ganglia echo "${arch} ${branch} ${buildid}" > ${buildroot}/stamp/${pkgname} exit $error Index: projects/portbuild/scripts/setupnode =================================================================== --- projects/portbuild/scripts/setupnode (revision 221183) +++ projects/portbuild/scripts/setupnode (revision 221184) @@ -1,169 +1,169 @@ #!/bin/sh # # Script run on the clients, to set them up in preparation for building # packages. This includes setting up parts of the /var/portbuild # directory hierarchy, the portbuild script and the bindist.tar file # for populating the build chroots. if [ $# -lt 8 ]; then echo "usage: $0 portbuilddir arch branch buildid tmpdir portsmd5 srcmd5 phase [-nocopy] [-force]" exit 1 fi pbd=$1 arch=$2 branch=$3 buildid=$4 tmpdir=$5 portsmd5=$6 srcmd5=$7 bindistmd5=$8 phase=$9 shift 9 precopy() { # Create directories and symlinks for later population # Timestamp of finished builds mkdir -p ${tmpdir}/stamp/ # Prepare all directories, they will be populated by a rsync # push from the master mkdir -p ${pbd}/${arch}/clients/ if [ "${buildid}" != "-" -a "${branch}" != "-" ]; then if [ ${nocopy} -eq 0 ]; then mkdir -p ${builddir} fi fi } postcopy() { if [ "${buildid}" != "-" -a "${branch}" != "-" ]; then # Extract ports trees and cleanup if [ ${nocopy} -eq 0 ]; then cd ${builddir} || return 1 # Unpack bindist if [ -f bindist.tbz.md5 -a "${force}" -ne 1 ]; then localbindistmd5=$(awk '{print $4}' bindist.tbz.md5) else localbindistmd5=0 fi if [ ${localbindistmd5} != ${bindistmd5} -o ! -f bindist.tar ]; then if [ -f bindist.tar ]; then rm -f bindist.tar fi bzcat bindist.tbz > bindist.tar || return 1 fi # Unpack ports if [ -f ports-${buildid}.tbz.md5 -a "${force}" -ne 1 ]; then localportsmd5=$(awk '{print $4}' ports-${buildid}.tbz.md5) else localportsmd5=0 fi if [ ${localportsmd5} != ${portsmd5} -o ! -d ports ]; then if [ -d ports ]; then mv ports ports~ mkdir ports rm -rf ports~ & fi tar xfj ports-${buildid}.tbz || return 1 fi # Unpack src if [ -f src-${buildid}.tbz.md5 -a "${force}" -ne 1 ]; then localsrcmd5=$(awk '{print $4}' src-${buildid}.tbz.md5) else localsrcmd5=0 fi if [ ${localsrcmd5} != ${srcmd5} -o ! -d src ]; then if [ -d src ]; then mv src src~ mkdir src rm -rf src~ & fi tar xfj src-${buildid}.tbz || return 1 fi touch .ready fi # Clean up the tmpdir # By now the portbuild.conf files are in place so we can source them . ${pbd}/${arch}/portbuild.conf me=$(hostname) if [ -f ${pbd}/${arch}/portbuild.${me} ] ; then . ${pbd}/${arch}/portbuild.${me} fi if [ "${buildid}" != "-" -a "${branch}" != "-" ]; then mkdir -p ${wrkdir}/chroot if [ "${use_zfs}" -eq 1 ]; then zbase=${scratchdir#/} zfs create ${zbase}/${branch} || true zfs create ${zbase}/${branch}/${buildid} || true zfs create ${zbase}/${branch}/${buildid}/world || true zfs create ${zbase}/${branch}/${buildid}/chroot || true tar xfpC ${builddir}/bindist.tar ${scratchdir}/${branch}/${buildid}/world tar xfpC ${pbd}/${arch}/clients/bindist-$(hostname).tar ${scratchdir}/${branch}/${buildid}/world zfs snapshot ${zbase}/${branch}/${buildid}/world@base else mkdir -p ${wrkdir}/tarballs if [ ${nocopy} -eq 0 ]; then ln -sf ${pbab}/builds/${buildid}/bindist.tar ${wrkdir}/tarballs ln -sf ${pbd}/${arch}/clients/bindist-$(hostname).tar ${wrkdir}/tarballs fi fi fi for i in ${wrkdir}/chroot/*; do - ${sudo_cmd} ${builddir}/scripts/clean-chroot ${arch} ${branch} ${buildid} ${i} 2 + ${sudo_cmd} /tmp/${buildid}/scripts/clean-chroot ${arch} ${branch} ${buildid} ${i} 2 done wait else # Client may have been waiting for us to set it up, so finish # the job. touch /tmp/.boot_finished fi } if [ "${branch}" != "-" -a "${buildid}" != "-" ]; then pbab=${pbd}/${arch}/${branch} builddir=${pbab}/builds/${buildid} wrkdir=${tmpdir}/${branch}/${buildid} fi nocopy=0 force=0 while [ $# -ge 1 ]; do case $1 in -nocopy) nocopy=1 ;; -force) force=1 ;; esac shift done case ${phase} in pre-copy) precopy ;; post-copy) postcopy ;; *) echo "Invalid phase ${phase}" exit 1 esac