Hi!
Depsolve.processConflict() has been on the "Needs to be revisited" list for
quite some time. The attached patch offers a simple but powerful
implementation by invoking self.update. This code passes the few conflict
test cases we have including the one that are failing right now. It tries to
update both of the involved pkgs and tries to be smart which one to try first.
While I think that implementation of processConflict is quite good I am a
bit unsure if YumBase.update is capable of handling all situations that we
are handing over. I guess we need to make .update handling more situations
properly - especially updates to non newest versions.
Comments anyone?
Florian
diff --git a/yum/depsolve.py b/yum/depsolve.py
index cde96f1..4bca606 100644
--- a/yum/depsolve.py
+++ b/yum/depsolve.py
@@ -568,13 +568,12 @@ class Depsolve(object):
return checkdeps, missingdep
- def _processConflict(self, po, conflict):
+ def _processConflict(self, po, conflict, conflicting_po):
"""processes a Conflict dep from the resolveDeps() method"""
-
- CheckDeps = 0
- conflicts = 0
+
+ CheckDeps = True
errormsgs = []
-
+
needname, flags, needversion = conflict
(name, arch, epoch, ver, rel) = po.pkgtup
@@ -582,71 +581,23 @@ class Depsolve(object):
niceformatneed = rpmUtils.miscutils.formatRequire(needname, needversion, flags)
if self.dsCallback: self.dsCallback.procConflict(name, niceformatneed)
- # we should try to update out of the dep, if possible
- # see which side of the conflict is installed and which is in the transaction Set
- needmode = self.tsInfo.getMode(name=needname)
- confmode = self.tsInfo.getMode(name=name, ver=ver, rel=rel)
- if confmode is None:
- confname = name
- elif needmode is None:
- confname = needname
- else:
- confname = name
-
- po = None
-
- uplist = self.up.getUpdatesList(name=confname)
-
- conflict_packages = self.rpmdb.searchNevra(name=confname)
- if conflict_packages:
- confpkg = conflict_packages[0] # take the first one, probably the only one
-
-
- # if there's an update for the reqpkg, then update it
- if len(uplist) > 0:
- if confpkg.name not in self.conf.exactarchlist:
- try:
- pkgs = self.pkgSack.returnNewestByName(confpkg.name)
- except Errors.PackageSackError:
- self.verbose_logger.log(logginglevels.DEBUG_4, "unable to find newer package for %s" %(confpkg.name,))
- pkgs = []
- archs = {}
- for pkg in pkgs:
- (n,a,e,v,r) = pkg.pkgtup
- archs[a] = pkg
- a = rpmUtils.arch.getBestArchFromList(archs.keys())
- po = archs[a]
- else:
- try:
- po = self.pkgSack.returnNewestByNameArch((confpkg.name,confpkg.arch))[0]
- except Errors.PackageSackError:
- self.verbose_logger.log(logginglevels.DEBUG_4, "unable to find newer package for %s.%s" %(confpkg.name,confpkg.arch))
- po = None
- if po and po.pkgtup not in uplist:
- po = None
+ if flags & rpm.RPMSENSE_LESS:
+ if self.update(name=conflicting_po.name):
+ return CheckDeps, errormsgs
+ elif flags & rpm.RPMSENSE_GREATER:
+ if self.update(name=name):
+ return CheckDeps, errormsgs
- if po:
- self.verbose_logger.log(logginglevels.DEBUG_2,
- 'TSINFO: Updating %s to resolve conflict.', po)
- txmbr = self.tsInfo.addUpdate(po, confpkg)
- txmbr.setAsDep()
- txmbr.reason = "dep"
- CheckDeps = 1
-
- else:
- conf = rpmUtils.miscutils.formatRequire(needname, needversion, flags)
- CheckDeps, conflicts = self._unresolveableConflict(conf, name, errormsgs)
- self.verbose_logger.log(logginglevels.DEBUG_1, '%s conflicts: %s',
- name, conf)
-
- return (CheckDeps, conflicts, errormsgs)
+ if self.update(name=conflicting_po.name):
+ return CheckDeps, errormsgs
+ if self.update(name=name):
+ return CheckDeps, errormsgs
- def _unresolveableConflict(self, conf, name, errors):
- CheckDeps = 0
- conflicts = 1
msg = '%s conflicts with %s' % (name, conf)
- errors.append(msg)
- return CheckDeps, conflicts
+ errormsgs.append(msg)
+ self.verbose_logger.log(logginglevels.DEBUG_1, msg)
+ CheckDeps = False
+ return CheckDeps, errormsgs
def _undoDepInstalls(self):
# clean up after ourselves in the case of failures
@@ -731,7 +682,7 @@ class Depsolve(object):
if CheckInstalls:
CheckInstalls = False
for conflict in self._checkConflicts():
- (checkdep, conflict, errormsgs) = self._processConflict(*conflict)
+ (checkdep, errormsgs) = self._processConflict(*conflict)
CheckDeps |= checkdep
errors += errormsgs
@@ -937,7 +888,7 @@ class Depsolve(object):
for conflicting_po in self.tsInfo.getNewProvides(r, f, v):
if conflicting_po.pkgtup[0] == po.pkgtup[0] and conflicting_po.pkgtup[2:] == po.pkgtup[2:]:
continue
- ret.append( (po, (r, flags[f], version_tuple_to_string(v))) )
+ ret.append( (po, (r, flags[f], version_tuple_to_string(v)), conflicting_po) )
for txmbr in self.tsInfo.getMembersWithState(output_states=TS_INSTALL_STATES):
po = txmbr.po
for conflict in txmbr.po.returnPrco('conflicts'):
@@ -945,7 +896,7 @@ class Depsolve(object):
for conflicting_po in self.tsInfo.getProvides(r, f, v):
if conflicting_po.pkgtup[0] == po.pkgtup[0] and conflicting_po.pkgtup[2:] == po.pkgtup[2:]:
continue
- ret.append( (po, (r, flags[f], version_tuple_to_string(v))) )
+ ret.append( (po, (r, flags[f], version_tuple_to_string(v)), conflicting_po) )
return ret
_______________________________________________
Yum-devel mailing list
[email protected]
https://lists.dulug.duke.edu/mailman/listinfo/yum-devel