Package dak :: Module control_overrides
[hide private]
[frames] | no frames]

Source Code for Module dak.control_overrides

  1  #! /usr/bin/env python3 
  2   
  3  """ Bulk manipulation of the overrides """ 
  4  # Copyright (C) 2000, 2001, 2002, 2003, 2006  James Troup <james@nocrew.org> 
  5   
  6  # This program is free software; you can redistribute it and/or modify 
  7  # it under the terms of the GNU General Public License as published by 
  8  # the Free Software Foundation; either version 2 of the License, or 
  9  # (at your option) any later version. 
 10   
 11  # This program is distributed in the hope that it will be useful, 
 12  # but WITHOUT ANY WARRANTY; without even the implied warranty of 
 13  # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
 14  # GNU General Public License for more details. 
 15   
 16  # You should have received a copy of the GNU General Public License 
 17  # along with this program; if not, write to the Free Software 
 18  # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA 
 19   
 20  ################################################################################ 
 21   
 22  # On 30 Nov 1998, James Troup wrote: 
 23  # 
 24  # > James Troup<2> <troup2@debian.org> 
 25  # > 
 26  # >    James is a clone of James; he's going to take over the world. 
 27  # >    After he gets some sleep. 
 28  # 
 29  # Could you clone other things too? Sheep? Llamas? Giant mutant turnips? 
 30  # 
 31  # Your clone will need some help to take over the world, maybe clone up an 
 32  # army of penguins and threaten to unleash them on the world, forcing 
 33  # governments to sway to the new James' will! 
 34  # 
 35  # Yes, I can envision a day when James' duplicate decides to take a horrific 
 36  # vengance on the James that spawned him and unleashes his fury in the form 
 37  # of thousands upon thousands of chickens that look just like Captin Blue 
 38  # Eye! Oh the horror. 
 39  # 
 40  # Now you'll have to were name tags to people can tell you apart, unless of 
 41  # course the new clone is truely evil in which case he should be easy to 
 42  # identify! 
 43  # 
 44  # Jason 
 45  # Chicken. Black. Helicopters. 
 46  # Be afraid. 
 47   
 48  # <Pine.LNX.3.96.981130011300.30365Z-100000@wakko> 
 49   
 50  ################################################################################ 
 51   
 52  import sys 
 53  import time 
 54  import apt_pkg 
 55   
 56  from daklib.dbconn import * 
 57  from daklib.config import Config 
 58  from daklib import utils 
 59  from daklib import daklog 
 60  from daklib.regexes import re_comments 
 61   
 62  ################################################################################ 
 63   
 64  Logger = None 
 65   
 66  ################################################################################ 
 67   
 68   
