def transaction_exists(pkglist): """ checks the package list to see if any packages are involved in an incomplete transaction """ conflicts = [] if not transaction_helpers: return conflicts # first, we create a list of the package 'nvreas' # so we can compare the pieces later more easily pkglist_nvreas = [] for pkg in pkglist: pkglist_nvreas.append(splitFilename(pkg)) # next, we build the list of packages that are # contained within an unfinished transaction unfinished_transactions = find_unfinished_transactions() for trans in unfinished_transactions: steps = find_ts_remaining(trans) for step in steps: # the action is install/erase/etc., but we only # care about the package spec contained in the step (action, step_spec) = step (n, v, r, e, a) = splitFilename(step_spec) # and see if that spec is in the list of packages # requested for installation/updating for pkg in pkglist_nvreas: # if the name and arch match, we're going to assume # this package is part of a pending transaction # the label is just for display purposes label = "%s-%s" % (n, a) if n == pkg[0] and a == pkg[4]: if label not in conflicts: conflicts.append("%s-%s" % (n, a)) break return conflicts
class YumCompleteTransaction(YumUtilBase): NAME = 'yum-complete-transaction' VERSION = '1.0' USAGE = """ yum-complete-transaction: completes unfinished yum transactions which occur due to error, failure or act of $deity usage: yum-complete-transaction """ def __init__(self): YumUtilBase.__init__(self, YumCompleteTransaction.NAME, YumCompleteTransaction.VERSION, YumCompleteTransaction.USAGE) self.logger = logging.getLogger("yum.verbose.cli.yumcompletets") # Add util commandline options to the yum-cli ones self.optparser = self.getOptionParser() if hasattr(self, 'getOptionGroup'): self.optparser_grp = self.getOptionGroup() else: self.optparser_grp = self.optparser self.addCmdOptions() try: self.main() finally: self.unlock() def clean_up_ts_files(self, timestamp, path, disable=False): # clean up the transactions tsdone = '%s/transaction-done.%s' % (path, timestamp) tsall = '%s/transaction-all.%s' % (path, timestamp) results = [] for f in [tsall, tsdone]: if os.path.exists(f): if disable: disable_f = f + '.disabled' os.rename(f, disable_f) results.append(disable_f) else: os.unlink(f) return results def addCmdOptions(self): self.optparser_grp.add_option( "--cleanup-only", default=False, action="store_true", dest="cleanup", help= 'Do not complete the transaction just clean up transaction journals' ) def main(self): # Parse the commandline option and setup the basics. try: opts = self.doUtilConfigSetup() except yum.Errors.RepoError, e: self.logger.error( "Cannot handle specific enablerepo/disablerepo options.") sys.exit(50) if self.conf.uid != 0: self.logger.error( "Error: You must be root to run yum-complete-transaction.") sys.exit(1) # Setup yum (Ts, RPM db, Repo & Sack) self.doUtilYumSetup() # Do the real action # get the list of transactions remaining # list the number of them # take the most recent one # populate the ts # run it self.run_with_package_names.add('yum-utils') times = [] for thistime in find_unfinished_transactions(self.conf.persistdir): if thistime.endswith('disabled'): continue # XXX maybe a check here for transactions that are just too old to try and complete? times.append(thistime) if not times: print "No unfinished transactions left." sys.exit() if opts.cleanup: print "Cleaning up unfinished transaction journals" # nuke ts files in yumlibpath for timestamp in times: print "Cleaning up %s" % timestamp self.clean_up_ts_files(timestamp, self.conf.persistdir) sys.exit() timestamp = times[-1] print "There are %d outstanding transactions to complete. Finishing the most recent one" % len( times) try: remaining = find_ts_remaining(timestamp, yumlibpath=self.conf.persistdir) except yum.Errors.MiscError, e: self.logger.error("Error: %s" % e) self.logger.error("Please report this error to: %s" % self.conf.bugtracker_url) sys.exit(1)