6. Tips and Tricks for Using the CLI

JBoss ON CLI scripts make it possible to automate tasks, from simply importing discovered resources to running complex management operations to remedy configuration drift or schedule web app upgrades.
The JBoss ON CLI has some usability features to make it easier to use interactively for developing scripts, to integrate with system tools to help task automation, and to create custom functions for more versatile, real-life applications.

6.1. Using Tab Complete

In interactive mode, the JBoss ON CLI is aware of the implicit variables (Section 3, “Available Implicit Variables in the JBoss ON API”) in the domain API and the JBoss ON remote API, as well as the specific CLI commands and methods (Section 4, “Methods Specific to the JBoss ON CLI”). When running the CLI interactively, any of these methods can be filled in using Tab complete.
Filling in part of a class lists potential matching classes (or, if it matches, commands). For example:
[jsmith@server bin]# ./rhq-cli.sh -u rhqadmin -p rhqadmin
RHQ Enterprise Remote CLI 3.1.2
Remote server version is: 3.1.2 (2484565)
Login successful
rhqadmin@localhost:7080$ Resource

ResourceFactoryManager   ResourceGroupManager     ResourceManager
ResourceTypeManager

rhqadmin@localhost:7080$ ex

exporter   exec
After selecting a class, hitting Tab once lists all of the methods for that class.
rhqadmin@localhost:7080$ ResourceManager.

availabilitySummary           disableResources
enableResources               findChildResources
findResourceLineage           findResourcesByCriteria
getAvailabilitySummary        getLiveResourceAvailability
getParentResource             getResource
getResourcesAncestry          liveResourceAvailability
parentResource                resource
toString                      uninventoryResources
updateResource
Hitting Tab twice prints the full method signatures:
rhqadmin@localhost:7080$
	
              List<Integer> enableResources(GenericArrayTypeImpl[int])
                   Resource updateResource(Resource resource)
              List<Integer> uninventoryResources(GenericArrayTypeImpl[int] resourceIds)
ResourceAvailabilitySummary getAvailabilitySummary(int resourceId)
         PageList<Resource> findChildResources(int resourceId, PageControl pageControl)
        Map<Integer,String> getResourcesAncestry(GenericArrayTypeImpl[Integer] resourceIds, ResourceAncestryFormat format)
              List<Integer> disableResources(GenericArrayTypeImpl[int])
             List<Resource> findResourceLineage(int resourceId)
       ResourceAvailability getLiveResourceAvailability(int resourceId)
         PageList<Resource> findResourcesByCriteria(ResourceCriteria criteria)
                   Resource getResource(int resourceId)
                     String toString()
		 Resource getParentResource(int resourceId)
Autocomplete is very useful for finding what methods or objects are implicitly available, for building criteria-based searches (because it is easier to select criteria), and for developing server scripts.

6.2. Differences Between Running the CLI Interactively and with Files

Scripts can be run in the CLI either by entering the lines directly (in interactive mode) or by passing a script file to the CLI using the -f option or exec command.
Scripts that are entered interactively and scripts in a file are substantively the same, with one exception. In interactive mode, the CLI has a set of commands (Section 2.3, “Interactive CLI Commands”). These commands are part of the CLI, and most of those commands are only available in interactive mode. These commands cannot be referenced inside a referenced script file:
  • quit (which exits the CLI)
  • exec
  • record
The login and logout commands are not directly available, either, but there are login and logout functions available which can be used within a script.
rhq.login('rhqadmin', 'rhqadmin');

rhq.logout();
As with the differences between the GUI, CLI, and alert scripts, this is a matter of context. Most of the CLI-defined commands only make sense within an interactive environment, like executing an external script file or recording inputted commands. Outside that interactive context, other Java methods should be used.

6.3. API Differences Between Resources Types and Versions

One important thing to remember about the structure of objects in JBoss ON is that each resource type is defined individually, in its own plug-in descriptor. (There can be multiple resource types in a single plug-in descriptor, and these are all related as parent and children resource types.)
Each resource type has different management APIs, which reflect the software application. Obviously, a Tomcat server is different than a Postgres database, so they have different metrics, operations, and configuration properties. Even seemingly common traits like stopping and starting a resource are different depending on the resource type descriptor. Tomcat has an operation to stop gracefully (something not needed for a database or most services), while JBoss AS 5 servers are stopped and then started as separate tasks instead of restarting in one step.
An agent plug-in defines a resource type not only by the application or service, but also by the version of that application or service. An EJB resource is difference than an EJB3 resource, with a different definition.
This distinction — that different versions of the same application are treated as different resource types — is particularly critical for server resources.
Different resource types have configuration properties and operations available. This can impact CLI scripts written to manage those resources. For example, a script written for a JBoss AS 5 resource may not work for a JBoss AS 4 or JBoss AS 7 resource because the different resources have different APIs.
If you are writing a script which may be used for different versions of a server, create a CLI script which first identifies the resource type and then calls the appropriate method.

6.4. Available Utility and Sample Scripts

