X-Git-Url: https://git.decadent.org.uk/gitweb/?a=blobdiff_plain;f=dak%2Fprocess_new.py;h=dd990f1fc3c53705c392bd9c573606bcd5dd6157;hb=5d965c34b35048f8a8fab0a7a11f2943d833952d;hp=060fa236964d539dbc2aa7ec5b49e7929f0b6513;hpb=ed2d1928a25b95eb69616cf10bedd02c40740d8d;p=dak.git diff --git a/dak/process_new.py b/dak/process_new.py index 060fa236..dd990f1f 100755 --- a/dak/process_new.py +++ b/dak/process_new.py @@ -64,6 +64,7 @@ from daklib.regexes import re_no_epoch, re_default_answer, re_isanum, re_package from daklib.dak_exceptions import CantOpenError, AlreadyLockedError, CantGetLockError from daklib.summarystats import SummaryStats from daklib.config import Config +from daklib.changesutils import * # Globals Options = None @@ -108,104 +109,6 @@ def recheck(upload, session): ################################################################################ -def indiv_sg_compare (a, b): - """Sort by source name, source, version, 'have source', and - finally by filename.""" - # Sort by source version - q = apt_pkg.VersionCompare(a["version"], b["version"]) - if q: - return -q - - # Sort by 'have source' - a_has_source = a["architecture"].get("source") - b_has_source = b["architecture"].get("source") - if a_has_source and not b_has_source: - return -1 - elif b_has_source and not a_has_source: - return 1 - - return cmp(a["filename"], b["filename"]) - -############################################################ - -def sg_compare (a, b): - a = a[1] - b = b[1] - """Sort by have note, source already in database and time of oldest upload.""" - # Sort by have note - a_note_state = a["note_state"] - b_note_state = b["note_state"] - if a_note_state < b_note_state: - return -1 - elif a_note_state > b_note_state: - return 1 - # Sort by source already in database (descending) - source_in_database = cmp(a["source_in_database"], b["source_in_database"]) - if source_in_database: - return -source_in_database - - # Sort by time of oldest upload - return cmp(a["oldest"], b["oldest"]) - -def sort_changes(changes_files, session): - """Sort into source groups, then sort each source group by version, - have source, filename. Finally, sort the source groups by have - note, time of oldest upload of each source upload.""" - if len(changes_files) == 1: - return changes_files - - sorted_list = [] - cache = {} - # Read in all the .changes files - for filename in changes_files: - u = Upload() - try: - u.pkg.changes_file = filename - u.load_changes(filename) - u.update_subst() - cache[filename] = copy.copy(u.pkg.changes) - cache[filename]["filename"] = filename - except: - sorted_list.append(filename) - break - # Divide the .changes into per-source groups - per_source = {} - for filename in cache.keys(): - source = cache[filename]["source"] - if not per_source.has_key(source): - per_source[source] = {} - per_source[source]["list"] = [] - per_source[source]["list"].append(cache[filename]) - # Determine oldest time and have note status for each source group - for source in per_source.keys(): - q = session.query(DBSource).filter_by(source = source).all() - per_source[source]["source_in_database"] = len(q)>0 - source_list = per_source[source]["list"] - first = source_list[0] - oldest = os.stat(first["filename"])[stat.ST_MTIME] - have_note = 0 - for d in per_source[source]["list"]: - mtime = os.stat(d["filename"])[stat.ST_MTIME] - if mtime < oldest: - oldest = mtime - have_note += has_new_comment(d["source"], d["version"], session) - per_source[source]["oldest"] = oldest - if not have_note: - per_source[source]["note_state"] = 0; # none - elif have_note < len(source_list): - per_source[source]["note_state"] = 1; # some - else: - per_source[source]["note_state"] = 2; # all - per_source[source]["list"].sort(indiv_sg_compare) - per_source_items = per_source.items() - per_source_items.sort(sg_compare) - for i in per_source_items: - for j in i[1]["list"]: - sorted_list.append(j["filename"]) - return sorted_list - -################################################################################ - class Section_Completer: def __init__ (self, session): self.sections = [] @@ -430,43 +333,6 @@ def edit_overrides (new, upload, session): return new -################################################################################ - -def edit_note(note, upload, session): - # Write the current data to a temporary file - (fd, temp_filename) = utils.temp_filename() - editor = os.environ.get("EDITOR","vi") - answer = 'E' - while answer == 'E': - os.system("%s %s" % (editor, temp_filename)) - temp_file = utils.open_file(temp_filename) - newnote = temp_file.read().rstrip() - temp_file.close() - print "New Note:" - print utils.prefix_multi_line_string(newnote," ") - prompt = "[D]one, Edit, Abandon, Quit ?" - answer = "XXX" - while prompt.find(answer) == -1: - answer = utils.our_raw_input(prompt) - m = re_default_answer.search(prompt) - if answer == "": - answer = m.group(1) - answer = answer[:1].upper() - os.unlink(temp_filename) - if answer == 'A': - return - elif answer == 'Q': - end() - sys.exit(0) - - comment = NewComment() - comment.package = upload.pkg.changes["source"] - comment.version = upload.pkg.changes["version"] - comment.comment = newnote - comment.author = utils.whoami() - comment.trainee = bool(Options["Trainee"]) - session.add(comment) - session.commit() ################################################################################ @@ -477,17 +343,17 @@ def check_pkg (upload): try: sys.stdout = less_fd changes = utils.parse_changes (upload.pkg.changes_file) - examine_package.display_changes(changes['distribution'], upload.pkg.changes_file) + print examine_package.display_changes(changes['distribution'], upload.pkg.changes_file) files = upload.pkg.files for f in files.keys(): if files[f].has_key("new"): ftype = files[f]["type"] if ftype == "deb": - examine_package.check_deb(changes['distribution'], f) + print examine_package.check_deb(changes['distribution'], f) elif ftype == "dsc": - examine_package.check_dsc(changes['distribution'], f) + print examine_package.check_dsc(changes['distribution'], f) finally: - examine_package.output_package_relations() + print examine_package.output_package_relations() sys.stdout = stdout_fd except IOError, e: if e.errno == errno.EPIPE: @@ -545,59 +411,6 @@ def add_overrides (new, upload, session): ################################################################################ -def prod_maintainer (note, upload): - cnf = Config() - # Here we prepare an editor and get them ready to prod... - (fd, temp_filename) = utils.temp_filename() - temp_file = os.fdopen(fd, 'w') - if len(note) > 0: - for line in note: - temp_file.write(line) - temp_file.close() - editor = os.environ.get("EDITOR","vi") - answer = 'E' - while answer == 'E': - os.system("%s %s" % (editor, temp_filename)) - temp_fh = utils.open_file(temp_filename) - prod_message = "".join(temp_fh.readlines()) - temp_fh.close() - print "Prod message:" - print utils.prefix_multi_line_string(prod_message," ",include_blank_lines=1) - prompt = "[P]rod, Edit, Abandon, Quit ?" - answer = "XXX" - while prompt.find(answer) == -1: - answer = utils.our_raw_input(prompt) - m = re_default_answer.search(prompt) - if answer == "": - answer = m.group(1) - answer = answer[:1].upper() - os.unlink(temp_filename) - if answer == 'A': - return - elif answer == 'Q': - end() - sys.exit(0) - # Otherwise, do the proding... - user_email_address = utils.whoami() + " <%s>" % ( - cnf["Dinstall::MyAdminAddress"]) - - Subst = upload.Subst - - Subst["__FROM_ADDRESS__"] = user_email_address - Subst["__PROD_MESSAGE__"] = prod_message - Subst["__CC__"] = "Cc: " + cnf["Dinstall::MyEmailAddress"] - - prod_mail_message = utils.TemplateSubst( - Subst,cnf["Dir::Templates"]+"/process-new.prod") - - # Send the prod mail if appropriate - if not cnf["Dinstall::Options::No-Mail"]: - utils.send_mail(prod_mail_message) - - print "Sent proding message" - -################################################################################ - def do_new(upload, session): print "NEW\n" files = upload.pkg.files @@ -611,26 +424,11 @@ def do_new(upload, session): # Make a copy of distribution we can happily trample on changes["suite"] = copy.copy(changes["distribution"]) - # Fix up the list of target suites - for suite in changes["suite"].keys(): - override = cnf.Find("Suite::%s::OverrideSuite" % (suite)) - if override: - (olderr, newerr) = (get_suite(suite, session) == None, - get_suite(override, session) == None) - if olderr or newerr: - (oinv, newinv) = ("", "") - if olderr: oinv = "invalid " - if newerr: ninv = "invalid " - print "warning: overriding %ssuite %s to %ssuite %s" % ( - oinv, suite, ninv, override) - del changes["suite"][suite] - changes["suite"][override] = 1 - # The main NEW processing loop done = 0 while not done: # Find out what's new - new = determine_new(changes, files) + new, byhand = determine_new(upload.pkg.changes_file, changes, files, session=session) if not new: break @@ -667,7 +465,7 @@ def do_new(upload, session): try: check_daily_lock() done = add_overrides (new, upload, session) - do_accept(upload, session) + new_accept(upload, Options["No-Action"], session) Logger.log(["NEW ACCEPT: %s" % (upload.pkg.changes_file)]) except CantGetLockError: print "Hello? Operator! Give me the number for 911!" @@ -731,14 +529,14 @@ def do_byhand(upload, session): done = 0 while not done: files = upload.pkg.files - will_install = 1 + will_install = True byhand = [] for f in files.keys(): - if files[f]["type"] == "byhand": + if files[f]["section"] == "byhand": if os.path.exists(f): print "W: %s still present; please process byhand components and try again." % (f) - will_install = 0 + will_install = False else: byhand.append(f) @@ -760,21 +558,39 @@ def do_byhand(upload, session): answer = answer[:1].upper() if answer == 'A': - try: - check_daily_lock() - done = 1 - for f in byhand: - del files[f] - Logger.log(["BYHAND ACCEPT: %s" % (upload.pkg.changes_file)]) - except CantGetLockError: - print "Hello? Operator! Give me the number for 911!" - print "Dinstall in the locked area, cant process packages, come back later" + dbchg = get_dbchange(upload.pkg.changes_file, session) + if dbchg is None: + print "Warning: cannot find changes file in database; can't process BYHAND" + else: + try: + check_daily_lock() + done = 1 + for b in byhand: + # Find the file entry in the database + found = False + for f in dbchg.files: + if f.filename == b: + found = True + f.processed = True + break + + if not found: + print "Warning: Couldn't find BYHAND item %s in the database to mark it processed" % b + + session.commit() + Logger.log(["BYHAND ACCEPT: %s" % (upload.pkg.changes_file)]) + except CantGetLockError: + print "Hello? Operator! Give me the number for 911!" + print "Dinstall in the locked area, cant process packages, come back later" elif answer == 'M': - Logger.log(["BYHAND REJECT: %s" % (upload.pkg.changes_file)]) - upload.do_reject(manual=1, reject_message=Options["Manual-Reject"]) - upload.pkg.remove_known_changes(session=session) - session.commit() - done = 1 + aborted = upload.do_reject(manual=1, + reject_message=Options["Manual-Reject"], + notes=get_new_comments(changes.get("source", ""), session=session)) + if not aborted: + upload.pkg.remove_known_changes(session=session) + session.commit() + Logger.log(["BYHAND REJECT: %s" % (upload.pkg.changes_file)]) + done = 1 elif answer == 'S': done = 1 elif answer == 'Q': @@ -836,55 +652,15 @@ class clean_holding(object): os.unlink(os.path.join(h.holding_dir, f)) +def do_pkg(changes_full_path, session): + changes_dir = os.path.dirname(changes_full_path) + changes_file = os.path.basename(changes_full_path) -def changes_to_newstage(upload, session): - """move a changes file to newstage""" - new = get_policy_queue('new', session ); - newstage = get_policy_queue('newstage', session ); - - chg = session.query(DBChange).filter_by(changesname=os.path.basename(upload.pkg.changes_file)).one() - chg.approved_for = newstage.policy_queue_id - - for f in chg.files: - # update the changes_pending_files row - f.queue = newstage - utils.move(os.path.join(new.path, f.filename), newstage.path, perms=int(newstage.perms, 8)) - - utils.move(os.path.join(new.path, upload.pkg.changes_file), newstage.path, perms=int(newstage.perms, 8)) - chg.in_queue = newstage - session.commit() - -def _accept(upload, session): - if Options["No-Action"]: - return - (summary, short_summary) = upload.build_summaries() - # upload.accept(summary, short_summary, targetqueue) - - changes_to_newstage(upload, session) - -def do_accept(upload, session): - print "ACCEPT" - cnf = Config() - if not Options["No-Action"]: - (summary, short_summary) = upload.build_summaries() - - if cnf.FindB("Dinstall::SecurityQueueHandling"): - upload.dump_vars(cnf["Dir::Queue::Embargoed"]) - upload.move_to_queue(get_policy_queue('embargoed')) - upload.queue_build("embargoed", cnf["Dir::Queue::Embargoed"]) - # Check for override disparities - upload.Subst["__SUMMARY__"] = summary - else: - # Just a normal upload, accept it... - _accept(upload, session) - -def do_pkg(changes_file, session): - new_queue = get_policy_queue('new', session ); u = Upload() u.pkg.changes_file = changes_file (u.pkg.changes["fingerprint"], rejects) = utils.check_signature(changes_file) u.load_changes(changes_file) - u.pkg.directory = new_queue.path + u.pkg.directory = changes_dir u.update_subst() u.logger = Logger origchanges = os.path.abspath(u.pkg.changes_file) @@ -913,32 +689,19 @@ def do_pkg(changes_file, session): if not recheck(u, session): return - # FIXME: This does need byhand checks added! - new = determine_new(u.pkg.changes, files) - if new: + new, byhand = determine_new(u.pkg.changes_file, u.pkg.changes, files, session=session) + if byhand: + do_byhand(u, session) + elif new: do_new(u, session) else: try: check_daily_lock() - do_accept(u, session) + new_accept(u, Options["No-Action"], session) except CantGetLockError: print "Hello? Operator! Give me the number for 911!" print "Dinstall in the locked area, cant process packages, come back later" -# (new, byhand) = check_status(files) -# if new or byhand: -# if new: -# do_new(u, session) -# if byhand: -# do_byhand(u, session) -# (new, byhand) = check_status(files) - -# if not new and not byhand: -# try: -# check_daily_lock() -# do_accept(u) -# except CantGetLockError: -# print "Hello? Operator! Give me the number for 911!" -# print "Dinstall in the locked area, cant process packages, come back later" + except AlreadyLockedError, e: print "Seems to be locked by %s already, skipping..." % (e) @@ -979,7 +742,9 @@ def main(): changes_files = apt_pkg.ParseCommandLine(cnf.Cnf,Arguments,sys.argv) if len(changes_files) == 0: new_queue = get_policy_queue('new', session ); - changes_files = utils.get_changes_files(new_queue.path) + changes_paths = [ os.path.join(new_queue.path, j) for j in utils.get_changes_files(new_queue.path) ] + else: + changes_paths = [ os.path.abspath(j) for j in changes_files ] Options = cnf.SubTree("Process-New::Options") @@ -996,18 +761,15 @@ def main(): Priorities = Priority_Completer(session) readline.parse_and_bind("tab: complete") - if len(changes_files) > 1: + if len(changes_paths) > 1: sys.stderr.write("Sorting changes...\n") - changes_files = sort_changes(changes_files, session) - - # Kill me now? **FIXME** - cnf["Dinstall::Options::No-Mail"] = "" + changes_files = sort_changes(changes_paths, session) - for changes_file in changes_files: + for changes_file in changes_paths: changes_file = utils.validate_changes_file_arg(changes_file, 0) if not changes_file: continue - print "\n" + changes_file + print "\n" + os.path.basename(changes_file) do_pkg (changes_file, session)