Browse Source

AMBARI-4056. Add to service scripts some method to determine service state(started/stopped) (dlysnichenko)

Lisnichenko Dmitro 11 years ago
parent
commit
fd9cd27a1a
70 changed files with 820 additions and 239 deletions
  1. 10 1
      ambari-agent/src/main/python/ambari_agent/ActionQueue.py
  2. 72 10
      ambari-agent/src/main/python/ambari_agent/CustomServiceOrchestrator.py
  3. 13 9
      ambari-agent/src/main/python/ambari_agent/LiveStatus.py
  4. 9 3
      ambari-agent/src/main/python/ambari_agent/PythonExecutor.py
  5. 16 0
      ambari-agent/src/main/python/resource_management/core/exceptions.py
  6. 1 0
      ambari-agent/src/main/python/resource_management/libraries/functions/__init__.py
  7. 36 0
      ambari-agent/src/main/python/resource_management/libraries/functions/check_process_status.py
  8. 2 1
      ambari-agent/src/main/python/resource_management/libraries/script/__init__.py
  9. 13 3
      ambari-agent/src/main/python/resource_management/libraries/script/script.py
  10. 18 2
      ambari-agent/src/test/python/ambari_agent/TestActionQueue.py
  11. 65 7
      ambari-agent/src/test/python/ambari_agent/TestCustomServiceOrchestrator.py
  12. 12 0
      ambari-agent/src/test/python/ambari_agent/TestLiveStatus.py
  13. 0 1
      ambari-agent/src/test/python/ambari_agent/TestPythonExecutor.py
  14. 9 0
      ambari-server/src/main/java/org/apache/ambari/server/RoleCommand.java
  15. 1 0
      ambari-server/src/main/java/org/apache/ambari/server/agent/ExecutionCommand.java
  16. 85 50
      ambari-server/src/main/java/org/apache/ambari/server/agent/HeartbeatMonitor.java
  17. 24 0
      ambari-server/src/main/java/org/apache/ambari/server/agent/StatusCommand.java
  18. 30 0
      ambari-server/src/main/resources/stacks/HDP/1.3._/hooks/before-START.py
  19. 17 0
      ambari-server/src/main/resources/stacks/HDP/1.3._/services/GANGLIA/package/scripts/ganglia_monitor.py
  20. 7 0
      ambari-server/src/main/resources/stacks/HDP/1.3._/services/GANGLIA/package/scripts/ganglia_server.py
  21. 25 0
      ambari-server/src/main/resources/stacks/HDP/1.3._/services/GANGLIA/package/scripts/status_params.py
  22. 3 0
      ambari-server/src/main/resources/stacks/HDP/1.3._/services/SQOOP/package/scripts/sqoop_client.py
  23. 17 0
      ambari-server/src/main/resources/stacks/HDP/2.0._/services/GANGLIA/package/scripts/ganglia_monitor.py
  24. 7 0
      ambari-server/src/main/resources/stacks/HDP/2.0._/services/GANGLIA/package/scripts/ganglia_server.py
  25. 25 0
      ambari-server/src/main/resources/stacks/HDP/2.0._/services/GANGLIA/package/scripts/status_params.py
  26. 0 2
      ambari-server/src/main/resources/stacks/HDP/2.0._/services/HBASE/package/scripts/__init__.py
  27. 0 2
      ambari-server/src/main/resources/stacks/HDP/2.0._/services/HBASE/package/scripts/functions.py
  28. 0 2
      ambari-server/src/main/resources/stacks/HDP/2.0._/services/HBASE/package/scripts/hbase.py
  29. 4 3
      ambari-server/src/main/resources/stacks/HDP/2.0._/services/HBASE/package/scripts/hbase_client.py
  30. 7 3
      ambari-server/src/main/resources/stacks/HDP/2.0._/services/HBASE/package/scripts/hbase_master.py
  31. 6 2
      ambari-server/src/main/resources/stacks/HDP/2.0._/services/HBASE/package/scripts/hbase_regionserver.py
  32. 2 4
      ambari-server/src/main/resources/stacks/HDP/2.0._/services/HBASE/package/scripts/hbase_service.py
  33. 2 3
      ambari-server/src/main/resources/stacks/HDP/2.0._/services/HBASE/package/scripts/params.py
  34. 0 2
      ambari-server/src/main/resources/stacks/HDP/2.0._/services/HBASE/package/scripts/service_check.py
  35. 25 0
      ambari-server/src/main/resources/stacks/HDP/2.0._/services/HBASE/package/scripts/status_params.py
  36. 0 2
      ambari-server/src/main/resources/stacks/HDP/2.0._/services/HIVE/package/scripts/__init__.py
  37. 0 2
      ambari-server/src/main/resources/stacks/HDP/2.0._/services/HIVE/package/scripts/hcat.py
  38. 4 2
      ambari-server/src/main/resources/stacks/HDP/2.0._/services/HIVE/package/scripts/hcat_client.py
  39. 0 2
      ambari-server/src/main/resources/stacks/HDP/2.0._/services/HIVE/package/scripts/hcat_service_check.py
  40. 0 2
      ambari-server/src/main/resources/stacks/HDP/2.0._/services/HIVE/package/scripts/hive.py
  41. 5 2
      ambari-server/src/main/resources/stacks/HDP/2.0._/services/HIVE/package/scripts/hive_client.py
  42. 8 2
      ambari-server/src/main/resources/stacks/HDP/2.0._/services/HIVE/package/scripts/hive_metastore.py
  43. 9 2
      ambari-server/src/main/resources/stacks/HDP/2.0._/services/HIVE/package/scripts/hive_server.py
  44. 1 3
      ambari-server/src/main/resources/stacks/HDP/2.0._/services/HIVE/package/scripts/hive_service.py
  45. 0 58
      ambari-server/src/main/resources/stacks/HDP/2.0._/services/HIVE/package/scripts/mysql.py
  46. 31 6
      ambari-server/src/main/resources/stacks/HDP/2.0._/services/HIVE/package/scripts/mysql_server.py
  47. 12 8
      ambari-server/src/main/resources/stacks/HDP/2.0._/services/HIVE/package/scripts/mysql_service.py
  48. 5 12
      ambari-server/src/main/resources/stacks/HDP/2.0._/services/HIVE/package/scripts/params.py
  49. 0 2
      ambari-server/src/main/resources/stacks/HDP/2.0._/services/HIVE/package/scripts/service_check.py
  50. 30 0
      ambari-server/src/main/resources/stacks/HDP/2.0._/services/HIVE/package/scripts/status_params.py
  51. 7 1
      ambari-server/src/main/resources/stacks/HDP/2.0._/services/NAGIOS/package/scripts/nagios_server.py
  52. 3 4
      ambari-server/src/main/resources/stacks/HDP/2.0._/services/NAGIOS/package/scripts/params.py
  53. 26 0
      ambari-server/src/main/resources/stacks/HDP/2.0._/services/NAGIOS/package/scripts/status_params.py
  54. 3 0
      ambari-server/src/main/resources/stacks/HDP/2.0._/services/OOZIE/package/scripts/oozie_client.py
  55. 5 2
      ambari-server/src/main/resources/stacks/HDP/2.0._/services/OOZIE/package/scripts/oozie_server.py
  56. 3 2
      ambari-server/src/main/resources/stacks/HDP/2.0._/services/OOZIE/package/scripts/params.py
  57. 26 0
      ambari-server/src/main/resources/stacks/HDP/2.0._/services/OOZIE/package/scripts/status_params.py
  58. 3 0
      ambari-server/src/main/resources/stacks/HDP/2.0._/services/PIG/package/scripts/pig_client.py
  59. 0 2
      ambari-server/src/main/resources/stacks/HDP/2.0._/services/SQOOP/package/scripts/__init__.py
  60. 0 2
      ambari-server/src/main/resources/stacks/HDP/2.0._/services/SQOOP/package/scripts/params.py
  61. 0 2
      ambari-server/src/main/resources/stacks/HDP/2.0._/services/SQOOP/package/scripts/service_check.py
  62. 0 2
      ambari-server/src/main/resources/stacks/HDP/2.0._/services/SQOOP/package/scripts/sqoop.py
  63. 3 2
      ambari-server/src/main/resources/stacks/HDP/2.0._/services/SQOOP/package/scripts/sqoop_client.py
  64. 3 2
      ambari-server/src/main/resources/stacks/HDP/2.0._/services/WEBHCAT/package/scripts/params.py
  65. 26 0
      ambari-server/src/main/resources/stacks/HDP/2.0._/services/WEBHCAT/package/scripts/status_params.py
  66. 5 0
      ambari-server/src/main/resources/stacks/HDP/2.0._/services/WEBHCAT/package/scripts/webhcat_server.py
  67. 4 3
      ambari-server/src/main/resources/stacks/HDP/2.0._/services/ZOOKEEPER/package/scripts/params.py
  68. 26 0
      ambari-server/src/main/resources/stacks/HDP/2.0._/services/ZOOKEEPER/package/scripts/status_params.py
  69. 4 0
      ambari-server/src/main/resources/stacks/HDP/2.0._/services/ZOOKEEPER/package/scripts/zookeeper_client.py
  70. 5 0
      ambari-server/src/main/resources/stacks/HDP/2.0._/services/ZOOKEEPER/package/scripts/zookeeper_server.py

+ 10 - 1
ambari-agent/src/main/python/ambari_agent/ActionQueue.py

@@ -210,9 +210,18 @@ class ActionQueue(threading.Thread):
         globalConfig = configurations['global']
         globalConfig = configurations['global']
       else:
       else:
         globalConfig = {}
         globalConfig = {}
+
+      command_format = self.determine_command_format_version(command)
+
       livestatus = LiveStatus(cluster, service, component,
       livestatus = LiveStatus(cluster, service, component,
                               globalConfig, self.config)
                               globalConfig, self.config)
-      result = livestatus.build()
+      component_status = None
+      if command_format == self.COMMAND_FORMAT_V2:
+        # For custom services, responsibility to determine service status is
+        # delegated to python scripts
+        component_status = self.customServiceOrchestrator.requestComponentStatus(command)
+
+      result = livestatus.build(forsed_component_status= component_status)
       logger.debug("Got live status for component " + component + \
       logger.debug("Got live status for component " + component + \
                    " of service " + str(service) + \
                    " of service " + str(service) + \
                    " of cluster " + str(cluster))
                    " of cluster " + str(cluster))

+ 72 - 10
ambari-agent/src/main/python/ambari_agent/CustomServiceOrchestrator.py

@@ -28,6 +28,7 @@ from AgentException import AgentException
 from PythonExecutor import PythonExecutor
 from PythonExecutor import PythonExecutor
 from AmbariConfig import AmbariConfig
 from AmbariConfig import AmbariConfig
 import hostname
 import hostname
+from LiveStatus import LiveStatus
 
 
 
 
 logger = logging.getLogger()
 logger = logging.getLogger()
@@ -39,6 +40,7 @@ class CustomServiceOrchestrator():
   """
   """
 
 
   SCRIPT_TYPE_PYTHON = "PYTHON"
   SCRIPT_TYPE_PYTHON = "PYTHON"
+  COMMAND_NAME_STATUS = "STATUS"
   CUSTOM_ACTION_COMMAND = 'ACTIONEXECUTE'
   CUSTOM_ACTION_COMMAND = 'ACTIONEXECUTE'
 
 
   PRE_HOOK_PREFIX="before"
   PRE_HOOK_PREFIX="before"
@@ -49,16 +51,43 @@ class CustomServiceOrchestrator():
     self.tmp_dir = config.get('agent', 'prefix')
     self.tmp_dir = config.get('agent', 'prefix')
     self.file_cache = FileCache(config)
     self.file_cache = FileCache(config)
     self.python_executor = PythonExecutor(self.tmp_dir, config)
     self.python_executor = PythonExecutor(self.tmp_dir, config)
