#!/bin/sh # # INDEX build tinderbox script. Build an INDEX for all supported FreeBSD branches # using the latest value of OSVERSION according to the src trees. If the build # fails, yowl about it on ${REPORT_ADDRESS} If not, copy the index to www.freebsd.org so # that 'make fetchindex' sees it. # # When INDEX is broken, assemble the list of committers who touched files # on the most recent 'cvs update', and put those committers "on the hook". # These committers all stay on the hook until INDEX is buildable again. # # MAINTAINER= erwin@FreeBSD.org # # -------------------------------------------------------- # Change these! # Address for success/failure reports REPORT_ADDRESS=root@localhost # Address for script errors ERROR_ADDRESS=root@localhost # Where to scp the resulting indexes after build SCP_DEST_HOST=root@localhost SCP_DEST_TMP=/tmp SCP_DEST_DIR=/usr/local/www/ports SNAP_DIR=a/snap/ports # Privileged zfs command ZFSCMD="/usr/local/bin/sudo /sbin/zfs" # Location of ports tree and source trees export BASEDIR=/local0/tmp/kris/tindex export PORTSDIR=${BASEDIR}/ports export SRCDIR6=${BASEDIR}/src.6 export SRCDIR7=${BASEDIR}/src.7 export SRCDIR8=${BASEDIR}/src.8 # Target architecture if not set in the environment if [ "${ARCH}" = "" ]; then export ARCH=i386 fi # SSH key to use for copying INDEXes to www host (if non-default) export SSHKEY="-i /home/kris/.ssh/id_dsa-index" # -------------------------------------------------------- blame() { # Find out who is responsible for current version of file $1 ident=$(ident ${BASEDIR}/$1 2>/dev/null | grep '$FreeBSD') who=$(echo $ident | awk '{print $6}') if [ ! -z $who ]; then echo $who fi } indexfail() { BRANCH=$1 # Leave a cookie behind so that we know when the index is fixed touch ${BASEDIR}/broken.${BRANCH} ( echo "INDEX build failed with errors:"; len=$(wc -l index.out | awk '{print $1}') if [ "$len" -gt "40" ]; then head -20 index.out echo "[...]" tail -20 index.out else cat index.out fi len=$(wc -l index.err | awk '{print $1}') if [ "$len" -gt "40" ]; then head -20 index.err echo "[...]" tail -20 index.err else cat index.err fi # Find out which committers are on the hook commits=$(grep Edit ${PORTSDIR}/cvsup.log | awk '{print $2}') for i in ${commits}; do blame $i >> ${PORTSDIR}/hook done sort -u ${PORTSDIR}/hook > ${PORTSDIR}/hook.new mv ${PORTSDIR}/hook.new ${PORTSDIR}/hook echo echo "Committers on the hook:" tr -s '\n' ' ' < ${PORTSDIR}/hook echo echo echo "Most recent CVS update was:"; grep 'Edit' ${PORTSDIR}/cvsup.log | awk '{print $2}' ) | mail -s "INDEX build failed for ${BRANCH}" ${REPORT_ADDRESS} exit 1 } checkfixed() { BRANCH=$1 # If the cookie exists that means that this is the first build for which the # INDEX succeeded, so announce this. if [ -e ${BASEDIR}/broken.${BRANCH} ]; then rm -f ${BASEDIR}/broken.${BRANCH} mail -s "INDEX now builds successfully on ${BRANCH}" ${REPORT_ADDRESS} < /dev/null fi } createtmpdir() { TMPDIR=`ssh ${SCP_DEST_HOST} "mktemp -qd ${SCP_DEST_TMP}/tindex.XXXXXX"` if [ $? -ne 0 ]; then echo "$0: Can't create temp file, exiting..." exit 1 fi } get_parent() { local fs=$1 # Check whether this filesystem has a parent /sbin/zfs get -H -o value origin ${fs} } now() { date +%Y%m%d%H%M%S } do_portsupdate() { do_destroy now=$(now) ${ZFSCMD} snapshot ${SNAP_DIR}@${now} ${ZFSCMD} clone ${SNAP_DIR}@${now} ${PORTSDIR#?} } do_destroy() { if [ -d ${PORTSDIR} ]; then parent=$(get_parent ${PORTSDIR#?}) ${ZFSCMD} destroy ${PORTSDIR#?} || exit 1 if [ ! -z "${parent}" ]; then ${ZFSCMD} destroy ${parent} || exit 1 fi fi } do_run() { # Sanitize the environment so that the indexes aren't customized by the # local machine settinge export __MAKE_CONF=/dev/null export PORT_DBDIR=/nonexistent export PKG_DBDIR=/nonexistent export INDEX_PRISTINE=1 export INDEX_JOBS=4 export INDEX_QUIET=1 # First update the source trees to get current OSVERSION cd ${SRCDIR6}/sys/sys cvs -Rq update -PdA -r RELENG_6 param.h OSVERSION6=$(awk '/^#define[[:blank:]]__FreeBSD_version/ {print $3}' < ${SRCDIR6}/sys/sys/param.h) cd ${SRCDIR7}/sys/sys cvs -Rq update -PdA -r RELENG_7 param.h OSVERSION7=$(awk '/^#define[[:blank:]]__FreeBSD_version/ {print $3}' < ${SRCDIR7}/sys/sys/param.h) cd ${SRCDIR8}/sys/sys cvs -Rq update -PdA param.h OSVERSION8=$(awk '/^#define[[:blank:]]__FreeBSD_version/ {print $3}' < ${SRCDIR8}/sys/sys/param.h) cd ${PORTSDIR} rm -f INDEX-6 INDEX-6.bz2 INDEX-7 INDEX-7.bz2 INDEX-8 INDEX-8.bz2 for branch in 6.x 7.x 8.x; do release=$(echo $branch | sed -e 's,.x,,') eval _osver=\$OSVERSION${release} export OSVERSION=${_osver} echo "Building INDEX for ${branch} with OSVERSION=${OSVERSION}" cd ${PORTSDIR} ((make index 2> index.err) > index.out) || indexfail ${branch} if [ -s index.err ]; then indexfail ${branch} fi checkfixed ${branch} createtmpdir bzip2 -kf ${PORTSDIR}/INDEX-${release} scp -q ${SSHKEY} ${PORTSDIR}/INDEX-${release} ${PORTSDIR}/INDEX-${release}.bz2 ${SCP_DEST_HOST}:${TMPDIR} || mail -s "Cannot copy INDEX-${release} to temp dir" ${ERROR_ADDRESS} ssh ${SCP_DEST_HOST} "/bin/mv ${TMPDIR}/INDEX-${release} ${SCP_DEST_DIR}; /bin/mv ${TMPDIR}/INDEX-${release}.bz2 ${SCP_DEST_DIR}; rmdir ${TMPDIR}" || mail -s "Cannot move INDEX-${release} to final dir" ${ERROR_ADDRESS} done } usage () { echo "usage: tindex " exit 1 } ############################# if [ $# -lt 1 ]; then usage fi cmd=$1 shift # Unprivileged commands case "$cmd" in run) do_run ;; portsupdate) do_portsupdate ;; destroy) do_destroy ;; *) echo "Invalid command: $cmd" exit 1 ;; esac