Bug 603028

Summary: rhn_check does not update packages whose architecture was changed from noarch to multiarch and vice-versa
Product: Red Hat Enterprise Linux 5 Reporter: Martin Osvald 🛹 <mosvald>
Component: rhn-client-toolsAssignee: Jan Pazdziora <jpazdziora>
Status: CLOSED ERRATA QA Contact: Martin Minar <mminar>
Severity: medium Docs Contact:
Priority: high    
Version: 5.6CC: andrew.clements, cperry, jcavallaro, jhutar, jpazdziora, mkoci, mminar, mmraka, xdmoon
Target Milestone: ---   
Target Release: ---   
Hardware: All   
OS: Linux   
Whiteboard:
Fixed In Version: rhn-client-tools-0.4.20-40.el5 Doc Type: Bug Fix
Doc Text:
Due to an error in the architecture checking, the rhn_register utility failed to update packages when their architecture had changed from "noarch" to "multiarch" or vice versa. With this update, the underlying source code has been modified to target this issue, and such packages are now updated as expected.
Story Points: ---
Clone Of: Environment:
Last Closed: 2011-01-14 00:10:18 UTC Type: ---
Regression: --- Mount Type: ---
Documentation: --- CRM:
Verified Versions: Category: ---
oVirt Team: --- RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: --- Target Upstream Version:
Embargoed:
Attachments:
Description Flags
temporary patch which fixes the bug none

Description Martin Osvald 🛹 2010-06-11 10:40:09 UTC
Created attachment 423234 [details]
temporary patch which fixes the bug

Description of problem:

rhn_check fails to update packages whose architecture got changed not only from noarch to multiarch, but also from e.g. i386 to i686.


Version-Release number of selected component (if applicable):

Satellite 5.3
rhn-check-0.4.20-33.el5_5.1


How reproducible:

always


Steps to Reproduce:

I will use a package tzdata as example as its architecture was changed from noarch to multiarch.

1. Install RHEL5.4 or 5.5 (no matter which version, we are to downgrade the tzdata package anyway)

2. download the last version of tzdata released as noarch and install it:

 $ wget http://download.devel.redhat.com/brewroot//packages/tzdata/2010e/1.el5/noarch/tzdata-2010e-1.el5.noarch.rpm
 $ rpm --force -Uvh tzdata-2010e-1.el5.noarch.rpm
 $ rhn-profile-sync

3. Schedule the latest errata for tzdata through WebUI:

On main Satellite page click on: "Errata" -> fill in "Filter by Synopsis" a value 'tzdata' and click on "Go" -> click on the latest errata -> "Affected Systems" -> and choose the system we just installed the old tzdata on -> "Apply Errata" -> "Confirm"

4. Run rhn_check on the system:

 $ rhn_check -vv


Actual results:

rhn_check fails with error:

D: Sending back response (39, 'No packages from that errata are available', {'version': '0', 'name': 'errata.update.no_packages', 'erratas': [1767]})

$ rhn_check -vv
D: do_call packages.checkNeedUpdate ('rhnsd=1',)
Loaded plugins: rhnplugin
D: login(forceUpdate=False) invoked
D: readCachedLogin invoked
D: Checking pickled loginInfo, currentTime= 1276249794.23 , createTime= 1276249791.19 , expire-offset= 3600.0
D: readCachedLogin(): using pickled loginInfo set to expire at  1276253391.19
D: local action status:  (0, 'rpm database not modified since last update (or package list recently updated)', {})
[root@localhost ~]# rhn_check -vv
D: check_action {'action': "<?xml version='1.0'?>\n<methodCall>\n<methodName>errata.update</methodName>\n<params>\n<param>\n<value><array><data>\n<value><int>1767</int></value>\n</data></array></value>\n</param>\n</params>\n</methodCall>\n", 'version': 2, 'id': 711}
updateLoginInfo() login info
D: login(forceUpdate=True) invoked
logging into up2date server
D: writeCachedLogin() invoked
D: Wrote pickled loginInfo at  1276249803.04  with expiration of  1276253403.04  seconds.
successfully retrieved authentication token from up2date server
D: logininfo: {'X-RHN-Server-Id': 1000010301, 'X-RHN-Auth-Server-Time': '1276249805.02', 'X-RHN-Auth': 'BkygWDsUEm4B0Tpgb0Evrw==', 'X-RHN-Auth-Channels': [['rhel-i386-server-5', '20100531154406', '1', '1']], 'X-RHN-Auth-User-Id': '', 'X-RHN-Auth-Expire-Offset': '3600.0'}
D: handle_action {'action': "<?xml version='1.0'?>\n<methodCall>\n<methodName>errata.update</methodName>\n<params>\n<param>\n<value><array><data>\n<value><int>1767</int></value>\n</data></array></value>\n</param>\n</params>\n</methodCall>\n", 'version': 2, 'id': 711}
D: handle_action actionid = 711, version = 2
D: do_call errata.update ([1767],)
Loaded plugins: rhnplugin
D: Sending back response (39, 'No packages from that errata are available', {'version': '0', 'name': 'errata.update.no_packages', 'erratas': [1767]})
D: do_call packages.checkNeedUpdate ('rhnsd=1',)
D: local action status:  (0, 'rpm database not modified since last update (or package list recently updated)', {})
$


