File Coverage

blib/lib/Ixchel/Actions/systemd_auto.pm
Criterion Covered Total %
statement 17 94 18.0
branch 0 40 0.0
condition 0 6 0.0
subroutine 6 10 60.0
pod 2 4 50.0
total 25 154 16.2


line stmt bran cond sub pod time code
1             package Ixchel::Actions::systemd_auto;
2              
3 1     1   82875 use 5.006;
  1         5  
4 1     1   4 use strict;
  1         2  
  1         36  
5 1     1   4 use warnings;
  1         1  
  1         74  
6 1     1   545 use File::Slurp;
  1         32565  
  1         63  
7 1     1   425 use String::ShellQuote;
  1         773  
  1         56  
8 1     1   5 use base 'Ixchel::Actions::base';
  1         2  
  1         374  
9              
10             =head1 NAME
11              
12             Ixchel::Actions::systemd_auto - Generate systemd service files using the systemd_service template.
13              
14             =head1 VERSION
15              
16             Version 0.2.0
17              
18             =cut
19              
20             our $VERSION = '0.2.0';
21              
22             =head1 CLI SYNOPSIS
23              
24             ixchel -a systemd_auto [B<-s> ] [B<--np>] [B<-w>] [B<-s> ]
25             [B<--reload>] [B<--enable>] [B<--start>] [B<--restart>]
26              
27             =head1 CODE SYNOPSIS
28              
29             use Data::Dumper;
30              
31             my $results=$ixchel->action(action=>'systemd_auto', opts=>{np=>1, w=>1, reload=>1, enable=>1, start=>1, });
32              
33             print Dumper($results);
34              
35             =head1 DESCRIPTION
36              
37             The template used is systemd_service.
38              
39             The generated services will be named ixchelAuto-$service.
40              
41             Should be noted that the this can return what the generated templates will contain via checking the
42             output on non-systemd systems attempting to use -w or the like outside of systemd systems will result
43             in it failing. Printing the results on other systems is meant primarily for testing/debugging purposes.
44              
45             =head1 FLAGS
46              
47             =head2 -w
48              
49             Write the generated services to service files.
50              
51             =head2 -s
52              
53             A auto service to operate on.
54              
55             Otherwise operates on them all.
56              
57             =head2 --reload
58              
59             Run systemctl daemon-reload.
60              
61             =head2 --enable
62              
63             Enable the generated services.
64              
65             =head2 --start
66              
67             Start the generated services.
68              
69             =head2 --restart
70              
71             Restart the generated services.
72              
73             =head1 RESULT HASH REF
74              
75             .errors :: A array of errors encountered.
76             .status_text :: A string description of what was done and teh results.
77             .is_systemd :: Set to 1 if the system in question is systemd.
78             .started :: Set to 0 if starting anything failed.
79             .restarted :: Set to 0 if restarting anything failed.
80             .enabled :: Set to 0 if enabling anything failed.
81             .reloaded :: Set to 0 if reloading systemd failed.
82             .ok :: Set to zero if any of the above errored.
83              
84             =cut
85              
86             sub new_extra {
87 0     0 0   my $self = $_[0];
88              
89             $self->{results} = {
90 0           errors => [],
91             status_text => '',
92             is_systemd => 0,
93             written => 1,
94             started => 1,
95             restarted => 1,
96             enabled => 1,
97             reloaded => 1,
98             ok => 0,
99             };
100             } ## end sub new_extra
101              
102             sub action_extra {
103 0     0 0   my $self = $_[0];
104              
105             # not dying here is intentional for testing purposes
106 0 0 0       if ( $^O eq 'linux' && ( -f '/usr/bin/systemctl' || -f '/bin/systemctl' ) ) {
      0        
107 0           $self->{results}{is_systemd} = 1;
108             }
109              
110 0           my @units;
111              
112             # if we have a single service specified via -s, use that
113             # otherwise act upon them all
114             my @services;
115 0 0         if ( defined( $self->{opts}{s} ) ) {
116 0 0         if ( !defined( $self->{config}{systemd}{auto}{ $self->{opts}{s} } ) ) {
117 0           die( '"' . $self->{opts}{s} . '" does not exist as a defined systemd auto service' );
118             }
119 0           @services = ( $self->{opts}{s} );
120             } else {
121 0           @services = keys( %{ $self->{config}{systemd}{auto} } );
  0            
122             }
123              
124             # if we don't have any services, nothing we can do
125 0 0         if ( !defined( $services[0] ) ) {
126 0           die('There are no configured auto services under .systemd.auto');
127             }
128              
129             # attempt to configure the various services
130 0           foreach my $service (@services) {
131 0           my $service_vars = $self->{config}{systemd}{auto}{$service};
132              
133 0           my $unit = 'ixchelAuto-' . $service . '.service';
134              
135 0 0         if ( !defined( $service_vars->{description} ) ) {
136 0           $service_vars->{description} = 'Ixchel autogenerated service ' . $service;
137             }
138              
139 0           my $filled_in;
140 0           eval {
141             $filled_in = $self->{ixchel}->action(
142 0           action => 'template',
143             vars => $service_vars,
144             opts => {
145             np => 1,
146             t => 'systemd_service',
147             },
148             );
149              
150 0 0         if ( $self->{opts}{w} ) {
151 0           write_file( '/lib/systemd/system/' . $unit, $filled_in );
152             }
153             };
154 0 0         if ($@) {
155 0           $self->{results}{written} = 0;
156 0 0         if ( !defined($filled_in) ) {
157 0           $filled_in = '';
158             }
159             $self->status_add(
160 0           status => '-----[ ERROR '
161             . $unit
162             . ' ]-------------------------------------' . "\n" . '# '
163             . $@
164             . $filled_in . "\n",
165             error => 1,
166             );
167 0           $self->{ixchel}{errors_count}++;
168             } else {
169 0           push( @units, $unit );
170 0           $self->status_add( status => '-----[ '
171             . $unit
172             . ' ]-------------------------------------' . "\n"
173             . $filled_in
174             . "\n" );
175             }
176             } ## end foreach my $service (@services)
177              
178             # if asked to reload systemd, attempt to do so
179 0 0         if ( $self->{opts}{reload} ) {
180 0           my $output = `systemctl daemon-reload 2>&1`;
181 0 0         if ( !defined($output) ) {
182 0           $output = '';
183             }
184 0 0         if ( $? != 0 ) {
185 0           $self->status_add(
186             status => '-----[ Reload Error ]-------------------------------------' . "\n"
187             . "# systemctl daemon-reload 2>&1 exited non zero...\n"
188             . $output . "\n",
189             error => 1,
190             );
191 0           $self->{ixchel}{errors_count}++;
192             } else {
193 0           $self->status_add( status => '-----[ Reload ]-------------------------------------' . "\n"
194             . "# systemctl daemon-reload 2>&1 exit zero...\n"
195             . $output
196             . "\n" );
197             }
198             } ## end if ( $self->{opts}{reload} )
199              
200             # if asked to enable the services, attempt to do so
201 0 0         if ( $self->{opts}{enable} ) {
202 0           foreach my $unit (@units) {
203 0           my $escaped_unit = shell_quote($unit);
204 0           my $command = 'systemctl enable ' . $escaped_unit . ' 2>&1';
205 0           my $output = `$command`;
206 0 0         if ( !defined($output) ) {
207 0           $output = '';
208             }
209 0 0         if ( $? != 0 ) {
210 0           $self->{results}{enabled} = 0;
211 0           $self->status_add(
212             status => '-----[ Enable '
213             . $unit
214             . ' Error ]-------------------------------------' . "\n" . '# '
215             . $command
216             . " exited non zero...\n"
217             . $output . "\n",
218             error => 1
219             );
220 0           $self->{ixchel}{errors_count}++;
221             } else {
222 0           $self->status_add( status => '-----[ Enable '
223             . $unit
224             . ' ]-------------------------------------' . "\n" . '# '
225             . $command
226             . " exited zero...\n"
227             . $output
228             . "\n" );
229             }
230             } ## end foreach my $unit (@units)
231             } ## end if ( $self->{opts}{enable} )
232              
233             # if asked to start the services, attempt to do so
234 0 0         if ( $self->{opts}{start} ) {
235 0           foreach my $unit (@units) {
236 0           my $escaped_unit = shell_quote($unit);
237 0           my $command = 'systemctl start ' . $escaped_unit . ' 2>&1';
238 0           my $output = `$command`;
239 0 0         if ( !defined($output) ) {
240 0           $output = '';
241             }
242 0 0         if ( $? != 0 ) {
243 0           $self->{results}{started} = 0;
244 0           $self->status_add(
245             status => '-----[ Start '
246             . $unit
247             . ' Error ]-------------------------------------' . "\n" . '# '
248             . $command
249             . " exited non zero...\n"
250             . $output . "\n",
251             error => 1,
252             );
253             } else {
254 0           $self->status_add( status => '-----[ Start '
255             . $unit
256             . ' ]-------------------------------------' . "\n" . '# '
257             . $command
258             . " exited zero...\n"
259             . $output
260             . "\n" );
261             }
262             } ## end foreach my $unit (@units)
263             } ## end if ( $self->{opts}{start} )
264              
265             # if asked to restart the services, attempt to do so
266 0 0         if ( $self->{opts}{restart} ) {
267 0           foreach my $unit (@units) {
268 0           my $escaped_unit = shell_quote($unit);
269 0           my $command = 'systemctl restart ' . $escaped_unit . ' 2>&1';
270 0           my $output = `$command`;
271 0 0         if ( !defined($output) ) {
272 0           $output = '';
273             }
274 0 0         if ( $? != 0 ) {
275 0           $self->{results}{restarted} = 0;
276 0           $self->status_add(
277             '-----[ Retart '
278             . $unit
279             . ' Error ]-------------------------------------' . "\n" . '# '
280             . $command
281             . " exited non zero...\n"
282             . $output . "\n",
283             error => 1
284             );
285             } else {
286 0           $self->status_add( status => '-----[ Retart '
287             . $unit
288             . ' ]-------------------------------------' . "\n" . '# '
289             . $command
290             . " exited zero...\n"
291             . $output
292             . "\n" );
293             }
294             } ## end foreach my $unit (@units)
295             } ## end if ( $self->{opts}{restart} )
296              
297 0           return undef;
298             } ## end sub action_extra
299              
300             sub short {
301 0     0 1   return 'Handles generation of service file as specified under .systemd.auto .';
302             }
303              
304             sub opts_data {
305 0     0 1   return 's=s
306             w
307             reload
308             start
309             enable
310             restart
311             ';
312             }
313              
314             1;