]> git.decadent.org.uk Git - dak.git/commitdiff
per-queue NEW comments and permissions
authorAnsgar Burchardt <ansgar@debian.org>
Thu, 20 Sep 2012 15:11:49 +0000 (17:11 +0200)
committerAnsgar Burchardt <ansgar@debian.org>
Thu, 20 Sep 2012 15:11:49 +0000 (17:11 +0200)
dak/dakdb/update91.py [new file with mode: 0644]
dak/process_new.py
dak/queue_report.py
dak/update_db.py
daklib/dbconn.py
daklib/queue.py

diff --git a/dak/dakdb/update91.py b/dak/dakdb/update91.py
new file mode 100644 (file)
index 0000000..7cd278b
--- /dev/null
@@ -0,0 +1,108 @@
+#!/usr/bin/env python
+# coding=utf8
+
+"""
+per-queue NEW comments and permissions
+
+@contact: Debian FTP Master <ftpmaster@debian.org>
+@copyright: 2012 Ansgar Burchardt <ansgar@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
+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))
index afd03d23c8283ee5410ac4cc4ab76f83def95c38..61eb8ec9f67de76335a3dc8dbca63f827e4f01d3 100755 (executable)
@@ -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)
index 882eab2a82ebe4d2e04c259d4ff62cff60ee6adc..1bef3e55915bd9de7b1b43e04120a69ffe377190 100755 (executable)
@@ -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
index ea364a77cdf57a0bab8d97883b1bd4af9966203f..cddb4c2aeeeba0cdfcfb65c8ef12c2e6c124f0c4 100755 (executable)
@@ -46,7 +46,7 @@ from daklib.daklog import Logger
 ################################################################################
 
 Cnf = None
-required_database_schema = 90
+required_database_schema = 91
 
 ################################################################################
 
index 7c1feed635c49a34b616aa548b8ccb1362d914cf..08765171442890abb1cdaf415e5ee50fc3a250da 100644 (file)
@@ -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,
index 9dd2702ca02aa296071f768cd7764c7c4e9f37cf..f2dc55a0d91ae5c9ccc2c8a6ce25f89f329bb57f 100644 (file)
@@ -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