Bug 620578

Summary: Satellite 5.3: RHN API call errata.publish pushes all packages in errata into target channel regardless of RHEL release (e.g., RHEL 5 pkgs into RHEL 4 channel)
Product: Red Hat Satellite 5 Reporter: Xixi <xdmoon>
Component: APIAssignee: Tomas Lestach <tlestach>
Status: CLOSED ERRATA QA Contact: Garik Khachikyan <gkhachik>
Severity: high Docs Contact:
Priority: high    
Version: 530CC: ahumbe, brsmith, cperry, gkhachik, jwest, mkoci, tao, xdmoon
Target Milestone: ---Keywords: Reopened
Target Release: ---   
Hardware: All   
OS: Linux   
Whiteboard:
Fixed In Version: Doc Type: Bug Fix
Doc Text:
This update introduces a new API call, errata.publishAsOriginal(), that ensures only the packages that are present in the original channel are published in its clone.
Story Points: ---
Clone Of: Environment:
Last Closed: 2010-12-16 15:44:38 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:
Bug Depends On:    
Bug Blocks: 646488    

Description Xixi 2010-08-02 21:50:09 UTC
Description of problem:
When customer clones errata and publishes it using errata.publish RHN API call on satellite 5.3 then wrong packages get added in channel. For example, if they clone errata applicable to multiple RHEL releases (e.g., RHEL 4 & RHEL 5) then publishing it using the API errata.publish and specifying a RHEL 4 target channel, RHEL 5 packages also get added into the RHEL 4 channel.

Version-Release number of selected component (if applicable):
Red Hat Network (RHN) Satellite 5.3.0

How reproducible:
Always.

Steps to Reproduce:
1. Clone "Red Hat Enterprise Linux AS (v. 4 for 32-bit x86)" as "test-clone-rhel-i386-as-4" channel, original state.
2. Go to Errata -> Clone Errata, and choose the above cloned channel in drop-down list and click "View".
3. Clone an errata that applies to both RHEL 4 and 5 such as "RHSA-2010:0534 Important: libpng security update" which applies to RHEL 4 and 5 custom/cloned channels like below:
Security Advisory   RHSA-2010:0534    Important: libpng security update   2010-07-14   Clone 2 of Red Hat Enterprise Linux (v. 5 for 32-bit x86)
Clone of Red Hat Enterprise Linux (v. 5 for 32-bit x86)
Clone of Red Hat Enterprise Linux (v. 5 for 64-bit x86_64)
Clone of Red Hat Enterprise Linux AS (v. 4 for 32-bit x86)
4. Use API call errata.publish to publish the cloned errata, e.g., "print server.errata.publish(session, 'CLA-2010:0534', ['test-clone-rhel-i386-as-4'])"
Results:
[]$ ./publishErrata.py
{'date': '7/14/10', 'advisory_name': 'CLA-2010:0534', 'advisory_type': 'Security Advisory', 'id': 26355, 'advisory_synopsis': 'Important: libpng security update'}
5. Search for one of the RHEL 5 pkgs in the errata such as "libpng-1.2.10-7.1.el5_5.3:2.i386".

Actual results:
RHEL 5 pkgs in the errata are also pushed to the target "test-clone-rhel-i386-as-4" channel which is RHEL 4.

Expected results:
Only pkgs applicable to the target channel should be pushed.

Additional info:

Comment 1 Xixi 2010-08-02 21:57:44 UTC
Unfortunately, per jsherrill in Satellite Engineering, this may be a tricky one to fix - it basically comes down to there's no guaranteed way to map a package to a RHEL release.  If the target is a cloned channel *and* the the errata is also in the original then the mapping can be done using the original channel and the packages that are in the original channel and the errata, otherwise there's no way to know.  What's the right thing to do in that case: error out? require manual user intervention?

Relevant code snippets:

