3 """ Cruft checker and hole filler for overrides """
4 # Copyright (C) 2000, 2001, 2002, 2004, 2006 James Troup <james@nocrew.org>
5 # Copyright (C) 2005 Jeroen van Wolffelaar <jeroen@wolffelaar.nl>
7 # This program is free software; you can redistribute it and/or modify
8 # it under the terms of the GNU General Public License as published by
9 # the Free Software Foundation; either version 2 of the License, or
10 # (at your option) any later version.
12 # This program is distributed in the hope that it will be useful,
13 # but WITHOUT ANY WARRANTY; without even the implied warranty of
14 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 # GNU General Public License for more details.
17 # You should have received a copy of the GNU General Public License
18 # along with this program; if not, write to the Free Software
19 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 ################################################################################
23 ######################################################################
24 # NB: dak check-overrides is not a good idea with New Incoming as it #
25 # doesn't take into account accepted. You can minimize the impact #
26 # of this by running it immediately after dak process-accepted but #
27 # that's still racy because 'dak process-new' doesn't lock with 'dak #
28 # process-accepted'. A better long term fix is the evil plan for #
29 # accepted to be in the DB. #
30 ######################################################################
32 # dak check-overrides should now work fine being done during
33 # cron.daily, for example just before 'dak make-overrides' (after 'dak
34 # process-accepted' and 'dak make-suite-file-list'). At that point,
35 # queue/accepted should be empty and installed, so... dak
36 # check-overrides does now take into account suites sharing overrides
39 # * Only update out-of-sync overrides when corresponding versions are equal to
41 # * consistency checks like:
42 # - section=debian-installer only for udeb and # dsc
43 # - priority=source iff dsc
44 # - (suite, package, 'dsc') is unique,
45 # - just as (suite, package, (u)deb) (yes, across components!)
46 # - sections match their component (each component has an own set of sections,
47 # could probably be reduced...)
49 ################################################################################
53 from daklib import database
54 from daklib import logging
55 from daklib import utils
57 ################################################################################
66 ################################################################################
68 def usage (exit_code=0):
69 print """Usage: dak check-overrides
70 Check for cruft in overrides.
72 -n, --no-action don't do anything
73 -h, --help show this help and exit"""
77 ################################################################################
79 def gen_blacklist(dir):
80 for entry in os.listdir(dir):
81 entry = entry.split('_')[0]
84 def process(osuite, affected_suites, originosuite, component, type):
85 global Logger, Options, projectB, sections, priorities
87 osuite_id = database.get_suite_id(osuite)
89 utils.fubar("Suite '%s' not recognised." % (osuite))
90 originosuite_id = None
92 originosuite_id = database.get_suite_id(originosuite)
93 if originosuite_id == -1:
94 utils.fubar("Suite '%s' not recognised." % (originosuite))
96 component_id = database.get_component_id(component)
97 if component_id == -1:
98 utils.fubar("Component '%s' not recognised." % (component))
100 type_id = database.get_override_type_id(type)
102 utils.fubar("Type '%s' not recognised. (Valid types are deb, udeb and dsc)" % (type))
103 dsc_type_id = database.get_override_type_id("dsc")
105 source_priority_id = database.get_priority_id("source")
107 if type == "deb" or type == "udeb":
109 q = projectB.query("""
110 SELECT b.package FROM binaries b, bin_associations ba, files f,
111 location l, component c
112 WHERE b.type = '%s' AND b.id = ba.bin AND f.id = b.file AND l.id = f.location
113 AND c.id = l.component AND ba.suite IN (%s) AND c.id = %s
114 """ % (type, ",".join([ str(i) for i in affected_suites ]), component_id))
115 for i in q.getresult():
119 q = projectB.query("""
120 SELECT s.source FROM source s, src_associations sa, files f, location l,
122 WHERE s.id = sa.source AND f.id = s.file AND l.id = f.location
123 AND c.id = l.component AND sa.suite IN (%s) AND c.id = %s
124 """ % (",".join([ str(i) for i in affected_suites]), component_id))
125 for i in q.getresult():
126 src_packages[i[0]] = 0
129 # Drop unused overrides
131 q = projectB.query("SELECT package, priority, section, maintainer FROM override WHERE suite = %s AND component = %s AND type = %s" % (osuite_id, component_id, type_id))
132 projectB.query("BEGIN WORK")
134 for i in q.getresult():
136 if src_packages.has_key(package):
137 src_packages[package] = 1
139 if blacklist.has_key(package):
140 utils.warn("%s in incoming, not touching" % package)
142 Logger.log(["removing unused override", osuite, component,
143 type, package, priorities[i[1]], sections[i[2]], i[3]])
144 if not Options["No-Action"]:
145 projectB.query("""DELETE FROM override WHERE package =
146 '%s' AND suite = %s AND component = %s AND type =
147 %s""" % (package, osuite_id, component_id, type_id))
148 # create source overrides based on binary overrides, as source
149 # overrides not always get created
150 q = projectB.query(""" SELECT package, priority, section,
151 maintainer FROM override WHERE suite = %s AND component = %s
152 """ % (osuite_id, component_id))
153 for i in q.getresult():
155 if not src_packages.has_key(package) or src_packages[package]:
157 src_packages[package] = 1
159 Logger.log(["add missing override", osuite, component,
160 type, package, "source", sections[i[2]], i[3]])
161 if not Options["No-Action"]:
162 projectB.query("""INSERT INTO override (package, suite,
163 component, priority, section, type, maintainer) VALUES
164 ('%s', %s, %s, %s, %s, %s, '%s')""" % (package,
165 osuite_id, component_id, source_priority_id, i[2],
167 # Check whether originosuite has an override for us we can
170 q = projectB.query("""SELECT origin.package, origin.priority,
171 origin.section, origin.maintainer, target.priority,
172 target.section, target.maintainer FROM override origin LEFT
173 JOIN override target ON (origin.package = target.package AND
174 target.suite=%s AND origin.component = target.component AND origin.type =
175 target.type) WHERE origin.suite = %s AND origin.component = %s
176 AND origin.type = %s""" %
177 (osuite_id, originosuite_id, component_id, type_id))
178 for i in q.getresult():
180 if not src_packages.has_key(package) or src_packages[package]:
181 if i[4] and (i[1] != i[4] or i[2] != i[5] or i[3] != i[6]):
182 Logger.log(["syncing override", osuite, component,
183 type, package, "source", sections[i[5]], i[6], "source", sections[i[2]], i[3]])
184 if not Options["No-Action"]:
185 projectB.query("""UPDATE override SET section=%s,
186 maintainer='%s' WHERE package='%s' AND
187 suite=%s AND component=%s AND type=%s""" %
188 (i[2], i[3], package, osuite_id, component_id,
192 src_packages[package] = 1
193 Logger.log(["copying missing override", osuite, component,
194 type, package, "source", sections[i[2]], i[3]])
195 if not Options["No-Action"]:
196 projectB.query("""INSERT INTO override (package, suite,
197 component, priority, section, type, maintainer) VALUES
198 ('%s', %s, %s, %s, %s, %s, '%s')""" % (package,
199 osuite_id, component_id, source_priority_id, i[2],
202 for package, hasoverride in src_packages.items():
204 utils.warn("%s has no override!" % package)
206 else: # binary override
207 for i in q.getresult():
209 if packages.has_key(package):
210 packages[package] = 1
212 if blacklist.has_key(package):
213 utils.warn("%s in incoming, not touching" % package)
215 Logger.log(["removing unused override", osuite, component,
216 type, package, priorities[i[1]], sections[i[2]], i[3]])
217 if not Options["No-Action"]:
218 projectB.query("""DELETE FROM override WHERE package =
219 '%s' AND suite = %s AND component = %s AND type =
220 %s""" % (package, osuite_id, component_id, type_id))
222 # Check whether originosuite has an override for us we can
225 q = projectB.query("""SELECT origin.package, origin.priority,
226 origin.section, origin.maintainer, target.priority,
227 target.section, target.maintainer FROM override origin LEFT
228 JOIN override target ON (origin.package = target.package AND
229 target.suite=%s AND origin.component = target.component AND
230 origin.type = target.type) WHERE origin.suite = %s AND
231 origin.component = %s AND origin.type = %s""" % (osuite_id,
232 originosuite_id, component_id, type_id))
233 for i in q.getresult():
235 if not packages.has_key(package) or packages[package]:
236 if i[4] and (i[1] != i[4] or i[2] != i[5] or i[3] != i[6]):
237 Logger.log(["syncing override", osuite, component,
238 type, package, priorities[i[4]], sections[i[5]],
239 i[6], priorities[i[1]], sections[i[2]], i[3]])
240 if not Options["No-Action"]:
241 projectB.query("""UPDATE override SET priority=%s, section=%s,
242 maintainer='%s' WHERE package='%s' AND
243 suite=%s AND component=%s AND type=%s""" %
244 (i[1], i[2], i[3], package, osuite_id,
245 component_id, type_id))
248 packages[package] = 1
249 Logger.log(["copying missing override", osuite, component,
250 type, package, priorities[i[1]], sections[i[2]], i[3]])
251 if not Options["No-Action"]:
252 projectB.query("""INSERT INTO override (package, suite,
253 component, priority, section, type, maintainer) VALUES
254 ('%s', %s, %s, %s, %s, %s, '%s')""" % (package, osuite_id, component_id, i[1], i[2], type_id, i[3]))
256 for package, hasoverride in packages.items():
258 utils.warn("%s has no override!" % package)
260 projectB.query("COMMIT WORK")
264 ################################################################################
267 global Logger, Options, projectB, sections, priorities
269 Cnf = utils.get_conf()
271 Arguments = [('h',"help","Check-Overrides::Options::Help"),
272 ('n',"no-action", "Check-Overrides::Options::No-Action")]
273 for i in [ "help", "no-action" ]:
274 if not Cnf.has_key("Check-Overrides::Options::%s" % (i)):
275 Cnf["Check-Overrides::Options::%s" % (i)] = ""
276 apt_pkg.ParseCommandLine(Cnf, Arguments, sys.argv)
277 Options = Cnf.SubTree("Check-Overrides::Options")
282 projectB = pg.connect(Cnf["DB::Name"], Cnf["DB::Host"], int(Cnf["DB::Port"]))
283 database.init(Cnf, projectB)
285 # init sections, priorities:
286 q = projectB.query("SELECT id, section FROM section")
287 for i in q.getresult():
288 sections[i[0]] = i[1]
289 q = projectB.query("SELECT id, priority FROM priority")
290 for i in q.getresult():
291 priorities[i[0]] = i[1]
293 if not Options["No-Action"]:
294 Logger = logging.Logger(Cnf, "check-overrides")
296 Logger = logging.Logger(Cnf, "check-overrides", 1)
298 gen_blacklist(Cnf["Dir::Queue::Accepted"])
300 for osuite in Cnf.SubTree("Check-Overrides::OverrideSuites").List():
301 if "1" != Cnf["Check-Overrides::OverrideSuites::%s::Process" % osuite]:
304 osuite = osuite.lower()
309 originosuite = Cnf["Check-Overrides::OverrideSuites::%s::OriginSuite" % osuite]
310 originosuite = originosuite.lower()
311 originremark = " taking missing from %s" % originosuite
315 print "Processing %s%s..." % (osuite, originremark)
316 # Get a list of all suites that use the override file of 'osuite'
317 ocodename = Cnf["Suite::%s::codename" % osuite].lower()
319 for suite in Cnf.SubTree("Suite").List():
320 if ocodename == Cnf["Suite::%s::OverrideCodeName" % suite].lower():
323 q = projectB.query("SELECT id FROM suite WHERE suite_name in (%s)" \
324 % ", ".join([ repr(i) for i in suites ]).lower())
327 for i in q.getresult():
328 suiteids.append(i[0])
330 if len(suiteids) != len(suites) or len(suiteids) < 1:
331 utils.fubar("Couldn't find id's of all suites: %s" % suites)
333 for component in Cnf.SubTree("Component").List():
334 if component == "mixed":
336 # It is crucial for the dsc override creation based on binary
337 # overrides that 'dsc' goes first
338 otypes = Cnf.ValueList("OverrideType")
340 otypes = ["dsc"] + otypes
342 print "Processing %s [%s - %s] using %s..." \
343 % (osuite, component, otype, suites)
345 process(osuite, suiteids, originosuite, component, otype)
349 ################################################################################
351 if __name__ == '__main__':