File Coverage

blib/lib/Rex/JobControl/Helper/Project/Rexfile.pm
Criterion Covered Total %
statement 27 152 17.7
branch 0 28 0.0
condition 0 10 0.0
subroutine 9 31 29.0
pod 0 16 0.0
total 36 237 15.1


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::Rexfile;
8             $Rex::JobControl::Helper::Project::Rexfile::VERSION = '0.18.0';
9 1     1   4 use strict;
  1         1  
  1         30  
10 1     1   4 use warnings;
  1         1  
  1         20  
11 1     1   3 use File::Spec;
  1         1  
  1         13  
12 1     1   3 use File::Path;
  1         1  
  1         41  
13 1     1   4 use File::Basename;
  1         1  
  1         75  
14 1     1   5 use YAML;
  1         1  
  1         37  
15 1     1   492 use Capture::Tiny qw'capture';
  1         10713  
  1         53  
16              
17 1     1   6 use Rex::JobControl::Helper::Chdir;
  1         3  
  1         34  
18 1     1   4 use Data::Dumper;
  1         2  
  1         1408  
19              
20             sub new {
21 0     0 0   my $that = shift;
22 0   0       my $proto = ref($that) || $that;
23 0           my $self = {@_};
24              
25 0           bless( $self, $proto );
26              
27 0           $self->load;
28              
29 0           return $self;
30             }
31              
32             sub load {
33 0     0 0   my ($self) = @_;
34              
35 0 0         if ( -f $self->_config_file() ) {
36 0           $self->{rex_configuration} = YAML::LoadFile( $self->_config_file );
37             }
38             }
39              
40 0     0 0   sub project { (shift)->{project} }
41 0     0 0   sub name { (shift)->{rex_configuration}->{name} }
42 0     0 0   sub url { (shift)->{rex_configuration}->{url} }
43 0     0 0   sub description { (shift)->{rex_configuration}->{description} }
44 0     0 0   sub groups { (shift)->{rex_configuration}->{rex}->{groups} }
45 0     0 0   sub directory { (shift)->{directory} }
46 0     0 0   sub rexfile { (shift)->{rex_configuration}->{rexfile} }
47              
48             sub _config_file {
49 0     0     my ($self) = @_;
50 0           return File::Spec->catfile( $self->project->project_path(),
51             "rex", $self->{directory}, "rex.conf.yml" );
52             }
53              
54             sub create {
55 0     0 0   my ( $self, %data ) = @_;
56              
57 0           my $rex_path = File::Spec->catdir( $self->project->project_path,
58             "rex", $self->{directory} );
59              
60 0           $self->project->app->log->debug(
61             "Creating new Rexfile $self->{directory} in $rex_path.");
62              
63 0           File::Path::make_path($rex_path);
64              
65 0           my $rexfile = basename( $self->{url} );
66 0           $rexfile =~ s/(\.git|\.tar\.gz)$//;
67              
68 0           my $url = $self->{url};
69             chwd "$rex_path", sub {
70 0     0     my $rexify_cmd = $self->project->app->config->{rexify};
71 0           my @out = `$rexify_cmd --init=$url 2>&1`;
72 0           chomp @out;
73              
74 0           $self->project->app->log->debug("Output of rexify --init=$url");
75 0           for my $l (@out) {
76 0           $self->project->app->log->debug("rexfile: $l");
77             }
78 0           };
79              
80 0           my @tasks;
81             my $rex_info;
82              
83             chwd "$rex_path/$rexfile", sub {
84 0     0     my $rex_cmd = $self->project->app->config->{rex};
85 0           my $out = `$rex_cmd -Ty 2>&1`;
86 0 0         eval { $rex_info = YAML::Load($out); } or do {
  0            
87 0           $self->project->app->log->error("Error reading Rexfile information.");
88 0           $self->project->app->log->error("$out");
89 0           $self->project->app->log->error(
90             "Please try to run rex -Ty on the Rexfile to see the error.");
91             };
92 0           };
93              
94 0           delete $data{directory};
95              
96 0           my $rex_configuration = {
97             %data,
98             rexfile => $rexfile,
99             rex => $rex_info,
100             };
101              
102 0           YAML::DumpFile( "$rex_path/rex.conf.yml", $rex_configuration );
103             }
104              
105             sub tasks {
106 0     0 0   my ($self) = @_;
107 0   0       return ( $self->{rex_configuration}->{rex}->{tasks} || [] );
108             }
109              
110             sub environments {
111 0     0 0   my ($self) = @_;
112 0   0       return ( $self->{rex_configuration}->{rex}->{envs} || [] );
113             }
114              
115             sub all_server {
116 0     0 0   my ($self) = @_;
117              
118 0           my @all_server;
119              
120 0           for my $group ( keys %{ $self->groups } ) {
  0            
121 0           push @all_server,
122 0           ( map { $_ = { name => $_->{name}, group => $group, %{$_} } }
  0            
123 0           @{ $self->groups->{$group} } );
124             }
125              
126 0           return \@all_server;
127             }
128              
129             sub reload {
130 0     0 0   my ($self) = @_;
131              
132 0           my $rex_path = File::Spec->catdir( $self->project->project_path,
133             "rex", $self->{directory} );
134              
135 0           my $rexfile = $self->rexfile;
136 0           my $url = $self->url;
137              
138             chwd "$rex_path", sub {
139 0     0     my $rexify_cmd = $self->project->app->config->{rexify};
140 0           my @out = `$rexify_cmd --init=$url 2>&1`;
141 0           chomp @out;
142              
143 0           $self->project->app->log->debug("Output of rexify --init=$url");
144 0           for my $l (@out) {
145 0           $self->project->app->log->debug("rexfile: $l");
146             }
147 0           };
148              
149 0           my @tasks;
150             my $rex_info;
151              
152             chwd "$rex_path/$rexfile", sub {
153 0     0     my $rex_cmd = $self->project->app->config->{rex};
154 0           my $out = `$rex_cmd -Ty`;
155 0           $rex_info = YAML::Load($out);
156 0           };
157              
158 0           my $rex_configuration = {
159             name => $self->name,
160             url => $url,
161             rexfile => $rexfile,
162             rex => $rex_info,
163             };
164              
165 0           YAML::DumpFile( "$rex_path/rex.conf.yml", $rex_configuration );
166              
167             }
168              
169             sub remove {
170 0     0 0   my ($self) = @_;
171 0           my $rexfile_path = File::Spec->catdir( $self->project->project_path,
172             "rex", $self->{directory} );
173              
174 0           File::Path::remove_tree($rexfile_path);
175             }
176              
177             sub execute {
178 0     0 0   my ( $self, %option ) = @_;
179              
180 0           my $task = $option{task};
181 0           my $job = $option{job};
182 0           my @server = @{ $option{server} };
  0            
183 0           my $cmdb = $option{cmdb};
184              
185 0 0         if ( scalar @server == 0 ) {
186 0           @server = ("");
187             }
188              
189 0           my $rex_path = File::Spec->catdir( $self->project->project_path,
190             "rex", $self->{directory}, $self->rexfile );
191              
192 0           $self->project->app->log->debug("rex_path: $rex_path");
193              
194 0           my @ret;
195              
196 0           my $all_server = $self->project->all_server;
197              
198 0           for my $srv (@server) {
199              
200 0           my ($srv_object) = grep { $_->{name} eq $srv } @{$all_server};
  0            
  0            
201              
202 0 0         if ( exists $srv_object->{auth} ) {
203 0 0         if ( exists $srv_object->{auth}->{auth_type} ) {
204 0           $ENV{REX_AUTH_TYPE} = $srv_object->{auth}->{auth_type};
205             }
206              
207 0 0         if ( exists $srv_object->{auth}->{public_key} ) {
208 0           $ENV{REX_PUBLIC_KEY} = $srv_object->{auth}->{public_key};
209             }
210              
211 0 0         if ( exists $srv_object->{auth}->{private_key} ) {
212 0           $ENV{REX_PRIVATE_KEY} = $srv_object->{auth}->{private_key};
213             }
214              
215 0 0         if ( exists $srv_object->{auth}->{user} ) {
216 0           $ENV{REX_USER} = $srv_object->{auth}->{user};
217             }
218              
219 0 0         if ( exists $srv_object->{auth}->{password} ) {
220 0           $ENV{REX_PASSWORD} = $srv_object->{auth}->{password};
221             }
222              
223 0 0         if ( exists $srv_object->{auth}->{sudo_password} ) {
224 0           $ENV{REX_SUDO_PASSWORD} = $srv_object->{auth}->{sudo_password};
225             }
226              
227 0 0         if ( exists $srv_object->{auth}->{sudo} ) {
228 0           $ENV{REX_SUDO} = $srv_object->{auth}->{sudo};
229             }
230              
231             }
232              
233 0           $ENV{JOBCONTROL_PROJECT_PATH} = $self->project->project_path;
234              
235 0           my $child_exit_status;
236             chwd $rex_path, sub {
237 0     0     my ( $chld_out, $chld_in, $pid );
238              
239 0           $self->project->app->log->debug(
240             "Writing output to: $ENV{JOBCONTROL_EXECUTION_PATH}/output.log");
241              
242 0           my $out_fh =
243             IO::File->new( "$ENV{JOBCONTROL_EXECUTION_PATH}/output.log", "a+" );
244 0           my $err_fh =
245             IO::File->new( "$ENV{JOBCONTROL_EXECUTION_PATH}/output.log", "a+" );
246             capture {
247 0 0         system( $self->project->app->config->{rex},
248             '-H', $srv, '-t', 1, '-F', '-c', '-m',
249             ( $cmdb ? ( '-O', "cmdb_path=$cmdb/jobcontrol.yml" ) : () ), $task );
250              
251 0           $child_exit_status = $?;
252             }
253 0           stdout => $out_fh, stderr => $err_fh;
254              
255 0           };
256              
257 0 0         if ( $child_exit_status == 0 ) {
258 0           push @ret,
259             {
260             server => $srv,
261             rexfile => $self->name,
262             task => $task,
263             status => "success",
264             };
265             }
266             else {
267 0           push @ret,
268             {
269             server => $srv,
270             rexfile => $self->name,
271             task => $task,
272             status => "failed",
273             };
274             }
275              
276 0 0 0       if ( $child_exit_status != 0 && $job->fail_strategy eq "terminate" ) {
277 0           $ret[-1]->{terminate_message} =
278             "Terminating execution due to terminate fail strategy.";
279             }
280              
281             }
282              
283 0           return \@ret;
284             }
285              
286             1;