Core Plugin Support

Registered by Antonio Rosales

[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:
milestone icon 1.11.0
Started by
Tim Penhey
Completed by
Tim Penhey

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/juju-watch-status'.

Insure the file is executable and that '~/bin' is in your PATH

    $ chmod +x ~/bin/juju-watch-status
    $ export PATH=$HOME/bin:$PATH

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/juju-watch-status' like the following

    #!/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

This blueprint contains Public information 
Everyone can see this information.