spacewalk-java-0.5.44/code/src/com/redhat/rhn/frontend/xmlrpc/errata/ErrataHandler.java
...
   1076     public Errata publish(String sessionKey, String advisory, List channelLabels)
   1077                                                      throws InvalidChannelRoleException {
   1078         User loggedInUser = getLoggedInUser(sessionKey);
   1079         List channels = verifyChannelList(channelLabels, loggedInUser);
   1080         Errata toPublish = lookupErrata(advisory, loggedInUser.getOrg());
   1081         return publish(toPublish, channels, loggedInUser);
   1082     }
...
   1119     private Errata publish(Errata errata, List<Channel> channels, User user) {
   1120         Errata published = ErrataFactory.publish(errata);
   1121         for (Channel chan : channels) {
   1122             published = ErrataFactory.publishToChannel(published, chan, user);
   1123         }
   1124         return published;
   1125     }
...

spacewalk-java-0.5.44/code/src/com/redhat/rhn/domain/errata/ErrataFactory.java
...
    190     public static Errata publish(Errata unpublished) {
    191         //Make sure the errata we're publishing is unpublished
    192         if (unpublished.isPublished()) {
    193             return unpublished; //there is nothing we can do here
    194         }
    195         //Create a published errata using unpublished
    196
    197         Errata published;
    198
    199         if (unpublished.isCloned()) {
    200             published = new PublishedClonedErrata();
    201             ((PublishedClonedErrata)published).setOriginal(
    202                                   ((UnpublishedClonedErrata)unpublished).getOriginal());
    203         }
    204         else {
    205             published = ErrataFactory.createPublishedErrata();
    206         }
    207
    208         copyDetails(published, unpublished, false);
    209
    210         //Save the published Errata
    211         save(published);
    212
    213         //Remove the unpublished Errata from db
    214         try {
    215             Session session = HibernateFactory.getSession();
    216             session.delete(unpublished);
    217         }
    218         catch (HibernateException e) {
    219             throw new HibernateRuntimeException(
    220                           "Errors occurred while publishing errata", e);
    221         }
    222
    223         //return the published errata
    224         return published;
    225     }
    226
    227
    228     /**
    229      * Takes a published or unpublished errata and publishes to a channel, creating
    230      *      all of the correct ErrataFile* entries.  This method does push packages to
    231      *      the appropriate channel. (Appropriate as defined as the channel previously
    232      *      having a package with the same name).
    233      * @param errata errata to publish
    234      * @param chan channel to publish it into.
    235      * @param user the user doing the pushing
    236      * @return the publsihed errata
    237      */
    238     public static Errata publishToChannel(Errata errata, Channel chan, User user) {
    239         if (!errata.isPublished()) {
    240            errata = publish(errata);
    241         }
    242         errata.addChannel(chan);
    243
    244         Set<Package> packagesToPush = new HashSet<Package>();
    245         DataResult<PackageOverview> packs =
    246             ErrataManager.lookupPacksFromErrataForChannel(chan, errata, user);
    247         for (PackageOverview packOver : packs) {
    248             //lookup the Package object
    249             Package pack = PackageFactory.lookupByIdAndUser(
    250                     packOver.getId().longValue(), user);
    251             packagesToPush.add(pack);
    252         }
    253         return publishErrataPackagesToChannel(errata, chan, user, packagesToPush);
    254     }
...

spacewalk-java-0.5.44/code/src/com/redhat/rhn/manager/errata/ErrataManager.java
...
   /**
    * Finds the packages contained in an errata that apply to a channel
    * @param customChan the channel to look in
    * @param errata the errata to look for packs with
    * @param user the user doing the request.
    * @return collection of PackageOverview objects
    */
   public static DataResult<PackageOverview> lookupPacksFromErrataForChannel(
               Channel customChan, Errata errata, User user) {
       Map params = new HashMap();
       //params.put("uid", user.getId());
       params.put("eid" , errata.getId());
       params.put("org_id" , user.getOrg().getId());
       params.put("custom_cid", customChan.getId());
       SelectMode m = ModeFactory.getMode(
               "Errata_queries",  "find_packages_for_errata_and_channel");
       return m.execute(params);

   }
...

