- Subscribe to RSS Feed
- Mark as New
- Mark as Read
- Bookmark
- Subscribe
- Printer Friendly Page
- Report Inappropriate Content
Created on 10-01-2017 12:04 PM
This article describes how to add a new custom script and execute the script through Ambari. In this article, I took a simple use case to install kerberos packages through custom scripts.
1) Below is the code to install kerberos packages (install_kerberos_package.py)
#!/usr/bin/env python from resource_management import Script, Execute, format from ambari_commons.os_check import OSCheck from resource_management.core import shell from resource_management.core.logger import Logger class InstallKerberosPackage(Script): def actionexecute(self, env): config = Script.get_config() structured_output = {} cmd = self.get_install_cmd() Logger.info("Installing Kerberos Package") code, output = shell.call(cmd, sudo = True) if 0 == code: structured_output["install_kerberos_package"] = {"exit_code" : 0, "message": format("Packages installed successfully")} else: structured_output["install_kerberos_package"] = {"exit_code": code, "message": "Failed to install packages! {0}".format(str(output))} self.put_structured_out(structured_output) def get_install_cmd(self): if OSCheck.is_redhat_family(): Logger.info("Installing kerberos package for the RedHat OS family"); return ("/usr/bin/yum", "install", "-y", "krb5-server", "krb5-libs", "krb5-workstation") elif OSCheck.is_suse_family(): Logger.info("Installing kerberos package for the SUSE OS family"); return ('/usr/bin/zypper', '-n','install', 'krb5', 'krb5-server', 'krb5-client') elif OSCheck.is_ubuntu_family(): Logger.info("Installing kerberos package for the Ubuntu OS family"); return ('/usr/bin/apt-get', 'install', '-y', 'krb5-kdc', 'krb5-admin-server') else: raise Exception("Unsupported OS family: '{0}' ".format(OSCheck.get_os_family())) if __name__ == "__main__": InstallKerberosPackage().execute()
2) Save the file with install_kerberos_package.py and put it in the custom actions folder of ambari and change the permissions
cp install_kerberos_package.py /var/lib/ambari-server/resources/custom_actions/scripts/ chmod 755 /var/lib/ambari-server/resources/custom_actions/scripts/install_kerberos_package.py chown root:root /var/lib/ambari-server/resources/custom_actions/scripts/install_kerberos_package.py
3) The next step is to add the definition for this action. Open the file system_action_definitions.xml located under "/var/lib/ambari-server/resources/custom_action_definitions/" folder using your favourite editor and add the below content alertDefinitions tag
<actionDefinition> <actionName>install_kerberos_package</actionName> <actionType>SYSTEM</actionType> <inputs></inputs> <targetService/> <targetComponent/> <defaultTimeout>60</defaultTimeout> <description>Install kerberos packages</description> <targetType>ALL</targetType> <permissions>HOST.ADD_DELETE_COMPONENTS, HOST.ADD_DELETE_HOSTS, SERVICE.ADD_DELETE_SERVICES</permissions> </actionDefinition>
Note: You can add comma separated inputs if you need any inputs for the script.
4) Now that the action is defined, restart ambari server for the changes to reflect.
ambari-server restart
5) Check if your action is listed by calling the Ambari REST API.
curl -u <username>:<password> "http://<ambari-host>:<ambari-port>/api/v1/actions"
6) Now you are ready to run the custom script which you have created.
curl -u <username>:<password> -X POST -H 'X-Requested-By:ambari' -d'{"RequestInfo":{"context":"Execute an action", "action" : "install_kerberos_package", "service_name" : "", "component_name":"", "hosts":"<comma-separated-hosts>"}}' http://<ambari-host>:<ambari-port>/api/v1/clusters/<cluster-name>/requests
You can check the output in the Ambari UI. Please check the screenshot(sample-output.png) for reference
Created on 01-13-2018 04:24 PM
- Mark as Read
- Mark as New
- Bookmark
- Permalink
- Report Inappropriate Content
The mentioned command in the post is not working:
curl -u <username>:<password>-X POST -H 'X-Requested-By:ambari'-d'{"RequestInfo":{"context":"Execute an action", "action" : "install_kerberos_package", "service_name" : "", "component_name":"", "hosts":"<comma-separated-hosts>"}}' http://<ambari-host>:<ambari-port>/api/v1/clusters/<cluster-name>/requests
I am working in a Azure HDInsight Hadoop Cluster having 2 headnodes [primary and secondary] and 2 worker nodes and 1 edge node. I have configured the script and restarted ambari server to reflect the changes as you've mentioned but want to execute the script specific to primary head node.
By executing the command hostname -f, I got the FQDN of that host and execute the following command from edge node:
curl -u admin:<password> -X POST -H 'X-Requested-By:ambari' -d'{"RequestInfo":{"context":"Execute an action", "acton" : "validate_nfs_server_export_path", "service_name" : "", "component_name":"", "hosts":"hn0-kalyan.qjhddkgqet0efmcgr4zymppb4e.cx.internal.cloudapp.net"}}' http://headnodehost:8080/api/v1/clusters/cluster_name/requests
But when I saw the AMBARI UI, it shows executed on all the all nodes which it should not be.
Created on 01-14-2018 10:44 AM
- Mark as Read
- Mark as New
- Bookmark
- Permalink
- Report Inappropriate Content
After going through the Ambari API documentation, what I found that the given curl command to execute the custom script action needs to be modified as I have tested and it's working fine.
curl -u <username>:<password> -X POST -H 'X-Requested-By:ambari' -d'{"RequestInfo":{"context":"Execute an action", "action" : "<action_name>"}, "Requests/resource_filters":[{"service_name" : "", "component_name":"", "hosts":"<comma_separated_host_names>"}]}' http://ambari_host:port/api/v1/clusters/cluster_name/requests
For specific components manageability:
curl -k -i -u <ambari_admin_user>:<ambari_admin_password> -H 'X-Requested-By: ambari' -X
POST -d '{"RequestInfo":
{"query":"Hosts/host_name.in(<comma separated list of
hosts to be added, if one node give only one
name>)"},
"Body":{"host_components":[{"HostRoles":{"component_name":"BIGSQL_WORKER"}}
]}}'
http://<ambari-host>:
<ambari-port>/api/v1/clusters/<cluster_name>/hosts?
curl -k -i -u <ambari_admin_user>:<ambari_admin_password> -H 'X-Requested-By: ambari' -X
PUT -d '{ "HostRoles": {"state":"INSTALLED" } }'
Created on 01-14-2018 02:41 PM
- Mark as Read
- Mark as New
- Bookmark
- Permalink
- Report Inappropriate Content
Changes in system_action_definitions.xml is not picking up by ambari-server even after restart. Even I have kept the <actionName.py> file in the respective diretory. Could you please help me out?
Created on 01-15-2018 11:39 AM
- Mark as Read
- Mark as New
- Bookmark
- Permalink
- Report Inappropriate Content
I have resolved the issue by placing ACTIVEAMBARIHOST with headnode FQDN name as from Edge Node it was not reflecting.
Created on 01-19-2018 11:53 PM
- Mark as Read
- Mark as New
- Bookmark
- Permalink
- Report Inappropriate Content
Thanks for the article, it is very helpful.
I'd like to point out that in the article you included the note:
Note: You can add comma separated inputs if you need any inputs for the script.
That is great because I need to pass my script an input. I was able to create the custom action definition so that it expects and input (as you suggested was possible). Unfortunately I can't find anywhere that tells/shows how to pass the input. I have tried something like the following:
curl -u <username>:<password> -X POST -H 'X-Requested-By:ambari' -d'{"RequestInfo":{"context":"Execute my action", "action":"my_action"}, "Requests/resource_filters":[{"service_name":"", "component_name":"", "hosts":"<comma_separated_host_names>"}], "Requests/inputs":{"my_input":"input_value"}}' http://<ambari_host>:<port>/api/v1/clusters/<cluster_name>/requests
but that returns a 500 error saying:
An internal system exception occurred. Action my_action requires input 'my_input' that is not provided.
All my attempts so far have resulted in a 500 return code with the same message. So how am I supposed to pass the custom action its input via curl?
Created on 01-20-2018 05:19 AM
- Mark as Read
- Mark as New
- Bookmark
- Permalink
- Report Inappropriate Content
You should pass your inputs inside parameters
curl -u <username>:<password> -X POST -H 'X-Requested-By:ambari' -d'{"RequestInfo":{"context":"Execute my action", "action":"my_action", "parameters" : {"my_input" : "value"}}, "Requests/resource_filters":[{"service_name":"", "component_name":"", "hosts":"<comma_separated_host_names>"}]' http://<ambari_host>:<port>/api/v1/clusters/<cluster_name>/requests
Created on 01-22-2018 02:46 PM
- Mark as Read
- Mark as New
- Bookmark
- Permalink
- Report Inappropriate Content
Thank you for the quick response! That was exactly what I needed.