File Coverage

blib/lib/Clustericious/Admin/RemoteHandler.pm
Criterion Covered Total %
statement 66 75 88.0
branch 31 40 77.5
condition 21 30 70.0
subroutine 18 21 85.7
pod 0 11 0.0
total 136 177 76.8


line stmt bran cond sub pod time code
1             package Clustericious::Admin::RemoteHandler;
2              
3 9     9   70 use strict;
  9         23  
  9         347  
4 9     9   62 use warnings;
  9         24  
  9         314  
5 9     9   217 use 5.010;
  9         45  
6 9     9   59 use AE;
  9         23  
  9         257  
7 9     9   4409 use AnyEvent::Open3::Simple 0.76;
  9         55012  
  9         10313  
8              
9             our $VERSION = '1.10'; # VERSION
10              
11             sub new
12             {
13 30     30 0 347 my($class, %args) = @_;
14            
15             # args: prefix, clad, user, host, payload
16            
17             my $self = bless {
18             prefix => $args{prefix},
19             clad => $args{clad},
20             cv => AE::cv,
21             summary => $args{clad}->summary,
22 30         1808 }, $class;
23            
24 30         143 my $clad = $args{clad};
25            
26             # TODO: handle the same host multiple times
27 30 100       263 if($clad->log_dir)
28             {
29 3         39 my $fn = $clad->log_dir->file($args{prefix} . ".log");
30 3 50       771 open(my $fh, '>', "$fn")
31             || die "unable to write to $fn $!";
32 3         582 $self->{logfile} = $fh;
33 3         196 $self->{logfilename} = $fn;
34             }
35            
36 30         107 my $done = $self->{cv};
37            
38             my $ipc = AnyEvent::Open3::Simple->new(
39             on_start => sub {
40 30     30   311308 my($proc, $program, @args) = @_;
41 30 50       3007 $self->print_line(star => "% $program @args") if $clad->verbose;
42             },
43             on_stdout => sub {
44 35     35   3965430 my($proc, $line) = @_;
45 35         319 $self->print_line(out => $line);
46             },
47             on_stderr => sub {
48 6     6   89520 my($proc, $line) = @_;
49 6         45 $self->print_line(err => $line);
50             },
51             on_exit => sub {
52 30     30   1613527 my($proc, $exit, $signal) = @_;
53 30 100 66     163 $self->print_line(exit => $exit) if ($self->summary && !$signal) || $exit;
      100        
54 30 50       157 $self->print_line(sig => $signal) if $signal;
55 30 100 66     271 $clad->ret(2) if $exit || $signal;
56 30         204 $self->cleanup;
57             },
58             on_error => sub {
59 0     0   0 my($error) = @_;
60 0         0 $self->print_line(fail => $error);
61 0         0 $clad->ret(2);
62 0         0 $self->cleanup;
63             },
64 30         1166 );
65            
66             $ipc->run(
67             $clad->ssh_command,
68             $clad->ssh_options,
69             $clad->ssh_extra,
70             ($args{user} ? ('-l' => $args{user}) : ()),
71             $args{host},
72             $clad->server_command,
73             \$args{payload},
74 30 100       2648 );
75              
76 30         7480 $self;
77             }
78              
79 69     69 0 592 sub clad { shift->{clad} }
80 41     41 0 2131 sub prefix { shift->{prefix} }
81 77     77 0 1528 sub summary { shift->{summary} }
82 80     80 0 575 sub logfile { shift->{logfile} }
83 0     0 0 0 sub logfilename { shift->{logfilename} }
84              
85             sub cleanup
86             {
87 30     30 0 102 my($self) = @_;
88 30 100       848 $self->logfile->close if $self->logfile;
89 30         564 $self->{cv}->send;
90             }
91              
92             sub color
93             {
94 0     0 0 0 my($self) = @_;
95 0   0     0 $self->{color} //= $self->clad->next_color;
96             }
97              
98             sub is_color
99             {
100 88     88 0 286 my($self) = @_;
101 88   66     600 $self->{is_color} //= $self->clad->color;
102             }
103              
104             sub print_line
105             {
106 47     47 0 223 my($self, $code, $line) = @_;
107              
108 47         212 my $fh = $self->logfile;
109 47 100       257 printf $fh "[%-4s] %s\n", $code, $line
110             if $fh;
111            
112 47         358 my $last_line = $code =~ /^(exit|sig|fail)$/;
113            
114 47 100 100     735 return if $self->summary && ! $last_line;
115            
116 41 100 100     253 if($last_line && $line ne '0')
117             {
118 4 50       24 print Term::ANSIColor::color($self->clad->fail_color) if $self->is_color;
119             }
120             else
121             {
122 37 50       158 print Term::ANSIColor::color($self->color) if $self->is_color;
123             }
124              
125 41         188 printf "[%@{[ $self->clad->host_length ]}s %-4s] ", $self->prefix, $code;
  41         156  
126              
127 41 100       314 if(! $last_line)
128             {
129 35 100       139 if($code eq 'err')
130             {
131 6 50       34 print Term::ANSIColor::color($self->clad->err_color) if $self->is_color;
132             }
133             else
134             {
135 29 50       128 print Term::ANSIColor::color('reset') if $self->is_color;
136             }
137             }
138            
139 41         544 print $line;
140            
141 41 100 100     328 if($last_line || $code eq 'err')
142             {
143 12 50       78 print Term::ANSIColor::color('reset') if $self->is_color;
144             }
145            
146 41         468 print "\n";
147            
148 41 50 66     533 if($fh && $last_line && $line ne '0')
      33        
149             {
150 0         0 print ' ' x ($self->clad->host_length +8), "see @{[ $self->logfilename ]}\n";
  0         0  
151             }
152             }
153              
154 30     30 0 196 sub cv { shift->{cv} }
155              
156             1;
157              
158             __END__
159              
160             =pod
161              
162             =encoding UTF-8
163              
164             =head1 NAME
165              
166             Clustericious::Admin::RemoteHandler
167              
168             =head1 VERSION
169              
170             version 1.10
171              
172             =head1 AUTHOR
173              
174             Graham Ollis <plicease@cpan.org>
175              
176             =head1 COPYRIGHT AND LICENSE
177              
178             This software is copyright (c) 2015 by Graham Ollis.
179              
180             This is free software; you can redistribute it and/or modify it under
181             the same terms as the Perl 5 programming language system itself.
182              
183             =cut