Several scripts are provided that supply additional functionality, like simplified functions for parsing search results, deploying bundles, or managing drift. These utility scripts add functions without performing any concrete task. They are available as a reference for and extension to custom scripts. These example functions can be copied into a script file or can be loaded before a script is run, as in Section 6.6, “Script Dependencies and Loading Functions”.
A couple of scripts are available that both provide additional functions (for reference or ease of use) and also perform management tasks when run. This scripts can be used directly to manage resources, without having to write a custom script.

IMPORTANT

Utility and sample scripts have not been extensively tested and may not be updated between releases. These are included for convenience and for real-life, complete examples of writing server scripts.
Test these scripts for quality and consistency within your environment.

Table 6. Utility and Sample Scripts

Script Description Location
Utility Scripts
util.js Defines search functions for iterating through an array of object (foreach), to return the first matching object (find) or to return all matching objects (findAll). It also has functions for converting information from JavaScript hashes to JBoss ON configuration objects and back. cliRoot/rhq-remoting-cli-3.1.2.GA/samples/
measurement_utils.js Defines functions to enable, disable, or update metric schedules. cliRoot/rhq-remoting-cli-3.1.2.GA/samples/
bundles.js Defines functions to create and deploy a bundle, create a bundle destination, or get information on supported base directories for a resource. cliRoot/rhq-remoting-cli-3.1.2.GA/samples/
drift.js Defines functions to create and diff snapshots, get a definition, and show the history for a resource or specific file. cliRoot/rhq-remoting-cli-3.1.2.GA/samples/
Sample Scripts
add-as7-standalone-server-to-cluster.js Defines a series of functions that add a specified AS 7 to a cluster. cliRoot/rhq-remoting-cli-3.1.2.GA/samples/
deploy-to-and-restart-JBAS.js Defines two functions to deploy new content to EAP servers and to update existing content. With the proper variables set, this script can be run directly to deploy content and restart the given app server. cliRoot/rhq-remoting-cli-3.1.2.GA/samples/
fix-bundle-deployment.js An example server-side alert script that reverts a bundle deployment to a specified version. serverRoot/jon-server-3.1.2.GA/jbossas/server/default/deploy/rhq.ear/rhq-downloads/cli-alert-scripts/

6.5. Defining Custom Functions

Custom functions are permissible and supported in CLI scripts as long as they are properly structured and conform to the JBoss ON remote API.

6.6. Script Dependencies and Loading Functions

When executing a script from a file by using the rhq-cli.sh -f option, there is no way to define a dependency with an external file. Any functions required by that script must be contained in the script.
When executing scripts interactively, however, there is a bit more flexibility. The exec -f command loads whatever functions are in the file into the active CLI session. This allows utility scripts to be loaded first and then scripts to be run that take advantage of the utility functions.
For example, util.js contains very useful functions for iterating through an array of objects and returning some or all of the matching objects. This can be loaded first, and then a script which relies on its search functions can be executed next:
rhqadmin@localhost:7080$ exec -f cliRoot/rhq-remoting-cli-3.1.2.GA/samples/util.js
rhqadmin@localhost:7080$ exec -f /export/scripts/myScript.js

IMPORTANT

Scripts must be executed in order for the functions to be loaded properly. For example, if ScriptB.js depends on ScriptA.js, then ScriptA.js must be executed first for its functions to be available to ScriptB.js.

6.7. Scheduling Script Runs with Cron

Administrators may create some scripts to perform routine maintenance on their JBoss ON systems, such as deleting old bundle versions to improve database performance or to add newly-discovered resources to the inventory automatically.
Scripts can be run through the JBoss ON CLI using a simple cron job. For example, an administrator writes import.js to add discovered resources to the inventory automatically and runs it daily:
vim /etc/cron.daily/rhq-cli
	
#!/bin/sh
# run JON CLI every morning to import new resources
cliRoot/rhq-remoting-cli-3.1.2.GA/bin/rhq-cli.sh -u rhqadmin -p rhqadmin -f /export/scripts/import.js
More information about scheduling jobs with cron is available in the crontab manpage.

6.8. Using Wrapper Scripts

Ultimately, JBoss ON CLI scripts are regular JavaScript files. For simplicity or ease of programming, you may write a number of different scripts, each performing a different task or for a different resource type.
This collection of scripts can be controlled through wrapper scripts. Using simple shell scripts can make running the JBoss ON CLI scripts more user-friendly (by providing a nicer interface) or it can make it easier to pass variables to manage specific resources.
There is a simplistic example of using a wrapper script in Section 6, “Example: Managing Grouped Servers (JBoss EAP 5)”.

6.9. Permissions and Setup for JBoss ON Users

Every CLI script, either for a logged in user or through the rhq.login method, is run on the JBoss ON server by a JBoss ON user.
The JBoss ON CLI does enforce access controls to resources touched by JBoss ON CLI scripts. This means that the script's user must meet the same authorization requirements as a GUI user to perform the given operation.
Additionally, any user who runs a CLI script must already exist in JBoss ON as a user. When the JBoss ON server is configured to create LDAP users, these users are created automatically the first time the LDAP user logs into the JBoss ON web UI. The same account creation does not occur when logging in with the CLI. Therefore, LDAP users must log into the web UI before they can run the JBoss ON CLI.