File Coverage

lib/Rex/Task.pm
Criterion Covered Total %
statement 286 359 79.6
branch 82 124 66.1
condition 50 70 71.4
subroutine 58 68 85.2
pod 48 50 96.0
total 524 671 78.0


line stmt bran cond sub pod time code
1             #
2             # (c) Jan Gehring
3             #
4              
5             =head1 NAME
6              
7             Rex::Task - The Task Object
8              
9             =head1 DESCRIPTION
10              
11             The Task Object. Typically you only need this class if you want to manipulate tasks after their initial creation.
12              
13             =head1 SYNOPSIS
14              
15             use Rex::Task;
16              
17             # create a new task
18             my $task = Rex::Task->new( name => 'testtask' );
19             $task->set_server('remoteserver');
20             $task->set_code( sub { say 'Hello'; } );
21             $task->modify( 'no_ssh', 1 );
22              
23             # retrieve an existing task
24             use Rex::TaskList;
25              
26             my $existing_task = Rex::TaskList->create->get_task('my_task');
27              
28             =head1 METHODS
29              
30             =cut
31              
32             package Rex::Task;
33              
34 56     56   69029 use v5.12.5;
  56         235  
35 56     56   406 use warnings;
  56         171  
  56         1452  
36 56     56   954 use Data::Dumper;
  56         7612  
  56         2585  
37 56     56   977 use Time::HiRes qw(time);
  56         1480  
  56         663  
38              
39             our $VERSION = '1.14.3'; # VERSION
40              
41 56     56   8998 use Rex::Logger;
  56         210  
  56         455  
42 56     56   1956 use Rex::TaskList;
  56         130  
  56         513  
43 56     56   2223 use Rex::Interface::Connection;
  56         121  
  56         611  
44 56     56   1751 use Rex::Interface::Executor;
  56         137  
  56         466  
45 56     56   2593 use Rex::Group::Entry::Server;
  56         156  
  56         1382  
46 56     56   2386 use Rex::Profiler;
  56         148  
  56         600  
47 56     56   1681 use Rex::Hardware;
  56         138  
  56         512  
48 56     56   1564 use Rex::Interface::Cache;
  56         129  
  56         468  
49 56     56   1405 use Rex::Report;
  56         114  
  56         480  
50 56     56   1308 use Rex::Helper::Run;
  56         132  
  56         3746  
51 56     56   376 use Rex::Helper::Path;
  56         121  
  56         3628  
52 56     56   379 use Rex::Notify;
  56         137  
  56         569  
53 56     56   1601 use Carp;
  56         127  
  56         233897  
