Development guide - mrvisser/node-cowboy GitHub Wiki
Cowboy modules, which contain command plugins, are packaged as NPM modules. There is some metadata that is required to set in order for cowboy to identify it as such. Those requirements are discussed here.
cowboy.json
If your NPM module provides cowboy plugins, it needs to have a cowboy.json
file that sits in the same directory as the package.json
file. Currently, the cowboy.json
file only contains one metadata key: plugins.dir
, which indicates where (relative to the module root) the cowboy plugins directory is. If unspecified, it defaults to plugins
, which means there should be a plugins
directory in the root of your module.
If you are using the default plugins directory, your cowboy.json
file can actually just have the contents {}
, but it is necessary to have the file there with the empty object in order for it to be identified as a cowboy module.
The plugins
directory should contain a directory commands
with JavaScript files that provide implementations of the Command
prototype. The file name of those JavaScript files are the command name. Therefore, given this sample module file hierarchy:
cowboy.json
package.json
plugins/
commands/
ping.js
install.js
uninstall.js
describe.js
This represents a module with commands ping
, install
, uninstall
, describe
.
Command Prototype
There is a simple command prototype that can be implemented to customize various functionality of the command. The command is instantiated at the time that the command is invoked with new Command()
, therefore the object can be stateful from the start of the command (constructor) through out to the end of the command (when end
is invoked). All command methods are invoked on the cowboy client at the time in the command lifecycle specified, except the exec method which is actual command logic invoked on the cattle server.
The full documented command prototype is available in the source. I recommend you copy/paste it and work from it, as well as use the core command implementations as a reference. With the prototype, you can implement the following methods:
help
- (optional) Describe how the help content of the plugin should lookvalidate
- (optional) Validate the command arguments before sending any data to the cattle serverstimeout
- (optional) Specify the idle timeout of the command. Basically, the maximum duration allowed by the cowboy client between receiving a reply frame from any data nodebefore
- (optional) Invoked on the cowboy client to output any preliminary header information, or store any preliminary state (seeping.js
as an example of storing preliminary state)exec
- (required) The only function invoked on the cattle server. This actually carries out the logic of the command execution on the cattle serverhostEnd
- (optional) Invoked on the cowboy client whenever one of the hosts has finished its execution. This can be used to give on-the-fly output as cattle servers complete their taskend
- (optional) Invoked on the cowboy client when all live cattle servers have finished their execution
World's Simplest Cowboy Command
This is a really simple command that just replies with "pong" and outputs the results from each host to the command line:
var Command = module.exports = function() {};
Command.prototype.exec = function(ctx, reply, done) {
reply('pong');
return done();
};
Command.prototype.end = function(ctx, responses, expired, done) {
console.log(JSON.stringify(responses, null, 2));
return done();
};
Testing Your Module
Being good little developers, we ensure we test our modules. There is a utility API node-cowboy-cli-api which can be included in your project to run a cattle server in TravisCI and invoke cowboy commands. An example of it being used is in the cowboy-exec module which uses Grunt and Mocha to facilitate continuous integration testing.
Publishing Your Module
Once you have your command(s) implemented and tested, you can publish it the way you would publish any other npm module:
- If you want to distribute it through NPM (recommended), use
npm publish
to make it available- When published this way, it can be installed with:
cowboy install my-cowboy-module
- When published this way, it can be installed with:
- If you want to distribute it through GIT, simply leave it in git
- The module can then be installed with:
cowboy install git://github.com/my-repo/my-cowboy-module
- The module can then be installed with: