File Coverage

blib/lib/Svsh/Runit.pm
Criterion Covered Total %
statement 9 15 60.0
branch n/a
condition 0 4 0.0
subroutine 3 5 60.0
pod 2 2 100.0
total 14 26 53.8


line stmt bran cond sub pod time code
1             package Svsh::Runit;
2              
3 1     1   1047 use Moo;
  1         2  
  1         6  
4 1     1   290 use namespace::clean;
  1         1  
  1         5  
5              
6 1     1   796 use Proc::Killall;
  1         5670  
  1         672  
7              
8             our $DEFAULT_BASEDIR = -e '/etc/service' ? '/etc/service' : '/service';
9              
10             with 'Svsh';
11              
12             =head1 NAME
13              
14             Svsh::Runit - runit support for svsh
15              
16             =head1 DESCRIPTION
17              
18             This class provides support for L
19             to L - the supervisor shell.
20              
21             =head2 DEFAULT BASE DIRECTORY
22              
23             Traditionally, C used C as the default base directory,
24             but versions 1.9.0 changed the default to C. C still recommends
25             C for FHS compliant systems, so this class uses C
26             if it exists, or C otherwise, if a base directory is not provided
27             to C.
28              
29             =head1 IMPLEMENTED METHODS
30              
31             Refer to L for complete explanation of these methods. Only changes from
32             the base specifications are listed here.
33              
34             =head2 status()
35              
36             =cut
37              
38             sub status {
39             my $statuses = {};
40             foreach ($_[0]->_service_dirs) {
41             my $raw = $_[0]->run_cmd('sv', 'status', $_[0]->basedir.'/'.$_);
42              
43             my ($status, $pid, $duration) = $raw =~ m/^([^:]+):[^:]+:(?: \(pid (\d+)\))? (\d+)s/;
44              
45             $status = 'up'
46             if $status eq 'run';
47              
48             $statuses->{$_} = {
49             status => $status,
50             duration => $duration || 0,
51             pid => $pid || '-'
52             };
53             }
54             return $statuses;
55             }
56              
57             =head start( @services )
58              
59             =cut
60              
61             sub start {
62             $_[0]->run_cmd('sv', 'up', map { $_[0]->basedir.'/'.$_ } @{$_[2]->{args}});
63             }
64              
65             =head stop( @services )
66              
67             =cut
68              
69             sub stop {
70             $_[0]->run_cmd('sv', 'down', map { $_[0]->basedir.'/'.$_ } @{$_[2]->{args}});
71             }
72              
73             =head restart( @services )
74              
75             =cut
76              
77             sub restart {
78             $_[0]->run_cmd('sv', 'quit', map { $_[0]->basedir.'/'.$_ } @{$_[2]->{args}});
79             }
80              
81             =head signal( $signal, @services )
82              
83             =cut
84              
85             sub signal {
86             my ($sign, @sv) = @{$_[2]->{args}};
87              
88             # convert signal to perpctl command
89             $sign =~ s/^sig//i;
90             if ($sign =~ m/^usr(1|2)$/) {
91             $sign = $1;
92             } elsif ($sign eq 'alrm') {
93             $sign = 'alarm';
94             } elsif ($sign eq 'int') {
95             $sign = 'interrupt';
96             }
97              
98             $_[0]->run_cmd('sv', lc($sign), map { $_[0]->basedir.'/'.$_ } @sv);
99             }
100              
101             =head2 fg( $service )
102              
103             =cut
104              
105             sub fg {
106             # find out the pid of the logging process
107 0     0 1   my $text = $_[0]->run_cmd('sv', 'status', $_[0]->basedir.'/'.$_[2]->{args}->[0]);
108 0   0       my $pid = ($text =~ m/log: \(pid (\d+)\)/)[0]
109             || die "Can't figure out pid of the logging process";
110              
111             # find out the current log file
112 0   0       my $logfile = $_[0]->find_logfile($pid)
113             || die "Can't find out process' log file";
114              
115 0           $_[0]->run_cmd('tail', '-f', $logfile, { as_system => 1 });
116             }
117              
118             =head2 terminate()
119              
120             =cut
121              
122             sub terminate {
123 0     0 1   my $basedir = $_[0]->basedir;
124 0           killall('HUP', "runsvdir $basedir");
125             }
126              
127             =head1 BUGS AND LIMITATIONS
128              
129             No bugs have been reported.
130              
131             Please report any bugs or feature requests to
132             C, or through the web interface at
133             L.
134              
135             =head1 SUPPORT
136              
137             You can find documentation for this module with the perldoc command.
138              
139             perldoc Svsh::Runit
140              
141             You can also look for information at:
142              
143             =over 4
144            
145             =item * RT: CPAN's request tracker
146            
147             L
148            
149             =item * AnnoCPAN: Annotated CPAN documentation
150            
151             L
152            
153             =item * CPAN Ratings
154            
155             L
156            
157             =item * Search CPAN
158            
159             L
160            
161             =back
162              
163             =head1 AUTHOR
164              
165             Ido Perlmuter
166              
167             =head1 LICENSE AND COPYRIGHT
168              
169             Copyright (c) 2015, Ido Perlmuter C<< ido at ido50 dot net >>.
170              
171             This module is free software; you can redistribute it and/or
172             modify it under the same terms as Perl itself, either version
173             5.8.1 or any later version. See L
174             and L.
175              
176             The full text of the license can be found in the
177             LICENSE file included with this module.
178              
179             =head1 DISCLAIMER OF WARRANTY
180              
181             BECAUSE THIS SOFTWARE IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
182             FOR THE SOFTWARE, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
183             OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
184             PROVIDE THE SOFTWARE "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER
185             EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
186             WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE
187             ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE SOFTWARE IS WITH
188             YOU. SHOULD THE SOFTWARE PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL
189             NECESSARY SERVICING, REPAIR, OR CORRECTION.
190              
191             IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
192             WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
193             REDISTRIBUTE THE SOFTWARE AS PERMITTED BY THE ABOVE LICENCE, BE
194             LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL,
195             OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE
196             THE SOFTWARE (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
197             RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
198             FAILURE OF THE SOFTWARE TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
199             SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
200             SUCH DAMAGES.
201              
202             =cut
203              
204             1;
205             __END__