golden hour
/usr/lib/python2.7/site-packages/yum
⬆️ Go Up
Upload
File/Folder
Size
Actions
Errors.py
4.26 KB
Del
OK
Errors.pyc
9.08 KB
Del
OK
__init__.py
304.17 KB
Del
OK
__init__.pyc
199.58 KB
Del
OK
callbacks.py
5.64 KB
Del
OK
callbacks.pyc
6.23 KB
Del
OK
comps.py
31.59 KB
Del
OK
comps.pyc
26.87 KB
Del
OK
config.py
49.89 KB
Del
OK
config.pyc
48.02 KB
Del
OK
constants.py
4.94 KB
Del
OK
constants.pyc
3.46 KB
Del
OK
depsolve.py
74.05 KB
Del
OK
depsolve.pyc
46.75 KB
Del
OK
drpm.py
12.65 KB
Del
OK
drpm.pyc
10.69 KB
Del
OK
failover.py
5 KB
Del
OK
failover.pyc
5.24 KB
Del
OK
fssnapshots.py
10.16 KB
Del
OK
fssnapshots.pyc
9.75 KB
Del
OK
history.py
61.13 KB
Del
OK
history.pyc
53.31 KB
Del
OK
i18n.py
20.44 KB
Del
OK
i18n.pyc
16.05 KB
Del
OK
igroups.py
9.31 KB
Del
OK
igroups.pyc
10.22 KB
Del
OK
logginglevels.py
7.9 KB
Del
OK
logginglevels.pyc
6.51 KB
Del
OK
mdparser.py
6.26 KB
Del
OK
mdparser.pyc
7.58 KB
Del
OK
metalink.py
9.19 KB
Del
OK
metalink.pyc
8.84 KB
Del
OK
misc.py
39.57 KB
Del
OK
misc.pyc
39.58 KB
Del
OK
packageSack.py
40.79 KB
Del
OK
packageSack.pyc
41.88 KB
Del
OK
packages.py
84.1 KB
Del
OK
packages.pyc
84.51 KB
Del
OK
parser.py
7.97 KB
Del
OK
parser.pyc
6.5 KB
Del
OK
pgpmsg.py
53.5 KB
Del
OK
pgpmsg.pyc
38.27 KB
Del
OK
pkgtag_db.py
4.86 KB
Del
OK
pkgtag_db.pyc
5.06 KB
Del
OK
plugins.py
28.1 KB
Del
OK
plugins.pyc
29.1 KB
Del
OK
repoMDObject.py
11.23 KB
Del
OK
repoMDObject.pyc
9.17 KB
Del
OK
repos.py
16.53 KB
Del
OK
repos.pyc
17.38 KB
Del
OK
rpmsack.py
70.25 KB
Del
OK
rpmsack.pyc
58.36 KB
Del
OK
rpmtrans.py
24.84 KB
Del
OK
rpmtrans.pyc
22.54 KB
Del
OK
sqlitesack.py
69.76 KB
Del
OK
sqlitesack.pyc
53.75 KB
Del
OK
sqlutils.py
6.27 KB
Del
OK
sqlutils.pyc
5.6 KB
Del
OK
transactioninfo.py
33.78 KB
Del
OK
transactioninfo.pyc
30.29 KB
Del
OK
update_md.py
25.9 KB
Del
OK
update_md.pyc
21.72 KB
Del
OK
updateinfo.py
18.29 KB
Del
OK
updateinfo.pyc
16.36 KB
Del
OK
yumRepo.py
83.85 KB
Del
OK
yumRepo.pyc
64.83 KB
Del
OK
Edit: transactioninfo.py
#! /usr/bin/python -tt # 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 Library 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. # Copyright 2005 Duke University # Written by Seth Vidal # TODOS: make all the package relationships deal with package objects # search by package object for TransactionData, etc. # provide a real TransactionData.remove(txmbr) method, It should # remove the given txmbr and iterate to remove all those in depedent relationships # with the given txmbr. """ Classes and functions for manipulating a transaction to be passed to rpm. """ from constants import * from packageSack import PackageSack, PackageSackVersion from packages import YumInstalledPackage from sqlitesack import YumAvailablePackageSqlite import Errors import warnings import misc import time class GetProvReqOnlyPackageSack(PackageSack): def __init__(self, need_files=False): PackageSack.__init__(self) self._need_index_files = need_files def __addPackageToIndex_primary_files(self, obj): for ftype in obj.returnFileTypes(primary_only=True): for file in obj.returnFileEntries(ftype, primary_only=True): self._addToDictAsList(self.filenames, file, obj) def __addPackageToIndex_files(self, obj): for ftype in obj.returnFileTypes(): for file in obj.returnFileEntries(ftype): self._addToDictAsList(self.filenames, file, obj) def _addPackageToIndex(self, obj): for (n, fl, (e,v,r)) in obj.returnPrco('provides'): self._addToDictAsList(self.provides, n, obj) for (n, fl, (e,v,r)) in obj.returnPrco('requires'): self._addToDictAsList(self.requires, n, obj) if self._need_index_files: self.__addPackageToIndex_files(obj) else: self.__addPackageToIndex_primary_files(obj) def __buildFileIndexes(self): for repoid in self.pkgsByRepo: for obj in self.pkgsByRepo[repoid]: self.__addPackageToIndex_files(obj) def searchFiles(self, name): if not self._need_index_files and not misc.re_primary_filename(name): self._need_index_files = True if self.indexesBuilt: self.filenames = {} self.__buildFileIndexes() return PackageSack.searchFiles(self, name) class TransactionData: """Data Structure designed to hold information on a yum Transaction Set""" def __init__(self): self.flags = [] self.vsflags = [] self.probFilterFlags = [] self.root = '/' self.pkgdict = {} # key = pkgtup, val = list of TransactionMember obj self._namedict = {} # name -> list of TransactionMember obj self._unresolvedMembers = set() self.debug = 0 self.changed = False self.installonlypkgs = [] self.state_counter = 0 self.tm_created = time.time() self.tm_changed = time.time() self.conditionals = {} # key = pkgname, val = list of pos to add self.rpmdb = None self._pkgSack = None self._pkgSackCtor = None self.pkgSackPackages = 0 self.localSack = PackageSack() self._inSack = GetProvReqOnlyPackageSack() # lists of txmbrs in their states - just placeholders self.instgroups = [] self.removedgroups = [] self.instenvironments = [] self.removedenvironments = [] self.removed = [] self.installed = [] self.updated = [] self.obsoleted = [] self.depremoved = [] self.depinstalled = [] self.depupdated = [] self.reinstalled = [] self.downgraded = [] self.failed = [] self._future_rpmdbv = None self._check_future_rpmdbv = None def _changed(self): self.changed = True self.state_counter += 1 self.tm_changed = time.time() def __len__(self): return len(self.pkgdict) def __iter__(self): if hasattr(self.getMembers(), '__iter__'): return self.getMembers().__iter__() else: return iter(self.getMembers()) def _getPkgSack(self): if self._pkgSack is not None: return self._pkgSack if self._pkgSackCtor is not None: self._pkgSack = self._pkgSackCtor() return self._pkgSack pkgSack = property(fget=lambda self: self._getPkgSack(), fset=lambda self, value: setattr(self, "_pkgSack",value), fdel=lambda self: setattr(self, "_pkgSack", None), doc="Package sack object") def debugprint(self, msg): if self.debug: print msg def getMembersWithState(self, pkgtup=None, output_states=None): return filter(lambda p: p.output_state in output_states, self.getMembers(pkgtup)) def getMembers(self, pkgtup=None): """takes an optional package tuple and returns all transaction members matching, no pkgtup means it returns all transaction members""" returnlist = [] if pkgtup is None: for members in self.pkgdict.itervalues(): returnlist.extend(members) elif pkgtup in self.pkgdict: returnlist.extend(self.pkgdict[pkgtup]) return returnlist # The order we resolve things in _matters_, so for sanity sort the list # otherwise .i386 can be different to .x86_64 etc. def getUnresolvedMembers(self): return list(sorted(self._unresolvedMembers)) def markAsResolved(self, txmbr): self._unresolvedMembers.discard(txmbr) def resetResolved(self, hard=False): if hard or len(self) < len(self._unresolvedMembers): self._unresolvedMembers.clear() self._unresolvedMembers.update(self.getMembers()) return True return False def getMode(self, name=None, arch=None, epoch=None, ver=None, rel=None): """returns the mode of the first match from the transaction set, otherwise, returns None""" txmbrs = self.matchNaevr(name=name, arch=arch, epoch=epoch, ver=ver, rel=rel) if not len(txmbrs): return None states = [] for txmbr in txmbrs: states.append(txmbr.ts_state) if 'u' in states: return 'u' elif 'i' in states: return 'i' else: return states[0] def matchNaevr(self, name=None, arch=None, epoch=None, ver=None, rel=None): """returns the list of packages matching the args above""" if name is None: txmbrs = self.getMembers() else: txmbrs = self._namedict.get(name, []) if arch is None and epoch is None and ver is None and rel is None: return txmbrs[:] result = [] for txmbr in txmbrs: (n, a, e, v, r) = txmbr.pkgtup # Name is done above if arch is not None and arch != a: continue if epoch is not None and epoch != e: continue if ver is not None and ver != v: continue if rel is not None and rel != r: continue result.append(txmbr) return result def deselect(self, pattern): """ Remove these packages from the transaction. This is more user orientated than .remove(). Used from kickstart/install -blah. """ # We don't have a returnPackages() here, so just try the "simple" # specifications. Pretty much 100% hit rate on kickstart. txmbrs = self.matchNaevr(pattern) if not txmbrs: na = pattern.rsplit('.', 2) if len(na) == 2: txmbrs = self.matchNaevr(na[0], na[1]) if not txmbrs: pkgs = [] if self._inSack is not None: pkgs = self._inSack.returnPackages(patterns=[pattern]) if not pkgs and self.pkgSack is not None: pkgs = self.pkgSack.returnPackages(patterns=[pattern]) if not pkgs: pkgs = self.rpmdb.returnPackages(patterns=[pattern]) for pkg in pkgs: txmbrs.extend(self.getMembers(pkg.pkgtup)) # Now we need to do conditional group packages, so they don't # get added later on. This is hacky :( for req, cpkgs in self.conditionals.iteritems(): if pkg in cpkgs: cpkgs.remove(pkg) self.conditionals[req] = cpkgs for txmbr in txmbrs: self.remove(txmbr.pkgtup) return txmbrs def _isLocalPackage(self, txmember): # Is this the right criteria? # FIXME: This is kinda weird, we really want all local pkgs to be in a # special pkgsack before this point ... so that "yum up ./*.rpm" works. # Also FakePackage() sets it off ... which is confusing and not what # happens IRL. return txmember.ts_state in ('u', 'i') and not isinstance(txmember.po, (YumInstalledPackage, YumAvailablePackageSqlite)) # NOTE: This is a copy of Depsolve.allowedMultipleInstalls() because # we can't get to YumBase from here. Use that as the main/public API. def _allowedMultipleInstalls(self, po): """takes a packageObject, returns 1 or 0 depending on if the package should/can be installed multiple times with different vers like kernels and kernel modules, for example""" if po.name in self.installonlypkgs: return True provides = po.provides_names if filter (lambda prov: prov in self.installonlypkgs, provides): return True return False def add(self, txmember): """add a package to the transaction""" for oldpo in txmember.updates: self.addUpdated(oldpo, txmember.po) if txmember.pkgtup not in self.pkgdict: self.pkgdict[txmember.pkgtup] = [] else: self.debugprint("Package: %s.%s - %s:%s-%s already in ts" % txmember.pkgtup) for member in self.pkgdict[txmember.pkgtup]: if member.ts_state == txmember.ts_state: self.debugprint("Package in same mode, skipping.") return self.pkgdict[txmember.pkgtup].append(txmember) self._namedict.setdefault(txmember.name, []).append(txmember) self._changed() if self._isLocalPackage(txmember): self.localSack.addPackage(txmember.po) elif isinstance(txmember.po, YumAvailablePackageSqlite): self.pkgSackPackages += 1 if self._inSack is not None and txmember.output_state in TS_INSTALL_STATES: if not txmember.po.have_fastReturnFileEntries(): # In theory we could keep this on if a "small" repo. fails self._inSack = None else: self._inSack.addPackage(txmember.po) if txmember.name in self.conditionals: for pkg in self.conditionals[txmember.name]: if self.rpmdb.contains(po=pkg): continue for condtxmbr in self.install_method(po=pkg): condtxmbr.setAsDep(po=txmember.po) self._unresolvedMembers.add(txmember) def remove(self, pkgtup): """remove a package from the transaction""" if pkgtup not in self.pkgdict: self.debugprint("Package: %s not in ts" %(pkgtup,)) return for txmbr in self.pkgdict[pkgtup]: txmbr.po.state = None if self._isLocalPackage(txmbr): self.localSack.delPackage(txmbr.po) elif isinstance(txmbr.po, YumAvailablePackageSqlite): self.pkgSackPackages -= 1 if self._inSack is not None and txmbr.output_state in TS_INSTALL_STATES: self._inSack.delPackage(txmbr.po) self._namedict[txmbr.name].remove(txmbr) self._unresolvedMembers.add(txmbr) del self.pkgdict[pkgtup] if not self._namedict[pkgtup[0]]: del self._namedict[pkgtup[0]] self._changed() def exists(self, pkgtup): """tells if the pkg is in the class""" if pkgtup in self.pkgdict: if len(self.pkgdict[pkgtup]) != 0: return 1 return 0 def isObsoleted(self, pkgtup): """true if the pkgtup is marked to be obsoleted""" if self.exists(pkgtup): for txmbr in self.getMembers(pkgtup=pkgtup): if txmbr.output_state == TS_OBSOLETED: return True return False def makelists(self, include_reinstall=False, include_downgrade=False): """returns lists of transaction Member objects based on mode: updated, installed, erased, obsoleted, depupdated, depinstalled deperased""" self.instgroups = [] self.removedgroups = [] self.instenvironments = [] self.removedenvironments = [] self.removed = [] self.installed = [] self.updated = [] self.obsoleted = [] self.depremoved = [] self.depinstalled = [] self.depupdated = [] self.reinstalled = [] self.downgraded = [] self.failed = [] for txmbr in self.getMembers(): if txmbr.output_state == TS_UPDATE: if txmbr.isDep: self.depupdated.append(txmbr) else: self.updated.append(txmbr) elif txmbr.output_state in (TS_INSTALL, TS_TRUEINSTALL): if include_reinstall and txmbr.reinstall: self.reinstalled.append(txmbr) continue if include_downgrade and txmbr.downgrades: self.downgraded.append(txmbr) continue if txmbr.groups: for g in txmbr.groups: if g not in self.instgroups: self.instgroups.append(g) if txmbr.environments: for evg in txmbr.environments: if evg not in self.instenvironments: self.instenvironments.append(evg) # "user" here is kind of a hack ... we really shouldn't have # .isDep == True, but this probably doesn't hurt. if txmbr.isDep and txmbr.reason != 'user': self.depinstalled.append(txmbr) else: self.installed.append(txmbr) elif txmbr.output_state == TS_ERASE: if include_downgrade and txmbr.downgraded_by: continue for g in txmbr.groups: if g not in self.instgroups: self.removedgroups.append(g) for evg in txmbr.environments: if evg not in self.instenvironments: self.removedenvironments.append(evg) if txmbr.isDep: self.depremoved.append(txmbr) else: self.removed.append(txmbr) elif txmbr.output_state == TS_OBSOLETED: self.obsoleted.append(txmbr) elif txmbr.output_state == TS_OBSOLETING: self.installed.append(txmbr) elif txmbr.output_state == TS_FAILED: self.failed.append(txmbr) else: pass self.updated.sort() self.installed.sort() self.removed.sort() self.obsoleted.sort() self.depupdated.sort() self.depinstalled.sort() self.depremoved.sort() self.instgroups.sort() self.removedgroups.sort() self.instenvironments.sort() self.removedenvironments.sort() self.reinstalled.sort() self.downgraded.sort() self.failed.sort() def addInstall(self, po): """adds a package as an install but in mode 'u' to the ts takes a packages object and returns a TransactionMember Object""" if self._allowedMultipleInstalls(po): return self.addTrueInstall(po) txmbr = TransactionMember(po) txmbr.current_state = TS_AVAILABLE txmbr.output_state = TS_INSTALL txmbr.po.state = TS_INSTALL txmbr.ts_state = 'u' if self.rpmdb.contains(po=txmbr.po): txmbr.reinstall = True self.findObsoletedByThisMember(txmbr) self.add(txmbr) return txmbr def addTrueInstall(self, po): """adds a package as an install takes a packages object and returns a TransactionMember Object""" txmbr = TransactionMember(po) txmbr.current_state = TS_AVAILABLE txmbr.output_state = TS_TRUEINSTALL txmbr.po.state = TS_INSTALL txmbr.ts_state = 'i' if self.rpmdb.contains(po=txmbr.po): txmbr.reinstall = True self.add(txmbr) return txmbr def addErase(self, po): """adds a package as an erasure takes a packages object and returns a TransactionMember Object""" txmbr = TransactionMember(po) txmbr.current_state = TS_INSTALL txmbr.output_state = TS_ERASE txmbr.po.state = TS_INSTALL txmbr.ts_state = 'e' self.add(txmbr) return txmbr def addUpdate(self, po, oldpo=None): """adds a package as an update takes a packages object and returns a TransactionMember Object""" if self._allowedMultipleInstalls(po): return self.addTrueInstall(po) txmbr = TransactionMember(po) txmbr.current_state = TS_AVAILABLE txmbr.output_state = TS_UPDATE txmbr.po.state = TS_UPDATE txmbr.ts_state = 'u' if oldpo: txmbr.relatedto.append((oldpo, 'updates')) txmbr.updates.append(oldpo) self.add(txmbr) self.findObsoletedByThisMember(txmbr) return txmbr def addDowngrade(self, po, oldpo): """adds a package as an downgrade takes a packages object and returns a pair of TransactionMember Objects""" itxmbr = self.addErase(oldpo) itxmbr.relatedto.append((po, 'downgradedby')) itxmbr.downgraded_by.append(po) atxmbr = self.addInstall(po) if not atxmbr: # Fail? self.remove(itxmbr.pkgtup) return None if 'reason' in oldpo.yumdb_info: atxmbr.reason = oldpo.yumdb_info.reason atxmbr.relatedto.append((oldpo, 'downgrades')) atxmbr.downgrades.append(oldpo) return (itxmbr, atxmbr) def addUpdated(self, po, updating_po): """adds a package as being updated by another pkg takes a packages object and returns a TransactionMember Object""" txmbr = TransactionMember(po) txmbr.current_state = TS_INSTALL txmbr.output_state = TS_UPDATED txmbr.po.state = TS_UPDATED txmbr.ts_state = 'ud' txmbr.relatedto.append((updating_po, 'updatedby')) txmbr.updated_by.append(updating_po) if 'reason' in po.yumdb_info: # Propbably worthless, but... txmbr.reason = po.yumdb_info.reason self.add(txmbr) return txmbr def addObsoleting(self, po, oldpo): """adds a package as an obsolete over another pkg takes a packages object and returns a TransactionMember Object""" txmbr = TransactionMember(po) txmbr.current_state = TS_AVAILABLE txmbr.output_state = TS_OBSOLETING txmbr.po.state = TS_OBSOLETING txmbr.ts_state = 'u' txmbr.relatedto.append((oldpo, 'obsoletes')) txmbr.obsoletes.append(oldpo) if self.rpmdb.contains(po=txmbr.po): txmbr.reinstall = True self.add(txmbr) return txmbr def addObsoleted(self, po, obsoleting_po): """adds a package as being obsoleted by another pkg takes a packages object and returns a TransactionMember Object""" txmbr = TransactionMember(po) txmbr.current_state = TS_INSTALL txmbr.output_state = TS_OBSOLETED txmbr.po.state = TS_OBSOLETED txmbr.ts_state = 'od' txmbr.relatedto.append((obsoleting_po, 'obsoletedby')) txmbr.obsoleted_by.append(obsoleting_po) if 'reason' in po.yumdb_info: # Propbably worthless, but... txmbr.reason = po.yumdb_info.reason self.add(txmbr) for otxmbr in self.getMembersWithState(obsoleting_po.pkgtup, [TS_OBSOLETING]): if po in otxmbr.obsoletes: continue otxmbr.relatedto.append((po, 'obsoletes')) otxmbr.obsoletes.append(po) return txmbr def setDatabases(self, rpmdb, pkgSack, pkgSackCtor=None): self.rpmdb = rpmdb self._pkgSack = pkgSack self._pkgSackCtor = pkgSackCtor def getNewProvides(self, name, flag=None, version=(None, None, None)): """return dict { packages -> list of matching provides } searches in packages to be installed""" result = { } if not self.pkgSackPackages: pass elif self._inSack is None: for pkg, hits in self.pkgSack.getProvides(name, flag, version).iteritems(): if self.getMembersWithState(pkg.pkgtup, TS_INSTALL_STATES): result[pkg] = hits else: for pkg, hits in self._inSack.getProvides(name, flag, version).iteritems(): result[pkg] = hits result.update(self.localSack.getProvides(name, flag, version)) return result def getOldProvides(self, name, flag=None, version=(None, None, None)): """return dict { packages -> list of matching provides } searches in packages already installed and not going to be removed""" result = { } for pkg, hits in self.rpmdb.getProvides(name, flag, version).iteritems(): if not self.getMembersWithState(pkg.pkgtup, TS_REMOVE_STATES): result[pkg] = hits return result def getProvides(self, name, flag=None, version=(None, None, None)): """return dict { packages -> list of matching provides }""" result = self.getOldProvides(name, flag, version) result.update(self.getNewProvides(name, flag, version)) return result def getNewRequires(self, name, flag=None, version=(None, None, None)): """return dict { packages -> list of matching provides } searches in packages to be installed""" result = { } if not self.pkgSackPackages: pass elif self._inSack is None: for pkg, hits in self.pkgSack.getRequires(name, flag, version).iteritems(): if self.getMembersWithState(pkg.pkgtup, TS_INSTALL_STATES): result[pkg] = hits else: for pkg, hits in self._inSack.getRequires(name, flag, version).iteritems(): result[pkg] = hits result.update(self.localSack.getRequires(name, flag, version)) return result def getOldRequires(self, name, flag=None, version=(None, None, None)): """return dict { packages -> list of matching provides } searches in packages already installed and not going to be removed""" result = { } for pkg, hits in self.rpmdb.getRequires(name, flag, version).iteritems(): if not self.getMembersWithState(pkg.pkgtup, TS_REMOVE_STATES): result[pkg] = hits return result def getRequires(self, name, flag=None, version=(None, None, None)): """return dict { packages -> list of matching provides }""" result = self.getOldRequires(name, flag, version) result.update(self.getNewRequires(name, flag, version)) return result def futureRpmDBVersion(self): """ Return a simple version for the future rpmdb. Works like rpmdb.simpleVersion(main_only=True)[0], but for the state the rpmdb will be in after the transaction. """ if self._future_rpmdbv is not None: sc, ret = self._future_rpmdbv if sc == self.state_counter: return ret pkgs = self.rpmdb.returnPackages() _reinstalled_pkgtups = {} for txmbr in self.getMembersWithState(None, TS_INSTALL_STATES): # reinstalls have to use their "new" checksum data, in case it's # different. if txmbr.reinstall: _reinstalled_pkgtups[txmbr.po.pkgtup] = txmbr.po pkgs.append(txmbr.po) self.rpmdb.preloadPackageChecksums() main = PackageSackVersion() pkg_checksum_tups = [] for pkg in sorted(pkgs): if pkg.repoid != 'installed': # Paste from PackageSackBase.simpleVersion() csum = pkg.returnIdSum() main.update(pkg, csum) pkg_checksum_tups.append((pkg.pkgtup, csum)) continue # Installed pkg, see if it's about to die if self.getMembersWithState(pkg.pkgtup, TS_REMOVE_STATES): continue # ...or die and be risen again (Zombie!) if pkg.pkgtup in _reinstalled_pkgtups: continue # Paste from rpmdb.simpleVersion() ydbi = pkg.yumdb_info csum = None if 'checksum_type' in ydbi and 'checksum_data' in ydbi: csum = (ydbi.checksum_type, ydbi.checksum_data) # We need all the pkgtups, so we even save the ones without a # checksum. pkg_checksum_tups.append((pkg.pkgtup, csum)) main.update(pkg, csum) self.rpmdb.transactionCachePackageChecksums(pkg_checksum_tups) self._future_rpmdbv = (self.state_counter, main) return main def findObsoletedByThisMember(self, txmbr): """addObsoleted() pkgs for anything that this txmbr will obsolete""" # this is mostly to keep us in-line with what will ACTUALLY happen # when rpm hits the obsoletes, whether we added them or not for obs_n in txmbr.po.obsoletes_names: for pkg in self.rpmdb.searchNevra(name=obs_n): if pkg.obsoletedBy([txmbr.po]): self.addObsoleted(pkg, txmbr.po) txmbr.output_state = TS_OBSOLETING txmbr.po.state = TS_OBSOLETING class ConditionalTransactionData(TransactionData): """A transaction data implementing conditional package addition""" def __init__(self): warnings.warn("ConditionalTransactionData will go away in a future " "version of Yum.", Errors.YumFutureDeprecationWarning) TransactionData.__init__(self) class SortableTransactionData(TransactionData): """A transaction data implementing topological sort on it's members""" def __init__(self): # Cache of sort self._sorted = [] # Current dependency path self.path = [] # List of loops self.loops = [] TransactionData.__init__(self) def _visit(self, txmbr): self.path.append(txmbr.name) txmbr.sortColour = TX_GREY for po in txmbr.depends_on: vertex = self.getMembers(pkgtup=po.pkgtup)[0] if vertex.sortColour == TX_GREY: self._doLoop(vertex.name) if vertex.sortColour == TX_WHITE: self._visit(vertex) txmbr.sortColour = TX_BLACK self._sorted.insert(0, txmbr.pkgtup) def _doLoop(self, name): self.path.append(name) loop = self.path[self.path.index(self.path[-1]):] if len(loop) > 2: self.loops.append(loop) def add(self, txmember): txmember.sortColour = TX_WHITE TransactionData.add(self, txmember) self._sorted = [] def remove(self, pkgtup): TransactionData.remove(self, pkgtup) self._sorted = [] def sort(self): if self._sorted: return self._sorted self._sorted = [] # loop over all members for txmbr in self.getMembers(): if txmbr.sortColour == TX_WHITE: self.path = [ ] self._visit(txmbr) self._sorted.reverse() return self._sorted class TransactionMember: """Class to describe a Transaction Member (a pkg to be installed/ updated/erased).""" def __init__(self, po): # holders for data self.po = po # package object self.current_state = None # where the package currently is (repo, installed) self.ts_state = None # what state to put it into in the transaction set self.output_state = None # what state to list if printing it self.isDep = 0 self.reason = 'user' # reason for it to be in the transaction set self.process = None # I think this is used nowhere by nothing - skv 2010/11/03 self.relatedto = [] # ([relatedpkg, relationship)] self.depends_on = [] self.obsoletes = [] self.obsoleted_by = [] self.updates = [] self.updated_by = [] self.downgrades = [] self.downgraded_by = [] self.reinstall = False self.groups = [] # groups it's in self.environments = [] # Env. groups it's in self.repopkg = None # repo pkg "group" it was removed/installed by self._poattr = ['pkgtup', 'repoid', 'name', 'arch', 'epoch', 'version', 'release'] for attr in self._poattr: val = getattr(self.po, attr) setattr(self, attr, val) if po.repoid == 'installed': # We want to load these so that we can auto hardlink in the same # new values. Because of the hardlinks it should be really cheap # to load them ... although it's still a minor hack. po.yumdb_info.get('from_repo') po.yumdb_info.get('releasever') po.yumdb_info.get('changed_by') def setAsDep(self, po=None, relonly=False): """sets the transaction member as a dependency and maps the dep into the relationship list attribute""" if not relonly: self.isDep = 1 if po: self.relatedto.append((po, 'dependson')) self.depends_on.append(po) def removeDep(self, po): """sets the transaction member as a dependency and maps the dep into the relationship list attribute""" nrelto = [] for data in self.relatedto: if data[0] == po: continue nrelto.append(data) self.relatedto = nrelto ndepon = [] for data in self.depends_on: if data == po: continue ndepon.append(data) self.depends_on = ndepon def __cmp__(self, other): return cmp(self.po, other.po) def __hash__(self): return object.__hash__(self) def __str__(self): return "%s.%s %s:%s-%s - %s" % (self.name, self.arch, self.epoch, self.version, self.release, self.ts_state) def __repr__(self): return "<%s : %s (%s)>" % (self.__class__.__name__, str(self),hex(id(self))) def _dump(self): msg = ["mbr: %s,%s,%s,%s,%s %s\n" % (self.name, self.arch, self.epoch, self.version, self.release, self.current_state), " repo: %s\n" % self.po.repo.id, " ts_state: %s\n" % self.ts_state, " output_state: %s\n" % self.output_state, " isDep: %s\n" % bool(self.isDep), " reason: %s\n" % self.reason, # " process: %s\n" % self.process, " reinstall: %s\n" % bool(self.reinstall)] if self.relatedto: msg += [" relatedto:"] for (po, rel) in self.relatedto: pkgorigin = 'a' if isinstance(po, YumInstalledPackage): pkgorigin = 'i' msg += [" %s,%s,%s,%s,%s@%s:%s" % (po.name, po.arch, po.epoch, po.version, po.release, pkgorigin, rel)] msg += ["\n"] for lst in ['depends_on', 'obsoletes', 'obsoleted_by', 'downgrades', 'downgraded_by', 'updates', 'updated_by']: thislist = getattr(self, lst) if thislist: msg += [" %s:" % lst] for po in thislist: pkgorigin = 'a' if isinstance(po, YumInstalledPackage): pkgorigin = 'i' msg += [" %s,%s,%s,%s,%s@%s" % (po.name, po.arch, po.epoch, po.version, po.release, pkgorigin)] msg += ["\n"] if self.groups: msg += [" groups: %s\n" % ' '.join(self.groups)] if self.environments: msg += [" environments: %s\n" % ' '.join(self.environments)] if self.repopkg: msg += [" repopkg: %s\n" % self.repopkg] return ''.join(msg)
Save