1408 lines
52 KiB
Bash
Executable File
1408 lines
52 KiB
Bash
Executable File
#!/bin/bash
|
|
#
|
|
# Autodist -- batch build tool for RPM based distributions
|
|
# Copyright (C) 2006-2016 by Silvan Calarco <silvan.calarco@mambasoft.it>
|
|
#
|
|
# Released under the terms of the GNU GPL release 3 license
|
|
#
|
|
VERSION=1.4.0
|
|
me=(${0##*/} $VERSION "Tue Jan 26 2016")
|
|
exec 3>`readlink /proc/self/fd/0`
|
|
|
|
function usage() {
|
|
echo "\
|
|
${me[0]} ${me[1]}
|
|
"$"Copyright (C) 2006-2016 Silvan Calarco <silvan.calarco@mambasoft.it>""
|
|
"$"Released under the terms of the GNU GPL v3 license"
|
|
echo "
|
|
"$"Batch build tool for bulding a whole distribution and much more.""
|
|
|
|
"$"Usage"":
|
|
$me [operations ...] [options ...] [job ...] [-- autospec_args] [--- script_args]
|
|
|
|
"$"Operations"":
|
|
-a,--autobuild "$"Start batch build operations (implies -p -u -b -s --severity 1)""
|
|
-p,--prepare "$"Prepare packages (download and prepare for update)""
|
|
-u,--update "$"Update packages""
|
|
-b,--build "$"Build packages""
|
|
-i,--install "$"Install packages on local system""
|
|
-s,--send "$"Send packages to repository""
|
|
--list-jobs "$"List configured jobs""
|
|
--list-pkgs job "$"List packages for specified job""
|
|
|
|
"$"Options"":
|
|
-c,--cleanlogs "$"Clean all logs before starting""
|
|
-d,--debug "$"Enable print of debugging information""
|
|
-h,--help "$"Print this help, then exit""
|
|
-t,--test "$"Just simulate the execution of programs""
|
|
-q,--quiet "$"Be quiet (don't display tail of error logs)""
|
|
-r,--rebuild "$"Rebuild packages""
|
|
-v,--verbose "$"Be verbose""
|
|
--force "$"Pass force parameter to autospec""
|
|
--repository "$"Pass given repository as base for operations""
|
|
--repository-strict "$"Only prepare packages from base repository specified with --repository""
|
|
--server num "$"Pass given server number to autospec for send operation""
|
|
--severity num "$"Error handling level:
|
|
0: don't stop
|
|
1: skip current job on error (default)
|
|
2: abort on error""
|
|
--arch "$"Build packages for specified target architecture""
|
|
--user user "$"Pass calling user name for Webbuild social messages""
|
|
--rebuild-srpms "$"Rebuild SRPMs when sending""
|
|
|
|
job "$"Job specification in the form pkg#version, job#version, job/pkg#version, examples:
|
|
glibc#2.11.1
|
|
kernel-extra
|
|
kernel-packages/lirc""
|
|
autospec_args "$"Send specified arguments to autospec""
|
|
script_args "$"Send specified arguments to update-specfile script""
|
|
"
|
|
|
|
}
|
|
|
|
function fetch_repository_file() {
|
|
local REPOFILE=$1
|
|
if [ -r ${LOCAL_REPS_BASE_DIR}/$REPOFILE ]; then
|
|
echo ${LOCAL_REPS_BASE_DIR}/$REPOFILE
|
|
return 0
|
|
else
|
|
if [ ! -r $USERCONFDIR/$REPOFILE -o "`find $USERCONFDIR/$REPOFILE -mmin +60 2>/dev/null`" ]; then
|
|
mkdir -p `dirname $USERCONFDIR/$REPOFILE`
|
|
curl -f -L -s $REPS_BASE_URL/$REPOFILE -o $USERCONFDIR/$REPOFILE || return 1
|
|
fi
|
|
echo $USERCONFDIR/$REPOFILE
|
|
return 0
|
|
fi
|
|
}
|
|
|
|
[ $# -gt 0 ] || { usage ; exit 1; }
|
|
|
|
DATE_NOW=`LANG=C date +%s`
|
|
BUILDTIME=`date -Iseconds`
|
|
SYSCONFDIR=/etc/autodist
|
|
LOCALSTATEDIR=/var/autodist
|
|
[ "$USER" = "autodist" ] && USERCONFDIR=$LOCALSTATEDIR || USERCONFDIR=$HOME/.autodist
|
|
LOGBASEDIR=$USERCONFDIR/log
|
|
RPMTMPPATH=/var/tmp/autodist
|
|
SCRIPTDIR=$SYSCONFDIR/scripts
|
|
|
|
DISTDB=$SYSCONFDIR/distdb
|
|
DISTDBDIR=$SYSCONFDIR/distdb.d/
|
|
BLACKLIST=$SYSCONFDIR/blacklist
|
|
LEGACYLIST=$SYSCONFDIR/legacy
|
|
BUILDARCH=`rpm --eval %{_build_cpu}`
|
|
TARGETARCH=$BUILDARCH
|
|
CONFIGFILE=$SYSCONFDIR/config
|
|
SCRIPT_UPDATE_SPECFILE=$SCRIPTDIR/update-specfile
|
|
SCRIPT_UPDATE_SPECFILE_CUSTOM=$SCRIPTDIR/update-specfile-custom
|
|
AUTOSPEC_CMD="/usr/bin/autospec"
|
|
PIDFILE="/run/autodist/autodist.pid"
|
|
|
|
# Configuration defaults normally overriden in configuration file
|
|
AUTOBUILD_MAXNUM=50
|
|
AUTOBUILD_DATEFROM=20070101
|
|
AUTODIST_REPOSITORY=
|
|
SEND_SERVER=
|
|
|
|
[ -r $CONFIGFILE ] && . $CONFIGFILE
|
|
|
|
# init environment especially to have a full PATH when executed by crond with
|
|
# system init PATH
|
|
. /etc/profile
|
|
. /etc/profile.d/*.sh
|
|
export PATH
|
|
|
|
# error handling severity: 0=don't stop; 1=skip; 2=stop
|
|
SEVERITY=1
|
|
|
|
for ((i=1; i<=$#; i++)); do
|
|
case ${!i} in
|
|
-a|--autobuild) do_autobuild=1;
|
|
do_prepare=1;
|
|
do_update=1;
|
|
do_build=1;
|
|
do_send=1;
|
|
SEVERITY=1
|
|
;;
|
|
-c|--cleanlogs) do_cleanlogs=1 ;;
|
|
-h|--help) usage
|
|
exit 0
|
|
;;
|
|
-p|--prepare) do_prepare=1 ;;
|
|
-u|--update) do_update=1 ;;
|
|
-r|--rebuild) rebuild_packages=1 ;;
|
|
-b|--build) do_build=1 ;;
|
|
-d|--debug) debug=1 ;;
|
|
-i|--install) do_install=1 ;;
|
|
-s|--send) do_send=1 ;;
|
|
-t|--test) simulate=1 ;;
|
|
-q|--quiet) quiet=1 ;;
|
|
-v|--verbose) verbose=1 ;;
|
|
--list-jobs) do_listjobs=1 ;;
|
|
--list-pkgs) do_listpkgs=1
|
|
let i+=1
|
|
[ "${!i}" ] || {
|
|
echo "Error: job parameter not given, aborting."
|
|
exit 1
|
|
}
|
|
LISTPKGSJOB="${!i}"
|
|
;;
|
|
--force) SEND_FORCE="--force"
|
|
SEND_FORCE_BUILD="--force-build"
|
|
;;
|
|
--server) let i+=1
|
|
[ "${!i}" ] || {
|
|
echo "Error: --server parameter not given, aborting."
|
|
exit 1
|
|
}
|
|
SEND_SERVER="${!i}"
|
|
;;
|
|
--repository) let i+=1
|
|
[ "${!i}" ] || {
|
|
echo "Error: --repository parameter not given, aborting."
|
|
exit 1
|
|
}
|
|
AUTODIST_REPOSITORY="${!i}"
|
|
;;
|
|
--repository-strict)
|
|
REPOSITORY_STRICT=1
|
|
;;
|
|
--severity) let i+=1
|
|
[ "${!i}" ] || {
|
|
echo "Error: --severity parameter not given, aborting."
|
|
exit 1
|
|
}
|
|
SEVERITY=${!i}
|
|
;;
|
|
--arch) let i+=1
|
|
[ "${!i}" ] || {
|
|
echo "Error: --arch parameter not given, aborting."
|
|
exit 1
|
|
}
|
|
TARGETARCH=${!i}
|
|
;;
|
|
--user) let i+=1
|
|
[ "${!i}" ] || {
|
|
echo "Error: --user parameter not given, aborting."
|
|
exit 1
|
|
}
|
|
WEBBUILD_USER_CMDLINE="${!i}"
|
|
;;
|
|
--rebuild-srpms)
|
|
REBUILD_SRPMS=1
|
|
;;
|
|
-*) if [ "${!i}" = "--" ]; then
|
|
AUTOSPEC_ARGS_MODE=1
|
|
SCRIPT_ARGS_MODE=
|
|
elif [ "${!i}" = "---" ]; then
|
|
SCRIPT_ARGS_MODE=1
|
|
AUTOSPEC_ARGS_MODE=
|
|
elif [ "$AUTOSPEC_ARGS_MODE" ]; then
|
|
AUTOSPEC_ARGS="$AUTOSPEC_ARGS ${!i}"
|
|
elif [ "$SCRIPT_ARGS_MODE" ]; then
|
|
SCRIPT_ARGS="$SCRIPT_ARGS ${!i}"
|
|
else
|
|
echo "ERROR: invalid option \`${!i}'; aborting."
|
|
exit 1
|
|
fi
|
|
;;
|
|
*) if [ "$AUTOSPEC_ARGS_MODE" ]; then
|
|
if [ "${!i/ }" != "${!i}" ]; then
|
|
# pass multiple word arguments inside quotation marks
|
|
AUTOSPEC_ARGS="$AUTOSPEC_ARGS \"${!i}\""
|
|
else
|
|
AUTOSPEC_ARGS="$AUTOSPEC_ARGS ${!i}"
|
|
fi
|
|
elif [ "$SCRIPT_ARGS_MODE" ]; then
|
|
if [ "${!i/ }" != "${!i}" ]; then
|
|
# pass multiple word arguments inside quotation marks
|
|
SCRIPT_ARGS="$SCRIPT_ARGS \"${!i}\""
|
|
else
|
|
SCRIPT_ARGS="$SCRIPT_ARGS ${!i}"
|
|
fi
|
|
else
|
|
JOBIDX=${#JOBNAME[@]}
|
|
JOBNAME[$JOBIDX]="${!i/\#*}"
|
|
[ "${!i/*\#}" != "${!i}" ] && JOBVER[$JOBIDX]="+${!i/*\#}"
|
|
fi
|
|
;;
|
|
esac
|
|
done
|
|
|
|
if [ "$do_autobuild" ]; then
|
|
if [ -e $PIDFILE ]; then
|
|
PIDCHECK=`cat $PIDFILE`
|
|
if [ "$PIDCHECK" -a -e /proc/$PIDCHECK -a ! "$DISABLE_PID_CHECK" ]; then
|
|
echo "Error: autodist -a already running with PID=$PIDCHECK.Aborting."
|
|
exit 0
|
|
fi
|
|
fi
|
|
fi
|
|
|
|
[ "$AUTODIST_REPOSITORY" ] || AUTODIST_REPOSITORY=devel-autodist
|
|
[ "$SEND_SERVER" ] || SEND_SERVER=$AUTODIST_REPOSITORY
|
|
|
|
SEND_SERVER_CMD="--server $SEND_SERVER"
|
|
|
|
# perform arch names conversions
|
|
case $BUILDARCH in
|
|
i386|i486|i686) BUILDARCH=i586 ;;
|
|
esac
|
|
|
|
case $TARGETARCH in
|
|
i386|i486|i686) TARGETARCH=i586 ;;
|
|
esac
|
|
|
|
|
|
# for webbuild message
|
|
function cgi_encodevar() {
|
|
local string="${1}"
|
|
local strlen=${#string}
|
|
local encoded=""
|
|
|
|
for (( pos=0 ; pos<strlen ; pos++ )); do
|
|
c=${string:$pos:1}
|
|
case "$c" in
|
|
[-_.~a-zA-Z0-9] ) o="${c}" ;;
|
|
* ) printf -v o '%%%02x' "'$c"
|
|
esac
|
|
encoded+="${o}"
|
|
done
|
|
echo "${encoded}" # You can either set a return variable (FASTER)
|
|
# REPLY="${encoded}" #+or echo the result (EASIER)... or both... :p
|
|
}
|
|
|
|
function tempfile() {
|
|
local tmpfile
|
|
tmpfile=`mktemp -q -t $me.XXXXXXXX` || {
|
|
echo "ERROR: cannot create temporary files." >&2
|
|
exit 1
|
|
}
|
|
trap "rm -f $tmpfile" 0 1 2 5 15
|
|
|
|
> $tmpfile || {
|
|
echo "ERROR: cannot write to temporary files." >&2
|
|
exit 1
|
|
}
|
|
echo $tmpfile
|
|
}
|
|
|
|
function version_compare()
|
|
{
|
|
local A B
|
|
A=$1
|
|
B=$2
|
|
|
|
if [ ${A/[a-zA-Z_]*} -gt ${B/[a-zA-Z_]*} ]; then
|
|
return 1
|
|
elif [ ${A/[a-zA-Z_]*} -lt ${B/[a-zA-Z_]*} ]; then
|
|
return 2
|
|
else
|
|
if [[ "$A" > "$B" ]]; then
|
|
return 1
|
|
elif [[ "$A" < "$B" ]]; then
|
|
return 2
|
|
fi
|
|
fi
|
|
return 0
|
|
|
|
}
|
|
|
|
function version_find_bigger()
|
|
{
|
|
local VER1 VER2 FPOS CUTVER1 CUTVER2
|
|
|
|
VER1=$1
|
|
VER2=$2
|
|
FPOS=1
|
|
while true; do
|
|
CUTVER1=`echo $VER1. | cut -d. -f $FPOS`
|
|
CUTVER2=`echo $VER2. | cut -d. -f $FPOS`
|
|
if [ "$CUTVER1" -a ! "$CUTVER2" ]; then
|
|
return 1
|
|
elif [ "$CUTVER2" -a ! "$CUTVER1" ]; then
|
|
return 2
|
|
elif [ ! "$CUTVER1" -a "$CUTVER2" ]; then
|
|
return 0
|
|
else
|
|
version_compare $CUTVER1 $CUTVER2
|
|
case $? in
|
|
1) return 1 ;;
|
|
2) return 2 ;;
|
|
esac
|
|
fi
|
|
FPOS=`expr $FPOS + 1`
|
|
done
|
|
return 0
|
|
}
|
|
|
|
function tail_file() {
|
|
local elapsedtime elapsedstring elapsedcount phase lastprinttime newtime begintime lines c difftimestep
|
|
c=0
|
|
lines=0
|
|
begintime=`LANG=C date +%s`
|
|
lastlinetime=$begintime
|
|
lastprinttime=0
|
|
|
|
if [ "$do_autobuild" ]; then
|
|
difftimestep=1800
|
|
else
|
|
difftimestep=1
|
|
fi
|
|
while read line; do
|
|
echo "$line" >> $1
|
|
let lines+=1
|
|
newtime=`LANG=C date +%s`
|
|
let difftime=$newtime-$lastprinttime
|
|
|
|
case $verbose in
|
|
1) echo "$line"
|
|
;;
|
|
*) if [ $difftime -gt $difftimestep ]; then
|
|
let c+=1
|
|
lastprinttime=$newtime
|
|
let elapsedtime=$newtime-$begintime
|
|
[ $elapsedtime -gt 0 ] && let speed=$lines/$elapsedtime
|
|
|
|
case $c in
|
|
1) phase="|" ;;
|
|
2) phase="/" ;;
|
|
3) phase="-" ;;
|
|
4) phase="\\"
|
|
let c=0 ;;
|
|
esac
|
|
elapsedstring="`expr $elapsedtime % 60`s"
|
|
elapsedcount=`expr $elapsedtime / 60`
|
|
[ $elapsedcount -gt 0 ] && elapsedstring="`expr $elapsedcount % 60`m $elapsedstring"
|
|
elapsedcount=`expr $elapsedcount / 60`
|
|
[ $elapsedcount -gt 0 ] && elapsedstring="${elapsedcount}h $elapsedstring"
|
|
[ ! "$do_autobuild" ] && echo -n -e "\r"
|
|
echo -n "$2 $phase ($lines lines, $elapsedstring, $speed l/s)"
|
|
fi
|
|
;;
|
|
esac
|
|
done
|
|
}
|
|
|
|
get_job_vector() {
|
|
# note: if JOB_NAME contains a "-" or "." translate it to "_"
|
|
local JTARGET=${1/\/*}
|
|
local JPKG=
|
|
[ "$JTARGET" != "$1" ] && JPKG="${1/*\/}"
|
|
local JNAME=`echo $JTARGET | tr - _ | tr . _ | tr @ _`
|
|
if [[ ${JNAME:0:1} =~ [0-9] ]]; then
|
|
# prepend a underscore to job names starting with a number (e.g. 54321)
|
|
JNAME="_$JNAME"
|
|
fi
|
|
|
|
# resolve JOB_NAME from distdb
|
|
local jobtmpfile=`tempfile`
|
|
# hack to get an array variable named as $j assigned to the JOB array
|
|
echo "echo \${$JNAME[*]}" > $jobtmpfile
|
|
|
|
JOB=(`. $jobtmpfile`)
|
|
rm -f $jobtmpfile
|
|
|
|
if [ ${#JOB[*]} -eq 0 ]; then
|
|
# create a default job with given JOB_NAME
|
|
JOB=($JTARGET "" "")
|
|
elif [ ${#JOB[*]} -eq 1 ]; then
|
|
# no variables defined, add an empty job
|
|
JOB=(${JOB[*]} "" "")
|
|
elif [ "${JPKG}" ]; then
|
|
TMPJOB=($JPKG)
|
|
for i in `seq 1 ${#JOB[*]}`; do
|
|
TMPJOB=(${TMPJOB[*]} "${JOB[$i]}")
|
|
done
|
|
JOB=(${TMPJOB[*]})
|
|
fi
|
|
JOB_PKGS=(${JOB[0]//,/ })
|
|
JOB_VARNAMES=(${JOB[1]//,/ })
|
|
}
|
|
|
|
function autobuild_log() {
|
|
local pkg=$1
|
|
local operation=$2
|
|
local result=$3
|
|
local job=$4
|
|
local logfile=$5
|
|
|
|
[ "$pkg" -a "$operation" -a "$result" ] || return
|
|
if [ "$job" -a "$job" != "$pkg" ]; then
|
|
echo "$job/$pkg $operation $result $logfile" >> $LOGBASEDIR/autoupdate-current
|
|
else
|
|
echo "$pkg $operation $result $logfile" >> $LOGBASEDIR/autoupdate-current
|
|
fi
|
|
}
|
|
|
|
function launch_pkgs_loop() {
|
|
# This function iterates the passed operation for each package (column) in job
|
|
#
|
|
# $1: operation (prepare, update, build, send, install)
|
|
# $2: options
|
|
# $3: job variables (e.g. i386,std)
|
|
|
|
local JOB_VALUES JOB_ARGS JOB_IDX DEFINES_STRING i a PKGLINE
|
|
local cross_target_cpu autodist_crossonly operation
|
|
|
|
# evaluate job variables
|
|
JOB_VALUES=(${3//,/ })
|
|
JOB_IDX=$4
|
|
|
|
[ "$debug" = "1" ] && JOB_ARGS="--debug " || JOB_ARGS=""
|
|
[ $JOB_IDX ] || JOB_IDX=0
|
|
operation="$1"
|
|
passed_arguments="$2"
|
|
ret=0
|
|
DEFINES_STRING=""
|
|
|
|
if [ "$TARGETARCH" != "$BUILDARCH" ]; then
|
|
TARGET_PLATFORM=`rpm --target ${TARGETARCH} --eval %{_target_platform}`
|
|
JOB_ARGS="$JOB_ARGS-A \"${TARGETARCH}\" --root /usr/${TARGET_PLATFORM} "
|
|
DEFINES_STRING="--define _host_cpu=\"${TARGETARCH}\",_target_cpu=\"${TARGETARCH}\""
|
|
fi
|
|
|
|
cross_target_cpu=""
|
|
autodist_crossonly=""
|
|
patch_operation=$operation
|
|
continue_on_error=
|
|
|
|
for i in `seq 1 ${#JOB_VALUES[*]}`; do
|
|
[ "${JOB_VALUES[$i-1]}" = "-" ] || \
|
|
case ${JOB_VARNAMES[$i-1]} in
|
|
%build_and_install)
|
|
[ "$operation" = "build" ] && operation=buildinstall
|
|
;;
|
|
%continue_on_error)
|
|
continue_on_error=1
|
|
;;
|
|
%*)
|
|
echo "!! Warning: skipping unknown internal variable: ${JOB_VARNAMES[$i-1]}"
|
|
;;
|
|
autodist_crossonly)
|
|
autodist_crossonly=1
|
|
;;
|
|
cross_target_cpu)
|
|
cross_target_cpu="${JOB_VALUES[$i-1]}"
|
|
# don't specify cross_target_cpu for non-cross-target builds
|
|
if [ "$cross_target_cpu" = "$TARGETARCH" ]; then
|
|
# set cross_target_cpu as don't use
|
|
JOB_VALUES[$i-1]="-"
|
|
else
|
|
[ "$DEFINES_STRING" ] &&
|
|
DEFINES_STRING="${DEFINES_STRING}," ||
|
|
DEFINES_STRING="--define "
|
|
DEFINES_STRING="${DEFINES_STRING}${JOB_VARNAMES[$i-1]}=$cross_target_cpu"
|
|
fi
|
|
;;
|
|
target)
|
|
# specific target build was specified, don't build packages containing explicit different target
|
|
[ "$BUILDARCH" != "$TARGETARCH" -a "${JOB_VALUES[$i-1]}" != "$TARGETARCH" ] && return 0;
|
|
JOB_ARGS="$JOB_ARGS-A \"${JOB_VALUES[$i-1]}\" "
|
|
;;
|
|
*)
|
|
if [ "${JOB_VALUES[$i-1]}" ]; then
|
|
[ "$DEFINES_STRING" ] &&
|
|
DEFINES_STRING="${DEFINES_STRING}," ||
|
|
DEFINES_STRING="--define "
|
|
DEFINES_STRING="${DEFINES_STRING}${JOB_VARNAMES[$i-1]}=${JOB_VALUES[$i-1]}"
|
|
fi
|
|
;;
|
|
esac
|
|
done
|
|
# don't build cross package for the same arch as target arch
|
|
[[ ( "$autodist_crossonly" = "1" ) && ( "$cross_target_cpu" = "$TARGETARCH" ) ]] && return 0;
|
|
|
|
JOB_ARGS="$JOB_ARGS$DEFINES_STRING"
|
|
|
|
[ "$patch_operation" = "buildinstall" ] && patch_operation=build
|
|
[ "$patch_operation" = "autoupdate" -o "$patch_operation" = "rebuild" ] && patch_operation=update
|
|
|
|
# launch loop for each package
|
|
for pkg in ${JOB_PKGS[*]}; do
|
|
|
|
unset LOGFILE_SUFFIX AUTOUPDATE_SCRIPT_ALREADY_RUN
|
|
for a in ${JOB_VALUES[*]}; do
|
|
tr_job=`echo $a | tr / _`
|
|
LOGFILE_SUFFIX=${LOGFILE_SUFFIX}__$tr_job
|
|
done
|
|
LOGFILE_SUFFIX=$LOGFILE_SUFFIX.$TARGETARCH
|
|
[ "$JOB_NAME" = "${pkg}" ] &&
|
|
LOGFILE_PKG_NAME=${pkg}${LOGFILE_SUFFIX} ||
|
|
LOGFILE_PKG_NAME=${JOB_NAME}_${pkg}${LOGFILE_SUFFIX}
|
|
LOGFILE_PKG=${LOGDIR}/${LOGFILE_PKG_NAME}
|
|
|
|
# clean previous logs for this package
|
|
[ -e ${LOGDIR}/ok/${LOGFILE_PKG_NAME}${LOGFILE_SUFFIX} ] &&
|
|
rm -f ${LOGDIR}/ok/${LOGFILE_PKG_NAME}${LOGFILE_SUFFIX}
|
|
[ -e ${LOGDIR}/failed/${LOGFILE_PKG_NAME}${LOGFILE_SUFFIX} ] &&
|
|
rm -f ${LOGDIR}/failed/${LOGFILE_PKG_NAME}-${LOGFILE_SUFFIX}
|
|
|
|
case $operation in
|
|
autoupdate|update|build|rebuild|buildinstall)
|
|
[ -e $spec_dir/$pkg.spec ] || {
|
|
case $SEVERITY in
|
|
0) ;;
|
|
1) echo "!! Error: spec filename must be the same as package name or invalid job name; skipping $pkg package."
|
|
[ "$do_autobuild" ] && autobuild_log $pkg $operation 240 $JOB_NAME $LOGDIR/failed/${LOGFILE_PKG_NAME}
|
|
continue ;;
|
|
*) echo "!! Error: spec filename must be the same as package name or invalid job name; aborting."
|
|
exit 1 ;;
|
|
esac
|
|
}
|
|
|
|
# apply patches
|
|
SPEC_DATE=`stat $spec_dir/$pkg.spec --printf=%y`
|
|
if [ $JOB_IDX -eq 0 -a "$do_autobuild" ]; then
|
|
# preserve specfile modification date
|
|
if [ -e $AUTOUPDATEDIR/spec-patches-$patch_operation/$pkg.spec.patch ]; then
|
|
echo -n "?= "
|
|
patch -p1 $spec_dir/$pkg.spec $AUTOUPDATEDIR/spec-patches-$patch_operation/$pkg.spec.patch || {
|
|
case $SEVERITY in
|
|
0) ;;
|
|
1) echo "%! Error: could not apply patch to specfile; skipping $pkg package."
|
|
[ "$do_autobuild" ] && autobuild_log $pkg $operation 241 $JOB_NAME $LOGDIR/failed/${LOGFILE_PKG_NAME}
|
|
ret=1
|
|
continue ;;
|
|
*) echo "!! Error: could not apply patch to specfile; aborting."
|
|
exit 1 ;;
|
|
esac
|
|
}
|
|
[ "$operation" = "update" -o "$operation" = "autoupdate" ] && continue
|
|
fi
|
|
fi
|
|
if [ -x $SCRIPT_UPDATE_SPECFILE ]; then
|
|
$SCRIPT_UPDATE_SPECFILE $spec_dir/$pkg.spec $SCRIPT_ARGS || {
|
|
case $SEVERITY in
|
|
0) ;;
|
|
1) echo "%! Error: update-specfile script returned $?; skipping $pkg package."
|
|
ret=1
|
|
continue ;;
|
|
*) echo "!! Error: update-specfile script returned $?; aborting."
|
|
exit 1 ;;
|
|
esac
|
|
}
|
|
fi
|
|
if [ -x $SCRIPT_UPDATE_SPECFILE_CUSTOM ]; then
|
|
$SCRIPT_UPDATE_SPECFILE_CUSTOM $spec_dir/$pkg.spec $SCRIPT_ARGS || {
|
|
case $SEVERITY in
|
|
0) ;;
|
|
1) echo "%! Error: update-specfile-custom script returned $?; skipping $pkg package."
|
|
ret=1
|
|
continue ;;
|
|
*) echo "!! Error: update-specfile-custom script returned $?; aborting."
|
|
exit 1 ;;
|
|
esac
|
|
}
|
|
fi
|
|
;;
|
|
esac
|
|
|
|
[ -e $spec_dir/$pkg.spec ] && {
|
|
SPEC_EPOCH=`grep "Epoch:" $spec_dir/$pkg.spec | sed "s|Epoch:[[:space:]]*||"`
|
|
SPEC_VERSION=`grep "Version:" $spec_dir/$pkg.spec | sed "s|Version:[[:space:]]*||"`
|
|
SPEC_RELEASE=`grep "Release:" $spec_dir/$pkg.spec | sed "s|Release:[[:space:]]*||"`
|
|
}
|
|
|
|
|
|
[ -e "$SRCPKGLIST" ] && PKGLINE=`grep "^${pkg} " $SRCPKGLIST` || PKGLINE=
|
|
[ "$PKGLINE" -a -e "$BUILDSLIST" ] && BUILDSLINE=`grep "^${pkg}:" $BUILDSLIST` || BUILDSLINE=
|
|
[ -e "$SRCPKGLIST_DELAYED" ] && PKGLINE_DELAYED=`grep "^${pkg} " $SRCPKGLIST_DELAYED` || PKGLINE_DELAYED=
|
|
[ "$PKGLINE_DELAYED" -a -e "$BUILDSLIST_DELAYED" ] && BUILDSLINE_DELAYED=`grep "^${pkg} " $SRCPKGLIST_DELAYED` || BUILDSLINE_DELAYED=
|
|
|
|
if [ "$PKGLINE_DELAYED" -a "$do_autobuild" ]; then
|
|
set -- $PKGLINE
|
|
_ver1=$2
|
|
_rel1=$6
|
|
set -- $PKGLINE_DELAYED
|
|
_ver2=$2
|
|
_rel2=$6
|
|
version_find_bigger ${_ver1} ${_ver2}
|
|
if [ $? -eq 2 ]; then
|
|
PKGLINE=$PKGLINE_DELAYED
|
|
echo "!! Warning: using package from delayed repository (${_ver2} > ${_ver1})"
|
|
elif [ $? -eq 0 ]; then
|
|
version_find_bigger ${_rel1} ${_rel2}
|
|
if [ $? -eq 0 ]; then
|
|
echo "!! Warning: package with same version (${_ver1}-${_rel1}) exists in delayed repository"
|
|
elif [ $? -eq 2 ]; then
|
|
echo "!! Warning: using package from delayed repository (${_ver2}-${_rel2} > ${_ver1}-${_rel1})"
|
|
PKGLINE=$PKGLINE_DELAYED
|
|
fi
|
|
fi
|
|
fi
|
|
|
|
case $operation in
|
|
prepare)
|
|
command_opts="-a1"
|
|
if [ "$PKGLINE" ]; then
|
|
set -- $PKGLINE
|
|
[[ $4 =~ "^[0-9]+$" ]] && REPNAME=${AUTODIST_REPOSITORIES[$4]} || REPNAME="$4"
|
|
if [ "$REPNAME" != "$AUTODIST_REPOSITORY" -a "$REPOSITORY_STRICT" ]; then
|
|
case $SEVERITY in
|
|
0) echo "!! Warning: package comes from $REPNAME instead of $AUTODIST_REPOSITORY" ;;
|
|
1) echo "!! Error: package comes from $REPNAME instead of $AUTODIST_REPOSITORY; skipping $pkg package."
|
|
continue ;;
|
|
*) echo "!! Error: package comes from $REPNAME instead of $AUTODIST_REPOSITORY; aborting."
|
|
exit 1 ;;
|
|
esac
|
|
fi
|
|
if [ "$REPNAME" ]; then
|
|
command_opts="$command_opts --server ${REPNAME}"
|
|
else
|
|
echo "!! Warning: undefined repository $4 in srcpkglist, check AUTODIST_REPOSITORIES in configuration file"
|
|
fi
|
|
else
|
|
echo "!! Warning: package $pkg is missing in srcpkglist file"
|
|
fi
|
|
;;
|
|
rebuild) command_opts="-a4 --rebuild" ;;
|
|
autoupdate) command_opts="-a2:4" ;;
|
|
update)
|
|
# skip package in job if up to date
|
|
if [ "$PKGLINE" ]; then
|
|
set -- $PKGLINE
|
|
pkglinever=$2
|
|
# warning: assuming version is passed first
|
|
version_find_bigger "${passed_arguments/ *}" "$pkglinever"
|
|
[ $? -eq 1 ] || {
|
|
echo "!! Warning: skipping ${pkg} package already up to date ($pkglinever >= ${passed_arguments/ *})."
|
|
# echo "%% Adding ${pkg} job to skipped list."
|
|
# echo "${pkg} $DATE_NOW 255" >> $SKIPPEDLISTDIR/auto.skip
|
|
[ "$do_autobuild" ] && autobuild_log $pkg $operation skipped $JOB_NAME
|
|
continue
|
|
}
|
|
fi
|
|
if [ -e $source_dir/$pkg-autoupdate ]; then
|
|
echo "?= Running $pkg-autoupdate script with version ${passed_arguments/ *}"
|
|
(cd $source_dir; sh ./$pkg-autoupdate ${passed_arguments/ *} >/dev/null)
|
|
AUTOUPDATE_SCRIPT_ALREADY_RUN=1
|
|
fi
|
|
command_opts="-a3:4" ;;
|
|
build)
|
|
# skip package in job if it is in the delayed repository
|
|
if [ "$PKGLINE_DELAYED" -a "$BUILDSLINE_DELAYED" -a "$do_autobuild" ]; then
|
|
set -- $PKGLINE_DELAYED
|
|
if [ "$SPEC_VERSION-$SPEC_RELEASE" = "$2-$6" ]; then
|
|
echo "!! Warning: skipping ${pkg} package build because already present in delayed repository."
|
|
echo "%% Adding ${pkg} job to skipped list."
|
|
echo "${pkg} $DATE_NOW 254" >> $SKIPPEDLISTDIR/auto.skip
|
|
[ "$do_autobuild" ] && autobuild_log $pkg $operation skipped $JOB_NAME
|
|
continue
|
|
fi
|
|
fi
|
|
command_opts="-a5:6 -b" ;;
|
|
buildsrpm)
|
|
command_opts="-a5:6 --norpm" ;;
|
|
buildinstall)
|
|
# skip package in job if up to date
|
|
if [ "$PKGLINE" -a "$BUILDSLINE" ]; then
|
|
set -- $PKGLINE
|
|
pkglinever=$2
|
|
pkglinerel=$6
|
|
# warning: assuming version is passed first
|
|
version_find_bigger "$SPEC_VERSION" "$pkglinever"
|
|
[ $? -eq 0 ] && {
|
|
version_find_bigger "$SPEC_RELEASE" "$pkglinerel"
|
|
if [ $? -ne 1 ]; then
|
|
echo "!! Warning: skipping ${pkg} package already up to date ($SPEC_VERSION-$SPEC_RELEASE >= $pkglinever-$pkglinerel)."
|
|
continue
|
|
fi
|
|
}
|
|
fi
|
|
# skip package in job if it is in the delayed repository
|
|
if [ "$PKGLINE_DELAYED" -a "$BUILDSLINE_DELAYED" -a "$do_autobuild" ]; then
|
|
set -- $PKGLINE_DELAYED
|
|
if [ "$SPEC_VERSION-$SPEC_RELEASE" = "$2-$6" ]; then
|
|
echo "!! Warning: skipping ${pkg} package build because already present in delayed repository."
|
|
continue
|
|
fi
|
|
fi
|
|
command_opts="-a5,6,10,11 --force-install" ;;
|
|
send)
|
|
# skip package in job if up to date
|
|
if [ "$PKGLINE" -a "$BUILDSLINE" -a "$do_autobuild" ]; then
|
|
set -- $PKGLINE
|
|
pkglinever=$2
|
|
pkglinerel=$6
|
|
# warning: assuming version is passed first
|
|
version_find_bigger "$SPEC_VERSION" "$pkglinever"
|
|
[ $? -eq 0 ] && {
|
|
version_find_bigger "$SPEC_RELEASE" "$pkglinerel"
|
|
if [ $? -ne 1 ]; then
|
|
echo "!! Warning: skipping ${pkg} package already up to date ($SPEC_VERSION-$SPEC_RELEASE >= $pkglinever-$pkglinerel)."
|
|
continue
|
|
fi
|
|
}
|
|
fi
|
|
# skip package in job if it is in the delayed repository
|
|
if [ "$PKGLINE_DELAYED" -a "$BUILDSLINE_DELAYED" -a "$do_autobuild" ]; then
|
|
set -- $PKGLINE_DELAYED
|
|
if [ "$SPEC_VERSION-$SPEC_RELEASE" = "$2-$6" ]; then
|
|
echo "!! Warning: skipping ${pkg} package send because already present in delayed repository."
|
|
continue
|
|
fi
|
|
fi
|
|
command_opts="-a10" ;;
|
|
install) command_opts="-a11" ;;
|
|
*)
|
|
echo "!! Internal error: unknown operation $operation; aborting."
|
|
exit 1
|
|
;;
|
|
esac
|
|
|
|
command="$AUTOSPEC_CMD -u $pkg $command_opts $passed_arguments $JOB_ARGS"
|
|
|
|
tmpfile=${LOGBASEDIR}/current.$$
|
|
> $tmpfile
|
|
tmpfile1=`tempfile`
|
|
echo -n "== "`log_date`" $JOB_NAME with args: $JOB_ARGS..." >> $LOGFILE
|
|
echo "
|
|
=> $command" >> $LOGFILE_PKG
|
|
[ "$verbose" ] && echo "== "`log_date`" $JOB_NAME with args: $JOB_ARGS...
|
|
=> $command"
|
|
|
|
if [ "$simulate" ]; then
|
|
echo "Command: $command"
|
|
else
|
|
# eval "$command 2>&1 && echo '0'>$tmpfile1 || echo '1'>$tmpfile1" | tail_file $tmpfile "== $pkg (${JOB_VALUES[*]})..."
|
|
(export LANG=en_US.UTF-8; $command 2>&1; echo $? >$tmpfile1) | tail_file $tmpfile "== $pkg (${JOB_VALUES[*]})..."
|
|
if [ -e $tmpfile1 ]; then
|
|
ret=`cat $tmpfile1`
|
|
rm -f $tmpfile1
|
|
else
|
|
ret=0
|
|
fi
|
|
|
|
cat $tmpfile >> $LOGFILE_PKG
|
|
|
|
if [ $ret -gt 0 ]; then
|
|
echo " FAILED (ret=$ret)"
|
|
echo " FAILED (ret=$ret)" >> $LOGFILE
|
|
[ ! "$quiet" -a ! "$verbose" ] && {
|
|
echo "=> $command"
|
|
echo
|
|
echo " == begin of output log =="
|
|
echo
|
|
tail -n 40 $tmpfile
|
|
echo
|
|
echo " == end of output log =="
|
|
echo
|
|
}
|
|
mv $LOGFILE_PKG $LOGDIR/failed/
|
|
echo "?= See $LOGDIR/failed/${LOGFILE_PKG_NAME}"
|
|
[ "$do_autobuild" ] && autobuild_log $pkg $operation $ret $JOB_NAME $LOGDIR/failed/${LOGFILE_PKG_NAME}
|
|
case $operation in
|
|
autoupdate|update)
|
|
;;
|
|
build|buildinstall)
|
|
# copy new patches to sourcesdir for sharing
|
|
[ "$do_autobuild" ] && {
|
|
PATCHES=`diff $spec_dir/$pkg.spec $spec_dir/.$pkg.spec.autodist.preupdate | grep "> Patch" | sed "s|.*[[:space:]]\([^[:space:]]*\)|\1|"`
|
|
for p in $PATCHES; do
|
|
echo "== Copying patch $p to public dir"
|
|
[ -e $source_dir/$p ] && cp $source_dir/$p $SOURCESDIR/
|
|
done
|
|
}
|
|
;;
|
|
esac
|
|
[ $SEVERITY -gt 0 -a ! "$continue_on_error" ] && {
|
|
rm -f $tmpfile
|
|
return $ret
|
|
}
|
|
else
|
|
echo
|
|
echo " OK" >> $LOGFILE
|
|
mv $LOGFILE_PKG $LOGDIR/ok/
|
|
echo "?= See $LOGDIR/ok/${LOGFILE_PKG_NAME}"
|
|
[ "$do_autobuild" ] && autobuild_log $pkg $operation ok $JOB_NAME $LOGDIR/ok/${LOGFILE_PKG_NAME}
|
|
|
|
case $operation in
|
|
prepare)
|
|
[ -e $spec_dir/.$pkg.spec.autodist.prebuild ] && \
|
|
rm -f $spec_dir/.$pkg.spec.autodist.prebuild
|
|
cp $spec_dir/$pkg.spec $spec_dir/.$pkg.spec.autodist.preupdate
|
|
;;
|
|
rebuild)
|
|
cp $spec_dir/$pkg.spec $spec_dir/.$pkg.spec.autodist.prebuild
|
|
;;
|
|
update|autoupdate)
|
|
cp $spec_dir/$pkg.spec $spec_dir/.$pkg.spec.autodist.prebuild
|
|
SPEC_EPOCH=`grep -m1 "^Epoch:" $spec_dir/$pkg.spec | sed "s|Epoch:[[:space:]]*||"`
|
|
SPEC_VERSION=`grep -m1 "^Version:" $spec_dir/$pkg.spec | sed "s|Version:[[:space:]]*||"`
|
|
SPEC_RELEASE=`grep -m1 "^Release:" $spec_dir/$pkg.spec | sed "s|Release:[[:space:]]*||"`
|
|
if [ "$PKGLINE" ]; then
|
|
set -- $PKGLINE
|
|
echo "?= Specfile updated from version $2-$6 to $SPEC_VERSION-$SPEC_RELEASE"
|
|
if [ "`echo $SPEC_VERSION | grep -i alpha`" -o \
|
|
"`echo $SPEC_VERSION | grep -i beta`" -o \
|
|
"`echo $SPEC_VERSION | grep -i rc`" -o \
|
|
"`echo $SPEC_VERSION | grep -i pre`" -o \
|
|
"`echo $SPEC_VERSION | grep -i pl`" ]; then
|
|
if [ ! "`echo $2 | grep -i alpha`" -a \
|
|
! "`echo $2 | grep -i beta`" -a \
|
|
! "`echo $2 | grep -i rc`" -a \
|
|
! "`echo $2 | grep -i pre`" -a \
|
|
! "`echo $2 | grep -i pl`" ]; then
|
|
echo "!! Looks like an update to an unstable release; skipping."
|
|
[ $SEVERITY -gt 0 ] && {
|
|
rm -f $tmpfile
|
|
return 3
|
|
}
|
|
fi
|
|
fi
|
|
if [ "$2" != "$SPEC_VERSION" -a -e $source_dir/$pkg-autoupdate -a ! "$AUTOUPDATE_SCRIPT_ALREADY_RUN" ]; then
|
|
echo "?= Running $pkg-autoupdate script with version ${passed_arguments/ *}"
|
|
(cd $source_dir; sh ./$pkg-autoupdate ${passed_arguments/ *} >/dev/null)
|
|
AUTOUPDATE_SCRIPT_ALREADY_RUN=1
|
|
fi
|
|
fi
|
|
;;
|
|
buildinstall|send)
|
|
if [ $JOB_IDX -eq $JOB_LAST -a "$do_autobuild" ]; then
|
|
# archive patches
|
|
[ -e $AUTOUPDATEDIR/spec-patches-update/$pkg.spec.patch ] && \
|
|
mv $AUTOUPDATEDIR/spec-patches-update/$pkg.spec.patch \
|
|
$AUTOUPDATEDIR/spec-patches-update/old/
|
|
[ -e $AUTOUPDATEDIR/spec-patches-build/$pkg.spec.patch ] && \
|
|
mv $AUTOUPDATEDIR/spec-patches-build/$pkg.spec.patch \
|
|
$AUTOUPDATEDIR/spec-patches-build/old/
|
|
PATCHES=`diff $spec_dir/$pkg.spec $spec_dir/.$pkg.spec.autodist.preupdate | grep "> Patch" | sed "s|.*[[:space:]]\([^[:space:]]*\)|\1|"`
|
|
for p in $PATCHES; do
|
|
[ -e $SOURCESDIR/$p ] && rm -f $SOURCESDIR/$p
|
|
done
|
|
fi
|
|
if [ "$operation" = "buildinstall" -o "${passed_arguments/--norpm}" != "${passed_arguments}" ]; then
|
|
# send operation: check for --norpm (source send) to avoid sending notification twice
|
|
[ "$WEBBUILD_URL" -a "$WEBBUILD_USER" ] && {
|
|
SPEC_VERSION=`grep -m1 "^Version:" $spec_dir/$pkg.spec | sed "s|Version:[[:space:]]*||"`
|
|
if [ "$WEBBUILD_USER_CMDLINE" ]; then
|
|
curl -s "$WEBBUILD_URL?REQUEST=message&USER=$WEBBUILD_USER&SECRET=$WEBBUILD_SECRET&USER_EMAIL=$WEBBUILD_EMAIL&\
|
|
MESSAGE=`cgi_encodevar \"(invoked by $WEBBUILD_USER_CMDLINE) sent <b>$pkg $SPEC_VERSION-$SPEC_RELEASE</b> for ${TARGETARCH} to <b>$SEND_SERVER</b>\"`" >/dev/null
|
|
else
|
|
curl -s "$WEBBUILD_URL?REQUEST=message&USER=$WEBBUILD_USER&SECRET=$WEBBUILD_SECRET&USER_EMAIL=$WEBBUILD_EMAIL&\
|
|
MESSAGE=`cgi_encodevar \"sent <b>$pkg $SPEC_VERSION-$SPEC_RELEASE</b> for ${TARGETARCH} to <b>$SEND_SERVER</b>\"`" >/dev/null
|
|
fi
|
|
}
|
|
fi
|
|
;;
|
|
esac
|
|
fi
|
|
rm -f $tmpfile
|
|
fi
|
|
done
|
|
return $ret
|
|
}
|
|
|
|
function launch_job_loop() {
|
|
# Iterates launch_pkgs_loop for each of the lines of current job
|
|
# (defined from JOB_FIRST to JOB_LAST)
|
|
# This is needed for build, send and install operations
|
|
numerr=0
|
|
for j in `seq $JOB_FIRST $JOB_LAST`; do
|
|
launch_pkgs_loop "$1" "$2" "${JOBS[$j]}" $j
|
|
if [ $? -gt 0 ]; then
|
|
numerr=$(($numerr + 1))
|
|
[ "$continue_on_error" ] || return $numerr;
|
|
fi
|
|
done
|
|
return $numerr
|
|
}
|
|
|
|
function log_date() {
|
|
echo -n `LANG=C date +%Y%m%d@%H%M%S`
|
|
}
|
|
|
|
[ -e $LOGBASEDIR ] || {
|
|
mkdir -p $LOGBASEDIR/prepare/{ok,failed}
|
|
mkdir -p $LOGBASEDIR/update/{ok,failed}
|
|
mkdir -p $LOGBASEDIR/build/{ok,failed}
|
|
mkdir -p $LOGBASEDIR/install/{ok,failed}
|
|
mkdir -p $LOGBASEDIR/send/{ok,failed}
|
|
}
|
|
|
|
#
|
|
# Main
|
|
#
|
|
|
|
DISTDBFILES=
|
|
|
|
DISTDB=`fetch_repository_file ${AUTODIST_REPOSITORY/-*}/distdb`
|
|
[ "$DISTDB" ] && DISTDBFILES="$DISTDB"
|
|
|
|
DISTDBARCH=`fetch_repository_file ${AUTODIST_REPOSITORY/-*}/distdb.$TARGETARCH`
|
|
if [ "$DISTDBARCH" ]; then
|
|
DISTDBFILES="$DISTDBFILES $DISTDBARCH"
|
|
fi
|
|
|
|
if [ ! "$DISTDBFILES" ]; then
|
|
[ -e $SYSCONFDIR/distdb ] && DISTDBFILES="$SYSCONFDIR/distdb"
|
|
[ -e $SYSCONFDIR/distdb.$TARGETARCH ] && DISTDBFILES="$DISTDBFILES $SYSCONFDIR/distdb.$TARGETARCH"
|
|
fi
|
|
|
|
if [ "$do_listjobs" ]; then
|
|
for f in $DISTDBFILES; do
|
|
for j in `grep -v "^#" $f | grep ".*=(" | sed "s|\(.*\)=(.*|\1|"`; do
|
|
echo $j
|
|
done
|
|
done
|
|
exit 0
|
|
fi
|
|
|
|
# include global distdb files
|
|
for f in $DISTDBFILES; do
|
|
. $f
|
|
done
|
|
|
|
if [ "$do_listpkgs" ]; then
|
|
get_job_vector $LISTPKGSJOB
|
|
for p in ${JOB_PKGS[*]}; do
|
|
echo $p
|
|
done
|
|
exit 0
|
|
fi
|
|
|
|
# FIXME: DISTDBDIR contains private jobs we don't want to publish on webbuild
|
|
for f in $DISTDBDIR/*.db; do
|
|
. $f
|
|
done
|
|
|
|
eval `autospec -q --eval="srpms_dir"`
|
|
eval `autospec -q --eval="rpms_dir"`
|
|
eval `autospec -q --eval="spec_dir"`
|
|
eval `autospec -q --eval="source_dir"`
|
|
eval `autospec -q --eval="tmppath_dir"`
|
|
|
|
for a in $LOGBASEDIR/{,prepare/{,ok,failed},update/{,ok,failed},build/{,ok,failed},install/{,ok,failed},send/{,ok,failed}}; do
|
|
|
|
[ ! -w $a ] && {
|
|
echo "!! Error: directory $a is missing or read-only; aborting."
|
|
exit 1
|
|
}
|
|
|
|
[ "$do_cleanlogs" ] && {
|
|
find $a -type f -exec rm -f {} \;
|
|
}
|
|
|
|
done
|
|
|
|
AUTOUPDATEDIR=${LOCAL_REPS_BASE_DIR}/$AUTODIST_REPOSITORY/autoupdate/
|
|
[ -r $AUTOUPDATEDIR ] || {
|
|
AUTOUPDATEDIR=$USERCONFDIR/$AUTODIST_REPOSITORY/autoupdate
|
|
mkdir -p $AUTOUPDATEDIR
|
|
}
|
|
|
|
SOURCESDIR=$AUTOUPDATEDIR/sources/
|
|
SUCCESSLISTDIR=$AUTOUPDATEDIR
|
|
SKIPPEDLISTDIR=$AUTOUPDATEDIR
|
|
|
|
SRCPKGLIST=`fetch_repository_file $AUTODIST_REPOSITORY/srcpkglist`
|
|
[ $? -eq 0 ] || echo "Warning: unable to fetch $SRCPKGLIST">&2
|
|
|
|
[ "$AUTODIST_DELAYED_REPOSITORY" ] && SRCPKGLIST_DELAYED=`fetch_repository_file $AUTODIST_DELAYED_REPOSITORY/srcpkglist`
|
|
[ $? -eq 0 ] || echo "Warning: unable to fetch $SRCPKGLIST_DELAYED">&2
|
|
|
|
BUILDSLIST=`fetch_repository_file distromatic/$AUTODIST_REPOSITORY/builds-$TARGETARCH`
|
|
[ "$AUTODIST_DELAYED_REPOSITORY" ] && BUILDSLIST_DELAYED=`fetch_repository_file distromatic/$AUTODIST_DELAYED_REPOSITORY/builds-$TARGETARCH`
|
|
[ $? -eq 0 ] || echo "Warning: unable to fetch $BUILDSLIST">&2
|
|
|
|
LEGACYLIST=`fetch_repository_file ${AUTODIST_REPOSITORY/-*}/legacy`
|
|
[ "$LEGACYLIST" ] || LEGACYLIST=$SYSCONFDIR/legacy
|
|
[ $? -eq 0 ] || echo "Warning: unable to fetch $LEGACYLIST">&2
|
|
|
|
echo "%% Autodist started with PID $$ @ `LANG=C date`"
|
|
|
|
# autobuild: add jobs ordered by oldest builds
|
|
if [ "$do_autobuild" = "1" ]; then
|
|
trap "rm -f $PIDFILE; exit 1" SIGQUIT SIGINT SIGKILL SIGTERM
|
|
echo $$ > $PIDFILE
|
|
[ -e "$SRCPKGLIST" ] || {
|
|
echo "ERROR: missing srcpkglist file $SRCPKGLIST; aborting."
|
|
exit 1
|
|
}
|
|
srctmpfile=`tempfile`
|
|
|
|
cat $AUTOUPDATEDIR/*.in > $srctmpfile
|
|
cat $SRCPKGLIST | sort --key=3 >> $srctmpfile
|
|
|
|
pkgtmpfile=`tempfile`
|
|
[ "$pkgtmpfile" ] || {
|
|
echo "ERROR: cannot create temporary files; aborting."
|
|
exit 1
|
|
}
|
|
|
|
## when autobuilding always rebuild packages
|
|
#SEND_FORCE_BUILD="--force-build"
|
|
AUTOBUILD_NUMADDED=0
|
|
BUILDDATE=0
|
|
PKGCOUNT=`wc -l $srctmpfile | awk '{ print $1 }'`
|
|
SKIPPEDCOUNT=0
|
|
BLACKLISTCOUNT=0
|
|
SUCCESSLISTCOUNT=0
|
|
REBUILDOLDCOUNT=0
|
|
|
|
> $pkgtmpfile
|
|
|
|
# cat $srctmpfile | sort --key=3 | \
|
|
while read line; do
|
|
set -- $line
|
|
PKGNAME=${1}
|
|
VERSION=${2}
|
|
BUILDDATE=${3}
|
|
SOURCEREP=${4}
|
|
RELEASE=${5}
|
|
EPOCH=${6}
|
|
|
|
# skip duplicates
|
|
grep "^$PKGNAME " $pkgtmpfile >/dev/null && continue
|
|
|
|
# check blacklist
|
|
awk '{ print $1 }' $BLACKLIST | grep "^$PKGNAME$" >/dev/null && {
|
|
BLACKLISTCOUNT=`expr $BLACKLISTCOUNT + 1`
|
|
# echo "?= Job $PKGNAME is in the blacklist; skipping"
|
|
continue
|
|
}
|
|
|
|
if [ "${VERSION:0:1}" != "+" ]; then
|
|
if [ $REBUILDOLDCOUNT -lt $AUTODIST_REBUILDOLD_MAX -a $BUILDDATE -ge $AUTODIST_REBUILDOLD_FROMDATE ]; then
|
|
# rebuilt oldest packages
|
|
REBUILDOLDCOUNT=$(($REBUILDOLDCOUNT + 1))
|
|
VERSION=+0
|
|
else
|
|
# check skippedlist (but ignore for scheduled updates)
|
|
SKIPPEDLINE=`awk '{ print $1" "$2 }' $SKIPPEDLISTDIR/*.skip | grep -m1 "^$PKGNAME "`
|
|
if [ "$SKIPPEDLINE" ]; then
|
|
set -- $SKIPPEDLINE
|
|
SKIPPEDTIME=$2
|
|
SKIPPEDDAYS=`expr \( $DATE_NOW - $SKIPPEDTIME \) / 86400`
|
|
if [ "$SKIPPEDDAYS" -le "$AUTOBUILD_SKIP_DAYS" ]; then
|
|
SKIPPEDCOUNT=`expr $SKIPPEDCOUNT + 1`
|
|
#echo "?= Package $PKGNAME has been in the skippedlist for $SKIPPEDDAYS days; skipping"
|
|
continue
|
|
else
|
|
sed -i "/^$PKGNAME /d" $SKIPPEDLISTDIR/*.skip
|
|
fi
|
|
fi
|
|
fi
|
|
fi
|
|
|
|
if [ "${VERSION:0:1}" != "+" ]; then
|
|
# check legacylist
|
|
awk '{ print $1 }' $LEGACYLIST | grep "^$PKGNAME$" >/dev/null && {
|
|
echo "?= Job $PKGNAME is in the legacy list; skipping automatic update"
|
|
echo "$PKGNAME $DATE_NOW 100" >> $SKIPPEDLISTDIR/auto.skip
|
|
continue
|
|
}
|
|
fi
|
|
|
|
# manually or from lists scheduled jobs
|
|
if [ "${VERSION:0:1}" == "+" -a "$VERSION" != "+0" ]; then
|
|
TRVER=`echo ${VERSION:1} | tr - .`
|
|
get_job_vector $PKGNAME
|
|
NEED_REBUILD=0
|
|
if [ ${#JOB_PKGS[*]} -gt 1 ]; then
|
|
# jobs are not fully rebuilt
|
|
for j in ${JOB_PKGS[*]}; do
|
|
REPVER=`grep "^$j " $SRCPKGLIST | gawk '{ print $2 }'`
|
|
version_find_bigger "$TRVER" "$REPVER"
|
|
[ $? -eq 1 ] && NEED_REBUILD=1
|
|
done
|
|
else
|
|
# single packages are rebuilt if scheduled
|
|
NEED_REBUILD=1
|
|
fi
|
|
if [ "$NEED_REBUILD" = "0" ]; then
|
|
echo "?= Job $PKGNAME is already up to date; skipping"
|
|
continue
|
|
fi
|
|
elif [ "$VERSION" != "+0" ]; then
|
|
# check successlist
|
|
SUCCESSLINE=`awk '{ print $1" "$2 }' $SUCCESSLISTDIR/*.success | grep -m1 "^$PKGNAME "`
|
|
if [ "$SUCCESSLINE" ]; then
|
|
set -- $SUCCESSLINE
|
|
SUCCESSTIME=$2
|
|
[ "$SUCCESSTIME" ] || SUCCESSTIME=0
|
|
SUCCESSDAYS=`expr \( $DATE_NOW - $SUCCESSTIME \) / 86400`
|
|
if [ "$SUCCESSDAYS" -le "$AUTOBUILD_SUCCESS_DAYS" ]; then
|
|
SUCCESSLISTCOUNT=`expr $SUCCESSLISTCOUNT + 1`
|
|
#echo "?= Job $PKGNAME has been in the successlist for $SUCCESSDAYS days; skipping"
|
|
continue
|
|
else
|
|
sed -i "/^$PKGNAME /d" $SUCCESSLISTDIR/*.success
|
|
fi
|
|
fi
|
|
fi
|
|
|
|
[ $AUTOBUILD_NUMADDED -ge $AUTOBUILD_MAXNUM ] && break
|
|
|
|
# FIXME: hardcoded skipped packages
|
|
#[ "${PKGNAME:0:5}" = "java-" -o "${PKGNAME:0:7}" = "apache-" -o \
|
|
# "${PKGNAME:0:8}" = "jakarta-" -o "${PKGNAME:0:6}" = "compiz" ] && continue
|
|
|
|
if [ $BUILDDATE -ge $AUTOBUILD_DATEFROM -o $BUILDDATE -eq 0 ]; then
|
|
AUTOBUILD_NUMADDED=`expr $AUTOBUILD_NUMADDED + 1`
|
|
echo "$PKGNAME $VERSION" >> $pkgtmpfile
|
|
fi
|
|
done < $srctmpfile
|
|
|
|
echo "%% Total pkgs: $PKGCOUNT, skipped list: $SKIPPEDCOUNT, blacklist: $BLACKLISTCOUNT, success list: $SUCCESSLISTCOUNT, rebuild-old list: $REBUILDOLDCOUNT, last build date: $BUILDDATE"
|
|
while read line; do
|
|
set -- $line
|
|
PKGNAME=${1}
|
|
VERSION=${2}
|
|
JOBVER[${#JOBNAME[@]}]=$VERSION
|
|
JOBNAME[${#JOBNAME[@]}]=$PKGNAME
|
|
done < $pkgtmpfile
|
|
|
|
echo -n "%% autoupdate jobs: "
|
|
for i in `seq 1 ${#JOBNAME[@]}`; do
|
|
echo -n "${JOBNAME[$i-1]}(${JOBVER[$i-1]}) "
|
|
done
|
|
echo
|
|
rm -f $pkgtmpfile $srctmpfile
|
|
|
|
[ -e $LOGBASEDIR/autoupdate-current ] && mv $LOGBASEDIR/autoupdate-current $LOGBASEDIR/autoupdate-last
|
|
fi
|
|
|
|
OPERATION_ERRORS=0
|
|
|
|
echo "%% ${#JOBNAME[*]} job(s) scheduled"
|
|
echo "%% Starting main jobs loop"
|
|
for JOB_NUM in `seq 1 ${#JOBNAME[*]}`; do
|
|
JOB_NAME=${JOBNAME[$JOB_NUM-1]}
|
|
JOB_VER=${JOBVER[$JOB_NUM-1]}
|
|
JOB_VER=`echo $JOB_VER | tr - .`
|
|
|
|
# resolve JOB_NAME from distdb
|
|
get_job_vector $JOB_NAME
|
|
JOB_NAME=${JOB_NAME/*\/}
|
|
|
|
[ "$quiet" ] || echo "== =======================$JOB_NAME============================="
|
|
echo -n "%% Doing $JOB_NAME (VER=$JOB_VER"
|
|
for k in ${JOB_VARNAMES[*]}; do
|
|
echo -n " %${k}"
|
|
done
|
|
echo ") job"
|
|
|
|
DATE_NOW=`LANG=C date +%s`
|
|
JOBS=()
|
|
for k in `seq 3 ${#JOB[*]}`; do
|
|
JOBS=(${JOBS[*]} "${JOB[$k-1]}")
|
|
done
|
|
|
|
JOB_NUMBER=${#JOBS[*]}
|
|
JOB_FIRST=0
|
|
JOB_LAST=`expr $JOB_NUMBER - 1`
|
|
|
|
if [ "$do_prepare" ]; then
|
|
LOGDIR=$LOGBASEDIR/prepare
|
|
LOGFILE=$LOGDIR/last
|
|
> $LOGFILE
|
|
echo "%% Starting PREPARE operation @ `LANG=C date`"
|
|
echo "%% "`log_date`" Starting PREPARE operation" > $LOGFILE
|
|
launch_pkgs_loop prepare "$AUTOSPEC_ARGS --force" || {
|
|
case $SEVERITY in
|
|
0) ;;
|
|
1) echo "%! Error during package prepare; skipping $JOB_NAME job."
|
|
OPERATION_ERRORS=`expr $OPERATION_ERRORS + 1`
|
|
continue ;;
|
|
*) echo "!! Error during package prepare; aborting."
|
|
exit 255 ;;
|
|
esac
|
|
}
|
|
if [ ! "$do_update" -a "$do_autobuild" = "1" ]; then
|
|
[ "${AUTOSPEC_ARGS/--changelog}" = "${AUTOSPEC_ARGS}" ] &&
|
|
AUTOSPEC_CHANGELOG="--changelog \"automatic rebuild by autodist\"" || AUTOSPEC_CHANGELOG=
|
|
launch_pkgs_loop rebuild "$AUTOSPEC_ARGS $AUTOSPEC_CHANGELOG" || {
|
|
case $SEVERITY in
|
|
0) ;;
|
|
1) echo "%! Error during package update for rebuild; skipping $JOB_NAME job."
|
|
OPERATION_ERRORS=`expr $OPERATION_ERRORS + 1`
|
|
continue ;;
|
|
*) echo "!! Error during package update for rebuild; aborting."
|
|
exit 255 ;;
|
|
esac
|
|
}
|
|
fi
|
|
fi
|
|
|
|
if [ "$do_update" ]; then
|
|
LOGDIR=$LOGBASEDIR/update
|
|
LOGFILE=$LOGDIR/last
|
|
echo "%% Starting UPDATE operation @ `LANG=C date`"
|
|
echo "%% "`log_date`" Starting UPDATE operation" > $LOGFILE
|
|
|
|
if [ "${JOB_VER:0:1}" != "+" -o "${JOB_VER}" = "+0" ]; then
|
|
ret=1
|
|
# don't update when --rebuild is passed
|
|
if [ ! "$rebuild_packages" ]; then
|
|
# check legacylist
|
|
awk '{ print $1 }' $LEGACYLIST | grep "^$JOB_NAME$" >/dev/null && {
|
|
echo "?= Job $JOB_NAME is in the legacy list; forcing rebuild"
|
|
} || {
|
|
[ "${AUTOSPEC_ARGS/--changelog}" = "${AUTOSPEC_ARGS}" ] &&
|
|
AUTOSPEC_CHANGELOG="--changelog \"automatic update by autodist\"" || AUTOSPEC_CHANGELOG
|
|
launch_pkgs_loop autoupdate "$AUTOSPEC_ARGS $AUTOSPEC_CHANGELOG $SEND_FORCE"
|
|
ret=$?
|
|
}
|
|
fi
|
|
if [ $ret != 0 ]; then
|
|
if [ ! "$rebuild_packages" -a "${JOB_VER}" != "+0" ]; then
|
|
[ $ret -ge 2 -a "$do_autobuild" ] && {
|
|
echo "%% Adding $JOB_NAME job to skipped list."
|
|
echo "$JOB_NAME $DATE_NOW $ret" >> $SKIPPEDLISTDIR/auto.skip
|
|
}
|
|
case $SEVERITY in
|
|
0) ;;
|
|
1) echo "%! Error during package update; skipping $JOB_NAME job."
|
|
OPERATION_ERRORS=`expr $OPERATION_ERRORS + 1`
|
|
continue ;;
|
|
*) echo "!! Error during package update; aborting."
|
|
exit 255 ;;
|
|
esac
|
|
else
|
|
echo "%% Rebuilding package(s)"
|
|
[ "${AUTOSPEC_ARGS/--changelog}" = "${AUTOSPEC_ARGS}" ] &&
|
|
AUTOSPEC_CHANGELOG="--changelog \"automatic rebuild by autodist\"" || AUTOSPEC_CHANGELOG=
|
|
launch_pkgs_loop rebuild "$AUTOSPEC_ARGS $AUTOSPEC_CHANGELOG" || {
|
|
case $SEVERITY in
|
|
0) ;;
|
|
1) echo "%! Error during package update for rebuild; skipping $JOB_NAME job."
|
|
OPERATION_ERRORS=`expr $OPERATION_ERRORS + 1`
|
|
continue ;;
|
|
*) echo "!! Error during package update for rebuild; aborting."
|
|
exit 255 ;;
|
|
esac
|
|
}
|
|
fi
|
|
fi
|
|
else
|
|
## skip package in job if up to date
|
|
#for j in ${JOB_PKGS[*]}; do
|
|
# REPVER=`grep "^$j " $SRCPKGLIST | gawk '{ print $2 }'`
|
|
# version_find_bigger "$TRVER" "$REPVER"
|
|
# [ $? -eq 1 ] && NEED_REBUILD=1
|
|
# done
|
|
echo "%% Updating to version ${JOB_VER:1}"
|
|
# WARNING: JOB_VER must be passed to launch_pkgs_loop as the first string in the second parameter
|
|
[ "${AUTOSPEC_ARGS/--changelog}" = "${AUTOSPEC_ARGS}" ] &&
|
|
AUTOSPEC_CHANGELOG="--changelog \"automatic version update by autodist\"" || AUTOSPEC_CHANGELOG=
|
|
launch_pkgs_loop update "${JOB_VER:1} $AUTOSPEC_ARGS $AUTOSPEC_CHANGELOG $SEND_FORCE" || {
|
|
if [ ! "$rebuild_packages" ]; then
|
|
case $SEVERITY in
|
|
0) ;;
|
|
1) echo "%! Error during update; skipping $JOB_NAME job."
|
|
OPERATION_ERRORS=`expr $OPERATION_ERRORS + 1`
|
|
continue ;;
|
|
*) echo "!! Error during update; aborting."
|
|
exit 255 ;;
|
|
esac
|
|
else
|
|
[ "${AUTOSPEC_ARGS/--changelog}" = "${AUTOSPEC_ARGS}" ] &&
|
|
AUTOSPEC_CHANGELOG="--changelog \"automatic rebuild by autodist\"" || AUTOSPEC_CHANGELOG=
|
|
launch_pkgs_loop rebuild "$AUTOSPEC_ARGS $AUTOSPEC_CHANGELOG" || {
|
|
case $SEVERITY in
|
|
0) ;;
|
|
1) echo "%! Error during package update for rebuild; skipping $JOB_NAME job."
|
|
OPERATION_ERRORS=`expr $OPERATION_ERRORS + 1`
|
|
continue ;;
|
|
*) echo "!! Error during package update for rebuild; aborting."
|
|
exit 255 ;;
|
|
esac
|
|
}
|
|
fi
|
|
}
|
|
fi
|
|
fi
|
|
|
|
if [ "$do_build" ]; then
|
|
LOGDIR=$LOGBASEDIR/build
|
|
LOGFILE=$LOGDIR/last
|
|
echo "%% Starting BUILD operation @ `LANG=C date`"
|
|
echo "%% "`log_date`" Starting BUILD operation" > $LOGFILE
|
|
launch_job_loop build "$AUTOSPEC_ARGS $SEND_FORCE_BUILD $SEND_SERVER_CMD" || {
|
|
case $SEVERITY in
|
|
0) ;;
|
|
1) echo "%! Error during build; skipping $JOB_NAME job."
|
|
OPERATION_ERRORS=`expr $OPERATION_ERRORS + 1`
|
|
continue ;;
|
|
*) echo "!! Error during build; aborting."
|
|
exit 255 ;;
|
|
esac
|
|
}
|
|
fi
|
|
|
|
if [ "$do_install" ]; then
|
|
LOGDIR=$LOGBASEDIR/install
|
|
LOGFILE=$LOGDIR/last
|
|
> $LOGFILE
|
|
echo "%% Starting INSTALL operation @ `LANG=C date`"
|
|
echo "%% "`log_date`" Starting INSTALL operation" > $LOGFILE
|
|
launch_job_loop install "$AUTOSPEC_ARGS" || {
|
|
case $SEVERITY in
|
|
0) ;;
|
|
1) echo "%! Error during installation; skipping $JOB_NAME job."
|
|
OPERATION_ERRORS=`expr $OPERATION_ERRORS + 1`
|
|
continue ;;
|
|
*) echo "!! Error during installation; aborting."
|
|
exit 255 ;;
|
|
esac
|
|
}
|
|
fi
|
|
|
|
if [ "$do_send" ]; then
|
|
LOGDIR=$LOGBASEDIR/send
|
|
LOGFILE=$LOGDIR/last
|
|
> $LOGFILE
|
|
echo "%% Starting SEND operation @ `LANG=C date`"
|
|
echo "%% "`log_date`" Starting SEND operation" > $LOGFILE
|
|
launch_job_loop send "$AUTOSPEC_ARGS --nosrpm $SEND_SERVER_CMD" || {
|
|
case $SEVERITY in
|
|
0) ;;
|
|
1) echo "%! Error sending packages; skipping $JOB_NAME job."
|
|
continue ;;
|
|
*) echo "!! Error sending packages; aborting."
|
|
exit 1 ;;
|
|
esac
|
|
}
|
|
# avoid calling autospec with --nosrpm --norpm (not working as expected and not useful)
|
|
if [ "${AUTOSPEC_ARGS/--nosrpm}" = "$AUTOSPEC_ARGS" ]; then
|
|
if [ $REBUILD_SRPMS ]; then
|
|
echo "== rebuilding and sending source rpms"
|
|
launch_pkgs_loop buildsrpm "$AUTOSPEC_ARGS --norpm"
|
|
else
|
|
echo "== sending source rpms"
|
|
fi
|
|
launch_pkgs_loop send "$AUTOSPEC_ARGS --norpm $SEND_SERVER_CMD"
|
|
if [ $? -gt 0 ]; then
|
|
case $SEVERITY in
|
|
0) ;;
|
|
1) echo "%! Error sending sources; skipping $JOB_NAME job."
|
|
continue ;;
|
|
*) echo "!! Error sending sources; aborting."
|
|
exit 1 ;;
|
|
esac
|
|
else
|
|
# archive patches
|
|
if [ "$do_autobuild" ]; then
|
|
[ -e $AUTOUPDATEDIR/spec-patches-update/$JOB_NAME.spec.patch ] && \
|
|
mv $AUTOUPDATEDIR/spec-patches-update/$JOB_NAME.spec.patch \
|
|
$AUTOUPDATEDIR/spec-patches-update/old/${JOB_NAME}.spec.${DATE_NOW}.patch
|
|
[ -e $AUTOUPDATEDIR/spec-patches-build/$JOB_NAME.spec.patch ] && \
|
|
mv $AUTOUPDATEDIR/spec-patches-build/${JOB_NAME}.spec.${DATE_NOW}.patch \
|
|
$AUTOUPDATEDIR/spec-patches-build/old/${JOB_NAME}.spec.${DATE_NOW}.patch
|
|
fi
|
|
fi
|
|
fi
|
|
fi
|
|
# if we are here the job was completed; remove manual entry, if any, and add to successlist
|
|
[ "$do_autobuild" ] && {
|
|
sed -i "/^$JOB_NAME .*/d" $AUTOUPDATEDIR/*.in
|
|
echo "$JOB_NAME $DATE_NOW" >> $SUCCESSLISTDIR/auto.success
|
|
}
|
|
done
|
|
[ "$do_autobuild" = "1" ] && rm -f $PIDFILE
|
|
echo "%! $OPERATION_ERRORS error(s)"
|
|
echo "%% All jobs done @ `LANG=C date`"
|
|
exit $OPERATION_ERRORS
|