From a644e931617220b1771931d5239dffc637d7e9cd Mon Sep 17 00:00:00 2001 From: Joerg Jaspert Date: Wed, 12 Mar 2008 00:23:49 +0100 Subject: [PATCH] * dak/dak.py (init): Renamed check -> edit transitions * dak/edit_transitions.py: Renamed from check_transitions.py (main): Also rename new_vers/curvers to expected/current Basically a nice rewrite, so it now does checks and edit, depending on how you call it. Check also removes old transitions, if user wants it --- ChangeLog | 8 + dak/check_transitions.py | 149 ------------------- dak/dak.py | 4 +- dak/edit_transitions.py | 311 +++++++++++++++++++++++++++++++++++++++ 4 files changed, 321 insertions(+), 151 deletions(-) delete mode 100755 dak/check_transitions.py create mode 100755 dak/edit_transitions.py diff --git a/ChangeLog b/ChangeLog index 0767b5c7..2ce29782 100644 --- a/ChangeLog +++ b/ChangeLog @@ -11,6 +11,14 @@ * The above changes are based on modifications from Anthony. + * dak/dak.py (init): Renamed check -> edit transitions + + * dak/edit_transitions.py: Renamed from check_transitions.py + (main): Also rename new_vers/curvers to expected/current + Basically a nice rewrite, so it now does checks and edit, + depending on how you call it. Check also removes old transitions, + if user wants it. + 2008-03-02 Joerg Jaspert * debian/control (Suggests): Add python-syck to Depends: diff --git a/dak/check_transitions.py b/dak/check_transitions.py deleted file mode 100755 index 20964258..00000000 --- a/dak/check_transitions.py +++ /dev/null @@ -1,149 +0,0 @@ -#!/usr/bin/env python - -# Check the release managers transition file for correctness and outdated transitions -# Copyright (C) 2008 Joerg Jaspert - -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. - -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. - -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - -################################################################################ - -# if klecker.d.o died, I swear to god, I'm going to migrate to gentoo. - -################################################################################ - -import os, pg, sys -import apt_pkg -import daklib.database -import daklib.utils - -from syck import * - -# Globals -Cnf = None -Options = None -projectB = None - -################################################################################ - -def init(): - global Cnf, Options, projectB - - apt_pkg.init() - - Cnf = daklib.utils.get_conf() - - Arguments = [('h',"help","Check-Transitions::Options::Help"), - ('n',"no-action","Check-Transitions::Options::No-Action")] - - for i in ["help", "no-action"]: - if not Cnf.has_key("Check-Transitions::Options::%s" % (i)): - Cnf["Check-Transitions::Options::%s" % (i)] = "" - - apt_pkg.ParseCommandLine(Cnf, Arguments, sys.argv) - - Options = Cnf.SubTree("Check-Transitions::Options") - - projectB = pg.connect(Cnf["DB::Name"], Cnf["DB::Host"], int(Cnf["DB::Port"])) - daklib.database.init(Cnf, projectB) - - - if Options["help"]: - usage() - -################################################################################ - -def usage (exit_code=0): - print """Usage: check_transitions [OPTION]... - Check the release managers transition file for correctness and outdated transitions - -h, --help show this help and exit. - -n, --no-action don't do anything""" - sys.exit(exit_code) - -################################################################################ - -def main(): - global Cnf - - init() - - # Only check if there is a file defined (and existant) with checks. It's a little bit - # specific to Debian, not much use for others, so return early there. - if not Cnf.has_key("Dinstall::Reject::ReleaseTransitions") or not os.path.exists("%s" % (Cnf["Dinstall::Reject::ReleaseTransitions"])): - daklib.utils.warn("Dinstall::Reject::ReleaseTransitions not defined or file %s not existant." % - (Cnf["Dinstall::Reject::ReleaseTransitions"])) - sys.exit(1) - - # Parse the yaml file - sourcefile = file(Cnf["Dinstall::Reject::ReleaseTransitions"], 'r') - sourcecontent = sourcefile.read() - try: - transitions = load(sourcecontent) - except error, msg: - # This shouldn't happen, the release team has a wrapper to check the file, but better - # safe then sorry - daklib.utils.warn("Not checking transitions, the transitions file is broken: %s." % (msg)) - sys.exit(2) - - to_dump = 0 - to_remove = [] - # Now look through all defined transitions - for trans in transitions: - t = transitions[trans] - source = t["source"] - new_vers = t["new"] - - # Will be None if nothing is in testing. - curvers = daklib.database.get_testing_version(source) - - print """ -Looking at transition: %s - Source: %s - New Version: %s - Responsible: %s - Description: %s - Blocked Packages (total: %d): %s -""" % (trans, source, new_vers, t["rm"], t["reason"], len(t["packages"]), ", ".join(t["packages"])) - - if curvers == None: - # No package in testing - print "Transition source %s not in testing, transition still ongoing." % (source) - else: - compare = apt_pkg.VersionCompare(curvers, new_vers) - print "Apt compare says: %s" % (compare) - if compare < 0: - # This is still valid, the current version in database is older than - # the new version we wait for - print "This transition is still ongoing, we currently have version %s" % (curvers) - else: - print "This transition is over, the target package reached testing, removing" - print "%s wanted version: %s, has %s" % (source, new_vers, curvers) - to_remove.append(trans) - to_dump = 1 - print "-------------------------------------------------------------------------" - - if to_dump: - for remove in to_remove: - if Options["no-action"]: - print "I: I would remove the %s transition" % (remove) - else: - del transitions[remove] - if not Options["no-action"]: - destfile = file(Cnf["Dinstall::Reject::ReleaseTransitions"], 'w') - dump(transitions, destfile) - -################################################################################ - -if __name__ == '__main__': - main() diff --git a/dak/dak.py b/dak/dak.py index 859f67f5..6f1ac6a6 100755 --- a/dak/dak.py +++ b/dak/dak.py @@ -92,8 +92,8 @@ def init(): ("clean-proposed-updates", "Remove obsolete .changes from proposed-updates"), - ("check-transitions", - "Check release transition file"), + ("edit-transitions", + "Edit the release transition file"), ("check-overrides", "Override cruft checks"), ("check-proposed-updates", diff --git a/dak/edit_transitions.py b/dak/edit_transitions.py new file mode 100755 index 00000000..0a9dae28 --- /dev/null +++ b/dak/edit_transitions.py @@ -0,0 +1,311 @@ +#!/usr/bin/env python + +# Edit and then check the release managers transition file for correctness +# and outdated transitions +# Copyright (C) 2008 Joerg Jaspert + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +################################################################################ + +# if klecker.d.o died, I swear to god, I'm going to migrate to gentoo. + +################################################################################ + +import os, pg, sys, time +import apt_pkg +import daklib.database +import daklib.utils +import syck + +# Globals +Cnf = None +Options = None +projectB = None + +################################################################################ + +def init(): + global Cnf, Options, projectB + + apt_pkg.init() + + Cnf = daklib.utils.get_conf() + + Arguments = [('h',"help","Edit-Transitions::Options::Help"), + ('e',"edit","Edit-Transitions::Option::Edit"), + ('c',"check","Edit-Transitions::Option::check"), + ('n',"no-action","Edit-Transitions::Options::No-Action")] + + for i in ["help", "no-action", "edit", "check"]: + if not Cnf.has_key("Edit-Transitions::Options::%s" % (i)): + Cnf["Edit-Transitions::Options::%s" % (i)] = "" + + apt_pkg.ParseCommandLine(Cnf, Arguments, sys.argv) + + Options = Cnf.SubTree("Edit-Transitions::Options") + + projectB = pg.connect(Cnf["DB::Name"], Cnf["DB::Host"], int(Cnf["DB::Port"])) + daklib.database.init(Cnf, projectB) + + if Options["help"]: + usage() + +################################################################################ + +def usage (exit_code=0): + print """Usage: edit_transitions [OPTION]... + Check the release managers transition file for correctness and outdated transitions + -h, --help show this help and exit. + -e, --edit edit the transitions file + -c, --check check the transitions file, remove outdated entries + -n, --no-action don't do anything + + Called without an option this tool will check the transition file for outdated + transitions and remove them.""" + sys.exit(exit_code) + +################################################################################ + +def lock_file(lockfile): + while retry < 10: + try: + lock_fd = os.open(lockfile, os.O_RDONLY | os.O_CREAT | os.O_EXCL) + retry = 10 + except OSError, e: + if errno.errorcode[e.errno] == 'EACCES' or errno.errorcode[e.errno] == 'EEXIST': + retry += 1 + if (retry >= 10): + daklib.utils.fubar("Couldn't obtain lock for %s." % (lockfile) ) + else: + print("Unable to get lock for %s (try %d of 10)" % (lockfile, retry) ) + time.sleep(60) + else: + raise + + +################################################################################ + +def edit_transitions(): + trans_file = Cnf["Dinstall::Reject::ReleaseTransitions"] + + tempfile = "./%s.transition.tmp" % (os.getpid() ) + + lockfile="%s.lock" % (tempfile) + lock_file(lockfile) + + daklib.utils.copy(trans_file, tempfile ) + + editor = os.environ.get("EDITOR", "vi") + + while True: + result = os.system("%s %s" % (editor, temp_file)) + if result != 0: + os.unlink(tempfile) + os.unlink(lockfile) + daklib.utils.fubar("%s invocation failed for %s, not removing tempfile." % (editor, temp_file)) + + # Now try to load the new file + test = load_transitions(tempfile) + + if test = None: + # Edit is broken + prompt = "Broken edit: [E]dit again, Drop changes?" + while prompt.find(answer) == -1: + answer = daklib.utils.our_raw_input(prompt) + m = daklib.queue.re_default_answer.match(prompt) + if answer == "": + answer = m.group(1) + answer = answer[:1].upper() + + if answer == 'E': + continue + elif answer == 'D': + os.unlink(tempfile) + os.unlink(lockfile) + sys.exit(0) + else: + # No problems in loading the new file, jump out of the while loop + break + + # We seem to be done and also have a working file. Copy over. + daklib.utils.copy(tempfile, trans_file) + os.unlink(tempfile) + os.unlink(lockfile) + +################################################################################ + +def load_transitions(trans_file): + # Parse the yaml file + sourcefile = file(trans_file, 'r') + sourcecontent = sourcefile.read() + try: + trans = syck.load(sourcecontent) + except error, msg: + # Someone fucked it up + print "ERROR: %s" % (msg) + return None + return trans + +################################################################################ + +def print_info(trans, source, expected, rm, reason, packages): + print """ +Looking at transition: %s + Source: %s + New Version: %s + Responsible: %s + Description: %s + Blocked Packages (total: %d): %s +""" % (trans, source, expected, rm, reason, len(packages), ", ".join(packages)) + return + +################################################################################ + +def transition_info(transitions): + print "Currently defined transitions:" + for trans in transitions: + t = transitions[trans] + source = t["source"] + expected = t["new"] + + # Will be None if nothing is in testing. + current = daklib.database.get_testing_version(source) + + print_info(trans, source, expected, t["rm"], t["reason"], t["packages"]) + + if current == None: + # No package in testing + print "Transition source %s not in testing, transition still ongoing." % (source) + else: + compare = apt_pkg.VersionCompare(current, expected) + print "Apt compare says: %s" % (compare) + if compare < 0: + # This is still valid, the current version in database is older than + # the new version we wait for + print "This transition is still ongoing, we currently have version %s" % (current) + else: + print "This transition is over, the target package reached testing, should be removed" + print "%s wanted version: %s, has %s" % (source, expected, current) + print "-------------------------------------------------------------------------" + +################################################################################ + +def check_transitions(transitions): + to_dump = 0 + to_remove = [] + # Now look through all defined transitions + for trans in transitions: + t = transitions[trans] + source = t["source"] + expected = t["new"] + + # Will be None if nothing is in testing. + current = daklib.database.get_testing_version(source) + + print_info(trans, source, expected, t["rm"], t["reason"], t["packages"]) + + if current == None: + # No package in testing + print "Transition source %s not in testing, transition still ongoing." % (source) + else: + compare = apt_pkg.VersionCompare(current, expected) + print "Apt compare says: %s" % (compare) + if compare < 0: + # This is still valid, the current version in database is older than + # the new version we wait for + print "This transition is still ongoing, we currently have version %s" % (current) + else: + print "REMOVE: This transition is over, the target package reached testing. REMOVE" + print "%s wanted version: %s, has %s" % (source, expected, current) + to_remove.append(trans) + to_dump = 1 + print "-------------------------------------------------------------------------" + + if to_dump: + prompt = "Removing: " + for remove in to_remove: + prompt += remove + prompt += "," + + prompt += " Commit Changes? (y/N)" + + if Options["no-action"]: + answer="n" + else: + answer = daklib.utils.our_raw_input(prompt).lower() + + if answer == "": + answer = "n" + + if answer == 'n': + print "Not committing changes" + sys.exit(0) + elif answer == 'y': + print "Committing" + for remove in to_remove: + del transitions[remove] + destfile = file(Cnf["Dinstall::Reject::ReleaseTransitions"], 'w') + syck.dump(transitions, destfile) + print "Done" + else: + print "WTF are you typing?" + sys.exit(0) + + +################################################################################ + +def main(): + global Cnf + + init() + + # Only check if there is a file defined (and existant) with checks. It's a little bit + # specific to Debian, not much use for others, so return early there. + if not Cnf.has_key("Dinstall::Reject::ReleaseTransitions") or not os.path.exists("%s" % (Cnf["Dinstall::Reject::ReleaseTransitions"])): + daklib.utils.warn("Dinstall::Reject::ReleaseTransitions not defined or file %s not existant." % + (Cnf["Dinstall::Reject::ReleaseTransitions"])) + sys.exit(1) + + # Parse the yaml file + transitions = load_transitions(Cnf["Dinstall::Reject::ReleaseTransitions"]) + if transitions = None: + # Something very broken with the transitions, exit + daklib.utils.warn("Not doing any work, someone fucked up the transitions file outside our control") + sys.exit(2) + + if Options["edit"]: + # Output information about the currently defined transitions. + transition_info(transitions) + daklib.utils.our_raw_input("Press a key to continue...") + + # Lets edit the transitions file + edit_transitions(Cnf["Dinstall::Reject::ReleaseTransitions"]) + elif Options["check"]: + # Check and remove outdated transitions + check_transitions(transitions, Cnf["Dinstall::Reject::ReleaseTransitions"]) + else: + # Output information about the currently defined transitions. + transition_info(transitions) + daklib.utils.our_raw_input("Press a key to continue...") + + # Nothing requested, doing nothing besides the above display of the transitions + sys.exit(0) + + +################################################################################ + +if __name__ == '__main__': + main() -- 2.39.5