def main(): cnf = Config() Arguments = [('a', "architecture", "Ls::Options::Architecture", "HasArg"), ('b', "binarytype", "Ls::Options::BinaryType", "HasArg"), ('c', "component", "Ls::Options::Component", "HasArg"), ('f', "format", "Ls::Options::Format", "HasArg"), ('g', "greaterorequal", "Ls::Options::GreaterOrEqual"), ('G', "greaterthan", "Ls::Options::GreaterThan"), ('r', "regex", "Ls::Options::Regex"), ('s', "suite", "Ls::Options::Suite", "HasArg"), ('S', "source-and-binary", "Ls::Options::Source-And-Binary"), ('h', "help", "Ls::Options::Help")] for i in ["architecture", "binarytype", "component", "format", "greaterorequal", "greaterthan", "regex", "suite", "source-and-binary", "help"]: key = "Ls::Options::%s" % i if key not in cnf: cnf[key] = "" packages = apt_pkg.parse_commandline(cnf.Cnf, Arguments, sys.argv) Options = cnf.subtree("Ls::Options") if Options["Help"]: usage() if not packages: utils.fubar("need at least one package name as an argument.") # Handle buildd maintenance helper options if Options["GreaterOrEqual"] or Options["GreaterThan"]: if Options["GreaterOrEqual"] and Options["GreaterThan"]: utils.fubar("-g/--greaterorequal and -G/--greaterthan are mutually exclusive.") if not Options["Suite"]: Options["Suite"] = "unstable" kwargs = dict() if Options["Regex"]: kwargs['regex'] = True if Options["Source-And-Binary"]: kwargs['source_and_binary'] = True if Options["Suite"]: kwargs['suites'] = utils.split_args(Options['Suite']) if Options["Architecture"]: kwargs['architectures'] = utils.split_args(Options['Architecture']) if Options['BinaryType']: kwargs['binary_types'] = utils.split_args(Options['BinaryType']) if Options['Component']: kwargs['components'] = utils.split_args(Options['Component']) if Options['Format']: kwargs['format'] = Options['Format'] if Options['GreaterOrEqual']: kwargs['highest'] = '>=' elif Options['GreaterThan']: kwargs['highest'] = '>>' for line in list_packages(packages, **kwargs): print(line)
def main(): global Options, Logger cnf = Config() Arguments = [('h', "help", "Obsolete::Options::Help"), ('s', "suite", "Obsolete::Options::Suite", "HasArg"), ('n', "no-action", "Obsolete::Options::No-Action"), ('f', "force", "Obsolete::Options::Force")] cnf['Obsolete::Options::Help'] = '' cnf['Obsolete::Options::No-Action'] = '' cnf['Obsolete::Options::Force'] = '' apt_pkg.parse_commandline(cnf.Cnf, Arguments, sys.argv) Options = cnf.subtree("Obsolete::Options") if Options['Help']: usage() if 'Suite' not in Options: query_suites = DBConn().session().query(Suite) suites = [suite.suite_name for suite in query_suites.all()] cnf['Obsolete::Options::Suite'] = ','.join(suites) Logger = daklog.Logger("dominate") session = DBConn().session() for suite_name in utils.split_args(Options['Suite']): suite = session.query(Suite).filter_by(suite_name = suite_name).one() if not suite.untouchable or Options['Force']: doDaDoDa(suite.suite_id, session) if Options['No-Action']: session.rollback() else: session.commit() Logger.close()
def main(): cnf = Config() cnf['Contents::Options::Help'] = '' cnf['Contents::Options::Suite'] = '' cnf['Contents::Options::Component'] = '' cnf['Contents::Options::Limit'] = '' cnf['Contents::Options::Force'] = '' arguments = [ ('h', "help", 'Contents::Options::Help'), ('a', 'archive', 'Contents::Options::Archive', 'HasArg'), ('s', "suite", 'Contents::Options::Suite', "HasArg"), ('c', "component", 'Contents::Options::Component', "HasArg"), ('l', "limit", 'Contents::Options::Limit', "HasArg"), ('f', "force", 'Contents::Options::Force'), ] args = apt_pkg.parse_commandline(cnf.Cnf, arguments, sys.argv) options = cnf.subtree('Contents::Options') if (len(args) != 1) or options['Help']: usage() limit = None if len(options['Limit']) > 0: limit = int(options['Limit']) if args[0] == 'scan-source': source_scan_all(cnf, limit) return if args[0] == 'scan-binary': binary_scan_all(cnf, limit) return archive_names = utils.split_args(options['Archive']) suite_names = utils.split_args(options['Suite']) component_names = utils.split_args(options['Component']) force = bool(options['Force']) if args[0] == 'generate': write_all(cnf, archive_names, suite_names, component_names, force) return usage()
def main(): cnf = Config() cnf['Contents::Options::Help'] = '' cnf['Contents::Options::Suite'] = '' cnf['Contents::Options::Component'] = '' cnf['Contents::Options::Limit'] = '' cnf['Contents::Options::Force'] = '' arguments = [('h', "help", 'Contents::Options::Help'), ('a', 'archive', 'Contents::Options::Archive', 'HasArg'), ('s', "suite", 'Contents::Options::Suite', "HasArg"), ('c', "component", 'Contents::Options::Component', "HasArg"), ('l', "limit", 'Contents::Options::Limit', "HasArg"), ('f', "force", 'Contents::Options::Force'), ] args = apt_pkg.parse_commandline(cnf.Cnf, arguments, sys.argv) options = cnf.subtree('Contents::Options') if (len(args) != 1) or options['Help']: usage() limit = None if len(options['Limit']) > 0: limit = int(options['Limit']) if args[0] == 'scan-source': source_scan_all(cnf, limit) return if args[0] == 'scan-binary': binary_scan_all(cnf, limit) return archive_names = utils.split_args(options['Archive']) suite_names = utils.split_args(options['Suite']) component_names = utils.split_args(options['Component']) force = bool(options['Force']) if args[0] == 'generate': write_all(cnf, archive_names, suite_names, component_names, force) return usage()
def main(): global Options, Logger cnf = Config() Arguments = [('h', "help", "Obsolete::Options::Help"), ('s', "suite", "Obsolete::Options::Suite", "HasArg"), ('n', "no-action", "Obsolete::Options::No-Action"), ('f', "force", "Obsolete::Options::Force")] cnf['Obsolete::Options::Help'] = '' cnf['Obsolete::Options::No-Action'] = '' cnf['Obsolete::Options::Force'] = '' apt_pkg.parse_commandline(cnf.Cnf, Arguments, sys.argv) Options = cnf.subtree("Obsolete::Options") if Options['Help']: usage() if not Options['No-Action']: Logger = daklog.Logger("dominate") session = DBConn().session() suites_query = (session.query(Suite).order_by( Suite.suite_name).filter(~exists().where( Suite.suite_id == PolicyQueue.suite_id))) if 'Suite' in Options: suites_query = suites_query.filter( Suite.suite_name.in_(utils.split_args(Options['Suite']))) if not Options['Force']: suites_query = suites_query.filter_by(untouchable=False) suites = suites_query.all() assocs = list(retrieve_associations(suites, session)) if Options['No-Action']: headers = ('source package', 'source version', 'package', 'version', 'arch', 'suite', 'id') print(tabulate(assocs, headers, tablefmt="orgtbl")) session.rollback() else: delete_associations(assocs, session) session.commit() if Logger: Logger.close()
def main(): global Options, Logger cnf = Config() Arguments = [('h', "help", "Obsolete::Options::Help"), ('s', "suite", "Obsolete::Options::Suite", "HasArg"), ('n', "no-action", "Obsolete::Options::No-Action"), ('f', "force", "Obsolete::Options::Force")] cnf['Obsolete::Options::Help'] = '' cnf['Obsolete::Options::No-Action'] = '' cnf['Obsolete::Options::Force'] = '' apt_pkg.parse_commandline(cnf.Cnf, Arguments, sys.argv) Options = cnf.subtree("Obsolete::Options") if Options['Help']: usage() if not Options['No-Action']: Logger = daklog.Logger("dominate") session = DBConn().session() suites_query = (session .query(Suite) .order_by(Suite.suite_name) .filter(~exists().where(Suite.suite_id == PolicyQueue.suite_id))) if 'Suite' in Options: suites_query = suites_query.filter(Suite.suite_name.in_(utils.split_args(Options['Suite']))) if not Options['Force']: suites_query = suites_query.filter_by(untouchable=False) suites = suites_query.all() assocs = list(retrieve_associations(suites, session)) if Options['No-Action']: headers = ('source package', 'source version', 'package', 'version', 'arch', 'suite', 'id') print((tabulate(assocs, headers, tablefmt="orgtbl"))) session.rollback() else: delete_associations(assocs, session) session.commit() if Logger: Logger.close()
def main(): global Options, Logger cnf = Config() Arguments = [ ("h", "help", "Obsolete::Options::Help"), ("s", "suite", "Obsolete::Options::Suite", "HasArg"), ("n", "no-action", "Obsolete::Options::No-Action"), ("f", "force", "Obsolete::Options::Force"), ] cnf["Obsolete::Options::Help"] = "" cnf["Obsolete::Options::No-Action"] = "" cnf["Obsolete::Options::Force"] = "" apt_pkg.parse_commandline(cnf.Cnf, Arguments, sys.argv) Options = cnf.subtree("Obsolete::Options") if Options["Help"]: usage() if "Suite" not in Options: query_suites = DBConn().session().query(Suite) suites = [suite.suite_name for suite in query_suites] cnf["Obsolete::Options::Suite"] = str(",".join(suites)) if not Options["No-Action"]: Logger = daklog.Logger("dominate") session = DBConn().session() for suite_name in utils.split_args(Options["Suite"]): suite = session.query(Suite).filter_by(suite_name=suite_name).one() # Skip policy queues. We don't want to remove obsolete packages from those. policy_queue = session.query(PolicyQueue).filter_by(suite=suite).first() if policy_queue is not None: continue if not suite.untouchable or Options["Force"]: doDaDoDa(suite.suite_id, session) if Options["No-Action"]: session.rollback() else: session.commit() if Logger: Logger.close()
def main(): global Options, Logger cnf = Config() Arguments = [('h', "help", "Obsolete::Options::Help"), ('s', "suite", "Obsolete::Options::Suite", "HasArg"), ('n', "no-action", "Obsolete::Options::No-Action"), ('f', "force", "Obsolete::Options::Force")] cnf['Obsolete::Options::Help'] = '' cnf['Obsolete::Options::No-Action'] = '' cnf['Obsolete::Options::Force'] = '' apt_pkg.parse_commandline(cnf.Cnf, Arguments, sys.argv) Options = cnf.subtree("Obsolete::Options") if Options['Help']: usage() if 'Suite' not in Options: query_suites = DBConn().session().query(Suite) suites = [suite.suite_name for suite in query_suites] cnf['Obsolete::Options::Suite'] = str(','.join(suites)) if not Options['No-Action']: Logger = daklog.Logger("dominate") session = DBConn().session() for suite_name in utils.split_args(Options['Suite']): suite = session.query(Suite).filter_by(suite_name = suite_name).one() # Skip policy queues. We don't want to remove obsolete packages from those. policy_queue = session.query(PolicyQueue).filter_by(suite=suite).first() if policy_queue is not None: continue if not suite.untouchable or Options['Force']: doDaDoDa(suite.suite_id, session) if Options['No-Action']: session.rollback() else: session.commit() if Logger: Logger.close()
def main(): cnf = Config() cnf["Metadata::Options::Help"] = "" cnf["Metadata::Options::Suite"] = "" cnf["Metadata::Options::Limit"] = "" cnf["Metadata::Options::Force"] = "" arguments = [ ("h", "help", "Metadata::Options::Help"), ("s", "suite", "Metadata::Options::Suite", "HasArg"), ("l", "limit", "Metadata::Options::Limit", "HasArg"), ("f", "force", "Metadata::Options::Force"), ] args = apt_pkg.parse_commandline(cnf.Cnf, arguments, sys.argv) options = cnf.subtree("Metadata::Options") if (len(args) != 1) or options["Help"]: usage() limit = None if len(options["Limit"]) > 0: limit = int(options["Limit"]) if args[0] == "scan-source": scan_all(cnf, "source", limit) return elif args[0] == "scan-binary": scan_all(cnf, "binary", limit) return suite_names = utils.split_args(options["Suite"]) force = bool(options["Force"]) if args[0] == "generate": raise NotImplementError usage()
def main(): cnf = Config() Logger = daklog.Logger('generate-filelist') Arguments = [('h', "help", "Filelist::Options::Help"), ('s', "suite", "Filelist::Options::Suite", "HasArg"), ('c', "component", "Filelist::Options::Component", "HasArg"), ('a', "architecture", "Filelist::Options::Architecture", "HasArg"), ('i', "incremental", "Filelist::Options::Incremental")] session = DBConn().session() query_suites = session.query(Suite) suites = [suite.suite_name for suite in query_suites] if not cnf.has_key('Filelist::Options::Suite'): cnf['Filelist::Options::Suite'] = ','.join(suites).encode() query_components = session.query(Component) components = \ [component.component_name for component in query_components] if not cnf.has_key('Filelist::Options::Component'): cnf['Filelist::Options::Component'] = ','.join(components).encode() query_architectures = session.query(Architecture) architectures = \ [architecture.arch_string for architecture in query_architectures] if not cnf.has_key('Filelist::Options::Architecture'): cnf['Filelist::Options::Architecture'] = ','.join(architectures).encode() cnf['Filelist::Options::Help'] = '' cnf['Filelist::Options::Incremental'] = '' apt_pkg.parse_commandline(cnf.Cnf, Arguments, sys.argv) Options = cnf.subtree("Filelist::Options") if Options['Help']: usage() pool = DakProcessPool() query_suites = query_suites. \ filter(Suite.suite_name.in_(utils.split_args(Options['Suite']))) query_components = query_components. \ filter(Component.component_name.in_(utils.split_args(Options['Component']))) query_architectures = query_architectures. \ filter(Architecture.arch_string.in_(utils.split_args(Options['Architecture']))) def parse_results(message): # Split out into (code, msg) code, msg = message if code == PROC_STATUS_SUCCESS: Logger.log([msg]) elif code == PROC_STATUS_SIGNALRAISED: Logger.log(['E: Subprocess recieved signal ', msg]) else: Logger.log(['E: ', msg]) for suite in query_suites: suite_id = suite.suite_id for component in query_components: component_id = component.component_id for architecture in query_architectures: architecture_id = architecture.arch_id if architecture not in suite.architectures: pass elif architecture.arch_string == 'source': pool.apply_async(writeSourceList, (suite_id, component_id, Options['Incremental']), callback=parse_results) elif architecture.arch_string == 'all': pool.apply_async(writeAllList, (suite_id, component_id, architecture_id, 'deb', Options['Incremental']), callback=parse_results) pool.apply_async(writeAllList, (suite_id, component_id, architecture_id, 'udeb', Options['Incremental']), callback=parse_results) else: # arch any pool.apply_async(writeBinaryList, (suite_id, component_id, architecture_id, 'deb', Options['Incremental']), callback=parse_results) pool.apply_async(writeBinaryList, (suite_id, component_id, architecture_id, 'udeb', Options['Incremental']), callback=parse_results) pool.close() pool.join() # this script doesn't change the database session.close() Logger.close() sys.exit(pool.overall_status())
def main(): global Logger cnf = Config() for i in ["Help", "Suite", "Force", "Quiet"]: key = "Generate-Releases::Options::%s" % i if key not in cnf: cnf[key] = "" Arguments = [('h', "help", "Generate-Releases::Options::Help"), ('a', 'archive', 'Generate-Releases::Options::Archive', 'HasArg'), ('s', "suite", "Generate-Releases::Options::Suite"), ('f', "force", "Generate-Releases::Options::Force"), ('q', "quiet", "Generate-Releases::Options::Quiet"), ('o', 'option', '', 'ArbItem')] suite_names = apt_pkg.parse_commandline(cnf.Cnf, Arguments, sys.argv) Options = cnf.subtree("Generate-Releases::Options") if Options["Help"]: usage() Logger = daklog.Logger('generate-releases') pool = DakProcessPool() session = DBConn().session() if Options["Suite"]: suites = [] for s in suite_names: suite = get_suite(s.lower(), session) if suite: suites.append(suite) else: print("cannot find suite %s" % s) Logger.log(['cannot find suite %s' % s]) else: query = session.query(Suite).filter(Suite.untouchable == False) # noqa:E712 if 'Archive' in Options: archive_names = utils.split_args(Options['Archive']) query = query.join(Suite.archive).filter(Archive.archive_name.in_(archive_names)) suites = query.all() for s in suites: # Setup a multiprocessing Pool. As many workers as we have CPU cores. if s.untouchable and not Options["Force"]: print("Skipping %s (untouchable)" % s.suite_name) continue if not Options["Quiet"]: print("Processing %s" % s.suite_name) Logger.log(['Processing release file for Suite: %s' % (s.suite_name)]) pool.apply_async(generate_helper, (s.suite_id, )) # No more work will be added to our pool, close it and then wait for all to finish pool.close() pool.join() retcode = pool.overall_status() if retcode > 0: # TODO: CENTRAL FUNCTION FOR THIS / IMPROVE LOGGING Logger.log(['Release file generation broken: %s' % (','.join([str(x[1]) for x in pool.results]))]) Logger.close() sys.exit(retcode)
def main (): global Options cnf = Config() Arguments = [('h',"help","Rm::Options::Help"), ('A','no-arch-all-rdeps','Rm::Options::NoArchAllRdeps'), ('a',"architecture","Rm::Options::Architecture", "HasArg"), ('b',"binary", "Rm::Options::Binary"), ('B',"binary-only", "Rm::Options::Binary-Only"), ('c',"component", "Rm::Options::Component", "HasArg"), ('C',"carbon-copy", "Rm::Options::Carbon-Copy", "HasArg"), # Bugs to Cc ('d',"done","Rm::Options::Done", "HasArg"), # Bugs fixed ('D',"do-close","Rm::Options::Do-Close"), ('R',"rdep-check", "Rm::Options::Rdep-Check"), ('m',"reason", "Rm::Options::Reason", "HasArg"), # Hysterical raisins; -m is old-dinstall option for rejection reason ('n',"no-action","Rm::Options::No-Action"), ('p',"partial", "Rm::Options::Partial"), ('s',"suite","Rm::Options::Suite", "HasArg"), ('S',"source-only", "Rm::Options::Source-Only"), ] for i in [ 'NoArchAllRdeps', "architecture", "binary", "binary-only", "carbon-copy", "component", "done", "help", "no-action", "partial", "rdep-check", "reason", "source-only", "Do-Close" ]: if not cnf.has_key("Rm::Options::%s" % (i)): cnf["Rm::Options::%s" % (i)] = "" if not cnf.has_key("Rm::Options::Suite"): cnf["Rm::Options::Suite"] = "unstable" arguments = apt_pkg.parse_commandline(cnf.Cnf, Arguments, sys.argv) Options = cnf.subtree("Rm::Options") if Options["Help"]: usage() session = DBConn().session() # Sanity check options if not arguments: utils.fubar("need at least one package name as an argument.") if Options["Architecture"] and Options["Source-Only"]: utils.fubar("can't use -a/--architecture and -S/--source-only options simultaneously.") if ((Options["Binary"] and Options["Source-Only"]) or (Options["Binary"] and Options["Binary-Only"]) or (Options["Binary-Only"] and Options["Source-Only"])): utils.fubar("Only one of -b/--binary, -B/--binary-only and -S/--source-only can be used.") if Options.has_key("Carbon-Copy") and not Options.has_key("Done"): utils.fubar("can't use -C/--carbon-copy without also using -d/--done option.") if Options["Architecture"] and not Options["Partial"]: utils.warn("-a/--architecture implies -p/--partial.") Options["Partial"] = "true" if Options["Do-Close"] and not Options["Done"]: utils.fubar("No.") if (Options["Do-Close"] and (Options["Binary"] or Options["Binary-Only"] or Options["Source-Only"])): utils.fubar("No.") # Force the admin to tell someone if we're not doing a 'dak # cruft-report' inspired removal (or closing a bug, which counts # as telling someone). if not Options["No-Action"] and not Options["Carbon-Copy"] \ and not Options["Done"] and Options["Reason"].find("[auto-cruft]") == -1: utils.fubar("Need a -C/--carbon-copy if not closing a bug and not doing a cruft removal.") # Process -C/--carbon-copy # # Accept 3 types of arguments (space separated): # 1) a number - assumed to be a bug number, i.e. [email protected] # 2) the keyword 'package' - cc's [email protected] for every argument # 3) contains a '@' - assumed to be an email address, used unmodified # carbon_copy = [] for copy_to in utils.split_args(Options.get("Carbon-Copy")): if copy_to.isdigit(): if cnf.has_key("Dinstall::BugServer"): carbon_copy.append(copy_to + "@" + cnf["Dinstall::BugServer"]) else: utils.fubar("Asked to send mail to #%s in BTS but Dinstall::BugServer is not configured" % copy_to) elif copy_to == 'package': for package in arguments: if cnf.has_key("Dinstall::PackagesServer"): carbon_copy.append(package + "@" + cnf["Dinstall::PackagesServer"]) if cnf.has_key("Dinstall::TrackingServer"): carbon_copy.append(package + "@" + cnf["Dinstall::TrackingServer"]) elif '@' in copy_to: carbon_copy.append(copy_to) else: utils.fubar("Invalid -C/--carbon-copy argument '%s'; not a bug number, 'package' or email address." % (copy_to)) if Options["Binary"]: field = "b.package" else: field = "s.source" con_packages = "AND %s IN (%s)" % (field, ", ".join([ repr(i) for i in arguments ])) (con_suites, con_architectures, con_components, check_source) = \ utils.parse_args(Options) # Additional suite checks suite_ids_list = [] whitelists = [] suites = utils.split_args(Options["Suite"]) suites_list = utils.join_with_commas_and(suites) if not Options["No-Action"]: for suite in suites: s = get_suite(suite, session=session) if s is not None: suite_ids_list.append(s.suite_id) whitelists.append(s.mail_whitelist) if suite in ("oldstable", "stable"): print "**WARNING** About to remove from the (old)stable suite!" print "This should only be done just prior to a (point) release and not at" print "any other time." game_over() elif suite == "testing": print "**WARNING About to remove from the testing suite!" print "There's no need to do this normally as removals from unstable will" print "propogate to testing automagically." game_over() # Additional architecture checks if Options["Architecture"] and check_source: utils.warn("'source' in -a/--argument makes no sense and is ignored.") # Don't do dependency checks on multiple suites if Options["Rdep-Check"] and len(suites) > 1: utils.fubar("Reverse dependency check on multiple suites is not implemented.") to_remove = [] maintainers = {} # We have 3 modes of package selection: binary, source-only, binary-only # and source+binary. # XXX: TODO: This all needs converting to use placeholders or the object # API. It's an SQL injection dream at the moment if Options["Binary"]: # Removal by binary package name q = session.execute("SELECT b.package, b.version, a.arch_string, b.id, b.maintainer FROM binaries b, bin_associations ba, architecture a, suite su, files f, files_archive_map af, component c WHERE ba.bin = b.id AND ba.suite = su.id AND b.architecture = a.id AND b.file = f.id AND af.file_id = f.id AND af.archive_id = su.archive_id AND af.component_id = c.id %s %s %s %s" % (con_packages, con_suites, con_components, con_architectures)) to_remove.extend(q) else: # Source-only if not Options["Binary-Only"]: q = session.execute("SELECT s.source, s.version, 'source', s.id, s.maintainer FROM source s, src_associations sa, suite su, archive, files f, files_archive_map af, component c WHERE sa.source = s.id AND sa.suite = su.id AND archive.id = su.archive_id AND s.file = f.id AND af.file_id = f.id AND af.archive_id = su.archive_id AND af.component_id = c.id %s %s %s" % (con_packages, con_suites, con_components)) to_remove.extend(q) if not Options["Source-Only"]: # Source + Binary q = session.execute(""" SELECT b.package, b.version, a.arch_string, b.id, b.maintainer FROM binaries b JOIN bin_associations ba ON b.id = ba.bin JOIN architecture a ON b.architecture = a.id JOIN suite su ON ba.suite = su.id JOIN archive ON archive.id = su.archive_id JOIN files_archive_map af ON b.file = af.file_id AND af.archive_id = archive.id JOIN component c ON af.component_id = c.id JOIN source s ON b.source = s.id JOIN src_associations sa ON s.id = sa.source AND sa.suite = su.id WHERE TRUE %s %s %s %s""" % (con_packages, con_suites, con_components, con_architectures)) to_remove.extend(q) if not to_remove: print "Nothing to do." sys.exit(0) # If we don't have a reason; spawn an editor so the user can add one # Write the rejection email out as the <foo>.reason file if not Options["Reason"] and not Options["No-Action"]: (fd, temp_filename) = utils.temp_filename() editor = os.environ.get("EDITOR","vi") result = os.system("%s %s" % (editor, temp_filename)) if result != 0: utils.fubar ("vi invocation failed for `%s'!" % (temp_filename), result) temp_file = utils.open_file(temp_filename) for line in temp_file.readlines(): Options["Reason"] += line temp_file.close() os.unlink(temp_filename) # Generate the summary of what's to be removed d = {} for i in to_remove: package = i[0] version = i[1] architecture = i[2] maintainer = i[4] maintainers[maintainer] = "" if not d.has_key(package): d[package] = {} if not d[package].has_key(version): d[package][version] = [] if architecture not in d[package][version]: d[package][version].append(architecture) maintainer_list = [] for maintainer_id in maintainers.keys(): maintainer_list.append(get_maintainer(maintainer_id).name) summary = "" removals = d.keys() removals.sort() for package in removals: versions = d[package].keys() versions.sort(apt_pkg.version_compare) for version in versions: d[package][version].sort(utils.arch_compare_sw) summary += "%10s | %10s | %s\n" % (package, version, ", ".join(d[package][version])) print "Will remove the following packages from %s:" % (suites_list) print print summary print "Maintainer: %s" % ", ".join(maintainer_list) if Options["Done"]: print "Will also close bugs: "+Options["Done"] if carbon_copy: print "Will also send CCs to: " + ", ".join(carbon_copy) if Options["Do-Close"]: print "Will also close associated bug reports." print print "------------------- Reason -------------------" print Options["Reason"] print "----------------------------------------------" print if Options["Rdep-Check"]: arches = utils.split_args(Options["Architecture"]) include_arch_all = Options['NoArchAllRdeps'] == '' reverse_depends_check(removals, suites[0], arches, session, include_arch_all=include_arch_all) # If -n/--no-action, drop out here if Options["No-Action"]: sys.exit(0) print "Going to remove the packages now." game_over() # Do the actual deletion print "Deleting...", sys.stdout.flush() try: bugs = utils.split_args(Options["Done"]) remove(session, Options["Reason"], suites, to_remove, partial=Options["Partial"], components=utils.split_args(Options["Component"]), done_bugs=bugs, carbon_copy=carbon_copy, close_related_bugs=Options["Do-Close"] ) except ValueError as ex: utils.fubar(ex.message) else: print "done."
def main(): global Options cnf = Config() Arguments = [ ('h', "help", "Rm::Options::Help"), ('A', 'no-arch-all-rdeps', 'Rm::Options::NoArchAllRdeps'), ('a', "architecture", "Rm::Options::Architecture", "HasArg"), ('b', "binary", "Rm::Options::Binary"), ('B', "binary-only", "Rm::Options::Binary-Only"), ('c', "component", "Rm::Options::Component", "HasArg"), ('C', "carbon-copy", "Rm::Options::Carbon-Copy", "HasArg"), # Bugs to Cc ('d', "done", "Rm::Options::Done", "HasArg"), # Bugs fixed ('D', "do-close", "Rm::Options::Do-Close"), ('R', "rdep-check", "Rm::Options::Rdep-Check"), ( 'm', "reason", "Rm::Options::Reason", "HasArg" ), # Hysterical raisins; -m is old-dinstall option for rejection reason ('n', "no-action", "Rm::Options::No-Action"), ('p', "partial", "Rm::Options::Partial"), ('s', "suite", "Rm::Options::Suite", "HasArg"), ('S', "source-only", "Rm::Options::Source-Only"), ] for i in [ 'NoArchAllRdeps', "architecture", "binary", "binary-only", "carbon-copy", "component", "done", "help", "no-action", "partial", "rdep-check", "reason", "source-only", "Do-Close" ]: key = "Rm::Options::%s" % (i) if key not in cnf: cnf[key] = "" if "Rm::Options::Suite" not in cnf: cnf["Rm::Options::Suite"] = "unstable" arguments = apt_pkg.parse_commandline(cnf.Cnf, Arguments, sys.argv) Options = cnf.subtree("Rm::Options") if Options["Help"]: usage() session = DBConn().session() # Sanity check options if not arguments: utils.fubar("need at least one package name as an argument.") if Options["Architecture"] and Options["Source-Only"]: utils.fubar( "can't use -a/--architecture and -S/--source-only options simultaneously." ) if ((Options["Binary"] and Options["Source-Only"]) or (Options["Binary"] and Options["Binary-Only"]) or (Options["Binary-Only"] and Options["Source-Only"])): utils.fubar( "Only one of -b/--binary, -B/--binary-only and -S/--source-only can be used." ) if "Carbon-Copy" not in Options and "Done" not in Options: utils.fubar( "can't use -C/--carbon-copy without also using -d/--done option.") if Options["Architecture"] and not Options["Partial"]: utils.warn("-a/--architecture implies -p/--partial.") Options["Partial"] = "true" if Options["Do-Close"] and not Options["Done"]: utils.fubar("No.") if (Options["Do-Close"] and (Options["Binary"] or Options["Binary-Only"] or Options["Source-Only"])): utils.fubar("No.") # Force the admin to tell someone if we're not doing a 'dak # cruft-report' inspired removal (or closing a bug, which counts # as telling someone). if not Options["No-Action"] and not Options["Carbon-Copy"] \ and not Options["Done"] and Options["Reason"].find("[auto-cruft]") == -1: utils.fubar( "Need a -C/--carbon-copy if not closing a bug and not doing a cruft removal." ) if Options["Binary"]: field = "b.package" else: field = "s.source" con_packages = "AND %s IN (%s)" % (field, ", ".join( [repr(i) for i in arguments])) (con_suites, con_architectures, con_components, check_source) = \ utils.parse_args(Options) # Additional suite checks suite_ids_list = [] whitelists = [] suites = utils.split_args(Options["Suite"]) suites_list = utils.join_with_commas_and(suites) if not Options["No-Action"]: for suite in suites: s = get_suite(suite, session=session) if s is not None: suite_ids_list.append(s.suite_id) whitelists.append(s.mail_whitelist) if suite in ("oldstable", "stable"): print( "**WARNING** About to remove from the (old)stable suite!") print( "This should only be done just prior to a (point) release and not at" ) print("any other time.") game_over() elif suite == "testing": print("**WARNING About to remove from the testing suite!") print( "There's no need to do this normally as removals from unstable will" ) print("propogate to testing automagically.") game_over() # Additional architecture checks if Options["Architecture"] and check_source: utils.warn("'source' in -a/--argument makes no sense and is ignored.") # Don't do dependency checks on multiple suites if Options["Rdep-Check"] and len(suites) > 1: utils.fubar( "Reverse dependency check on multiple suites is not implemented.") to_remove = [] maintainers = {} # We have 3 modes of package selection: binary, source-only, binary-only # and source+binary. # XXX: TODO: This all needs converting to use placeholders or the object # API. It's an SQL injection dream at the moment if Options["Binary"]: # Removal by binary package name q = session.execute(""" SELECT b.package, b.version, a.arch_string, b.id, b.maintainer, s.source FROM binaries b JOIN source s ON s.id = b.source JOIN bin_associations ba ON ba.bin = b.id JOIN architecture a ON a.id = b.architecture JOIN suite su ON su.id = ba.suite JOIN files f ON f.id = b.file JOIN files_archive_map af ON af.file_id = f.id AND af.archive_id = su.archive_id JOIN component c ON c.id = af.component_id WHERE TRUE %s %s %s %s """ % (con_packages, con_suites, con_components, con_architectures)) to_remove.extend(q) else: # Source-only if not Options["Binary-Only"]: q = session.execute(""" SELECT s.source, s.version, 'source', s.id, s.maintainer, s.source FROM source s JOIN src_associations sa ON sa.source = s.id JOIN suite su ON su.id = sa.suite JOIN archive ON archive.id = su.archive_id JOIN files f ON f.id = s.file JOIN files_archive_map af ON af.file_id = f.id AND af.archive_id = su.archive_id JOIN component c ON c.id = af.component_id WHERE TRUE %s %s %s """ % (con_packages, con_suites, con_components)) to_remove.extend(q) if not Options["Source-Only"]: # Source + Binary q = session.execute( """ SELECT b.package, b.version, a.arch_string, b.id, b.maintainer, s.source FROM binaries b JOIN bin_associations ba ON b.id = ba.bin JOIN architecture a ON b.architecture = a.id JOIN suite su ON ba.suite = su.id JOIN archive ON archive.id = su.archive_id JOIN files_archive_map af ON b.file = af.file_id AND af.archive_id = archive.id JOIN component c ON af.component_id = c.id JOIN source s ON b.source = s.id JOIN src_associations sa ON s.id = sa.source AND sa.suite = su.id WHERE TRUE %s %s %s %s""" % (con_packages, con_suites, con_components, con_architectures)) to_remove.extend(q) if not to_remove: print("Nothing to do.") sys.exit(0) # Process -C/--carbon-copy # # Accept 3 types of arguments (space separated): # 1) a number - assumed to be a bug number, i.e. [email protected] # 2) the keyword 'package' - cc's [email protected] for every argument # 3) contains a '@' - assumed to be an email address, used unmodified # carbon_copy = [] for copy_to in utils.split_args(Options.get("Carbon-Copy")): if copy_to.isdigit(): if "Dinstall::BugServer" in cnf: carbon_copy.append(copy_to + "@" + cnf["Dinstall::BugServer"]) else: utils.fubar( "Asked to send mail to #%s in BTS but Dinstall::BugServer is not configured" % copy_to) elif copy_to == 'package': for package in set([s[5] for s in to_remove]): if "Dinstall::PackagesServer" in cnf: carbon_copy.append(package + "@" + cnf["Dinstall::PackagesServer"]) elif '@' in copy_to: carbon_copy.append(copy_to) else: utils.fubar( "Invalid -C/--carbon-copy argument '%s'; not a bug number, 'package' or email address." % (copy_to)) # If we don't have a reason; spawn an editor so the user can add one # Write the rejection email out as the <foo>.reason file if not Options["Reason"] and not Options["No-Action"]: (fd, temp_filename) = utils.temp_filename() editor = os.environ.get("EDITOR", "vi") result = os.system("%s %s" % (editor, temp_filename)) if result != 0: utils.fubar("vi invocation failed for `%s'!" % (temp_filename), result) temp_file = utils.open_file(temp_filename) for line in temp_file.readlines(): Options["Reason"] += line temp_file.close() os.unlink(temp_filename) # Generate the summary of what's to be removed d = {} for i in to_remove: package = i[0] version = i[1] architecture = i[2] maintainer = i[4] maintainers[maintainer] = "" if package not in d: d[package] = {} if version not in d[package]: d[package][version] = [] if architecture not in d[package][version]: d[package][version].append(architecture) maintainer_list = [] for maintainer_id in maintainers.keys(): maintainer_list.append(get_maintainer(maintainer_id).name) summary = "" removals = d.keys() removals.sort() for package in removals: versions = d[package].keys() versions.sort(key=functools.cmp_to_key(apt_pkg.version_compare)) for version in versions: d[package][version].sort(key=utils.ArchKey) summary += "%10s | %10s | %s\n" % (package, version, ", ".join( d[package][version])) print("Will remove the following packages from %s:" % (suites_list)) print() print(summary) print("Maintainer: %s" % ", ".join(maintainer_list)) if Options["Done"]: print("Will also close bugs: " + Options["Done"]) if carbon_copy: print("Will also send CCs to: " + ", ".join(carbon_copy)) if Options["Do-Close"]: print("Will also close associated bug reports.") print() print("------------------- Reason -------------------") print(Options["Reason"]) print("----------------------------------------------") print() if Options["Rdep-Check"]: arches = utils.split_args(Options["Architecture"]) include_arch_all = Options['NoArchAllRdeps'] == '' reverse_depends_check(removals, suites[0], arches, session, include_arch_all=include_arch_all) # If -n/--no-action, drop out here if Options["No-Action"]: sys.exit(0) print("Going to remove the packages now.") game_over() # Do the actual deletion print("Deleting...", end=' ') sys.stdout.flush() try: bugs = utils.split_args(Options["Done"]) remove(session, Options["Reason"], suites, to_remove, partial=Options["Partial"], components=utils.split_args(Options["Component"]), done_bugs=bugs, carbon_copy=carbon_copy, close_related_bugs=Options["Do-Close"]) except ValueError as ex: utils.fubar(ex.message) else: print("done.")
def main(): cnf = Config() Arguments = [ ("h", "help", "Override::Options::Help"), ("c", "check", "Override::Options::Check"), ("d", "done", "Override::Options::Done", "HasArg"), ("n", "no-action", "Override::Options::No-Action"), ("s", "suite", "Override::Options::Suite", "HasArg"), ] for i in ["help", "check", "no-action"]: if not cnf.has_key("Override::Options::%s" % (i)): cnf["Override::Options::%s" % (i)] = "" if not cnf.has_key("Override::Options::Suite"): cnf["Override::Options::Suite"] = "unstable" arguments = apt_pkg.parse_commandline(cnf.Cnf, Arguments, sys.argv) Options = cnf.subtree("Override::Options") if Options["Help"]: usage() session = DBConn().session() if not arguments: utils.fubar("package name is a required argument.") package = arguments.pop(0) suite_name = Options["Suite"] if arguments and len(arguments) > 2: utils.fubar("Too many arguments") suite = get_suite(suite_name, session) if suite is None: utils.fubar("Unknown suite '{0}'".format(suite_name)) if arguments and len(arguments) == 1: # Determine if the argument is a priority or a section... arg = arguments.pop() q = session.execute( """ SELECT ( SELECT COUNT(*) FROM section WHERE section = :arg ) AS secs, ( SELECT COUNT(*) FROM priority WHERE priority = :arg ) AS prios """, {"arg": arg}, ) r = q.fetchall() if r[0][0] == 1: arguments = (arg, ".") elif r[0][1] == 1: arguments = (".", arg) else: utils.fubar("%s is not a valid section or priority" % (arg)) # Retrieve current section/priority... oldsection, oldsourcesection, oldpriority = None, None, None for packagetype in ["source", "binary"]: eqdsc = "!=" if packagetype == "source": eqdsc = "=" q = session.execute( """ SELECT priority.priority AS prio, section.section AS sect, override_type.type AS type FROM override, priority, section, suite, override_type WHERE override.priority = priority.id AND override.type = override_type.id AND override_type.type %s 'dsc' AND override.section = section.id AND override.package = :package AND override.suite = suite.id AND suite.suite_name = :suite_name """ % (eqdsc), {"package": package, "suite_name": suite_name}, ) if q.rowcount == 0: continue if q.rowcount > 1: utils.fubar("%s is ambiguous. Matches %d packages" % (package, q.rowcount)) r = q.fetchone() if packagetype == "binary": oldsection = r[1] oldpriority = r[0] else: oldsourcesection = r[1] oldpriority = "source" if not oldpriority and not oldsourcesection: utils.fubar("Unable to find package %s" % (package)) if oldsection and oldsourcesection and oldsection != oldsourcesection: # When setting overrides, both source & binary will become the same section utils.warn("Source is in section '%s' instead of '%s'" % (oldsourcesection, oldsection)) if not oldsection: oldsection = oldsourcesection if not arguments: print "%s is in section '%s' at priority '%s'" % (package, oldsection, oldpriority) sys.exit(0) # At this point, we have a new section and priority... check they're valid... newsection, newpriority = arguments if newsection == ".": newsection = oldsection if newpriority == ".": newpriority = oldpriority s = get_section(newsection, session) if s is None: utils.fubar("Supplied section %s is invalid" % (newsection)) newsecid = s.section_id p = get_priority(newpriority, session) if p is None: utils.fubar("Supplied priority %s is invalid" % (newpriority)) newprioid = p.priority_id if newpriority == oldpriority and newsection == oldsection: print "I: Doing nothing" sys.exit(0) if oldpriority == "source" and newpriority != "source": utils.fubar("Trying to change priority of a source-only package") if Options["Check"] and newpriority != oldpriority: check_override_compliance(package, p, suite.archive.path, suite_name, cnf, session) # If we're in no-action mode if Options["No-Action"]: if newpriority != oldpriority: print "I: Would change priority from %s to %s" % (oldpriority, newpriority) if newsection != oldsection: print "I: Would change section from %s to %s" % (oldsection, newsection) if Options.has_key("Done"): print "I: Would also close bug(s): %s" % (Options["Done"]) sys.exit(0) if newpriority != oldpriority: print "I: Will change priority from %s to %s" % (oldpriority, newpriority) if newsection != oldsection: print "I: Will change section from %s to %s" % (oldsection, newsection) if not Options.has_key("Done"): pass # utils.warn("No bugs to close have been specified. Noone will know you have done this.") else: print "I: Will close bug(s): %s" % (Options["Done"]) game_over() Logger = daklog.Logger("override") dsc_otype_id = get_override_type("dsc").overridetype_id # We're already in a transaction # We're in "do it" mode, we have something to do... do it if newpriority != oldpriority: session.execute( """ UPDATE override SET priority = :newprioid WHERE package = :package AND override.type != :otypedsc AND suite = (SELECT id FROM suite WHERE suite_name = :suite_name)""", {"newprioid": newprioid, "package": package, "otypedsc": dsc_otype_id, "suite_name": suite_name}, ) Logger.log(["changed priority", package, oldpriority, newpriority]) if newsection != oldsection: q = session.execute( """ UPDATE override SET section = :newsecid WHERE package = :package AND suite = (SELECT id FROM suite WHERE suite_name = :suite_name)""", {"newsecid": newsecid, "package": package, "suite_name": suite_name}, ) Logger.log(["changed section", package, oldsection, newsection]) session.commit() if Options.has_key("Done"): if not cnf.has_key("Dinstall::BugServer"): utils.warn("Asked to send Done message but Dinstall::BugServer is not configured") Logger.close() return Subst = {} Subst["__OVERRIDE_ADDRESS__"] = cnf["Dinstall::MyEmailAddress"] Subst["__BUG_SERVER__"] = cnf["Dinstall::BugServer"] bcc = [] if cnf.find("Dinstall::Bcc") != "": bcc.append(cnf["Dinstall::Bcc"]) if bcc: Subst["__BCC__"] = "Bcc: " + ", ".join(bcc) else: Subst["__BCC__"] = "X-Filler: 42" if cnf.has_key("Dinstall::PackagesServer"): Subst["__CC__"] = "Cc: " + package + "@" + cnf["Dinstall::PackagesServer"] + "\nX-DAK: dak override" else: Subst["__CC__"] = "X-DAK: dak override" Subst["__ADMIN_ADDRESS__"] = cnf["Dinstall::MyAdminAddress"] Subst["__DISTRO__"] = cnf["Dinstall::MyDistribution"] Subst["__WHOAMI__"] = utils.whoami() Subst["__SOURCE__"] = package summary = "Concerning package %s...\n" % (package) summary += "Operating on the %s suite\n" % (suite_name) if newpriority != oldpriority: summary += "Changed priority from %s to %s\n" % (oldpriority, newpriority) if newsection != oldsection: summary += "Changed section from %s to %s\n" % (oldsection, newsection) Subst["__SUMMARY__"] = summary template = os.path.join(cnf["Dir::Templates"], "override.bug-close") for bug in utils.split_args(Options["Done"]): Subst["__BUG_NUMBER__"] = bug mail_message = utils.TemplateSubst(Subst, template) utils.send_mail(mail_message) Logger.log(["closed bug", bug]) Logger.close()
def main (): global Options cnf = Config() Arguments = [('h',"help","Rm::Options::Help"), ('a',"architecture","Rm::Options::Architecture", "HasArg"), ('b',"binary", "Rm::Options::Binary"), ('B',"binary-only", "Rm::Options::Binary-Only"), ('c',"component", "Rm::Options::Component", "HasArg"), ('C',"carbon-copy", "Rm::Options::Carbon-Copy", "HasArg"), # Bugs to Cc ('d',"done","Rm::Options::Done", "HasArg"), # Bugs fixed ('D',"do-close","Rm::Options::Do-Close"), ('R',"rdep-check", "Rm::Options::Rdep-Check"), ('m',"reason", "Rm::Options::Reason", "HasArg"), # Hysterical raisins; -m is old-dinstall option for rejection reason ('n',"no-action","Rm::Options::No-Action"), ('p',"partial", "Rm::Options::Partial"), ('s',"suite","Rm::Options::Suite", "HasArg"), ('S',"source-only", "Rm::Options::Source-Only"), ] for i in [ "architecture", "binary", "binary-only", "carbon-copy", "component", "done", "help", "no-action", "partial", "rdep-check", "reason", "source-only", "Do-Close" ]: if not cnf.has_key("Rm::Options::%s" % (i)): cnf["Rm::Options::%s" % (i)] = "" if not cnf.has_key("Rm::Options::Suite"): cnf["Rm::Options::Suite"] = "unstable" arguments = apt_pkg.parse_commandline(cnf.Cnf, Arguments, sys.argv) Options = cnf.subtree("Rm::Options") if Options["Help"]: usage() session = DBConn().session() # Sanity check options if not arguments: utils.fubar("need at least one package name as an argument.") if Options["Architecture"] and Options["Source-Only"]: utils.fubar("can't use -a/--architecture and -S/--source-only options simultaneously.") if ((Options["Binary"] and Options["Source-Only"]) or (Options["Binary"] and Options["Binary-Only"]) or (Options["Binary-Only"] and Options["Source-Only"])): utils.fubar("Only one of -b/--binary, -B/--binary-only and -S/--source-only can be used.") if Options.has_key("Carbon-Copy") and not Options.has_key("Done"): utils.fubar("can't use -C/--carbon-copy without also using -d/--done option.") if Options["Architecture"] and not Options["Partial"]: utils.warn("-a/--architecture implies -p/--partial.") Options["Partial"] = "true" if Options["Do-Close"] and not Options["Done"]: utils.fubar("No.") if (Options["Do-Close"] and (Options["Binary"] or Options["Binary-Only"] or Options["Source-Only"])): utils.fubar("No.") # Force the admin to tell someone if we're not doing a 'dak # cruft-report' inspired removal (or closing a bug, which counts # as telling someone). if not Options["No-Action"] and not Options["Carbon-Copy"] \ and not Options["Done"] and Options["Reason"].find("[auto-cruft]") == -1: utils.fubar("Need a -C/--carbon-copy if not closing a bug and not doing a cruft removal.") # Process -C/--carbon-copy # # Accept 3 types of arguments (space separated): # 1) a number - assumed to be a bug number, i.e. [email protected] # 2) the keyword 'package' - cc's [email protected] for every argument # 3) contains a '@' - assumed to be an email address, used unmofidied # carbon_copy = [] for copy_to in utils.split_args(Options.get("Carbon-Copy")): if copy_to.isdigit(): if cnf.has_key("Dinstall::BugServer"): carbon_copy.append(copy_to + "@" + cnf["Dinstall::BugServer"]) else: utils.fubar("Asked to send mail to #%s in BTS but Dinstall::BugServer is not configured" % copy_to) elif copy_to == 'package': for package in arguments: if cnf.has_key("Dinstall::PackagesServer"): carbon_copy.append(package + "@" + cnf["Dinstall::PackagesServer"]) if cnf.has_key("Dinstall::TrackingServer"): carbon_copy.append(package + "@" + cnf["Dinstall::TrackingServer"]) elif '@' in copy_to: carbon_copy.append(copy_to) else: utils.fubar("Invalid -C/--carbon-copy argument '%s'; not a bug number, 'package' or email address." % (copy_to)) if Options["Binary"]: field = "b.package" else: field = "s.source" con_packages = "AND %s IN (%s)" % (field, ", ".join([ repr(i) for i in arguments ])) (con_suites, con_architectures, con_components, check_source) = \ utils.parse_args(Options) # Additional suite checks suite_ids_list = [] whitelists = [] suites = utils.split_args(Options["Suite"]) suites_list = utils.join_with_commas_and(suites) if not Options["No-Action"]: for suite in suites: s = get_suite(suite, session=session) if s is not None: suite_ids_list.append(s.suite_id) whitelists.append(s.mail_whitelist) if suite in ("oldstable", "stable"): print "**WARNING** About to remove from the (old)stable suite!" print "This should only be done just prior to a (point) release and not at" print "any other time." game_over() elif suite == "testing": print "**WARNING About to remove from the testing suite!" print "There's no need to do this normally as removals from unstable will" print "propogate to testing automagically." game_over() # Additional architecture checks if Options["Architecture"] and check_source: utils.warn("'source' in -a/--argument makes no sense and is ignored.") # Additional component processing over_con_components = con_components.replace("c.id", "component") # Don't do dependency checks on multiple suites if Options["Rdep-Check"] and len(suites) > 1: utils.fubar("Reverse dependency check on multiple suites is not implemented.") to_remove = [] maintainers = {} # We have 3 modes of package selection: binary, source-only, binary-only # and source+binary. # XXX: TODO: This all needs converting to use placeholders or the object # API. It's an SQL injection dream at the moment if Options["Binary"]: # Removal by binary package name q = session.execute("SELECT b.package, b.version, a.arch_string, b.id, b.maintainer FROM binaries b, bin_associations ba, architecture a, suite su, files f, files_archive_map af, component c WHERE ba.bin = b.id AND ba.suite = su.id AND b.architecture = a.id AND b.file = f.id AND af.file_id = f.id AND af.archive_id = su.archive_id AND af.component_id = c.id %s %s %s %s" % (con_packages, con_suites, con_components, con_architectures)) to_remove.extend(q) else: # Source-only if not Options["Binary-Only"]: q = session.execute("SELECT s.source, s.version, 'source', s.id, s.maintainer FROM source s, src_associations sa, suite su, archive, files f, files_archive_map af, component c WHERE sa.source = s.id AND sa.suite = su.id AND archive.id = su.archive_id AND s.file = f.id AND af.file_id = f.id AND af.archive_id = su.archive_id AND af.component_id = c.id %s %s %s" % (con_packages, con_suites, con_components)) to_remove.extend(q) if not Options["Source-Only"]: # Source + Binary q = session.execute(""" SELECT b.package, b.version, a.arch_string, b.id, b.maintainer FROM binaries b JOIN bin_associations ba ON b.id = ba.bin JOIN architecture a ON b.architecture = a.id JOIN suite su ON ba.suite = su.id JOIN archive ON archive.id = su.archive_id JOIN files_archive_map af ON b.file = af.file_id AND af.archive_id = archive.id JOIN component c ON af.component_id = c.id JOIN source s ON b.source = s.id JOIN src_associations sa ON s.id = sa.source AND sa.suite = su.id WHERE TRUE %s %s %s %s""" % (con_packages, con_suites, con_components, con_architectures)) to_remove.extend(q) if not to_remove: print "Nothing to do." sys.exit(0) # If we don't have a reason; spawn an editor so the user can add one # Write the rejection email out as the <foo>.reason file if not Options["Reason"] and not Options["No-Action"]: (fd, temp_filename) = utils.temp_filename() editor = os.environ.get("EDITOR","vi") result = os.system("%s %s" % (editor, temp_filename)) if result != 0: utils.fubar ("vi invocation failed for `%s'!" % (temp_filename), result) temp_file = utils.open_file(temp_filename) for line in temp_file.readlines(): Options["Reason"] += line temp_file.close() os.unlink(temp_filename) # Generate the summary of what's to be removed d = {} for i in to_remove: package = i[0] version = i[1] architecture = i[2] maintainer = i[4] maintainers[maintainer] = "" if not d.has_key(package): d[package] = {} if not d[package].has_key(version): d[package][version] = [] if architecture not in d[package][version]: d[package][version].append(architecture) maintainer_list = [] for maintainer_id in maintainers.keys(): maintainer_list.append(get_maintainer(maintainer_id).name) summary = "" removals = d.keys() removals.sort() versions = [] for package in removals: versions = d[package].keys() versions.sort(apt_pkg.version_compare) for version in versions: d[package][version].sort(utils.arch_compare_sw) summary += "%10s | %10s | %s\n" % (package, version, ", ".join(d[package][version])) print "Will remove the following packages from %s:" % (suites_list) print print summary print "Maintainer: %s" % ", ".join(maintainer_list) if Options["Done"]: print "Will also close bugs: "+Options["Done"] if carbon_copy: print "Will also send CCs to: " + ", ".join(carbon_copy) if Options["Do-Close"]: print "Will also close associated bug reports." print print "------------------- Reason -------------------" print Options["Reason"] print "----------------------------------------------" print if Options["Rdep-Check"]: arches = utils.split_args(Options["Architecture"]) reverse_depends_check(removals, suites[0], arches, session) # If -n/--no-action, drop out here if Options["No-Action"]: sys.exit(0) print "Going to remove the packages now." game_over() whoami = utils.whoami() date = commands.getoutput('date -R') # Log first; if it all falls apart I want a record that we at least tried. logfile = utils.open_file(cnf["Rm::LogFile"], 'a') logfile.write("=========================================================================\n") logfile.write("[Date: %s] [ftpmaster: %s]\n" % (date, whoami)) logfile.write("Removed the following packages from %s:\n\n%s" % (suites_list, summary)) if Options["Done"]: logfile.write("Closed bugs: %s\n" % (Options["Done"])) logfile.write("\n------------------- Reason -------------------\n%s\n" % (Options["Reason"])) logfile.write("----------------------------------------------\n") # Do the same in rfc822 format logfile822 = utils.open_file(cnf["Rm::LogFile822"], 'a') logfile822.write("Date: %s\n" % date) logfile822.write("Ftpmaster: %s\n" % whoami) logfile822.write("Suite: %s\n" % suites_list) sources = [] binaries = [] for package in summary.split("\n"): for row in package.split("\n"): element = row.split("|") if len(element) == 3: if element[2].find("source") > 0: sources.append("%s_%s" % tuple(elem.strip(" ") for elem in element[:2])) element[2] = sub("source\s?,?", "", element[2]).strip(" ") if element[2]: binaries.append("%s_%s [%s]" % tuple(elem.strip(" ") for elem in element)) if sources: logfile822.write("Sources:\n") for source in sources: logfile822.write(" %s\n" % source) if binaries: logfile822.write("Binaries:\n") for binary in binaries: logfile822.write(" %s\n" % binary) logfile822.write("Reason: %s\n" % Options["Reason"].replace('\n', '\n ')) if Options["Done"]: logfile822.write("Bug: %s\n" % Options["Done"]) dsc_type_id = get_override_type('dsc', session).overridetype_id deb_type_id = get_override_type('deb', session).overridetype_id # Do the actual deletion print "Deleting...", sys.stdout.flush() for i in to_remove: package = i[0] architecture = i[2] package_id = i[3] for suite_id in suite_ids_list: if architecture == "source": session.execute("DELETE FROM src_associations WHERE source = :packageid AND suite = :suiteid", {'packageid': package_id, 'suiteid': suite_id}) #print "DELETE FROM src_associations WHERE source = %s AND suite = %s" % (package_id, suite_id) else: session.execute("DELETE FROM bin_associations WHERE bin = :packageid AND suite = :suiteid", {'packageid': package_id, 'suiteid': suite_id}) #print "DELETE FROM bin_associations WHERE bin = %s AND suite = %s" % (package_id, suite_id) # Delete from the override file if not Options["Partial"]: if architecture == "source": type_id = dsc_type_id else: type_id = deb_type_id # TODO: Again, fix this properly to remove the remaining non-bind argument session.execute("DELETE FROM override WHERE package = :package AND type = :typeid AND suite = :suiteid %s" % (over_con_components), {'package': package, 'typeid': type_id, 'suiteid': suite_id}) session.commit() print "done." # If we don't have a Bug server configured, we're done if not cnf.has_key("Dinstall::BugServer"): if Options["Done"] or Options["Do-Close"]: print "Cannot send mail to BugServer as Dinstall::BugServer is not configured" logfile.write("=========================================================================\n") logfile.close() logfile822.write("\n") logfile822.close() return # read common subst variables for all bug closure mails Subst_common = {} Subst_common["__RM_ADDRESS__"] = cnf["Dinstall::MyEmailAddress"] Subst_common["__BUG_SERVER__"] = cnf["Dinstall::BugServer"] Subst_common["__CC__"] = "X-DAK: dak rm" if carbon_copy: Subst_common["__CC__"] += "\nCc: " + ", ".join(carbon_copy) Subst_common["__SUITE_LIST__"] = suites_list Subst_common["__SUBJECT__"] = "Removed package(s) from %s" % (suites_list) Subst_common["__ADMIN_ADDRESS__"] = cnf["Dinstall::MyAdminAddress"] Subst_common["__DISTRO__"] = cnf["Dinstall::MyDistribution"] Subst_common["__WHOAMI__"] = whoami # Send the bug closing messages if Options["Done"]: Subst_close_rm = Subst_common bcc = [] if cnf.find("Dinstall::Bcc") != "": bcc.append(cnf["Dinstall::Bcc"]) if cnf.find("Rm::Bcc") != "": bcc.append(cnf["Rm::Bcc"]) if bcc: Subst_close_rm["__BCC__"] = "Bcc: " + ", ".join(bcc) else: Subst_close_rm["__BCC__"] = "X-Filler: 42" summarymail = "%s\n------------------- Reason -------------------\n%s\n" % (summary, Options["Reason"]) summarymail += "----------------------------------------------\n" Subst_close_rm["__SUMMARY__"] = summarymail for bug in utils.split_args(Options["Done"]): Subst_close_rm["__BUG_NUMBER__"] = bug if Options["Do-Close"]: mail_message = utils.TemplateSubst(Subst_close_rm,cnf["Dir::Templates"]+"/rm.bug-close-with-related") else: mail_message = utils.TemplateSubst(Subst_close_rm,cnf["Dir::Templates"]+"/rm.bug-close") utils.send_mail(mail_message, whitelists=whitelists) # close associated bug reports if Options["Do-Close"]: Subst_close_other = Subst_common bcc = [] wnpp = utils.parse_wnpp_bug_file() versions = list(set([re_bin_only_nmu.sub('', v) for v in versions])) if len(versions) == 1: Subst_close_other["__VERSION__"] = versions[0] else: utils.fubar("Closing bugs with multiple package versions is not supported. Do it yourself.") if bcc: Subst_close_other["__BCC__"] = "Bcc: " + ", ".join(bcc) else: Subst_close_other["__BCC__"] = "X-Filler: 42" # at this point, I just assume, that the first closed bug gives # some useful information on why the package got removed Subst_close_other["__BUG_NUMBER__"] = utils.split_args(Options["Done"])[0] if len(sources) == 1: source_pkg = source.split("_", 1)[0] else: utils.fubar("Closing bugs for multiple source packages is not supported. Do it yourself.") Subst_close_other["__BUG_NUMBER_ALSO__"] = "" Subst_close_other["__SOURCE__"] = source_pkg merged_bugs = set() other_bugs = bts.get_bugs('src', source_pkg, 'status', 'open', 'status', 'forwarded') if other_bugs: for bugno in other_bugs: if bugno not in merged_bugs: for bug in bts.get_status(bugno): for merged in bug.mergedwith: other_bugs.remove(merged) merged_bugs.add(merged) logfile.write("Also closing bug(s):") logfile822.write("Also-Bugs:") for bug in other_bugs: Subst_close_other["__BUG_NUMBER_ALSO__"] += str(bug) + "-done@" + cnf["Dinstall::BugServer"] + "," logfile.write(" " + str(bug)) logfile822.write(" " + str(bug)) logfile.write("\n") logfile822.write("\n") if source_pkg in wnpp.keys(): logfile.write("Also closing WNPP bug(s):") logfile822.write("Also-WNPP:") for bug in wnpp[source_pkg]: # the wnpp-rm file we parse also contains our removal # bugs, filtering that out if bug != Subst_close_other["__BUG_NUMBER__"]: Subst_close_other["__BUG_NUMBER_ALSO__"] += str(bug) + "-done@" + cnf["Dinstall::BugServer"] + "," logfile.write(" " + str(bug)) logfile822.write(" " + str(bug)) logfile.write("\n") logfile822.write("\n") mail_message = utils.TemplateSubst(Subst_close_other,cnf["Dir::Templates"]+"/rm.bug-close-related") if Subst_close_other["__BUG_NUMBER_ALSO__"]: utils.send_mail(mail_message) logfile.write("=========================================================================\n") logfile.close() logfile822.write("\n") logfile822.close()
def main(): cnf = Config() Logger = daklog.Logger('generate-filelist') Arguments = [('h', "help", "Filelist::Options::Help"), ('s', "suite", "Filelist::Options::Suite", "HasArg"), ('c', "component", "Filelist::Options::Component", "HasArg"), ('a', "architecture", "Filelist::Options::Architecture", "HasArg"), ('i', "incremental", "Filelist::Options::Incremental")] session = DBConn().session() query_suites = session.query(Suite) suites = [suite.suite_name for suite in query_suites] if not cnf.has_key('Filelist::Options::Suite'): cnf['Filelist::Options::Suite'] = ','.join(suites).encode() query_components = session.query(Component) components = \ [component.component_name for component in query_components] if not cnf.has_key('Filelist::Options::Component'): cnf['Filelist::Options::Component'] = ','.join(components).encode() query_architectures = session.query(Architecture) architectures = \ [architecture.arch_string for architecture in query_architectures] if not cnf.has_key('Filelist::Options::Architecture'): cnf['Filelist::Options::Architecture'] = ','.join( architectures).encode() cnf['Filelist::Options::Help'] = '' cnf['Filelist::Options::Incremental'] = '' apt_pkg.parse_commandline(cnf.Cnf, Arguments, sys.argv) Options = cnf.subtree("Filelist::Options") if Options['Help']: usage() pool = DakProcessPool() query_suites = query_suites. \ filter(Suite.suite_name.in_(utils.split_args(Options['Suite']))) query_components = query_components. \ filter(Component.component_name.in_(utils.split_args(Options['Component']))) query_architectures = query_architectures. \ filter(Architecture.arch_string.in_(utils.split_args(Options['Architecture']))) def parse_results(message): # Split out into (code, msg) code, msg = message if code == PROC_STATUS_SUCCESS: Logger.log([msg]) elif code == PROC_STATUS_SIGNALRAISED: Logger.log(['E: Subprocess recieved signal ', msg]) else: Logger.log(['E: ', msg]) for suite in query_suites: suite_id = suite.suite_id for component in query_components: component_id = component.component_id for architecture in query_architectures: architecture_id = architecture.arch_id if architecture not in suite.architectures: pass elif architecture.arch_string == 'source': pool.apply_async( writeSourceList, (suite_id, component_id, Options['Incremental']), callback=parse_results) elif architecture.arch_string == 'all': pool.apply_async(writeAllList, (suite_id, component_id, architecture_id, 'deb', Options['Incremental']), callback=parse_results) pool.apply_async(writeAllList, (suite_id, component_id, architecture_id, 'udeb', Options['Incremental']), callback=parse_results) else: # arch any pool.apply_async(writeBinaryList, (suite_id, component_id, architecture_id, 'deb', Options['Incremental']), callback=parse_results) pool.apply_async(writeBinaryList, (suite_id, component_id, architecture_id, 'udeb', Options['Incremental']), callback=parse_results) pool.close() pool.join() # this script doesn't change the database session.close() Logger.close() sys.exit(pool.overall_status())
def main(): cnf = Config() Arguments = [('a', "architecture", "Ls::Options::Architecture", "HasArg"), ('b', "binarytype", "Ls::Options::BinaryType", "HasArg"), ('c', "component", "Ls::Options::Component", "HasArg"), ('f', "format", "Ls::Options::Format", "HasArg"), ('g', "greaterorequal", "Ls::Options::GreaterOrEqual"), ('G', "greaterthan", "Ls::Options::GreaterThan"), ('r', "regex", "Ls::Options::Regex"), ('s', "suite", "Ls::Options::Suite", "HasArg"), ('S', "source-and-binary", "Ls::Options::Source-And-Binary"), ('h', "help", "Ls::Options::Help")] for i in [ "architecture", "binarytype", "component", "format", "greaterorequal", "greaterthan", "regex", "suite", "source-and-binary", "help" ]: key = "Ls::Options::%s" % i if key not in cnf: cnf[key] = "" packages = apt_pkg.parse_commandline(cnf.Cnf, Arguments, sys.argv) Options = cnf.subtree("Ls::Options") if Options["Help"]: usage() if not packages: utils.fubar("need at least one package name as an argument.") # Handle buildd maintenance helper options if Options["GreaterOrEqual"] or Options["GreaterThan"]: if Options["GreaterOrEqual"] and Options["GreaterThan"]: utils.fubar( "-g/--greaterorequal and -G/--greaterthan are mutually exclusive." ) if not Options["Suite"]: Options["Suite"] = "unstable" kwargs = dict() if Options["Regex"]: kwargs['regex'] = True if Options["Source-And-Binary"]: kwargs['source_and_binary'] = True if Options["Suite"]: kwargs['suites'] = utils.split_args(Options['Suite']) if Options["Architecture"]: kwargs['architectures'] = utils.split_args(Options['Architecture']) if Options['BinaryType']: kwargs['binary_types'] = utils.split_args(Options['BinaryType']) if Options['Component']: kwargs['components'] = utils.split_args(Options['Component']) if Options['Format']: kwargs['format'] = Options['Format'] if Options['GreaterOrEqual']: kwargs['highest'] = '>=' elif Options['GreaterThan']: kwargs['highest'] = '>>' for line in list_packages(packages, **kwargs): print(line)
def main (): cnf = Config() Arguments = [('a', "architecture", "Ls::Options::Architecture", "HasArg"), ('b', "binarytype", "Ls::Options::BinaryType", "HasArg"), ('c', "component", "Ls::Options::Component", "HasArg"), ('f', "format", "Ls::Options::Format", "HasArg"), ('g', "greaterorequal", "Ls::Options::GreaterOrEqual"), ('G', "greaterthan", "Ls::Options::GreaterThan"), ('r', "regex", "Ls::Options::Regex"), ('s', "suite", "Ls::Options::Suite", "HasArg"), ('S', "source-and-binary", "Ls::Options::Source-And-Binary"), ('h', "help", "Ls::Options::Help")] for i in [ "architecture", "binarytype", "component", "format", "greaterorequal", "greaterthan", "regex", "suite", "source-and-binary", "help" ]: if not cnf.has_key("Ls::Options::%s" % (i)): cnf["Ls::Options::%s" % (i)] = "" packages = apt_pkg.parse_commandline(cnf.Cnf, Arguments, sys.argv) Options = cnf.subtree("Ls::Options") if Options["Help"]: usage() if not packages: utils.fubar("need at least one package name as an argument.") # If cron.daily is running; warn the user that our output might seem strange if os.path.exists(os.path.join(cnf["Dir::Lock"], "daily.lock")): utils.warn("Archive maintenance is in progress; database inconsistencies are possible.") # Handle buildd maintenance helper options if Options["GreaterOrEqual"] or Options["GreaterThan"]: if Options["GreaterOrEqual"] and Options["GreaterThan"]: utils.fubar("-g/--greaterorequal and -G/--greaterthan are mutually exclusive.") if not Options["Suite"]: Options["Suite"] = "unstable" kwargs = dict() if Options["Regex"]: kwargs['regex'] = True if Options["Source-And-Binary"]: kwargs['source_and_binary'] = True if Options["Suite"]: kwargs['suites'] = utils.split_args(Options['Suite']) if Options["Architecture"]: kwargs['architectures'] = utils.split_args(Options['Architecture']) if Options['BinaryType']: kwargs['binary_types'] = utils.split_args(Options['BinaryType']) if Options['Component']: kwargs['components'] = utils.split_args(Options['Component']) if Options['Format']: kwargs['format'] = Options['Format'] if Options['GreaterOrEqual']: kwargs['highest'] = '>=' elif Options['GreaterThan']: kwargs['highest'] = '>>' for line in list_packages(packages, **kwargs): print(line)
def main(): cnf = Config() Arguments = [ ('h', "help", "Override::Options::Help"), ('c', "check", "Override::Options::Check"), ('d', "done", "Override::Options::Done", "HasArg"), ('n', "no-action", "Override::Options::No-Action"), ('s', "suite", "Override::Options::Suite", "HasArg"), ] for i in ["help", "check", "no-action"]: if not cnf.has_key("Override::Options::%s" % (i)): cnf["Override::Options::%s" % (i)] = "" if not cnf.has_key("Override::Options::Suite"): cnf["Override::Options::Suite"] = "unstable" arguments = apt_pkg.parse_commandline(cnf.Cnf, Arguments, sys.argv) Options = cnf.subtree("Override::Options") if Options["Help"]: usage() session = DBConn().session() if not arguments: utils.fubar("package name is a required argument.") package = arguments.pop(0) suite_name = Options["Suite"] if arguments and len(arguments) > 2: utils.fubar("Too many arguments") suite = get_suite(suite_name, session) if suite is None: utils.fubar("Unknown suite '{0}'".format(suite_name)) if arguments and len(arguments) == 1: # Determine if the argument is a priority or a section... arg = arguments.pop() q = session.execute( """ SELECT ( SELECT COUNT(*) FROM section WHERE section = :arg ) AS secs, ( SELECT COUNT(*) FROM priority WHERE priority = :arg ) AS prios """, {'arg': arg}) r = q.fetchall() if r[0][0] == 1: arguments = (arg, ".") elif r[0][1] == 1: arguments = (".", arg) else: utils.fubar("%s is not a valid section or priority" % (arg)) # Retrieve current section/priority... oldsection, oldsourcesection, oldpriority = None, None, None for packagetype in ['source', 'binary']: eqdsc = '!=' if packagetype == 'source': eqdsc = '=' q = session.execute( """ SELECT priority.priority AS prio, section.section AS sect, override_type.type AS type FROM override, priority, section, suite, override_type WHERE override.priority = priority.id AND override.type = override_type.id AND override_type.type %s 'dsc' AND override.section = section.id AND override.package = :package AND override.suite = suite.id AND suite.suite_name = :suite_name """ % (eqdsc), { 'package': package, 'suite_name': suite_name }) if q.rowcount == 0: continue if q.rowcount > 1: utils.fubar("%s is ambiguous. Matches %d packages" % (package, q.rowcount)) r = q.fetchone() if packagetype == 'binary': oldsection = r[1] oldpriority = r[0] else: oldsourcesection = r[1] oldpriority = 'source' if not oldpriority and not oldsourcesection: utils.fubar("Unable to find package %s" % (package)) if oldsection and oldsourcesection and oldsection != oldsourcesection: # When setting overrides, both source & binary will become the same section utils.warn("Source is in section '%s' instead of '%s'" % (oldsourcesection, oldsection)) if not oldsection: oldsection = oldsourcesection if not arguments: print "%s is in section '%s' at priority '%s'" % (package, oldsection, oldpriority) sys.exit(0) # At this point, we have a new section and priority... check they're valid... newsection, newpriority = arguments if newsection == ".": newsection = oldsection if newpriority == ".": newpriority = oldpriority s = get_section(newsection, session) if s is None: utils.fubar("Supplied section %s is invalid" % (newsection)) newsecid = s.section_id p = get_priority(newpriority, session) if p is None: utils.fubar("Supplied priority %s is invalid" % (newpriority)) newprioid = p.priority_id if newpriority == oldpriority and newsection == oldsection: print "I: Doing nothing" sys.exit(0) if oldpriority == 'source' and newpriority != 'source': utils.fubar("Trying to change priority of a source-only package") if Options["Check"] and newpriority != oldpriority: check_override_compliance(package, p, suite.archive.path, suite_name, cnf, session) # If we're in no-action mode if Options["No-Action"]: if newpriority != oldpriority: print "I: Would change priority from %s to %s" % (oldpriority, newpriority) if newsection != oldsection: print "I: Would change section from %s to %s" % (oldsection, newsection) if Options.has_key("Done"): print "I: Would also close bug(s): %s" % (Options["Done"]) sys.exit(0) if newpriority != oldpriority: print "I: Will change priority from %s to %s" % (oldpriority, newpriority) if newsection != oldsection: print "I: Will change section from %s to %s" % (oldsection, newsection) if not Options.has_key("Done"): pass #utils.warn("No bugs to close have been specified. Noone will know you have done this.") else: print "I: Will close bug(s): %s" % (Options["Done"]) game_over() Logger = daklog.Logger("override") dsc_otype_id = get_override_type('dsc').overridetype_id # We're already in a transaction # We're in "do it" mode, we have something to do... do it if newpriority != oldpriority: session.execute( """ UPDATE override SET priority = :newprioid WHERE package = :package AND override.type != :otypedsc AND suite = (SELECT id FROM suite WHERE suite_name = :suite_name)""", { 'newprioid': newprioid, 'package': package, 'otypedsc': dsc_otype_id, 'suite_name': suite_name }) Logger.log(["changed priority", package, oldpriority, newpriority]) if newsection != oldsection: q = session.execute( """ UPDATE override SET section = :newsecid WHERE package = :package AND suite = (SELECT id FROM suite WHERE suite_name = :suite_name)""", { 'newsecid': newsecid, 'package': package, 'suite_name': suite_name }) Logger.log(["changed section", package, oldsection, newsection]) session.commit() if Options.has_key("Done"): if not cnf.has_key("Dinstall::BugServer"): utils.warn( "Asked to send Done message but Dinstall::BugServer is not configured" ) Logger.close() return Subst = {} Subst["__OVERRIDE_ADDRESS__"] = cnf["Dinstall::MyEmailAddress"] Subst["__BUG_SERVER__"] = cnf["Dinstall::BugServer"] bcc = [] if cnf.find("Dinstall::Bcc") != "": bcc.append(cnf["Dinstall::Bcc"]) if bcc: Subst["__BCC__"] = "Bcc: " + ", ".join(bcc) else: Subst["__BCC__"] = "X-Filler: 42" if cnf.has_key("Dinstall::PackagesServer"): Subst["__CC__"] = "Cc: " + package + "@" + cnf[ "Dinstall::PackagesServer"] + "\nX-DAK: dak override" else: Subst["__CC__"] = "X-DAK: dak override" Subst["__ADMIN_ADDRESS__"] = cnf["Dinstall::MyAdminAddress"] Subst["__DISTRO__"] = cnf["Dinstall::MyDistribution"] Subst["__WHOAMI__"] = utils.whoami() Subst["__SOURCE__"] = package summary = "Concerning package %s...\n" % (package) summary += "Operating on the %s suite\n" % (suite_name) if newpriority != oldpriority: summary += "Changed priority from %s to %s\n" % (oldpriority, newpriority) if newsection != oldsection: summary += "Changed section from %s to %s\n" % (oldsection, newsection) Subst["__SUMMARY__"] = summary template = os.path.join(cnf["Dir::Templates"], "override.bug-close") for bug in utils.split_args(Options["Done"]): Subst["__BUG_NUMBER__"] = bug mail_message = utils.TemplateSubst(Subst, template) utils.send_mail(mail_message) Logger.log(["closed bug", bug]) Logger.close()
def main (): cnf = Config() Arguments = [('a', "architecture", "Ls::Options::Architecture", "HasArg"), ('b', "binarytype", "Ls::Options::BinaryType", "HasArg"), ('c', "component", "Ls::Options::Component", "HasArg"), ('f', "format", "Ls::Options::Format", "HasArg"), ('g', "greaterorequal", "Ls::Options::GreaterOrEqual"), ('G', "greaterthan", "Ls::Options::GreaterThan"), ('r', "regex", "Ls::Options::Regex"), ('s', "suite", "Ls::Options::Suite", "HasArg"), ('S', "source-and-binary", "Ls::Options::Source-And-Binary"), ('h', "help", "Ls::Options::Help")] for i in [ "architecture", "binarytype", "component", "format", "greaterorequal", "greaterthan", "regex", "suite", "source-and-binary", "help" ]: if not cnf.has_key("Ls::Options::%s" % (i)): cnf["Ls::Options::%s" % (i)] = "" packages = apt_pkg.parse_commandline(cnf.Cnf, Arguments, sys.argv) Options = cnf.subtree("Ls::Options") if Options["Help"]: usage() if not packages: utils.fubar("need at least one package name as an argument.") # If cron.daily is running; warn the user that our output might seem strange if os.path.exists(os.path.join(cnf["Dir::Lock"], "daily.lock")): utils.warn("Archive maintenance is in progress; database inconsistencies are possible.") # Handle buildd maintenance helper options if Options["GreaterOrEqual"] or Options["GreaterThan"]: if Options["GreaterOrEqual"] and Options["GreaterThan"]: utils.fubar("-g/--greaterorequal and -G/--greaterthan are mutually exclusive.") if not Options["Suite"]: Options["Suite"] = "unstable" kwargs = dict() if Options["Regex"]: kwargs['regex'] = True if Options["Source-And-Binary"]: kwargs['source_and_binary'] = True if Options["Suite"]: kwargs['suites'] = utils.split_args(Options['Suite']) if Options["Architecture"]: kwargs['architectures'] = utils.split_args(Options['Architecture']) if Options['BinaryType']: kwargs['binary_types'] = utils.split_args(Options['BinaryType']) if Options['Component']: kwargs['components'] = utils.split_args(Options['Component']) if Options['Format']: kwargs['format'] = Options['Format'] if Options['GreaterOrEqual']: kwargs['highest'] = '>=' elif Options['GreaterThan']: kwargs['highest'] = '>>' for line in list_packages(packages, **kwargs): print line
def main(): global Cnf, Options, Logger os.umask(0o002) Cnf = utils.get_conf() Arguments = [('h', "help", "Generate-Index-Diffs::Options::Help"), ('a', 'archive', 'Generate-Index-Diffs::Options::Archive', 'hasArg'), ('c', None, "Generate-Index-Diffs::Options::CanonicalPath", "hasArg"), ('p', "patchname", "Generate-Index-Diffs::Options::PatchName", "hasArg"), ('d', "tmpdir", "Generate-Index-Diffs::Options::TempDir", "hasArg"), ('m', "maxdiffs", "Generate-Index-Diffs::Options::MaxDiffs", "hasArg"), ('n', "no-act", "Generate-Index-Diffs::Options::NoAct"), ('v', "verbose", "Generate-Index-Diffs::Options::Verbose"), ] suites = apt_pkg.parse_commandline(Cnf, Arguments, sys.argv) Options = Cnf.subtree("Generate-Index-Diffs::Options") if "Help" in Options: usage() maxdiffs = Options.get("MaxDiffs::Default", "56") maxpackages = Options.get("MaxDiffs::Packages", maxdiffs) maxcontents = Options.get("MaxDiffs::Contents", maxdiffs) maxsources = Options.get("MaxDiffs::Sources", maxdiffs) # can only be set via config at the moment max_parallel = int(Options.get("MaxParallel", "8")) if "PatchName" not in Options: format = "%Y-%m-%d-%H%M.%S" Options["PatchName"] = time.strftime(format) session = DBConn().session() pending_tasks = [] if not suites: query = session.query(Suite.suite_name) if Options.get('Archive'): archives = utils.split_args(Options['Archive']) query = query.join(Suite.archive).filter(Archive.archive_name.in_(archives)) suites = [s.suite_name for s in query] for suitename in suites: print("Processing: " + suitename) suiteobj = get_suite(suitename.lower(), session=session) # Use the canonical version of the suite name suite = suiteobj.suite_name if suiteobj.untouchable: print("Skipping: " + suite + " (untouchable)") continue skip_all = True if suiteobj.separate_contents_architecture_all or suiteobj.separate_packages_architecture_all: skip_all = False architectures = get_suite_architectures(suite, skipall=skip_all, session=session) components = [c.component_name for c in session.query(Component.component_name)] suite_suffix = utils.suite_suffix(suitename) if components and suite_suffix: longsuite = suite + "/" + suite_suffix else: longsuite = suite merged_pdiffs = suiteobj.merged_pdiffs tree = os.path.join(suiteobj.archive.path, 'dists', longsuite) # See if there are Translations which might need a new pdiff cwd = os.getcwd() for component in components: workpath = os.path.join(tree, component, "i18n") if os.path.isdir(workpath): os.chdir(workpath) for dirpath, dirnames, filenames in os.walk(".", followlinks=True, topdown=True): for entry in filenames: if not re_includeinpdiff.match(entry): continue (fname, fext) = os.path.splitext(entry) processfile = os.path.join(workpath, fname) storename = "%s/%s_%s_%s" % (Options["TempDir"], suite, component, fname) coroutine = genchanges(Options, processfile + ".diff", storename, processfile, maxdiffs, merged_pdiffs) pending_tasks.append(coroutine) os.chdir(cwd) for archobj in architectures: architecture = archobj.arch_string if architecture == "source": longarch = architecture packages = "Sources" maxsuite = maxsources else: longarch = "binary-%s" % architecture packages = "Packages" maxsuite = maxpackages for component in components: # Process Contents file = "%s/%s/Contents-%s" % (tree, component, architecture) storename = "%s/%s_%s_contents_%s" % (Options["TempDir"], suite, component, architecture) coroutine = genchanges(Options, file + ".diff", storename, file, maxcontents, merged_pdiffs) pending_tasks.append(coroutine) file = "%s/%s/%s/%s" % (tree, component, longarch, packages) storename = "%s/%s_%s_%s" % (Options["TempDir"], suite, component, architecture) coroutine = genchanges(Options, file + ".diff", storename, file, maxsuite, merged_pdiffs) pending_tasks.append(coroutine) asyncio.run(process_pdiff_tasks(pending_tasks, max_parallel))
def main(): global Logger cnf = Config() for i in ["Help", "Suite", "Force", "Quiet"]: key = "Generate-Releases::Options::%s" % i if key not in cnf: cnf[key] = "" Arguments = [('h', "help", "Generate-Releases::Options::Help"), ('a', 'archive', 'Generate-Releases::Options::Archive', 'HasArg'), ('s', "suite", "Generate-Releases::Options::Suite"), ('f', "force", "Generate-Releases::Options::Force"), ('q', "quiet", "Generate-Releases::Options::Quiet"), ('o', 'option', '', 'ArbItem')] suite_names = apt_pkg.parse_commandline(cnf.Cnf, Arguments, sys.argv) Options = cnf.subtree("Generate-Releases::Options") if Options["Help"]: usage() Logger = daklog.Logger('generate-releases') pool = DakProcessPool() session = DBConn().session() if Options["Suite"]: suites = [] for s in suite_names: suite = get_suite(s.lower(), session) if suite: suites.append(suite) else: print("cannot find suite %s" % s) Logger.log(['cannot find suite %s' % s]) else: query = session.query(Suite).filter(Suite.untouchable == False) # noqa:E712 if 'Archive' in Options: archive_names = utils.split_args(Options['Archive']) query = query.join(Suite.archive).filter(Archive.archive_name.in_(archive_names)) suites = query.all() broken = [] for s in suites: # Setup a multiprocessing Pool. As many workers as we have CPU cores. if s.untouchable and not Options["Force"]: print("Skipping %s (untouchable)" % s.suite_name) continue if not Options["Quiet"]: print("Processing %s" % s.suite_name) Logger.log(['Processing release file for Suite: %s' % (s.suite_name)]) pool.apply_async(generate_helper, (s.suite_id, )) # No more work will be added to our pool, close it and then wait for all to finish pool.close() pool.join() retcode = pool.overall_status() if retcode > 0: # TODO: CENTRAL FUNCTION FOR THIS / IMPROVE LOGGING Logger.log(['Release file generation broken: %s' % (','.join([str(x[1]) for x in pool.results]))]) Logger.close() sys.exit(retcode)