#!/bin/bash # Copyright 1999-2014 Gentoo Foundation # Distributed under the terms of the GNU General Public License v2 # First let's get our own namespaces to avoid leaking crap. if [[ -z ${UNSHARE} ]] ; then if type -P unshare >&/dev/null ; then uargs=() # Probe the namespaces as some can be disabled (or we are not root). unshare -m -- true >&/dev/null && uargs+=( -m ) unshare -u -- true >&/dev/null && uargs+=( -u ) unshare -i -- true >&/dev/null && uargs+=( -i ) unshare -p -- true >&/dev/null && uargs+=( -p -f --mount-proc ) # Re-exec ourselves in the new namespace. UNSHARE=true exec unshare "${uargs[@]}" -- "$0" "$@" fi fi unset UNSHARE config_file= verbose=0 keep_tmpdir=0 testing=0 # Set pipefail so that run_cmd returns the right value in $? set -o pipefail usage() { local msg=$1 if [ -n "${msg}" ]; then printf "%b\n\n" "${msg}" fi cat <] [-v|--verbose] [-h|--help] Options: -c|--config Specifies the config file to use (required) -v|--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 the checkout of the releng repo 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 ;; -v|--verbose) verbose=1 ;; -k|--keep-tmpdir) keep_tmpdir=1 ;; -t|--test) testing=1 ;; -*) usage "ERROR: You have specified an invalid option: ${a}" exit 1 ;; esac done # Make sure all required values were specified if [ -z "${config_file}" -o ! -e "${config_file}" ]; then usage "ERROR: You must specify a valid config file to use" exit 1 fi # Probe the default gitdir from this script name. GITDIR=$(dirname "$(dirname "$(realpath "$0")")") source ${config_file} TMPDIR=$(mktemp -d --tmpdir="${TMP_PATH:-/tmp}" catalyst-auto.XXXXXX) DATESTAMP=$(date +%Y%m%d) if [ ${verbose} = 1 ]; then echo "TMPDIR = ${TMPDIR}" echo "DATESTAMP = ${DATESTAMP}" fi if ! mkdir -p "${TMPDIR}"/{specs,kconfig,log}; then echo "Couldn't create tempdirs!" exit 1 fi 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