if [ -f $m ]; then
mv $m ${m}-$DATE
sleep 20
- gzip -9 ${m}-$DATE
- chgrp backports ${m}-$DATE.gz
- chmod 660 ${m}-$DATE.gz
+ xz -9 ${m}-$DATE
+ chgrp backports ${m}-$DATE.xz
+ chmod 660 ${m}-$DATE.xz
fi;
done
};
KeyServer "wwwkeys.eu.pgp.net";
};
+
+Changelogs
+{
+ Export "/srv/backports-master.debian.org/export/changelogs";
+}
Action start: ${RIGHTNOW}
EOF
}
+
+# extract changelogs and stuff
+function changelogs() {
+ log "Extracting changelogs"
+ dak make-changelog -e
+ mkdir -p ${exportpublic}/changelogs
+ cd ${exportpublic}/changelogs
+ rsync -aHW --delete --delete-after --ignore-errors ${exportdir}/changelogs/. .
+}
# locations used by many scripts
base=/srv/backports-master.debian.org
+public=/srv/backports-web.debian.org
bindir=$base/bin
ftpdir=$base/ftp/
indices=$ftpdir/indices
-webdir=/srv/backports-web.debian.org/underlay/
+webdir=$public/underlay/
scriptdir=$base/scripts
archs="alpha amd64 arm armel hppa hurd-i386 i386 ia64 mips mipsel powerpc s390 sparc kfreebsd-i386 kfreebsd-amd64 "
logdir=$base/log/cron/
mirrordir=$base/mirror/
newstage=$queuedir/newstage/
+exportdir=$base/export/
+exportpublic=$public/export/
ftpgroup=debadmin
ts "locked part finished"
state "postlock"
+GO=(
+ FUNC="changelogs"
+ TIME="changelogs"
+ ARGS=""
+ ERR="false"
+)
+stage $GO &
+
GO=(
FUNC="pgdump_post"
TIME="pg_dump2"
chown dak:ftpteam ${m}
chmod 660 ${m}
sleep 20
- gzip -9 ${m}-$DATE
- chgrp $ftpgroup ${m}-$DATE.gz
- chmod 660 ${m}-$DATE.gz
+ xz -9 ${m}-$DATE
+ chgrp $ftpgroup ${m}-$DATE.xz
+ chmod 660 ${m}-$DATE.xz
fi;
done
Action start: ${RIGHTNOW}
EOF
}
+
+# extract changelogs and stuff
+function changelogs() {
+ log "Extracting changelogs"
+ dak make-changelog -e
+ mkdir -p ${exportpublic}/changelogs
+ cd ${exportpublic}/changelogs
+ rsync -aHW --delete --delete-after --ignore-errors ${exportdir}/changelogs/. .
+}
mirrordir=$base/mirror/
incoming=$base/incoming
newstage=$queuedir/newstage/
+exportdir=$base/export/
+exportpublic=$public/rsync/export/
ftpgroup=debadmin
--- /dev/null
+# ~/.bash_logout: executed by bash(1) when login shell exits.
+
+# when leaving the console clear the screen to increase privacy
+
+if [ "$SHLVL" = 1 ]; then
+ [ -x /usr/bin/clear_console ] && /usr/bin/clear_console -q
+fi
--- /dev/null
+.bashrc
\ No newline at end of file
--- /dev/null
+# bashrc for dak user
+
+# If not running interactively, don't do anything
+[ -z "$PS1" ] && return
+
+
+# append to the history file, don't overwrite it
+shopt -s histappend
+export HISTCONTROL=ignoreboth
+
+# check the window size after each command and, if necessary,
+# update the values of LINES and COLUMNS.
+shopt -s checkwinsize
+
+# make less more friendly for non-text input files, see lesspipe(1)
+[ -x /usr/bin/lesspipe ] && eval "$(SHELL=/bin/sh lesspipe)"
+
+## A little nice prompt.
+PS1='`_ret=$?; if test $_ret -ne 0; then echo "\[\033[01;31m\]$_ret "; set ?=$_ret; unset _ret; fi`\[\033[01;33m\][`git branch 2>/dev/null|cut -f2 -d\* -s` ] \[\033[01;32m\]\u@\[\033[00;36m\]\h\[\033[01m\]:\[\033[00;37m\]\w\[\033[00m\]\$ '
+
+# If this is an xterm set the title to user@host:dir
+case "$TERM" in
+xterm*|rxvt*)
+ PS1="\[\e]0;\u@\h: \w\a\]$PS1"
+ ;;
+*)
+ ;;
+esac
+
+case "$HOSTNAME" in
+ franck)
+ export SCRIPTVARS=/srv/ftp-master.debian.org/dak/config/debian/vars
+ ;;
+ morricone)
+ export SCRIPTVARS=/srv/backports-master.debian.org/dak/config/backports/vars
+ ;;
+ chopin|ries)
+ export SCRIPTVARS=/srv/security-master.debian.org/dak/config/debian-security/vars
+ ;;
+ *)
+ echo "Unconfigured dak host, not importing the usual vars"
+ ;;
+esac
+
+. $SCRIPTVARS
+
+function emacs() {
+ export EDITOR=$(which emacs)
+}
+
+export PAGER=less
+export LESS="-X"
+export EDITOR=$(which vim)
+export HISTFILESIZE=6000
+export GREP_OPTIONS="--color=auto"
+export CDPATH=".:~:${base}:${public}:${queuedir}"
+
+alias base='cd ${base}'
+alias config='cd ${configdir}'
--- /dev/null
+(custom-set-variables
+ ;; custom-set-variables was added by Custom -- don't edit or cut/paste it!
+ ;; Your init file should contain only one such instance.
+ '(global-font-lock-mode t nil (font-lock))
+ '(show-trailing-whitespace t))
+(custom-set-faces
+ ;; custom-set-faces was added by Custom -- don't edit or cut/paste it!
+ ;; Your init file should contain only one such instance.
+ )
--- /dev/null
+#
+# System configuration file for Mutt
+#
+
+# default list of header fields to weed when displaying
+#
+ignore "from " received content- mime-version status x-status message-id
+ignore sender references return-path lines
+ignore date delivered-to precedence errors-to in-reply-to user-agent
+ignore x-loop x-sender x-mailer x-msmail-priority x-mimeole x-priority
+ignore x-accept-language x-authentication-warning
+
+# emacs-like bindings
+bind editor "\e<delete>" kill-word
+bind editor "\e<backspace>" kill-word
+
+# map delete-char to a sane value
+bind editor <delete> delete-char
+
+# don't add the hostname to the From header
+unset use_domain
+# don't generate a From header
+unset use_from
+
+# Specifies how to sort messages in the index menu.
+set sort=threads
+
+# Exim does not remove Bcc headers
+unset write_bcc
+# Postfix and qmail use Delivered-To for detecting loops
+unset bounce_delivered
+
+# imitate the old search-body function
+macro index \eb '/~b ' 'search in message bodies'
+
+# simulate the old url menu
+macro index \cb |urlview\n 'call urlview to extract URLs out of a message'
+macro pager \cb |urlview\n 'call urlview to extract URLs out of a message'
+
+# Show documentation when pressing F1
+macro generic <f1> "!zless /usr/share/doc/mutt/manual.txt.gz\n" "Show Mutt documentation"
+macro index <f1> "!zless /usr/share/doc/mutt/manual.txt.gz\n" "Show Mutt documentation"
+macro pager <f1> "!zless /usr/share/doc/mutt/manual.txt.gz\n" "Show Mutt documentation"
+
+# Use folders which match on \\.gz$ as gzipped folders:
+open-hook \\.gz$ "gzip -cd %f > %t"
+close-hook \\.gz$ "gzip -c %t > %f"
+append-hook \\.gz$ "gzip -c %t >> %f"
+
+# Use folders which match on \\.xz$ as xz compressed folders:
+open-hook \\.xz$ "xz -cd %f > %t"
+close-hook \\.xz$ "xz -c %t > %f"
+append-hook \\.xz$ "xz -c %t >> %f"
+
+# colors
+color normal white black
+color attachment brightyellow black
+color hdrdefault cyan black
+color indicator black cyan
+color markers brightred black
+color quoted green black
+color signature cyan black
+color status brightgreen blue
+color tilde blue black
+color tree red black
+
+# aliases for broken MUAs
+charset-hook windows-1250 CP1250
+charset-hook windows-1251 CP1251
+charset-hook windows-1252 CP1252
+charset-hook windows-1253 CP1253
+charset-hook windows-1254 CP1254
+charset-hook windows-1255 CP1255
+charset-hook windows-1256 CP1256
+charset-hook windows-1257 CP1257
+charset-hook windows-1258 CP1258
+
+##
+## More settings
+##
+set ispell=ispell
+
+# GnuPG configuration
+set pgp_decode_command="/usr/bin/gpg --status-fd=2 %?p?--passphrase-fd 0? --no-verbose --quiet --batch --output - %f"
+set pgp_verify_command="/usr/bin/gpg --status-fd=2 --no-verbose --quiet --batch --output - --verify %s %f"
+set pgp_decrypt_command="/usr/bin/gpg --status-fd=2 --passphrase-fd 0 --no-verbose --quiet --batch --output - %f"
+set pgp_sign_command="/usr/bin/gpg --no-verbose --batch --quiet --output - --passphrase-fd 0 --armor --detach-sign --textmode %?a?-u %a? %f"
+set pgp_clearsign_command="/usr/bin/gpg --no-verbose --batch --quiet --output - --passphrase-fd 0 --armor --textmode --clearsign %?a?-u %a? %f"
+set pgp_encrypt_only_command="/usr/lib/mutt/pgpewrap /usr/bin/gpg --batch --quiet --no-verbose --output - --encrypt --textmode --armor --always-trust -- -r %r -- %f"
+set pgp_encrypt_sign_command="/usr/lib/mutt/pgpewrap /usr/bin/gpg --passphrase-fd 0 --batch --quiet --no-verbose --textmode --output - --encrypt --sign %?a?-u %a? --armor --always-trust -- -r %r -- %f"
+set pgp_import_command="/usr/bin/gpg --no-verbose --import -v %f"
+set pgp_export_command="/usr/bin/gpg --no-verbose --export --armor %r"
+set pgp_verify_key_command="/usr/bin/gpg --verbose --batch --fingerprint --check-sigs %r"
+set pgp_list_pubring_command="/usr/bin/gpg --no-verbose --batch --quiet --with-colons --list-keys %r"
+set pgp_list_secring_command="/usr/bin/gpg --no-verbose --batch --quiet --with-colons --list-secret-keys %r"
+set pgp_good_sign="^\\[GNUPG:\\] VALIDSIG"
+
+set nomove
+bind pager <up> previous-line
+bind pager <down> next-line
+bind index <up> previous-entry
+bind index <down> next-entry
+bind index <left> previous-entry
+bind index <right> next-entry
+bind pager <left> previous-entry
+bind pager <right> next-entry
+bind pager $ bottom
+bind index <tab> next-unread
+bind index \c? search-reverse
+bind index \c\\ search-opposite
+set edit_hdrs
+set xterm_set_titles
+
+ignore *
+unignore date from to cc subject x-mailer resent-from reply-to mail-followup-to
+
+set index_format="%4C %Z %(%b%d %H) %-15.15L (%?l?%4l&%4c?) %s"
+
+set folder=~/mail
+
+unset confirmappend
+
+my_hdr From: Archive Administrator <ftpmaster@debian.org>
+
+macro index s <save-message>=
+
+set tmpdir="/tmp"
+
+macro index s <save-message>=
+macro index c <change-folder>=
+macro pager s <save-message>=
+macro pager c <change-folder>=
+
+set index_format="%4C %Z %(%b%d %H) %-15.15L (%?l?%4l&%4c?) %s"
+
+
+set delete=yes
+unset confirmappend
+
+set implicit_autoview
+auto_view text/html
+
+set pager_stop
+set wrap_search # Wrap search to top/bottom.
+set smart_wrap # wrap long lines at word boundary.
+set tilde # Internal Pager: ~~~~ at and of message?
+
+set pager_context=3
+set pager_index_lines=9 # number of lines to see from the index
+set pgp_timeout=60 # number of seconds to cache passphrase
+
+set mail_check=1
+set timeout=1
+
+set beep
+set beep_new
+set fast_reply
+set metoo
--- /dev/null
+# if running bash
+if [ -n "$BASH_VERSION" ]; then
+ # include .bashrc if it exists
+ if [ -f "$HOME/.bashrc" ]; then
+ . "$HOME/.bashrc"
+ fi
+fi
+
+# set PATH so it includes user's private bin if it exists
+if [ -d "$HOME/bin" ] ; then
+ PATH="$HOME/bin:$PATH"
+fi
--- /dev/null
+\set HISTSIZE 12000
--- /dev/null
+#!/usr/bin/env python
+# coding=utf8
+
+"""
+Add processed field to changes_pending_files
+
+@contact: Debian FTP Master <ftpmaster@debian.org>
+@copyright: 2010 Mark Hymers <mhy@debian.org>
+@license: GNU General Public License version 2 or later
+"""
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+################################################################################
+
+
+################################################################################
+
+import psycopg2
+from daklib.dak_exceptions import DBUpdateError
+
+################################################################################
+def do_update(self):
+ """
+ Add processed field to changes_pending_files
+ """
+ print __doc__
+ try:
+ c = self.db.cursor()
+ c.execute('ALTER TABLE changes_pending_files ADD COLUMN processed BOOL DEFAULT FALSE')
+ c.execute("UPDATE config SET value = '36' WHERE name = 'db_revision'")
+ self.db.commit()
+
+ except psycopg2.ProgrammingError, msg:
+ self.db.rollback()
+ raise DBUpdateError, 'Unable to apply build_queue update 36, rollback issued. Error message : %s' % (str(msg))
return new
-################################################################################
-
-def edit_note(note, upload, session):
- # Write the current data to a temporary file
- (fd, temp_filename) = utils.temp_filename()
- editor = os.environ.get("EDITOR","vi")
- answer = 'E'
- while answer == 'E':
- os.system("%s %s" % (editor, temp_filename))
- temp_file = utils.open_file(temp_filename)
- newnote = temp_file.read().rstrip()
- temp_file.close()
- print "New Note:"
- print utils.prefix_multi_line_string(newnote," ")
- prompt = "[D]one, Edit, Abandon, Quit ?"
- answer = "XXX"
- while prompt.find(answer) == -1:
- answer = utils.our_raw_input(prompt)
- m = re_default_answer.search(prompt)
- if answer == "":
- answer = m.group(1)
- answer = answer[:1].upper()
- os.unlink(temp_filename)
- if answer == 'A':
- return
- elif answer == 'Q':
- end()
- sys.exit(0)
-
- comment = NewComment()
- comment.package = upload.pkg.changes["source"]
- comment.version = upload.pkg.changes["version"]
- comment.comment = newnote
- comment.author = utils.whoami()
- comment.trainee = bool(Options["Trainee"])
- session.add(comment)
- session.commit()
################################################################################
################################################################################
-def prod_maintainer (notes, upload):
- cnf = Config()
- # Here we prepare an editor and get them ready to prod...
- (fd, temp_filename) = utils.temp_filename()
- temp_file = os.fdopen(fd, 'w')
- for note in notes:
- temp_file.write(note.comment)
- temp_file.close()
- editor = os.environ.get("EDITOR","vi")
- answer = 'E'
- while answer == 'E':
- os.system("%s %s" % (editor, temp_filename))
- temp_fh = utils.open_file(temp_filename)
- prod_message = "".join(temp_fh.readlines())
- temp_fh.close()
- print "Prod message:"
- print utils.prefix_multi_line_string(prod_message," ",include_blank_lines=1)
- prompt = "[P]rod, Edit, Abandon, Quit ?"
- answer = "XXX"
- while prompt.find(answer) == -1:
- answer = utils.our_raw_input(prompt)
- m = re_default_answer.search(prompt)
- if answer == "":
- answer = m.group(1)
- answer = answer[:1].upper()
- os.unlink(temp_filename)
- if answer == 'A':
- return
- elif answer == 'Q':
- end()
- sys.exit(0)
- # Otherwise, do the proding...
- user_email_address = utils.whoami() + " <%s>" % (
- cnf["Dinstall::MyAdminAddress"])
-
- Subst = upload.Subst
-
- Subst["__FROM_ADDRESS__"] = user_email_address
- Subst["__PROD_MESSAGE__"] = prod_message
- Subst["__CC__"] = "Cc: " + cnf["Dinstall::MyEmailAddress"]
-
- prod_mail_message = utils.TemplateSubst(
- Subst,cnf["Dir::Templates"]+"/process-new.prod")
-
- # Send the prod mail
- utils.send_mail(prod_mail_message)
-
- print "Sent proding message"
-
-################################################################################
-
def do_new(upload, session):
print "NEW\n"
files = upload.pkg.files
done = 0
while not done:
# Find out what's new
- new = determine_new(changes, files)
+ new, byhand = determine_new(upload.pkg.changes_file, changes, files, session=session)
if not new:
break
done = 0
while not done:
files = upload.pkg.files
- will_install = 1
+ will_install = True
byhand = []
for f in files.keys():
- if files[f]["type"] == "byhand":
+ if files[f]["section"] == "byhand":
if os.path.exists(f):
print "W: %s still present; please process byhand components and try again." % (f)
- will_install = 0
+ will_install = False
else:
byhand.append(f)
answer = answer[:1].upper()
if answer == 'A':
- try:
- check_daily_lock()
- done = 1
- for f in byhand:
- del files[f]
- Logger.log(["BYHAND ACCEPT: %s" % (upload.pkg.changes_file)])
- except CantGetLockError:
- print "Hello? Operator! Give me the number for 911!"
- print "Dinstall in the locked area, cant process packages, come back later"
+ dbchg = get_dbchange(upload.pkg.changes_file, session)
+ if dbchg is None:
+ print "Warning: cannot find changes file in database; can't process BYHAND"
+ else:
+ try:
+ check_daily_lock()
+ done = 1
+ for b in byhand:
+ # Find the file entry in the database
+ found = False
+ for f in dbchg.files:
+ if f.filename == b:
+ found = True
+ f.processed = True
+ break
+
+ if not found:
+ print "Warning: Couldn't find BYHAND item %s in the database to mark it processed" % b
+
+ session.commit()
+ Logger.log(["BYHAND ACCEPT: %s" % (upload.pkg.changes_file)])
+ except CantGetLockError:
+ print "Hello? Operator! Give me the number for 911!"
+ print "Dinstall in the locked area, cant process packages, come back later"
elif answer == 'M':
- Logger.log(["BYHAND REJECT: %s" % (upload.pkg.changes_file)])
- upload.do_reject(manual=1, reject_message=Options["Manual-Reject"])
- upload.pkg.remove_known_changes(session=session)
- session.commit()
- done = 1
+ aborted = upload.do_reject(manual=1,
+ reject_message=Options["Manual-Reject"],
+ notes=get_new_comments(changes.get("source", ""), session=session))
+ if not aborted:
+ upload.pkg.remove_known_changes(session=session)
+ session.commit()
+ Logger.log(["BYHAND REJECT: %s" % (upload.pkg.changes_file)])
+ done = 1
elif answer == 'S':
done = 1
elif answer == 'Q':
os.unlink(os.path.join(h.holding_dir, f))
-def do_pkg(changes_file, session):
- new_queue = get_policy_queue('new', session );
+def do_pkg(changes_full_path, session):
+ changes_dir = os.path.dirname(changes_full_path)
+ changes_file = os.path.basename(changes_full_path)
+
u = Upload()
u.pkg.changes_file = changes_file
(u.pkg.changes["fingerprint"], rejects) = utils.check_signature(changes_file)
u.load_changes(changes_file)
- u.pkg.directory = new_queue.path
+ u.pkg.directory = changes_dir
u.update_subst()
u.logger = Logger
origchanges = os.path.abspath(u.pkg.changes_file)
if not recheck(u, session):
return
- # FIXME: This does need byhand checks added!
- new = determine_new(u.pkg.changes, files)
- if new:
+ new, byhand = determine_new(u.pkg.changes_file, u.pkg.changes, files, session=session)
+ if byhand:
+ do_byhand(u, session)
+ elif new:
do_new(u, session)
else:
try:
changes_files = apt_pkg.ParseCommandLine(cnf.Cnf,Arguments,sys.argv)
if len(changes_files) == 0:
new_queue = get_policy_queue('new', session );
- changes_files = utils.get_changes_files(new_queue.path)
+ changes_paths = [ os.path.join(new_queue.path, j) for j in utils.get_changes_files(new_queue.path) ]
+ else:
+ changes_paths = [ os.path.abspath(j) for j in changes_files ]
Options = cnf.SubTree("Process-New::Options")
Priorities = Priority_Completer(session)
readline.parse_and_bind("tab: complete")
- if len(changes_files) > 1:
+ if len(changes_paths) > 1:
sys.stderr.write("Sorting changes...\n")
- changes_files = sort_changes(changes_files, session)
+ changes_files = sort_changes(changes_paths, session)
- for changes_file in changes_files:
+ for changes_file in changes_paths:
changes_file = utils.validate_changes_file_arg(changes_file, 0)
if not changes_file:
continue
- print "\n" + changes_file
+ print "\n" + os.path.basename(changes_file)
do_pkg (changes_file, session)
u.check_source_against_db(deb_filename, session)
u.pkg.changes["suite"] = u.pkg.changes["distribution"]
- new = determine_new(u.pkg.changes, files, 0, session)
+ new, byhand = determine_new(u.pkg.changes_file, u.pkg.changes, files, 0, session)
htmlname = changes["source"] + "_" + changes["version"] + ".html"
sources.add(htmlname)
################################################################################
Cnf = None
-required_database_schema = 35
+required_database_schema = 36
################################################################################
for f in chg.files:
# update the changes_pending_files row
f.queue = destqueue
- utils.move(os.path.join(srcqueue.path, f.filename), destqueue.path, perms=int(destqueue.perms, 8))
+ # Only worry about unprocessed files
+ if not f.processed:
+ utils.move(os.path.join(srcqueue.path, f.filename), destqueue.path, perms=int(destqueue.perms, 8))
utils.move(os.path.join(srcqueue.path, upload.pkg.changes_file), destqueue.path, perms=int(destqueue.perms, 8))
chg.in_queue = destqueue
else:
# Just a normal upload, accept it...
(summary, short_summary) = upload.build_summaries()
- srcqueue = get_policy_queue('new', session)
destqueue = get_policy_queue('newstage', session)
+ srcqueue = get_policy_queue_from_path(upload.pkg.directory, session)
+
+ if not srcqueue:
+ # Assume NEW and hope for the best
+ srcqueue = get_policy_queue('new', session)
+
changes_to_queue(upload, srcqueue, destqueue, session)
__all__.append('new_accept')
__all__.append('get_policy_queue')
+@session_wrapper
+def get_policy_queue_from_path(pathname, session=None):
+ """
+ Returns PolicyQueue object for given C{path name}
+
+ @type queuename: string
+ @param queuename: The path
+
+ @type session: Session
+ @param session: Optional SQLA session object (a temporary one will be
+ generated if not supplied)
+
+ @rtype: PolicyQueue
+ @return: PolicyQueue object for the given queue
+ """
+
+ q = session.query(PolicyQueue).filter_by(path=pathname)
+
+ try:
+ return q.one()
+ except NoResultFound:
+ return None
+
+__all__.append('get_policy_queue_from_path')
+
################################################################################
class Priority(object):
# Determine what parts in a .changes are NEW
-def determine_new(changes, files, warn=1, session = None):
+def determine_new(filename, changes, files, warn=1, session = None):
"""
Determine what parts in a C{changes} file are NEW.
+ @type filename: str
+ @param filename: changes filename
+
@type changes: Upload.Pkg.changes dict
@param changes: Changes dictionary
@return: dictionary of NEW components.
"""
+ # TODO: This should all use the database instead of parsing the changes
+ # file again
new = {}
+ byhand = {}
+
+ dbchg = get_dbchange(filename, session)
+ if dbchg is None:
+ print "Warning: cannot find changes file in database; won't check byhand"
# Build up a list of potentially new things
for name, f in files.items():
- # Skip byhand elements
-# if f["type"] == "byhand":
-# continue
+ # Keep a record of byhand elements
+ if f["section"] == "byhand":
+ byhand[name] = 1
+ continue
+
pkg = f["package"]
priority = f["priority"]
section = f["section"]
del changes["suite"][suite]
changes["suite"][override] = 1
+ # Check for unprocessed byhand files
+ if dbchg is not None:
+ for b in byhand.keys():
+ # Find the file entry in the database
+ found = False
+ for f in dbchg.files:
+ if f.filename == b:
+ found = True
+ # If it's processed, we can ignore it
+ if f.processed:
+ del byhand[b]
+ break
+
+ if not found:
+ print "Warning: Couldn't find BYHAND item %s in the database; assuming unprocessed"
+
+ # Check for new stuff
for suite in changes["suite"].keys():
for pkg in new.keys():
ql = get_override(pkg, suite, new[pkg]["component"], new[pkg]["type"], session)
if new[pkg].has_key("othercomponents"):
print "WARNING: %s already present in %s distribution." % (pkg, new[pkg]["othercomponents"])
- return new
+ return new, byhand
################################################################################
###############################################################################
+def prod_maintainer(notes, upload):
+ cnf = Config()
+
+ # Here we prepare an editor and get them ready to prod...
+ (fd, temp_filename) = utils.temp_filename()
+ temp_file = os.fdopen(fd, 'w')
+ for note in notes:
+ temp_file.write(note.comment)
+ temp_file.close()
+ editor = os.environ.get("EDITOR","vi")
+ answer = 'E'
+ while answer == 'E':
+ os.system("%s %s" % (editor, temp_filename))
+ temp_fh = utils.open_file(temp_filename)
+ prod_message = "".join(temp_fh.readlines())
+ temp_fh.close()
+ print "Prod message:"
+ print utils.prefix_multi_line_string(prod_message," ",include_blank_lines=1)
+ prompt = "[P]rod, Edit, Abandon, Quit ?"
+ answer = "XXX"
+ while prompt.find(answer) == -1:
+ answer = utils.our_raw_input(prompt)
+ m = re_default_answer.search(prompt)
+ if answer == "":
+ answer = m.group(1)
+ answer = answer[:1].upper()
+ os.unlink(temp_filename)
+ if answer == 'A':
+ return
+ elif answer == 'Q':
+ end()
+ sys.exit(0)
+ # Otherwise, do the proding...
+ user_email_address = utils.whoami() + " <%s>" % (
+ cnf["Dinstall::MyAdminAddress"])
+
+ Subst = upload.Subst
+
+ Subst["__FROM_ADDRESS__"] = user_email_address
+ Subst["__PROD_MESSAGE__"] = prod_message
+ Subst["__CC__"] = "Cc: " + cnf["Dinstall::MyEmailAddress"]
+
+ prod_mail_message = utils.TemplateSubst(
+ Subst,cnf["Dir::Templates"]+"/process-new.prod")
+
+ # Send the prod mail
+ utils.send_mail(prod_mail_message)
+
+ print "Sent prodding message"
+
+################################################################################
+
+def edit_note(note, upload, session):
+ # Write the current data to a temporary file
+ (fd, temp_filename) = utils.temp_filename()
+ editor = os.environ.get("EDITOR","vi")
+ answer = 'E'
+ while answer == 'E':
+ os.system("%s %s" % (editor, temp_filename))
+ temp_file = utils.open_file(temp_filename)
+ newnote = temp_file.read().rstrip()
+ temp_file.close()
+ print "New Note:"
+ print utils.prefix_multi_line_string(newnote," ")
+ prompt = "[D]one, Edit, Abandon, Quit ?"
+ answer = "XXX"
+ while prompt.find(answer) == -1:
+ answer = utils.our_raw_input(prompt)
+ m = re_default_answer.search(prompt)
+ if answer == "":
+ answer = m.group(1)
+ answer = answer[:1].upper()
+ os.unlink(temp_filename)
+ if answer == 'A':
+ return
+ elif answer == 'Q':
+ end()
+ sys.exit(0)
+
+ comment = NewComment()
+ comment.package = upload.pkg.changes["source"]
+ comment.version = upload.pkg.changes["version"]
+ comment.comment = newnote
+ comment.author = utils.whoami()
+ comment.trainee = bool(Options["Trainee"])
+ session.add(comment)
+ session.commit()
+
+###############################################################################
+
class Upload(object):
"""
Everything that has to do with an upload processed.
session = DBConn().session()
self.check_source_against_db(dsc_filename, session)
self.check_dsc_against_db(dsc_filename, session)
- session.close()
+
+ dbchg = get_dbchange(self.pkg.changes_file, session)
# Finally, check if we're missing any files
for f in self.later_check_files:
- self.rejects.append("Could not find file %s references in changes" % f)
+ print 'XXX: %s' % f
+ # Check if we've already processed this file if we have a dbchg object
+ ok = False
+ if dbchg:
+ for pf in dbchg.files:
+ if pf.filename == f and pf.processed:
+ self.notes.append('%s was already processed so we can go ahead' % f)
+ ok = True
+ del self.pkg.files[f]
+ if not ok:
+ self.rejects.append("Could not find file %s references in changes" % f)
+
+ session.close()
return True
# Statically handled queues
target = None
- for q in ["new", "autobyhand", "byhand"]:
+ for q in ["autobyhand", "byhand", "new"]:
if QueueInfo[q]["is"](u):
target = q
break