Scripting

Batching Commands

The simplest scripting mechanism is to batch appliance shell commands. For example,
to automatically take a snapshot called "newsnap" in the project "myproj" and
the filesystem "myfs", put the following commands in a file:

shares
select myproj
select myfs
snapshots snapshot newsnap

Then ssh onto the appliance, redirecting standard input to be the file:

% ssh root@dory < myfile.txt

In many shells, you can abbreviate this by using a "here file",
where input up to a token is sent to standard input. Following
is the above example in terms of a here file:

This mechanism is sufficient for the simplest kind of automation, and may
be sufficient if wrapped in programmatic logic in a higher-level shell scripting
language on a client, but it generally leaves much to be desired.

Scripting

While batching commands is sufficient for the simplest of operations, it can
be tedious to wrap in programmatic logic. For example, if you want
to get information on the space usage for every share, you must
have many different invocations of the CLI, wrapped in a higher level
language on the client that parsed the output of specific commands. This
results in slow, brittle automation infrastructure. To allow for faster and most robust
automation, the appliance has a rich scripting environment based on ECMAScript 3. An ECMAScript
tutorial is beyond the scope of this document, but it is a
dynamically typed language with a C-like syntax that allows for:

The built-in dump function dumps the argument out, without expanding any embedded
newlines. ECMAScript's string handling facilities can be used to take apart
output. For example, splitting the above based on whitespace:

The Get Function

The run function is sufficiently powerful that it may be tempting to
rely exclusively on parsing output to get information about the system --
but this has the decided disadvantage that it leaves scripts parsing human-readable
output that may or may not change in the future. To more
robustly gather information about the system, use the built-in "get" function. In
the case of the boot_time property, this will return not the string
but rather the ECMAScript Date object, allowing the property value to be
manipulated programmatically. For example, you might want to use the boot_time property
in conjunction with the current time to determine the time since boot:

Assuming the above is saved as a "uptime.aksh", you could run it
this way:

% ssh root@dory < uptime.aksh
Pseudo-terminal will not be allocated because stdin is not a terminal.
Password:
up 2 days, 10 hours, 47 minutes, 48 seconds

The message about pseudo-terminal allocation is due to the ssh client; the
issue that this message refers to can be dealt with by specifying
the "-T" option to ssh.

The List Function

In a context with dynamic children, it can be very useful to
iterate over those children programmatically. This can be done by using
the list function, which returns an array of dynamic children. For example,
following is a script that iterates over every share in every project,
printing out the amount of space consumed and space available:

The Children Function

Even in a context with static children, it can be useful to
iterate over those children programmatically. This can be done by using
the children function, which returns an array of static children. For example,
here's a script that iterates over every service, printing out the status
of the service: