123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497 |
- # -*- mode:sh -*-
- # log something (basically echo it together with a timestamp)
- #
- # Set $PROGRAM to a string to have it added to the output.
- function log () {
- local prefix=${PROGRAM:-}
- echo "$(date +"%b %d %H:%M:%S") ${HOSTNAME} ${prefix}[$$]: $*"
- }
- # log the message using log() but then also send a mail
- # to the address configured in MAILTO (if non-empty)
- function log_error () {
- log "$@"
- if [[ -z ${MAILTO} ]]; then
- echo "$*" | mail -a "X-Debian: DAK" -e -s "[$PROGRAM@${HOSTNAME}] ERROR [$$]" -a "From: Debian FTP Masters <ftpmaster@ftp-master.debian.org>" ${MAILTO}
- fi
- }
- # debug log, only output when DEBUG=1
- function debug () {
- if [[ $DEBUG -eq 1 ]]; then
- log "$*"
- fi
- }
- # Get a tempfile, add it to the right variable to get rid of it,
- # and return it
- function gettempfile() {
- local MAKEDIR=${1:-false}
- local TMPARGS=""
- if [[ ${MAKEDIR} == true ]]; then
- TMPARGS="--directory"
- fi
- local TMPFILE=$( mktemp -p ${TMPDIR} ${TMPARGS} )
- TMPFILES="${TEMPFILES} ${TMPFILE}"
- echo "${TMPFILE}"
- }
- # Function that only cleans tempfiles, but does not exit or otherwise
- # care about any exit status
- function cleantempfiles() {
- resolvetmpfiles
- for TEMPFILE in $TMPFILES; do
- if [[ -n ${TEMPFILE} ]] && [[ -f ${TEMPFILE} ]]; then
- rm -f "${TEMPFILE}"
- elif [[ -n ${TEMPFILE} ]] && [[ -d ${TEMPFILE} ]]; then
- if [[ ${TEMPFILE} != / ]] && [[ ${TEMPFILE} != /* ]]; then
- rm -rf "${TEMPFILE}"
- fi
- fi
- done
- TMPFILES=""
- }
- function resolvetmpfiles() {
- # If you don't understand this better not touch the script
- for TEMPFILE in $TEMPFILES; do
- TMPFILES="${TMPFILES} ${!TEMPFILE:-""}"
- done
- TEMPFILES=""
- }
- # Function cleanup
- # No arguments
- # Cleans up any known tempfile.
- # Just ensure your script sets the variable
- # TEMPFILES to the names of variables of tempfiles
- # Or TMPFILES to the pathes of tempfiles
- function cleanup() {
- ERRVAL=$?
- trap - ERR EXIT TERM HUP INT QUIT
- cleantempfiles
- return $ERRVAL
- }
- TEMPFILES=${TEMPFILES:-""}
- TMPFILES=${TMPFILES:-""}
- # Timestamp. Used for dinstall stat graphs
- function log_timestamp() {
- echo "Archive maintenance timestamp ($1): $(date +%H:%M:%S)"
- }
- ########################################################################
- ########################################################################
- # used by cron.dinstall *and* cron.unchecked.
- function make_buildd_dir () {
- local archive=$1
- # We generate straight into the static mirror location for incoming
- log "Preparing buildd area"
- dak manage-build-queues -a
- dak generate-packages-sources2 -a build-queues
- dak generate-releases -a build-queues >/dev/null
- if [[ $archive = security ]]; then
- ${scriptsdir}/update-buildd-archive ${base}/build-queues ${incoming}/debian-security-buildd
- sudo -u archvsync runmirrors -a security-buildd-pool
- else
- # Stick a last modified date in the page footer
- echo "<p>Last updated: $(date -u)</p>" > ${incoming}/web/README.html
- write_project_trace "${incoming}/web/debian-buildd"
- # Tell the mirrors that we've updated
- log "Pushing static for incoming.d.o"
- sudo -u archvsync runmirrors -a buildd > ~dak/runmirrors-buildd.log 2>&1 &
- chronic timeout -k 600 480 /usr/local/bin/static-update-component incoming.debian.org < /dev/null
- wait
- fi
- }
- # Process (oldstable)-proposed-updates "NEW" queue
- function punew_do() {
- local queue="$1"
- local qdir="$2"
- local to="${3}"
- date -u -R >> REPORT
- dak process-policy "${queue}" | tee -a REPORT | mail -a "X-Debian: DAK" -e -s "NEW changes in ${queue}" -a "From: Debian FTP Masters <ftpmaster@ftp-master.debian.org>" "${to}"
- echo >> REPORT
- dak generate-packages-sources2 -s "${queue}"
- STAMP=${STAMP:-$(date "+%Y%m%d%H%M")}
- local ppexportdir="${qdir}/tree/${STAMP}"
- local targetdir="${qdir}/export"
- mkdir -p -- ${ppexportdir}
- dak export -q "${queue}" -d "${ppexportdir}" --all
- ln -sfT ${ppexportdir} ${targetdir}
- find "${qdir}/tree" -mindepth 1 -maxdepth 1 -not -name "${STAMP}" -type d -print0 | xargs --no-run-if-empty -0 rm -rf
- }
- # These versions used in dinstall
- function punew() {
- log "Doing automated p-u-new processing"
- cd "${queuedir}/p-u-new"
- punew_do "$1" "${queuedir}/p-u-new" "debian-release@lists.debian.org"
- }
- function opunew() {
- log "Doing automated o-p-u-new processing"
- cd "${queuedir}/o-p-u-new"
- punew_do "$1" "${queuedir}/o-p-u-new" "debian-release@lists.debian.org"
- }
- function backports_policy() {
- local queue="backports-policy"
- local qdir="/srv/backports-master.debian.org/queue/policy"
- local to="backports-team@debian.org"
- log "Doing automated ${queue} processing"
- cd "${qdir}"
- punew_do "${queue}" "${qdir}" "${to}"
- }
- # Do the unchecked processing, in case we have files.
- function do_unchecked () {
- cd $unchecked
- changes=$(find . -maxdepth 1 -mindepth 1 -type f \( -name \*.changes -o -name \*.dak-commands \) | sed -e "s,./,," | xargs)
- report=${queuedir}/REPORT
- timestamp=$(date "+%Y-%m-%d %H:%M")
- if [[ -n ${changes} ]]; then
- log "Processing files ${changes}"
- {
- echo "${timestamp}: ${changes}"
- dak process-upload -a -d "$unchecked"
- dak process-commands -d "$unchecked"
- } >> ${report}
- dak manage-external-signature-requests
- else
- log "Nothing to do"
- echo "Nothing to do" >> ${report}
- fi
- }
- function trigger_wb() {
- SSHOPT="-n -o BatchMode=yes -o ConnectTimeout=30 -o SetupTimeout=240"
- ssh -q -q ${SSHOPT} wbadm@buildd /srv/wanna-build/trigger.often
- }
- # process NEW policy queue
- function do_new () {
- log "Doing NEW processing"
- (dak process-policy new; dak process-policy byhand) | mail -a "X-Debian: DAK" -e -s "NEW and BYHAND processing" -a "From: Debian FTP Masters <ftpmaster@ftp-master.debian.org>" ftpmaster@ftp-master.debian.org
- log "Processing Backports NEW"
- dak process-policy backports-new | mail -a "X-Debian: DAK" -e -s "NEW processing for backports-new" -a "From: Debian FTP Masters <ftpmaster@ftp-master.debian.org>" backports-team@debian.org
- log "Cleanup NEW/Backports NEW"
- dak clean-suites -a new,backports-new
- }
- function sync_debbugs () {
- # sync with debbugs
- log "Sync debbugs version tracking information"
- timestamp=$(date "+%Y-%m-%d-%H:%M")
- mkdir -p $queuedir/bts_version_track_archive/${timestamp}
- rsync -aq $queuedir/bts_version_track/ $queuedir/bts_version_track_archive/${timestamp}
- rmdir --ignore-fail-on-non-empty $queuedir/bts_version_track_archive/${timestamp} # remove if empty.
- rsync -aq -e "ssh -o Batchmode=yes -o ConnectTimeout=30 -o SetupTimeout=30" --remove-source-files $queuedir/bts_version_track/ bugs-sync:/srv/bugs.debian.org/versions/queue/ftp-master/ 2>/dev/null && touch $lockdir/synced_bts_version || true
- NOW=$(date +%s)
- TSTAMP=$(stat -c %Y $lockdir/synced_bts_version)
- DIFF=$(( NOW - TSTAMP ))
- if [[ $DIFF -ge 259200 ]]; then
- log_error "Kids, you tried your best and you failed miserably. The lesson is, never try. (Homer Simpson)"
- fi
- }
- function clean_debbugs () {
- log "Cleanup debbugs"
- # Delete files older than 60 days
- find $queuedir/bts_version_track_archive/ -mtime +60 -type f -delete
- # Delete empty directories
- find $queuedir/bts_version_track_archive/ -empty -type d -delete
- }
- function reports() {
- # Send a report on NEW/BYHAND packages
- log "Nagging ftpteam about NEW/BYHAND packages"
- dak queue-report | mail -a "X-Debian: DAK" -e -s "NEW and BYHAND on $(date +%D)" -a "From: Debian FTP Masters <ftpmaster@ftp-master.debian.org>" ftpmaster@ftp-master.debian.org
- dak queue-report -d backports-new,backports-policy | mail -a "X-Debian: DAK" -e -s "NEW and POLICY on $(date +%D)" -a "From: Debian FTP Masters <ftpmaster@ftp-master.debian.org>" backports-team@debian.org
- # and one on crufty packages
- log "Sending information about crufty packages"
- dak cruft-report -R > $webdir/cruft-report-daily.txt.new
- dak cruft-report -R -s experimental >> $webdir/cruft-report-daily.txt.new
- echo "Page generated on $(date -u)" >> $webdir/cruft-report-daily.txt.new
- mv $webdir/cruft-report-daily.txt.new $webdir/cruft-report-daily.txt
- mail -a "X-Debian: DAK" -e -s "Debian archive cruft report for $(date +%D)" -a "From: Debian FTP Masters <ftpmaster@ftp-master.debian.org>" ftpmaster@ftp-master.debian.org < $webdir/cruft-report-daily.txt
- }
- function pg_timestamp() {
- tsname=${1:-"unknown"}
- log "Saving postgres transaction id for ${tsname}"
- psql -tAc 'select txid_current();' > $base/backup/txid_${tsname}_$(date +%Y.%m.%d-%H:%M:%S)
- }
- function get_archiveroot() {
- local archivename="$1"
- local query="SELECT path FROM archive WHERE name='${archivename}'"
- local archiveroot="$(psql -tAc "${query}")"
- if [[ -z ${archiveroot} ]]; then
- echo "get_archiveroot: couldn't get archiveroot for '${archivename}'" >&2
- return 1
- fi
- echo "${archiveroot}"
- }
- # Cleanup policy queues
- function cleanpolicy() {
- dak clean-suites -a backports-policy,policy
- }
- # Scan new packages for contents
- function scancontents() {
- dak contents -l 10000 scan-binary
- dak contents -l 1000 scan-source
- }
- function ddaccess() {
- # Tell our dd accessible mirror to sync itself up.
- log "Trigger dd accessible parts sync"
- ${scriptsdir}/sync-dd dd-sync dd-sync1 dd-sync2 sync
- }
- # Write ${path}/project/trace for given path
- # Note: use `write_project_trace` which sets version and date variables
- function write_project_trace1() {
- local path="${1}"
- local tracedir="${path}/project/trace"
- local TRACEFILE="${tracedir}/${functionname}"
- local TRACEFILE_MASTER="${tracedir}/master"
- local HIERFILE="${tracedir}/_hierarchy"
- mkdir -p -- "${tracedir}"
- local DATE_SERIAL=$(date +"%Y%m%d01")
- local FILESOAPLUS1=$(awk '/serial/ { print $3+1 }' ${TRACEFILE} || echo ${DATE_SERIAL} )
- local SERIAL
- if [[ ${DATE_SERIAL} -gt ${FILESOAPLUS1} ]]; then
- SERIAL="${DATE_SERIAL}"
- else
- SERIAL="${FILESOAPLUS1}"
- fi
- cat <<EOF > ${TRACEFILE}
- ${DATE}
- Creator: dak ${CREATOR_VERSION}
- Running on host: ${HOST}
- Archive serial: ${SERIAL}
- Date: ${RFC822DATE}
- Architectures: ${archs%* } source
- EOF
- cat <<EOF > ${HIERFILE}
- ${functionname} ${functionname} ${HOST} ${HOST}
- EOF
- cp ${HIERFILE} ${HIERFILE}.mirror
- # Now make it accessible via one name, no matter on which host we run
- ln -sf $(basename ${TRACEFILE}) ${TRACEFILE_MASTER}
- }
- # Write ${path}/project/trace for given paths
- function write_project_trace() {
- cd ${configdir}
- local CREATOR_VERSION="g$(git rev-parse --short HEAD)"
- local DATE=$(LC_ALL=POSIX LANG=POSIX date -u)
- local RFC822DATE=$(LC_ALL=POSIX LANG=POSIX date -u -R)
- local HOST=$(hostname -f)
- local path
- for path in "${@}"; do
- write_project_trace1 "${path}"
- done
- }
- function fingerprints() {
- log "Updating fingerprints"
- local todo=${1:-all}
- dak import-keyring -L /srv/keyring.debian.org/keyrings/debian-keyring.gpg
- if [[ ${todo} == all ]]; then
- dak import-keyring -L /srv/keyring.debian.org/keyrings/debian-nonupload.gpg
- OUTFILE=$( gettempfile )
- dak import-keyring --generate-users "%s" /srv/keyring.debian.org/keyrings/debian-maintainers.gpg >"${OUTFILE}"
- if [[ -s ${OUTFILE} ]]; then
- /usr/sbin/sendmail -odq -oi -t -f envelope@ftp-master.debian.org <<EOF
- From: Debian FTP Masters <ftpmaster@ftp-master.debian.org>
- To: <debian-project@lists.debian.org>
- Subject: Debian Maintainers Keyring changes
- Content-Type: text/plain; charset=utf-8
- X-Debian: DAK
- MIME-Version: 1.0
- The following changes to the debian-maintainers keyring have just been activated:
- $(cat $OUTFILE)
- Debian distribution maintenance software,
- on behalf of the Keyring maintainers
- EOF
- fi
- rm -f "$OUTFILE"
- fi
- }
- function dakcleanup() {
- log "Cleanup old packages/files"
- local queuevarnames=${1:-unchecked}
- dak clean-suites -m 10000
- for queue in ${queuevarnames}; do
- dak clean-queues -i ${!queue}
- done
- }
- function mklslar() {
- local archiveroot
- local FILENAME=ls-lR
- for archive in "${public_archives[@]}"; do
- archiveroot="$(get_archiveroot "${archive}")"
- cd "${archiveroot}"
- log "Removing any core files ..."
- find -type f -name core -print -delete
- log "Checking symlinks ..."
- symlinks -rd .
- log "Creating recursive directory listing ... "
- rm -f ${FILENAME}.gz
- TZ=UTC ls -lR | gzip -9c --rsyncable --no-name > ${FILENAME}.gz
- done
- }
- function linkmorgue() {
- ${scriptsdir}/link_morgue.sh
- }
- function fetchqueuedpackages() {
- local host=$1
- # Sync new uploaded packages from the central upload queue host.
- log "Sync new uploads from upload queues"
- cd ${unchecked}
- rsync -rtq --safe-links --chmod=F640,D755 --remove-source-files $1:/does/not/matter . || true
- }
- ########################################################################
- ########################################################################
- ########################################################################
- ########################################################################
- # Function to save which stage we are in, so we can restart an interrupted
- # dinstall. Or even run actions in parallel, if we dare to, by simply
- # backgrounding the call to this function. But that should only really be
- # done for things we don't care much about.
- #
- # This should be called with the first argument being an array, with the
- # members
- # - FUNC - the function name to call
- # - ARGS - Possible arguments to hand to the function. Can be the empty string
- # - TIME - The timestamp name. Can be the empty string
- # - ERR - if this is the string false, then the call will be surrounded by
- # set +e ... set -e calls, so errors in the function do not exit
- # dinstall. Can be the empty string, meaning true.
- #
- # MAKE SURE TO KEEP THIS THE LAST FUNCTION, AFTER ALL THE VARIOUS ONES
- # ADDED FOR DINSTALL FEATURES!
- function stage() {
- ARGS='GO[@]'
- local "${!ARGS}"
- local error=${ERR:-"true"}
- ARGS=${ARGS:-""}
- log "########## ${PROGRAM} BEGIN: ${FUNC} ${ARGS} ##########"
- local STAGEFILE="${stagedir}/${FUNC}${ARGS:+_}${ARGS}"
- STAGEFILE=${STAGEFILE// /_}
- if [[ -f ${STAGEFILE} ]]; then
- local stamptime=$(/usr/bin/stat -c %Z "${STAGEFILE}")
- local unixtime=$(date +%s)
- local difference=$(( unixtime - stamptime ))
- if [[ ${difference} -ge 14400 ]]; then
- log_error "Did already run ${FUNC}, stagefile exists, but that was ${difference} seconds ago. Please check."
- else
- log "Did already run ${FUNC}, not calling again..."
- fi
- return
- fi
- debug "Now calling function ${FUNC}. Arguments: ${ARGS}. Timestamp: ${TIME}"
- # Make sure we are always at the same place. If a function wants
- # to be elsewhere, it has to cd first!
- cd ${configdir}
- if [[ -f ${LOCK_STOP} ]]; then
- log "${LOCK_STOP} exists, exiting immediately"
- exit 42
- fi
- # Do we care about trouble in the function we call?
- if [[ ${error} == false ]]; then
- set +e
- fi
- # Now redirect the output into $STAGEFILE.log. In case it errors
- # out somewhere our errorhandler trap can then mail the contents
- # of $STAGEFILE.log only, instead of a whole ${PROGRAM} logfile.
- # Short error mails ftw!
- if [[ ${TIMESTAMP} == true ]]; then
- ${FUNC} ${ARGS} 2>&1 | tee -a "${STAGEFILE}.log" | ts "%b %d %H:%M:%S ${HOSTNAME} ${PROGRAM}[$$]: ${FUNC} "
- else
- ${FUNC} ${ARGS} 2>&1 | tee -a "${STAGEFILE}.log"
- fi
- # No matter what happened in the function, we make sure we have
- # set -e default state back
- set -e
- # Make sure we are always at the same place.
- cd ${configdir}
- # We always use the same umask. If a function wants to do
- # different, fine, but we reset.
- umask 022
- touch "${STAGEFILE}"
- if [[ -n ${TIME} ]]; then
- log_timestamp "${TIME}"
- fi
- rm -f "${STAGEFILE}.log"
- log "########## ${PROGRAM} END: ${FUNC} ##########"
- if [[ -f ${LOCK_STOP} ]]; then
- log "${LOCK_STOP} exists, exiting immediately"
- exit 42
- fi
- }
|