Expected results:

It should update the package without the error.


Additional info:

The bug is caused by the fact that rhn_check tries to match packages related to scheduled errata with list of installed packages with search keys constructed from [package name] + [package architecture] and doesn't check for situation in which the package to update could have different architecture.

Related source code (note '<<<---'):

RHEL-5/rhn-client-tools-svn-r191859/src/actions/errata.py:update():
=== <snip ===
def update(errataidlist):
   packagelist = []

   if type(errataidlist) not in [type([]), type(())]:
       errataidlist = [ errataidlist ]

   for errataid in errataidlist:
       tmpList = __getErrataInfo(errataid)
       packagelist = packagelist + tmpList

   current_packages_with_arch = {}
   current_packages ={}
   for p in rpmUtils.getInstalledPackageList(getArch=1):
       current_packages_with_arch[p['name']+p['arch']] = p
       current_packages[p['name']] = p

   u = {}
   # only update packages that are currently installed
   # since an "applicable errata" may only contain some packages
   # that actually apply. aka kernel. Fun fun fun. 

   if len(packagelist[0]) > 4:
       # Newer sats send down arch, filter using name+arch
       for p in packagelist:
           if current_packages_with_arch.has_key(p[0]+p[4]): <<<--- 1)
               u[p[0]+p[4]] = p
   else:
       # 5.2 and older sats + hosted dont send arch
       for p in packagelist:
           if current_packages.has_key(p[0]):
               u[p[0]] = p

   # XXX: Fix me - once we keep all errata packages around,
   # this is the WRONG thing to do - we want to keep the specific versions
   # that the user has asked for.
   packagelist = map(lambda a: u[a], u.keys())

   if packagelist == []:
       data = {}
       data['version'] = "0"
       data['name'] = "errata.update.no_packages"
       data['erratas'] = errataidlist

       return (39,
               "No packages from that errata are available",
               data)

   return packages.update(packagelist)
=== snip> ===

1) It fails to match situations where current_packages_with_arch could be matched with "tzdatai386" instead of "tzdatanoarch".

The callpath generated by `python /usr/lib/python2.4/trace.py --trace /usr/sbin/rhn_check` for RHEA-2010:0138 (success):
=== <snip> ===
...
errata.py(38):     for p in rpmUtils.getInstalledPackageList(getArch=1):
errata.py(39):         current_packages_with_arch[p[0]+p[4]] = p
errata.py(40):         current_packages[p[0]] = p
errata.py(38):     for p in rpmUtils.getInstalledPackageList(getArch=1):
errata.py(39):         current_packages_with_arch[p[0]+p[4]] = p
errata.py(40):         current_packages[p[0]] = p
errata.py(38):     for p in rpmUtils.getInstalledPackageList(getArch=1):
errata.py(42):     u = {}
errata.py(47):     if len(packagelist[0]) > 4:
errata.py(49):         for p in packagelist:
errata.py(50):      if current_packages_with_arch.has_key(p[0]+p[4]):
errata.py(51):          u[p[0]+p[4]] = p
errata.py(49):         for p in packagelist:
errata.py(62):     packagelist = map(lambda a: u[a], u.keys())
--- modulename: errata, funcname: <lambda>
errata.py(62):     packagelist = map(lambda a: u[a], u.keys())
errata.py(64):     if packagelist == []:
errata.py(74):     return packages.update(packagelist)
=== </snip> ===

