You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ambari.apache.org by sw...@apache.org on 2013/04/15 19:58:50 UTC

svn commit: r1468170 - in /incubator/ambari/trunk: ./ ambari-server/ ambari-server/src/main/java/org/apache/ambari/server/agent/ ambari-server/src/main/java/org/apache/ambari/server/api/services/ ambari-server/src/main/java/org/apache/ambari/server/boo...

Author: swagle
Date: Mon Apr 15 17:58:50 2013
New Revision: 1468170

URL: http://svn.apache.org/r1468170
Log:
AMBARI-1936. Support for installing on mixed OS versions install + mgmt. (swagle)

Added:
    incubator/ambari/trunk/ambari-server/src/main/python/os_type_check.sh
Modified:
    incubator/ambari/trunk/CHANGES.txt
    incubator/ambari/trunk/ambari-server/pom.xml
    incubator/ambari/trunk/ambari-server/src/main/java/org/apache/ambari/server/agent/HeartBeatHandler.java
    incubator/ambari/trunk/ambari-server/src/main/java/org/apache/ambari/server/api/services/AmbariMetaInfo.java
    incubator/ambari/trunk/ambari-server/src/main/java/org/apache/ambari/server/bootstrap/BSRunner.java
    incubator/ambari/trunk/ambari-server/src/main/java/org/apache/ambari/server/bootstrap/BootStrapImpl.java
    incubator/ambari/trunk/ambari-server/src/main/python/bootstrap.py
    incubator/ambari/trunk/ambari-server/src/test/java/org/apache/ambari/server/api/services/AmbariMetaInfoTest.java
    incubator/ambari/trunk/ambari-server/src/test/python/TestBootstrap.py

Modified: incubator/ambari/trunk/CHANGES.txt
URL: http://svn.apache.org/viewvc/incubator/ambari/trunk/CHANGES.txt?rev=1468170&r1=1468169&r2=1468170&view=diff
==============================================================================
--- incubator/ambari/trunk/CHANGES.txt (original)
+++ incubator/ambari/trunk/CHANGES.txt Mon Apr 15 17:58:50 2013
@@ -12,6 +12,8 @@ Trunk (unreleased changes):
 
  NEW FEATURES
 
+ AMBARI-1936. Support for installing on mixed OS versions install + mgmt. (swagle)
+
  AMBARI-1924. Allow for users to customize Ganglia gmetad + gmond user 
  accounts. (Sumit Mohanty via swagle)
 

Modified: incubator/ambari/trunk/ambari-server/pom.xml
URL: http://svn.apache.org/viewvc/incubator/ambari/trunk/ambari-server/pom.xml?rev=1468170&r1=1468169&r2=1468170&view=diff
==============================================================================
--- incubator/ambari/trunk/ambari-server/pom.xml (original)
+++ incubator/ambari/trunk/ambari-server/pom.xml Mon Apr 15 17:58:50 2013
@@ -331,6 +331,9 @@
                 <source>
                   <location>src/main/python/setupAgent.py</location>
                 </source>
+                <source>
+                  <location>src/main/python/os_type_check.sh</location>
+                </source>
               </sources>
             </mapping>
             <mapping>

