# coding=utf8
"""
-Adding table to get rid of queue/done checks
+Add policy queue handling support
@contact: Debian FTP Master <ftpmaster@debian.org>
-@copyright: 2009 Joerg Jaspert <joerg@debian.org>
+@copyright: 2009 Mark Hymers <mhy@debian.org>
@license: GNU General Public License version 2 or later
"""
import time
import os
import datetime
-from daklib.dak_exceptions import DBUpdateError, InvalidDscError, ChangesUnicodeError
-from daklib.config import Config
-from daklib.utils import parse_changes, warn, gpgv_get_status_output, process_gpgv_output
-
-################################################################################
+import traceback
-def check_signature (sig_filename, data_filename=""):
- keyrings = [
- "/home/joerg/keyring/keyrings/debian-keyring.gpg",
- "/home/joerg/keyring/keyrings/debian-keyring.pgp",
- "/home/joerg/keyring/keyrings/debian-maintainers.gpg",
- "/home/joerg/keyring/keyrings/debian-role-keys.gpg",
- "/home/joerg/keyring/keyrings/emeritus-keyring.pgp",
- "/home/joerg/keyring/keyrings/emeritus-keyring.gpg",
- "/home/joerg/keyring/keyrings/removed-keys.gpg",
- "/home/joerg/keyring/keyrings/removed-keys.pgp"
- ]
-
- keyringargs = " ".join(["--keyring %s" % x for x in keyrings ])
-
- # Build the command line
- status_read, status_write = os.pipe()
- cmd = "gpgv --status-fd %s %s %s" % (status_write, keyringargs, sig_filename)
-
- # Invoke gpgv on the file
- (output, status, exit_status) = gpgv_get_status_output(cmd, status_read, status_write)
-
- # Process the status-fd output
- (keywords, internal_error) = process_gpgv_output(status)
-
- # If we failed to parse the status-fd output, let's just whine and bail now
- if internal_error:
- warn("Couldn't parse signature")
- return (None, rejects)
-
- # usually one would check for bad things here. We, however, do not care.
-
- # Next check gpgv exited with a zero return code
- if exit_status:
- warn("Couldn't parse signature")
- return (None, rejects)
-
- # Sanity check the good stuff we expect
- if not keywords.has_key("VALIDSIG"):
- warn("Couldn't parse signature")
- else:
- args = keywords["VALIDSIG"]
- if len(args) < 1:
- warn("Couldn't parse signature")
- else:
- fingerprint = args[0]
-
- return (fingerprint, [])
+from daklib.dak_exceptions import DBUpdateError
+from daklib.config import Config
################################################################################
def do_update(self):
- print "Adding known_changes table"
+ print "Updating use of queue table"
try:
c = self.db.cursor()
- c.execute("""
- CREATE TABLE known_changes (
- id SERIAL PRIMARY KEY,
- changesname TEXT NOT NULL,
- seen TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT now(),
- source TEXT NOT NULL,
- binaries TEXT NOT NULL,
- architecture TEXT NOT NULL,
- version TEXT NOT NULL,
- distribution TEXT NOT NULL,
- urgency TEXT NOT NULL,
- maintainer TEXT NOT NULL,
- changedby TEXT NOT NULL,
- date TEXT NOT NULL,
- UNIQUE (changesname)
- )
- """)
- c.execute("CREATE INDEX changesname_ind ON known_changes(changesname)")
- c.execute("CREATE INDEX changestimestamp_ind ON known_changes(seen)")
- c.execute("CREATE INDEX changessource_ind ON known_changes(source)")
- c.execute("CREATE INDEX changesdistribution_ind ON known_changes(distribution)")
- c.execute("CREATE INDEX changesurgency_ind ON known_changes(urgency)")
-
- print "Done. Now looking for old changes files"
- count = 0
- failure = 0
+
cnf = Config()
- for directory in [ "Accepted", "Byhand", "Done", "New", "ProposedUpdates", "OldProposedUpdates" ]:
- checkdir = cnf["Dir::Queue::%s" % (directory) ]
- if os.path.exists(checkdir):
- print "Looking into %s" % (checkdir)
- for dirpath, dirnames, filenames in os.walk(checkdir, topdown=False):
- if not filenames:
- # Empty directory (or only subdirectories), next
- continue
- for changesfile in filenames:
- if not changesfile.endswith(".changes"):
- # Only interested in changes files.
- continue
- try:
- count += 1
- print "Directory %s, file %7d, failures %3d. (%s)" % (dirpath[-10:], count, failure, changesfile)
- changes = parse_changes(os.path.join(dirpath, changesfile), signing_rules=-1)
- (changes["fingerprint"], _) = check_signature(os.path.join(dirpath, changesfile))
- except InvalidDscError, line:
- warn("syntax error in .dsc file '%s', line %s." % (f, line))
- failure += 1
- except ChangesUnicodeError:
- warn("found invalid changes file, not properly utf-8 encoded")
- failure += 1
-
- filetime = datetime.datetime.fromtimestamp(os.path.getctime(os.path.join(dirpath, changesfile)))
- c.execute("INSERT INTO known_changes(changesname, seen, source, binaries, architecture, version, distribution, urgency, maintainer, changedby, date) VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s)" , [changesfile, filetime, changes["source"], changes["binary"], changes["architecture"], changes["version"], changes["distribution"], changes["urgency"], changes["maintainer"], changes["changed-by"], changes["date"]])
+ print "Adding path to queue table"
+ c.execute("ALTER TABLE queue ADD COLUMN path TEXT")
+ c.execute("SELECT * FROM queue")
+ rows = c.fetchall()
+ seenqueues = {}
+ for row in rows:
+ dir = cnf["Dir::Queue::%s" % row[1]].rstrip('/')
+ seenqueues[row[1].lower()] = 1
+ print "Setting %s queue to use path %s" % (row[1], dir)
+ c.execute("UPDATE queue SET path = %s WHERE id = %s", (dir, row[0]))
+
+ print "Adding missing queues to the queue table"
+ for q in cnf.SubTree("Dir::Queue").keys():
+ qname = q.lower()
+ if qname in seenqueues.keys():
+ continue
+ if qname in ["done", "holding", "reject", "newstage", "btsversiontrack"]:
+ print "Skipping queue %s" % qname
+ continue
+ pth = cnf["Dir::Queue::%s" % qname].rstrip('/')
+ if not os.path.exists(pth):
+ print "Skipping %s as %s does not exist" % (qname, pth)
+ continue
+
+ print "Adding %s queue with path %s" % (qname, pth)
+ c.execute("INSERT INTO queue (queue_name, path) VALUES (%s, %s)", (qname, pth))
+ seenqueues[qname] = 1
+
+ print "Adding queue and approved_for columns to known_changes"
+ c.execute("ALTER TABLE known_changes ADD COLUMN in_queue INT4 REFERENCES queue(id) DEFAULT NULL")
+ c.execute("ALTER TABLE known_changes ADD COLUMN approved_for INT4 REFERENCES queue(id) DEFAULT NULL")
+
+ print "Adding policy queue column to suite table"
+ c.execute("ALTER TABLE suite DROP COLUMN policy_engine")
+ c.execute("ALTER TABLE suite ADD COLUMN policy_queue_id INT4 REFERENCES queue(id) DEFAULT NULL")
+ # Handle some of our common cases automatically
+ if seenqueues.has_key('proposedupdates'):
+ c.execute("""UPDATE suite SET policy_queue_id = (SELECT id FROM queue WHERE queue_name = 'proposedupdates')
+ WHERE suite_name = 'proposed-updates'""")
+
+ if seenqueues.has_key('oldproposedupdates'):
+ c.execute("""UPDATE suite SET policy_queue_id = (SELECT id FROM queue WHERE queue_name = 'oldproposedupdates')
+ WHERE suite_name = 'oldstable-proposed-updates'""")
+
+ print "Committing"
c.execute("UPDATE config SET value = '20' WHERE name = 'db_revision'")
self.db.commit()
- except psycopg2.ProgrammingError, msg:
+ except psycopg2.InternalError, msg:
self.db.rollback()
- raise DBUpdateError, "Unable to apply source format update 15, rollback issued. Error message : %s" % (str(msg))
+ raise DBUpdateError, "Unable to apply debversion update 20, rollback issued. Error message : %s" % (str(msg))