spacewalk-java-0.5.44/code/src/com/redhat/rhn/common/db/datasource/xml/Errata_queries.xml
...
    646 <mode name="find_packages_for_errata_and_channel" class="com.redhat.rhn.frontend.dto.PackageOverview">
    647   <query params="custom_cid, eid, org_id">
    648         select distinct P.id, PN.name package_name, PA.label as package_arch,
    649                 EVR.version
    650        || '-' || EVR.release || (CASE WHEN EVR.epoch IS NULL THEN '' ELSE ':' || EVR.epoch END)
    651          package_nvre
    652     from
    653         rhnErrata E inner join
    654         rhnErrataPackage EP on E.id = EP.errata_id inner join
    655         rhnPackage P on P.id = EP.package_id inner join
    656         rhnPackageArch PA on PA.id = P.package_arch_id inner join
    657         rhnPackageEvr EVR on Evr.id = P.evr_id inner join
    658     rhnPackage P2 on P2.name_id = P.name_id inner join
    659     rhnChannelPackage CP on CP.package_id = P2.id
    660     inner join rhnPackageName PN on  PN.id = P.name_id
    661     inner join rhnChannel CN on CP.channel_id = CN.id
    662     where E.id = :eid
    663          and CP.channel_id = :custom_cid
    664          and P2.Package_arch_id = P.package_arch_id
    665          and CN.org_id = :org_id and
    666          (E.org_id is NULL or E.org_id = :org_id)
    667   </query>
    668 </mode>
...

Comment 2 Tomas Lestach 2010-09-09 12:34:10 UTC
That's correct. There's not a clear way how to do it.
A general custom erratum doesn't contain the information what packages shall land in what channels.

Suggested way is to use channel.software.mergeErrata API call for merging errata and channel.software.mergePackages API for merging selected packages.

Comment 3 Tomas Lestach 2010-09-09 12:40:36 UTC
Closing as WONTFIX. Explanation in Comment#2.

Comment 5 Xixi 2010-11-12 03:48:22 UTC
(In reply to comment #2)
> That's correct. There's not a clear way how to do it.
> A general custom erratum doesn't contain the information what packages shall
> land in what channels.
> 
> Suggested way is to use channel.software.mergeErrata API call for merging
> errata and channel.software.mergePackages API for merging selected packages.

Hi, re-opening bug since above API calls don't meet customer needs - "mergeErrata operates on all errata within a channel, optionally constrained by a date range. mergePackages operates on all packages within a channel. These are too general for our needs. Often we will want to clone/publish only a single erratum, and only merge the packages included in said erratum." ...which is a valid and common use case so this bug still needs to be addressed.

So, what can we do to either fix or workaround this?  Maybe add user intervention so they can optionally remove packages from being published into the channel, if there's no way to do this programmatically (which seems to be the case unless we can play a "guessing" game)?  There're probably better ways...

Comment 12 Tomas Lestach 2010-12-06 12:49:13 UTC
Sorry for a wrong api call stated in my previous commit. Correct name is:
errata.publishAsOriginal

one more commit (exception handling optimizing):

spacewalk.git: 8e934d115ecaba0cca04840fbe6c5755bdd6f361

Comment 19 Garik Khachikyan 2010-12-07 15:05:32 UTC
# VERIFIED

The following package(s) fixing the issue:
spacewalk-java-config-1.2.39-33.el5sat.noarch.rpm			
spacewalk-java-oracle-1.2.39-33.el5sat.noarch.rpm			
spacewalk-java-lib-1.2.39-33.el5sat.noarch.rpm			
spacewalk-taskomatic-1.2.39-33.el5sat.noarch.rpm			
spacewalk-java-1.2.39-33.el5sat.noarch.rpm

print server.errata.publish(token,'CLA-2010:10268',['tbr-rhel-i386-as-4'] python code just produces additionally 4 new packages and none of *.el5 stuff as before.

Comment 21 errata-xmlrpc 2010-12-16 15:44:38 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/RHBA-2010-0991.html

Comment 22 Jaromir Hradilek 2010-12-16 16:32:50 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:
This update introduces a new API call, errata.publishAsOriginal(), that ensures only the packages that are present in the original channel are published in its clone.