Incorporating Machines.pm into rexec.pl
authorAndrew DeFaria <Andrew@DeFaria.com>
Fri, 20 Jul 2018 15:47:14 +0000 (08:47 -0700)
committerAndrew DeFaria <Andrew@DeFaria.com>
Fri, 20 Jul 2018 15:47:14 +0000 (08:47 -0700)
bin/rexec.pl

index 4cc0eff..1c61a3f 100755 (executable)
@@ -55,7 +55,7 @@ $Date: 2008/02/29 15:09:15 $
 
 This script will perform and arbitrary command on a set of machines. It uses the
 Rexec module which utilizes Perl::Expect to attempt a connection using ssh, rsh
-and finally telnet. Username and password can be suppliec (or set up ssh 
+and finally telnet. Username and password can be supplied (or set up ssh 
 pre-shared key) to log in. This is especially important when ssh'ing into
 Windows machines using Cygwin and wanting to use network resources. If you ssh
 into a Windows box using pre-shared key then Windows will not have your 
@@ -64,6 +64,36 @@ file systems. Therefore on Windows machines, do not set up preshared key if you
 wish to access remotely mounted file systems. Instead supply the username and 
 password (hopefully in a secure manner).
 
+Machines:
+
+The list of machines that will be operated on can be specified in the machines
+option but is more often obtained using a Machines module. The default Machines
+module will parse a flat file that lists machine names and the characteristics
+of those machines (OS version, CPU count, owner - See Machines.pm). If a
+different mechanism is used to store and retrieve machine information then the
+use can write a replacement for the Machines module. This replacement must
+present an object oriented approach at supplying the qualifying machines by
+supporting the following methods:
+
+new: Create new Machines object
+
+find: Find machines based on a specified condition (e.g. OS = "Ubuntu 18.04")
+
+next: Return the next qualifying machine
+
+Logging and reruning:
+
+If -log is specified then a directory will be created based on the machine's
+name in -logdir (default current directory) where all output will be written to 
+a log file named $machine/$machine.log. The command attempted will be written to
+$machine/command and the status will be written to $machine/status. If instead
+the we were not able to connect to the remote machine, often because the machine
+was down, then the $machine directory will only have the command file indicating
+that the command was not run on the remote machine. This allows the -restart
+parameter to work. When run with -restart, rexec will exam all log directories
+to see which ones only contain a command file and attempt to execute them on
+$machine again.
+
 =cut
 
 use FindBin;
@@ -78,16 +108,18 @@ use CmdLine;
 use Display;
 use Logger;
 use Rexec;
+use Machines;
 
-my ($currentHost, $skip, $log);
+my ($currentHost, $log);
 
 my %opts = (
   usage    => sub { pod2usage },
   help     => sub { pod2usage (-verbose => 2)},
   verbose  => sub { set_verbose },
   debug    => sub { set_debug },
-  username => $ENV{REXEC_USER} ? $ENV{REXEC_USER} : $ENV{USER},
+  username => $ENV{REXEC_USER} || $ENV{USER},
   password => $ENV{REXEC_PASSWD},
+  filename => $ENV{REXEC_MACHINES_FILE} || '/opt/clearscm/data/machines',
 );
 
 sub Interrupted {
@@ -190,6 +222,9 @@ GetOptions (
   'username=s',
   'password=s',
   'log',
+  'logdir',
+  'filename=s',
+  'database',
   'machines=s@',
 ) or pod2usage;
 
@@ -202,17 +237,24 @@ unless ($opts{machines}) {
   $opts{machines} = [$ENV{REXEC_HOST}] if $ENV{REXEC_HOST};
 } # unless
 
-pod2usage 'Must specify -machines to run on' unless $opts{machines};
+# Connect to Machines module
+my $machines;
+
+unless ($opts{database}) {
+  require Machines; Machines->import;
 
-my @machines;
+  $machines = Machines->new(filename => $opts{filename});
+} else {
+  require Machines::MySQL; Machines::MySQL->import;
 
-push @machines, (split /,/, join (',', $_)) for (@{$opts{machines}}); 
+  $machines = Machines::MySQL->new;
+} # if
 
-$opts{machines} = [@machines];
+my %machines = $machines->select;
 
 my ($status, @lines);
 
-for my $machine (@{$opts{machines}}) {
+for my $machine (sort keys %machines) {
   if ($cmd) {
     ($status, @lines) = execute $machine, $cmd;