Repository: ambari
Updated Branches:
  refs/heads/trunk 3ad685095 -> 282a59a7b


AMBARI-5671. Externalize OS family relationship (ncole)


Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/282a59a7
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/282a59a7
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/282a59a7

Branch: refs/heads/trunk
Commit: 282a59a7b2b6615b6a1359af0f65ad1598c5feff
Parents: 3ad6850
Author: Nate Cole <[email protected]>
Authored: Mon May 5 20:33:50 2014 -0400
Committer: Nate Cole <[email protected]>
Committed: Fri May 9 17:03:18 2014 -0400

----------------------------------------------------------------------
 .../src/main/python/ambari_agent/Facter.py      |  2 +-
 .../test/python/ambari_agent/TestHardware.py    | 17 ++--
 .../AmbariCustomCommandExecutionHelper.java     | 20 +++--
 .../server/state/stack/LatestRepoCallable.java  |  5 +-
 .../ambari/server/state/stack/OsFamily.java     | 93 +++++++++++++++-----
 .../ambari/server/upgrade/StackUpgradeUtil.java |  8 +-
 ambari-server/src/main/resources/os_family.json | 23 +++++
 7 files changed, 123 insertions(+), 45 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ambari/blob/282a59a7/ambari-agent/src/main/python/ambari_agent/Facter.py
----------------------------------------------------------------------
diff --git a/ambari-agent/src/main/python/ambari_agent/Facter.py 
b/ambari-agent/src/main/python/ambari_agent/Facter.py
index 1d16604..f9bca94 100644
--- a/ambari-agent/src/main/python/ambari_agent/Facter.py
+++ b/ambari-agent/src/main/python/ambari_agent/Facter.py
@@ -111,7 +111,7 @@ class Facter():
 
   # Returns the full name of the OS
   def getOperatingSystem(self):
-    return OSCheck.get_os_family()
+    return OSCheck.get_os_type()
 
   # Returns the OS version
   def getOperatingSystemRelease(self):

http://git-wip-us.apache.org/repos/asf/ambari/blob/282a59a7/ambari-agent/src/test/python/ambari_agent/TestHardware.py
----------------------------------------------------------------------
diff --git a/ambari-agent/src/test/python/ambari_agent/TestHardware.py 
b/ambari-agent/src/test/python/ambari_agent/TestHardware.py
index 64d0d12..e65f2b5 100644
--- a/ambari-agent/src/test/python/ambari_agent/TestHardware.py
+++ b/ambari-agent/src/test/python/ambari_agent/TestHardware.py
@@ -187,26 +187,29 @@ lo        Link encap:Local Loopback
   @patch.object(OSCheck, "get_os_type")
   @patch.object(OSCheck, "get_os_family")
   @patch.object(OSCheck, "get_os_version")
-  def test_facterDataOperatingsystemIsFamily(self, get_os_version_mock, 
get_os_family_mock, get_os_type_mock):
-    #Check that getOperatingSystem == os_family (NOT os_type)
+  def test_facterDataOperatingsystemVsFamily(self, get_os_version_mock, 
get_os_family_mock, get_os_type_mock):
     get_os_type_mock.return_value = "some_type_of_os"
     get_os_version_mock.return_value = "11"
-
     get_os_family_mock.return_value = "redhat"
+
     result = Facter().facterInfo()
-    self.assertEquals(result['operatingsystem'], 'redhat')
+    self.assertEquals(result['operatingsystem'], 'some_type_of_os')
+    self.assertEquals(result['osfamily'], 'redhat')
 
     get_os_family_mock.return_value = "debian"
     result = Facter().facterInfo()
-    self.assertEquals(result['operatingsystem'], 'debian')
+    self.assertEquals(result['operatingsystem'], 'some_type_of_os')
+    self.assertEquals(result['osfamily'], 'debian')
 
     get_os_family_mock.return_value = "suse"
     result = Facter().facterInfo()
-    self.assertEquals(result['operatingsystem'], 'suse')
+    self.assertEquals(result['operatingsystem'], 'some_type_of_os')
+    self.assertEquals(result['osfamily'], 'suse')
 
     get_os_family_mock.return_value = "My_new_family"
     result = Facter().facterInfo()
-    self.assertEquals(result['operatingsystem'], 'My_new_family')
+    self.assertEquals(result['operatingsystem'], 'some_type_of_os')
+    self.assertEquals(result['osfamily'], 'My_new_family')
 
 if __name__ == "__main__":
   unittest.main()

http://git-wip-us.apache.org/repos/asf/ambari/blob/282a59a7/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariCustomCommandExecutionHelper.java
----------------------------------------------------------------------
diff --git 
a/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariCustomCommandExecutionHelper.java
 
b/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariCustomCommandExecutionHelper.java
index d2ba553..8294895 100644
--- 
a/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariCustomCommandExecutionHelper.java
+++ 
b/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariCustomCommandExecutionHelper.java
@@ -49,6 +49,7 @@ import org.apache.ambari.server.state.ServiceInfo;
 import org.apache.ambari.server.state.StackId;
 import org.apache.ambari.server.state.StackInfo;
 import org.apache.ambari.server.state.State;
