#!/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:-/a/portbuild} pbd=${PORTBUILD_DATA:-/a/portbuild} arch=$1 branch=$2 buildid=$3 nodelist=$4 shift 4 # XXX MCL 20121216 in theory if the slaves become owner 'portbuild' you won't need this. sudo_cmd= . ${pbc}/conf/server.conf if [ -f ${pbd}/${arch}/portbuild.conf ]; then . ${pbd}/${arch}/portbuild.conf else echo "Cannot find file ${pbd}/${arch}/portbuild.conf" exit 1 fi if [ -f ${pbd}/${arch}/${branch}/builds/${buildid}/portbuild.conf ]; then . ${pbd}/${arch}/${branch}/builds/${buildid}/portbuild.conf 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 if [ -f ${pbd}/${arch}/${branch}/builds/${buildid}/portbuild.conf ]; then . ${pbd}/${arch}/${branch}/builds/${buildid}/portbuild.conf fi . ${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_cmd} -a ${client_user}@${node} 't=$(mktemp -t setupnode); cat >$t; echo $t; chmod 755 $t') case ${cmdpath} in /tmp/*) ;; *) echo "Failed to upload or run setupnode on ${node}."; 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 # create one master copy in the default directory rsync ${rsync_gzip} -e "${ssh_cmd}" -r -l -p --delete ${pbc}/scripts ${pbc}/sources \ ${client_user}@${node}:/a/portbuild/ checkerror $? || (echo "Copying scripts to ${node} failed"; return 1) # copy the default conf files (i.e., client.conf and common.conf) in case # they are not overriden by per-buildenv ones, and have not been symlinked rsync ${rsync_gzip} -e "${ssh_cmd}" -r -L -p --delete ${pbd}/conf/client.conf \ ${client_user}@${node}:${pbd}/${arch} checkerror $? || (echo "Copying client.conf to ${node} failed"; return 1) rsync ${rsync_gzip} -e "${ssh_cmd}" -r -L -p --delete ${pbd}/conf/common.conf \ ${client_user}@${node}:${pbd}/${arch} checkerror $? || (echo "Copying common.conf to ${node} failed"; return 1) # per-buildenv conf files (e.g., 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 # XXX MCL really, only have to do portbuild.conf and portbuild..conf 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) if [ -f ${builddir}/portbuild.conf ]; then rsync ${rsync_gzip} -e "${ssh_cmd}" -r -L -p --delete ${builddir}/portbuild.conf \ ${client_user}@${node}:${builddir}/ checkerror $? || (echo "Copying custom portbuild.conf to ${node} failed"; return 1) else echo "No custom portbuild.conf." fi if [ -f ${builddir}/make.conf.client ]; then rsync ${rsync_gzip} -e "${ssh_cmd}" -r -L -p --delete ${builddir}/make.conf.client \ ${client_user}@${node}:${builddir}/ checkerror $? || (echo "Copying custom make.conf.client to ${node} failed"; return 1) else echo "No custom make.conf.client." fi 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 # XXX MCL NEED TIMEOUT HERE 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 ${ssh_cmd} ${client_user}@${node} ${sudo_cmd} rm -rf ${cmdpath} 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} /tmp/${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 # XXX MCL return value not being checked, as always setup ${node} & done wait