Core Plugin Support
[GOAL]
Plugins allow external projects to extend the behavior of the juju command-line interface (CLI), in a very simple manner (they can add new commands, but not change existing functionality, and they MUST be built on top of the public API of Juju itself (though they MAY use other API's to build interactions with other external tools)
[RATIONALE]
Allow inovation to happen outside of the core, and encourage ecosystem partners to build on top of Juju.
Blueprint information
- Status:
- Complete
- Approver:
- Mark Ramm
- Priority:
- Low
- Drafter:
- Tim Penhey
- Direction:
- Approved
- Assignee:
- Tim Penhey
- Definition:
- Approved
- Series goal:
- None
- Implementation:
- Implemented
- Milestone target:
- 1.11.0
- Started by
- Tim Penhey
- Completed by
- Tim Penhey
Related branches
Related bugs
Whiteboard
[USER STORIES]
Adding Custom Functionality
-------
The juju CLI has a set of builtin subcommands,
$ juju <subcommand>
such as 'status' or 'deploy'.
The plugin system will allow a user to define their own subcommand
$ juju mycommand
simply by creating an executable named 'juju-mycommand' and placing it in their executable path.
For example, save the following
#!/bin/bash
watch -n60 'juju status'
to the file '~/bin/
Insure the file is executable and that '~/bin' is in your PATH
$ chmod +x ~/bin/juju-
$ export PATH=$HOME/
and then call the newly-available 'watch-status' juju subcommand
$ juju watch-status
The flexibility of this approach also allows Juju to remain language-neutral for the end-user. Plugins can be written
in any language that runs on the client platform.
Plugin Arguments
----------------
Each subcommand typically accepts its own set of arguments
juju deploy --repository <repo> <charm-name>
and that works for plugins as well.
To continue the simple example from above,
juju watch-status -n30
can be handled with a '~/bin/
#!/bin/bash
#TODO use args
*NOTE* Juju passes arguments relative to the subcommand, so $0 would be the subcommand name and not 'juju'.
A more realistic version of the above would insure any extra arguments would get passed to the wrapped subcommand. I.e.,
juju watch-status -n30 --format json
can be handled
#!/bin/bash
#TODO use args, then shift and pass args
[ASSUMPTIONS]
[RISKS]
[IN SCOPE]
[OUT OF SCOPE]
[USER ACCEPTANCE]
[RELEASE NOTE/BLOG
[IMPLEMENTATION NOTE]
== environment ==
The current environment will be passed through to the plugin using the JUJU_ENV environment variable. This is irrespective of how that current environment was determined by juju. This means that it works with the default environment from the environments.yaml file, the new current-environment defined by juju switch, someone using JUJU_ENV inside the environment that is calling the juju plugin, or someone using a -e swich on the plugin command line.
If a user calls a plugin like
juju watch-status -e foo -n30 --format json
This will end up calling the juju-watch-status executable with the arg list ["-n30", "--format", "json"] and the environment JUJU_ENV is set to foo.
== discovourability and help ==
Since plugin writers have ultimate flexibility in what they write, I'd like to propose a standard to help with the discovourability. Each plugin, no matter what the language, should support two different argument calls:
--description
returns a single line description of the plugin
--help
longer information about what the plugin is and how it is called
=== Rationale ===
We want to have 'juju help plugins'
I would like this to start with how plugins are found and called, followed by a list of plugins found on the users system. For each plugin, I would like this call to exec the plugin with the sole parameter --description. For both the help and description calls, JUJU_ENV would be set to ""
By having --help, we could have the help mechanism hook into showing the help for the plugins.
While we can land plugin support without either of these, I would like to start with plugins that support this so when people copy them, they do so with good practice.
Work Items
Work items:
[thumper] Implement the supercommand fallthough callback for cmd.SuperCommand: DONE
[thumper] Provide an implementation for juju that looks for 'juju-command': DONE
[thumper] Make sure the -e environment is extracted properly: DONE
[thumper] Implement 'juju help plugins' to return the installed plugins: DONE
[thumper] Land the code in trunk: DONE