#!/bin/bash PID=$$ config_file= verbose=0 keep_tmpdir=0 testing=0 usage() { msg=$1 if [ -n "${msg}" ]; then echo -e "${msg}\n"; fi cat <] [--verbose] [-h|--help] Options: -c|--config Specifies the config file to use (required) --verbose Send output of commands to console as well as log -k|--keep-tmpdir Don't remove temp dir when build finishes -t|--test Stop after mangling specs and copying files -h|--help Show this message and quit EOH } send_email() { subject="${EMAIL_SUBJECT_PREPEND} $1" message=$2 logfile=$3 if [ -n "${logfile}" ]; then body=$(echo -e "${message}\n\n"; tail -n 200 "${logfile}"; echo -e "\n\n\nFull build log at ${logfile}") else body=${message} fi echo -e "From: ${EMAIL_FROM}\r\nTo: ${EMAIL_TO}\r\nSubject: ${subject}\r\n\r\n${body}" | /usr/sbin/sendmail -f ${EMAIL_FROM} ${EMAIL_TO} } run_cmd() { cmd=$1 logfile=$2 if [ $verbose = 1 ]; then echo "*** Running command: ${cmd}" ${cmd} 2>&1 | tee ${logfile} else ${cmd} &> ${logfile} fi } pre_build() { # This is a skeleton function that you can override from the config file. # It will be executed before the build is started. You can use this to # update a svn checkout of spec files local foo=bar } post_build() { # This is a skeleton function that you can override from the config file. # It will be executed after the build is successfully completed. You can # use this to rsync the builds to another box local foo=bar } # Parse args params=${#} while [ ${#} -gt 0 ] do a=${1} shift case "${a}" in -h|--help) usage exit 0 ;; -c|--config) config_file=$1 shift ;; --verbose) verbose=1 ;; -k|--keep-tmpdir) keep_tmpdir=1 ;; -t|--test) testing=1 ;; -*) echo "You have specified an invalid option: ${a}" usage exit 1 ;; esac done # Make sure all required values were specified if [ -z "${config_file}" -o ! -e "${config_file}" ]; then usage "You must specify a valid config file to use" exit 1 fi source ${config_file} TMPDIR=/tmp/catalyst-auto.${PID} DATESTAMP=$(date +%Y%m%d) if [ ${verbose} = 1 ]; then echo "TMPDIR = ${TMPDIR}" echo "DATESTAMP = ${DATESTAMP}" fi # Check if tmp directory exists and remove it if [ -d "${TMPDIR}" ]; then if ! rm -rf "${TMPDIR}"; then echo "Couldn't remove stale tmpdir ${TMPDIR}!" exit 1 fi fi for i in ${TMPDIR} ${TMPDIR}/specs ${TMPDIR}/kconfig ${TMPDIR}/log; do if ! mkdir -p "${i}"; then echo "Couldn't create dir ${i}!" exit 1 fi done if ! run_cmd "pre_build" "${TMPDIR}/log/pre_build.log"; then send_email "Catalyst build error - pre_build" "Your pre_build function sucks" "${TMPDIR}/log/pre_build.log" exit 1 fi cd ${SPECS_DIR} for a in "" ${SETS}; do if [ -z "${a}" ]; then specs_var="SPECS" optional_specs_var="OPTIONAL_SPECS" else specs_var="SET_${a}_SPECS" optional_specs_var="SET_${a}_OPTIONAL_SPECS" fi for i in ${!specs_var} ${!optional_specs_var}; do cp --parents ${i} ${TMPDIR}/specs/ done done find ${KCONFIG_DIR} -type f -exec cp {} ${TMPDIR}/kconfig \; cd ${TMPDIR}/specs # Fix up specs with datestamp for i in $(find -name '*.spec'); do # Grab current version_stamp and source_subpath old_version_stamp=$(grep version_stamp ${i} | sed -e 's|^version_stamp: *||') old_source_subpath=$(grep source_subpath ${i} | sed -e 's|^source_subpath: *||') new_version_stamp=$(echo "${old_version_stamp}" | sed -e 's|^\(.*-\)\?.*$|\1'${DATESTAMP}'|') new_source_subpath=$(echo "${old_source_subpath}" | sed -e 's|'${old_version_stamp}'$|'${new_version_stamp}'|') sed -i 's|^version_stamp:.*$|version_stamp: '${new_version_stamp}'|' ${i} sed -i 's|^snapshot:.*$|snapshot: '${DATESTAMP}'|' ${i} # We don't want to mangle the source_subpath for our stage1 spec if ! grep -q '^target: *stage1$' ${i}; then sed -i 's|^source_subpath:.*$|source_subpath: '${new_source_subpath}'|' ${i} fi sed -i '/^livecd\/iso/s|'${old_version_stamp}'|'${new_version_stamp}'|' ${i} sed -i '/^livecd\/volid/s|'${old_version_stamp}'|'${new_version_stamp}'|' ${i} kconfig_lines=$(grep '^boot/kernel/[^/]\+/config:' ${i}) if [ -n "${kconfig_lines}" ]; then echo "${kconfig_lines}" | while read line; do key=$(echo "${line}" | cut -d: -f1) filename=$(basename $(echo "${line}" | cut -d: -f2)) sed -i "s|^${key}:.*\$|${key}: ${TMPDIR}/kconfig/${filename}|" ${i} done fi done if [ "${testing}" -eq 1 ]; then echo "Exiting due to --test" exit fi # Create snapshot if ! run_cmd "catalyst -c ${CATALYST_CONFIG} -s ${DATESTAMP}" "${TMPDIR}/log/snapshot.log"; then send_email "Catalyst build error - snapshot" "" "${TMPDIR}/log/snapshot.log" exit 1 fi build_failure=0 for a in "" ${SETS}; do if [ -z "${a}" ]; then specs_var="SPECS" optional_specs_var="OPTIONAL_SPECS" else specs_var="SET_${a}_SPECS" optional_specs_var="SET_${a}_OPTIONAL_SPECS" fi for i in ${!specs_var}; do LOGFILE="${TMPDIR}/log/$(echo "${i}" | sed -e 's:/:_:' -e 's:\.spec$::').log" run_cmd "catalyst -a -p -c ${CATALYST_CONFIG} -f ${i}" ${LOGFILE} if [ $? != 0 ]; then build_failure=1 send_email "Catalyst fatal build error - ${i}" "" "${LOGFILE}" continue 2 fi done for i in ${!optional_specs_var}; do LOGFILE="${TMPDIR}/log/$(echo "${i}" | sed -e 's:/:_:' -e 's:\.spec$::').log" run_cmd "catalyst -a -p -c ${CATALYST_CONFIG} -f ${i}" ${LOGFILE} if [ $? != 0 ]; then build_failure=1 send_email "Catalyst non-fatal build error - ${i}" "" "${LOGFILE}" break fi done for i in ${!specs_var} ${!optional_specs_var}; do LOGFILE="${TMPDIR}/log/$(echo "${i}" | sed -e 's:/:_:' -e 's:\.spec$::')_purge.log" run_cmd "catalyst -P -c ${CATALYST_CONFIG} -f ${i}" "${LOGFILE}" done done if ! run_cmd "post_build" "${TMPDIR}/log/post_build.log"; then send_email "Catalyst build error - post_build" "Your post_build function sucks" "${TMPDIR}/log/post_build.log" exit 1 fi if [ ${build_failure} = 0 ]; then send_email "Catalyst build success" "Build process complete." if [ "${keep_tmpdir}" = 0 ]; then if ! rm -rf "${TMPDIR}"; then echo "Could not remove tmpdir ${TMPDIR}!" exit 1 fi fi else send_email "Catalyst build complete, but with errors" "Build process has completed, but there were errors. Please consult previous emails to determine the problem." fi