[ Avaa Bypassed ]




Upload:

Command:

hmhc3928@18.191.200.151: ~ $
#! /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)

Filemanager

Name Type Size Permission Actions
Errors.py File 4.26 KB 0755
Errors.pyc File 9.08 KB 0644
__init__.py File 304.1 KB 0755
__init__.pyc File 199.78 KB 0644
callbacks.py File 5.64 KB 0755
callbacks.pyc File 6.23 KB 0644
comps.py File 31.59 KB 0755
comps.pyc File 26.87 KB 0644
config.py File 49.89 KB 0755
config.pyc File 48.02 KB 0644
constants.py File 4.52 KB 0755
constants.pyc File 3.42 KB 0644
depsolve.py File 74.05 KB 0755
depsolve.pyc File 46.91 KB 0644
drpm.py File 12.85 KB 0755
drpm.pyc File 10.83 KB 0644
failover.py File 5 KB 0755
failover.pyc File 5.24 KB 0644
fssnapshots.py File 10.16 KB 0755
fssnapshots.pyc File 9.75 KB 0644
history.py File 61.13 KB 0755
history.pyc File 53.31 KB 0644
i18n.py File 20.44 KB 0755
i18n.pyc File 16.05 KB 0644
igroups.py File 9.31 KB 0755
igroups.pyc File 10.22 KB 0644
logginglevels.py File 7.9 KB 0755
logginglevels.pyc File 6.51 KB 0644
mdparser.py File 6.26 KB 0755
mdparser.pyc File 7.58 KB 0644
metalink.py File 9.19 KB 0755
metalink.pyc File 8.84 KB 0644
misc.py File 39.57 KB 0755
misc.pyc File 39.58 KB 0644
packageSack.py File 40.79 KB 0755
packageSack.pyc File 41.88 KB 0644
packages.py File 84.1 KB 0755
packages.pyc File 84.51 KB 0644
parser.py File 7.97 KB 0755
parser.pyc File 6.5 KB 0644
pgpmsg.py File 53.5 KB 0755
pgpmsg.pyc File 38.27 KB 0644
pkgtag_db.py File 4.86 KB 0755
pkgtag_db.pyc File 5.06 KB 0644
plugins.py File 28.1 KB 0755
plugins.pyc File 29.1 KB 0644
repoMDObject.py File 11.23 KB 0755
repoMDObject.pyc File 9.17 KB 0644
repos.py File 16.53 KB 0755
repos.pyc File 17.38 KB 0644
rpmsack.py File 70.25 KB 0755
rpmsack.pyc File 58.36 KB 0644
rpmtrans.py File 24.84 KB 0755
rpmtrans.pyc File 22.54 KB 0644
sqlitesack.py File 69.76 KB 0755
sqlitesack.pyc File 53.75 KB 0644
sqlutils.py File 6.27 KB 0755
sqlutils.pyc File 5.6 KB 0644
transactioninfo.py File 33.78 KB 0755
transactioninfo.pyc File 30.29 KB 0644
update_md.py File 25.9 KB 0755
update_md.pyc File 21.72 KB 0644
updateinfo.py File 18.29 KB 0755
updateinfo.pyc File 16.36 KB 0644
yumRepo.py File 83.85 KB 0755
yumRepo.pyc File 64.83 KB 0644