File Coverage

blib/lib/Rex/JobControl/Helper/Project/Rexfile.pm
Criterion Covered Total %
statement 27 146 18.4
branch 0 24 0.0
condition 0 6 0.0
subroutine 9 31 29.0
pod 0 16 0.0
total 36 223 16.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.6.0';
9 1     1   5 use strict;
  1         3  
  1         35  
10 1     1   5 use warnings;
  1         63  
  1         28  
11 1     1   4 use File::Spec;
  1         8  
  1         18  
12 1     1   4 use File::Path;
  1         2  
  1         73  
13 1     1   5 use File::Basename;
  1         2  
  1         57  
14 1     1   4 use YAML;
  1         1  
  1         40  
15 1     1   1616 use IPC::Open2;
  1         5342  
  1         66  
16              
17 1     1   10 use Rex::JobControl::Helper::Chdir;
  1         2  
  1         50  
18 1     1   7 use Data::Dumper;
  1         2  
  1         8797  
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           $rex_info = YAML::Load($out);
87 0           };
88              
89 0           $data{name} = $data{directory};
90 0           delete $data{directory};
91              
92 0           my $rex_configuration = {
93             %data,
94             rexfile => $rexfile,
95             rex => $rex_info,
96             };
97              
98 0           YAML::DumpFile( "$rex_path/rex.conf.yml", $rex_configuration );
99             }
100              
101             sub tasks {
102 0     0 0   my ($self) = @_;
103 0           return $self->{rex_configuration}->{rex}->{tasks};
104             }
105              
106             sub environments {
107 0     0 0   my ($self) = @_;
108 0           return $self->{rex_configuration}->{rex}->{envs};
109             }
110              
111             sub all_server {
112 0     0 0   my ($self) = @_;
113              
114 0           my @all_server;
115              
116 0           for my $group ( keys %{ $self->groups } ) {
  0            
117 0           push @all_server,
118 0           ( map { $_ = { name => $_->{name}, group => $group, %{ $_ } } }
  0            
119 0           @{ $self->groups->{$group} } );
120             }
121              
122 0           return \@all_server;
123             }
124              
125             sub reload {
126 0     0 0   my ($self) = @_;
127              
128 0           my $rex_path = File::Spec->catdir( $self->project->project_path,
129             "rex", $self->{directory} );
130              
131 0           my $rexfile = $self->rexfile;
132 0           my $url = $self->url;
133              
134             chwd "$rex_path", sub {
135 0     0     my $rexify_cmd = $self->project->app->config->{rexify};
136 0           my @out = `$rexify_cmd --init=$url 2>&1`;
137 0           chomp @out;
138              
139 0           $self->project->app->log->debug("Output of rexify --init=$url");
140 0           for my $l (@out) {
141 0           $self->project->app->log->debug("rexfile: $l");
142             }
143 0           };
144              
145 0           my @tasks;
146             my $rex_info;
147              
148             chwd "$rex_path/$rexfile", sub {
149 0     0     my $rex_cmd = $self->project->app->config->{rex};
150 0           my $out = `$rex_cmd -Ty`;
151 0           $rex_info = YAML::Load($out);
152 0           };
153              
154 0           my $rex_configuration = {
155             name => $self->{directory},
156             url => $url,
157             rexfile => $rexfile,
158             rex => $rex_info,
159             };
160              
161 0           YAML::DumpFile( "$rex_path/rex.conf.yml", $rex_configuration );
162              
163             }
164              
165             sub remove {
166 0     0 0   my ($self) = @_;
167 0           my $rexfile_path = File::Spec->catdir( $self->project->project_path,
168             "rex", $self->{directory} );
169              
170 0           File::Path::remove_tree($rexfile_path);
171             }
172              
173             sub execute {
174 0     0 0   my ( $self, %option ) = @_;
175              
176 0           my $task = $option{task};
177 0           my $job = $option{job};
178 0           my @server = @{ $option{server} };
  0            
179 0           my $cmdb = $option{cmdb};
180              
181 0           my $rex_path = File::Spec->catdir( $self->project->project_path,
182             "rex", $self->{directory}, $self->rexfile );
183              
184 0           my @ret;
185              
186 0           my $all_server = $self->project->all_server;
187              
188 0           for my $srv (@server) {
189              
190 0           my ($srv_object) = grep { $_->{name} eq $srv } @{ $all_server };
  0            
  0            
191              
192 0 0         if(exists $srv_object->{auth}) {
193 0 0         if(exists $srv_object->{auth}->{auth_type}) {
194 0           $ENV{REX_AUTH_TYPE} = $srv_object->{auth}->{auth_type};
195             }
196              
197 0 0         if(exists $srv_object->{auth}->{public_key}) {
198 0           $ENV{REX_PUBLIC_KEY} = $srv_object->{auth}->{public_key};
199             }
200              
201 0 0         if(exists $srv_object->{auth}->{private_key}) {
202 0           $ENV{REX_PRIVATE_KEY} = $srv_object->{auth}->{private_key};
203             }
204              
205 0 0         if(exists $srv_object->{auth}->{user}) {
206 0           $ENV{REX_USER} = $srv_object->{auth}->{user};
207             }
208              
209 0 0         if(exists $srv_object->{auth}->{password}) {
210 0           $ENV{REX_PASSWORD} = $srv_object->{auth}->{password};
211             }
212              
213 0 0         if(exists $srv_object->{auth}->{sudo_password}) {
214 0           $ENV{REX_SUDO_PASSWORD} = $srv_object->{auth}->{sudo_password};
215             }
216              
217 0 0         if(exists $srv_object->{auth}->{sudo}) {
218 0           $ENV{REX_SUDO} = $srv_object->{auth}->{sudo};
219             }
220              
221             }
222              
223 0           $ENV{JOBCONTROL_PROJECT_PATH} = $self->project->project_path;
224              
225 0           my $child_exit_status;
226             chwd $rex_path, sub {
227 0     0     my ( $chld_out, $chld_in, $pid );
228 0 0         $pid = open2(
229             $chld_out, $chld_in, $self->project->app->config->{rex},
230             '-H', $srv, '-t', 1, '-F', '-m',
231             ( $cmdb ? ( '-O', "cmdb_path=$cmdb/jobcontrol.yml" ) : () ), $task
232             );
233              
234 0           while ( my $line = <$chld_out> ) {
235 0           chomp $line;
236 0           $self->project->app->log->debug("rex: $line");
237             }
238              
239 0           waitpid( $pid, 0 );
240              
241 0           $child_exit_status = $? >> 8;
242 0           };
243              
244 0 0         if ( $child_exit_status == 0 ) {
245 0           push @ret,
246             {
247             server => $srv,
248             rexfile => $self->name,
249             task => $task,
250             status => "success",
251             };
252             }
253             else {
254 0           push @ret,
255             {
256             server => $srv,
257             rexfile => $self->name,
258             task => $task,
259             status => "failed",
260             };
261             }
262              
263 0 0 0       if ( $child_exit_status != 0 && $job->fail_strategy eq "terminate" ) {
264 0           $ret[-1]->{terminate_message} =
265             "Terminating execution due to terminate fail strategy.";
266             }
267              
268             }
269              
270 0           return \@ret;
271             }
272              
273             1;