]> git.decadent.org.uk Git - dak.git/blob - dak/dakdb/update18.py
And how about we make this mhy fault?
[dak.git] / dak / dakdb / update18.py
1 #!/usr/bin/env python
2 # coding=utf8
3
4 """
5 Adding table to get rid of queue/done checks
6
7 @contact: Debian FTP Master <ftpmaster@debian.org>
8 @copyright: 2009  Joerg Jaspert <joerg@debian.org>
9 @license: GNU General Public License version 2 or later
10 """
11
12 # This program is free software; you can redistribute it and/or modify
13 # it under the terms of the GNU General Public License as published by
14 # the Free Software Foundation; either version 2 of the License, or
15 # (at your option) any later version.
16
17 # This program is distributed in the hope that it will be useful,
18 # but WITHOUT ANY WARRANTY; without even the implied warranty of
19 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20 # GNU General Public License for more details.
21
22 # You should have received a copy of the GNU General Public License
23 # along with this program; if not, write to the Free Software
24 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
25
26 ################################################################################
27
28
29 ################################################################################
30
31 import psycopg2
32 import time
33 import os
34 import datetime
35 from daklib.dak_exceptions import DBUpdateError, InvalidDscError, ChangesUnicodeError
36 from daklib.config import Config
37 from daklib.changes import Changes
38 from daklib.utils import parse_changes, warn, gpgv_get_status_output, process_gpgv_output
39
40 ################################################################################
41
42 def check_signature (sig_filename, data_filename=""):
43     keyrings = [
44         "/home/joerg/keyring/keyrings/debian-keyring.gpg",
45         "/home/joerg/keyring/keyrings/debian-keyring.pgp",
46         "/home/joerg/keyring/keyrings/debian-maintainers.gpg",
47         "/home/joerg/keyring/keyrings/debian-role-keys.gpg",
48         "/home/joerg/keyring/keyrings/emeritus-keyring.pgp",
49         "/home/joerg/keyring/keyrings/emeritus-keyring.gpg",
50         "/home/joerg/keyring/keyrings/removed-keys.gpg",
51         "/home/joerg/keyring/keyrings/removed-keys.pgp"
52         ]
53
54     keyringargs = " ".join(["--keyring %s" % x for x in keyrings ])
55
56     # Build the command line
57     status_read, status_write = os.pipe()
58     cmd = "gpgv --status-fd %s %s %s" % (status_write, keyringargs, sig_filename)
59
60     # Invoke gpgv on the file
61     (output, status, exit_status) = gpgv_get_status_output(cmd, status_read, status_write)
62
63     # Process the status-fd output
64     (keywords, internal_error) = process_gpgv_output(status)
65
66     # If we failed to parse the status-fd output, let's just whine and bail now
67     if internal_error:
68         warn("Couldn't parse signature")
69         return None
70
71     # usually one would check for bad things here. We, however, do not care.
72
73     # Next check gpgv exited with a zero return code
74     if exit_status:
75         warn("Couldn't parse signature")
76         return None
77
78     # Sanity check the good stuff we expect
79     if not keywords.has_key("VALIDSIG"):
80         warn("Couldn't parse signature")
81     else:
82         args = keywords["VALIDSIG"]
83         if len(args) < 1:
84             warn("Couldn't parse signature")
85         else:
86             fingerprint = args[0]
87
88     return fingerprint
89
90 ################################################################################
91
92 def do_update(self):
93     print "Adding known_changes table"
94
95     try:
96         c = self.db.cursor()
97         c.execute("""
98                     CREATE TABLE known_changes (
99                     id SERIAL PRIMARY KEY,
100                     changesname TEXT NOT NULL,
101                     seen TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT now(),
102                     source TEXT NOT NULL,
103                     binaries TEXT NOT NULL,
104                     architecture TEXT NOT NULL,
105                     version TEXT NOT NULL,
106                     distribution TEXT NOT NULL,
107                     urgency TEXT NOT NULL,
108                     maintainer TEXT NOT NULL,
109                     fingerprint TEXT NOT NULL,
110                     changedby TEXT NOT NULL,
111                     date TEXT NOT NULL,
112                     UNIQUE (changesname)
113             )
114         """)
115         c.execute("CREATE INDEX changesname_ind ON known_changes(changesname)")
116         c.execute("CREATE INDEX changestimestamp_ind ON known_changes(seen)")
117         c.execute("CREATE INDEX changessource_ind ON known_changes(source)")
118         c.execute("CREATE INDEX changesdistribution_ind ON known_changes(distribution)")
119         c.execute("CREATE INDEX changesurgency_ind ON known_changes(urgency)")
120
121         print "Done. Now looking for old changes files"
122         count = 0
123         failure = 0
124         cnf = Config()
125         for directory in [ "Accepted", "Byhand", "Done", "New", "ProposedUpdates", "OldProposedUpdates" ]:
126             checkdir = cnf["Dir::Queue::%s" % (directory) ]
127             if os.path.exists(checkdir):
128                 print "Looking into %s" % (checkdir)
129                 for filename in os.listdir(checkdir):
130                     if not filename.endswith(".changes"):
131                         # Only interested in changes files.
132                         continue
133                     try:
134                         count += 1
135                         print "Directory %s, file %7d, failures %3d. (%s)" % (directory, count, failure, filename)
136                         changes = Changes()
137                         changes.changes_file = filename
138                         changesfile = os.path.join(checkdir, filename)
139                         changes.changes = parse_changes(changesfile, signing_rules=-1)
140                         changes.changes["fingerprint"], = check_signature(changesfile)
141                         changes.add_known_changes(directory)
142                     except InvalidDscError, line:
143                         warn("syntax error in .dsc file '%s', line %s." % (f, line))
144                         failure += 1
145                     except ChangesUnicodeError:
146                         warn("found invalid changes file, not properly utf-8 encoded")
147                         failure += 1
148
149
150         c.execute("GRANT ALL ON known_changes TO ftpmaster;")
151         c.execute("GRANT SELECT ON known_changes TO public;")
152
153         c.execute("UPDATE config SET value = '18' WHERE name = 'db_revision'")
154         self.db.commit()
155
156     except psycopg2.ProgrammingError, msg:
157         self.db.rollback()
158         raise DBUpdateError, "Unable to apply knownchanges update 18, rollback issued. Error message : %s" % (str(msg))