and the callpath for RHEA-2010:0336 (failure):
=== <snip> ===
...
errata.py(38):     for p in rpmUtils.getInstalledPackageList(getArch=1):
errata.py(39):         current_packages_with_arch[p[0]+p[4]] = p
errata.py(40):         current_packages[p[0]] = p
errata.py(38):     for p in rpmUtils.getInstalledPackageList(getArch=1):
errata.py(39):         current_packages_with_arch[p[0]+p[4]] = p
errata.py(40):         current_packages[p[0]] = p
errata.py(38):     for p in rpmUtils.getInstalledPackageList(getArch=1):
errata.py(42):     u = {}
errata.py(47):     if len(packagelist[0]) > 4:
errata.py(49):         for p in packagelist:
errata.py(50):      if current_packages_with_arch.has_key(p[0]+p[4]):
errata.py(49):         for p in packagelist:
errata.py(50):      if current_packages_with_arch.has_key(p[0]+p[4]):
errata.py(49):         for p in packagelist:
errata.py(62):     packagelist = map(lambda a: u[a], u.keys())
errata.py(64):     if packagelist == []:
errata.py(65):  data = {}
errata.py(66):  data['version'] = "0"
errata.py(67):  data['name'] = "errata.update.no_packages"
errata.py(68):  data['erratas'] = errataidlist
errata.py(70):  return (39, 
rhn_check(271):         return retval
rhn_check(289):         return (status, message, data)
rhn_check(182):         log.log_debug("Sending back response", (status, message, data))
=== </snip> ===

Attached patch solves the bug.

Comment 1 Jan Pazdziora 2010-08-31 09:30:08 UTC
Taking for investigation.

Comment 2 Jan Pazdziora 2010-08-31 11:24:43 UTC
The proposed patch is:

--- rhn-client-tools-svn-r191859/src/actions/errata.py.archchange	2010-06-11 12:24:52.959592767 +0200
+++ rhn-client-tools-svn-r191859/src/actions/errata.py.archchange	2010-06-11 12:27:45.177819621 +0200
@@ -49,6 +49,8 @@ def update(errataidlist):
         for p in packagelist:
 	    if current_packages_with_arch.has_key(p[0]+p[4]):
 	        u[p[0]+p[4]] = p
+	    elif current_packages.has_key(p[0]):
+	        u[p[0]] = p
     else:
         # 5.2 and older sats + hosted dont send arch
         for p in packagelist:

However, that would effectively mean that we would ignore the arch values and revert the fix which was done for bug 476894.

Comment 3 Jan Pazdziora 2010-08-31 11:26:22 UTC
A more correct fix is:

--- /usr/share/rhn/actions/errata.py.orig	2010-04-29 12:10:32.000000000 +0200
+++ /usr/share/rhn/actions/errata.py	2010-08-31 13:25:18.000000000 +0200
@@ -49,6 +49,10 @@
         for p in packagelist:
 	    if current_packages_with_arch.has_key(p[0]+p[4]):
 	        u[p[0]+p[4]] = p
+	    elif current_packages_with_arch.has_key(p[0]+"noarch"):
+	        u[p[0]+p[4]] = p
+	    elif p[4] == "noarch" and current_packages.has_key(p[0]):
+	        u[p[0]] = p
     else:
         # 5.2 and older sats + hosted dont send arch
         for p in packagelist:

which allows transition from any arch to noarch and from noarch to any arch, while preventing for example i386 -> x86_64 change.

Comment 4 Jan Pazdziora 2010-08-31 11:44:57 UTC
Incidentally, it was the change for bug 476894 (released for RHEL 5.4) which introduced this issue by adding a check for architecture.

Note for QA: use Satellite 5.3+ to verify as that's the one which provides the arch data.

Comment 5 Jan Pazdziora 2010-08-31 11:58:28 UTC
Fix committed to Spacewalk master, 4da050d299f45cfdaaad643eff8be750eb9a8555.

Comment 6 Jan Pazdziora 2010-08-31 12:15:08 UTC
Sending        rhn-client-tools/src/actions/errata.py
Transmitting file data .
Committed revision 195655.

Comment 11 Jaromir Hradilek 2010-11-30 12:33:19 UTC
    Technical note added. If any revisions are required, please edit the "Technical Notes" field
    accordingly. All revisions will be proofread by the Engineering Content Services team.
    
    New Contents:
Due to an error in the architecture checking, the rhn_register utility failed to update packages when their architecture had changed from "noarch" to "multiarch" or vice versa. With this update, the underlying source code has been modified to target this issue, and such packages are now updated as expected.

Comment 13 errata-xmlrpc 2011-01-14 00:10:18 UTC
An advisory has been issued which should help the problem
described in this bug report. This report is therefore being
closed with a resolution of ERRATA. For more information
on therefore solution and/or where to find the updated files,
please follow the link below. You may reopen this bug report
if the solution does not work for you.

http://rhn.redhat.com/errata/RHEA-2011-0112.html