From: Ansgar Burchardt Date: Thu, 20 Sep 2012 15:11:49 +0000 (+0200) Subject: per-queue NEW comments and permissions X-Git-Url: https://git.decadent.org.uk/gitweb/?a=commitdiff_plain;h=07f1aa392e54c3d7a0747720c32db2b8aa202a42;p=dak.git per-queue NEW comments and permissions --- diff --git a/dak/dakdb/update91.py b/dak/dakdb/update91.py new file mode 100644 index 00000000..7cd278b2 --- /dev/null +++ b/dak/dakdb/update91.py @@ -0,0 +1,108 @@ +#!/usr/bin/env python +# coding=utf8 + +""" +per-queue NEW comments and permissions + +@contact: Debian FTP Master +@copyright: 2012 Ansgar Burchardt +@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 +from daklib.config import Config + +statements = [ +""" +ALTER TABLE new_comments +ADD COLUMN policy_queue_id INTEGER REFERENCES policy_queue(id) +""", + +""" +UPDATE new_comments +SET policy_queue_id = (SELECT id FROM policy_queue WHERE queue_name = 'new') +""", + +""" +ALTER TABLE new_comments ALTER COLUMN policy_queue_id SET NOT NULL +""", + +""" +CREATE OR REPLACE FUNCTION trigger_check_policy_queue_permission() RETURNS TRIGGER +SET search_path = public, pg_temp +LANGUAGE plpgsql +AS $$ +DECLARE + v_row RECORD; + v_suite_id suite.id%TYPE; + v_policy_queue_name policy_queue.queue_name%TYPE; +BEGIN + + CASE TG_OP + WHEN 'INSERT', 'UPDATE' THEN + v_row := NEW; + WHEN 'DELETE' THEN + v_row := OLD; + ELSE + RAISE EXCEPTION 'Unexpected TG_OP (%)', TG_OP; + END CASE; + + IF TG_OP = 'UPDATE' AND OLD.policy_queue_id != NEW.policy_queue_id THEN + RAISE EXCEPTION 'Cannot change policy_queue_id'; + END IF; + + SELECT suite_id, queue_name INTO STRICT v_suite_id, v_policy_queue_name + FROM policy_queue WHERE id = v_row.policy_queue_id; + IF NOT has_suite_permission(TG_OP, v_suite_id) THEN + RAISE EXCEPTION 'Not allowed to % in %', TG_OP, v_policy_queue_name; + END IF; + + RETURN v_row; + +END; +$$ +""", + +""" +CREATE CONSTRAINT TRIGGER trigger_new_comments_permission + AFTER INSERT OR UPDATE OR DELETE + ON new_comments + FOR EACH ROW + EXECUTE PROCEDURE trigger_check_policy_queue_permission() +""", +] + +################################################################################ +def do_update(self): + print __doc__ + try: + cnf = Config() + + c = self.db.cursor() + + for stmt in statements: + c.execute(stmt) + + c.execute("UPDATE config SET value = '91' WHERE name = 'db_revision'") + self.db.commit() + + except psycopg2.ProgrammingError as msg: + self.db.rollback() + raise DBUpdateError('Unable to apply sick update 91, rollback issued. Error message: {0}'.format(msg)) diff --git a/dak/process_new.py b/dak/process_new.py index afd03d23..61eb8ec9 100755 --- a/dak/process_new.py +++ b/dak/process_new.py @@ -137,7 +137,7 @@ def print_new (upload, missing, indexed, session, file=sys.stdout): if not m['valid']: line = line + ' [!]' print >>file, line - notes = get_new_comments(upload.changes.source) + notes = get_new_comments(upload.policy_queue, upload.changes.source) for note in notes: print "\nAuthor: %s\nVersion: %s\nTimestamp: %s\n\n%s" \ % (note.author, note.version, note.notedate, note.comment) @@ -534,19 +534,19 @@ def do_new(upload, upload_copy, handler, session): missing = edit_overrides (missing, upload, session) elif answer == 'M' and not Options["Trainee"]: reason = Options.get('Manual-Reject', '') + "\n" - reason = reason + "\n\n=====\n\n".join([n.comment for n in get_new_comments(upload.changes.source, session=session)]) + reason = reason + "\n\n=====\n\n".join([n.comment for n in get_new_comments(upload.policy_queue, upload.changes.source, session=session)]) reason = get_reject_reason(reason) if reason is not None: Logger.log(["NEW REJECT", upload.changes.changesname]) handler.reject(reason) done = True elif answer == 'N': - if edit_note(get_new_comments(upload.changes.source, session=session), + if edit_note(get_new_comments(upload.policy_queue, upload.changes.source, session=session), upload, session, bool(Options["Trainee"])) == 0: end() sys.exit(0) elif answer == 'P' and not Options["Trainee"]: - if prod_maintainer(get_new_comments(upload.changes.source, session=session), + if prod_maintainer(get_new_comments(upload.policy_queue, upload.changes.source, session=session), upload) == 0: end() sys.exit(0) @@ -554,13 +554,13 @@ def do_new(upload, upload_copy, handler, session): elif answer == 'R' and not Options["Trainee"]: confirm = utils.our_raw_input("Really clear note (y/N)? ").lower() if confirm == "y": - for c in get_new_comments(upload.changes.source, upload.changes.version, session=session): + for c in get_new_comments(upload.policy_queue, upload.changes.source, upload.changes.version, session=session): session.delete(c) session.commit() elif answer == 'O' and not Options["Trainee"]: confirm = utils.our_raw_input("Really clear all notes (y/N)? ").lower() if confirm == "y": - for c in get_new_comments(upload.changes.source, session=session): + for c in get_new_comments(upload.policy_queue, upload.changes.source, session=session): session.delete(c) session.commit() @@ -699,13 +699,13 @@ def show_new_comments(uploads, session): ################################################################################ -def sort_uploads(uploads, session, nobinaries=False): +def sort_uploads(new_queue, uploads, session, nobinaries=False): sources = {} sorteduploads = [] suitesrc = [s.source for s in session.query(DBSource.source). \ filter(DBSource.suites.any(Suite.suite_name.in_(['unstable', 'experimental'])))] comments = [p.package for p in session.query(NewComment.package). \ - filter_by(trainee=False).distinct()] + filter_by(trainee=False, policy_queue=new_queue).distinct()] for upload in uploads: source = upload.changes.source if not source in sources: @@ -798,7 +798,7 @@ def main(): if len(uploads) > 1: sys.stderr.write("Sorting changes...\n") - uploads = sort_uploads(uploads, session, Options["No-Binaries"]) + uploads = sort_uploads(new_queue, uploads, session, Options["No-Binaries"]) if Options["Comments"]: show_new_comments(uploads, session) diff --git a/dak/queue_report.py b/dak/queue_report.py index 882eab2a..1bef3e55 100755 --- a/dak/queue_report.py +++ b/dak/queue_report.py @@ -399,7 +399,7 @@ def process_queue(queue, log, rrd_dir): else: if mtime < oldest: oldest = mtime - have_note += has_new_comment(d.changes.source, d.changes.version) + have_note += has_new_comment(d.policy_queue, d.changes.source, d.changes.version) per_source[source]["oldest"] = oldest if not have_note: per_source[source]["note_state"] = 0; # none diff --git a/dak/update_db.py b/dak/update_db.py index ea364a77..cddb4c2a 100755 --- a/dak/update_db.py +++ b/dak/update_db.py @@ -46,7 +46,7 @@ from daklib.daklog import Logger ################################################################################ Cnf = None -required_database_schema = 90 +required_database_schema = 91 ################################################################################ diff --git a/daklib/dbconn.py b/daklib/dbconn.py index 7c1feed6..08765171 100644 --- a/daklib/dbconn.py +++ b/daklib/dbconn.py @@ -1474,7 +1474,7 @@ class NewComment(object): __all__.append('NewComment') @session_wrapper -def has_new_comment(package, version, session=None): +def has_new_comment(policy_queue, package, version, session=None): """ Returns true if the given combination of C{package}, C{version} has a comment. @@ -1492,7 +1492,7 @@ def has_new_comment(package, version, session=None): @return: true/false """ - q = session.query(NewComment) + q = session.query(NewComment).filter_by(policy_queue=policy_queue) q = q.filter_by(package=package) q = q.filter_by(version=version) @@ -1501,7 +1501,7 @@ def has_new_comment(package, version, session=None): __all__.append('has_new_comment') @session_wrapper -def get_new_comments(package=None, version=None, comment_id=None, session=None): +def get_new_comments(policy_queue, package=None, version=None, comment_id=None, session=None): """ Returns (possibly empty) list of NewComment objects for the given parameters @@ -1523,7 +1523,7 @@ def get_new_comments(package=None, version=None, comment_id=None, session=None): @return: A (possibly empty) list of NewComment objects will be returned """ - q = session.query(NewComment) + q = session.query(NewComment).filter_by(policy_queue=policy_queue) if package is not None: q = q.filter_by(package=package) if version is not None: q = q.filter_by(version=version) if comment_id is not None: q = q.filter_by(comment_id=comment_id) @@ -2734,7 +2734,8 @@ class DBConn(object): extension = validator) mapper(NewComment, self.tbl_new_comments, - properties = dict(comment_id = self.tbl_new_comments.c.id)) + properties = dict(comment_id = self.tbl_new_comments.c.id, + policy_queue = relation(PolicyQueue))) mapper(Override, self.tbl_override, properties = dict(suite_id = self.tbl_override.c.suite, diff --git a/daklib/queue.py b/daklib/queue.py index 9dd2702c..f2dc55a0 100644 --- a/daklib/queue.py +++ b/daklib/queue.py @@ -188,6 +188,7 @@ def edit_note(note, upload, session, trainee=False): return 0 comment = NewComment() + comment.policy_queue = upload.policy_queue comment.package = upload.changes.source comment.version = upload.changes.version comment.comment = newnote