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 |