RexOps / Rex

Rex, the friendly automation framework
https://www.rexify.org
716 stars 223 forks source link

Passing args to tasks is awkward #623

Open kablamo opened 9 years ago

kablamo commented 9 years ago

I'd like to limit the number of tasks Rex can do at a time to 1. That way all arguments after the task name can be passed to the task. For example:

rex Unix:ls -l /etc

would result in `-l /etc' being passed to the task Unix::ls() in some way. The only way to do this currently is to do something really awkward like:

rex Unix:ls --l --dir /etc

How would you feel about a pull request that did something like this? I realize there are a lot of details that need to be worked out here.

krimdomu commented 9 years ago

Hi @kablamo

if this is possible without changing the current behaviour we welcome any patches. There is already a task on the backlog (without a ticket yet) to refactor the argument parsing. Maybe we can do this together in one step. Maybe there is a nice CPAN module that can do this?

kablamo commented 9 years ago

Currently Rex (sort of) allows you to do more than one task at a time. So for example:

rex -G group task1 task2

task1 runs for each server in "group". However task2 seems to run on the local machine only.

I want to only allow Rex to do one task at a time. So in the above example, the string "task2" would get passed as an argument to task1 (in some backwards compatible way) and task2 would not run.

Does that count as changing current behavior? <-- The part about only doing one task at a time, I mean.

kablamo commented 9 years ago

Hmm after reading some more of the documentation I think that would count as breaking backwards compatibility.

kablamo commented 9 years ago

I'm interested in getting involved in refactoring argument parsing. What specific goals did you have in mind?

One way to break backwards compatibility without affecting any users would be to create a new command line util with a different name. Or maybe just something that wraps the 'rex' script.

krimdomu commented 9 years ago

Well,

i think we can add a new feature flag for example 1.3 (if the new arg parser is part of version 1.3) which will enable this new arg parser. So there is no problem for people who are using an older feature flag. This would be a little bit of a hack, because currently the arguments are parsed before the Rexfile is parsed. So we would ne to parse the Rexfile twice. The first time to check which feature flag is enabled, then parse the arguments and then load the Rexfile for real.

Another option would be to try to autodetect which parser should be used (i would vote for this one).

For example if we define that we wan't to have a more generic cli interface:

Syntax:
rex $action @options

To execute a task

rex execute $task
rex execute $task -u user -p password --foo=bar --action=fun

To query modules.rexify.org

rex search apache

To download a module from modules.rexify.org, git, ...

rex download https://github.com/RexOps/rex-apache.git

Or to publish a module to modules.rexify.org (or a private rex recipes repository)

rex publish

To create a new Rex project:

rex new MyProject

@ferki What do you think?

kablamo commented 9 years ago

And

rex tasks [topic]

The clarity and flexibility are really tempting. I was initially wanting this. But its so much work to type rex execute. rex is nice and short. I have mixed feelings about it. Another thought is to keep rex usage very simple and put all those subcommands into another script called rex-control or something. I'm not sure.

krimdomu commented 9 years ago

well, i think the new parser can also handle rex $task so that the short version will work :)

kablamo commented 9 years ago

So then you wouldn't be able to name any of your tasks tasks, new, publish, download, search, or execute. Or rather you could, but you would have to use the rex execute to do them

ferki commented 9 years ago

I find those ideas interesting, but I need some more time to think about them. I also believe that we started to talk about 2 or 3 smaller problems instead of a single big one.

krimdomu commented 9 years ago

So, i just started with implementing a new cli parser that is based on MooX::Cmd and MooX::Options.

Current state

I have pushed the current code state to my private repo: https://github.com/krimdomu/Rex/tree/feature/new-cli/lib/Rex/CLI

An example can be found in this other branch which is adding Rex-Overlord commands. (Rex-Overlord will be a rex server)

https://github.com/krimdomu/Rex/tree/feature/overlord/lib/Rex/CLI

What this is technically doing is this:

With PPI the rex command (https://github.com/krimdomu/Rex/blob/feature/new-cli/bin/rex) first try to detect if the cli_v2 feature should be activated.

This is done in Rex::DetectCLI::detect_cli (https://github.com/krimdomu/Rex/blob/feature/new-cli/lib/Rex/DetectCLI.pm). This function returns which version of the cli parser rex shoud load.

With this we can now write a new cli parser without compromising already running Rex installations and give people the time to migrate to the new cli as soon as we decide to make the new cli the default one.

Next steps

kablamo commented 9 years ago

Awesome. I was going to do that. I'll take a look

krimdomu commented 9 years ago

I've pushed the feature/new-cli branch to this repository. So it is easier to contribute to it.

kablamo commented 9 years ago

I've been thinking about the command line UI too. I"ve been trying to evolve the current cli to something that works like this:

rex task                                     # execute task on localhost
rex namespace:task                           # execute namespace:task on localhost 
rex task option=value                        # execute task with options
rex task arg1                                # execute task with arguments
rex task arg1 option=value                   # execute task with arguments and options 
rex -H host task option=value                   # execute task on a host
rex -G group task arg1 arg2                     # execute task on a group
rex -H host task1 arg1 arg2 task2 option=value  # task chaining
rex tasks                                    # list tasks
rex batches                                  # list batches
rex environments                             # list environments
rex groups                                   # list groups
rex sometask -h                              # show usage for a task

One thought I keep having is that the root level namespace should be reserved for subcommands and all user created tasks should live somewhere else.

krimdomu commented 9 years ago

@kablamo yes this looks good. and also the idea with the root level namespace. i think it would be good to have it this way, because then we can custom commands to it. Like migrating all the rexify commands.

And it would be cool to have the ability to extend these root-level commands with custom plugins.

rex project Foo                         # to create a new project
rex search foo                          # to search online for a module named foo
rex use Foo                             # download Foo module and install it into lib folder
rex webserver                           # to start a webserver for the current project for a webui
rex some-other-interessting-stuff
...

Edit: grmpf i wrote nearly the same thing a few comments above :D