X-Git-Url: https://defaria.com/gitweb/?a=blobdiff_plain;f=bin%2Frexec.pl;h=b65933878e2db931541e57f52bd571c469d6ab64;hb=bdb1e0c845a6921e22d52fbff3404d5c1dfae520;hp=1c61a3faecdad967d8bbf22ea963c5e33de9727a;hpb=f0f576efaf276a513338c6303070740a23fea5ab;p=clearscm.git diff --git a/bin/rexec.pl b/bin/rexec.pl index 1c61a3f..b659338 100755 --- a/bin/rexec.pl +++ b/bin/rexec.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl use strict; use warnings; @@ -18,7 +18,7 @@ Andrew DeFaria =item Revision -$Revision: 1.0 $ +$Revision: 2.0 $ =item Created: @@ -35,7 +35,8 @@ $Date: 2008/02/29 15:09:15 $ Usage: rexec.pl [-usa|ge] [-h|elp] [-v|erbose] [-d|ebug] [-use|rname ] [-p|assword ] [-log] - -m|achines ,,... + [-m|achines ,,...] + [-f|ile ] @@ -47,6 +48,7 @@ $Date: 2008/02/29 15:09:15 $ -use|rname: User name to login as (Default: $USER - Env: REXEC_USER) -p|assword: Password to use (Default: None - Env: REXEC_PASSWD) -m|achines: Machine(s) to run the command on + -f|ile: File containing machine info -l|og: Log output (.log) : Commands to execute (Enclose multiple commands in quotes) @@ -119,15 +121,17 @@ my %opts = ( debug => sub { set_debug }, username => $ENV{REXEC_USER} || $ENV{USER}, password => $ENV{REXEC_PASSWD}, - filename => $ENV{REXEC_MACHINES_FILE} || '/opt/clearscm/data/machines', + database => 1, ); sub Interrupted { use Term::ReadKey; - display BLUE . "\nInterrupted execution on $currentHost->{host}" . RESET; + my $host = $currentHost->{host} || 'Unknown Host'; - display_nolf "Executing on " . YELLOW . $currentHost->{host} . RESET . " - " + display BLUE . "\nInterrupted execution on $host" . RESET; + + display_nolf "Executing on " . CYAN . $host . RESET . " - " . CYAN . BOLD . "C" . RESET . CYAN . "ontinue" . RESET . " or " . MAGENTA . BOLD . "A" . RESET . MAGENTA . "bort run" . RESET . " (" . CYAN . BOLD . "C" . RESET . "/" @@ -147,7 +151,7 @@ sub Interrupted { if ($answer eq "s") { *STDOUT->flush; - display "Skipping $currentHost->{host}"; + display "Skipping $host"; } elsif ($answer eq "a") { display RED . "Aborting run". RESET; exit; @@ -161,9 +165,6 @@ sub Interrupted { sub connectHost ($) { my ($host) = @_; - # Start a log... - $log = Logger->new (name => $host) if $opts{log}; - eval { $currentHost = Rexec->new ( host => $host, @@ -184,27 +185,60 @@ sub connectHost ($) { return; } # connectHost +sub initLog($) { + my ($machine) = @_; + + if ($opts{log}) { + my $logdir = $opts{logdir} ? "$opts{logdir}/$machine" : $machine; + + mkdir $logdir or error "Unable to make directory $logdir", 1; + + $log = Logger->new( + name => 'output', + path => $logdir, + ); + } # if +} # initLog + +sub Log($;$) { + my ($msg, $nocrlf) = @_; + + if ($log) { + $log->msg($msg, $nocrlf); + } else { + verbose $msg, $nocrlf; + } # +} # Log + +sub logError ($;$) { + my ($msg, $exit) = @_; + + if ($log) { + $log->err($msg, $exit); + } else { + error $msg, $exit; + } # if +} # logError + sub execute ($$;$) { my ($host, $cmd, $prompt) = @_; my @lines; - verbose_nolf "Connecting to machine $host..."; + Log "Connecting to machine $host...", 1; - display_nolf BOLD . YELLOW . "$host:" . RESET if $opts{verbose}; + display_nolf BOLD . CYAN . "$host:" . RESET if $opts{verbose}; connectHost $host unless $currentHost and $currentHost->{host} eq $host; return (1, ()) unless $currentHost; - verbose " connected"; + Log ' connected'; - display WHITE . UNDERLINE . "$cmd" . RESET if $opts{verbose}; + Log "$host:" . UNDERLINE . $cmd . RESET; @lines = $currentHost->execute ($cmd); - verbose "Disconnected from $host"; - my $status = $currentHost->status; return ($status, @lines); @@ -224,8 +258,9 @@ GetOptions ( 'log', 'logdir', 'filename=s', - 'database', + 'database!', 'machines=s@', + 'condition=s', ) or pod2usage; $opts{debug} = get_debug if ref $opts{debug} eq 'CODE'; @@ -233,38 +268,47 @@ $opts{verbose} = get_verbose if ref $opts{verbose} eq 'CODE'; my $cmd = join ' ', @ARGV; +$opts{machines} = [$ENV{REXEC_HOST}] if $ENV{REXEC_HOST}; + unless ($opts{machines}) { - $opts{machines} = [$ENV{REXEC_HOST}] if $ENV{REXEC_HOST}; -} # unless + # Connect to Machines module + my $machines; -# Connect to Machines module -my $machines; + unless ($opts{database}) { + require Machines; Machines->import; -unless ($opts{database}) { - require Machines; Machines->import; + $machines = Machines->new(filename => $opts{filename}); + } else { + require Machines::MySQL; Machines::MySQL->import; - $machines = Machines->new(filename => $opts{filename}); -} else { - require Machines::MySQL; Machines::MySQL->import; + $machines = Machines::MySQL->new; - $machines = Machines::MySQL->new; -} # if + my %machines = $machines->select($opts{condition}); -my %machines = $machines->select; + $opts{machines} = [keys %machines]; + } # if +} # if my ($status, @lines); -for my $machine (sort keys %machines) { +for my $machine (sort @{$opts{machines}}) { + initLog $machine; + if ($cmd) { ($status, @lines) = execute $machine, $cmd; - display BOLD . YELLOW . "$machine:" . RESET . WHITE . $cmd; + display BOLD . CYAN . "$machine:" . UNDERLINE . WHITE . $cmd . RESET; + + logError "Execution of $cmd on $machine failed", $status if $status; - error "Execution of $cmd on $machine yielded error $status" if $status; + if ($log) { + $log->log($_) for @lines; + } # if display $_ for @lines; undef $currentHost; + undef $log; } else { verbose_nolf "Connecting to machine $machine..."; @@ -273,13 +317,15 @@ for my $machine (sort keys %machines) { if ($currentHost) { my $cmdline = CmdLine->new (); - $cmdline->set_prompt (BOLD . YELLOW . "$machine:" . RESET . WHITE); + $cmdline->set_prompt (BOLD . CYAN . "$machine:" . RESET . WHITE); while () { - #$cmd = ; + Log "$machine:"; + $cmd = $cmdline->get(); unless ($cmd) { + $log->msg('') if $log; display ''; last; } # unless @@ -289,12 +335,17 @@ for my $machine (sort keys %machines) { chomp $cmd; + Log $cmd; + ($status, @lines) = execute $machine, $cmd; - error "Execution of $cmd on $machine yielded error $status" if $status; + logError "Execution of $cmd on $machine failed", $status if $status; + Log $_ for @lines; display $_ for @lines; } # while } # if + + undef $log; } # if } # for