+import org.apache.ambari.server.state.stack.OsFamily;
 import 
org.apache.ambari.server.state.svccomphost.ServiceComponentHostOpInProgressEvent;
 import org.apache.ambari.server.utils.StageUtils;
 import org.apache.commons.lang.StringUtils;
@@ -746,7 +747,7 @@ public class AmbariCustomCommandExecutionHelper {
    * Get repository info given a cluster and host.
    * @param cluster
    * @param host
-   * @return
+   * @return the repo info
    * @throws AmbariException
    */
   public String getRepoInfo(Cluster cluster, Host host) throws AmbariException 
{
@@ -755,16 +756,23 @@ public class AmbariCustomCommandExecutionHelper {
     Map<String, List<RepositoryInfo>> repos = ambariMetaInfo.getRepository(
         stackId.getStackName(), stackId.getStackVersion());
     String repoInfo = "";
-    if (!repos.containsKey(host.getOsFamily())) {
-      // FIXME should this be an error?
+
+    String family = OsFamily.find(host.getOsType());
+    if (null == family)
+      family = host.getOsFamily();
+   
+    // !!! check for the most specific first
+    if (repos.containsKey(host.getOsType()))
+      repoInfo = gson.toJson(repos.get(host.getOsType()));
+    else if (null != family && repos.containsKey(family))
+      repoInfo = gson.toJson(repos.get(family));
+    else {
       LOG.warn("Could not retrieve repo information for host"
           + ", hostname=" + host.getHostName()
           + ", clusterName=" + cluster.getClusterName()
           + ", stackInfo=" + stackId.getStackId());
-    } else {
-      repoInfo = gson.toJson(repos.get(host.getOsFamily()));
     }
-
+    
     return repoInfo;
   }
 }

http://git-wip-us.apache.org/repos/asf/ambari/blob/282a59a7/ambari-server/src/main/java/org/apache/ambari/server/state/stack/LatestRepoCallable.java
----------------------------------------------------------------------
diff --git 
a/ambari-server/src/main/java/org/apache/ambari/server/state/stack/LatestRepoCallable.java
 
b/ambari-server/src/main/java/org/apache/ambari/server/state/stack/LatestRepoCallable.java
index f8847d9..b542c4c 100644
--- 
a/ambari-server/src/main/java/org/apache/ambari/server/state/stack/LatestRepoCallable.java
+++ 
b/ambari-server/src/main/java/org/apache/ambari/server/state/stack/LatestRepoCallable.java
@@ -21,14 +21,13 @@ import java.io.File;
 import java.io.FileReader;
 import java.io.InputStreamReader;
 import java.lang.reflect.Type;
-import java.net.URI;
 import java.util.Map;
+import java.util.Set;
 import java.util.concurrent.Callable;
 
 import org.apache.ambari.server.controller.internal.URLStreamProvider;
 import org.apache.ambari.server.state.RepositoryInfo;
 import org.apache.ambari.server.state.StackInfo;
-import org.apache.http.client.utils.URIBuilder;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -139,7 +138,7 @@ public class LatestRepoCallable implements Callable<Void> {
       return osMap.get(os);
     
     // !!! os not found, find and return the first compatible one
-    String[] possibleTypes = OsFamily.findTypes(os);
+    Set<String> possibleTypes = OsFamily.findTypes(os);
     
     for (String type : possibleTypes) {
       if (osMap.containsKey(type))

http://git-wip-us.apache.org/repos/asf/ambari/blob/282a59a7/ambari-server/src/main/java/org/apache/ambari/server/state/stack/OsFamily.java
----------------------------------------------------------------------
diff --git 
a/ambari-server/src/main/java/org/apache/ambari/server/state/stack/OsFamily.java
 
b/ambari-server/src/main/java/org/apache/ambari/server/state/stack/OsFamily.java
index 5c458a4..40ef3ea 100644
--- 
a/ambari-server/src/main/java/org/apache/ambari/server/state/stack/OsFamily.java
+++ 
b/ambari-server/src/main/java/org/apache/ambari/server/state/stack/OsFamily.java
@@ -17,41 +17,86 @@
  */
 package org.apache.ambari.server.state.stack;
 
-public enum OsFamily {
-  REDHAT5("centos5", "redhat5", "oraclelinux5", "rhel5"),
-  REDHAT6("centos6", "redhat6", "oraclelinux6", "rhel6"),
-  SUSE11("suse11", "sles11"),
-  DEBIAN12("debian12", "ubuntu12");
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.lang.reflect.Type;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.gson.Gson;
+import com.google.gson.reflect.TypeToken;
+
+/**
+ * Class that encapsulates OS family logic
+ */
+public class OsFamily {
+
+  private static final String FILE_NAME = "os_family.json";
+  private static final Logger LOG = LoggerFactory.getLogger(OsFamily.class);
   
-  private String[] osTypes;
-  private OsFamily(String... oses) {
-    osTypes = oses;
-  }
+  private static Map<String, Set<String>> osMap = new HashMap<String, 
Set<String>>();
   
-  static String[] findTypes(String os) {
-    for (OsFamily f : values()) {
-      for (String t : f.osTypes) {
-        if (t.equals(os)) {
-          return f.osTypes;
-        }
-      }
+  static {
+    try {
+      InputStream inputStream = 
OsFamily.class.getClassLoader().getResourceAsStream(FILE_NAME);
+      if (null == inputStream)
+        inputStream = ClassLoader.getSystemResourceAsStream(FILE_NAME);
+      
+      Type type = new TypeToken<Map<String, Set<String>>>(){}.getType();
+      Gson gson = new Gson();
+      osMap = gson.fromJson(new InputStreamReader(inputStream), type);
+      
+    } catch (Exception e) {
+      LOG.error("Could not load OS family definition, using defaults");
+      osMap.put("centos5", new HashSet<String>());
+      osMap.put("centos6", new HashSet<String>());
+      osMap.put("suse11", new HashSet<String>());
+      osMap.put("debian12", new HashSet<String>());
+      
+      Collections.addAll(osMap.get("centos5"), "centos5", "redhat5", 
"oraclelinux5", "rhel5");
+      Collections.addAll(osMap.get("centos6"), "centos6", "redhat6", 
"oraclelinux6", "rhel6");
+      Collections.addAll(osMap.get("suse11"), "suse11", "sles11", 
"opensuse11");
+      Collections.addAll(osMap.get("debian12"), "ubuntu12");
     }
-    return new String[0];
   }
 
+
   /**
-   * Finds the family for the specific os
+   * Gets the array of compatible OS types
    * @param os the os
+   * @return all types that are compatible with the supplied type
+   */
+  static Set<String> findTypes(String os) {
+    for (Entry<String, Set<String>> entry : osMap.entrySet()) {
+      for (String type : entry.getValue()) {
+        if (type.equals(os))
+          return Collections.unmodifiableSet(entry.getValue());
+      }
+    }
+    return Collections.emptySet();
+  }
+
+  /**
+   * Finds the family for the specific OS
+   * @param os the OS
    * @return the family, or <code>null</code> if not defined
    */
-  public static OsFamily find(String os) {
-    for (OsFamily f : values()) {
-      for (String t : f.osTypes) {
-        if (t.equals(os)) {
-          return f;
-        }
+  public static String find(String os) {
+    for (Entry<String, Set<String>> entry : osMap.entrySet()) {
+      for (String type : entry.getValue()) {
+        if (type.equals(os))
+          return entry.getKey();
       }
     }
+    
     return null;
   }
+
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ambari/blob/282a59a7/ambari-server/src/main/java/org/apache/ambari/server/upgrade/StackUpgradeUtil.java
----------------------------------------------------------------------
diff --git 
a/ambari-server/src/main/java/org/apache/ambari/server/upgrade/StackUpgradeUtil.java
 
b/ambari-server/src/main/java/org/apache/ambari/server/upgrade/StackUpgradeUtil.java
index bdce8a7..f443146 100644
--- 
a/ambari-server/src/main/java/org/apache/ambari/server/upgrade/StackUpgradeUtil.java
+++ 
b/ambari-server/src/main/java/org/apache/ambari/server/upgrade/StackUpgradeUtil.java
@@ -183,13 +183,13 @@ public class StackUpgradeUtil {
     } else {
       for (String os : oses) {
         
-        OsFamily family = OsFamily.find(os);
+        String family = OsFamily.find(os);
         if (null != family) {
           String key = ami.generateRepoMetaKey(stackName, stackVersion, os,
-              stackName + "-" + stackVersion, 
AmbariMetaInfo.REPOSITORY_XML_PROPERTY_BASEURL);
+              stackRepoId, AmbariMetaInfo.REPOSITORY_XML_PROPERTY_BASEURL);
 
-          String familyKey = ami.generateRepoMetaKey(stackName, stackVersion,
-              family.name().toLowerCase(), stackRepoId, 
AmbariMetaInfo.REPOSITORY_XML_PROPERTY_BASEURL);
+          String familyKey = ami.generateRepoMetaKey(stackName, stackVersion, 
family,
+              stackRepoId, AmbariMetaInfo.REPOSITORY_XML_PROPERTY_BASEURL);
           
           // need to use (for example) redhat6 if the os is centos6
           MetainfoEntity entity = metaDao.findByKey(key);

http://git-wip-us.apache.org/repos/asf/ambari/blob/282a59a7/ambari-server/src/main/resources/os_family.json
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/os_family.json 
b/ambari-server/src/main/resources/os_family.json
new file mode 100644
index 0000000..be030e3
--- /dev/null
+++ b/ambari-server/src/main/resources/os_family.json
@@ -0,0 +1,23 @@
+{
+  "redhat6": [
+    "redhat6",
+    "centos6",
+    "oraclelinux6",
+    "rhel6"
+  ],
+  "redhat5": [
+    "redhat5",
+    "centos5",
+    "oraclelinux5",
+    "rhel5"
+  ],
+  "suse11": [
+    "suse11",
+    "sles11",
+    "opensuse11"
+  ],
+  "debian12": [
+    "debian12",
+    "ubuntu12"
+  ]
+}

Reply via email to