File Coverage

blib/lib/Rex/JobControl/Helper/Project/Job.pm
Criterion Covered Total %
statement 21 160 13.1
branch 0 38 0.0
condition 0 6 0.0
subroutine 7 26 26.9
pod 0 18 0.0
total 28 248 11.2


line stmt bran cond sub pod time code
1             #
2             # (c) Jan Gehring
3             #
4             # vim: set ts=2 sw=2 tw=0:
5             # vim: set expandtab:
6              
7             package Rex::JobControl::Helper::Project::Job;
8             $Rex::JobControl::Helper::Project::Job::VERSION = '0.7.0';
9 1     1   7 use strict;
  1         2  
  1         41  
10 1     1   6 use warnings;
  1         3  
  1         30  
11              
12 1     1   5 use File::Spec;
  1         3  
  1         22  
13 1     1   6 use File::Path;
  1         3  
  1         59  
14 1     1   6 use YAML;
  1         2  
  1         46  
15 1     1   684 use Rex::JobControl::Helper::Chdir;
  1         3  
  1         49  
16 1     1   6 use Data::Dumper;
  1         2  
  1         2674  
17              
18             sub new {
19 0     0 0   my $that = shift;
20 0   0       my $proto = ref($that) || $that;
21 0           my $self = {@_};
22              
23 0           bless( $self, $proto );
24              
25 0           $self->load;
26              
27 0           return $self;
28             }
29              
30 0     0 0   sub name { (shift)->{job_configuration}->{name} }
31 0     0 0   sub description { (shift)->{job_configuration}->{description} }
32 0     0 0   sub environment { (shift)->{job_configuration}->{environment} }
33 0     0 0   sub project { (shift)->{project} }
34 0     0 0   sub directory { (shift)->{directory} }
35 0     0 0   sub steps { (shift)->{job_configuration}->{steps} }
36 0     0 0   sub fail_strategy { (shift)->{job_configuration}->{fail_strategy} }
37 0     0 0   sub execute_strategy { (shift)->{job_configuration}->{execute_strategy} }
38              
39             sub load {
40 0     0 0   my ($self) = @_;
41              
42 0 0         if ( -f $self->_config_file() ) {
43 0           $self->{job_configuration} = YAML::LoadFile( $self->_config_file );
44             }
45             }
46              
47             sub _config_file {
48 0     0     my ($self) = @_;
49 0           return File::Spec->catfile( $self->project->project_path(),
50             "jobs", $self->{directory}, "job.conf.yml" );
51             }
52              
53             sub get_output_log {
54 0     0 0   my ($self, $job_id) = @_;
55              
56 0           my $job_path = File::Spec->catdir( $self->project->project_path,
57             "jobs", $self->{directory} );
58 0           my $execute_path = "$job_path/execute/$job_id";
59              
60 0           my $logfile = "$execute_path/output.log";
61              
62 0 0         if(! -f $logfile) {
63 0           $self->project->app->log->error("This job doesn't have an output.log file.");
64 0           return "No output.log found.";
65             }
66            
67 0           my @loglines = eval { local (@ARGV, $/) = ($logfile); <>; };
  0            
  0            
68              
69 0           return \@loglines;
70             }
71              
72             sub create {
73 0     0 0   my ( $self, %data ) = @_;
74              
75 0           my $job_path = File::Spec->catdir( $self->project->project_path,
76             "jobs", $self->{directory} );
77              
78 0           $self->project->app->log->debug(
79             "Creating new job $self->{directory} in $job_path.");
80              
81 0           File::Path::make_path($job_path);
82              
83 0           delete $data{directory};
84              
85 0           my $job_configuration = {%data};
86              
87 0           YAML::DumpFile( "$job_path/job.conf.yml", $job_configuration );
88             }
89              
90             sub update {
91 0     0 0   my ( $self, %data ) = @_;
92 0           $self->{job_configuration} = \%data;
93              
94 0           my $job_path = File::Spec->catdir( $self->project->project_path,
95             "jobs", $self->{directory} );
96              
97 0           YAML::DumpFile( "$job_path/job.conf.yml", \%data );
98             }
99              
100             sub remove {
101 0     0 0   my ($self) = @_;
102 0           my $job_path = File::Spec->catdir( $self->project->project_path,
103             "jobs", $self->{directory} );
104              
105 0           File::Path::remove_tree($job_path);
106             }
107              
108             sub execute {
109 0     0 0   my ( $self, $user, $cmdb, @server ) = @_;
110 0           $self->project->app->log->debug( "Executing job: " . $self->name );
111 0           my $job_path = File::Spec->catdir( $self->project->project_path,
112             "jobs", $self->{directory} );
113              
114 0           my $pid = time;
115 0           my $execute_path = "$job_path/execute/$pid";
116 0           my $cmdb_path = "$job_path/execute/$pid/cmdb";
117              
118 0           $ENV{JOBCONTROL_EXECUTION_PATH} = $execute_path;
119              
120 0           my @status;
121              
122 0           File::Path::make_path($execute_path);
123 0           File::Path::make_path($cmdb_path);
124              
125 0           $self->project->app->log->debug(
126             "Executing-Strategy: " . $self->execute_strategy );
127 0           $self->project->app->log->debug( "Fail-Strategy: " . $self->fail_strategy );
128              
129 0 0         if ($cmdb) {
130 0           $self->project->app->log->debug("Creating cmdb file");
131 0           YAML::DumpFile( "$cmdb_path/jobcontrol.yml", $cmdb );
132             }
133              
134             YAML::DumpFile(
135 0           "$execute_path/running.status.yml",
136             {
137             start_time => $pid,
138             user => $user,
139             }
140             );
141              
142 0 0         if ( $self->execute_strategy eq "step" ) {
143              
144             # execute strategy = step
145             # execute a step on all hosts, than continue with next step
146              
147 0           STEP: for my $s ( @{ $self->steps } ) {
  0            
148              
149 0           SERVER: for my $srv (@server) {
150              
151 0           my ( $rexfile_name, $task ) = split( /\//, $s );
152 0           my $rexfile = $self->project->get_rexfile($rexfile_name);
153              
154 0 0         my $ret = $rexfile->execute(
155             task => $task,
156             server => [$srv],
157             job => $self,
158             ( $cmdb ? ( cmdb => $cmdb_path ) : () )
159             );
160 0           push @status, $ret->[0];
161              
162 0 0         if ( exists $ret->[0]->{terminate_message} ) {
163 0           $self->project->app->log->debug("Terminating due to fail strategy.");
164 0           last STEP;
165             }
166              
167             }
168             }
169              
170             }
171             else {
172              
173             # execute strategt = node
174             # execute all steps on a server, than continue
175              
176 0           SERVER: for my $srv (@server) {
177              
178 0           STEP: for my $s ( @{ $self->steps } ) {
  0            
179              
180 0 0         if(-f $self->project->project_path . "/next_server.txt") {
181 0           $srv = eval { local(@ARGV, $/) = ($self->project->project_path . "/next_server.txt"); <>; };
  0            
  0            
182 0           chomp $srv;
183 0           unlink $self->project->project_path . "/next_server.txt";
184             }
185              
186 0           my ( $rexfile_name, $task ) = split( /\//, $s );
187 0           my $rexfile = $self->project->get_rexfile($rexfile_name);
188              
189 0 0         my $ret = $rexfile->execute(
190             task => $task,
191             server => [$srv],
192             job => $self,
193             ( $cmdb ? ( cmdb => $cmdb_path ) : () )
194             );
195 0           push @status, $ret->[0];
196              
197 0 0         if ( exists $ret->[0]->{terminate_message} ) {
198 0           $self->project->app->log->debug("Terminating due to fail strategy.");
199 0           last SERVER;
200             }
201             }
202              
203             }
204              
205             }
206              
207 0           unlink "$execute_path/running.status.yml";
208              
209 0           YAML::DumpFile(
210             "$execute_path/run.status.yml",
211             {
212             start_time => $pid,
213             end_time => time,
214             user => $user,
215             status => \@status,
216             }
217             );
218             }
219              
220             sub last_status {
221 0     0 0   my ($self) = @_;
222              
223 0           my $last_execution = $self->last_execution;
224              
225 0           my $job_path = File::Spec->catdir( $self->project->project_path,
226             "jobs", $self->{directory} );
227 0           my $execute_path = "$job_path/execute/$last_execution";
228              
229 0 0         if ( !-f "$execute_path/run.status.yml" ) {
230 0           return "not executed yet";
231             }
232              
233 0           my $ref = YAML::LoadFile("$execute_path/run.status.yml");
234              
235 0           my ($failed) = grep { $_->{status} eq "failed" } @{ $ref->{status} };
  0            
  0            
236              
237 0 0         if ($failed) {
238 0           return "failed";
239             }
240              
241 0           return "success";
242             }
243              
244             sub last_execution {
245 0     0 0   my ($self) = @_;
246 0           my $job_path = File::Spec->catdir( $self->project->project_path,
247             "jobs", $self->{directory} );
248 0           my $execute_path = "$job_path/execute";
249              
250 0 0         if ( -d $execute_path ) {
251 0           my @entries;
252 0 0         opendir( my $dh, $execute_path ) or die($!);
253 0           while ( my $entry = readdir($dh) ) {
254 0 0         next if ( !-f "$execute_path/$entry/run.status.yml" );
255 0           push @entries, $entry;
256             }
257 0           closedir($dh);
258              
259 0           my ($last) = sort { $b <=> $a } @entries;
  0            
260              
261 0           return $last;
262             }
263             else {
264 0           return 0;
265             }
266              
267             }
268              
269             sub get_logs {
270 0     0 0   my ($self) = @_;
271              
272 0           my $job_path = File::Spec->catdir( $self->project->project_path,
273             "jobs", $self->{directory} );
274              
275 0           my $execute_path = "$job_path/execute";
276              
277 0 0         if ( -d $execute_path ) {
278              
279 0           my @entries;
280 0 0         opendir( my $dh, $execute_path ) or die($!);
281 0           while ( my $entry = readdir($dh) ) {
282 0 0 0       next if($entry eq "." || $entry eq "..");
283 0 0         if ( -f "$execute_path/$entry/running.status.yml" ) {
284 0           my $run_status = YAML::LoadFile("$execute_path/$entry/running.status.yml");
285 0           $run_status->{id} = $entry;
286 0           $run_status->{finished} = 0;
287 0           push @entries, $run_status;
288             }
289              
290 0 0         if( -f "$execute_path/$entry/run.status.yml" ) {
291 0           my $run_status = YAML::LoadFile("$execute_path/$entry/run.status.yml");
292 0           $run_status->{id} = $entry;
293 0           $run_status->{finished} = 1;
294 0           push @entries, $run_status;
295             }
296             }
297 0           closedir($dh);
298              
299 0           @entries = sort { $b->{start_time} <=> $a->{start_time} } @entries;
  0            
300              
301 0           return \@entries;
302              
303             }
304              
305             else {
306              
307 0           return [];
308              
309             }
310             }
311              
312              
313              
314              
315             1;