Bug 966668

Summary: CartridgeCache#find_all_cartridges can return duplicate matches for non-Red Hat carts
Product: OpenShift Online Reporter: Miciah Dashiel Butler Masters <mmasters>
Component: PodAssignee: Rajat Chopra <rchopra>
Status: CLOSED CURRENTRELEASE QA Contact: libra bugs <libra-bugs>
Severity: high Docs Contact:
Priority: unspecified    
Version: 2.xCC: agoldste, qgong, rchopra, xtian
Target Milestone: ---   
Target Release: ---   
Hardware: Unspecified   
OS: Unspecified   
Whiteboard:
Fixed In Version: Doc Type: Bug Fix
Doc Text:
Story Points: ---
Clone Of: Environment:
Last Closed: 2013-06-11 04:09:45 UTC Type: Bug
Regression: --- Mount Type: ---
Documentation: --- CRM:
Verified Versions: Category: ---
oVirt Team: --- RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: --- Target Upstream Version:
Embargoed:

Description Miciah Dashiel Butler Masters 2013-05-23 16:01:59 UTC
Description of problem:

When a refactoring introduced find_all_cartridges in commit <https://github.com/openshift/origin-server/commit/50a1c23399a821c45f8f0b5a0c5a567bf32907e2>, the refactoring included the introduction of a subtle bug.  At <https://github.com/openshift/origin-server/commit/50a1c23399a821c45f8f0b5a0c5a567bf32907e2#L3R108>, we have the following code:

+      matching_carts << cart if cart.name == requested_feature
+      matching_carts << cart if (cart.features.include?(feature) and 
+                                (vendor.nil? or cart.cartridge_vendor == vendor) and 
+                                (version.nil? or cart.version.to_s == version.to_s)) 

If a cartridge matches both on name as well as on features, vendor, and version, the cartridge is returned twice.  This problem can be seen with the cartridges Red Hat ships if one uses the REST API.  For example, the resource http://127.0.0.1:8080/broker/rest/cartridges/jbossews-1.0 shows the same cartridge twice.

If one uses the rhc client tool to create an app, the cartridge is looked up using CartridgeCache#find_cartridge, which in turn calls find_all_cartridges.  We don't normally hit the bug with rhc because find_cartridge has the following code at <https://github.com/openshift/origin-server/commit/7210b89573448a71ae882b9d82664cff1d764d22#L3R100>:

+    #if any is by redhat return that one
+    cart = matching_carts.find { |c| c.cartridge_vendor == "redhat"}
+    return cart if cart 

This preferential treatment for Red Hat's cartridges means that even if Red Hat's jbossews-1.0 cartridge is returned twice by find_all_cartridges, find_cartridge still returns only one match.  Custom cartridges, where the Vendor: is not "redhat," will be out of luck.  For example, if we change the Vendor: for the shipped jbossews-1.0 cartridge to something other than Red Hat, rhc will return an error message.

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

How reproducible:
Entirely.

Steps to Reproduce:

1. The bug can be reproduced using the REST API:

 [root@broker ~]# curl -s http://127.0.0.1:8080/broker/rest/cartridges/jbossews-1.0 |python -mjson.tool |grep '"name": "jbossews-1.0",' |wc -l
 2

2. The bug can be reproduced using rhc if one tries to use a cartridge with a Vendor: that is not "redhat."  For example,

 [root@node01 ~]# ed /usr/libexec/openshift/cartridges/jbossews-1.0/info/manifest.yml
 2727
 /Vendor:
 Cartridge-Vendor: redhat
 s/redhat/deadrat
 Cartridge-Vendor: deadrat
 wq
 2728
 [root@node01 ~]# /etc/cron.minutely/openshift-facts
 [root@broker ~]# oo-admin-broker-cache -c --console
 [...]
 [root@broker ~]# rhc app create testapp jbossews-1.0 -p changeme --no-git
 [...]
 Creating application 'testapp' ... More that one cartridge was found matching jbossews-1.0.  Please select one of ["deadrat-jbossews-1.0-1.0", "deadrat-jbossews-1.0-1.0"]


Actual results:

The REST API returns 2 matches.

rhc fails on cartridges with Vendor: that is not "redhat."

Expected results:

The REST API should return 1 match.

rhc should succeed.

Additional info:

Comment 1 Miciah Dashiel Butler Masters 2013-05-23 17:39:06 UTC
Suggested fix: https://github.com/openshift/origin-server/pull/2616

Comment 3 Rajat Chopra 2013-05-25 19:01:25 UTC
fixed with rev#0188dd7a4cdbe6d837d174074789ebf11fa2c37c in origin-server.repo!

Comment 4 Xiaoli Tian 2013-05-27 09:45:14 UTC
Verified it on devenv_3277:

1. Modify jbossews cartridge vendor to nonredhat to simulate this situation:

Update /var/lib/openshift/.cartridge_repository/redhat-jbossews/0.0.1/metadata/manifest.yml

2. [root@ metadata]# oo-admin-broker-cache --clear --console
Clearing broker cache.
Clearing console cache.

3. Try to find the original cartridge:

[root@ metadata]#  curl -s http://127.0.0.1:8080/broker/rest/cartridges/jbossews-1.0 |python -mjson.tool |grep '"name": "jbossews-1.0",' |wc -l
0
[root@ip-10-152-178-106 metadata]#  curl -s http://127.0.0.1:8080/broker/rest/cartridges/jbossews-2.0 |python -mjson.tool |grep '"name": "jbossews-2.0",' |wc -l
0

4. Try to list the cartridge with vendor name:
[root@ip-10-152-178-106 ~]#  curl -s http://127.0.0.1:8080/broker/rest/cartridges |python -mjson.tool |grep '"name": "nonredhat-jbossews-2.0"' |wc -l
1
[root@ip-10-152-178-106 ~]#  curl -s http://127.0.0.1:8080/broker/rest/cartridges |python -mjson.tool |grep '"name": "nonredhat-jbossews-1.0"' |wc -l
1

5. [root@ip-10-152-178-106 ~]# rhc cartridge list -k |grep jbossews
nonredhat-jbossews-1.0 Tomcat 6 (JBoss EWS 1.0)                  web
nonredhat-jbossews-2.0 Tomcat 7 (JBoss EWS 2.0)                  web