The Cloudify Script Plugin from the Inside Out
Hot on the heels of Barak’s previous post, that explores new features and functionality available in 3.1, I’d like to take a deeper technical dive into a specific feature, so you can have a bit of a better understanding how to really leverage these new tools. In this post I’m going to focus on the newly added Script Plugin that fuses together the functionality of two plugins (the Bash and Python plugins) to bring the best of both worlds together.
The basic functionality of the script plugin provides the ability to execute scripts. These are commonly bash scripts, but can generally be written in any language – including Python, Ruby, PowerShell, etc… (whatever is supported in your agent’s environment).
3.1 with plugins galore. Get it now. Go
The unique aspect of this specific plugin, that has earned it a post of its own, is the fact that although the script plugin is indeed a plugin just like all the rest and is based on the standard plugin API; it provides a mechanism for executing scripts that users write. These scripts are capable of using the full plugin API functionality, without actually writing a full-blown plugin (i.e. with all of the boilerplate and plugin structure you would need for any other plugin).
There are a few neat things you can do with this plugin. First, although the script plugin can run scripts written in any language, Python scripts get special treatment. You can pretty much write the same code you would write in a full-fledged plugin without all the boilerplate, and the script plugin will evaluate the code within the context of the script plugin. Other scripts that we may run, will be executed in an external process.
Another nifty feature of the script plugin is the CTX executable feature, which enables scripts written in languages other than Python to use the same context object that is used by plugins. This is essentially a CLI client that implements a simple protocol on top of ZeroMQ or HTTP.
What this means practically, is that the CTX executable could potentially be used by any language because it’s simply an external process that you call. While the provided CTX executable is largely best suited for shell scripts, if someone chooses to implement a CTX client in Ruby, for example, it can provide a lot of syntactic sugaring to simplify the experience without a lot of effort.
This proxied context is the main entry point, generally speaking, when you write any plugin for accessing information about your deployment, your node instances and their properties/runtime properties, etc… While it sounds simple enough, in practice, it allows you to do powerful things.
As an example, let’s say you are implementing a relationship operation and you want to read the port runtime property of the target node instance. Without this functionality, you would have to make a REST call to the manager REST service, parse the JSON response and extract the runtime property you are interested in (a lot of boilerplate). Using the CTX executable, it’s as simple as:
port=$(ctx target instance runtime-properties port)
Our DSL parser was also extended to make mapping operations to scripts much simpler. Without the extension to the DSL parser, in order to map an operation to a script, you would have to do something like this:
In the previous example, we mapped some script to the create operation. This is nice, but also very verbose. Now, doing exactly the same thing, this time using the sugared API:
Well, that’s about it for now. You can read the docs here, and play around with it.