File Coverage

lib/Ubic/Service/SimpleDaemon.pm
Criterion Covered Total %
statement 71 94 75.5
branch 21 40 52.5
condition n/a
subroutine 18 21 85.7
pod 11 11 100.0
total 121 166 72.8


line stmt bran cond sub pod time code
1             package Ubic::Service::SimpleDaemon;
2             $Ubic::Service::SimpleDaemon::VERSION = '1.59';
3 20     20   3164 use strict;
  20         31  
  20         543  
4 20     20   67 use warnings;
  20         24  
  20         657  
5              
6             # ABSTRACT: service module for daemonizing any binary
7              
8              
9 20     20   71 use parent qw(Ubic::Service::Skeleton);
  20         24  
  20         132  
10              
11 20     20   5614 use Ubic::Daemon qw(start_daemon stop_daemon check_daemon);
  20         33  
  20         141  
12 20     20   87 use Ubic::Result qw(result);
  20         28  
  20         817  
13 20     20   70 use Ubic::Settings;
  20         24  
  20         404  
14              
15 20     20   69 use Params::Validate qw(:all);
  20         25  
  20         20785  
16              
17             # Beware - this code will ignore any overrides if you're using custom Ubic->new(...) objects
18             our $PID_DIR;
19              
20             sub _pid_dir {
21 140 100   140   1268 return $PID_DIR if defined $PID_DIR;
22 11 50       64 if ($ENV{UBIC_DAEMON_PID_DIR}) {
23 0         0 warn "UBIC_DAEMON_PID_DIR env variable is deprecated, use Ubic->set_data_dir or configs instead (see Ubic::Settings for details)";
24 0         0 $PID_DIR = $ENV{UBIC_DAEMON_PID_DIR};
25             }
26             else {
27 11         73 $PID_DIR = Ubic::Settings->data_dir."/simple-daemon/pid";
28             }
29 11         132 return $PID_DIR;
30             }
31              
32             sub _send_signal {
33 8     8   24 my ($self, $signal) = @_;
34              
35 8         41 my $daemon = check_daemon($self->pidfile);
36 8 100       28 unless ($daemon) {
37 3         12 return result('not running');
38             }
39              
40 5         28 my $pid = $daemon->pid;
41 5         176 kill $signal => $pid;
42              
43 5         32 my $guardian_pid = $daemon->guardian_pid;
44 5         53 kill HUP => $guardian_pid;
45              
46 5         48 return result('reloaded', "sent $self->{reload_signal} to $pid, sent HUP to $guardian_pid");
47             }
48              
49             sub new {
50 39     39 1 13215 my $class = shift;
51 39         3180 my $params = validate(@_, {
52             bin => { type => SCALAR | ARRAYREF },
53             user => { type => SCALAR, optional => 1 },
54             group => { type => SCALAR | ARRAYREF, optional => 1 },
55             daemon_user => { type => SCALAR, optional => 1 },
56             daemon_group => { type => SCALAR | ARRAYREF, optional => 1 },
57             name => { type => SCALAR, optional => 1 },
58             pidfile => { type => SCALAR, optional => 1 },
59             stdout => { type => SCALAR, optional => 1 },
60             stderr => { type => SCALAR, optional => 1 },
61             ubic_log => { type => SCALAR, optional => 1 },
62             proxy_logs => { type => BOOLEAN, optional => 1 },
63             cwd => { type => SCALAR, optional => 1 },
64             env => { type => HASHREF, optional => 1 },
65             reload_signal => { type => SCALAR, optional => 1 },
66             term_timeout => { type => SCALAR, optional => 1, regex => qr/^\d+$/ },
67             stop_timeout => { type => SCALAR, optional => 1, regex => qr/^\d+$/ },
68             ulimit => { type => HASHREF, optional => 1 },
69             auto_start => { type => BOOLEAN, default => 0 },
70             });
71              
72 39 50       591 if ($params->{ulimit}) {
73             # load BSD::Resource lazily, but fail fast if we're asked for it
74 0         0 eval "require BSD::Resource";
75 0 0       0 if ($@) {
76 0         0 die "BSD::Resource is not installed";
77             }
78 0 0       0 if (BSD::Resource->VERSION < 1.29) {
79             # 1.29 supports string names for resources
80 0         0 die "BSD::Resource >= 1.29 required";
81             }
82             }
83              
84 39         385 return bless {%$params} => $class;
85             }
86              
87             sub pidfile {
88 140     140 1 216 my ($self) = @_;
89 140 50       599 return $self->{pidfile} if exists($self->{pidfile});
90 140 50       903 my $name = $self->full_name or die "Can't start nameless SimpleDaemon";
91 140         490 return _pid_dir."/$name";
92             }
93              
94             sub start_impl {
95 21     21 1 33 my ($self) = @_;
96              
97             my $start_params = {
98             pidfile => $self->pidfile,
99             bin => $self->{bin},
100 21         61 };
101 21         77 for (qw/ env cwd stdout stderr ubic_log proxy_logs term_timeout /) {
102 147 100       290 $start_params->{$_} = $self->{$_} if defined $self->{$_};
103             }
104 21 100       58 if ($self->{reload_signal}) {
105 5         22 $start_params->{proxy_logs} = 1;
106             }
107 21 50       61 if (defined $self->{daemon_user}) {
108             $start_params->{credentials} = Ubic::Credentials->new(
109             user => $self->{daemon_user},
110             group => $self->{daemon_group},
111 0         0 );
112             }
113 21 50       89 if (defined $self->{ulimit}) {
114             $start_params->{start_hook} = sub {
115 0     0   0 for my $name (keys %{$self->{ulimit}}) {
  0         0  
116 0         0 my $value = $self->{ulimit}{$name};
117 0         0 my $result = BSD::Resource::setrlimit($name, $value, $value);
118 0 0       0 unless ($result) {
119 0         0 die "Failed to set $name=$value ulimit";
120             }
121             }
122 0         0 };
123             }
124 21         114 start_daemon($start_params);
125             }
126              
127             sub user {
128 60     60 1 100 my $self = shift;
129 60 50       166 return $self->{user} if defined $self->{user};
130 60         247 return $self->SUPER::user();
131             }
132              
133             sub group {
134 60     60 1 76 my $self = shift;
135 60         76 my $groups = $self->{group};
136 60 50       377 return $self->SUPER::group() if not defined $groups;
137 0 0       0 return @$groups if ref $groups eq 'ARRAY';
138 0         0 return $groups;
139             }
140              
141             sub stop_impl {
142 15     15 1 26 my ($self) = @_;
143 15         31 my $options = {};
144 15 50       51 $options->{timeout} = $self->{stop_timeout} if $self->{stop_timeout};
145 15         41 stop_daemon($self->pidfile,$options);
146             }
147              
148             sub status_impl {
149 96     96 1 246 my ($self) = @_;
150 96 100       356 if (my $daemon = check_daemon($self->pidfile)) {
151 44         154 return result('running', "pid ".$daemon->pid);
152             }
153             else {
154 52         254 return result('not running');
155             }
156             }
157              
158             sub reload {
159 11     11 1 4002618 my $self = shift;
160 11 100       64 unless (defined $self->{reload_signal}) {
161 3         30 return result('unknown', 'not implemented');
162             }
163 8         50 return $self->_send_signal($self->{reload_signal});
164             }
165              
166             sub auto_start {
167 4     4 1 8 my $self = shift;
168 4         34 return $self->{auto_start};
169             }
170              
171              
172             our %SIGNALS = (
173             sigusr1 => 'SIGUSR1',
174             sigusr2 => 'SIGUSR2',
175             );
176              
177             sub custom_commands {
178 0     0 1   my ($self) = @_;
179 0           return keys %SIGNALS;
180             }
181              
182             sub do_custom_command {
183 0     0 1   my ($self, $command) = @_;
184 0 0         unless (defined $SIGNALS{$command}) {
185 0           return result('unknown', 'not implemented');
186             }
187              
188 0           return $self->_send_signal($SIGNALS{$command});
189             }
190              
191              
192             1;
193              
194             __END__