def getConflicts(self): """Check for conflicts in conflicts and obsoletes among currently installed packages. Return a HashList: RpmPackage => [((name, RPMSENSE_* flags, EVR string), conflicting RpmPackage)].""" conflicts = HashList() if self.config.noconflicts: # conflicts turned off return conflicts if self.config.checkinstalled == 0: for r in self.installs: log.debug1("Checking for conflicts for %s", r.getNEVRA()) self.getPkgConflicts(r, r["conflicts"] + r["obsoletes"], conflicts) return conflicts for name in self.database.getNames(): for r in self.database.getPkgsByName(name): log.debug1("Checking for conflicts for %s", r.getNEVRA()) self.getPkgConflicts(r, r["conflicts"] + r["obsoletes"], conflicts) return conflicts
def getConflicts(self): """Check for conflicts in conflicts and obsoletes among currently installed packages. Return a HashList: RpmPackage => [((name, RPMSENSE_* flags, EVR string), conflicting RpmPackage)].""" conflicts = HashList() if self.config.noconflicts: # conflicts turned off return conflicts if self.config.checkinstalled == 0: for r in self.installs: log.debug1("Checking for conflicts for %s", r.getNEVRA()) self.getPkgConflicts(r, r["conflicts"] + r["obsoletes"], conflicts) return conflicts for name in self.database.getNames(): for r in self.database.getPkgsByName(name): log.debug1( "Checking for conflicts for %s", r.getNEVRA()) self.getPkgConflicts(r, r["conflicts"] + r["obsoletes"], conflicts) return conflicts
def genRelations(self, rpms, operation, externaldb=None): # clear list to get to a sane state self.clear() # add relations for all packages for pkg in rpms: self[pkg] = RpmRelation() # Build a new resolver to list all dependencies between packages. if externaldb: db = RpmExternalSearchDB(externaldb, self.config, None) else: db = RpmMemoryDB(self.config, None) db.addPkgs(rpms) resolver = RpmResolver(self.config, db, nocheck=1) # Add dependencies: for pkg in db.getPkgs(): log.debug1("Generating relations for %s", pkg.getNEVRA()) resolved = resolver.getResolvedPkgDependencies(pkg) # ignore unresolved, we are only looking at the changes, # therefore not all symbols are resolvable in these changes for ((name, flag, version), s) in resolved: if name[:7] == "config(": continue f = operationFlag(flag, operation) for pkg2 in s: if pkg2 != pkg: self.addRelation(pkg, pkg2, f) self.printRel()
def __arch_incompat(self, pkg, r): """Return True (and warn) if RpmPackage's pkg and r have different architectures, but the same base arch. Warn the user before returning True.""" if pkg["arch"] != r["arch"] and archDuplicate(pkg["arch"], r["arch"]): log.debug1("%s does not match arch %s.", pkg.getNEVRA(), r["arch"]) return 1 return 0
def getResolvedDependencies(self): """Get resolved dependencies. Return a HashList: RpmPackage => [((name, RPMSENSE_* flags, EVR string), [relevant resolving RpmPackage's])].""" all_resolved = HashList() for name in self.database.getNames(): for r in self.database.getPkgsByName(name): log.debug1("Checking dependencies for %s", r.getNEVRA()) (unresolved, resolved) = self.getPkgDependencies(r) if len(resolved) > 0: all_resolved.setdefault(r, [ ]).extend(resolved) return all_resolved
def getResolvedDependencies(self): """Get resolved dependencies. Return a HashList: RpmPackage => [((name, RPMSENSE_* flags, EVR string), [relevant resolving RpmPackage's])].""" all_resolved = HashList() for name in self.database.getNames(): for r in self.database.getPkgsByName(name): log.debug1("Checking dependencies for %s", r.getNEVRA()) (unresolved, resolved) = self.getPkgDependencies(r) if len(resolved) > 0: all_resolved.setdefault(r, []).extend(resolved) return all_resolved
def order(self): """Order operations. Return an ordered list of operations on success, with tuples of the form (operation, RpmPackage). The operation is one of OP_INSTALL, OP_UPDATE or OP_ERASE per package. If an error occurs, return None.""" log.debug1("Start ordering") order = self.genOrder() if order == None: return None # generate operations return self.genOperations(order)
def __install_check(self, r, pkg): """Check whether RpmPackage pkg can be installed when RpmPackage r with same %name is already in the current list. Return an RpmList error code (after warning the user).""" if r == pkg or r.isEqual(pkg): if self.isInstalled(r): log.debug1("%s: %s is already installed", pkg.getNEVRA(), r.getNEVRA()) return self.ALREADY_INSTALLED else: log.debug1("%s: %s was already added", pkg.getNEVRA(), r.getNEVRA()) return self.ALREADY_ADDED return self.OK
def genOrder(self): """Order rpms in orderer.RpmRelations relations. Return an ordered list of RpmPackage's on success, None on error.""" length = len(self) order = [] connected_components = ConnectedComponentsDetector(self).detect(self) if connected_components: if log.isDebugLoggingHere(log.DEBUG1): # debug output the components log.debug1("-- STRONGLY CONNECTED COMPONENTS --") for i in xrange(len(connected_components)): s = ", ".join([ pkg.getNEVRA() for pkg in connected_components[i].pkgs ]) log.debug1(" %d: %s", i, s) # weights = self.calculateWeights() # weight_keys = weights.keys() # weight_keys.sort() # weight_keys.reverse() # for key in weight_keys: # if key == -1: continue # for pkg in weights[key]: # log.debug2("%s %s", key, pkg.getNEVRA()) # self.collect(pkg, order) self.processLeafNodes(order) if len(order) != length: log.error( "%d Packages of %d in order list! Number of connected " "components: %d ", len(order), length, len(connected_components)) return order
def checkDependencies(self): """Check dependencies, report errors. Return 1 if all dependencies are resolved, 0 if not (after warning the user).""" no_unresolved = 1 if self.config.checkinstalled == 0: unresolved = self.getUnresolvedDependencies() for p in unresolved.keys(): log.error("%s: unresolved dependencies:", p.getNEVRA()) for u in unresolved[p]: log.error("\t%s", depString(u)) if unresolved: return 0 return 1 for name in self.database.getNames(): for r in self.database.getPkgsByName(name): if self.config.checkinstalled == 0 and \ len(self.erases) == 0 and self.isInstalled(r): # do not check installed packages if no packages # are getting removed (by erase, update or obsolete) continue log.debug1("Checking dependencies for %s", r.getNEVRA()) (unresolved, resolved) = self.getPkgDependencies(r) if len(resolved) > 0: log.debug2("%s: resolved dependencies:", r.getNEVRA()) for (u, s) in resolved: s2 = "" for r2 in s: s2 += "%s " % r2.getNEVRA() log.debug2("\t%s: %s", depString(u), s2) if len(unresolved) > 0: no_unresolved = 0 log.error("%s: unresolved dependencies:", r.getNEVRA()) for u in unresolved: log.erro("\t%s", depString(u)) return no_unresolved
def genOrder(self): """Order rpms in orderer.RpmRelations relations. Return an ordered list of RpmPackage's on success, None on error.""" length = len(self) order = [ ] connected_components = ConnectedComponentsDetector(self).detect(self) if connected_components: if log.isDebugLoggingHere(log.DEBUG1): # debug output the components log.debug1("-- STRONGLY CONNECTED COMPONENTS --") for i in xrange(len(connected_components)): s = ", ".join([pkg.getNEVRA() for pkg in connected_components[i].pkgs]) log.debug1(" %d: %s", i, s) # weights = self.calculateWeights() # weight_keys = weights.keys() # weight_keys.sort() # weight_keys.reverse() # for key in weight_keys: # if key == -1: continue # for pkg in weights[key]: # log.debug2("%s %s", key, pkg.getNEVRA()) # self.collect(pkg, order) self.processLeafNodes(order) if len(order) != length: log.error("%d Packages of %d in order list! Number of connected " "components: %d ", len(order), length, len(connected_components)) return order
def getFileConflicts(self): """Find file conflicts among packages in self.database.names. Return a HashList: RpmPackage => [(filename, conflicting RpmPackage)].""" conflicts = HashList() db = self.database if self.config.nofileconflicts: # file conflicts turned off return conflicts if self.config.checkinstalled == 0: # no conflicts if there is no new package for pkg in self.installs: for name in pkg.iterFilenames(): dups = db.searchFilenames(name) if len(dups) == 1: continue log.debug1("Checking for file conflicts for '%s'", name) for p in dups: if p is pkg: continue if self._hasFileConflict(pkg, p, name): conflicts.setdefault(pkg, [ ]).append( (name, p)) return conflicts # duplicates: { name: [(pkg, idx),..], .. } duplicates = self.database.getFileDuplicates() for name in duplicates: dups = duplicates[name] log.debug1("Checking for file conflicts for '%s'", name) for j in xrange(len(dups)): for k in xrange(j+1, len(dups)): if not self._hasFileConflict(dups[j], dups[k], name): continue conflicts.setdefault(dups[j], [ ]).append((name, dups[k])) conflicts.setdefault(dups[k], [ ]).append((name, dups[j])) return conflicts
def getFileConflicts(self): """Find file conflicts among packages in self.database.names. Return a HashList: RpmPackage => [(filename, conflicting RpmPackage)].""" conflicts = HashList() db = self.database if self.config.nofileconflicts: # file conflicts turned off return conflicts if self.config.checkinstalled == 0: # no conflicts if there is no new package for pkg in self.installs: for name in pkg.iterFilenames(): dups = db.searchFilenames(name) if len(dups) == 1: continue log.debug1("Checking for file conflicts for '%s'", name) for p in dups: if p is pkg: continue if self._hasFileConflict(pkg, p, name): conflicts.setdefault(pkg, []).append((name, p)) return conflicts # duplicates: { name: [(pkg, idx),..], .. } duplicates = self.database.getFileDuplicates() for name in duplicates: dups = duplicates[name] log.debug1("Checking for file conflicts for '%s'", name) for j in xrange(len(dups)): for k in xrange(j + 1, len(dups)): if not self._hasFileConflict(dups[j], dups[k], name): continue conflicts.setdefault(dups[j], []).append((name, dups[k])) conflicts.setdefault(dups[k], []).append((name, dups[j])) return conflicts
def getObsoletes(self): """Check for obsoletes among packages in self.database.names. Return a HashList: RpmPackage => [((name, RPMSENSE_* flags, EVR string), obsoleted RpmPackage)].""" obsoletes = HashList() if self.config.noconflicts: # conflicts turned off, obsoletes are also conflicts, but in an # other level return obsoletes if self.config.checkinstalled == 0: for r in self.installs: log.debug1("Checking for obsoletes for %s", r.getNEVRA()) self.getPkgConflicts(r, r["obsoletes"], obsoletes) return obsoletes for name in self.database.getNames(): for r in self.database.getPkgsByName(name): log.debug1(1, "Checking for obsoletes for %s" % r.getNEVRA()) self.getPkgConflicts(r, r["obsoletes"], obsoletes) return obsoletes
def update(self, pkg): name = pkg["name"] # get obsoletes # Valid only during OP_UPDATE: list of RpmPackage's that will be # obsoleted by the current update self.pkg_obsoletes = set() for u in pkg["obsoletes"]: s = self.database.searchDependency(u[0], u[1], u[2]) for r in s: if r["name"] != pkg["name"]: self.pkg_obsoletes.add(r) # update package # Valid only during OP_UPDATE: list of RpmPackage's that will be # removed by the current update self.pkg_updates = [ ] for r in self.database.getPkgsByName(name): ret = pkgCompare(r, pkg) if ret > 0: # old_ver > new_ver if self.config.oldpackage == 0: if self.isInstalled(r): msg = "%s: A newer package is already installed" else: msg = "%s: A newer package was already added" log.debug1(msg, pkg.getNEVRA()) del self.pkg_updates return self.OLD_PACKAGE else: # old package: simulate a new package ret = -1 if ret < 0: # old_ver < new_ver if self.config.exactarch == 1 and \ self.__arch_incompat(pkg, r): del self.pkg_updates return self.ARCH_INCOMPAT if archDuplicate(pkg["arch"], r["arch"]) or \ pkg["arch"] == "noarch" or r["arch"] == "noarch": self.pkg_updates.append(r) else: # ret == 0, old_ver == new_ver if self.config.exactarch == 1 and \ self.__arch_incompat(pkg, r): del self.pkg_updates return self.ARCH_INCOMPAT ret = self.__install_check(r, pkg) # Fails for same NEVRAs if ret != self.OK: del self.pkg_updates return ret if archDuplicate(pkg["arch"], r["arch"]): if archCompat(pkg["arch"], r["arch"]): if self.isInstalled(r): msg = "%s: Ignoring due to installed %s" ret = self.ALREADY_INSTALLED else: msg = "%s: Ignoring due to already added %s" ret = self.ALREADY_ADDED log.debug1(msg, pkg.getNEVRA(), r.getNEVRA()) del self.pkg_updates return ret else: self.pkg_updates.append(r) ret = self.install(pkg, operation=OP_UPDATE) if ret != self.OK: del self.pkg_updates return ret for r in self.pkg_updates: if self.isInstalled(r): log.debug1("%s was already installed, replacing with %s", r.getNEVRA(), pkg.getNEVRA()) else: log.debug1("%s was already added, replacing with %s", r.getNEVRA(), pkg.getNEVRA()) if self._pkgUpdate(pkg, r) != self.OK: # Currently can't fail del self.pkg_updates return self.UPDATE_FAILED del self.pkg_updates # handle obsoletes for r in self.pkg_obsoletes: # package is not the same and has not the same name if self.isInstalled(r): fmt = "%s obsoletes installed %s, removing %s" else: fmt = "%s obsoletes added %s, removing %s" log.debug1(fmt, pkg.getNEVRA(), r.getNEVRA(), r.getNEVRA()) if self._pkgObsolete(pkg, r) != self.OK: del self.pkg_obsoletes return self.OBSOLETE_FAILED del self.pkg_obsoletes return self.OK
def update(self, pkg): name = pkg["name"] # get obsoletes # Valid only during OP_UPDATE: list of RpmPackage's that will be # obsoleted by the current update self.pkg_obsoletes = set() for u in pkg["obsoletes"]: s = self.database.searchDependency(u[0], u[1], u[2]) for r in s: if r["name"] != pkg["name"]: self.pkg_obsoletes.add(r) # update package # Valid only during OP_UPDATE: list of RpmPackage's that will be # removed by the current update self.pkg_updates = [] for r in self.database.getPkgsByName(name): ret = pkgCompare(r, pkg) if ret > 0: # old_ver > new_ver if self.config.oldpackage == 0: if self.isInstalled(r): msg = "%s: A newer package is already installed" else: msg = "%s: A newer package was already added" log.debug1(msg, pkg.getNEVRA()) del self.pkg_updates return self.OLD_PACKAGE else: # old package: simulate a new package ret = -1 if ret < 0: # old_ver < new_ver if self.config.exactarch == 1 and \ self.__arch_incompat(pkg, r): del self.pkg_updates return self.ARCH_INCOMPAT if archDuplicate(pkg["arch"], r["arch"]) or \ pkg["arch"] == "noarch" or r["arch"] == "noarch": self.pkg_updates.append(r) else: # ret == 0, old_ver == new_ver if self.config.exactarch == 1 and \ self.__arch_incompat(pkg, r): del self.pkg_updates return self.ARCH_INCOMPAT ret = self.__install_check(r, pkg) # Fails for same NEVRAs if ret != self.OK: del self.pkg_updates return ret if archDuplicate(pkg["arch"], r["arch"]): if archCompat(pkg["arch"], r["arch"]): if self.isInstalled(r): msg = "%s: Ignoring due to installed %s" ret = self.ALREADY_INSTALLED else: msg = "%s: Ignoring due to already added %s" ret = self.ALREADY_ADDED log.debug1(msg, pkg.getNEVRA(), r.getNEVRA()) del self.pkg_updates return ret else: self.pkg_updates.append(r) ret = self.install(pkg, operation=OP_UPDATE) if ret != self.OK: del self.pkg_updates return ret for r in self.pkg_updates: if self.isInstalled(r): log.debug1("%s was already installed, replacing with %s", r.getNEVRA(), pkg.getNEVRA()) else: log.debug1("%s was already added, replacing with %s", r.getNEVRA(), pkg.getNEVRA()) if self._pkgUpdate(pkg, r) != self.OK: # Currently can't fail del self.pkg_updates return self.UPDATE_FAILED del self.pkg_updates # handle obsoletes for r in self.pkg_obsoletes: # package is not the same and has not the same name if self.isInstalled(r): fmt = "%s obsoletes installed %s, removing %s" else: fmt = "%s obsoletes added %s, removing %s" log.debug1(fmt, pkg.getNEVRA(), r.getNEVRA(), r.getNEVRA()) if self._pkgObsolete(pkg, r) != self.OK: del self.pkg_obsoletes return self.OBSOLETE_FAILED del self.pkg_obsoletes return self.OK