0

How can Rundeck execute a remote commands with multi-values?

Allowed values: folder1,folder2,folder3

Multi-valued: [x]Yes

Need to execute a remote commands on remote node:

/home/$folder1/run.sh

/home/$folder2/run.sh

/home/$folder3/run.sh

Inline script or something else?

2 Answers2

0

Yes, an inline script is probably easiest for this case.

Below is a job definition that shows how to parse the multi values in a bash script:

- description: 'execute script with an option using multiple values' executionEnabled: true loglevel: INFO name: SO-48341496 nodeFilterEditable: false options: - delimiter: ',' enforced: true multivalued: true name: folders required: true values: - folder1 - folder2 - folder3 scheduleEnabled: false sequence: commands: - args: ${option.folders} script: |- #!/usr/bin/env bash IFS=',' read -ra FOLDERS <<< "$1" for folder in "${FOLDERS[@]}" do echo "execute '/home/$folder/run.sh'" done keepgoing: false strategy: node-first

Alex-SF
  • 176
  • 2
0

I'd like to share my answer here as well.

Whenever you use a multivalued option on Rundeck, you are given the option to provide a delimiter between the multiple values. Regardless of the delimiter you choose the values will be converted into the following form:

<value1><delimiter><value2><delimiter><value3><delimiter>...

If you choose a blank space as a delimiter, the values will be converted to:

<value1> <value2> <value3> ...

Scripts have issues recognizing these values as $1,$2,$3... Everything gets put in $1 for some reason - I guess Rundeck converts everything into:

'<value1> <value2> <value3> ...'

but I am not 100% sure about this.

The solution, usually, is to split this string of arguments into separate arguments based on the delimiter. However, if your target script is a bash script (.sh) then this, may or may not be as easy.

In my opinion there are a couple of solutions to this:

  • Solve this in the bash script itself as Alex-SF said above. However, you should know that this is not as straight forward as it seems. See this stack overflow answer for details.
  • Convert the functionality of the bash script into a script of a different language (Perl, Python, Java, ...) that supports splitting of strings. Call this new script from Rundeck instead of the bash script. This may not be desirable in some cases because the bash script can be complex and converting it might not be as easy or possible.
  • Use a helper script written in a different language (Perl, Python, Java, ...) that supports splitting of strings. Call this script from Rundeck and from this script call the bash script after correctly doing the splitting. Example in perl:
#!/usr/bin/perl
use strict;
use warnings;
use 5.16.3;

my $rundeck_input = $ARGV[0];
my @arguments = split(';',$rundeck_input);
my $final_str="";
my $i = 0;
foreach my $ele ( @arguments ) {
  $final_str = $final_str . '\'' . $ele . '\'';
  if ($i == ($#arguments)) {
  }
  else {
      $final_str = $final_str . " ";
    }
  $i++;
}
system("/usr/bin/bash /home/rundeck/scripts/myscript.sh $final_str");

In the example above I used ; as a delimiting character as it is nearly impossible to appear in any of the arguments that someone enters on Rundeck. The perl script splits the string of arguments into multiple arguments and provides it to the bash script as:

'<value1>' '<value2>' '<value3>' ...

Maybe it is an even better idea to provide these as separate arguments in that system() call. There surely are more sophisticated ways of doing this. This is just an example.

Erica993
  • 3
  • 2