Bug 469088 - exceptions.IndexError in yum/__init__.py, line 2649, in update
Summary: exceptions.IndexError in yum/__init__.py, line 2649, in update
Keywords:
Status: CLOSED INSUFFICIENT_DATA
Alias: None
Product: Fedora
Classification: Fedora
Component: PackageKit
Version: 10
Hardware: All
OS: Linux
medium
medium
Target Milestone: ---
Assignee: Richard Hughes
QA Contact: Fedora Extras Quality Assurance
URL:
Whiteboard:
Depends On:
Blocks:
TreeView+ depends on / blocked
 
Reported: 2008-10-29 20:25 UTC by Matěj Cepl
Modified: 2018-04-11 09:54 UTC (History)
12 users (show)

Fixed In Version:
Clone Of:
Environment:
Last Closed: 2009-01-14 14:43:34 UTC
Type: ---
Embargoed:


Attachments (Terms of Use)

Description Matěj Cepl 2008-10-29 20:25:11 UTC
Description of problem:
Error Type: <type 'exceptions.IndexError'>
Error Value: list index out of range
  File : /usr/share/PackageKit/helpers/yum/yumBackend.py, line 2200, in <module>
    main()
  File : /usr/share/PackageKit/helpers/yum/yumBackend.py, line 2197, in main
    backend.dispatcher(sys.argv[1:])
  File : /usr/lib/python2.5/site-packages/packagekit/backend.py, line 610, in dispatcher
    self.dispatch_command(args[0], args[1:])
  File : /usr/lib/python2.5/site-packages/packagekit/backend.py, line 574, in dispatch_command
    self.update_packages(packages)
  File : /usr/share/PackageKit/helpers/yum/yumBackend.py, line 1434, in update_packages
    txmbr = self.yumbase.update(po=pkg)
  File : /usr/lib/python2.5/site-packages/yum/__init__.py, line 2649, in update
    updated_pkg =  self.rpmdb.searchPkgTuple(updated)[0]

Version-Release number of selected component (if applicable):
PackageKit-0.3.9-1.fc10.i386

How reproducible:
happened once

Steps to Reproduce:
1.run gpk-update-viewer
2.initiate doing upgrade
3.
  
Actual results:
see above

Expected results:
upgraded computer

Additional info:

Comment 1 James Antill 2008-10-30 13:48:27 UTC
 This is a PackageKit bug, from the above:

 File : /usr/share/PackageKit/helpers/yum/yumBackend.py, line 1434, in
update_packages
    txmbr = self.yumbase.update(po=pkg)

...the lines leading upto this are:

                pkg, inst = self._findPackage(package)
                if pkg:
                    txmbr = self.yumbase.update(po=pkg)

...here inst means "this package is installed" ... and you aren't checking it so you can be passing available packages to the update() method and then, yeh, update() kind of assumes the po is installed if you pass a po.

Comment 2 Tim Lauridsen 2008-10-31 06:13:36 UTC
the original code i did was:

        pkg,inst = self._findPackage(package)
        if pkg:
            txmbr = self.yumbase.update(name=pkg.name)

Then YumBase.update will do the right thing

Comment 3 Tim Lauridsen 2008-10-31 06:21:31 UTC
it was broken in 
9e2e8562f85f8234567dc6c6a1226e2e4e41a5ac

diff --git a/backends/yum/helpers/yumBackend.py b/backends/yum/helpers/yumBackend.py
index d70d8dc..bdd70e5 100644
--- a/backends/yum/helpers/yumBackend.py
+++ b/backends/yum/helpers/yumBackend.py
@@ -675,7 +675,7 @@ class PackageKitYumBackend(PackageKitBaseBackend):
         # FIXME: This is a hack, it simulates a removal of the
         # package and return the transaction
         if inst and pkg:
-            txmbrs = self.yumbase.remove(name=pkg.name)
+            txmbrs = self.yumbase.remove(po=pkg)
             if txmbrs:
                 rc,msgs =  self.yumbase.buildTransaction()
                 if rc !=2:
@@ -903,7 +903,7 @@ class PackageKitYumBackend(PackageKitBaseBackend):
                 if not already_warned and not repo.gpgcheck:
                     self.message(MESSAGE_WARNING,"The untrusted package %s will be installed from %s." % (pkg.name, repo))
                     already_warned = True
-                txmbr = self.yumbase.install(name=pkg.name)
+                txmbr = self.yumbase.install(po=pkg)
                 txmbrs.extend(txmbr)
             if inst:
                 self.error(ERROR_PACKAGE_ALREADY_INSTALLED,"The package %s is already installed", pkg.name)
@@ -1038,7 +1038,7 @@ class PackageKitYumBackend(PackageKitBaseBackend):
             for package in packages:
                 pkg,inst = self._findPackage(package)
                 if pkg:
-                    txmbr = self.yumbase.update(name=pkg.name)
+                    txmbr = self.yumbase.update(po=pkg)
                     txmbrs.extend(txmbr)
         except yum.Errors.RepoError,e:
             self.error(ERROR_REPO_NOT_AVAILABLE,str(e))