54              
55             require Rex::Commands;
56              
57             require Rex::Args;
58              
59             =head2 new
60              
61             This is the constructor.
62              
63             $task = Rex::Task->new(
64             func => sub { some_code_here },
65             server => [ @server ],
66             desc => $description,
67             no_ssh => $no_ssh,
68             hidden => $hidden,
69             auth => {
70             user => $user,
71             password => $password,
72             private_key => $private_key,
73             public_key => $public_key,
74             },
75             before => [sub {}, sub {}, ...],
76             after => [sub {}, sub {}, ...],
77             around => [sub {}, sub {}, ...],
78             before_task_start => [sub {}, sub {}, ...],
79             after_task_finished => [sub {}, sub {}, ...],
80             name => $task_name,
81             executor => Rex::Interface::Executor->create,
82             opts => {key1 => val1, key2 => val2, ...},
83             args => [arg1, arg2, ...],
84             );
85              
86             =cut
87              
88             sub new {
89 245     245 1 24117 my $that = shift;
90 245   33     1381 my $proto = ref($that) || $that;
91 245         1781 my $self = {@_};
92              
93 245         887 bless( $self, $proto );
94              
95 245 50       1053 if ( !exists $self->{name} ) {
96 0         0 die("You have to define a task name.");
97             }
98              
99 245   100     1582 $self->{no_ssh} ||= 0;
100 245   100 0   749 $self->{func} ||= sub { };
101 245   66     1060 $self->{executor} ||= Rex::Interface::Executor->create;
102 245   100     1372 $self->{opts} ||= {};
103 245   100     1353 $self->{args} ||= [];
104              
105 245         795 $self->{connection} = undef;
106              
107             # set to true as default
108 245 100       906 if ( !exists $self->{exit_on_connect_fail} ) {
109 33         271 $self->{exit_on_connect_fail} = 1;
110             }
111              
112 245         2059 return $self;
113             }
114              
115             =head2 connection
116              
117             Returns the current connection object.
118              
119             =cut
120              
121             sub connection {
122 260     260 1 609 my ($self) = @_;
123 260 100 100     1590 if ( !exists $self->{connection} || !$self->{connection} ) {
124             $self->{connection} =
125 40         290 Rex::Interface::Connection->create( $self->get_connection_type );
126             }
127              
128 260         1695 $self->{connection};
129             }
130              
131             sub set_connection {
132 7     7 0 24 my ( $self, $conn ) = @_;
133 7         23 $self->{connection} = $conn;
134             }
135              
136             =head2 executor
137              
138             Returns the current executor object.
139              
140             =cut
141              
142             sub executor {
143 54     54 1 255 my ($self) = @_;
144 54         2577 $self->{executor}->set_task($self);
145 54         738 return $self->{executor};
146             }
147              
148             =head2 hidden
149              
150             Returns true if the task is hidden. (Should not be displayed on ,,rex -T''.)
151              
152             =cut
153              
154             sub hidden {
155 60     60 1 118 my ($self) = @_;
156 60         207 return $self->{hidden};
157             }
158              
159             =head2 server
160              
161             Returns the servers on which the task should be executed as an ArrayRef.
162              
163             =cut
164              
165             sub server {
166 292     292 1 3262 my ($self) = @_;
167              
168 292         513 my @server = @{ $self->{server} };
  292         1102  
169 292         650 my @ret = ();
170              
171 292 50       1082 if ( ref( $server[-1] ) eq "HASH" ) {
172 0         0 Rex::deprecated(
173             undef, "0.40",
174             "Defining extra credentials within the task creation is deprecated.",
175             "Please use set auth => task => 'taskname' instead."
176             );
177              
178             # use extra defined credentials
179 0         0 my $data = pop(@server);
180 0         0 $self->set_auth( "user", $data->{'user'} );
181 0         0 $self->set_auth( "password", $data->{'password'} );
182              
183 0 0       0 if ( exists $data->{"private_key"} ) {
184 0         0 $self->set_auth( "private_key", $data->{"private_key"} );
185 0         0 $self->set_auth( "public_key", $data->{"public_key"} );
186             }
187             }
188              
189 292 100 66     2066 if ( ref( $self->{server} ) eq "ARRAY"
    50          
190 292         2310 && scalar( @{ $self->{server} } ) > 0 )
191             {
192 18         35 for my $srv ( @{ $self->{server} } ) {
  18         57  
193 30 100       70 if ( ref($srv) eq "CODE" ) {
194 1         10 push( @ret, &$srv() );
195             }
196             else {
197 29 100 66     162 if ( ref $srv && $srv->isa("Rex::Group::Entry::Server") ) {
198 28         86 push( @ret, $srv->get_servers );
199             }
200             else {
201 1         5 push( @ret, $srv );
202             }
203             }
204             }
205             }
206             elsif ( ref( $self->{server} ) eq "CODE" ) {
207 0         0 push( @ret, &{ $self->{server} }() );
  0         0  
208             }
209             else {
210 274         3460 push( @ret, Rex::Group::Entry::Server->new( name => "" ) );
211             }
212              
213 292         1215 return [@ret];
214             }
215              
216             =head2 set_server(@server)
217              
218             With this method you can set new servers on which the task should be executed on.
219              
220             =cut
221              
222             sub set_server {
223 1     1 1 4 my ( $self, @server ) = @_;
224 1         5 $self->{server} = \@server;
225             }
226              
227             =head2 delete_server
228              
229             Delete every server registered to the task.
230              
231             =cut
232              
233             sub delete_server {
234 1     1 1 4 my ($self) = @_;
235 1         7 delete $self->{current_server};
236 1         11 delete $self->{server};
237 1         9 $self->rethink_connection;
238             }
239              
240             =head2 current_server
241              
242             Returns the current server on which the tasks gets executed right now.
243              
244             =cut
245              
246             sub current_server {
247 2     2 1 6 my ($self) = @_;
248             return $self->{current_server}
249 2   66     23 || Rex::Group::Entry::Server->new( name => "" );
250             }
251              
252             =head2 desc
253              
254             Returns the description of a task.
255              
256             =cut
257              
258             sub desc {
259 2     2 1 6 my ($self) = @_;
260 2         9 return $self->{desc};
261             }
262              
263             =head2 set_desc($description)
264              
265             Set the description of a task.
266              
267             =cut
268              
269             sub set_desc {
270 1     1 1 6 my ( $self, $desc ) = @_;
271 1         3 $self->{desc} = $desc;
272             }
273              
274             =head2 is_remote
275              
276             Returns true (1) if the task will be executed remotely.
277              
278             =cut
279              
280             sub is_remote {
281 142     142 1 1732 my ($self) = @_;
282 142 100       362 if ( exists $self->{current_server} ) {
283 118 100       428 if ( $self->{current_server} ne '' ) {
284 14         87 return 1;
285             }
286             }
287             else {
288 24 100 100     63 if ( exists $self->{server} && scalar( @{ $self->{server} } ) > 0 ) {
  17         51  
289 14         56 return 1;
290             }
291             }
292              
293 114         1391 return 0;
294             }
295              
296             =head2 is_local
297              
298             Returns true (1) if the task gets executed on the local host.
299              
300             =cut
301              
302             sub is_local {
303 5     5 1 15 my ($self) = @_;
304 5 100       12 return $self->is_remote() == 0 ? 1 : 0;
305             }
306              
307             =head2 is_http
308              
309             Returns true (1) if the task gets executed over http protocol.
310              
311             =cut
312              
313             sub is_http {
314 46     46 1 235 my ($self) = @_;
315             return ( $self->{"connection_type"}
316 46   66     1015 && lc( $self->{"connection_type"} ) eq "http" );
317             }
318              
319             =head2 is_https
320              
321             Returns true (1) if the task gets executed over https protocol.
322              
323             =cut
324              
325             sub is_https {
326 46     46 1 211 my ($self) = @_;
327             return ( $self->{"connection_type"}
328 46   66     906 && lc( $self->{"connection_type"} ) eq "https" );
329             }
330              
331             =head2 is_openssh
332              
333             Returns true (1) if the task gets executed with openssh.
334              
335             =cut
336              
337             sub is_openssh {
338 10     10 1 25 my ($self) = @_;
339             return ( $self->{"connection_type"}
340 10   66     61 && lc( $self->{"connection_type"} ) eq "openssh" );
341             }
342              
343             =head2 want_connect
344              
345             Returns true (1) if the task will establish a connection to a remote system.
346              
347             =cut
348              
349             sub want_connect {
350 14     14 1 1143 my ($self) = @_;
351 14 100       81 return $self->{no_ssh} == 0 ? 1 : 0;
352             }
353              
354             =head2 get_connection_type
355              
356             This method tries to guess the right connection type for the task and returns it.
357              
358             Current return values are below:
359              
360             =over 4
361              
362             =item * SSH: connect to the remote server using Net::SSH2
363              
364             =item * OpenSSH: connect to the remote server using Net::OpenSSH
365              
366             =item * Local: runs locally (without any connections)
367              
368             =item * HTTP: uses experimental HTTP connection
369              
370             =item * HTTPS: uses experimental HTTPS connection
371              
372             =item * Fake: populate the connection properties, but do not connect
373              
374             So you can use this type to iterate over a list of remote hosts, but don't let rex build a connection. For example if you want to use Sys::Virt or other modules.
375              
376             =back
377              
378             =cut
379              
380             sub get_connection_type {
381 46     46 1 856 my ($self) = @_;
382              
383 46 50 100     479 if ( $self->is_http ) {
    50 66        
    50 100        
    100          
    100          
384 0         0 return "HTTP";
385             }
386             elsif ( $self->is_https ) {
387 0         0 return "HTTPS";
388             }
389             elsif ( $self->is_remote && $self->is_openssh && $self->want_connect ) {
390 0         0 return "OpenSSH";
391             }
392             elsif ( $self->is_remote && $self->want_connect ) {
393 5         34 return Rex::Config->get_connection_type();
394             }
395             elsif ( $self->is_remote ) {
396 5         48 return "Fake";
397             }
398             else {
399 36         798 return "Local";
400             }
401             }
402              
403             =head2 modify($key, $value)
404              
405             With this method you can modify values of the task.
406              
407             =cut
408              
409             sub modify {
410 90     90 1 229 my ( $self, $key, $value ) = @_;
411              
412 90 100       319 if ( ref( $self->{$key} ) eq "ARRAY" ) {
413 87         145 push( @{ $self->{$key} }, $value );
  87         201  
414             }
415             else {
416 3         8 $self->{$key} = $value;
417             }
418              
419 90         212 $self->rethink_connection;
420             }
421              
422             =head2 rethink_connection
423              
424             Deletes current connection object.
425              
426             =cut
427              
428             sub rethink_connection {
429 128     128 1 373 my ($self) = @_;
430 128         692 delete $self->{connection};
431             }
432              
433             =head2 user
434              
435             Returns the username the task will use.
436              
437             =cut
438              
439             sub user {
440 39     39 1 150 my ($self) = @_;
441 39 50 33     706 if ( exists $self->{auth} && $self->{auth}->{user} ) {
442 39         280 return $self->{auth}->{user};
443             }
444             }
445              
446             =head2 set_user($user)
447              
448             Set the username of a task.
449              
450             =cut
451              
452             sub set_user {
453 1     1 1 4 my ( $self, $user ) = @_;
454 1         5 $self->{auth}->{user} = $user;
455             }
456              
457             =head2 password
458              
459             Returns the password that will be used.
460              
461             =cut
462              
463             sub password {
464 2     2 1 5 my ($self) = @_;
465 2 50 33     15 if ( exists $self->{auth} && $self->{auth}->{password} ) {
466 2         11 return $self->{auth}->{password};
467             }
468             }
469              
470             =head2 set_password($password)
471              
472             Set the password of the task.
473              
474             =cut
475              
476             sub set_password {
477 1     1 1 4 my ( $self, $password ) = @_;
478 1         4 $self->{auth}->{password} = $password;
479             }
480              
481             =head2 name
482              
483             Returns the name of the task.
484              
485             =cut
486              
487             sub name {
488 250     250 1 1651 my ($self) = @_;
489 250         4239 return $self->{name};
490             }
491              
492             =head2 code
493              
494             Returns the code of the task.
495              
496             =cut
497              
498             sub code {
499 54     54 1 193 my ($self) = @_;
500 54         364 return $self->{func};
501             }
502              
503             =head2 set_code(\&code_ref)
504              
505             Set the code of the task.
506              
507             =cut
508              
509             sub set_code {
510 1     1 1 4 my ( $self, $code ) = @_;
511 1         8 $self->{func} = $code;
512             }
513              
514             =head2 run_hook($server, $hook)
515              
516             This method is used internally to execute the specified hooks.
517              
518             =cut
519              
520             sub run_hook {
521 136     136 1 1015 my ( $self, $server, $hook, @more_args ) = @_;
522 136         403 my $old_server;
523              
524 136         261 for my $code ( @{ $self->{$hook} } ) {
  136         1087  
525 24 100       108 if ( $hook eq "after" ) { # special case for after hooks
526             $code->(
527             $$server,
528 6   50     55 ( $self->{"__was_authenticated"} || 0 ),
529             { $self->get_opts }, @more_args
530             );
531             }
532             else {
533 18 50       66 $old_server = $$server if $server;
534 18         97 $code->( $$server, $server, { $self->get_opts }, @more_args );
535 18 100 66     158 if ( $old_server && $old_server ne $$server ) {
536 2         13 $self->{current_server} = $$server;
537             }
538             }
539             }
540             }
541              
542             =head2 set_auth($key, $value)
543              
544             Set the authentication of the task.
545              
546             $task->set_auth("user", "foo");
547             $task->set_auth("password", "bar");
548              
549             =cut
550              
551             sub set_auth {
552 4     4 1 21 my ( $self, $key, $value ) = @_;
553              
554 4 100       18 if ( scalar(@_) > 3 ) {
555 2         5 my $_d = shift;
556 2         13 $self->{auth} = {@_};
557             }
558             else {
559 2         11 $self->{auth}->{$key} = $value;
560             }
561             }
562              
563             =head2 merge_auth($server)
564              
565             Merges the authentication information from $server into the task.
566             Tasks authentication information have precedence.
567              
568             =cut
569              
570             sub merge_auth {
571 88     88 1 95698 my ( $self, $server ) = @_;
572              
573             # merge auth hashs
574             # task auth as precedence
575 88         890 my %auth = $server->merge_auth( $self->{auth} );
576              
577 88         636 return \%auth;
578             }
579              
580             =head2 get_sudo_password
581              
582             Returns the sudo password.
583              
584             =cut
585              
586             sub get_sudo_password {
587 0     0 1 0 my ($self) = @_;
588              
589 0         0 my $server = $self->connection->server;
590 0         0 my %auth = $server->merge_auth( $self->{auth} );
591              
592 0         0 return $auth{sudo_password};
593             }
594              
595             =head2 parallelism
596              
597             Get the parallelism count of a task.
598              
599             =cut
600              
601             sub parallelism {
602 138     138 1 739 my ($self) = @_;
603 138         3667 return $self->{parallelism};
604             }
605              
606             =head2 set_parallelism($count)
607              
608             Set the parallelism of the task.
609              
610             =cut
611              
612             sub set_parallelism {
613 0     0 1 0 my ( $self, $para ) = @_;
614 0         0 $self->{parallelism} = $para;
615             }
616              
617             =head2 connect($server)
618              
619             Initiate the connection to $server.
620              
621             =cut
622              
623             sub connect {
624 37     37 1 198 my ( $self, $server, %override ) = @_;
625              
626 37 100       296 if ( !ref $server ) {
627 1         11 $server = Rex::Group::Entry::Server->new( name => $server );
628             }
629 37         230 $self->{current_server} = $server;
630              
631 37         441 $self->run_hook( \$server, "before" );
632              
633             # need to be called, in case of a run_task task call.
634             # see #788
635 37         573 $self->rethink_connection;
636              
637 37         324 my $user = $self->user;
638              
639             #print Dumper($self);
640 37         355 my $auth = $self->merge_auth($server);
641              
642 37 50       291 if ( exists $override{auth} ) {
643 0         0 $auth = $override{auth};
644 0         0 $user = $auth->{user};
645             }
646              
647 37         998 my $rex_int_conf = Rex::Commands::get("rex_internals");
648 37         887 Rex::Logger::debug( Dumper($rex_int_conf) );
649 37         213 Rex::Logger::debug("Auth-Information inside Task:");
650 37         107 for my $key ( keys %{$auth} ) {
  37         440  
651 296         931 my $data = $auth->{$key};
652 296 100       848 $data = Rex::Logger::masq( "%s", $data ) if $key eq 'password';
653 296 100       819 $data = Rex::Logger::masq( "%s", $data ) if $key eq 'sudo_password';
654 296   100     1319 $data ||= "";
655              
656 296         921 Rex::Logger::debug("$key => [[$data]]");
657             }
658              
659             $auth->{public_key} = resolv_path( $auth->{public_key}, 1 )
660 37 50       220 if ( $auth->{public_key} );
661             $auth->{private_key} = resolv_path( $auth->{private_key}, 1 )
662 37 50       221 if ( $auth->{private_key} );
663              
664 37         895 my $profiler = Rex::Profiler->new;
665              
666             # task specific auth rules over all
667 37         117 my %connect_hash = %{$auth};
  37         376  
668 37         201 $connect_hash{server} = $server;
669              
670             # need to get rid of this
671 37         304 Rex::push_connection(
672             {
673             conn => $self->connection,
674             ssh => $self->connection->get_connection_object,
675             server => $server,
676             cache => Rex::Interface::Cache->create(),
677             task => [],
678             profiler => $profiler,
679             reporter => Rex::Report->create( Rex::Config->get_report_type ),
680             notify => Rex::Notify->new(),
681             }
682             );
683              
684 37         129 push @{ Rex::get_current_connection()->{task} }, $self;
  37         255  
685              
686 37         314 $profiler->start("connect");
687             eval {
688 37         200 $self->connection->connect(%connect_hash);
689 37         214 1;
690 37 50       164 } or do {
691 0 0       0 if ( !defined Rex::Config->get_fallback_auth ) {
692 0         0 croak $@;
693             }
694             };
695 37         292 $profiler->end("connect");
696              
697 37 50       205 if ( !$self->connection->is_connected ) {
    50          
698 0         0 Rex::pop_connection();
699 0         0 croak("Couldn't connect to $server.");
700             }
701             elsif ( !$self->connection->is_authenticated ) {
702 0         0 Rex::pop_connection();
703 0         0 my $message =
704             "Couldn't authenticate against $server. It may be caused by one or more of:\n";
705 0         0 $message .= " - wrong username, password, key or passphrase\n";
706 0         0 $message .= " - changed remote host key\n";
707             $message .= " - root is not permitted to login over SSH\n"
708 0 0       0 if ( $connect_hash{user} eq 'root' );
709              
710 0 0       0 if ( !exists $override{auth} ) {
711 0         0 my $fallback_auth = Rex::Config->get_fallback_auth;
712 0 0       0 if ( ref $fallback_auth eq "ARRAY" ) {
713 0         0 my $ret_eval;
714 0         0 for my $fallback_a ( @{$fallback_auth} ) {
  0         0  
715 0         0 $ret_eval = eval { $self->connect( $server, auth => $fallback_a ); };
  0         0  
716             }
717              
718 0 0       0 return $ret_eval if $ret_eval;
719             }
720             }
721              
722 0         0 croak($message);
723             }
724             else {
725 37 50       167 Rex::Logger::debug("Successfully authenticated on $server.")
726             if ( $self->connection->get_connection_type ne "Local" );
727 37         451 $self->{"__was_authenticated"} = 1;
728             }
729              
730 37         301 $self->run_hook( \$server, "around" );
731              
732 37         254 return 1;
733             }
734              
735             =head2 disconnect
736              
737             Disconnect from the current connection.
738              
739             =cut
740              
741             sub disconnect {
742 29     29 1 179 my ( $self, $server ) = @_;
743              
744 29         370 $self->run_hook( \$server, "around", 1 );
745 29         319 $self->connection->disconnect;
746              
747 29         206 my %args = Rex::Args->getopts;
748              
749 29 50 33     314 if ( defined $args{'d'} && $args{'d'} > 2 ) {
750 0         0 Rex::Commands::profiler()->report;
751             }
752              
753 29         279 delete $self->{connection};
754              
755 29         154 pop @{ Rex::get_current_connection()->{task} };
  29         2265  
756              
757             # need to get rid of this
758 29         317 Rex::pop_connection();
759              
760 29         1223 $self->run_hook( \$server, "after" );
761             }
762              
763             =head2 get_data
764              
765             Dump task data.
766              
767             =cut
768              
769             sub get_data {
770 33     33 1 278 my ($self) = @_;
771              
772             return {
773             func => $self->{func},
774             server => $self->{server},
775             desc => $self->{desc},
776             no_ssh => $self->{no_ssh},
777             hidden => $self->{hidden},
778             auth => $self->{auth},
779             before => $self->{before},
780             after => $self->{after},
781             around => $self->{around},
782             name => $self->{name},
783             executor => $self->{executor},
784             connection_type => $self->{connection_type},
785             opts => $self->{opts},
786             args => $self->{args},
787 33         5386 };
788             }
789              
790             =head2 run($server, %options)
791              
792             Run the task on C<$server>, with C<%options>.
793              
794             =cut
795              
796             sub run {
797 54 50   54 1 484 return pre_40_run(@_) unless ref $_[0];
798              
799 54         1040 my ( $self, $server, %options ) = @_;
800              
801 54   50     1101 $options{opts} ||= { $self->get_opts };
802 54   100     666 $options{args} ||= [ $self->get_args ];
803 54   66     415 $options{params} ||= $options{opts};
804              
805 54 100       345 if ( !ref $server ) {
806 22         213 $server = Rex::Group::Entry::Server->new( name => $server );
807             }
808              
809 54 50       268 if ( !$_[1] ) {
810              
811             # run is called without any server.
812             # so just connect to any servers.
813 0         0 return Rex::TaskList->create()->run( $self, %options );
814             }
815              
816             # this is a method call
817             # so run the task
818              
819             # TODO: refactor complete task calling
820             # direct call with function and normal task call
821              
822 54         309 my ( $in_transaction, $start_time );
823              
824 54         601 $start_time = time;
825              
826 54 100       452 if ( $server ne "" ) {
827              
828             # this is _not_ a task call via function syntax.
829              
830 36         137 $in_transaction = $options{in_transaction};
831              
832 36         119 eval { $self->connect($server) };
  36         593  
833 36 50       213 if ($@) {
834 0         0 my $error = $@;
835 0         0 $self->{"__was_authenticated"} = 0;
836 0         0 $self->run_hook( \$server, "after" );
837 0         0 die $error;
838             }
839              
840 36 50       960 if ( Rex::Args->is_opt("c") ) {
841              
842             # get and cache all os info
843 0 0       0 if ( !Rex::get_cache()->load() ) {
844 0         0 Rex::Logger::debug("No cache found, need to collect new data.");
845 0         0 $server->gather_information;
846             }
847             }
848              
849 36 50       451 if ( !$server->test_perl ) {
850 0         0 Rex::Logger::info(
851             "There is no perl interpreter found on this system. "
852             . "Some commands may not work. Sudo won't work.",
853             "warn"
854             );
855 0         0 sleep 3;
856             }
857              
858             }
859             else {
860             # we need to push the connection information of the last task onto this task object
861             # if we don't do this, the task doesn't have any information of the current connection when called like a function.
862             # See: #1091
863             $self->set_connection(
864             Rex::get_current_connection()->{task}->[-1]->connection )
865 18 100       73 if Rex::get_current_connection()->{task}->[-1];
866 18         31 push @{ Rex::get_current_connection()->{task} }, $self;
  18         48  
867             }
868              
869             # execute code
870 54         661 my @ret;
871 54         402 my $wantarray = wantarray;
872              
873             eval {
874 40         1292 $self->set_opts( %{ $options{params} } )
875 54 100       536 if ref $options{params} eq "HASH";
876 54 100       328 if ($wantarray) {
877 1         6 @ret = $self->executor->exec( $options{params}, $options{args} );
878             }
879             else {
880 53         668 $ret[0] = $self->executor->exec( $options{params}, $options{args} );
881             }
882 47         319 my $notify = Rex::get_current_connection()->{notify};
883 47         620 $notify->run_postponed();
884 54 50       197 } or do {
885 54 100       316 if ($@) {
886 7         36 my $error = $@;
887              
888             Rex::get_current_connection()->{reporter}
889 7         58 ->report_resource_failed( message => $error );
890              
891             Rex::get_current_connection()->{reporter}->report_task_execution(
892 7         27 failed => 1,
893             start_time => $start_time,
894             end_time => time,
895             message => $error,
896             );
897              
898 7         39 Rex::get_current_connection()->{reporter}->write_report();
899              
900 7         37 pop @{ Rex::get_current_connection()->{task} };
  7         30  
901 7         219 die($error);
902             }
903             };
904              
905 47 100       756 if ( $server ne "" ) {
906 29 50       430 if ( Rex::Args->is_opt("c") ) {
907              
908             # get and cache all os info
909 0         0 Rex::get_cache()->save();
910             }
911              
912             Rex::get_current_connection()->{reporter}->report_task_execution(
913 29         192 failed => 0,
914             start_time => $start_time,
915             end_time => time,
916             );
917              
918 29         244 Rex::get_current_connection()->{reporter}->write_report();
919              
920 29 100       134 if ($in_transaction) {
921 1         11 $self->run_hook( \$server, "around", 1 );
922 1         8 $self->run_hook( \$server, "after" );
923             }
924             else {
925 28         309 $self->disconnect($server);
926             }
927             }
928             else {
929 18         58 pop @{ Rex::get_current_connection()->{task} };
  18         71  
930             }
931              
932 47 100       342 if ($wantarray) {
933 1         14 return @ret;
934             }
935             else {
936 46         2016 return $ret[0];
937             }
938             }
939              
940             sub pre_40_run {
941 0     0 0 0 my ( $class, $task_name, $server_overwrite, $params ) = @_;
942              
943             # static calls to this method are deprecated
944 0         0 Rex::deprecated( "Rex::Task->run()", "0.40" );
945              
946 0         0 my $tasklist = Rex::TaskList->create;
947 0         0 my $task = $tasklist->get_task($task_name);
948              
949 0 0       0 $task->set_server($server_overwrite) if $server_overwrite;
950 0         0 $tasklist->run( $task, params => $params );
951             }
952              
953             =head2 modify_task($task, $key => $value)
954              
955             Modify C<$task>, by setting C<$key> to C<$value>.
956              
957             =cut
958              
959             sub modify_task {
960 0     0 1 0 my $class = shift;
961 0         0 my $task = shift;
962 0         0 my $key = shift;
963 0         0 my $value = shift;
964              
965 0         0 Rex::TaskList->create()->get_task($task)->modify( $key => $value );
966             }
967              
968             =head2 is_task
969              
970             Returns true(1) if the passed object is a task.
971              
972             =cut
973              
974             sub is_task {
975 0     0 1 0 my ( $class, $task ) = @_;
976 0         0 return Rex::TaskList->create()->is_task($task);
977             }
978              
979             =head2 get_tasks
980              
981             Returns list of tasks.
982              
983             =cut
984              
985             sub get_tasks {
986 0     0 1 0 my ( $class, @tmp ) = @_;
987 0         0 return Rex::TaskList->create()->get_tasks(@tmp);
988             }
989              
990             =head2 get_desc
991              
992             Returns description of task.
993              
994             =cut
995              
996             sub get_desc {
997 0     0 1 0 my ( $class, @tmp ) = @_;
998 0         0 return Rex::TaskList->create()->get_desc(@tmp);
999             }
1000              
1001             =head2 exit_on_connect_fail
1002              
1003             Returns true if rex should exit on connect failure.
1004              
1005             =cut
1006              
1007             sub exit_on_connect_fail {
1008 0     0 1 0 my ($self) = @_;
1009 0         0 return $self->{exit_on_connect_fail};
1010             }
1011              
1012             =head2 set_exit_on_connect_fail
1013              
1014             Sets if rex should exit on connect failure.
1015              
1016             =cut
1017              
1018             sub set_exit_on_connect_fail {
1019 0     0 1 0 my ( $self, $exit ) = @_;
1020 0         0 $self->{exit_on_connect_fail} = $exit;
1021             }
1022              
1023             =head2 get_args
1024              
1025             Returns arguments of task.
1026              
1027             =cut
1028              
1029             sub get_args {
1030 65     65 1 248 my ($self) = @_;
1031 65 50       197 @{ $self->{args} || [] };
  65         553  
1032             }
1033              
1034             =head2 get_opts
1035              
1036             Returns options of task.
1037              
1038             =cut
1039              
1040             sub get_opts {
1041 137     137 1 12086 my ($self) = @_;
1042 137 50       275 %{ $self->{opts} || {} };
  137         2629  
1043             }
1044              
1045             =head2 set_args
1046              
1047             Sets arguments for task.
1048              
1049             =cut
1050              
1051             sub set_args {
1052 101     101 1 220 my ( $self, @args ) = @_;
1053 101         339 $self->{args} = \@args;
1054             }
1055              
1056             =head2 set_opt
1057              
1058             Sets an option for task.
1059              
1060             =cut
1061              
1062             sub set_opt {
1063 6     6 1 45 my ( $self, $key, $value ) = @_;
1064 6         34 $self->{opts}->{$key} = $value;
1065             }
1066              
1067             =head2 set_opts
1068              
1069             Sets options for task.
1070              
1071             =cut
1072              
1073             sub set_opts {
1074 141     141 1 934 my ( $self, %opts ) = @_;
1075 141         955 $self->{opts} = \%opts;
1076             }
1077              
1078             =head2 clone
1079              
1080             Clones a task.
1081              
1082             =cut
1083              
1084             sub clone {
1085 32     32 1 185 my $self = shift;
1086 32         136 return Rex::Task->new( %{ $self->get_data } );
  32         682  
1087             }
1088              
1089             1;