File Coverage

blib/lib/Rex/JobControl/Helper/Project/Job.pm
Criterion Covered Total %
statement 21 137 15.3
branch 0 32 0.0
condition 0 3 0.0
subroutine 7 25 28.0
pod 0 17 0.0
total 28 214 13.0


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.6.0';
9 1     1   5 use strict;
  1         2  
  1         33  
10 1     1   6 use warnings;
  1         1  
  1         92  
11              
12 1     1   5 use File::Spec;
  1         2  
  1         21  
13 1     1   5 use File::Path;
  1         2  
  1         48  
14 1     1   5 use YAML;
  1         2  
  1         42  
15 1     1   1448 use Rex::JobControl::Helper::Chdir;
  1         3  
  1         44  
16 1     1   5 use Data::Dumper;
  1         1  
  1         2382  
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 create {
54 0     0 0   my ( $self, %data ) = @_;
55              
56 0           my $job_path = File::Spec->catdir( $self->project->project_path,
57             "jobs", $self->{directory} );
58              
59 0           $self->project->app->log->debug(
60             "Creating new job $self->{directory} in $job_path.");
61              
62 0           File::Path::make_path($job_path);
63              
64 0           delete $data{directory};
65              
66 0           my $job_configuration = {%data};
67              
68 0           YAML::DumpFile( "$job_path/job.conf.yml", $job_configuration );
69             }
70              
71             sub update {
72 0     0 0   my ( $self, %data ) = @_;
73 0           $self->{job_configuration} = \%data;
74              
75 0           my $job_path = File::Spec->catdir( $self->project->project_path,
76             "jobs", $self->{directory} );
77              
78 0           YAML::DumpFile( "$job_path/job.conf.yml", \%data );
79             }
80              
81             sub remove {
82 0     0 0   my ($self) = @_;
83 0           my $job_path = File::Spec->catdir( $self->project->project_path,
84             "jobs", $self->{directory} );
85              
86 0           File::Path::remove_tree($job_path);
87             }
88              
89             sub execute {
90 0     0 0   my ( $self, $user, $cmdb, @server ) = @_;
91 0           $self->project->app->log->debug( "Executing job: " . $self->name );
92 0           my $job_path = File::Spec->catdir( $self->project->project_path,
93             "jobs", $self->{directory} );
94              
95 0           my $pid = time;
96 0           my $execute_path = "$job_path/execute/$pid";
97 0           my $cmdb_path = "$job_path/execute/$pid/cmdb";
98              
99 0           my @status;
100              
101 0           File::Path::make_path($execute_path);
102 0           File::Path::make_path($cmdb_path);
103              
104 0           $self->project->app->log->debug(
105             "Executing-Strategy: " . $self->execute_strategy );
106 0           $self->project->app->log->debug( "Fail-Strategy: " . $self->fail_strategy );
107              
108 0 0         if ($cmdb) {
109 0           $self->project->app->log->debug("Creating cmdb file");
110 0           YAML::DumpFile( "$cmdb_path/jobcontrol.yml", $cmdb );
111             }
112              
113 0 0         if ( $self->execute_strategy eq "step" ) {
114              
115             # execute strategy = step
116             # execute a step on all hosts, than continue with next step
117              
118 0           STEP: for my $s ( @{ $self->steps } ) {
  0            
119              
120 0           SERVER: for my $srv (@server) {
121              
122 0           my ( $rexfile_name, $task ) = split( /\//, $s );
123 0           my $rexfile = $self->project->get_rexfile($rexfile_name);
124              
125 0 0         my $ret = $rexfile->execute(
126             task => $task,
127             server => [$srv],
128             job => $self,
129             ( $cmdb ? ( cmdb => $cmdb_path ) : () )
130             );
131 0           push @status, $ret->[0];
132              
133 0 0         if ( exists $ret->[0]->{terminate_message} ) {
134 0           $self->project->app->log->debug("Terminating due to fail strategy.");
135 0           last STEP;
136             }
137              
138             }
139             }
140              
141             }
142             else {
143              
144             # execute strategt = node
145             # execute all steps on a server, than continue
146              
147 0           SERVER: for my $srv (@server) {
148              
149 0           STEP: for my $s ( @{ $self->steps } ) {
  0            
150              
151 0 0         if(-f $self->project->project_path . "/next_server.txt") {
152 0           $srv = eval { local(@ARGV, $/) = ($self->project->project_path . "/next_server.txt"); <>; };
  0            
  0            
153 0           chomp $srv;
154 0           unlink $self->project->project_path . "/next_server.txt";
155             }
156              
157 0           my ( $rexfile_name, $task ) = split( /\//, $s );
158 0           my $rexfile = $self->project->get_rexfile($rexfile_name);
159              
160 0 0         my $ret = $rexfile->execute(
161             task => $task,
162             server => [$srv],
163             job => $self,
164             ( $cmdb ? ( cmdb => $cmdb_path ) : () )
165             );
166 0           push @status, $ret->[0];
167              
168 0 0         if ( exists $ret->[0]->{terminate_message} ) {
169 0           $self->project->app->log->debug("Terminating due to fail strategy.");
170 0           last SERVER;
171             }
172             }
173              
174             }
175              
176             }
177              
178 0           YAML::DumpFile(
179             "$execute_path/run.status.yml",
180             {
181             start_time => $pid,
182             end_time => time,
183             user => $user,
184             status => \@status,
185             }
186             );
187             }
188              
189             sub last_status {
190 0     0 0   my ($self) = @_;
191              
192 0           my $last_execution = $self->last_execution;
193              
194 0           my $job_path = File::Spec->catdir( $self->project->project_path,
195             "jobs", $self->{directory} );
196 0           my $execute_path = "$job_path/execute/$last_execution";
197              
198 0 0         if ( !-f "$execute_path/run.status.yml" ) {
199 0           return "not executed yet";
200             }
201              
202 0           my $ref = YAML::LoadFile("$execute_path/run.status.yml");
203              
204 0           my ($failed) = grep { $_->{status} eq "failed" } @{ $ref->{status} };
  0            
  0            
205              
206 0 0         if ($failed) {
207 0           return "failed";
208             }
209              
210 0           return "success";
211             }
212              
213             sub last_execution {
214 0     0 0   my ($self) = @_;
215 0           my $job_path = File::Spec->catdir( $self->project->project_path,
216             "jobs", $self->{directory} );
217 0           my $execute_path = "$job_path/execute";
218              
219 0 0         if ( -d $execute_path ) {
220 0           my @entries;
221 0 0         opendir( my $dh, $execute_path ) or die($!);
222 0           while ( my $entry = readdir($dh) ) {
223 0 0         next if ( !-f "$execute_path/$entry/run.status.yml" );
224 0           push @entries, $entry;
225             }
226 0           closedir($dh);
227              
228 0           my ($last) = sort { $b <=> $a } @entries;
  0            
229              
230 0           return $last;
231             }
232             else {
233 0           return 0;
234             }
235              
236             }
237              
238             sub get_logs {
239 0     0 0   my ($self) = @_;
240              
241 0           my $job_path = File::Spec->catdir( $self->project->project_path,
242             "jobs", $self->{directory} );
243              
244 0           my $execute_path = "$job_path/execute";
245              
246 0 0         if ( -d $execute_path ) {
247              
248 0           my @entries;
249 0 0         opendir( my $dh, $execute_path ) or die($!);
250 0           while ( my $entry = readdir($dh) ) {
251 0 0         next if ( !-f "$execute_path/$entry/run.status.yml" );
252 0           push @entries, YAML::LoadFile("$execute_path/$entry/run.status.yml");
253             }
254 0           closedir($dh);
255              
256 0           @entries = sort { $b->{start_time} <=> $a->{start_time} } @entries;
  0            
257              
258 0           return \@entries;
259              
260             }
261              
262             else {
263              
264 0           return [];
265              
266             }
267             }
268              
269             1;