#!/bin/bash # I Wish I Was A Ninja # Script to make catalyst stage building a breeze. # Running catalyst by hand sucks large donkey balls, # so lets not do it, mmmkay. # Grab settings from external source ... source /etc/catalyst/build-stages.conf >& /dev/null source /etc/catalyst2/build-stages.conf >& /dev/null source ~/.build-stages.conf >& /dev/null if [[ ! -z $1 ]] ; then if [[ ! -e $1 ]] ; then source /etc/catalyst/"$1" >& /dev/null source /etc/catalyst2/"$1" >& /dev/null source ~/"$1" >& /dev/null else source "$1" >& /dev/null fi fi ############################ #### CATALYST VARIABLES #### #ver=uclibc-20040909 #arch=x86 #profile=uclibc/x86 #rel_type=embedded ######################### #### STAGE VARIABLES #### #export CHOST="i386-gentoo-linux-uclibc" #export CFLAGS="-Os -pipe" #export CXXFLAGS="${CFLAGS}" #export LDFLAGS="-Wl,-z,relro" ##################### ### SCRIPT EXTRAS ### # which version of catalyst you want to use. we will try # to use the latest version available by default. you can # set this to '1', '2', or 'auto' #catalyst_ver="auto" # clean out the temp dir between catalyst runs useful for # systems which are low on space #clean=0 # name of the seed tarball (no .tar.bz2) ... # put it into the builds dir of catalyst: # (catalyst uses /var/tmp/catalyst/builds/ by default) #seed=seed # e-mail setup ... you need net-mail/smtptools for this ... # for extra options (like relay mail server) see the # smtpblast(8) manpage. #send_emails=0 #mail_from="vapier@gentoo.org" #mail_to="vapier@gentoo.org" #mail_opts="" ################# ### PACKAGES #### # You should emerge the following: # - sys-process/time # - net-mail/smtptools # - app-crypt/shash # Or just run ./build-stages --install-util ################# #### TODO :) #### #- gpg sign digests ##################################################### #### SHOULDNT NEED TO MODIFY ANYTHING BELOW HERE #### # HELP ME if [[ $1 == "-h" || $1 == "--help" ]] ; then cat <<-EOF About: Hide all the craptastic catalyst details and build a snapshot followed by stages 1, 2, and 3. Also generate some useful metadata. Usage: build-stages [config file] Config order: /etc/catalyst/build-stages.conf /etc/catalyst2/build-stages.conf ~/.build-stages.conf [config file on command line] Options: -h, --help Help screen -i, --install-util Install helper utils -u, --update Attempt to self update EOF exit 0 fi # Upgrade myself if [[ $1 == "-u" || $1 == "--update" ]] ; then set -x wget -q http://dev.gentoo.org/~vapier/build-stages -O update || exit 1 mv update $0 chmod a+rx $0 exit 0 fi # Install utility packages if [[ $1 == "-i" || $1 == "--install-util" || $1 == "--install-utils" ]] ; then UTIL_PKGS="dev-util/catalyst sys-process/time net-mail/smtptools app-crypt/shash" emerge -p --columns ${UTIL_PKGS} echo -ne "\n[ hit any key to continue ]" read exec emerge ${UTIL_PKGS} fi if [[ $1 == -* ]] ; then echo "Unknown option: $1" exit 1 fi # Catalyst SLOT fun case ${catalyst_ver:-auto} in 1) C=catalyst;; 2) C=catalyst2;; auto) type -p catalyst > /dev/null && C=catalyst type -p catalyst2 > /dev/null && C=catalyst2 [[ -z ${C} ]] && echo "Could not locate catalyst in PATH" && exit 1 ;; *) echo "Invalid catalyst_ver setting '${catalyst_ver}'" ; exit 1 ;; esac [[ ${C} == "catalyst" ]] \ && catalyst_ver="1" \ || catalyst_ver="2" # Setup sane defaults where we can ver=${ver:-$(date +%Y%m%d)} rel_type=${rel_type:-default} clean=${clean:-0} seed=${seed:-seed} send_emails=${send_emails:-0} # useful display funcs [[ -e /sbin/functions.sh ]] && source /sbin/functions.sh >& /dev/null type einfo >& /dev/null || einfo() { echo "* $@"; } type ewarn >& /dev/null || ewarn() { echo "! $@"; } type eerror >& /dev/null || eerror() { echo "!!! $@"; } # make sure the variables we can't default to are set if [[ -z ${arch} ]] ; then eerror "You did not set \$arch in any config file" exit 1 fi if [[ -z ${profile} ]] ; then eerror "You did not set \$profile in any config file" exit 1 fi # make sure we have all additional cool apps installed if [[ ! -x "/usr/bin/shash" ]] ; then ewarn "You do not have 'app-crypt/shash' installed." ewarn "Only MD5/SHA1 digests will be generated automatically." ewarn "Extra SHA/RIPEMD digests will not be computed. :(" echo fi if [[ ! -x "/usr/bin/time" ]] ; then eerror "Please 'emerge sys-process/time'" exit 1 fi if [[ ${send_emails} != "0" ]] && [[ ! -x /usr/bin/smtpblast ]] ; then eerror "Please 'emerge net-mail/smtptools'" exit 1 fi # dump summary info before we start running einfo "I, your stager monkey, will now build-stages for:" einfo " ver: ${ver}" einfo " arch: ${arch}" einfo " profile: ${profile}" einfo " rel_type: ${rel_type}" einfo " seed: ${seed}.tar.bz2" einfo "Options:" [[ ${clean} != "0" ]] \ && einfo " clean: delete tmp" \ || einfo " clean: retain tmp" [[ ${send_emails} != "0" ]] \ && einfo " send_emails: Yes please !" \ || einfo " send_emails: No, shut it." # setup all the path variables cdir=$(source /etc/${C}/${C}.conf ; echo ${storedir:-/var/tmp/${C}}) tmpdir=${cdir}/tmp snapdir=${cdir}/snapshots builddir=${cdir}/builds stagedir=${builddir}/${rel_type} unset PORTDIR_OVERLAY mkdir -p "${stagedir}" cd /etc/${C} sendemail() { ! type -p smtpblast >& /dev/null && return 0 [[ ${send_emails} == "0" ]] && return 0 subject=$1 shift smtpblast -g wh0rd.org -f "${mail_from}" -t "${mail_to}" << EOF To: ${mail_to} From: Catalyst Stager <${mail_from}> Subject: Stager on ${HOSTNAME} reports: ${subject} Date: $(date +"%d %h %Y %H:%M:%S") $@ EOF } die() { local subject=$1 local log="" [[ -n $3 ]] && log=$(tail -n 100 "$3") sendemail "Failed to build $subject" "$2"$'\n\n\n'"$log" exit 2 } docatalyst() { echo if [[ ${clean} != "0" ]] ; then if [[ -d ${tmpdir} ]] ; then einfo "Cleaning temp dir" rm -rf "${tmpdir}" fi fi einfo "Building $3" local basetarget="${1}/${2}.tar.bz2" if [[ -f ${basetarget} ]] ; then einfo "$3 is cached at ${1}/${2}.tar.bz2 :)" return fi if [[ ${3} == "snapshot" ]] ; then ${C} -C \ version_stamp="${ver}" \ target="${3}" \ || die "snapshot" return fi if [[ ! -f ${builddir}/${4}.tar.bz2 ]] ; then eerror "$3 lacks the source tarball '${4}.tar.bz2'" eerror "Could not find it in ${builddir}" die "$3" "No source tarball '${4}.tar.bz2'" fi # Generate spec files for catalyst since releng retains .spec # files for all their releases cat <<-EOF > "${basetarget}.spec" subarch: ${arch} target: ${3} version_stamp: ${ver} rel_type: ${rel_type} profile: ${profile} snapshot: ${ver} source_subpath: ${4} ${CHOST+chost: ${CHOST}} ${CFLAGS+cflags: ${CFLAGS}} ${CXXFLAGS+cxxflags: ${CXXFLAGS}} ${LDFLAGS+ldflags: ${LDFLAGS}} EOF # Now run catalyst and gather stats about the build local startdate=$(date --utc) /usr/bin/time -v \ --output="${basetarget}.time" \ ${C} -f "${basetarget}.spec" 2>&1 | tee "${basetarget}.log" local _pipestatus=${PIPESTATUS[*]} [[ "${_pipestatus// /}" -eq 0 ]] || die "$3" "Catalyst aborted during run" "${basetarget}.log" local enddate=$(date --utc) # Write out the stats cat <<-EOF > "${basetarget}.stats" $3 completed by 'build-stages' uNF Begin: ${startdate} End: ${enddate} Stats: $(<"${basetarget}.time") EOF rm -f "${basetarget}.time" # Generate a bunch of digests dirname=$(dirname "${basetarget}") basename=$(basename "${basetarget}") cd "${dirname}" if [[ ${catalyst_ver} == "1" ]] ; then ( echo MD5 $(md5sum "${basename}") echo SHA1 $(sha1sum "${basename}") if [[ -x /usr/bin/shash ]] ; then for algo in SHA{224,256,384,512} RIPEMD{128,160,256,320} ; do echo ${algo} $(shash -a ${algo} "${basename}" | tail -n 1) done fi ) > "${basetarget}.digests" fi # Generate file listings of the tarball tar tf "${basetarget}" > "${basetarget}.CONTENTS" sendemail "Finished building $3" "$(<"${basetarget}.stats")" } stage_name="${arch}-${ver}" docatalyst "${snapdir}" "portage-${ver}" snapshot docatalyst "${stagedir}" "stage1-${stage_name}" stage1 "${seed}" docatalyst "${stagedir}" "stage2-${stage_name}" stage2 "${rel_type}/stage1-${stage_name}" docatalyst "${stagedir}" "stage3-${stage_name}" stage3 "${rel_type}/stage2-${stage_name}"