+    self.status_commands_stdout = os.path.join(self.tmp_dir,
+                                               'status_command_stdout.txt')
+    self.status_commands_stderr = os.path.join(self.tmp_dir,
+                                               'status_command_stderr.txt')
+    # Clean up old status command files if any
+    try:
+      os.unlink(self.status_commands_stdout)
+      os.unlink(self.status_commands_stderr)
+    except OSError:
+      pass # Ignore fail
 
 
 
 
-  def runCommand(self, command, tmpoutfile, tmperrfile):
+  def runCommand(self, command, tmpoutfile, tmperrfile, forsed_command_name = None,
+                 override_output_files = True):
+    """
+    forsed_command_name may be specified manually. In this case, value, defined at
+    command json, is ignored.
+    """
     try:
     try:
-      component_name = command['role']
+      try:
+        component_name = command['role']
+      except KeyError:
+        # For status commands and (maybe) custom actions component name
+        # is stored at another location
+        component_name = command['componentName']
       script_type = command['commandParams']['script_type']
       script_type = command['commandParams']['script_type']
       script = command['commandParams']['script']
       script = command['commandParams']['script']
-      command_name = command['roleCommand']
       timeout = int(command['commandParams']['command_timeout'])
       timeout = int(command['commandParams']['command_timeout'])
-      task_id = command['taskId']
+      task_id = "status"
+      try:
+        task_id = command['taskId']
+        command_name = command['roleCommand']
+      except KeyError:
+        pass # Status commands have no taskId
+
+      if forsed_command_name is not None: # If not supplied as an argument
+        command_name = forsed_command_name
 
 
       if command_name == self.CUSTOM_ACTION_COMMAND:
       if command_name == self.CUSTOM_ACTION_COMMAND:
         base_dir = self.config.get('python', 'custom_actions_dir')
         base_dir = self.config.get('python', 'custom_actions_dir')
@@ -74,6 +103,7 @@ class CustomServiceOrchestrator():
         script_path = self.resolve_script_path(base_dir, script, script_type)
         script_path = self.resolve_script_path(base_dir, script, script_type)
         script_tuple = (script_path, base_dir)
         script_tuple = (script_path, base_dir)
 
 
+
       tmpstrucoutfile = os.path.join(self.tmp_dir,
       tmpstrucoutfile = os.path.join(self.tmp_dir,
                                     "structured-out-{0}.json".format(task_id))
                                     "structured-out-{0}.json".format(task_id))
       if script_type.upper() != self.SCRIPT_TYPE_PYTHON:
       if script_type.upper() != self.SCRIPT_TYPE_PYTHON:
@@ -89,12 +119,16 @@ class CustomServiceOrchestrator():
       py_file_list = [pre_hook_tuple, script_tuple, post_hook_tuple]
       py_file_list = [pre_hook_tuple, script_tuple, post_hook_tuple]
       # filter None values
       # filter None values
       filtered_py_file_list = [i for i in py_file_list if i]
       filtered_py_file_list = [i for i in py_file_list if i]
+
       # Executing hooks and script
       # Executing hooks and script
       ret = None
       ret = None
       for py_file, current_base_dir in filtered_py_file_list:
       for py_file, current_base_dir in filtered_py_file_list:
         script_params = [command_name, json_path, current_base_dir]
         script_params = [command_name, json_path, current_base_dir]
         ret = self.python_executor.run_file(py_file, script_params,
         ret = self.python_executor.run_file(py_file, script_params,
-                               tmpoutfile, tmperrfile, timeout, tmpstrucoutfile)
+                               tmpoutfile, tmperrfile, timeout,
+                               tmpstrucoutfile, override_output_files)
+        # Next run_file() invocations should always append to current output
+        override_output_files = False
         if ret['exitcode'] != 0:
         if ret['exitcode'] != 0:
           break
           break
 
 
@@ -105,7 +139,7 @@ class CustomServiceOrchestrator():
       exc_type, exc_obj, exc_tb = sys.exc_info()
       exc_type, exc_obj, exc_tb = sys.exc_info()
       message = "Catched an exception while executing "\
       message = "Catched an exception while executing "\
         "custom service command: {0}: {1}".format(exc_type, exc_obj)
         "custom service command: {0}: {1}".format(exc_type, exc_obj)
-      logger.error(message)
+      logger.exception(message)
       ret = {
       ret = {
         'stdout' : message,
         'stdout' : message,
         'stderr' : message,
         'stderr' : message,
@@ -115,6 +149,24 @@ class CustomServiceOrchestrator():
     return ret
     return ret
 
 
 
 
+  def requestComponentStatus(self, command):
+    """
+     Component status is determined by exit code, returned by runCommand().
+     Exit code 0 means that component is running and any other exit code means that
+     component is not running
+    """
+    override_output_files=True # by default, we override status command output
+    if logger.level == logging.DEBUG:
+      override_output_files = False
+    res = self.runCommand(command, self.status_commands_stdout,
+                          self.status_commands_stderr, self.COMMAND_NAME_STATUS,
+                          override_output_files=override_output_files)
+    if res['exitcode'] == 0:
+      return LiveStatus.LIVE_STATUS
+    else:
+      return LiveStatus.DEAD_STATUS
+
+
   def resolve_script_path(self, base_dir, script, script_type):
   def resolve_script_path(self, base_dir, script, script_type):
     """
     """
     Incapsulates logic of script location determination.
     Incapsulates logic of script location determination.
@@ -151,10 +203,20 @@ class CustomServiceOrchestrator():
     public_fqdn = hostname.public_hostname()
     public_fqdn = hostname.public_hostname()
     command['public_hostname'] = public_fqdn
     command['public_hostname'] = public_fqdn
     # Now, dump the json file
     # Now, dump the json file
-    task_id = command['taskId']
-    file_path = os.path.join(self.tmp_dir, "command-{0}.json".format(task_id))
-    # Command json contains passwords, that's why we need proper permissions
-    with os.fdopen(os.open(file_path, os.O_WRONLY | os.O_CREAT,0600), 'w') as f:
+    command_type = command['commandType']
+    from ActionQueue import ActionQueue  # To avoid cyclic dependency
+    if command_type == ActionQueue.STATUS_COMMAND:
+      # These files are frequently created, thats why we don't
+      # store them all, but only the latest one
+      file_path = os.path.join(self.tmp_dir, "status_command.json")
+    else:
+      task_id = command['taskId']
+      file_path = os.path.join(self.tmp_dir, "command-{0}.json".format(task_id))
+    # Json may contain passwords, that's why we need proper permissions
+    if os.path.isfile(file_path):
+      os.unlink(file_path)
+    with os.fdopen(os.open(file_path, os.O_WRONLY | os.O_CREAT,
+                           0600), 'w') as f:
       content = json.dumps(command, sort_keys = False, indent = 4)
       content = json.dumps(command, sort_keys = False, indent = 4)
       f.write(content)
       f.write(content)
     return file_path
     return file_path

+ 13 - 9
ambari-agent/src/main/python/ambari_agent/LiveStatus.py

@@ -141,21 +141,25 @@ class LiveStatus:
     #TODO: Should also check belonging of server to cluster
     #TODO: Should also check belonging of server to cluster
     return component['serviceName'] == self.service
     return component['serviceName'] == self.service
 
 
-  # Live status was stripped from heartbeat after revision e1718dd
-  def build(self):
+  def build(self, forsed_component_status = None):
+    """
+    If forsed_component_status is explicitly defined, than StatusCheck methods are
+    not used. This feature has been added to support custom (ver 2.0) services.
+    """
     global SERVICES, CLIENT_COMPONENTS, COMPONENTS, LIVE_STATUS, DEAD_STATUS
     global SERVICES, CLIENT_COMPONENTS, COMPONENTS, LIVE_STATUS, DEAD_STATUS
-    statusCheck = StatusCheck(AmbariConfig.servicesToPidNames,
-      AmbariConfig.pidPathesVars, self.globalConfig,
-      AmbariConfig.servicesToLinuxUser)
+
     livestatus = None
     livestatus = None
     component = {"serviceName" : self.service, "componentName" : self.component}
     component = {"serviceName" : self.service, "componentName" : self.component}
     if component in self.COMPONENTS + self.CLIENT_COMPONENTS :
     if component in self.COMPONENTS + self.CLIENT_COMPONENTS :
-      # CLIENT components can't have status STARTED
-      if component in self.CLIENT_COMPONENTS:
-        status = self.DEAD_STATUS
+      if forsed_component_status: # If already determined
+        status = forsed_component_status  # Nothing to do
+      elif component in self.CLIENT_COMPONENTS:
+        status = self.DEAD_STATUS # CLIENT components can't have status STARTED
       else:
       else:
+        statusCheck = StatusCheck(AmbariConfig.servicesToPidNames,
+                                  AmbariConfig.pidPathesVars, self.globalConfig,
+                                  AmbariConfig.servicesToLinuxUser)
         serviceStatus = statusCheck.getStatus(self.component)
         serviceStatus = statusCheck.getStatus(self.component)
-
         if serviceStatus is None:
         if serviceStatus is None:
           logger.warn("There is no service to pid mapping for " + self.component)
           logger.warn("There is no service to pid mapping for " + self.component)
         status = self.LIVE_STATUS if serviceStatus else self.DEAD_STATUS
         status = self.LIVE_STATUS if serviceStatus else self.DEAD_STATUS

+ 9 - 3
ambari-agent/src/main/python/ambari_agent/PythonExecutor.py

@@ -48,16 +48,22 @@ class PythonExecutor:
     pass
     pass
 
 
   def run_file(self, script, script_params, tmpoutfile, tmperrfile, timeout,
   def run_file(self, script, script_params, tmpoutfile, tmperrfile, timeout,
-               tmpstructedoutfile):
+               tmpstructedoutfile, override_output_files = True):
     """
     """
     Executes the specified python file in a separate subprocess.
     Executes the specified python file in a separate subprocess.
     Method returns only when the subprocess is finished.
     Method returns only when the subprocess is finished.
     Params arg is a list of script parameters
     Params arg is a list of script parameters
     Timeout meaning: how many seconds should pass before script execution
     Timeout meaning: how many seconds should pass before script execution
     is forcibly terminated
     is forcibly terminated
+    override_output_files option defines whether stdout/stderr files will be
+    recreated or appended
     """
     """
-    tmpout =  open(tmpoutfile, 'w')
-    tmperr =  open(tmperrfile, 'w')
+    if override_output_files: # Recreate files
+      tmpout =  open(tmpoutfile, 'w')
+      tmperr =  open(tmperrfile, 'w')
+    else: # Append to files
+      tmpout =  open(tmpoutfile, 'a')
+      tmperr =  open(tmperrfile, 'a')
     script_params += [tmpstructedoutfile]
     script_params += [tmpstructedoutfile]
     pythonCommand = self.python_command(script, script_params)
     pythonCommand = self.python_command(script, script_params)
     logger.info("Running command " + pprint.pformat(pythonCommand))
     logger.info("Running command " + pprint.pformat(pythonCommand))

+ 16 - 0
ambari-agent/src/main/python/resource_management/core/exceptions.py

@@ -26,3 +26,19 @@ class Fail(Exception):
 
 
 class InvalidArgument(Fail):
 class InvalidArgument(Fail):
   pass
   pass
+
+class ClientComponentHasNoStatus(Fail):
+  """
+  Thrown when status() method is called for a CLIENT component.
+  The only valid status for CLIENT component is installed,
+  that's why exception is thrown and later silently processed at script.py
+  """
+  pass
+
+class ComponentIsNotRunning(Fail):
+  """
+  Thrown when status() method is called for a component (only
+  in situations when component process is not running).
+  Later exception is silently processed at script.py
+  """
+  pass

+ 1 - 0
ambari-agent/src/main/python/resource_management/libraries/functions/__init__.py

@@ -24,3 +24,4 @@ from resource_management.libraries.functions.default import *
 from resource_management.libraries.functions.format import *
 from resource_management.libraries.functions.format import *
 from resource_management.libraries.functions.get_kinit_path import *
 from resource_management.libraries.functions.get_kinit_path import *
 from resource_management.libraries.functions.get_unique_id_and_date import *
 from resource_management.libraries.functions.get_unique_id_and_date import *
+from resource_management.libraries.functions.check_process_status import *

+ 36 - 0
ambari-agent/src/main/python/resource_management/libraries/functions/check_process_status.py

@@ -0,0 +1,36 @@
+from resource_management.core.exceptions import ComponentIsNotRunning
+__all__ = ["check_process_status"]
+
+import os, logging
+
+log = logging.getLogger('resource_management')
+
+def check_process_status(pid_file):
+  """
+  Function checks whether process is running.
+  Process is considered running, if pid file exists, and process with
+  a pid, mentioned in pid file is running
+  If process is not running, will throw ComponentIsNotRunning exception
+
+  @param pid_file: path to service pid file
+  """
+  if not pid_file or not os.path.isfile(pid_file):
+    raise ComponentIsNotRunning()
+  with open(pid_file, "r") as f:
+    try:
+      pid = int(f.read())
+    except:
+      log.debug("Pid file {0} does not exist".format(pid_file))
+      raise ComponentIsNotRunning()
+    try:
+      # Kill will not actually kill the process
+      # From the doc:
+      # If sig is 0, then no signal is sent, but error checking is still
+      # performed; this can be used to check for the existence of a
+      # process ID or process group ID.
+      os.kill(pid, 0)
+    except OSError:
+      log.debug("Process with pid {0} is not running. Stale pid file"
+                " at {1}".format(pid, pid_file))
+      raise ComponentIsNotRunning()
+  pass

+ 2 - 1
ambari-agent/src/main/python/resource_management/libraries/script/__init__.py

@@ -21,4 +21,5 @@ Ambari Agent
 """
 """
 
 
 from resource_management.libraries.script.script import *
 from resource_management.libraries.script.script import *
-from resource_management.libraries.script.hook import *
+from resource_management.libraries.script.hook import *
+from resource_management.libraries.script.config_dictionary import *

+ 13 - 3
ambari-agent/src/main/python/resource_management/libraries/script/script.py

@@ -25,7 +25,7 @@ import json
 import logging
 import logging
 
 
 from resource_management.core.environment import Environment
 from resource_management.core.environment import Environment
-from resource_management.core.exceptions import Fail
+from resource_management.core.exceptions import Fail, ClientComponentHasNoStatus, ComponentIsNotRunning
 from resource_management.core.resources.packaging import Package
 from resource_management.core.resources.packaging import Package
 from resource_management.libraries.script.config_dictionary import ConfigDictionary
 from resource_management.libraries.script.config_dictionary import ConfigDictionary
 from resource_management.libraries.script.repo_installer import RepoInstaller
 from resource_management.libraries.script.repo_installer import RepoInstaller
@@ -35,8 +35,14 @@ class Script(object):
   Executes a command for custom service. stdout and stderr are written to
   Executes a command for custom service. stdout and stderr are written to
   tmpoutfile and to tmperrfile respectively.
   tmpoutfile and to tmperrfile respectively.
   Script instances share configuration as a class parameter and therefore
   Script instances share configuration as a class parameter and therefore
-  even different Script instances can not be used from different threads at
-  the same time
+  different Script instances can not be used from different threads at
+  the same time within a single python process
+
+  Accepted command line arguments mapping:
+  1 command type (START/STOP/...)
+  2 path to command json file
+  3 path to service metadata dir (Directory "package" inside service directory)
+  4 path to file with structured command output (file will be created)
   """
   """
   structuredOut = {}
   structuredOut = {}
 
 
@@ -87,6 +93,10 @@ class Script(object):
       method = self.choose_method_to_execute(command_name)
       method = self.choose_method_to_execute(command_name)
       with Environment(basedir) as env:
       with Environment(basedir) as env:
         method(env)
         method(env)
+    except ClientComponentHasNoStatus or ComponentIsNotRunning:
+      # Support of component status checks.
+      # Non-zero exit code is interpreted as an INSTALLED status of a component
+      sys.exit(1)
     except Fail:
     except Fail:
       logger.exception("Got exception while executing command {0}:".format(command_name))
       logger.exception("Got exception while executing command {0}:".format(command_name))
       sys.exit(1)
       sys.exit(1)

+ 18 - 2
ambari-agent/src/test/python/ambari_agent/TestActionQueue.py

@@ -354,20 +354,36 @@ class TestActionQueue(TestCase):
 
 
 
 
   @patch.object(ActionQueue, "status_update_callback")
   @patch.object(ActionQueue, "status_update_callback")
+  @patch.object(ActionQueue, "determine_command_format_version")
   @patch.object(StackVersionsFileHandler, "read_stack_version")
   @patch.object(StackVersionsFileHandler, "read_stack_version")
+  @patch.object(CustomServiceOrchestrator, "requestComponentStatus")
   @patch.object(ActionQueue, "execute_command")
   @patch.object(ActionQueue, "execute_command")
   @patch.object(LiveStatus, "build")
   @patch.object(LiveStatus, "build")
   def test_execute_status_command(self, build_mock, execute_command_mock,
   def test_execute_status_command(self, build_mock, execute_command_mock,
-                                  read_stack_version_mock,
+                                  requestComponentStatus_mock, read_stack_version_mock,
+                                  determine_command_format_version_mock,
                                   status_update_callback):
                                   status_update_callback):
     actionQueue = ActionQueue(AmbariConfig().getConfig(), 'dummy_controller')
     actionQueue = ActionQueue(AmbariConfig().getConfig(), 'dummy_controller')
+
     build_mock.return_value = "dummy report"
     build_mock.return_value = "dummy report"
-    # Try normal execution
+    # Check execution ov V1 status command
+    determine_command_format_version_mock.return_value = ActionQueue.COMMAND_FORMAT_V1
+    actionQueue.execute_status_command(self.status_command)
+    report = actionQueue.result()
+    expected = 'dummy report'
+    self.assertEqual(len(report['componentStatus']), 1)
+    self.assertEqual(report['componentStatus'][0], expected)
+    self.assertFalse(requestComponentStatus_mock.called)
+
+    # Check execution ov V2 status command
+    requestComponentStatus_mock.reset_mock()
+    determine_command_format_version_mock.return_value = ActionQueue.COMMAND_FORMAT_V2
     actionQueue.execute_status_command(self.status_command)
     actionQueue.execute_status_command(self.status_command)
     report = actionQueue.result()
     report = actionQueue.result()
     expected = 'dummy report'
     expected = 'dummy report'
     self.assertEqual(len(report['componentStatus']), 1)
     self.assertEqual(len(report['componentStatus']), 1)
     self.assertEqual(report['componentStatus'][0], expected)
     self.assertEqual(report['componentStatus'][0], expected)
+    self.assertTrue(requestComponentStatus_mock.called)
 
 
 
 
   def test_determine_command_format_version(self):
   def test_determine_command_format_version(self):

+ 65 - 7
ambari-agent/src/test/python/ambari_agent/TestCustomServiceOrchestrator.py

@@ -36,6 +36,7 @@ import StringIO
 import sys
 import sys
 from AgentException import AgentException
 from AgentException import AgentException
 from FileCache import FileCache
 from FileCache import FileCache
+from LiveStatus import LiveStatus
 
 
 
 
 class TestCustomServiceOrchestrator(TestCase):
 class TestCustomServiceOrchestrator(TestCase):
@@ -55,7 +56,9 @@ class TestCustomServiceOrchestrator(TestCase):
 
 
 
 
   @patch("hostname.public_hostname")
   @patch("hostname.public_hostname")
-  def test_dump_command_to_json(self, hostname_mock):
+  @patch("os.path.isfile")
+  @patch("os.unlink")
+  def test_dump_command_to_json(self, unlink_mock, isfile_mock, hostname_mock):
     hostname_mock.return_value = "test.hst"
     hostname_mock.return_value = "test.hst"
     command = {
     command = {
       'commandType': 'EXECUTION_COMMAND',
       'commandType': 'EXECUTION_COMMAND',
@@ -72,13 +75,25 @@ class TestCustomServiceOrchestrator(TestCase):
     tempdir = tempfile.gettempdir()
     tempdir = tempfile.gettempdir()
     config.set('agent', 'prefix', tempdir)
     config.set('agent', 'prefix', tempdir)
     orchestrator = CustomServiceOrchestrator(config)
     orchestrator = CustomServiceOrchestrator(config)
-    file = orchestrator.dump_command_to_json(command)
-    self.assertTrue(os.path.exists(file))
-    self.assertTrue(os.path.getsize(file) > 0)
-    self.assertEqual(oct(os.stat(file).st_mode & 0777), '0600')
-    os.unlink(file)
+    isfile_mock.return_value = True
+    # Test dumping EXECUTION_COMMAND
+    json_file = orchestrator.dump_command_to_json(command)
+    self.assertTrue(os.path.exists(json_file))
+    self.assertTrue(os.path.getsize(json_file) > 0)
+    self.assertEqual(oct(os.stat(json_file).st_mode & 0777), '0600')
+    self.assertTrue(json_file.endswith("command-3.json"))
+    os.unlink(json_file)
+    # Test dumping STATUS_COMMAND
+    command['commandType']='STATUS_COMMAND'
+    json_file = orchestrator.dump_command_to_json(command)
+    self.assertTrue(os.path.exists(json_file))
+    self.assertTrue(os.path.getsize(json_file) > 0)
+    self.assertEqual(oct(os.stat(json_file).st_mode & 0777), '0600')
+    self.assertTrue(json_file.endswith("status_command.json"))
+    os.unlink(json_file)
     # Testing side effect of dump_command_to_json
     # Testing side effect of dump_command_to_json
     self.assertEquals(command['public_hostname'], "test.hst")
     self.assertEquals(command['public_hostname'], "test.hst")
+    self.assertTrue(unlink_mock.called)
 
 
 
 
   @patch("os.path.exists")
   @patch("os.path.exists")
@@ -143,6 +158,25 @@ class TestCustomServiceOrchestrator(TestCase):
     self.assertEqual(run_file_mock.call_count, 3)
     self.assertEqual(run_file_mock.call_count, 3)
 
 
     run_file_mock.reset_mock()
     run_file_mock.reset_mock()
+
+    # Case when we force another command
+    run_file_mock.return_value = {
+        'stdout' : 'sss',
+        'stderr' : 'eee',
+        'exitcode': 0,
+      }
+    ret = orchestrator.runCommand(command, "out.txt", "err.txt",
+              forsed_command_name=CustomServiceOrchestrator.COMMAND_NAME_STATUS)
+    ## Check that override_output_files was true only during first call
+    self.assertEquals(run_file_mock.call_args_list[0][0][6], True)
+    self.assertEquals(run_file_mock.call_args_list[1][0][6], False)
+    self.assertEquals(run_file_mock.call_args_list[2][0][6], False)
+    ## Check that forsed_command_name was taken into account
+    self.assertEqual(run_file_mock.call_args_list[0][0][1][0],
+                                  CustomServiceOrchestrator.COMMAND_NAME_STATUS)
+
+    run_file_mock.reset_mock()
+
     # unknown script type case
     # unknown script type case
     command['commandParams']['script_type'] = "PUPPET"
     command['commandParams']['script_type'] = "PUPPET"
     ret = orchestrator.runCommand(command, "out.txt", "err.txt")
     ret = orchestrator.runCommand(command, "out.txt", "err.txt")
@@ -200,7 +234,31 @@ class TestCustomServiceOrchestrator(TestCase):
     res3 = orchestrator.resolve_hook_script_path("/hooks_dir/", "prefix", "command",
     res3 = orchestrator.resolve_hook_script_path("/hooks_dir/", "prefix", "command",
                                                  "script_type")
                                                  "script_type")
     self.assertEqual(res3, None)
     self.assertEqual(res3, None)
-    pass
+
+
+  @patch.object(CustomServiceOrchestrator, "runCommand")
+  def test_requestComponentStatus(self, runCommand_mock):
+    status_command = {
+      "serviceName" : 'HDFS',
+      "commandType" : "STATUS_COMMAND",
+      "clusterName" : "",
+      "componentName" : "DATANODE",
+      'configurations':{}
+    }
+    orchestrator = CustomServiceOrchestrator(self.config)
+    # Test alive case
+    runCommand_mock.return_value = {
+      "exitcode" : 0
+    }
+    status = orchestrator.requestComponentStatus(status_command)
+    self.assertEqual(LiveStatus.LIVE_STATUS, status)
+
+    # Test dead case
+    runCommand_mock.return_value = {
+      "exitcode" : 1
+    }
+    status = orchestrator.requestComponentStatus(status_command)
+    self.assertEqual(LiveStatus.DEAD_STATUS, status)
 
 
 
 
   def tearDown(self):
   def tearDown(self):

+ 12 - 0
ambari-agent/src/test/python/ambari_agent/TestLiveStatus.py

@@ -58,3 +58,15 @@ class TestLiveStatus(TestCase):
     result = livestatus.build()
     result = livestatus.build()
     self.assertTrue(len(result) > 0, 'Livestatus should not be empty')
     self.assertTrue(len(result) > 0, 'Livestatus should not be empty')
     self.assertTrue(result.has_key('configurationTags'))
     self.assertTrue(result.has_key('configurationTags'))
+    # Test build status with forsed_component_status
+    ## Alive
+    livestatus = LiveStatus('c1', 'HDFS', 'HDFS_CLIENT', { }, config)
+    result = livestatus.build(forsed_component_status = LiveStatus.LIVE_STATUS)
+    self.assertTrue(len(result) > 0, 'Livestatus should not be empty')
+    self.assertTrue(result['status'], LiveStatus.LIVE_STATUS)
+    ## Dead
+    livestatus = LiveStatus('c1', 'HDFS', 'HDFS_CLIENT', { }, config)
+    result = livestatus.build(forsed_component_status = LiveStatus.DEAD_STATUS)
+    self.assertTrue(len(result) > 0, 'Livestatus should not be empty')
+    self.assertTrue(result['status'], LiveStatus.DEAD_STATUS)
+

+ 0 - 1
ambari-agent/src/test/python/ambari_agent/TestPythonExecutor.py

@@ -136,7 +136,6 @@ class TestPythonExecutor(TestCase):
     self.assertTrue("python" in command[0])
     self.assertTrue("python" in command[0])
     self.assertEquals("script", command[1])
     self.assertEquals("script", command[1])
     self.assertEquals("script_param1", command[2])
     self.assertEquals("script_param1", command[2])
-    pprint.pprint(command)
 
 
 
 
   class Subprocess_mockup():
   class Subprocess_mockup():

+ 9 - 0
ambari-server/src/main/java/org/apache/ambari/server/RoleCommand.java

@@ -17,6 +17,15 @@
  */
  */
 package org.apache.ambari.server;
 package org.apache.ambari.server;
 
 
+public enum RoleCommand {
+
+  /*
+   * When adding/modifying enum members, please beware that except Java usages,
+   * RoleCommand string representations are used at role_command_order.json
+   * files
+   */
+
+
 public enum RoleCommand {
 public enum RoleCommand {
   INSTALL,
   INSTALL,
   UNINSTALL,
   UNINSTALL,

+ 1 - 0
ambari-server/src/main/java/org/apache/ambari/server/agent/ExecutionCommand.java

@@ -251,6 +251,7 @@ public class ExecutionCommand extends AgentCommand {
     String DB_DRIVER_FILENAME = "db_driver_filename";
     String DB_DRIVER_FILENAME = "db_driver_filename";
     String REPO_INFO = "repo_info";
     String REPO_INFO = "repo_info";
     String DB_NAME = "db_name";
     String DB_NAME = "db_name";
+    String GLOBAL = "global";
     String SERVICE_CHECK = "SERVICE_CHECK"; // TODO: is it standart command? maybe add it to RoleCommand enum?
     String SERVICE_CHECK = "SERVICE_CHECK"; // TODO: is it standart command? maybe add it to RoleCommand enum?
 
 
     String COMMAND_TIMEOUT_DEFAULT = "600"; // TODO: Will be replaced by proper initialization in another jira
     String COMMAND_TIMEOUT_DEFAULT = "600"; // TODO: Will be replaced by proper initialization in another jira

+ 85 - 50
ambari-server/src/main/java/org/apache/ambari/server/agent/HeartbeatMonitor.java

@@ -27,21 +27,14 @@ import com.google.inject.Injector;
 import org.apache.ambari.server.AmbariException;
 import org.apache.ambari.server.AmbariException;
 import org.apache.ambari.server.actionmanager.ActionManager;
 import org.apache.ambari.server.actionmanager.ActionManager;
 import org.apache.ambari.server.api.services.AmbariMetaInfo;
 import org.apache.ambari.server.api.services.AmbariMetaInfo;
-import org.apache.ambari.server.state.Cluster;
-import org.apache.ambari.server.state.Clusters;
-import org.apache.ambari.server.state.Config;
-import org.apache.ambari.server.state.ConfigHelper;
-import org.apache.ambari.server.state.Host;
-import org.apache.ambari.server.state.HostState;
-import org.apache.ambari.server.state.Service;
-import org.apache.ambari.server.state.ServiceComponent;
-import org.apache.ambari.server.state.ServiceComponentHost;
-import org.apache.ambari.server.state.State;
+import org.apache.ambari.server.state.*;
 import org.apache.ambari.server.state.fsm.InvalidStateTransitionException;
 import org.apache.ambari.server.state.fsm.InvalidStateTransitionException;
 import org.apache.ambari.server.state.host.HostHeartbeatLostEvent;
 import org.apache.ambari.server.state.host.HostHeartbeatLostEvent;
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 import org.apache.commons.logging.LogFactory;
 
 
+import static org.apache.ambari.server.agent.ExecutionCommand.KeyNames.*;
+
 /**
 /**
  * Monitors the node state and heartbeats.
  * Monitors the node state and heartbeats.
  */
  */
@@ -54,6 +47,7 @@ public class HeartbeatMonitor implements Runnable {
   private volatile boolean shouldRun = true;
   private volatile boolean shouldRun = true;
   private Thread monitorThread = null;
   private Thread monitorThread = null;
   private final ConfigHelper configHelper;
   private final ConfigHelper configHelper;
+  private final AmbariMetaInfo ambariMetaInfo;
 
 
   public HeartbeatMonitor(Clusters clusters, ActionQueue aq, ActionManager am,
   public HeartbeatMonitor(Clusters clusters, ActionQueue aq, ActionManager am,
                           int threadWakeupInterval, Injector injector) {
                           int threadWakeupInterval, Injector injector) {
@@ -62,6 +56,7 @@ public class HeartbeatMonitor implements Runnable {
     this.actionManager = am;
     this.actionManager = am;
     this.threadWakeupInterval = threadWakeupInterval;
     this.threadWakeupInterval = threadWakeupInterval;
     this.configHelper = injector.getInstance(ConfigHelper.class);
     this.configHelper = injector.getInstance(ConfigHelper.class);
+    this.ambariMetaInfo = injector.getInstance(AmbariMetaInfo.class);
   }
   }
 
 
   public void shutdown() {
   public void shutdown() {
@@ -176,58 +171,98 @@ public class HeartbeatMonitor implements Runnable {
 
 
     for (Cluster cl : clusters.getClustersForHost(hostname)) {
     for (Cluster cl : clusters.getClustersForHost(hostname)) {
       for (ServiceComponentHost sch : cl.getServiceComponentHosts(hostname)) {
       for (ServiceComponentHost sch : cl.getServiceComponentHosts(hostname)) {
-        String serviceName = sch.getServiceName();
-        Service service = cl.getService(sch.getServiceName());
-        ServiceComponent sc = service.getServiceComponent(sch
-          .getServiceComponentName());
-        // Send status commands for any components
-        if (LOG.isDebugEnabled()) {
-          LOG.debug("Live status will include status of service " + serviceName + " of cluster " + cl.getClusterName());
-        }
+        StatusCommand statusCmd = createStatusCommand(hostname, cl, sch);
+        cmds.add(statusCmd);
+      }
+    }
+    return cmds;
+  }
 
 
-        Map<String, Map<String, String>> configurations = new TreeMap<String, Map<String, String>>();
 
 
-        // get the cluster config for type 'global'
-        // apply config group overrides
+  /**
+   * Generates status command and fills all apropriate fields.
+   * @throws AmbariException
+   */
+  private StatusCommand createStatusCommand(String hostname, Cluster cluster,
+                               ServiceComponentHost sch) throws AmbariException {
+    String serviceName = sch.getServiceName();
+    String componentName = sch.getServiceComponentName();
+    Service service = cluster.getService(sch.getServiceName());
+    ServiceComponent sc = service.getServiceComponent(componentName);
+    StackId stackId = cluster.getDesiredStackVersion();
+    ServiceInfo serviceInfo = ambariMetaInfo.getServiceInfo(stackId.getStackName(),
+            stackId.getStackVersion(), serviceName);
+    ComponentInfo componentInfo = ambariMetaInfo.getComponent(
+            stackId.getStackName(), stackId.getStackVersion(),
+            serviceName, componentName);
 
 
-        Config clusterConfig = cl.getDesiredConfigByType("global");
-        if (clusterConfig != null) {
-          // cluster config for 'global'
-          Map<String, String> props = new HashMap<String, String>(clusterConfig.getProperties());
+    Map<String, Map<String, String>> configurations = new TreeMap<String, Map<String, String>>();
 
 
-          // Apply global properties for this host from all config groups
-          Map<String, Map<String, String>> allConfigTags = configHelper
-            .getEffectiveDesiredTags(cl, hostname);
+    // get the cluster config for type 'global'
+    // apply config group overrides
 
 
-          Map<String, Map<String, String>> configTags = new HashMap<String,
-            Map<String, String>>();
+    Config clusterConfig = cluster.getDesiredConfigByType(GLOBAL);
+    if (clusterConfig != null) {
+      // cluster config for 'global'
+      Map<String, String> props = new HashMap<String, String>(clusterConfig.getProperties());
 
 
-          for (Map.Entry<String, Map<String, String>> entry : allConfigTags.entrySet()) {
-            if (entry.getKey().equals("global")) {
-              configTags.put("global", entry.getValue());
-            }
-          }
+      // Apply global properties for this host from all config groups
+      Map<String, Map<String, String>> allConfigTags = configHelper
+              .getEffectiveDesiredTags(cluster, hostname);
 
 
-          Map<String, Map<String, String>> properties = configHelper
-            .getEffectiveConfigProperties(cl, configTags);
+      Map<String, Map<String, String>> configTags = new HashMap<String,
+              Map<String, String>>();
 
 
-          if (!properties.isEmpty()) {
-            for (Map<String, String> propertyMap : properties.values()) {
-              props.putAll(propertyMap);
-            }
-          }
+      for (Map.Entry<String, Map<String, String>> entry : allConfigTags.entrySet()) {
+        if (entry.getKey().equals(GLOBAL)) {
+          configTags.put(GLOBAL, entry.getValue());
+        }
+      }
 
 
-          configurations.put("global", props);
+      Map<String, Map<String, String>> properties = configHelper
+              .getEffectiveConfigProperties(cluster, configTags);
+
+      if (!properties.isEmpty()) {
+        for (Map<String, String> propertyMap : properties.values()) {
+          props.putAll(propertyMap);
         }
         }
+      }
 
 
-        StatusCommand statusCmd = new StatusCommand();
-        statusCmd.setClusterName(cl.getClusterName());
-        statusCmd.setServiceName(serviceName);
-        statusCmd.setComponentName(sch.getServiceComponentName());
-        statusCmd.setConfigurations(configurations);
-        cmds.add(statusCmd);
+      configurations.put(GLOBAL, props);
+    }
+
+    StatusCommand statusCmd = new StatusCommand();
+    statusCmd.setClusterName(cluster.getClusterName());
+    statusCmd.setServiceName(serviceName);
+    statusCmd.setComponentName(componentName);
+    statusCmd.setConfigurations(configurations);
+
+    // Fill command params
+    Map<String, String> commandParams = statusCmd.getCommandParams();
+    commandParams.put(SCHEMA_VERSION, serviceInfo.getSchemaVersion());
+
+    String commandTimeout = ExecutionCommand.KeyNames.COMMAND_TIMEOUT_DEFAULT;
+    CommandScriptDefinition script = componentInfo.getCommandScript();
+    if (serviceInfo.getSchemaVersion().equals(AmbariMetaInfo.SCHEMA_VERSION_2)) {
+      if (script != null) {
+        commandParams.put(SCRIPT, script.getScript());
+        commandParams.put(SCRIPT_TYPE, script.getScriptType().toString());
+        commandTimeout = String.valueOf(script.getTimeout());
+      } else {
+        String message = String.format("Component %s of service %s has not " +
+                "command script defined", componentName, serviceName);
+        throw new AmbariException(message);
       }
       }
     }
     }
-    return cmds;
+    commandParams.put(COMMAND_TIMEOUT, commandTimeout);
+    commandParams.put(SERVICE_METADATA_FOLDER,
+       serviceInfo.getServiceMetadataFolder());
+    // Fill host level params
+    Map<String, String> hostLevelParams = statusCmd.getHostLevelParams();
+    hostLevelParams.put(STACK_NAME, stackId.getStackName());
+    hostLevelParams.put(STACK_VERSION, stackId.getStackVersion());
+
+    return statusCmd;
   }
   }
+
 }
 }

+ 24 - 0
ambari-server/src/main/java/org/apache/ambari/server/agent/StatusCommand.java

@@ -17,6 +17,7 @@
  */
  */
 package org.apache.ambari.server.agent;
 package org.apache.ambari.server.agent;
 
 
+import java.util.HashMap;
 import java.util.List;
 import java.util.List;
 import java.util.Map;
 import java.util.Map;
 
 
@@ -35,6 +36,8 @@ public class StatusCommand extends AgentCommand {
   private String serviceName;
   private String serviceName;
   private String componentName;
   private String componentName;
   private Map<String, Map<String, String>> configurations;
   private Map<String, Map<String, String>> configurations;
+  private Map<String, String> commandParams = new HashMap<String, String>();
+  private Map<String, String> hostLevelParams = new HashMap<String, String>();
 
 
   @JsonProperty("clusterName")
   @JsonProperty("clusterName")
   public String getClusterName() {
   public String getClusterName() {
@@ -75,4 +78,25 @@ public class StatusCommand extends AgentCommand {
   public void setConfigurations(Map<String, Map<String, String>> configurations) {
   public void setConfigurations(Map<String, Map<String, String>> configurations) {
     this.configurations = configurations;
     this.configurations = configurations;
   }
   }
+
+  @JsonProperty("hostLevelParams")
+  public Map<String, String> getHostLevelParams() {
+    return hostLevelParams;
+  }
+
+  @JsonProperty("hostLevelParams")
+  public void setHostLevelParams(Map<String, String> params) {
+    this.hostLevelParams = params;
+  }
+
+  @JsonProperty("commandParams")
+  public Map<String, String> getCommandParams() {
+    return commandParams;
+  }
+
+  @JsonProperty("commandParams")
+  public void setCommandParams(Map<String, String> commandParams) {
+    this.commandParams = commandParams;
+  }
+
 }
 }

+ 30 - 0
ambari-server/src/main/resources/stacks/HDP/1.3._/hooks/before-START.py

@@ -0,0 +1,30 @@
+##!/usr/bin/env python2.6
+"""
+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.
+
+"""
+
+import sys
+from resource_management import *
+
+class BeforeStartHook(Hook):
+
+  def hook(self, env):
+    Execute(("touch", "/tmp/hook-test"))
+
+if __name__ == "__main__":
+  BeforeStartHook().execute()

+ 17 - 0
ambari-server/src/main/resources/stacks/HDP/1.3._/services/GANGLIA/package/scripts/ganglia_monitor.py

@@ -39,6 +39,23 @@ class GangliaMonitor(Script):
   def stop(self, env):
   def stop(self, env):
     ganglia_monitor_service.monitor("stop")
     ganglia_monitor_service.monitor("stop")
 
 
+
+  def status(self, env):
+    import status_params
+    pid_file_name = 'gmond.pid'
+    pid_file_count = 0
+    pid_dir = status_params.pid_dir
+    # Recursively check all existing gmond pid files
+    for cur_dir, subdirs, files in os.walk(pid_dir):
+      for file_name in files:
+        if file_name == pid_file_name:
+          pid_file = os.path.join(cur_dir, file_name)
+          check_process_status(pid_file)
+          pid_file_count += 1
+    if pid_file_count == 0: # If no any pid file is present
+      raise ComponentIsNotRunning()
+
+
   def config(self, env):
   def config(self, env):
     import params
     import params
 
 

+ 7 - 0
ambari-server/src/main/resources/stacks/HDP/1.3._/services/GANGLIA/package/scripts/ganglia_server.py

@@ -45,6 +45,13 @@ class GangliaServer(Script):
     env.set_params(params)
     env.set_params(params)
     ganglia_server_service.server("stop")
     ganglia_server_service.server("stop")
 
 
+  def status(self, env):
+    import status_params
+    env.set_params(status_params)
+    pid_file = format("{pid_dir}/gmetad.pid")
+    # Recursively check all existing gmetad pid files
+    check_process_status(pid_file)
+
   def config(self, env):
   def config(self, env):
     import params
     import params
 
 

+ 25 - 0
ambari-server/src/main/resources/stacks/HDP/1.3._/services/GANGLIA/package/scripts/status_params.py

@@ -0,0 +1,25 @@
+#!/usr/bin/env python
+"""
+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.
+
+"""
+
+from resource_management import *
+
+config = Script.get_config()
+
+pid_dir = config['configurations']['global']['ganglia_runtime_dir']

+ 3 - 0
ambari-server/src/main/resources/stacks/HDP/1.3._/services/SQOOP/package/scripts/sqoop_client.py

@@ -33,5 +33,8 @@ class SqoopClient(Script):
     env.set_params(params)
     env.set_params(params)
     sqoop(type='client')
     sqoop(type='client')
 
 
+  def status(self, env):
+    raise ClientComponentHasNoStatus()
+
 if __name__ == "__main__":
 if __name__ == "__main__":
   SqoopClient().execute()
   SqoopClient().execute()

+ 17 - 0
ambari-server/src/main/resources/stacks/HDP/2.0._/services/GANGLIA/package/scripts/ganglia_monitor.py

@@ -39,6 +39,23 @@ class GangliaMonitor(Script):
   def stop(self, env):
   def stop(self, env):
     ganglia_monitor_service.monitor("stop")
     ganglia_monitor_service.monitor("stop")
 
 
+
+  def status(self, env):
+    import status_params
+    pid_file_name = 'gmond.pid'
+    pid_file_count = 0
+    pid_dir = status_params.pid_dir
+    # Recursively check all existing gmond pid files
+    for cur_dir, subdirs, files in os.walk(pid_dir):
+      for file_name in files:
+        if file_name == pid_file_name:
+          pid_file = os.path.join(cur_dir, file_name)
+          check_process_status(pid_file)
+          pid_file_count += 1
+    if pid_file_count == 0: # If no any pid file is present
+      raise ComponentIsNotRunning()
+
+
   def config(self, env):
   def config(self, env):
     import params
     import params
 
 

+ 7 - 0
ambari-server/src/main/resources/stacks/HDP/2.0._/services/GANGLIA/package/scripts/ganglia_server.py

@@ -45,6 +45,13 @@ class GangliaServer(Script):
     env.set_params(params)
     env.set_params(params)
     ganglia_server_service.server("stop")
     ganglia_server_service.server("stop")
 
 
+  def status(self, env):
+    import status_params
+    env.set_params(status_params)
+    pid_file = format("{pid_dir}/gmetad.pid")
+    # Recursively check all existing gmetad pid files
+    check_process_status(pid_file)
+
   def config(self, env):
   def config(self, env):
     import params
     import params
 
 

+ 25 - 0
ambari-server/src/main/resources/stacks/HDP/2.0._/services/GANGLIA/package/scripts/status_params.py

@@ -0,0 +1,25 @@
+#!/usr/bin/env python
+"""
+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.
+
+"""
+
+from resource_management import *
+
+config = Script.get_config()
+
+pid_dir = config['configurations']['global']['ganglia_runtime_dir']

+ 0 - 2
ambari-server/src/main/resources/stacks/HDP/2.0._/services/HBASE/package/scripts/__init__.py

@@ -16,6 +16,4 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 See the License for the specific language governing permissions and
 See the License for the specific language governing permissions and
 limitations under the License.
 limitations under the License.
 
 
-Ambari Agent
-
 """
 """

+ 0 - 2
ambari-server/src/main/resources/stacks/HDP/2.0._/services/HBASE/package/scripts/functions.py

@@ -16,8 +16,6 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 See the License for the specific language governing permissions and
 See the License for the specific language governing permissions and
 limitations under the License.
 limitations under the License.
 
 
-Ambari Agent
-
 """
 """
 
 
 import os
 import os

+ 0 - 2
ambari-server/src/main/resources/stacks/HDP/2.0._/services/HBASE/package/scripts/hbase.py

@@ -16,8 +16,6 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 See the License for the specific language governing permissions and
 See the License for the specific language governing permissions and
 limitations under the License.
 limitations under the License.
 
 
-Ambari Agent
-
 """
 """
 
 
 from resource_management import *
 from resource_management import *

+ 4 - 3
ambari-server/src/main/resources/stacks/HDP/2.0._/services/HBASE/package/scripts/hbase_client.py

@@ -16,8 +16,6 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 See the License for the specific language governing permissions and
 See the License for the specific language governing permissions and
 limitations under the License.
 limitations under the License.
 
 
-Ambari Agent
-
 """
 """
 
 
 import sys
 import sys
@@ -36,7 +34,10 @@ class HbaseClient(Script):
     env.set_params(params)
     env.set_params(params)
     
     
     hbase(type='client')
     hbase(type='client')
-    
+
+  def status(self, env):
+    raise ClientComponentHasNoStatus()
+
 #for tests
 #for tests
 def main():
 def main():
   command_type = 'install'
   command_type = 'install'

+ 7 - 3
ambari-server/src/main/resources/stacks/HDP/2.0._/services/HBASE/package/scripts/hbase_master.py

@@ -16,8 +16,6 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 See the License for the specific language governing permissions and
 See the License for the specific language governing permissions and
 limitations under the License.
 limitations under the License.
 
 
-Ambari Agent
-
 """
 """
 
 
 import sys
 import sys
@@ -53,7 +51,13 @@ class HbaseMaster(Script):
     hbase_service( 'master',
     hbase_service( 'master',
       action = 'stop'
       action = 'stop'
     )
     )
-    
+
+  def status(self, env):
+    import status_params
+    env.set_params(status_params)
+    pid_file = format("{pid_dir}/hbase-hbase-master.pid")
+    check_process_status(pid_file)
+
 def main():
 def main():
   command_type = sys.argv[1] if len(sys.argv)>1 else "install"
   command_type = sys.argv[1] if len(sys.argv)>1 else "install"
   print "Running "+command_type
   print "Running "+command_type

+ 6 - 2
ambari-server/src/main/resources/stacks/HDP/2.0._/services/HBASE/package/scripts/hbase_regionserver.py

@@ -16,8 +16,6 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 See the License for the specific language governing permissions and
 See the License for the specific language governing permissions and
 limitations under the License.
 limitations under the License.
 
 
-Ambari Agent
-
 """
 """
 
 
 import sys
 import sys
@@ -53,6 +51,12 @@ class HbaseRegionServer(Script):
     hbase_service( 'regionserver',
     hbase_service( 'regionserver',
       action = 'stop'
       action = 'stop'
     )
     )
+
+  def status(self, env):
+    import status_params
+    env.set_params(status_params)
+    pid_file = format("{pid_dir}/hbase-hbase-regionserver.pid")
+    check_process_status(pid_file)
     
     
   def decommission(self):
   def decommission(self):
     print "Decommission not yet implemented!"
     print "Decommission not yet implemented!"

+ 2 - 4
ambari-server/src/main/resources/stacks/HDP/2.0._/services/HBASE/package/scripts/hbase_service.py

@@ -16,15 +16,13 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 See the License for the specific language governing permissions and
 See the License for the specific language governing permissions and
 limitations under the License.
 limitations under the License.
 
 
-Ambari Agent
-
 """
 """
 
 
 from resource_management import *
 from resource_management import *
 
 
 def hbase_service(
 def hbase_service(
   name,
   name,
-  action = 'start'): # 'start' or 'stop'
+  action = 'start'): # 'start' or 'stop' or 'status'
     
     
     import params
     import params
   
   
@@ -40,7 +38,7 @@ def hbase_service(
       no_op_test = format("ls {pid_file} >/dev/null 2>&1 && ps `cat {pid_file}` >/dev/null 2>&1")
       no_op_test = format("ls {pid_file} >/dev/null 2>&1 && ps `cat {pid_file}` >/dev/null 2>&1")
     elif action == 'stop':
     elif action == 'stop':
       daemon_cmd = format("{cmd} stop {role} && rm -f {pid_file}")
       daemon_cmd = format("{cmd} stop {role} && rm -f {pid_file}")
-  
+
     if daemon_cmd is not None:
     if daemon_cmd is not None:
       Execute ( daemon_cmd,
       Execute ( daemon_cmd,
         not_if = no_op_test,
         not_if = no_op_test,

+ 2 - 3
ambari-server/src/main/resources/stacks/HDP/2.0._/services/HBASE/package/scripts/params.py

@@ -16,12 +16,11 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 See the License for the specific language governing permissions and
 See the License for the specific language governing permissions and
 limitations under the License.
 limitations under the License.
 
 
-Ambari Agent
-
 """
 """
 
 
 from resource_management import *
 from resource_management import *
 import functions
 import functions
+import status_params
 
 
 # server configurations
 # server configurations
 config = Script.get_config()
 config = Script.get_config()
@@ -46,7 +45,7 @@ master_heapsize = config['configurations']['global']['hbase_master_heapsize']
 regionserver_heapsize = config['configurations']['global']['hbase_regionserver_heapsize']
 regionserver_heapsize = config['configurations']['global']['hbase_regionserver_heapsize']
 regionserver_xmn_size = functions.calc_xmn_from_xms(regionserver_heapsize, 0.2, 512)
 regionserver_xmn_size = functions.calc_xmn_from_xms(regionserver_heapsize, 0.2, 512)
 
 
-pid_dir = config['configurations']['global']['hbase_pid_dir']
+pid_dir = status_params.pid_dir
 tmp_dir = config['configurations']['hbase-site']['hbase.tmp.dir']
 tmp_dir = config['configurations']['hbase-site']['hbase.tmp.dir']
 
 
 client_jaas_config_file = default('hbase_client_jaas_config_file', format("{conf_dir}/hbase_client_jaas.conf"))
 client_jaas_config_file = default('hbase_client_jaas_config_file', format("{conf_dir}/hbase_client_jaas.conf"))

+ 0 - 2
ambari-server/src/main/resources/stacks/HDP/2.0._/services/HBASE/package/scripts/service_check.py

@@ -16,8 +16,6 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 See the License for the specific language governing permissions and
 See the License for the specific language governing permissions and
 limitations under the License.
 limitations under the License.
 
 
-Ambari Agent
-
 """
 """
 
 
 from resource_management import *
 from resource_management import *

+ 25 - 0
ambari-server/src/main/resources/stacks/HDP/2.0._/services/HBASE/package/scripts/status_params.py

@@ -0,0 +1,25 @@
+#!/usr/bin/env python
+"""
+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.
+
+"""
+
+from resource_management import *
+
+config = Script.get_config()
+
+pid_dir = config['configurations']['global']['hbase_pid_dir']

+ 0 - 2
ambari-server/src/main/resources/stacks/HDP/2.0._/services/HIVE/package/scripts/__init__.py

@@ -16,6 +16,4 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 See the License for the specific language governing permissions and
 See the License for the specific language governing permissions and
 limitations under the License.
 limitations under the License.
 
 
-Ambari Agent
-
 """
 """

+ 0 - 2
ambari-server/src/main/resources/stacks/HDP/2.0._/services/HIVE/package/scripts/hcat.py

@@ -16,8 +16,6 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 See the License for the specific language governing permissions and
 See the License for the specific language governing permissions and
 limitations under the License.
 limitations under the License.
 
 
-Ambari Agent
-
 """
 """
 
 
 from resource_management import *
 from resource_management import *

+ 4 - 2
ambari-server/src/main/resources/stacks/HDP/2.0._/services/HIVE/package/scripts/hcat_client.py

@@ -16,8 +16,6 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 See the License for the specific language governing permissions and
 See the License for the specific language governing permissions and
 limitations under the License.
 limitations under the License.
 
 
-Ambari Agent
-
 """
 """
 
 
 import sys
 import sys
@@ -37,5 +35,9 @@ class HCatClient(Script):
     hcat()
     hcat()
 
 
 
 
+  def status(self, env):
+    raise ClientComponentHasNoStatus()
+
+
 if __name__ == "__main__":
 if __name__ == "__main__":
   HCatClient().execute()
   HCatClient().execute()

+ 0 - 2
ambari-server/src/main/resources/stacks/HDP/2.0._/services/HIVE/package/scripts/hcat_service_check.py

@@ -16,8 +16,6 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 See the License for the specific language governing permissions and
 See the License for the specific language governing permissions and
 limitations under the License.
 limitations under the License.
 
 
-Ambari Agent
-
 """
 """
 
 
 from resource_management import *
 from resource_management import *

+ 0 - 2
ambari-server/src/main/resources/stacks/HDP/2.0._/services/HIVE/package/scripts/hive.py

@@ -16,8 +16,6 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 See the License for the specific language governing permissions and
 See the License for the specific language governing permissions and
 limitations under the License.
 limitations under the License.
 
 
-Ambari Agent
-
 """
 """
 
 
 from resource_management import *
 from resource_management import *

+ 5 - 2
ambari-server/src/main/resources/stacks/HDP/2.0._/services/HIVE/package/scripts/hive_client.py

@@ -16,8 +16,6 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 See the License for the specific language governing permissions and
 See the License for the specific language governing permissions and
 limitations under the License.
 limitations under the License.
 
 
-Ambari Agent
-
 """
 """
 import sys
 import sys
 from resource_management import *
 from resource_management import *
@@ -28,11 +26,16 @@ class HiveClient(Script):
   def install(self, env):
   def install(self, env):
     self.install_packages(env)
     self.install_packages(env)
     self.configure(env)
     self.configure(env)
+
   def configure(self, env):
   def configure(self, env):
     import params
     import params
     env.set_params(params)
     env.set_params(params)
 
 
     hive(type='client')
     hive(type='client')
 
 
+
+  def status(self, env):
+    raise ClientComponentHasNoStatus()
+
 if __name__ == "__main__":
 if __name__ == "__main__":
   HiveClient().execute()
   HiveClient().execute()

+ 8 - 2
ambari-server/src/main/resources/stacks/HDP/2.0._/services/HIVE/package/scripts/hive_metastore.py

@@ -16,8 +16,6 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 See the License for the specific language governing permissions and
 See the License for the specific language governing permissions and
 limitations under the License.
 limitations under the License.
 
 
-Ambari Agent
-
 """
 """
 
 
 import sys
 import sys
@@ -27,6 +25,7 @@ from hive import hive
 from hive_service import hive_service
 from hive_service import hive_service
 
 
 class HiveMetastore(Script):
 class HiveMetastore(Script):
+
   def install(self, env):
   def install(self, env):
     self.install_packages(env)
     self.install_packages(env)
     self.configure(env)
     self.configure(env)
@@ -53,5 +52,12 @@ class HiveMetastore(Script):
                    action = 'stop'
                    action = 'stop'
     )
     )
 
 
+  def status(self, env):
+    import status_params
+    env.set_params(status_params)
+    pid_file = format("{hive_pid_dir}/{hive_metastore_pid}")
+    # Recursively check all existing gmetad pid files
+    check_process_status(pid_file)
+
 if __name__ == "__main__":
 if __name__ == "__main__":
   HiveMetastore().execute()
   HiveMetastore().execute()

+ 9 - 2
ambari-server/src/main/resources/stacks/HDP/2.0._/services/HIVE/package/scripts/hive_server.py

@@ -16,8 +16,6 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 See the License for the specific language governing permissions and
 See the License for the specific language governing permissions and
 limitations under the License.
 limitations under the License.
 
 
-Ambari Agent
-
 """
 """
 
 
 import sys
 import sys
@@ -27,6 +25,7 @@ from hive import hive
 from hive_service import hive_service
 from hive_service import hive_service
 
 
 class HiveServer(Script):
 class HiveServer(Script):
+
   def install(self, env):
   def install(self, env):
     self.install_packages(env)
     self.install_packages(env)
     self.configure(env)
     self.configure(env)
@@ -52,5 +51,13 @@ class HiveServer(Script):
                   action = 'stop'
                   action = 'stop'
     )
     )
 
 
+
+  def status(self, env):
+    import status_params
+    env.set_params(status_params)
+    pid_file = format("{hive_pid_dir}/{hive_pid}")
+    # Recursively check all existing gmetad pid files
+    check_process_status(pid_file)
+
 if __name__ == "__main__":
 if __name__ == "__main__":
   HiveServer().execute()
   HiveServer().execute()

+ 1 - 3
ambari-server/src/main/resources/stacks/HDP/2.0._/services/HIVE/package/scripts/hive_service.py

@@ -16,8 +16,6 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 See the License for the specific language governing permissions and
 See the License for the specific language governing permissions and
 limitations under the License.
 limitations under the License.
 
 
-Ambari Agent
-
 """
 """
 
 
 from resource_management import *
 from resource_management import *
@@ -30,7 +28,7 @@ def hive_service(
   import params
   import params
 
 
   if name == 'metastore':
   if name == 'metastore':
-    pid_file = format("{hive_pid_dir}/hive.pid")
+    pid_file = format("{hive_pid_dir}/{hive_metastore_pid}")
     cmd = format(
     cmd = format(
       "env HADOOP_HOME={hadoop_home} JAVA_HOME={java64_home} {start_metastore_path} {hive_log_dir}/hive.out {hive_log_dir}/hive.log {pid_file} {hive_server_conf_dir}")
       "env HADOOP_HOME={hadoop_home} JAVA_HOME={java64_home} {start_metastore_path} {hive_log_dir}/hive.out {hive_log_dir}/hive.log {pid_file} {hive_server_conf_dir}")
   elif name == 'hiveserver2':
   elif name == 'hiveserver2':

+ 0 - 58
ambari-server/src/main/resources/stacks/HDP/2.0._/services/HIVE/package/scripts/mysql.py

@@ -1,58 +0,0 @@
-#!/usr/bin/env python
-"""
-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.
-
-Ambari Agent
-
-"""
-
-from resource_management import *
-import sys
-from mysql_service import *
-
-def mysql():
-  import params
-
-  if System.get_instance().platform == "suse":
-    Directory('/var/run/mysqld/',
-              owner=params.mysql_user,
-              group=params.mysql_group,
-              recursive=True
-    )
-
-    Link('/var/run/mysqld/mysqld.pid',
-         to='/var/lib/mysql/mysqld.pid')
-
-  mysql_service(action='start')
-
-  File(params.mysql_adduser_path,
-       mode=0755,
-       content=StaticFile('addMysqlUser.sh')
-  )
-
-  # Autoescaping
-  cmd = ("bash", "-x", params.mysql_adduser_path, params.service_name, 
-         params.hive_metastore_user_name, params.hive_metastore_user_passwd, params.mysql_host[0])
-  
-  Execute(cmd,
-          tries=3,
-          try_sleep=5,
-          path='/usr/sbin:/sbin:/usr/local/bin:/bin:/usr/bin',
-          logoutput=True
-  )
-
-  mysql_service(action='stop')

+ 31 - 6
ambari-server/src/main/resources/stacks/HDP/2.0._/services/HIVE/package/scripts/mysql_server.py

@@ -16,17 +16,20 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 See the License for the specific language governing permissions and
 See the License for the specific language governing permissions and
 limitations under the License.
 limitations under the License.
 
 
-Ambari Agent
-
 """
 """
 
 
 import sys
 import sys
 from resource_management import *
 from resource_management import *
 
 
-from mysql import mysql
 from mysql_service import mysql_service
 from mysql_service import mysql_service
 
 
 class MysqlServer(Script):
 class MysqlServer(Script):
+
+  if System.get_instance().platform == "suse":
+    daemon_name = 'mysql'
+  else:
+    daemon_name = 'mysqld'
+
   def install(self, env):
   def install(self, env):
     self.install_packages(env)
     self.install_packages(env)
     self.configure(env)
     self.configure(env)
@@ -34,19 +37,41 @@ class MysqlServer(Script):
   def configure(self, env):
   def configure(self, env):
     import params
     import params
     env.set_params(params)
     env.set_params(params)
-    mysql()
+
+    mysql_service(daemon_name=self.daemon_name, action='start')
+
+    File(params.mysql_adduser_path,
+         mode=0755,
+         content=StaticFile('addMysqlUser.sh')
+    )
+
+    # Autoescaping
+    cmd = ("bash", "-x", params.mysql_adduser_path, self.daemon_name,
+           params.hive_metastore_user_name, params.hive_metastore_user_passwd, params.mysql_host[0])
+
+    Execute(cmd,
+            tries=3,
+            try_sleep=5,
+            path='/usr/sbin:/sbin:/usr/local/bin:/bin:/usr/bin',
+            logoutput=True
+    )
+
+    mysql_service(daemon_name=self.daemon_name, action='stop')
 
 
   def start(self, env):
   def start(self, env):
     import params
     import params
     env.set_params(params)
     env.set_params(params)
 
 
-    mysql_service(action = 'start')
+    mysql_service(daemon_name=self.daemon_name, action = 'start')
 
 
   def stop(self, env):
   def stop(self, env):
     import params
     import params
     env.set_params(params)
     env.set_params(params)
 
 
-    mysql_service(action = 'stop')
+    mysql_service(daemon_name=self.daemon_name, action = 'stop')
+
+  def status(self, env):
+    mysql_service(daemon_name=self.daemon_name, action = 'status')
 
 
 if __name__ == "__main__":
 if __name__ == "__main__":
   MysqlServer().execute()
   MysqlServer().execute()

+ 12 - 8
ambari-server/src/main/resources/stacks/HDP/2.0._/services/HIVE/package/scripts/mysql_service.py

@@ -16,25 +16,29 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 See the License for the specific language governing permissions and
 See the License for the specific language governing permissions and
 limitations under the License.
 limitations under the License.
 
 
-Ambari Agent
-
 """
 """
 
 
 from resource_management import *
 from resource_management import *
 
 
 
 
-def mysql_service(action='start'):
-
-  import params
+def mysql_service(daemon_name=None, action='start'):
 
 
+  logoutput=True
   if action == 'start':
   if action == 'start':
-    cmd = format('service {service_name} start')
+    cmd = format('service {daemon_name} start')
   elif action == 'stop':
   elif action == 'stop':
-    cmd = format('service {service_name} stop')
+    cmd = format('service {daemon_name} stop')
+  elif action == 'status':
+    cmd = format('service {daemon_name} status')
+    logoutput = False
   else:
   else:
     cmd = None
     cmd = None
 
 
   if cmd is not None:
   if cmd is not None:
     Execute(cmd,
     Execute(cmd,
             path="/usr/local/bin/:/bin/:/sbin/",
             path="/usr/local/bin/:/bin/:/sbin/",
-            logoutput=True)
+            tries=1,
+            logoutput=logoutput)
+
+
+

+ 5 - 12
ambari-server/src/main/resources/stacks/HDP/2.0._/services/HIVE/package/scripts/params.py

@@ -16,11 +16,10 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 See the License for the specific language governing permissions and
 See the License for the specific language governing permissions and
 limitations under the License.
 limitations under the License.
 
 
-Ambari Agent
-
 """
 """
 
 
 from resource_management import *
 from resource_management import *
+import status_params
 
 
 # server configurations
 # server configurations
 config = Script.get_config()
 config = Script.get_config()
@@ -64,8 +63,8 @@ hive_metastore_keytab_path =  config['configurations']['hive-site']['hive.metast
 hive_conf_dir = "/etc/hive/conf"
 hive_conf_dir = "/etc/hive/conf"
 hive_dbroot = config['configurations']['global']['hive_dbroot']
 hive_dbroot = config['configurations']['global']['hive_dbroot']
 hive_log_dir = config['configurations']['global']['hive_log_dir']
 hive_log_dir = config['configurations']['global']['hive_log_dir']
-hive_pid_dir = config['configurations']['global']['hive_pid_dir']
-hive_pid = 'hive-server.pid'
+hive_pid_dir = status_params.hive_pid_dir
+hive_pid = status_params.hive_pid
 
 
 #hive-site
 #hive-site
 hive_database_name = config['configurations']['global']['hive_database_name']
 hive_database_name = config['configurations']['global']['hive_database_name']
@@ -77,7 +76,7 @@ hadoop_home = '/usr'
 
 
 ##Starting metastore
 ##Starting metastore
 start_metastore_script = 'startMetastore.sh'
 start_metastore_script = 'startMetastore.sh'
-
+hive_metastore_pid = status_params.hive_metastore_pid
 java_share_dir = '/usr/share/java'
 java_share_dir = '/usr/share/java'
 driver_curl_target = format("{java_share_dir}/{jdbc_jar_name}")
 driver_curl_target = format("{java_share_dir}/{jdbc_jar_name}")
 
 
@@ -106,12 +105,6 @@ mysql_host = config['clusterHostInfo']['hive_mysql_host']
 
 
 mysql_adduser_path = "/tmp/addMysqlUser.sh"
 mysql_adduser_path = "/tmp/addMysqlUser.sh"
 
 
-if System.get_instance().platform == "suse":
-  service_name = 'mysql'
-else:
-  service_name = 'mysqld'
-
-
 ########## HCAT
 ########## HCAT
 
 
 hcat_conf_dir = '/etc/hcatalog/conf'
 hcat_conf_dir = '/etc/hcatalog/conf'
@@ -124,7 +117,7 @@ hcat_dbroot = hcat_lib
 hcat_user = config['configurations']['global']['hcat_user']
 hcat_user = config['configurations']['global']['hcat_user']
 webhcat_user = config['configurations']['global']['webhcat_user']
 webhcat_user = config['configurations']['global']['webhcat_user']
 
 
-hcat_pid_dir = config['configurations']['global']['hcat_pid_dir']   #hcat_pid_dir
+hcat_pid_dir = status_params.hcat_pid_dir
 hcat_log_dir = config['configurations']['global']['hcat_log_dir']   #hcat_log_dir
 hcat_log_dir = config['configurations']['global']['hcat_log_dir']   #hcat_log_dir
 
 
 hadoop_conf_dir = '/etc/hadoop/conf'
 hadoop_conf_dir = '/etc/hadoop/conf'

+ 0 - 2
ambari-server/src/main/resources/stacks/HDP/2.0._/services/HIVE/package/scripts/service_check.py

@@ -16,8 +16,6 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 See the License for the specific language governing permissions and
 See the License for the specific language governing permissions and
 limitations under the License.
 limitations under the License.
 
 
-Ambari Agent
-
 """
 """
 
 
 from resource_management import *
 from resource_management import *

+ 30 - 0
ambari-server/src/main/resources/stacks/HDP/2.0._/services/HIVE/package/scripts/status_params.py

@@ -0,0 +1,30 @@
+#!/usr/bin/env python
+"""
+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.
+
+"""
+
+from resource_management import *
+
+config = Script.get_config()
+
+hive_pid_dir = config['configurations']['global']['hive_pid_dir']
+hive_pid = 'hive-server.pid'
+
+hive_metastore_pid = 'hive.pid'
+
+hcat_pid_dir = config['configurations']['global']['hcat_pid_dir'] #hcat_pid_dir

+ 7 - 1
ambari-server/src/main/resources/stacks/HDP/2.0._/services/NAGIOS/package/scripts/nagios_server.py

@@ -50,6 +50,12 @@ class NagiosServer(Script):
     env.set_params(params)
     env.set_params(params)
     
     
     nagios_service(action='stop')
     nagios_service(action='stop')
+
+
+  def status(self, env):
+    import status_params
+    env.set_params(status_params)
+    check_process_status(status_params.nagios_pid_file)
     
     
 def remove_conflicting_packages():  
 def remove_conflicting_packages():  
   Package( 'hdp_mon_nagios_addons',
   Package( 'hdp_mon_nagios_addons',
@@ -77,4 +83,4 @@ def main():
   
   
 if __name__ == "__main__":
 if __name__ == "__main__":
   #main()
   #main()
-  NagiosServer().execute()
+  NagiosServer().execute()

+ 3 - 4
ambari-server/src/main/resources/stacks/HDP/2.0._/services/NAGIOS/package/scripts/params.py

@@ -22,6 +22,7 @@ Ambari Agent
 
 
 from resource_management import *
 from resource_management import *
 from functions import get_port_from_url
 from functions import get_port_from_url
+import status_params
 
 
 # server configurations
 # server configurations
 config = Script.get_config()
 config = Script.get_config()
@@ -33,14 +34,12 @@ plugins_dir = "/usr/lib64/nagios/plugins"
 nagios_obj_dir = "/etc/nagios/objects"
 nagios_obj_dir = "/etc/nagios/objects"
 check_result_path = "/var/nagios/spool/checkresults"
 check_result_path = "/var/nagios/spool/checkresults"
 nagios_httpd_config_file = format("/etc/httpd/conf.d/nagios.conf")
 nagios_httpd_config_file = format("/etc/httpd/conf.d/nagios.conf")
-nagios_pid_dir = "/var/run/nagios"
-pid_file = format("{nagios_pid_dir}/nagios.pid")
 nagios_log_dir = "/var/log/nagios"
 nagios_log_dir = "/var/log/nagios"
 nagios_log_archives_dir = format("{nagios_log_dir}/archives")
 nagios_log_archives_dir = format("{nagios_log_dir}/archives")
 nagios_host_cfg = format("{nagios_obj_dir}/hadoop-hosts.cfg")
 nagios_host_cfg = format("{nagios_obj_dir}/hadoop-hosts.cfg")
 nagios_lookup_daemon_str = "/usr/sbin/nagios"
 nagios_lookup_daemon_str = "/usr/sbin/nagios"
-nagios_pid_dir = "/var/run/nagios"
-nagios_pid_file = format("{nagios_pid_dir}/nagios.pid")
+nagios_pid_dir = status_params.nagios_pid_dir
+nagios_pid_file = status_params.nagios_pid_file
 nagios_resource_cfg = format("{conf_dir}/resource.cfg")
 nagios_resource_cfg = format("{conf_dir}/resource.cfg")
 nagios_hostgroup_cfg = format("{nagios_obj_dir}/hadoop-hostgroups.cfg")
 nagios_hostgroup_cfg = format("{nagios_obj_dir}/hadoop-hostgroups.cfg")
 nagios_servicegroup_cfg = format("{nagios_obj_dir}/hadoop-servicegroups.cfg")
 nagios_servicegroup_cfg = format("{nagios_obj_dir}/hadoop-servicegroups.cfg")

+ 26 - 0
ambari-server/src/main/resources/stacks/HDP/2.0._/services/NAGIOS/package/scripts/status_params.py

@@ -0,0 +1,26 @@
+#!/usr/bin/env python
+"""
+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.
+
+"""
+
+from resource_management import *
+
+config = Script.get_config()
+
+nagios_pid_dir = "/var/run/nagios"
+nagios_pid_file = format("{nagios_pid_dir}/nagios.pid")

+ 3 - 0
ambari-server/src/main/resources/stacks/HDP/2.0._/services/OOZIE/package/scripts/oozie_client.py

@@ -15,6 +15,9 @@ class OozieClient(Script):
     env.set_params(params)
     env.set_params(params)
 
 
     oozie(is_server=False)
     oozie(is_server=False)
+
+  def status(self, env):
+    raise ClientComponentHasNoStatus()
     
     
 def main():
 def main():
   command_type = sys.argv[1] if len(sys.argv)>1 else "install"
   command_type = sys.argv[1] if len(sys.argv)>1 else "install"

+ 5 - 2
ambari-server/src/main/resources/stacks/HDP/2.0._/services/OOZIE/package/scripts/oozie_server.py

@@ -21,14 +21,17 @@ class OozieServer(Script):
   def start(self, env):
   def start(self, env):
     import params
     import params
     env.set_params(params)
     env.set_params(params)
-
     oozie_service(action='start')
     oozie_service(action='start')
     
     
   def stop(self, env):
   def stop(self, env):
     import params
     import params
     env.set_params(params)
     env.set_params(params)
-
     oozie_service(action='stop')
     oozie_service(action='stop')
+
+  def status(self, env):
+    import status_params
+    env.set_params(status_params)
+    check_process_status(status_params.pid_file)
     
     
 def main():
 def main():
   command_type = sys.argv[1] if len(sys.argv)>1 else "start"
   command_type = sys.argv[1] if len(sys.argv)>1 else "start"

+ 3 - 2
ambari-server/src/main/resources/stacks/HDP/2.0._/services/OOZIE/package/scripts/params.py

@@ -1,4 +1,5 @@
 from resource_management import *
 from resource_management import *
+import status_params
 
 
 # server configurations
 # server configurations
 config = Script.get_config()
 config = Script.get_config()
@@ -14,8 +15,8 @@ check_db_connection_jar = format("/usr/lib/ambari-agent/{check_db_connection_jar
 hadoop_prefix = "/usr"
 hadoop_prefix = "/usr"
 oozie_tmp_dir = "/var/tmp/oozie"
 oozie_tmp_dir = "/var/tmp/oozie"
 oozie_hdfs_user_dir = format("/user/{oozie_user}")
 oozie_hdfs_user_dir = format("/user/{oozie_user}")
-oozie_pid_dir = config['configurations']['global']['oozie_pid_dir']
-pid_file = format("{oozie_pid_dir}/oozie.pid")
+oozie_pid_dir = status_params.oozie_pid_dir
+pid_file = status_params.pid_file
 hadoop_jar_location = "/usr/lib/hadoop/"
 hadoop_jar_location = "/usr/lib/hadoop/"
 # for HDP1 it's "/usr/share/HDP-oozie/ext.zip"
 # for HDP1 it's "/usr/share/HDP-oozie/ext.zip"
 ext_js_path = "/usr/share/HDP-oozie/ext-2.2.zip"
 ext_js_path = "/usr/share/HDP-oozie/ext-2.2.zip"

+ 26 - 0
ambari-server/src/main/resources/stacks/HDP/2.0._/services/OOZIE/package/scripts/status_params.py

@@ -0,0 +1,26 @@
+#!/usr/bin/env python
+"""
+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.
+
+"""
+
+from resource_management import *
+
+config = Script.get_config()
+
+oozie_pid_dir = config['configurations']['global']['oozie_pid_dir']
+pid_file = format("{oozie_pid_dir}/oozie.pid")

+ 3 - 0
ambari-server/src/main/resources/stacks/HDP/2.0._/services/PIG/package/scripts/pig_client.py

@@ -34,6 +34,9 @@ class PigClient(Script):
     import params
     import params
     env.set_params(params)
     env.set_params(params)
     pig()
     pig()
+
+  def status(self, env):
+    raise ClientComponentHasNoStatus()
     
     
 #for tests
 #for tests
 def main():
 def main():

+ 0 - 2
ambari-server/src/main/resources/stacks/HDP/2.0._/services/SQOOP/package/scripts/__init__.py

@@ -16,6 +16,4 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 See the License for the specific language governing permissions and
 See the License for the specific language governing permissions and
 limitations under the License.
 limitations under the License.
 
 
-Ambari Agent
-
 """
 """

+ 0 - 2
ambari-server/src/main/resources/stacks/HDP/2.0._/services/SQOOP/package/scripts/params.py

@@ -15,8 +15,6 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 See the License for the specific language governing permissions and
 See the License for the specific language governing permissions and
 limitations under the License.
 limitations under the License.
 
 
-Ambari Agent
-
 """
 """
 
 
 from resource_management import *
 from resource_management import *

+ 0 - 2
ambari-server/src/main/resources/stacks/HDP/2.0._/services/SQOOP/package/scripts/service_check.py

@@ -16,8 +16,6 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 See the License for the specific language governing permissions and
 See the License for the specific language governing permissions and
 limitations under the License.
 limitations under the License.
 
 
-Ambari Agent
-
 """
 """
 
 
 
 

+ 0 - 2
ambari-server/src/main/resources/stacks/HDP/2.0._/services/SQOOP/package/scripts/sqoop.py

@@ -15,8 +15,6 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 See the License for the specific language governing permissions and
 See the License for the specific language governing permissions and
 limitations under the License.
 limitations under the License.
 
 
-Ambari Agent
-
 """
 """
 
 
 from resource_management import *
 from resource_management import *

+ 3 - 2
ambari-server/src/main/resources/stacks/HDP/2.0._/services/SQOOP/package/scripts/sqoop_client.py

@@ -16,8 +16,6 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 See the License for the specific language governing permissions and
 See the License for the specific language governing permissions and
 limitations under the License.
 limitations under the License.
 
 
-Ambari Agent
-
 """
 """
 
 
 import sys
 import sys
@@ -36,5 +34,8 @@ class SqoopClient(Script):
     env.set_params(params)
     env.set_params(params)
     sqoop(type='client')
     sqoop(type='client')
 
 
+  def status(self, env):
+    raise ClientComponentHasNoStatus()
+
 if __name__ == "__main__":
 if __name__ == "__main__":
   SqoopClient().execute()
   SqoopClient().execute()

+ 3 - 2
ambari-server/src/main/resources/stacks/HDP/2.0._/services/WEBHCAT/package/scripts/params.py

@@ -21,6 +21,7 @@ Ambari Agent
 """
 """
 
 
 from resource_management import *
 from resource_management import *
+import status_params
 
 
 # server configurations
 # server configurations
 config = Script.get_config()
 config = Script.get_config()
@@ -31,9 +32,9 @@ download_url = config['configurations']['global']['apache_artifacts_download_url
 config_dir = '/etc/hcatalog/conf'
 config_dir = '/etc/hcatalog/conf'
 
 
 templeton_log_dir = config['configurations']['global']['hcat_log_dir']
 templeton_log_dir = config['configurations']['global']['hcat_log_dir']
-templeton_pid_dir = config['configurations']['global']['hcat_pid_dir']
+templeton_pid_dir = status_params.templeton_pid_dir
 
 
-pid_file = format('{templeton_pid_dir}/webhcat.pid')
+pid_file = status_params.pid_file
 
 
 hadoop_conf_dir = config['configurations']['webhcat-site']['templeton.hadoop.conf.dir']
 hadoop_conf_dir = config['configurations']['webhcat-site']['templeton.hadoop.conf.dir']
 templeton_jar = config['configurations']['webhcat-site']['templeton.jar']
 templeton_jar = config['configurations']['webhcat-site']['templeton.jar']

+ 26 - 0
ambari-server/src/main/resources/stacks/HDP/2.0._/services/WEBHCAT/package/scripts/status_params.py

@@ -0,0 +1,26 @@
+#!/usr/bin/env python
+"""
+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.
+
+"""
+
+from resource_management import *
+
+config = Script.get_config()
+
+templeton_pid_dir = config['configurations']['global']['hcat_pid_dir']
+pid_file = format('{templeton_pid_dir}/webhcat.pid')

+ 5 - 0
ambari-server/src/main/resources/stacks/HDP/2.0._/services/WEBHCAT/package/scripts/webhcat_server.py

@@ -45,5 +45,10 @@ class WebHCatServer(Script):
 
 
     webhcat_service(action = 'stop')
     webhcat_service(action = 'stop')
 
 
+  def status(self, env):
+    import status_params
+    env.set_params(status_params)
+    check_process_status(status_params.pid_file)
+
 if __name__ == "__main__":
 if __name__ == "__main__":
   WebHCatServer().execute()
   WebHCatServer().execute()

+ 4 - 3
ambari-server/src/main/resources/stacks/HDP/2.0._/services/ZOOKEEPER/package/scripts/params.py

@@ -21,6 +21,7 @@ Ambari Agent
 """
 """
 
 
 from resource_management import *
 from resource_management import *
+import status_params
 
 
 # server configurations
 # server configurations
 config = Script.get_config()
 config = Script.get_config()
@@ -35,8 +36,8 @@ smoke_script = "/usr/lib/zookeeper/bin/zkCli.sh"
 
 
 zk_log_dir = config['configurations']['global']['zk_log_dir']
 zk_log_dir = config['configurations']['global']['zk_log_dir']
 zk_data_dir = config['configurations']['global']['zk_data_dir']
 zk_data_dir = config['configurations']['global']['zk_data_dir']
-zk_pid_dir = config['configurations']['global']['zk_pid_dir']
-zk_pid_file = format("{zk_pid_dir}/zookeeper_server.pid")
+zk_pid_dir = status_params.zk_pid_dir
+zk_pid_file = status_params.zk_pid_file
 zk_server_heapsize = "-Xmx1024m"
 zk_server_heapsize = "-Xmx1024m"
 
 
 tickTime = config['configurations']['global']['tickTime']
 tickTime = config['configurations']['global']['tickTime']
@@ -60,4 +61,4 @@ security_enabled = config['configurations']['global']['security_enabled']
 
 
 smoke_user_keytab = config['configurations']['global']['smokeuser_keytab']
 smoke_user_keytab = config['configurations']['global']['smokeuser_keytab']
 smokeuser = config['configurations']['global']['smokeuser']
 smokeuser = config['configurations']['global']['smokeuser']
-kinit_path_local = get_kinit_path([default("kinit_path_local",None), "/usr/bin", "/usr/kerberos/bin", "/usr/sbin"])
+kinit_path_local = get_kinit_path([default("kinit_path_local",None), "/usr/bin", "/usr/kerberos/bin", "/usr/sbin"])

+ 26 - 0
ambari-server/src/main/resources/stacks/HDP/2.0._/services/ZOOKEEPER/package/scripts/status_params.py

@@ -0,0 +1,26 @@
+#!/usr/bin/env python
+"""
+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.
+
+"""
+
+from resource_management import *
+
+config = Script.get_config()
+
+zk_pid_dir = config['configurations']['global']['zk_pid_dir']
+zk_pid_file = format("{zk_pid_dir}/zookeeper_server.pid")

+ 4 - 0
ambari-server/src/main/resources/stacks/HDP/2.0._/services/ZOOKEEPER/package/scripts/zookeeper_client.py

@@ -29,11 +29,15 @@ class ZookeeperClient(Script):
   def install(self, env):
   def install(self, env):
     self.install_packages(env)
     self.install_packages(env)
     self.configure(env)
     self.configure(env)
+
   def configure(self, env):
   def configure(self, env):
     import params
     import params
     env.set_params(params)
     env.set_params(params)
 
 
     zookeeper(type='client')
     zookeeper(type='client')
 
 
+  def status(self, env):
+    raise ClientComponentHasNoStatus()
+
 if __name__ == "__main__":
 if __name__ == "__main__":
   ZookeeperClient().execute()
   ZookeeperClient().execute()

+ 5 - 0
ambari-server/src/main/resources/stacks/HDP/2.0._/services/ZOOKEEPER/package/scripts/zookeeper_server.py

@@ -46,5 +46,10 @@ class ZookeeperServer(Script):
     env.set_params(params)
     env.set_params(params)
     zookeeper_service(action = 'stop')
     zookeeper_service(action = 'stop')
 
 
+  def status(self, env):
+    import status_params
+    env.set_params(status_params)
+    check_process_status(status_params.zk_pid_file)
+
 if __name__ == "__main__":
 if __name__ == "__main__":
   ZookeeperServer().execute()
   ZookeeperServer().execute()