File Coverage

blib/lib/Svsh/Perp.pm
Criterion Covered Total %
statement 6 12 50.0
branch n/a
condition 0 4 0.0
subroutine 2 5 40.0
pod 3 3 100.0
total 11 24 45.8


line stmt bran cond sub pod time code
1             package Svsh::Perp;
2              
3 1     1   1603 use Moo;
  1         2738  
  1         5  
4 1     1   777 use namespace::clean;
  1         11785  
  1         8  
5              
6             our $DEFAULT_BASEDIR = $ENV{PERP_BASE} || '/etc/perp';
7              
8             with 'Svsh';
9              
10             =head1 NAME
11              
12             Svsh::Perp - perp support for svsh
13              
14             =head1 DESCRIPTION
15              
16             This class provides support for L
17             to L - the supervisor shell.
18              
19             =head2 DEFAULT BASE DIRECTORY
20              
21             As per the L documentation,
22             C does not have a default base directory, but will check if a C environment
23             variable is set, and if not, will try C. This class will do the same if
24             a base directory is not provided to C.
25              
26             =head1 IMPLEMENTED METHODS
27              
28             Refer to L for complete explanation of these methods. Only changes from
29             the base specifications are listed here.
30              
31             =head2 status()
32              
33             C provides more information about service statuses then
34             other supervisors. C means the service is down but should be
35             up (unexpected down), C means the service is down because
36             it was manually stopped, C means the service is restarting,
37             and C means the service is attempting to start (possibly failing,
38             not necessarily).
39              
40             =cut
41              
42             sub status {
43             my $statuses = {};
44             foreach ($_[0]->run_cmd('perpls', '-b', $_[0]->basedir, '-g')) {
45             chomp;
46             my @m = m/^
47             \[
48             .\s # the perpd status
49             (.)(.)(.)\s # the process status
50             ... # the logger status
51             \]\s+
52             (\S+)\s+ # the process name
53             (?:
54             uptime:\s+
55             ([^\/]+)s # the process uptime
56             \/
57             \S+s # the logger uptime
58             \s+
59             pids:\s+
60             ([^\/]+) # the process pid
61             \/
62             \S+ # the logger pid
63             )? # optional because inactive services will not have this
64             /x;
65              
66             my $status = $m[0] eq '+' ? $m[2] eq 'r' ? 'resetting' : 'up' :
67             $m[0] eq '.' ? 'down' :
68             $m[0] eq '!' ? 'backoff' :
69             $m[0] eq '-' ? 'disabled' : 'unknown';
70              
71             $statuses->{$m[3]} = {
72             status => $status,
73             pid => $status eq 'up' ? $m[5] : '-',
74             duration => $status eq 'up' ? $m[4] eq '-' ? 0 : int($m[4]) : 0
75             };
76             }
77              
78             return $statuses;
79             }
80              
81             =head start( @services )
82              
83             This uses the C option of C instead of C or C, see
84             L why.
85              
86             =cut
87              
88             sub start {
89             $_[0]->run_cmd('perpctl', '-b', $_[0]->basedir, 'A', @{$_[2]->{args}});
90             }
91              
92             =head stop( @services )
93              
94             This uses the C option of C instead of C or C, as there
95             seems to be a bug(?) where processes stopped with this option failed to
96             start again when the L method is called.
97              
98             =cut
99              
100             sub stop {
101             $_[0]->run_cmd('perpctl', '-b', $_[0]->basedir, 'X', @{$_[2]->{args}});
102             }
103              
104             =head restart( @services )
105              
106             =cut
107              
108             sub restart {
109             $_[0]->run_cmd('perpctl', '-b', $_[0]->basedir, 'q', @{$_[2]->{args}});
110             }
111              
112             =head2 signal( $signal, @services )
113              
114             =cut
115              
116             sub signal {
117             my ($sign, @sv) = @{$_[2]->{args}};
118              
119             # convert signal to perpctl command
120             $sign =~ s/^sig//i;
121             my $cmd = $sign =~ m/^usr(1|2)$/i ? $1 : lc(substr($sign, 0, 1));
122              
123             $_[0]->run_cmd('perpctl', '-b', $_[0]->basedir, $cmd, @sv);
124             }
125              
126             =head2 fg( $service )
127              
128             =cut
129              
130             sub fg {
131             # find out the pid of the logging process
132 0     0 1   my $text = $_[0]->run_cmd('perpstat', '-b', $_[0]->basedir, $_[2]->{args}->[0]);
133 0   0       my $pid = ($text =~ m/log:.+\(pid (\d+)\)/)[0]
134             || die "Can't figure out pid of the logging process";
135              
136             # find out the current log file
137 0   0       my $logfile = $_[0]->find_logfile($pid)
138             || die "Can't find out process' log file";
139              
140 0           $_[0]->run_cmd('tail', '-f', $logfile, { as_system => 1 });
141             }
142              
143             =head2 rescan()
144              
145             =cut
146              
147             sub rescan {
148 0     0 1   $_[0]->run_cmd('perphup', $_[0]->basedir);
149             }
150              
151             =head2 terminate()
152              
153             =cut
154              
155             sub terminate {
156 0     0 1   $_[0]->run_cmd('perphup', '-t', $_[0]->basedir);
157             }
158              
159             =head1 BUGS AND LIMITATIONS
160              
161             Please report any bugs or feature requests to
162             L.
163              
164             =head1 AUTHOR
165              
166             Ido Perlmuter
167              
168             Thanks to the guys at the L,
169             especially Colin Booth, for helping out with suggestions and information.
170              
171             =head1 LICENSE AND COPYRIGHT
172              
173             Copyright (c) 2015-2023, Ido Perlmuter C<< ido@ido50.net >>.
174              
175             Licensed under the Apache License, Version 2.0 (the "License");
176             you may not use this file except in compliance with the License.
177             You may obtain a copy of the License at
178              
179             http://www.apache.org/licenses/LICENSE-2.0
180              
181             Unless required by applicable law or agreed to in writing, software
182             distributed under the License is distributed on an "AS IS" BASIS,
183             WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
184             See the License for the specific language governing permissions and
185             limitations under the License.
186              
187             =cut
188              
189             1;
190             __END__