Previous Topic: Using the run-remote CommandNext Topic: AutoShell Core Reference


Using the RemoteTarget Class

Use the run-remote command with the RemoteTarget class in the following ways:

The run-remote command always returns an array of RemoteTarget objects. The length of this array is equal to the number of remote targets that have been specified in the on clause. The array elements directly correspond to the remote targets by position:

arrRT = run-remote -file hello.js on "ascl1", "ascl2"

The run-remote command returns an array with two RemoteTarget objects:

RemoteTarget objects make status information of the script available, regarding its execution process, output, or result. The following RemoteTarget methods retrieve this status information:

hasCompleted()

Indicates if the command processing has been completed (true) or not (false). If run-remote is invoked without the optional -wait switch, command execution runs asynchronously. Call this method to verify if a command completes and if a result is available. The method hasCompleted() returns true when the command successfully completes or false when an error occurs that prevents further processing.

Return values: true or false

errorOccurred()

Indicates whether the command finishes successfully and the output and result can be verified (false), or if an error occurs (true).

Return values: true or false

output()

Returns a string that contains the captured output produced by running the specified script on the corresponding remote system.

Return value: string

result()

Returns an XML-encoded value of the specified script that has been executed on the corresponding remote system.

Return value: XML

See the AutoShell Classes section for additional methods of the RemoteTarget class.

Examples

Assuming the previously introduced hello.js script produces the "Hello World!" greeting, the output() methods for both RemoteTarget objects return this string. The following script puts this type of processing in a larger context:

var t;
var arrRT;
var i, l;

arrRT = run-remote -file hello.js on "ascl1", "ascl2"
l = arrRT.length;

// Wait for completion, could use -wait clause above as well
// but this way we can bail out on our own timeout
t = 0;

while(t<60)
{
    for(i=0; i<l; i++)
    {
        if(!arrRT[i].hasCompleted())
            break;    
    }
    // Break if all invocations finished
    if(i==l)
        break;
    sleep(500);
    t++;
}
for(i=0; i<l; i++)
{
    if(arrRT[i].hasCompleted())
    {
        if(arrRT[i].errorOccurred())
        {
            ? "Error occurred on ", arrRT[i].getHostName()
        }
        else
        {
            ? arrRT[i].getHostName(),"returned output:"
            ? arrRT[i].output()
        }
    }
    else
    {
        arrRT[i].abort();    
    }
}

Combining remote execution with OS command invocation enables access to OS services or data on remote systems. For example, the following code queries and returns the OS version string of the operating system running on server ascl1.

arrRT = run-remote ! ver on "ascl1" -wait
? arrRT[0].output()

AutoShell only displays the remote command output in the previous examples. Expressions or scripts processed remotely can also return a value:

arrRT = run-remote 2*21 on "ascl1" -wait

In this case the expression "2*21" is sent to server ascl1 for remote calculation. When the command completes, the result is available through the result() method of the corresponding RemoteTarget object.

The result() method does not return the value directly, but an XML representation of it:

? arrRT[0].result()
<value type="number">42</value>

To turn this XML string into a regular JavaScript value, use get-remoteResult():

v = get-remoteResult(arrRT[0])
? typeof v, v

AutoShell serialization also applies to remote scripts which return complex types like arrays or objects. Serialization enables the transfer of large amounts of structured data between remote servers without losing structural data. The following example shows a remote execution that returns an array consisting of three elements:

arrRT = run-remote [1,"abc",new Date()] on "ascl1" -wait
v = get-remoteResult(arrRT[0])
? typeof v, v

Another way of working with RemoteTarget objects is to create them before invoking the actual remote command. A RemoteTarget object is constructed by specifying the name of the target host in the object creation:

var rt1 = new RemoteTarget("ascl1");
var rt2 = new RemoteTarget("ascl2");

Explicitly creating RemoteTarget objects is useful when more than one command or script is executed for the same remote host. In this case, the same RemoteTarget object can be reused for each run-remote. Otherwise, run-remote creates a RemoteTarget object for each invocation.

To use the RemoteTarget objects with run-remote, specify them instead of the host names:

run-remote -file hello.js on rt1, rt2 -wait
? rt1.output()
? rt2.output()
run-remote Math.log(Math.E) on rt1, rt2
? get-remoteResult(rt1)
? get-remoteResult(rt2)

The usage of RemoteTarget objects does not require to store the array returned by run-remote. The array only contains references to the RemoteTarget objects that were initially passed to the command. So the explicitly created RemoteTarget objects can be directly accessed to query results of the execution.

You can specify remote targets in a list like in the previous example or as an array.

arrRT = [new RemoteTarget("ascl1"), new RemoteTarget("ascl2")];
run-remote -file hello.js on arrRT

RemoteTarget objects let you reuse objects in subsequent run-remote command invocations, and also provide a way to manage remote client session creation.

When AutoShell executes run-remote, it connects to the specified remote system through SSH. By default, the SSH server on the remote system starts a new instance of the client AutoShell. The newly created AutoShell process evaluates the passed script and the process is destroyed after evaluation finishes. For multiple subsequent command invocation, multiple client AutoShell processes are created and destroyed on the remote system. Additionally, any context information created when running a script is lost and is not available to subsequent remote scripts.

The RemoteTarget class implements an easy to use mechanism to control the client AutoShell session creation on the remote host. Call createRemoteContext() on a RemoteTarget object to create a permanent client AutoShell session on the remote host for this RemoteTarget object:

var rt = new RemoteTarget("ascl1");
rt.createRemoteContext()

Subsequent run-remote invocations do not allocate a temporary client AutoShell session on the remote host, but rather use the permanent one created by createRemoteContext(). Additionally, any context information that is created when running a script is available to any remote scripts executed later. The permanent client AutoShell session on the remote host is automatically destroyed when the RemoteTarget object is collected. The session can also be explicitly destroyed by calling destroyRemoteContext() on the corresponding object.

The effect of using createRemoteContext() can easily be verified using the following example:

var rt = new RemoteTarget("ascl1");
rt.createRemoteContext()
run-remote X=5 on rt -wait
run-remote X on rt -wait 
? get-remoteResult(rt)
rt.destroyRemoteContext()
run-remote X=5 on rt -wait
run-remote X on rt -wait
? get-remoteResult(rt)

The second command invocation returns 5 because the variable X created in the first call still exists in the permanent client AutoShell session. When the remote client session is destroyed, the two remaining invocations trigger the creation of two temporary client AutoShell sessions. The second command returns an empty result, because the variable X was created in another session was already destroyed.

More Information

RemoteTarget Class