#!/usr/bin/sudo /bin/sh USER="sparky" RPMS_FROM="$HOME/rpm/cleanRPMS.repo" DEST="th" SRC="-n th -n th-ready" SUFFIX="" CACHEDIR="$PWD/poldekcache" IGNORE="" [ -r .cleanbuildrc ] && . .cleanbuildrc export LC_ALL=C unset LANGUAGE unset LANG usage() { [ $# -gt 0 ] && echo "$*" echo "Usage:" echo " ./cleanbuild [cleanbuild options] specname [builder options]" echo " ./build [cleanbuild options] specname [builder options]" echo " ./clean [cleanbuild options]" echo " ./create [cleanbuild options]" echo " ./install [cleanbuild options] packages" echo "" echo "cleanbuild options:" echo " -32, -64, -th-i486 - select architecture" echo " -a, -b, -c, -d - select chroot directory" exit 1 } FETCH=false CLEAN=false CREATE=false BUILD=false INSTALL=false CLEANAFTER=false case "$0" in *clean) CLEAN=exit_after ;; *cleanbuild) FETCH=true CLEAN=true CREATE=true BUILD=true ;; *build) CREATE=true BUILD=true ;; *create) CLEAN=true CREATE=exit_after ;; *install) CREATE=true INSTALL=exit_after ;; *) usage ;; esac while [ $# -gt 0 ]; do OPT="${1}" case "$OPT" in -32) OPT="-th-i686" ;; -64) OPT="-th-x86_64" ;; -th-32) OPT="-th-i686" ;; -th-64) OPT="-th-x86_64" ;; -ac) OPT="-ac-amd64" ;; -ac-32) OPT="-ac-i586" ;; -ac-64) OPT="-ac-amd64" ;; esac V="${OPT#-}" case "$OPT" in -th-i[46]86 | -th-x86_64) DEST="$V" SRC="-n $V -n $V-ready -n th-noarch -n th-noarch-ready" ;; -ac-amd64 | -ac-i[356]86 | -ac-athlon) DEST="$V" SRC="-n $V" ;; --cleanafter | -ca) CLEANAFTER=true ;; -[a-z]) SUFFIX="$OPT" ;; -~*) SUFFIX="$V" ;; *) break ;; esac shift done if $BUILD; then [ $# -ne 0 ] || usage build_pkg="${1}" shift builder_options="$*" fi CHNAME="chroot-$DEST$SUFFIX" CHDIR="$PWD/$CHNAME" CHHOME="/home/users/$USER" warn() { echo -n -e "\033[31;1m" >&2 echo -n "$*" >&2 echo -e "\033[0m" >&2 } die() { code=$1 shift warn "$*" exit $code } info() { echo -n -e "\033[32m" echo -n "$*" echo -e "\033[0m" } title() { [ -t 1 ] || return 0 local msg="$CHNAME: $build_pkg: $*" case "$TERM" in cygwin|xterm*) echo -ne "\033]1;$msg\007\033]2;$msg\007" >&2 ;; screen*) echo -ne "\033]0;$msg\007" >&2 ;; esac return 0 } exit_after() { return 0; } check_running() { [ -r "$CHDIR/.pid" ] || return PID=$(< "$CHDIR/.pid") if [ -d /proc/$PID ]; then die 10 "Another process ($PID) already running in $CHNAME" fi } for D in installed buildlogs $CACHEDIR; do if [ ! -d "$D" ]; then info "mkdir $D" su $USER -c "mkdir -p $D" || die 13 "Cannot create work directories" fi done poldek_options="-O keep_downloads=yes -O suggests=no -O ignore=vserver-packages -O unique_package_names=yes -O particle_install=no" ignore() { IGNORE="$IGNORE $*"; } ignore \ vserver-packages \ upstart\* \ xorg-driver-video-fglrx\* xorg-driver-video-nvidia\* xorg-xserver-xgl-libGL \ xorg-data-xbitmaps \ compat-gcc\* \ libpng1\* \ anacron fcron hc-cron \ masqmail msmtp-sendmail omta postfix sendmail ssmtp nail-mail nullmailer \ ghostscript-esp \ \*-multilib-\* \ stfl-python \ perl-PathTools perl-MIME-Base64 \ gnome-speech-driver-festival gnome-speech-driver-speech-dispatcher \ phonon-backend-xine \ xemacs-extras \ freetype1-devel \ kde-icons-actions kipi-plugins \ gnome-menus \ java-sun-jre rebuilddb() { rpm --root=$CHDIR --rebuilddb } poldek() { rebuilddb /usr/bin/poldek $SRC -s "$RPMS_FROM" -r "$CHDIR" "--cachedir=$CACHEDIR" $poldek_options "$@" } build_umount() { for DIR in $CHHOME/rpm $CHHOME dev proc sys; do [ -d $CHDIR/$DIR ] && umount $CHDIR/$DIR done } build_remove_root() { umount $CHDIR rmdir $CHDIR } clean() { info "Cleaning $CHNAME" build_umount build_remove_root title "clean" } build_prepare_root() { set -e mkdir $CHDIR mount -t tmpfs -o size=8G /dev/null $CHDIR echo $$ > $CHDIR/.pid rpm --root=$CHDIR --initdb poldek --up || : poldek --noask -u FHS poldek --noask -u libstdc++ poldek --noask -u rpm-build poldek --upgrade-dist for DIR in dev proc sys; do mount -o bind /$DIR $CHDIR/$DIR done chroot $CHDIR useradd -m $USER cp -a $CHDIR/$CHHOME/{tmp,rpm} cp -a $CHDIR/$CHHOME/tmp $CHDIR/BUILD cp -a $CHDIR/$CHHOME/{.bashrc,.rpmmacros} cat <<-'EOM' > $CHDIR/$CHHOME/.rpmmacros %_builddir /BUILD %buildroot %{_builddir}/%{name}-%{version}-root-%(id -u -n) %_rpmdir %{_topdir}/cleanRPMS %distribution CleanPLD %_binary_payload w1.gzdio EOM cat <<-'EORC' > $CHDIR/$CHHOME/.builderrc TITLECHANGE=no EORC set +e } build_mount_home() { mount -o bind $HOME/rpm $CHDIR/$CHHOME/rpm } print_installed() { echo=$1 if [ -r installed/$build_pkg ]; then $echo "$(cat installed/$build_pkg | awk '{print $1}' | sort -u \ | awk '{br=br ", " $1} END{gsub(/^, /, "- BR: ", br ); print br}')" cat installed/$build_pkg fi } addlist() { LIST="$1" print_installed info echo "*** $build_pkg $(date --rfc-3339=seconds) ***" >> $LIST print_installed echo >> $LIST } builddie() { LIST="$1"; shift CODE="$1"; shift MSG="$*" rm -f $CHDIR/.pid $CLEANAFTER && clean title "failed !" addlist "ERROR_$LIST" die $CODE "$MSG" } LAST_INSTALL="" poldek_install() { I="$1"; # Nothing to install [ -n "$I" ] || return 1 # Installing same packets second time [ "$LAST_INSTALL" != "$I" ] || return 1 LAST_INSTALL="$I" info "Installing" $I poldek -O "ignore=$IGNORE" -u $I | tee $$.poldek_install ret= if grep -q "Preparing... ##################################################" $$.poldek_install \ && ! grep -q "file .* from install of .* conflicts with file from package" $$.poldek_install then info "Poldek:" $I "installed" ret=0 elif grep -q "Nothing to do" $$.poldek_install; then warn "Poldek:" $I "installed already" ret=1 fi rm $$.poldek_install [ -n "$ret" ] && return $ret # try harder poldek -u $I && return 0 poldek -u $I && return 0 warn "Poldek:" "Could not install" $I return 1 } maybe_call() { local cond="$1"; shift local func="$1"; shift [ $cond == "false" ] && return $func "$@" [ $cond == "exit_after" ] && exit } fetch() { info "Fetching $build_pkg" title "fetch" su $USER -c "$HOME/rpm/packages/builder -g $build_pkg $builder_options" \ || die 11 "Fetch failed" } create() { su $USER -c "poldek -s $RPMS_FROM --mkidx" if [ ! -d $CHDIR ]; then info "Preparing $CHNAME" build_prepare_root build_mount_home fi } maybe_call $FETCH fetch check_running maybe_call $CLEAN clean maybe_call $CREATE create echo $$ > $CHDIR/.pid maybe_call $INSTALL poldek_install "$*" $BUILD || exit if [ -p /tmp/fixfreq ]; then echo $$ > /tmp/fixfreq fi while true; do info "Building $build_pkg in $CHNAME" rebuilddb buildlog="buildlogs/$build_pkg" if [ -r $buildlog ]; then i=1 while [ -r $buildlog.$i ]; do i=$((i+1)) done info "moving $buildlog to $buildlog.$i" mv $buildlog $buildlog.$i fi title "building" { chroot $CHDIR su $USER -c "$CHHOME/rpm/packages/builder -nn -bb $build_pkg $builder_options" 2>&1; echo $? > ecode; } | tee $buildlog ECODE=$(< ecode) rm -f ecode if grep -q "error: Failed build dependencies:" $buildlog; then SEARCH=$(cat $buildlog | awk '/^Error:/ { p = 0 }; { if ( p ) { f="p"; if ( $1 ~ /^\// ) f="f"; printf "search -%c %s; ", f, $1; } }; /error: Failed build dependencies:/ { p = 1 }') INSTALL=$(poldek -O "ignore=$IGNORE" --shcmd="$SEARCH" | awk '{ if ( p ) { print; p = 0; } } / package\(s\) found:$/ { p = 1 }' | sed 's/^\(.*\)-.*-.*$/\1/' | sort -u) if poldek_install "$INSTALL"; then info "Deps installed" continue else addlist ERROR_BRINSTALL die 4 "Cannot install BRs" fi fi ./findbr $CHDIR/BUILD $buildlog > $$.installed installed_something=false while read pkg msg; do if poldek_install $pkg; then info "findbr:" $pkg "installed" echo "$pkg $msg" >> installed/$build_pkg ./addbr $build_pkg "$pkg" "$msg" installed_something=true else warn "findbr:" $pkg "not installed" fi done < $$.installed rm -f $$.installed $installed_something && continue if [ $ECODE -eq 0 ]; then $CLEANAFTER && clean addlist BUILT_OK info "$build_pkg built OK !" title "OK !" exit 0 else builddie UNKNOWN 1 "Got error but dunno what to do !" fi done # vim: ts=4 sw=4 filetype=sh