RexOps / Rex

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

case group #857

Closed shaitand closed 1 year ago

shaitand commented 8 years ago

For some reason case group seems to be broken.

This gives:

task "get_a", "localhost", sub { my $cmd = case group, { app => ["service siloA_tc status"], web => ["service siloA_web status"], db => ['echo "Not Applicable to DB"'], };

$ rex -E prod -G app get_a [2015-12-14 23:24:20] INFO - Running task get_a on XXXXXXX [2015-12-14 23:24:20] INFO - Connecting to XXXXXXXX:22 (YY) [2015-12-14 23:24:20] INFO - Connected and authenticated to XXXXXXXX. [2015-12-14 23:24:21] INFO - Successfully authenticated on XXXXXXX. Use of uninitialized value $group_name in hash element at /opt/totality/vzscripts/perl5/perlbrew/perls/perl-5.22.0/lib/site_perl/5.22.0/Rex/Group.pm line 91.

krimdomu commented 8 years ago

hi @shaitand , i don't think that this code ever worked as expected. Because the group function never returned the current group the was set with -G.

You can get the cli parameter with:

my %cli_opts = Rex::Args->getopts;
my $group = $cli_opts{"G"};

And then use it in your case statement:

task "get_a", "localhost", sub {
  my %cli_opts = Rex::Args->getopts;
  my $group = $cli_opts{"G"};

  my $cmd = case $group, {
    app => ["service siloA_tc status"],
    web => ["service siloA_web status"],
    db => ['echo "Not Applicable to DB"'],
  };
ferki commented 1 year ago

@shaitand: thanks for your input and patience!

TL;DR

Targeting tasks with the -G CLI option, and determining a host's host group membership may result in a list of host groups. case only matches on scalars, so it is most probably not a good fit to define dispatch tables based on host group membership.

Viable alternatives may depend considerably on the exact situation, so if this is still a problem one needs to solve, please get in touch on one of our support channels so we can learn and help more.

Longer version

group in this context is used to define a named group of hosts, to be used as a target for tasks to execute on. Calling it without passing any arguments results in an error.

Also, -G (and its -g alias) CLI option overrides the task's target defined in the code. It can take a list of host groups, so there might be multiple values coming from the CLI.

Similarly, a given target host may belong to more than one host group. So even when a target's host group membership is determined, it might not be a single value, but a list.

According to the case docs, it

is a function to compare a string with some given options.

Therefore I don't consider case to be a reliable approach for such dispatch tables to decide what to do on a given target host, and I would recommend looking into describing the desired logic in more precise ways.

Making code decisions on a host's host group membership may be highly situational and opinionated, so I find it hard to come up with a generally useful alternative without more context.

One approach could be to use the internal get_groups() and get_servers() from Rex::Group and/or get_groups() from Rex::Group::Entry::Server to get a list of host groups the given host is a member of. And then make decisions based on the elements of that list.