File Coverage

blib/lib/Clustericious/Command/stop.pm
Criterion Covered Total %
statement 26 87 29.8
branch 0 34 0.0
condition 0 10 0.0
subroutine 9 15 60.0
pod 1 1 100.0
total 36 147 24.4


line stmt bran cond sub pod time code
1             package Clustericious::Command::stop;
2              
3 1     1   673 use strict;
  1         2  
  1         26  
4 1     1   6 use warnings;
  1         2  
  1         21  
5 1     1   16 use 5.010001;
  1         3  
6 1     1   5 use Clustericious::Log;
  1         1  
  1         7  
7 1     1   644 use Clustericious::App;
  1         2  
  1         6  
8 1     1   25 use Mojo::URL;
  1         2  
  1         8  
9 1     1   23 use File::Basename qw( dirname );
  1         2  
  1         49  
10 1     1   6 use base 'Clustericious::Command';
  1         2  
  1         107  
11 1     1   7 use Clustericious;
  1         2  
  1         689  
12              
13             # ABSTRACT: Clustericious command to stop a Clustericious application
14             our $VERSION = '1.27'; # VERSION
15              
16              
17             __PACKAGE__->attr(description => <<EOT);
18             Stop a running daemon.
19             EOT
20              
21             __PACKAGE__->attr(usage => <<EOT);
22             usage $0: stop
23              
24             Send a TERM signal to running daemon(s).
25             See Clustericious::Command::Stop.
26             EOT
27              
28             sub _stop_pidfile
29             {
30 0     0     my($pid_file, $signal) = @_;
31 0 0         -e $pid_file or do { WARN "No pid file $pid_file\n"; return; };
  0            
  0            
32 0           TRACE "pid_file : $pid_file";
33 0           my $pid = Clustericious::_slurp_pid $pid_file; # dies automatically
34 0           chomp $pid;
35 0           TRACE "file $pid_file has pid $pid";
36 0           _stop_pid($pid, $signal);
37 0 0         -e $pid_file or return;
38 0 0         unlink $pid_file or WARN "Could not remove $pid_file";
39             }
40              
41             sub _stop_pid
42             {
43 0     0     my($pid, $signal) = @_;
44 0   0       $signal //= 'QUIT';
45 0 0 0       unless ($pid && $pid=~/^\d+$/)
46             {
47 0           WARN "Bad pid '$pid'. Not stopping process.";
48 0           return;
49             }
50 0 0         kill 0, $pid or do { WARN "$pid is not running"; return; };
  0            
  0            
51 0           INFO "Sending $signal to $pid";
52 0           kill $signal, $pid;
53 0           sleep 1;
54 0           my $nap = 1;
55 0           while (kill 0, $pid)
56             {
57 0           INFO "waiting for $pid";
58 0           sleep $nap++;
59 0 0         if($nap > 5)
60             {
61 0           INFO "pid $pid did not die on request, killing with signal 9";
62 0           kill 9, $pid;
63 0           last;
64             }
65             }
66             }
67              
68             sub _stop_daemon
69             {
70 0     0     my($listen) = @_;
71 0           my $port = Mojo::URL->new($listen)->port;
72 0           my @got = `lsof -n -FR -i:$port`;
73 0 0 0       return unless @got && $got[0];
74             # Only the first one; others may be child processes
75 0           my ($pid) = $got[0] =~ /^p(\d+)$/;
76 0 0         unless ($pid)
77             {
78 0           WARN "could not find pid for daemon on port $port";
79 0           return;
80             }
81 0           TRACE "Stopping pid $pid";
82 0           _stop_pid($pid);
83             }
84              
85             sub _stop_nginx
86             {
87 0     0     my %conf = @_;
88 0           my $prefix = $conf{'-p'};
89 0   0       my $cnf = $conf{'-c'} || "";
90 0 0         $cnf = "-c $cnf" if $cnf;
91 0           INFO "stopping nginx in $prefix";
92 0 0         system("nginx -p $prefix $cnf -s quit")==0 or WARN "could not stop nginx";
93             }
94              
95             sub _stop_apache
96             {
97 0     0     my %conf = @_;
98 0           _stop_pidfile($conf{pid_file},'TERM');
99             }
100              
101             sub run
102             {
103 0     0 1   my($self, @args) = @_;
104 0 0         exit 2 unless $self->app->sanity_check;
105              
106 0           $self->app->init_logging();
107              
108 0           my $exe = $0;
109 0           for (reverse $self->app->config->start_mode) {
110 0           DEBUG "Stopping $_ server";
111 0 0         /hypnotoad/ and _stop_pidfile($self->app->config->hypnotoad->pid_file);
112 0 0         /plackup/ and _stop_pidfile($self->app->config->plackup->pid_file);
113 0 0         /lighttpd/ and _stop_pidfile($self->app->config->lighttpd->pid_file);
114 0 0         /daemon/ and _stop_daemon($self->app->config->daemon->listen);
115 0 0         /nginx/ and _stop_nginx($self->app->config->nginx);
116 0 0         /apache/ and _stop_apache($self->app->config->apache);
117             }
118              
119 0           1;
120             }
121              
122             1;
123              
124             __END__
125              
126             =pod
127              
128             =encoding UTF-8
129              
130             =head1 NAME
131              
132             Clustericious::Command::stop - Clustericious command to stop a Clustericious application
133              
134             =head1 VERSION
135              
136             version 1.27
137              
138             =head1 SYNOPSIS
139              
140             % yourapp stop
141              
142             =head1 DESCRIPTION
143              
144             Stop a running daemon.
145              
146             =head1 NOTES
147              
148             The different methods of starting put their pid files in
149             different places in the config file.
150              
151             =head1 AUTHOR
152              
153             Original author: Brian Duggan
154              
155             Current maintainer: Graham Ollis E<lt>plicease@cpan.orgE<gt>
156              
157             Contributors:
158              
159             Curt Tilmes
160              
161             Yanick Champoux
162              
163             =head1 COPYRIGHT AND LICENSE
164              
165             This software is copyright (c) 2013 by NASA GSFC.
166              
167             This is free software; you can redistribute it and/or modify it under
168             the same terms as the Perl 5 programming language system itself.
169              
170             =cut