Modified: incubator/ambari/trunk/ambari-server/src/main/java/org/apache/ambari/server/agent/HeartBeatHandler.java
URL: http://svn.apache.org/viewvc/incubator/ambari/trunk/ambari-server/src/main/java/org/apache/ambari/server/agent/HeartBeatHandler.java?rev=1468170&r1=1468169&r2=1468170&view=diff
==============================================================================
--- incubator/ambari/trunk/ambari-server/src/main/java/org/apache/ambari/server/agent/HeartBeatHandler.java (original)
+++ incubator/ambari/trunk/ambari-server/src/main/java/org/apache/ambari/server/agent/HeartBeatHandler.java Mon Apr 15 17:58:50 2013
@@ -412,15 +412,14 @@ public class HeartBeatHandler {
 
     String agentOsType = getOsType(register.getHardwareProfile().getOS(),
         register.getHardwareProfile().getOSRelease());
-    if (!ambariMetaInfo.areOsTypesCompatible(
-        config.getServerOsType().toLowerCase(), agentOsType)) {
-      LOG.warn("Received registration request from host with non matching"
+    if (!ambariMetaInfo.isOsSupported(agentOsType)) {
+      LOG.warn("Received registration request from host with not supported"
           + " os type"
           + ", hostname=" + hostname
           + ", serverOsType=" + config.getServerOsType()
           + ", agentOstype=" + agentOsType);
-      throw new AmbariException("Cannot register host as it does not match"
-          + " server's os type"
+      throw new AmbariException("Cannot register host with not supported"
+          + " os type"
           + ", hostname=" + hostname
           + ", serverOsType=" + config.getServerOsType()
           + ", agentOstype=" + agentOsType);

Modified: incubator/ambari/trunk/ambari-server/src/main/java/org/apache/ambari/server/api/services/AmbariMetaInfo.java
URL: http://svn.apache.org/viewvc/incubator/ambari/trunk/ambari-server/src/main/java/org/apache/ambari/server/api/services/AmbariMetaInfo.java?rev=1468170&r1=1468169&r2=1468170&view=diff
==============================================================================
--- incubator/ambari/trunk/ambari-server/src/main/java/org/apache/ambari/server/api/services/AmbariMetaInfo.java (original)
+++ incubator/ambari/trunk/ambari-server/src/main/java/org/apache/ambari/server/api/services/AmbariMetaInfo.java Mon Apr 15 17:58:50 2013
@@ -909,7 +909,8 @@ public class AmbariMetaInfo {
     return result;
   }
 
-  public boolean areOsTypesCompatible(String type1, String type2) {
+  //TODO: Method is unused as of now
+/*  public boolean areOsTypesCompatible(String type1, String type2) {
     if (type1 == null || type2 == null) {
       return false;
     }
@@ -928,7 +929,19 @@ public class AmbariMetaInfo {
           type2.equals("oraclelinux6")) {
         return true;
       }
+    } else if (type1.equals("suse11") || type1.equals("sles11")) {
+      if (type2.equals("suse11") || type2.equals("sles11")) {
+        return true;
+      }
     }
     return false;
+  }*/
+
+  public boolean isOsSupported(String osType) {
+    return osType.equals("redhat5") || osType.equals("centos5") ||
+            osType.equals("oraclelinux5") ||
+            osType.equals("redhat6") || osType.equals("centos6") ||
+            osType.equals("oraclelinux6") ||
+            osType.equals("suse11") || osType.equals("sles11");
   }
 }

Modified: incubator/ambari/trunk/ambari-server/src/main/java/org/apache/ambari/server/bootstrap/BSRunner.java
URL: http://svn.apache.org/viewvc/incubator/ambari/trunk/ambari-server/src/main/java/org/apache/ambari/server/bootstrap/BSRunner.java?rev=1468170&r1=1468169&r2=1468170&view=diff
==============================================================================
--- incubator/ambari/trunk/ambari-server/src/main/java/org/apache/ambari/server/bootstrap/BSRunner.java (original)
+++ incubator/ambari/trunk/ambari-server/src/main/java/org/apache/ambari/server/bootstrap/BSRunner.java Mon Apr 15 17:58:50 2013
@@ -19,7 +19,6 @@ package org.apache.ambari.server.bootstr
 
 import java.io.File;
 import java.io.IOException;
-import java.io.StringWriter;
 import java.util.List;
 import java.util.concurrent.Executors;
 import java.util.concurrent.ScheduledExecutorService;
@@ -28,7 +27,6 @@ import java.util.concurrent.TimeUnit;
 
 import org.apache.ambari.server.bootstrap.BootStrapStatus.BSStat;
 import org.apache.commons.io.FileUtils;
-import org.apache.commons.io.IOUtils;
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 
@@ -54,10 +52,11 @@ class BSRunner extends Thread {
   private String ambariHostname;
   private boolean verbose;
   private BootStrapImpl bsImpl;
+  private final String clusterOsType;
 
   public BSRunner(BootStrapImpl impl, SshHostInfo sshHostInfo, String bootDir,
       String bsScript, String agentSetupScript, String agentSetupPassword,
-      int requestId, long timeout, String hostName, boolean isVerbose)
+      int requestId, long timeout, String hostName, boolean isVerbose, String clusterOsType)
   {
     this.requestId = requestId;
     this.sshHostInfo = sshHostInfo;
@@ -69,6 +68,7 @@ class BSRunner extends Thread {
     this.agentSetupPassword = agentSetupPassword;
     this.ambariHostname = hostName;
     this.verbose = isVerbose;
+    this.clusterOsType = clusterOsType;
     this.bsImpl = impl;
     BootStrapStatus status = new BootStrapStatus();
     status.setLog("RUNNING");
@@ -148,7 +148,7 @@ class BSRunner extends Thread {
     if (user == null || user.isEmpty()) {
       user = DEFAULT_USER;
     }
-    String commands[] = new String[8];
+    String commands[] = new String[9];
     String shellCommand[] = new String[3];
     BSStat stat = BSStat.RUNNING;
     String scriptlog = "";
@@ -185,8 +185,9 @@ class BSRunner extends Thread {
       commands[4] = this.sshKeyFile.toString();
       commands[5] = this.agentSetupScript.toString();
       commands[6] = this.ambariHostname;
+      commands[7] = this.clusterOsType;
       if (this.passwordFile != null) {
-        commands[7] = this.passwordFile.toString();
+        commands[8] = this.passwordFile.toString();
       }
       LOG.info("Host= " + hostString + " bs=" + this.bsScript + " requestDir=" +
           requestIdDir + " user=" + user + " keyfile=" + this.sshKeyFile +
@@ -213,8 +214,7 @@ class BSRunner extends Thread {
       shellCommand[2] = commandString.toString();
       Process process = Runtime.getRuntime().exec(shellCommand, env);
 
-      /** Startup a scheduled executor service to look through the logs
-       */
+      // Startup a scheduled executor service to look through the logs
       ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);
       BSStatusCollector statusCollector = new BSStatusCollector();
       ScheduledFuture<?> handle = scheduler.scheduleWithFixedDelay(statusCollector,
@@ -290,7 +290,8 @@ class BSRunner extends Thread {
     } catch(IOException io) {
       LOG.info("Error executing bootstrap " + io.getMessage());
       stat = BSStat.ERROR;
-    } finally {
+    }
+    finally {
       /* get the bstatus */
       BootStrapStatus tmpStatus = bsImpl.getStatus(requestId);
       tmpStatus.setLog(scriptlog);

Modified: incubator/ambari/trunk/ambari-server/src/main/java/org/apache/ambari/server/bootstrap/BootStrapImpl.java
URL: http://svn.apache.org/viewvc/incubator/ambari/trunk/ambari-server/src/main/java/org/apache/ambari/server/bootstrap/BootStrapImpl.java?rev=1468170&r1=1468169&r2=1468170&view=diff
==============================================================================
--- incubator/ambari/trunk/ambari-server/src/main/java/org/apache/ambari/server/bootstrap/BootStrapImpl.java (original)
+++ incubator/ambari/trunk/ambari-server/src/main/java/org/apache/ambari/server/bootstrap/BootStrapImpl.java Mon Apr 15 17:58:50 2013
@@ -47,6 +47,7 @@ public class BootStrapImpl {
   /* Monotonically increasing requestid for the bootstrap api to query on */
   int requestId = 0;
   private FifoLinkedHashMap<Long, BootStrapStatus> bsStatus;
+  private final String clusterOsType;
 
 
   @Inject
@@ -58,6 +59,7 @@ public class BootStrapImpl {
     this.bsStatus = new FifoLinkedHashMap<Long, BootStrapStatus>();
     this.masterHostname = conf.getMasterHostname(
         InetAddress.getLocalHost().getCanonicalHostName());
+    this.clusterOsType = conf.getServerOsType();
   }
 
   /**
@@ -105,7 +107,7 @@ public class BootStrapImpl {
 
     bsRunner = new BSRunner(this, info, bootStrapDir.toString(),
         bootScript, bootSetupAgentScript, bootSetupAgentPassword, requestId, 0L,
-        this.masterHostname, info.isVerbose());
+        this.masterHostname, info.isVerbose(), this.clusterOsType);
     bsRunner.start();
     response.setStatus(BSRunStat.OK);
     response.setLog("Running Bootstrap now.");

Modified: incubator/ambari/trunk/ambari-server/src/main/python/bootstrap.py
URL: http://svn.apache.org/viewvc/incubator/ambari/trunk/ambari-server/src/main/python/bootstrap.py?rev=1468170&r1=1468169&r2=1468170&view=diff
==============================================================================
--- incubator/ambari/trunk/ambari-server/src/main/python/bootstrap.py (original)
+++ incubator/ambari/trunk/ambari-server/src/main/python/bootstrap.py Mon Apr 15 17:58:50 2013
@@ -251,7 +251,7 @@ pass    
     
 class BootStrap:
   """ BootStrapping the agents on a list of hosts"""
-  def __init__(self, hosts, user, sshkeyFile, scriptDir, boottmpdir, setupAgentFile, ambariServer, passwordFile = None):
+  def __init__(self, hosts, user, sshkeyFile, scriptDir, boottmpdir, setupAgentFile, ambariServer, cluster_os_type, passwordFile = None):
     self.hostlist = hosts
     self.successive_hostlist = hosts
     self.hostlist_to_remove_password_file = None
@@ -261,6 +261,7 @@ class BootStrap:
     self.scriptDir = scriptDir
     self.setupAgentFile = setupAgentFile
     self.ambariServer = ambariServer
+    self.cluster_os_type = cluster_os_type
     self.passwordFile = passwordFile
     self.statuses = None
     pass
@@ -282,6 +283,9 @@ class BootStrap:
     """ Ambari repo file for Ambari."""
     return os.path.join(self.getRepoDir(), "ambari.repo")
 
+  def getOsCheckScript(self):
+    return os.path.join(self.scriptDir, "os_type_check.sh")
+
   def getSetupScript(self):
     return os.path.join(self.scriptDir, "setupAgent.py")
 
@@ -303,6 +307,35 @@ class BootStrap:
     else:
       return self.getMoveRepoFileWithoutPasswordCommand(targetDir)
 
+  OS_CHECK_SCRIPT_REMOTE_LOCATION = "/tmp/os_type_check.sh"
+
+  def copyOsCheckScript(self):
+    try:
+      # Copying the os check script file
+      fileToCopy = self.getOsCheckScript()
+      target = self.OS_CHECK_SCRIPT_REMOTE_LOCATION
+      pscp = PSCP(self.hostlist, self.user, self.sshkeyFile, fileToCopy, target, self.bootdir)
+      pscp.run()
+      out = pscp.getstatus()
+      # Preparing report about failed hosts
+      self.successive_hostlist = skip_failed_hosts(out)
+      failed = get_difference(self.hostlist, self.successive_hostlist)
+      logging.info("Parallel scp returns for os type check script. Failed hosts are: " + str(failed))
+      #updating statuses
+      self.statuses = out
+
+      if not failed:
+        retstatus = 0
+      else:
+        retstatus = 1
+      return retstatus
+
+    except Exception, e:
+      logging.info("Traceback " + traceback.format_exc())
+      pass
+
+    pass
+
   def copyNeededFiles(self):
     try:
       # Copying the files
@@ -311,7 +344,7 @@ class BootStrap:
       pscp = PSCP(self.successive_hostlist, self.user, self.sshkeyFile, fileToCopy, "/tmp", self.bootdir)
       pscp.run()
       out = pscp.getstatus()
-      # Prepearing report about failed hosts
+      # Preparing report about failed hosts
       failed_current = get_difference(self.successive_hostlist, skip_failed_hosts(out))
       self.successive_hostlist = skip_failed_hosts(out)
       failed = get_difference(self.hostlist, self.successive_hostlist)
@@ -338,7 +371,7 @@ class BootStrap:
       pscp = PSCP(self.successive_hostlist, self.user, self.sshkeyFile, self.setupAgentFile, "/tmp", self.bootdir)
       pscp.run()
       out = pscp.getstatus()
-      # Prepearing report about failed hosts
+      # Preparing report about failed hosts
       failed_current = get_difference(self.successive_hostlist, skip_failed_hosts(out))
       self.successive_hostlist = skip_failed_hosts(out)
       failed = get_difference(self.hostlist, self.successive_hostlist)
@@ -371,6 +404,32 @@ class BootStrap:
     else:
       return self.getRunSetupWithoutPasswordCommand()
 
+  def runOsCheckScript(self):
+    logging.info("Running os type check...")
+    command = "chmod a+x %s && %s %s" % \
+           (self.OS_CHECK_SCRIPT_REMOTE_LOCATION,
+            self.OS_CHECK_SCRIPT_REMOTE_LOCATION,  self.cluster_os_type)
+
+    pssh = PSSH(self.successive_hostlist, self.user, self.sshkeyFile, command, self.bootdir)
+    pssh.run()
+    out = pssh.getstatus()
+
+    # Preparing report about failed hosts
+    failed_current = get_difference(self.successive_hostlist, skip_failed_hosts(out))
+    self.successive_hostlist = skip_failed_hosts(out)
+    failed = get_difference(self.hostlist, self.successive_hostlist)
+    logging.info("Parallel ssh returns for setup agent. All failed hosts are: " + str(failed) +
+                 ". Failed on last step: " + str(failed_current))
+
+    #updating statuses
+    self.statuses = unite_statuses(self.statuses, out)
+    retstatus = 0
+    if not failed:
+      retstatus = 0
+    else:
+      retstatus = 1
+    pass
+
   def runSetupAgent(self):
     logging.info("Running setup agent...")
     command = self.getRunSetupCommand()
@@ -378,7 +437,7 @@ class BootStrap:
     pssh.run()
     out = pssh.getstatus()
 
-    # Prepearing report about failed hosts
+    # Preparing report about failed hosts
     failed_current = get_difference(self.successive_hostlist, skip_failed_hosts(out))
     self.successive_hostlist = skip_failed_hosts(out)
     failed = get_difference(self.hostlist, self.successive_hostlist)
@@ -535,24 +594,28 @@ class BootStrap:
 
   def run(self):
     """ Copy files and run commands on remote hosts """
-    ret1 = self.checkSudoPackage()
+    ret1 = self.copyOsCheckScript()
+    logging.info("Copying os type check script finished")
+    ret2 = self.runOsCheckScript()
+    logging.info("Running os type check  finished")
+    ret3 = self.checkSudoPackage()
     logging.info("Checking 'sudo' package finished")
-    ret2 = 0
-    ret3 = 0
+    ret4 = 0
+    ret5 = 0
     if self.hasPassword():
-      ret2 = self.copyPasswordFile()
+      ret4 = self.copyPasswordFile()
       logging.info("Copying password file finished")
-      ret3 = self.changePasswordFileModeOnHost()
+      ret5 = self.changePasswordFileModeOnHost()
       logging.info("Change password file mode on host finished")
-    ret4 = self.copyNeededFiles()
+    ret6 = self.copyNeededFiles()
     logging.info("Copying files finished")
-    ret5 = self.runSetupAgent()
+    ret7 = self.runSetupAgent()
     logging.info("Running ssh command finished")
-    ret6 = 0
+    ret8 = 0
     if self.hasPassword() and self.hostlist_to_remove_password_file is not None:
-      ret6 = self.deletePasswordFile()
+      ret8 = self.deletePasswordFile()
       logging.info("Deleting password file finished")
-    retcode = max(ret1, ret2, ret3, ret4, ret5, ret6)
+    retcode = max(ret1, ret2, ret3, ret4, ret5, ret6, ret7, ret8)
     self.createDoneFiles()
     return retcode
     pass
@@ -564,7 +627,7 @@ def main(argv=None):
   onlyargs = argv[1:]
   if len(onlyargs) < 3:
     sys.stderr.write("Usage: <comma separated hosts> "
-                     "<tmpdir for storage> <user> <sshkeyFile> <agent setup script> <ambari-server name> <passwordFile>\n")
+                     "<tmpdir for storage> <user> <sshkeyFile> <agent setup script> <ambari-server name> <cluster os type> <passwordFile>\n")
     sys.exit(2)
     pass
   #Parse the input
@@ -574,7 +637,8 @@ def main(argv=None):
   sshKeyFile = onlyargs[3]
   setupAgentFile = onlyargs[4]
   ambariServer = onlyargs[5]
-  passwordFile = onlyargs[6]
+  cluster_os_type = onlyargs[6]
+  passwordFile = onlyargs[7]
 
   # ssh doesn't like open files
   stat = subprocess.Popen(["chmod", "600", sshKeyFile], stdout=subprocess.PIPE)
@@ -583,10 +647,10 @@ def main(argv=None):
     stat = subprocess.Popen(["chmod", "600", passwordFile], stdout=subprocess.PIPE)
   
   logging.info("BootStrapping hosts " + pprint.pformat(hostList) +
-               "using " + scriptDir + 
+               "using " + scriptDir + " cluster primary OS: " + cluster_os_type +
               " with user '" + user + "' sshKey File " + sshKeyFile + " password File " + passwordFile +
               " using tmp dir " + bootdir + " ambari: " + ambariServer)
-  bootstrap = BootStrap(hostList, user, sshKeyFile, scriptDir, bootdir, setupAgentFile, ambariServer, passwordFile)
+  bootstrap = BootStrap(hostList, user, sshKeyFile, scriptDir, bootdir, setupAgentFile, ambariServer, cluster_os_type, passwordFile)
   ret = bootstrap.run()
   #return  ret
   return 0 # Hack to comply with current usage

Added: incubator/ambari/trunk/ambari-server/src/main/python/os_type_check.sh
URL: http://svn.apache.org/viewvc/incubator/ambari/trunk/ambari-server/src/main/python/os_type_check.sh?rev=1468170&view=auto
==============================================================================
--- incubator/ambari/trunk/ambari-server/src/main/python/os_type_check.sh (added)
+++ incubator/ambari/trunk/ambari-server/src/main/python/os_type_check.sh Mon Apr 15 17:58:50 2013
@@ -0,0 +1,80 @@
+#!/bin/bash
+
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements.  See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License.  You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+C5="centos5"
+C6="centos6"
+RH5="redhat5"
+RH6="redhat6"
+SLES11="sles11"
+SUSE11="suse11"
+OL5="oraclelinux5"
+OL6="oraclelinux6"
+
+cluster_os=$1
+current_os="N/A"
+
+pattern='[^[:digit:]]*'
+
+# OS type detection
+if [ -f  "/etc/centos-release" ] 
+then
+  grep -qE "${pattern}6" /etc/centos-release && current_os=$C6
+  grep -qE "${pattern}5" /etc/centos-release && current_os=$C5
+elif [ -f  "/etc/oracle-release" ] || [ -f  "/etc/ovs-release" ] || [ -f  "/etc/enterprise-release" ] 
+then
+  grep -sqE "${pattern}6" /etc/oracle-release || grep -sqE "${pattern}6" /etc/ovs-release || \
+    grep -sqE "${pattern}6" /etc/enterprise-release && current_os=$OL6
+  grep -sqE "${pattern}5" /etc/oracle-release || grep -sqE "${pattern}5" /etc/ovs-release || \
+      grep -sqE "${pattern}5" /etc/enterprise-release && current_os=$OL5
+elif [ -f  "/etc/redhat-release" ]
+then
+  grep -sqiE "^centos ${pattern}5" /etc/redhat-release && current_os=$C5
+  grep -sqE "^Red Hat Enterprise Linux Server ${pattern}6" /etc/redhat-release && current_os=$RH6
+  grep -sqE "^Red Hat Enterprise Linux Server ${pattern}5" /etc/redhat-release && current_os=$RH5
+elif [ -f  "/etc/SuSE-release" ]
+then
+  grep -sqE "${pattern}11" /etc/SuSE-release && current_os=$SUSE11
+  grep -sqi "SUSE LINUX Enterprise Server" /etc/SuSE-release && [ "$current_os" = "$SUSE11" ] && current_os=$SLES11
+fi
+
+
+echo "Cluster primary OS type is $cluster_os and local OS type is $current_os"
+
+# Compatibility check
+res=1
+case "$cluster_os" in
+
+  $C5|$RH5|$OL5)
+    [ "$current_os" = "$C5" ] || [ "$current_os" = "$RH5" ] || [ "$current_os" = "$OL5" ] && res=0 
+  ;;
+
+  $C6|$RH6|$OL6)
+    [ "$current_os" = "$C6" ] || [ "$current_os" = "$RH6" ] || [ "$current_os" = "$OL6" ] && res=0 
+  ;;
+
+  $SUSE11|$SLES11)
+    [ "$current_os" = "$SUSE11" ] || [ "$current_os" = "$SLES11" ] && res=0 
+  ;;
+
+  *)
+    res=1
+  ;;
+esac
+
+[[ $res -ne 0 ]] && echo "Local OS is not compatible with cluster primary OS. Please perform manual bootstrap on this host."
+
+exit $res

Modified: incubator/ambari/trunk/ambari-server/src/test/java/org/apache/ambari/server/api/services/AmbariMetaInfoTest.java
URL: http://svn.apache.org/viewvc/incubator/ambari/trunk/ambari-server/src/test/java/org/apache/ambari/server/api/services/AmbariMetaInfoTest.java?rev=1468170&r1=1468169&r2=1468170&view=diff
==============================================================================
--- incubator/ambari/trunk/ambari-server/src/test/java/org/apache/ambari/server/api/services/AmbariMetaInfoTest.java (original)
+++ incubator/ambari/trunk/ambari-server/src/test/java/org/apache/ambari/server/api/services/AmbariMetaInfoTest.java Mon Apr 15 17:58:50 2013
@@ -413,4 +413,17 @@ public class AmbariMetaInfoTest {
       Assert.assertTrue(e instanceof StackAccessException);
     }
   }
+
+  @Test
+  public void isOsSupported() throws Exception {
+    Assert.assertTrue(metaInfo.isOsSupported("redhat5"));
+    Assert.assertTrue(metaInfo.isOsSupported("centos5"));
+    Assert.assertTrue(metaInfo.isOsSupported("oraclelinux5"));
+    Assert.assertTrue(metaInfo.isOsSupported("redhat6"));
+    Assert.assertTrue(metaInfo.isOsSupported("centos6"));
+    Assert.assertTrue(metaInfo.isOsSupported("oraclelinux6"));
+    Assert.assertTrue(metaInfo.isOsSupported("suse11"));
+    Assert.assertTrue(metaInfo.isOsSupported("sles11"));
+    Assert.assertFalse(metaInfo.isOsSupported("windows"));
+  }
 }

Modified: incubator/ambari/trunk/ambari-server/src/test/python/TestBootstrap.py
URL: http://svn.apache.org/viewvc/incubator/ambari/trunk/ambari-server/src/test/python/TestBootstrap.py?rev=1468170&r1=1468169&r2=1468170&view=diff
==============================================================================
--- incubator/ambari/trunk/ambari-server/src/test/python/TestBootstrap.py (original)
+++ incubator/ambari/trunk/ambari-server/src/test/python/TestBootstrap.py Mon Apr 15 17:58:50 2013
@@ -31,6 +31,8 @@ from unittest import TestCase
 from subprocess import Popen
 from bootstrap import AMBARI_PASSPHRASE_VAR_NAME
 from mock.mock import MagicMock, call
+from mock.mock import patch
+from mock.mock import create_autospec
 
 class TestBootstrap(TestCase):
 
@@ -70,7 +72,7 @@ class TestBootstrap(TestCase):
     SCP.writeLogToFile = lambda self, logFilePath: None
     SSH.writeLogToFile = lambda self, logFilePath: None
     SSH.writeDoneToFile = lambda self, doneFilePath, returncode: None
-    bootstrap = BootStrap(["hostname"], "root", "sshKeyFile", "scriptDir", "bootdir", "setupAgentFile", "ambariServer")
+    bootstrap = BootStrap(["hostname"], "root", "sshKeyFile", "scriptDir", "bootdir", "setupAgentFile", "ambariServer", "centos6")
     ret = bootstrap.checkSudoPackage()
     self.assertTrue("Error: Sudo command is not available. Please install the sudo command." in bootstrap.statuses["hostname"]["log"])
 
@@ -96,7 +98,7 @@ class TestBootstrap(TestCase):
     BootStrap.changePasswordFileModeOnHost = changePasswordFileModeOnHost
 
     os.environ[AMBARI_PASSPHRASE_VAR_NAME] = ""
-    bootstrap = BootStrap(["hostname"], "user", "sshKeyFile", "scriptDir", "bootdir", "setupAgentFile", "ambariServer", "passwordFile")
+    bootstrap = BootStrap(["hostname"], "user", "sshKeyFile", "scriptDir", "bootdir", "setupAgentFile", "ambariServer", "centos6", "passwordFile")
     ret = bootstrap.run()
     self.assertTrue(bootstrap.copyPasswordFile_called)
     self.assertTrue(deletePasswordFile.called)
@@ -124,7 +126,7 @@ class TestBootstrap(TestCase):
     BootStrap.changePasswordFileModeOnHost = changePasswordFileModeOnHost
 
     os.environ[AMBARI_PASSPHRASE_VAR_NAME] = ""
-    bootstrap = BootStrap(["hostname"], "user", "sshKeyFile", "scriptDir", "bootdir", "setupAgentFile", "ambariServer")
+    bootstrap = BootStrap(["hostname"], "user", "sshKeyFile", "scriptDir", "bootdir", "setupAgentFile", "ambariServer", "centos6")
     bootstrap.copyPasswordFile_called = False
     ret = bootstrap.run()
     self.assertFalse(bootstrap.copyPasswordFile_called)
@@ -150,7 +152,7 @@ class TestBootstrap(TestCase):
     BootStrap.getMoveRepoFileWithPasswordCommand = getMoveRepoFileWithPasswordCommand
 
     os.environ[AMBARI_PASSPHRASE_VAR_NAME] = ""
-    bootstrap = BootStrap(["hostname"], "user", "sshKeyFile", "scriptDir", "bootdir", "setupAgentFile", "ambariServer", "passwordFile")
+    bootstrap = BootStrap(["hostname"], "user", "sshKeyFile", "scriptDir", "bootdir", "setupAgentFile", "ambariServer", "centos6", "passwordFile")
     ret = bootstrap.run()
     self.assertTrue(getRunSetupWithPasswordCommand.called)
     self.assertTrue(getMoveRepoFileWithPasswordCommand.called)
@@ -171,7 +173,110 @@ class TestBootstrap(TestCase):
     BootStrap.getMoveRepoFileWithoutPasswordCommand = getMoveRepoFileWithoutPasswordCommand
 
     os.environ[AMBARI_PASSPHRASE_VAR_NAME] = ""
-    bootstrap = BootStrap(["hostname"], "user", "sshKeyFile", "scriptDir", "bootdir", "setupAgentFile", "ambariServer")
+    bootstrap = BootStrap(["hostname"], "user", "sshKeyFile", "scriptDir", "bootdir", "setupAgentFile", "ambariServer", "centos6")
     ret = bootstrap.run()
     self.assertTrue(getRunSetupWithoutPasswordCommand.called)
     self.assertTrue(getMoveRepoFileWithoutPasswordCommand.called)
+
+
+  @patch.object(BootStrap, "runSetupAgent")
+  @patch.object(BootStrap, "copyNeededFiles")
+  @patch.object(BootStrap, "checkSudoPackage")
+  @patch.object(BootStrap, "runOsCheckScript")
+  @patch.object(BootStrap, "copyOsCheckScript")
+  def test_os_check_performed(self, copyOsCheckScript_method,
+                              runOsCheckScript_method, checkSudoPackage_method,
+                              copyNeededFiles_method, runSetupAgent_method):
+    BootStrap.createDoneFiles = lambda self: None
+
+    getRunSetupWithoutPasswordCommand = MagicMock()
+    getRunSetupWithoutPasswordCommand.return_value = ""
+    BootStrap.getRunSetupWithoutPasswordCommand = getRunSetupWithoutPasswordCommand
+
+    getMoveRepoFileWithoutPasswordCommand = MagicMock()
+    getMoveRepoFileWithoutPasswordCommand.return_value = ""
+    BootStrap.getMoveRepoFileWithoutPasswordCommand = getMoveRepoFileWithoutPasswordCommand
+
+    copyOsCheckScript_method.return_value = 0
+    runOsCheckScript_method.return_value = 0
+    checkSudoPackage_method.return_value = 0
+    copyNeededFiles_method.return_value = 0
+    runSetupAgent_method.return_value = 0
+
+    BootStrap.copyOsCheckScript = copyOsCheckScript_method
+    BootStrap.runOsCheckScript = runOsCheckScript_method
+    BootStrap.checkSudoPackage = checkSudoPackage_method
+    BootStrap.copyNeededFiles = copyNeededFiles_method
+    BootStrap.runSetupAgent = runSetupAgent_method
+
+    os.environ[AMBARI_PASSPHRASE_VAR_NAME] = ""
+    bootstrap = BootStrap(["hostname"], "user", "sshKeyFile", "scriptDir",
+                          "bootdir", "setupAgentFile", "ambariServer",
+                          "centos6")
+    ret = bootstrap.run()
+    self.assertTrue(copyOsCheckScript_method.called)
+    self.assertTrue(runOsCheckScript_method.called)
+    self.assertTrue(ret == 0)
+
+  @patch.object(PSCP, "run")
+  @patch.object(PSCP, "getstatus")
+  def test_copyOsCheckScript(self, getstatus_method, run_method):
+    getstatus_method.return_value = {
+      "hostname" : {
+        "exitstatus" : 0,
+        "log" : ""
+      }
+    }
+    os.environ[AMBARI_PASSPHRASE_VAR_NAME] = ""
+    bootstrap = BootStrap(["hostname"], "user", "sshKeyFile", "scriptDir",
+                          "bootdir", "setupAgentFile", "ambariServer",
+                          "centos6")
+    res = bootstrap.copyOsCheckScript()
+    self.assertTrue(run_method.called)
+    self.assertTrue(getstatus_method.called)
+    self.assertTrue(res == 0)
+    pass
+
+  @patch.object(PSSH, "run")
+  @patch.object(PSSH, "getstatus")
+  def test_runOsCheckScript_success(self, getstatus_method, run_method):
+    good_stats = {
+      "hostname" : {
+        "exitstatus" : 0,
+        "log" : ""
+      }
+    }
+    getstatus_method.return_value = good_stats
+    os.environ[AMBARI_PASSPHRASE_VAR_NAME] = ""
+    bootstrap = BootStrap(["hostname"], "user", "sshKeyFile", "scriptDir",
+                          "bootdir", "setupAgentFile", "ambariServer",
+                          "centos6")
+    bootstrap.statuses = good_stats
+    bootstrap.runOsCheckScript()
+
+    self.assertTrue(run_method.called)
+    self.assertTrue(getstatus_method.called)
+    self.assertTrue("hostname" in bootstrap.successive_hostlist)
+    pass
+
+  @patch.object(PSSH, "run")
+  @patch.object(PSSH, "getstatus")
+  def test_runOsCheckScript_fail(self, getstatus_method, run_method):
+    good_stats = {
+      "hostname" : {
+        "exitstatus" : 1,
+        "log" : ""
+      }
+    }
+    getstatus_method.return_value = good_stats
+    os.environ[AMBARI_PASSPHRASE_VAR_NAME] = ""
+    bootstrap = BootStrap(["hostname"], "user", "sshKeyFile", "scriptDir",
+                          "bootdir", "setupAgentFile", "ambariServer",
+                          "centos6")
+    bootstrap.statuses = good_stats
+    bootstrap.runOsCheckScript()
+
+    self.assertTrue(run_method.called)
+    self.assertTrue(getstatus_method.called)
+    self.assertTrue("hostname" not in bootstrap.successive_hostlist)
+    pass
\ No newline at end of file