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:
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> ...
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.
Closing as WONTFIX. Explanation in Comment#2.
(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...
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
# 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.
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
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.