[katello-devel] Foreman CLI - design proposal the Ruby way

Petr Chalupa pchalupa at redhat.com
Tue May 7 08:56:37 UTC 2013


+1 for Kartit

We can start with the system wrapper for now and later get rid of python 
completely.

Both proposals are meeting the requirements, but kartit is in Ruby which 
I think is a BIG plus.
  * developers do not have to know two languages
  * one ecosystem for the whole project (Ruby's)
  * code sharing between CLI and Katello is possible allowing DRYness

DRY-ification example:
Let say that product (and other models) says about itself that it can be 
identified by `id` or by `[org_name, env_name, name]`. This information 
can be used to dynamically set options on a product-needing-command as 
`--id` or `--org --env --product`.

Also API documentation can be used. I think that with a little more work 
we can make most of the CLI to just reuse information placed elsewhere 
eliminating maintenance to a minimum.

Petr

On 03.05.13 9:18, Martin Bacovsky wrote:
> Hi,
>
> as Tomas announced a couple of days ago, here is my proposal for CLI
> design implemented in Ruby.
>
> For better reading experience and code to play with check
> https://github.com/mbacovsky/foreman_cli_draft
>
> Comments and questions are wellcome!
>
> Regards,
>
> Martin
>
> Foreman CLI design draft
> ========================
>
> This is my attempt to create outline of CLI client for the Foreman. The
> Foreman project has Ruby as its main langauage, so I choosed to explore
> the options Ruby world is offering to complete this task.
>
> My initial requirements are as follows:
>
>   - [x] implemented in Ruby
>   - [x] Git-like subcomands in CLI app
>   - [x] system shell autocompletion of commands and options
>   - [x] shell-like environment with autocompletion and history where the
> commands can be run directly
>   - [x] commands extensible via plugins
>   - [x] some way to wrap current Katello CLI commands and make it
> possible to have one CLI client for both
>   - [x] simillar UX as from katello CLI
>
>   All the requirements were addressed by the design. Though there is
> plenty of room for clean up and optimisation, the draft can serve as a
> proof of concept.
>
>
> Design
> ------
>
> ![Design draft](design.png)
>
> As the diagram shows, the CLI consist of almost generic framework
> (shell-like environment, autocompletion, command help text, option
> evaluation and command invocation) and set of plugins defining the
> actual commands. This setup is flexible and allows us to easily install
> different sets of commands for different products. The plugins are
> independant and can implement any action as an command, so that besides
> commands calling Foreman API you can have commands calling varius admin
> tasks on the server, etc.
>
> For real implementation of the plugins there would need to be some
> decision taken on how to approach the development of the actual commands.
>
> For *Katello* commands, there can be great deal of work done
> automatically (using Katello CLI autocompletion feature and templates).
> However calling Katello CLI via system call is not ideal solution and
> should be replaced by direct calls to Katello API in the future.
>
> For *Foreman* Commands development I can see three options
>   - generate and sync some generic CLI commands (apipie approach) with
> option to inherit and redefine individual commands
>   - manually create everything (Katello CLI approach)
>   - dynamic creation on the fly with option to exclude and manually
> define specific commands
>
> Sample working implementation you can find in this repo.
>
>   - [kartit]
> (https://github.com/mbacovsky/foreman_cli_draft/tree/master/kartit) gem
> contains generic CLI client
>   - [kartit-foreman]
> (https://github.com/mbacovsky/foreman_cli_draft/tree/master/kartit-foreman)
> gem contains Foreman related commands definition
>   - [kartit-katello]
> (https://github.com/mbacovsky/foreman_cli_draft/tree/master/kartit-katello)
> gem contains Katello related commands definition
>
>
> Pros and Cons
> --------------
>   - [+] same implementation language as the rest of the project
>   - [+] generic CLI, easy to extend by adding gems with commands
>   - [+] lightweight design
>   - [-] calling katello via *system* or need to create native Katello
> plugin
>
>
> Technologies
> ------------
>
> ### CLI Framework
>
> There is plenty of CLI framework gems with varying features and quality
> on the Internet. I took into consideration [Thor][thor] for its wide
> spread, [Boson][boson] for its features being very close to our
> requirements and [Clamp][clamp] for its simplicity.
>
> To compare them I played with each of them for a while - _Thor_ has well
> docummented features and good suport in the community. However the
> codebase was for me quite cryptic and really dificult to understand and
> extend. It seems good when you need what is built in. If you need
> something extra adding is time consuming or requires skills beyond mine.
> _Boson_ has good documentation, nice set of plugins available, live
> upstream and what makes it special for us is built in shell with
> autocompletion. What put it out of the game is lack of subcommands.
> _Clamp_ has very similar features as Thor has but it has minimalistic,
> clean and straghtforward codebase. It uses one class per command which
> can come handy if you need similar behavior for subset of commands. It
> was quite easy to add autocompletion and shell. And yes it is the winner
> for my CLI draft.
>
>
> ### Shell
> For shell there is not so much options. There is IRB and similar like
> Ripl but I started with minimalistic and Readline. It went quite smooth
> so I  kept it and didn't tried the others
>
>
> ### Autocompletion
> I wanted to have one solution for Bash and shell autocompletion and
> started with simple method recursively looking for endings in command
> tree. Simple bash wrapper call made it ready for use in bash. In
> shell-like env based on Readline I had dificulties with the fact that
> readline support autocompletion based on last word and there is no
> apparent way to take the context into account. I found some workaround
> but still looking for cleaner solution. Maybe Ripl + Bond are worth trying
>
>
> ### Input/Output
> I didn't focus much on processing of input and output in the commands
> yet. For Foreman commands I'd like to keep it as similar to Katello
> output as possible. There are gems like highline and
> [table_print][table-p] that could make it easy.
>
>
> Usage
> -----
> And here follows short demo of the features this CLI draft offers
>
> ### Help
>
>      $ kartit -u admin -p admin -h
>      Usage:
>          kartit [OPTIONS] SUBCOMMAND [ARGS] ...
>
>      Subcommands:
>          shell                         Interactive Shell
>          architecture                  Manipulate Foreman's architectures.
>          environment                   Manipulate Katello's environments.
>          ping                          Get the status of the katello server
>
>      Options:
>          -v, --verbose                 be verbose
>          -u, --username USERNAME       username to access the remote system
>          -p, --password PASSWORD       password to access the remote system
>          --version                     show version
>          --autocomplete LINE           Get list of possible endings
>          -h, --help                    print help
>
>
>      $ kartit -u admin -p admin architecture -h
>      Usage:
>          kartit architecture [OPTIONS] SUBCOMMAND [ARGS] ...
>
>      Subcommands:
>          list                          List foreman's architectures.
>
>      Options:
>          -h, --help                    print help
>
>
> ### Foreman call
>
> As it was said above output formating for foreman commands is still
> missing and will be added later
>
>      $ kartit -u admin -p admin architecture list
>      [
>          [0] {
>              "architecture" => {
>                                 "name" => "i386",
>                                   "id" => 5,
>                           "created_at" => "2012-06-27T17:21:16Z",
>                  "operatingsystem_ids" => [],
>                           "updated_at" => "2012-06-27T17:21:16Z"
>              }
>          },
>          [1] {
>              "architecture" => {
>                                 "name" => "ppc",
>                                   "id" => 9,
>                           "created_at" => "2012-07-31T12:19:26Z",
>                  "operatingsystem_ids" => [],
>                           "updated_at" => "2012-07-31T12:19:26Z"
>              }
>          },
>          [2] {
>              "architecture" => {
>                                 "name" => "x86_64",
>                                   "id" => 14,
>                           "created_at" => "2012-08-06T15:51:21Z",
>                  "operatingsystem_ids" => [],
>                           "updated_at" => "2012-08-06T15:51:21Z"
>              }
>          }
>      ]
>
>
> ### Katello call
>
>      $ kartit -u admin -p admin environment list --org ACME_Corporation
>      katello -u admin -p admin environment list --org ACME_Corporation
>
> ------------------------------------------------------------------------------------------------------------
>
>                                                Environment List
>
>      ID Name    Label   Description Org              Prior Environment
>
> ------------------------------------------------------------------------------------------------------------
>
>      1  Library Library None        ACME_Corporation None
>      2  Dev     Dev     None        ACME_Corporation Library
>      3  Prod    Prod    None        ACME_Corporation Dev
>
> ### Autocompletion
>
>      $ kartit architecture
>      -h      --help  list
>      $ kartit architecture list -
>      -h      --help
>
> ### Shell
>
>      $ kartit -u admin -p admin shell
>      kartit> -h
>      Usage:
>          kartit [OPTIONS] SUBCOMMAND [ARGS] ...
>
>      Subcommands:
>          shell                         Interactive Shell
>          architecture                  Manipulate Foreman's architectures.
>          environment                   Manipulate Katello's environments.
>          ping                          Get the status of the katello server
>
>      Options:
>          -v, --verbose                 be verbose
>          -u, --username USERNAME       username to access the remote system
>          -p, --password PASSWORD       password to access the remote system
>          --version                     show version
>          --autocomplete LINE           Get list of possible endings
>          -h, --help                    print help
>      kartit> ping
>      katello -u admin -p admin ping
>
> -----------------------------------------------------------------------------------------------------------
>
>                                                    Katello Status
>
>      Status Service        Result Duration Message
>
> -----------------------------------------------------------------------------------------------------------
>
>
>      FAIL
>      candlepin      ok     141ms
>      candlepin_auth ok     225ms
>      elasticsearch  ok     795ms
>      katello_jobs   FAIL   katello-jobs service not running
>      pulp           ok     1706ms
>      pulp_auth      ok     618ms
>
>
> [cli-gems]: http://www.awesomecommandlineapps.com/gems.html "CLI related
> gems"
> [thor]:  https://github.com/wycats/thor "Thor homepage"
> [boson]: https://github.com/cldwalker/boson "Boson homepage"
> [clamp]: https://github.com/mdub/clamp "Clamp homepage"
> [table-p]: https://github.com/arches/table_print "table-print homepage"
>
> _______________________________________________
> katello-devel mailing list
> katello-devel at redhat.com
> https://www.redhat.com/mailman/listinfo/katello-devel




More information about the katello-devel mailing list