Introducing OpenWhisk Shell

The Apache OpenWhisk project is an open source serverless computing platform. It currently offers a conventional CLI development and management experience, in the form of the wsk tool. Generally, I’m a pretty big fan of command line tools. The CLI experience is pleasantly non-modal. You can switch from one task to another, without having to click a half dozen close buttons, followed by navigating through byzantine navigational structures to work your way to your next task. Plus, you can easily persist your thought process, by pasting commands into a shell script.

In addition to remembering and automating your activities, CLI operations facilitate learning. They are easily shared, and can form the basis of helpful tutorials. Watching videos is nice, but commands and scripts can be Slack’d, and copied into my environment without having to transcribe a picture.

All is not rosy, however, with CLIs, especially when it comes to cloud development. The commands for interfacing with most cloud providers are pretty low-level, more geared towards automation than iterative exploration of the complex world of APIs. Worse, the output of most operations against cloud APIs are often large and deep JSON data structures. Interaction with APIs involves frequent jq interludes, and the tedious copy-paste transfer of data from one operation to the next.

Hybrid Tooling For a while now, we’ve been contemplating the possibility of a hybrid approach to interacting with cloud services. Use a CLI style of interaction for the command structure, but weave in graphics where it helps.

Local development is also important, so we don’t have to endure the often laggy nature of browser-based tools. Access to our local filesystem is key. Happily, with the advent of Electron, it is possible to develop a rich local dev environment that suits these needs.

Lucid The OpenWhisk Shell is the product of this thought process. It provides powerful and lucid commands for manipulating assets and viewing OpenWhisk activations.

Special care has been taken to offer a command set that is syntactically both familiar and lightweight. Important tasks can be accomplished via a single command, rather than requiring multiple commands and a bash script. The latter situation is frustratingly common with cloud development. CLI tools are often direct reflections of an underlying low-level REST API, necessitating some form of scripting layer on top of the CLI commands. Oftentimes, scripts are required for even simple tasks, because the APIs are truly raw. You can see this evident in every OpenWhisk tutorial out there.

Graphical To help with visualizing the output of commands, and with bridging from one command to the other, the shell provides graphical assistance. Every reference to an OpenWhisk entity, or to a previously executed command, is a clickable link. For example, after listing one’s actions via the ls command, clicking on the name of an action opens the sidecar and has the details of that action displayed in a pleasant form.

One last thought, for now, that we’ll expand on in subsequent articles. Most command line tools take a staid approach to context, and the wsk tool is no exception here. For example, to create, then execute a function in OpenWhisk involves at least these two commands:

wsk action update foo foo.jswsk action invoke foo -p name dhalgren

It gets worse in the common case where you need the action to be in a package. Say you want to create a packaged action, invoke it, then invoke it again with a different parameter; for good measure, we delete the action when we’ve discovered we made a mistake:

Note the repeated bits? Both the command context, i.e. wsk action, and the entity context (you just created public/foo) must be repeated. The OpenWhisk Shell has a unique take on context, allowing for a more conversational approach to command execution. Here, we show the use of the let command to create an function directly from a NodeJS expression (note how we are creating an echo action using the NodeJS arrow notation: x=>x, in this example), followed by invocation of that newly created action:

let public/foo = x=>xinvoke -p name dhalgreninvoke -p name delanyrm

The syntactic clutter is greatly reduced, and asset creation can be accomplished with a single command. A tutorial describing this scenario, using wsk, would also have to document how to transfer that code to a file, come up with some file name (e.g. foo.js in the above examples), and then delete that file when done.