Browse Source

AMBARI-4065. Add to hooks ability to include templates&static files (dlysnichenko)

Lisnichenko Dmitro 11 years ago
parent
commit
34b1cb86a2

+ 14 - 12
ambari-agent/src/main/python/ambari_agent/CustomServiceOrchestrator.py

@@ -62,7 +62,7 @@ class CustomServiceOrchestrator():
 
 
       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')
-        script_path = os.path.join(base_dir, script)
+        script_tuple = (os.path.join(base_dir, script) , base_dir)
         hook_dir = None
         hook_dir = None
       else:
       else:
         stack_name = command['hostLevelParams']['stack_name']
         stack_name = command['hostLevelParams']['stack_name']
@@ -72,6 +72,7 @@ class CustomServiceOrchestrator():
         base_dir = self.file_cache.get_service_base_dir(
         base_dir = self.file_cache.get_service_base_dir(
           stack_name, stack_version, metadata_folder, component_name)
           stack_name, stack_version, metadata_folder, component_name)
         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)
 
 
       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))
@@ -81,17 +82,17 @@ class CustomServiceOrchestrator():
         raise AgentException(message)
         raise AgentException(message)
       # Execute command using proper interpreter
       # Execute command using proper interpreter
       json_path = self.dump_command_to_json(command)
       json_path = self.dump_command_to_json(command)
-      script_params = [command_name, json_path, base_dir]
-      pre_hook = self.resolve_hook_script_path(hook_dir,
+      pre_hook_tuple = self.resolve_hook_script_path(hook_dir,
           self.PRE_HOOK_PREFIX, command_name, script_type)
           self.PRE_HOOK_PREFIX, command_name, script_type)
-      post_hook = self.resolve_hook_script_path(hook_dir,
+      post_hook_tuple = self.resolve_hook_script_path(hook_dir,
           self.POST_HOOK_PREFIX, command_name, script_type)
           self.POST_HOOK_PREFIX, command_name, script_type)
-      py_file_list = [pre_hook, script_path, post_hook]
+      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 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]
         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)
         if ret['exitcode'] != 0:
         if ret['exitcode'] != 0:
@@ -125,19 +126,20 @@ class CustomServiceOrchestrator():
     return path
     return path
 
 
 
 
-  def resolve_hook_script_path(self, hook_base_dir, prefix, command_name, script_type):
+  def resolve_hook_script_path(self, stack_hooks_dir, prefix, command_name, script_type):
     """
     """
-    Returns a path to hook script according to string prefix
+    Returns a tuple(path to hook script, hook base dir) according to string prefix
     and command name. If script does not exist, returns None
     and command name. If script does not exist, returns None
     """
     """
-    if not hook_base_dir:
+    if not stack_hooks_dir:
       return None
       return None
-    script_file = "{0}-{1}.py".format(prefix, command_name)
-    hook_script_path = os.path.join(hook_base_dir, script_file)
+    hook_dir = "{0}-{1}".format(prefix, command_name)
+    hook_base_dir = os.path.join(stack_hooks_dir, hook_dir)
+    hook_script_path = os.path.join(hook_base_dir, "scripts", "hook.py")
     if not os.path.isfile(hook_script_path):
     if not os.path.isfile(hook_script_path):
       logger.debug("Hook script {0} not found, skipping".format(hook_script_path))
       logger.debug("Hook script {0} not found, skipping".format(hook_script_path))
       return None
       return None
-    return hook_script_path
+    return hook_script_path, hook_base_dir
 
 
 
 
   def dump_command_to_json(self, command):
   def dump_command_to_json(self, command):

+ 5 - 2
ambari-agent/src/test/python/ambari_agent/TestCustomServiceOrchestrator.py

@@ -126,7 +126,9 @@ class TestCustomServiceOrchestrator(TestCase):
     }
     }
     get_service_base_dir_mock.return_value = "/basedir/"
     get_service_base_dir_mock.return_value = "/basedir/"
     resolve_script_path_mock.return_value = "/basedir/scriptpath"
     resolve_script_path_mock.return_value = "/basedir/scriptpath"
-    resolve_hook_script_path_mock.return_value = "/basedir/hooks/hookpath"
+    resolve_hook_script_path_mock.return_value = \
+      ('/hooks_dir/prefix-command/scripts/hook.py',
+       '/hooks_dir/prefix-command')
     orchestrator = CustomServiceOrchestrator(self.config)
     orchestrator = CustomServiceOrchestrator(self.config)
     get_hook_base_dir_mock.return_value = "/hooks/"
     get_hook_base_dir_mock.return_value = "/hooks/"
     # normal run case
     # normal run case
@@ -191,7 +193,8 @@ class TestCustomServiceOrchestrator(TestCase):
     isfile_mock.return_value = True
     isfile_mock.return_value = True
     res2 = orchestrator.resolve_hook_script_path("/hooks_dir/", "prefix", "command",
     res2 = orchestrator.resolve_hook_script_path("/hooks_dir/", "prefix", "command",
                                             "script_type")
                                             "script_type")
-    self.assertEqual(res2, "/hooks_dir/prefix-command.py")
+    self.assertEqual(res2, ('/hooks_dir/prefix-command/scripts/hook.py',
+                            '/hooks_dir/prefix-command'))
     # Testing not existing hook script
     # Testing not existing hook script
     isfile_mock.return_value = False
     isfile_mock.return_value = False
     res3 = orchestrator.resolve_hook_script_path("/hooks_dir/", "prefix", "command",
     res3 = orchestrator.resolve_hook_script_path("/hooks_dir/", "prefix", "command",

+ 0 - 0
ambari-server/src/main/resources/stacks/HDP/2.0._/hooks/before-START.py → ambari-server/src/main/resources/stacks/HDP/1.3._/hooks/before-START/scripts/hook.py


+ 30 - 0
ambari-server/src/main/resources/stacks/HDP/2.0._/hooks/before-START/scripts/hook.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()