[Yum-devel] [PATCH] Fix _remove_old_deps to deal with chains of revdeps.
Casey Jao
cjao at ugcs.caltech.edu
Fri Apr 8 16:35:55 UTC 2011
Hi,
I've done some minimal testing in a FC14 virtual machine. I installed
emacs, texworks, and google-chrome-stable. Emacs and
google-chrome-stable pulled in some common dependencies, like perl. Then
I did yum remove X where X varied over all subsets of {emacs, texworks,
google-chrome-stable}. In each case yum appeared to correctly resolve
which packages to remove.
What is the preferred method for debug loggin?
Casey
On 04/08/2011 08:56 AM, seth vidal wrote:
> On Fri, 2011-04-08 at 08:44 -0700, Casey Jao wrote:
>> ---
>> yum/__init__.py | 69
>> +++++++++++++++++++++++++++++++++++++++++++++++++++----
>> 1 files changed, 64 insertions(+), 5 deletions(-)
>>
>> diff --git a/yum/__init__.py b/yum/__init__.py
>> index cf4d827..bbb5204 100644
>> --- a/yum/__init__.py
>> +++ b/yum/__init__.py
>> @@ -5276,6 +5276,11 @@ class YumBase(depsolve.Depsolve):
>> found_leaves = set()
>> checked = set()
>> beingremoved = [ t.po for t in
>> self.tsInfo.getMembersWithState(output_states=TS_REMOVE_STATES) ]
>> + # cache previously examined packages
>> + okay_to_remove = {}
>> + for i in self.rpmdb.returnPackages():
>> + okay_to_remove[i] = True
>> +
>> for pkg in beingremoved: # for each package required by the pkg
>> being removed
>> #print 'removal: %s' % pkg.name
>> for required in pkg.required_packages():
>> @@ -5283,23 +5288,29 @@ class YumBase(depsolve.Depsolve):
>> # continue # if we've already checked it, skip it.
>> #checked.add(required)
>> if required.yumdb_info.get('reason', '') != 'dep': # if
>> the required pkg is not a dep, then skip it
>> + okay_to_remove[required] = False
>> continue
>> if required in beingremoved:
>> continue
>> + if self._has_needed_revdeps(required, beingremoved,
>> okay_to_remove):
>> + continue
>> still_needed = False
>> for requiring in required.requiring_packages(): # so we
>> have required deps - look at all the pkgs which require them
>> if requiring == required: # if they are
>> self-requiring skip them
>> continue
>> - if requiring not in beingremoved: # if the
>> requiring pkg is not in the list of pkgs being removed then it is still
>> needed
>> - still_needed = True
>> - break
>> + #if requiring not in beingremoved: # if the
>> requiring pkg is not in the list of pkgs being removed then it is still
>> needed
>> + #still_needed = True
>> + #break
>> +
>> # go through the stuff in the ts to be installed - make
>> sure none of that needs the required pkg, either.
>> for (provn,provf,provevr) in required.provides:
>> if self.tsInfo.getNewRequires(provn, provf,
>> provevr).keys():
>> still_needed = True
>> + okay_to_remove[required] = False
>> break
>> for fn in required.filelist + required.dirlist:
>> if self.tsInfo.getNewRequires(fn,
>> None,(None,None,None)).keys():
>> + okay_to_remove[required] = False
>> still_needed = True
>> break
>>
>> @@ -5319,5 +5330,53 @@ class YumBase(depsolve.Depsolve):
>> beingremoved.append(txmbr.po)
>> found_leaves.add(txmbr)
>> self.verbose_logger.log(logginglevels.INFO_2, "Found and
>> removing %s unneeded dependencies" % len(found_leaves))
>> -
>> -
>> +
>> + # Checks if pkg has any reverse deps which cannot be removed.
>> + # Currently this only checks the install reason for each revdep,
>> + # but we may want to check for other reasons that would
>> + # prevent the revdep from being removed (e.g. protected)
>> + def _has_needed_revdeps(self, pkg, beingremoved, ok_to_remove):
>> + # check if we've already found this package to have
>> user-installed deps
>> + if not ok_to_remove[pkg]:
>> + # Debugging output
>> + #print pkg, "has been visited already and cannot be removed!!!"
>> + return True
>> + # Debugging output
>> + #print "Examining revdeps of", pkg
>> + # track which pkgs we have visited already
>> + visited = {}
>> + for po in self.rpmdb.returnPackages():
>> + visited[po] = False
>> + # no need to consider packages that are already being removed
>> + for po in beingremoved:
>> + visited[po] = True
>> + stack = []
>> + stack.append(pkg)
>> + # depth-first search
>> + while stack:
>> + curpkg = stack[-1]
>> + if not visited[curpkg]:
>> + if not ok_to_remove[curpkg]:
>> + # Debugging
>> + #print pkg, "has been visited already and cannot be
>> removed!!!"
>> + ok_to_remove[pkg] = False
>> + return True
>> + if curpkg.yumdb_info.get('reason', '') != 'dep':
>> + # Debugging output
>> + #print pkg, "has revdep", curpkg, "which was
>> user-installed."
>> + ok_to_remove[pkg] = False
>> + return True
>> + visited[curpkg] = True
>> + all_leaves_visited = True
>> + leaves = curpkg.requiring_packages()
>> + for leaf in leaves:
>> + if not visited[leaf]:
>> + stack.append(leaf)
>> + all_leaves_visited = False
>> + break
>> + if all_leaves_visited:
>> + stack.pop()
>> + # Debugging output
>> + #print pkg, "has no user-installed revdeps"
>> + return False
>> +
>> _______________________________________________
>> Yum-devel mailing list
>> Yum-devel at lists.baseurl.org
>> http://lists.baseurl.org/mailman/listinfo/yum-devel
>
>
> Casey,
> This looks pretty good. Can you clean up the debugging comments and
> maybe turn them into higher debug-level log calls? Also do you have any
> testcases to go along with this?
>
> Thanks,
> -sv
>
>
> _______________________________________________
> Yum-devel mailing list
> Yum-devel at lists.baseurl.org
> http://lists.baseurl.org/mailman/listinfo/yum-devel
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 553 bytes
Desc: OpenPGP digital signature
URL: <http://lists.baseurl.org/pipermail/yum-devel/attachments/20110408/04ff7892/attachment.asc>
More information about the Yum-devel
mailing list