@@ -1135,7 +1135,7 @@ class PackageKitYumBackend(PackageKitBaseBackend):
         pkg,inst = self._findPackage(package)
         if pkg and inst:
             try:
-                txmbr = self.yumbase.remove(name=pkg.name)
+                txmbr = self.yumbase.remove(po=pkg)
             except yum.Errors.RepoError,e:
                 self.error(ERROR_REPO_NOT_AVAILABLE,str(e))

this was ok, in the YumBase.install and YumBase.remove, but not in YumBase.update

Comment 4 Richard Hughes 2008-10-31 09:37:19 UTC
Good find Tim. The reason I changed it from:

-                    txmbr = self.yumbase.update(name=pkg.name)
+                    txmbr = self.yumbase.update(po=pkg)

Is that we need to match on name and version, as we could have multiple versions of updates in a repo, and we need to choose the correct one, not just the latest.

What about something like this:

-                    txmbr = self.yumbase.update(po=pkg)
+                    txmbr = self.yumbase.update(name=pkg.name, epoch=pkg.epoch, version=pkg.version, release=pkg.release, arch=pkg.arch)

That would give us the exact matching and not the exact po match.

Comment 5 Tim Lauridsen 2008-10-31 13:18:18 UTC
This might do it, but i'm not sure

But after looking at the YumBase.update code, i can see it work, with both YumBase.update(po=avail_po) & YumBase.update(po=inst_po).

(YumBase.update)

        instpkgs = []
        availpkgs = []
        if po: # just a po
            if po.repoid == 'installed':
                instpkgs.append(po)
            else:
                availpkgs.append(po)

The part of the code there is failing, is the one there handles available packages.

        for available_pkg in availpkgs:
            for updated in self.up.updating_dict.get(available_pkg.pkgtup, []):
                if self.tsInfo.isObsoleted(updated):
                ..

                ..

                else:
                    updated_pkg =  self.rpmdb.searchPkgTuple(updated)[0]
  
The problem here is that self.rpmdb.searchPkgTuple(updated) returns []
i looks very weird, 
updated is the pkgtup for the package to be updated and the error indicates that that package dont exits in the rpmdb.
There must be some inconsistency somewhere, something is not in sync.

Comment 6 Richard Hughes 2008-11-06 10:57:41 UTC
Matej, can you reproduce this or was it a one-off?

Comment 7 Matěj Cepl 2008-11-06 16:25:24 UTC
Yeah, that was one-off and it probably relates to the general brokeness of rpm (I have to rm -f /var/lib/rpm/__db* all the time to make rpm work). Also, the problem is that PK when rpm is broken just sits there doing nothing (or what).

Comment 8 seth vidal 2008-11-06 19:31:02 UTC
you have to clean up your rpmdb all the time? Are you running a special kernel, bdb or glibc?

Comment 9 Matěj Cepl 2008-11-06 22:27:34 UTC
(In reply to comment #8)
> you have to clean up your rpmdb all the time? Are you running a special kernel,
> bdb or glibc?

On all my computers (all Rawhide, two i386 notebooks -- one mine, other my wife's, other is x86_64 destop at the office) quite often I get "Thread <uid> broken" or something like that, and the only medicine I found for it was

rm -f /var/lib/rpm/__db ; rpm --rebuilddb

And no, all of them have standard glibc, rpm, kernel from distribution and fully upgraded (i.e., I always run yum upgrade without any exclusion except for occassional exclusion of openoffice.org for saving the bandwidth).

Comment 10 Matěj Cepl 2008-11-06 22:28:21 UTC
of course, it should be

rm -f /var/lib/rpm/__db* ; rpm --rebuilddb

instead

Comment 11 Panu Matilainen 2008-11-07 06:45:44 UTC
This sounds to me like bug 468437... I suspect PackageKit might be going wild with threads, but librpm is not thread-safe, all access to rpmdb should happen in the same thread that opened the db.

Comment 12 Matěj Cepl 2008-11-07 09:14:12 UTC
(In reply to comment #11)
> This sounds to me like bug 468437... I suspect PackageKit might be going wild
> with threads, but librpm is not thread-safe, all access to rpmdb should happen
> in the same thread that opened the db.

yeah, that's it. Will provide backtrace, when it happens again.

Comment 13 Richard Hughes 2008-11-07 09:29:36 UTC
PackageKit spawns a new process to talk to yum using stdin and stdout as IPC. It does not use threads at all when using a spawned backend like yum.

Comment 14 Bug Zapper 2008-11-26 04:27:42 UTC
This bug appears to have been reported against 'rawhide' during the Fedora 10 development cycle.
Changing version to '10'.

More information and reason for this action is here:
http://fedoraproject.org/wiki/BugZappers/HouseKeeping

Comment 15 Richard Hughes 2009-01-14 13:38:37 UTC
Matej, do you still get this problem?

Comment 16 Matěj Cepl 2009-01-14 14:43:34 UTC
I don't have PackageKit on F10 anymore (doesn't work and shouldn't work with staff_u SELinux user). Closing as INSUFFICIENT_DATA.


Note You need to log in before you can comment on or make changes to this bug.