69 -def usage(exit_code=0):
70 print("""Usage: dak control-overrides [OPTIONS] 71 -h, --help print this help and exit 72 73 -c, --component=CMPT list/set overrides by component 74 (contrib,*main,non-free) 75 -s, --suite=SUITE list/set overrides by suite 76 (experimental,stable,testing,*unstable) 77 -t, --type=TYPE list/set overrides by type 78 (*deb,dsc,udeb) 79 80 -a, --add add overrides (changes and deletions are ignored) 81 -S, --set set overrides 82 -C, --change change overrides (additions and deletions are ignored) 83 -l, --list list overrides 84 85 -q, --quiet be less verbose 86 -n, --no-action only list the action that would have been done 87 88 starred (*) values are default""") 89 sys.exit(exit_code)
90 91 ################################################################################ 92 93
94 -def process_file(file, suite, component, otype, mode, action, session):
95 cnf = Config() 96 97 s = get_suite(suite, session=session) 98 if s is None: 99 utils.fubar("Suite '%s' not recognised." % (suite)) 100 suite_id = s.suite_id 101 102 c = get_component(component, session=session) 103 if c is None: 104 utils.fubar("Component '%s' not recognised." % (component)) 105 component_id = c.component_id 106 107 o = get_override_type(otype) 108 if o is None: 109 utils.fubar("Type '%s' not recognised. (Valid types are deb, udeb and dsc.)" % (otype)) 110 type_id = o.overridetype_id 111 112 # --set is done mostly internal for performance reasons; most 113 # invocations of --set will be updates and making people wait 2-3 114 # minutes while 6000 select+inserts are run needlessly isn't cool. 115 116 original = {} 117 new = {} 118 c_skipped = 0 119 c_added = 0 120 c_updated = 0 121 c_removed = 0 122 c_error = 0 123 124 q = session.execute("""SELECT o.package, o.priority, o.section, o.maintainer, p.priority, s.section 125 FROM override o, priority p, section s 126 WHERE o.suite = :suiteid AND o.component = :componentid AND o.type = :typeid 127 and o.priority = p.id and o.section = s.id""", 128 {'suiteid': suite_id, 'componentid': component_id, 'typeid': type_id}) 129 for i in q.fetchall(): 130 original[i[0]] = i[1:] 131 132 start_time = time.time() 133 134 section_cache = get_sections(session) 135 priority_cache = get_priorities(session) 136 137 # Our session is already in a transaction 138 139 for line in file.readlines(): 140 line = re_comments.sub('', line).strip() 141 if line == "": 142 continue 143 144 maintainer_override = None 145 if otype == "dsc": 146 split_line = line.split(None, 2) 147 if len(split_line) == 2: 148 (package, section) = split_line 149 elif len(split_line) == 3: 150 (package, section, maintainer_override) = split_line 151 else: 152 utils.warn("'%s' does not break into 'package section [maintainer-override]'." % (line)) 153 c_error += 1 154 continue 155 priority = "optional" 156 else: # binary or udeb 157 split_line = line.split(None, 3) 158 if len(split_line) == 3: 159 (package, priority, section) = split_line 160 elif len(split_line) == 4: 161 (package, priority, section, maintainer_override) = split_line 162 else: 163 utils.warn("'%s' does not break into 'package priority section [maintainer-override]'." % (line)) 164 c_error += 1 165 continue 166 167 if section not in section_cache: 168 utils.warn("'%s' is not a valid section. ['%s' in suite %s, component %s]." % (section, package, suite, component)) 169 c_error += 1 170 continue 171 172 section_id = section_cache[section] 173 174 if priority not in priority_cache: 175 utils.warn("'%s' is not a valid priority. ['%s' in suite %s, component %s]." % (priority, package, suite, component)) 176 c_error += 1 177 continue 178 179 priority_id = priority_cache[priority] 180 181 if package in new: 182 utils.warn("Can't insert duplicate entry for '%s'; ignoring all but the first. [suite %s, component %s]" % (package, suite, component)) 183 c_error += 1 184 continue 185 new[package] = "" 186 187 if package in original: 188 (old_priority_id, old_section_id, old_maintainer_override, old_priority, old_section) = original[package] 189 if mode == "add" or old_priority_id == priority_id and \ 190 old_section_id == section_id and \ 191 old_maintainer_override == maintainer_override: 192 # If it's unchanged or we're in 'add only' mode, ignore it 193 c_skipped += 1 194 continue 195 else: 196 # If it's changed, delete the old one so we can 197 # reinsert it with the new information 198 c_updated += 1 199 if action: 200 session.execute("""DELETE FROM override WHERE suite = :suite AND component = :component 201 AND package = :package AND type = :typeid""", 202 {'suite': suite_id, 'component': component_id, 203 'package': package, 'typeid': type_id}) 204 205 # Log changes 206 if old_priority_id != priority_id: 207 Logger.log(["changed priority", package, old_priority, priority]) 208 if old_section_id != section_id: 209 Logger.log(["changed section", package, old_section, section]) 210 if old_maintainer_override != maintainer_override: 211 Logger.log(["changed maintainer override", package, old_maintainer_override, maintainer_override]) 212 update_p = 1 213 elif mode == "change": 214 # Ignore additions in 'change only' mode 215 c_skipped += 1 216 continue 217 else: 218 c_added += 1 219 update_p = 0 220 221 if action: 222 if not maintainer_override: 223 m_o = None 224 else: 225 m_o = maintainer_override 226 session.execute("""INSERT INTO override (suite, component, type, package, 227 priority, section, maintainer) 228 VALUES (:suiteid, :componentid, :typeid, 229 :package, :priorityid, :sectionid, 230 :maintainer)""", 231 {'suiteid': suite_id, 'componentid': component_id, 232 'typeid': type_id, 'package': package, 233 'priorityid': priority_id, 'sectionid': section_id, 234 'maintainer': m_o}) 235 236 if not update_p: 237 Logger.log(["new override", suite, component, otype, package, priority, section, maintainer_override]) 238 239 if mode == "set": 240 # Delete any packages which were removed 241 for package in original.keys(): 242 if package not in new: 243 if action: 244 session.execute("""DELETE FROM override 245 WHERE suite = :suiteid AND component = :componentid 246 AND package = :package AND type = :typeid""", 247 {'suiteid': suite_id, 'componentid': component_id, 248 'package': package, 'typeid': type_id}) 249 c_removed += 1 250 Logger.log(["removed override", suite, component, otype, package]) 251 252 if action: 253 session.commit() 254 255 if not cnf["Control-Overrides::Options::Quiet"]: 256 print("Done in %d seconds. [Updated = %d, Added = %d, Removed = %d, Skipped = %d, Errors = %d]" % (int(time.time() - start_time), c_updated, c_added, c_removed, c_skipped, c_error)) 257 258 Logger.log(["set complete", c_updated, c_added, c_removed, c_skipped, c_error])
259 260 ################################################################################ 261 262
263 -def list_overrides(suite, component, otype, session):
264 dat = {} 265 s = get_suite(suite, session) 266 if s is None: 267 utils.fubar("Suite '%s' not recognised." % (suite)) 268 269 dat['suiteid'] = s.suite_id 270 271 c = get_component(component, session) 272 if c is None: 273 utils.fubar("Component '%s' not recognised." % (component)) 274 275 dat['componentid'] = c.component_id 276 277 o = get_override_type(otype) 278 if o is None: 279 utils.fubar("Type '%s' not recognised. (Valid types are deb, udeb and dsc)" % (otype)) 280 281 dat['typeid'] = o.overridetype_id 282 283 if otype == "dsc": 284 q = session.execute("""SELECT o.package, s.section, o.maintainer FROM override o, section s 285 WHERE o.suite = :suiteid AND o.component = :componentid 286 AND o.type = :typeid AND o.section = s.id 287 ORDER BY s.section, o.package""", dat) 288 for i in q.fetchall(): 289 print(utils.result_join(i)) 290 else: 291 q = session.execute("""SELECT o.package, p.priority, s.section, o.maintainer, p.level 292 FROM override o, priority p, section s 293 WHERE o.suite = :suiteid AND o.component = :componentid 294 AND o.type = :typeid AND o.priority = p.id AND o.section = s.id 295 ORDER BY s.section, p.level, o.package""", dat) 296 for i in q.fetchall(): 297 print(utils.result_join(i[:-1]))
298 299 ################################################################################ 300 301
302 -def main():
303 global Logger 304 305 cnf = Config() 306 Arguments = [('a', "add", "Control-Overrides::Options::Add"), 307 ('c', "component", "Control-Overrides::Options::Component", "HasArg"), 308 ('h', "help", "Control-Overrides::Options::Help"), 309 ('l', "list", "Control-Overrides::Options::List"), 310 ('q', "quiet", "Control-Overrides::Options::Quiet"), 311 ('s', "suite", "Control-Overrides::Options::Suite", "HasArg"), 312 ('S', "set", "Control-Overrides::Options::Set"), 313 ('C', "change", "Control-Overrides::Options::Change"), 314 ('n', "no-action", "Control-Overrides::Options::No-Action"), 315 ('t', "type", "Control-Overrides::Options::Type", "HasArg")] 316 317 # Default arguments 318 for i in ["add", "help", "list", "quiet", "set", "change", "no-action"]: 319 key = "Control-Overrides::Options::%s" % i 320 if key not in cnf: 321 cnf[key] = "" 322 if "Control-Overrides::Options::Component" not in cnf: 323 cnf["Control-Overrides::Options::Component"] = "main" 324 if "Control-Overrides::Options::Suite" not in cnf: 325 cnf["Control-Overrides::Options::Suite"] = "unstable" 326 if "Control-Overrides::Options::Type" not in cnf: 327 cnf["Control-Overrides::Options::Type"] = "deb" 328 329 file_list = apt_pkg.parse_commandline(cnf.Cnf, Arguments, sys.argv) 330 331 if cnf["Control-Overrides::Options::Help"]: 332 usage() 333 334 session = DBConn().session() 335 336 mode = None 337 for i in ["add", "list", "set", "change"]: 338 if cnf["Control-Overrides::Options::%s" % (i)]: 339 if mode: 340 utils.fubar("Can not perform more than one action at once.") 341 mode = i 342 343 # Need an action... 344 if mode is None: 345 utils.fubar("No action specified.") 346 347 (suite, component, otype) = (cnf["Control-Overrides::Options::Suite"], 348 cnf["Control-Overrides::Options::Component"], 349 cnf["Control-Overrides::Options::Type"]) 350 351 if mode == "list": 352 list_overrides(suite, component, otype, session) 353 else: 354 if get_suite(suite).untouchable: 355 utils.fubar("%s: suite is untouchable" % suite) 356 357 action = True 358 if cnf["Control-Overrides::Options::No-Action"]: 359 utils.warn("In No-Action Mode") 360 action = False 361 362 Logger = daklog.Logger("control-overrides", mode) 363 if file_list: 364 for f in file_list: 365 process_file(open(f), suite, component, otype, mode, action, session) 366 else: 367 process_file(sys.stdin, suite, component, otype, mode, action, session) 368 Logger.close()
369 370 ####################################################################################### 371 372 373 if __name__ == '__main__': 374 main() 375