3ab5f576f062e7f6abde022ec9d9de9b34aa092e
[OpenSRF.git] / bin / opensrf-perl.pl
1 #!/usr/bin/perl
2 # ---------------------------------------------------------------
3 # Copyright (C) 2008  Georgia Public Library Service
4 # Bill Erickson <erickson@esilibrary.com>
5 #
6 # This program is free software; you can redistribute it and/or
7 # modify it under the terms of the GNU General Public License
8 # as published by the Free Software Foundation; either version 2
9 # of the License, or (at your option) any later version.
10 #
11 # This program is distributed in the hope that it will be useful,
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 # GNU General Public License for more details.
15 # ---------------------------------------------------------------
16 use strict; use warnings;
17 use Getopt::Long;
18 use Net::Domain qw/hostfqdn/;
19 use POSIX qw/setsid :sys_wait_h/;
20 use OpenSRF::Utils::Logger q/$logger/;
21 use OpenSRF::System;
22 use OpenSRF::Transport::PeerHandle;
23 use OpenSRF::Utils::SettingsClient;
24 use OpenSRF::Transport::Listener;
25 use OpenSRF::Utils;
26 use OpenSRF::Utils::Config;
27
28 my $action = undef;
29 my $service = undef;
30 my $config = undef;
31 my $pid_dir = '/tmp';
32 my $no_daemon = 0;
33 my $help = 0;
34 my $sclient;
35 my $hostname = hostfqdn();
36
37 GetOptions(
38     'action=s' => \$action,
39     'service=s' => \$service,
40     'config=s' => \$config,
41     'pid_dir=s' => \$pid_dir,
42     'no_daemon' => \$no_daemon,
43     'help' => \$help,
44 );
45
46 my $pid_file = "$pid_dir/$service.pid" if $pid_dir and $service;
47
48 sub haltme {
49     kill('INT', -$$); #kill all in process group
50     exit;
51 };
52 $SIG{INT} = \&haltme;
53 $SIG{TERM} = \&haltme;
54
55 # stop a specific service
56 sub do_stop {
57     if(-e $pid_file) {
58         my $pid = `cat $pid_file`;
59         kill('INT', $pid);
60         unlink $pid_file;
61     } else {
62         msg("$service not running");
63     }
64 }
65
66 # start a specific service
67 sub do_start {
68
69     OpenSRF::System->bootstrap_client(config_file => $config);
70
71     die "Unable to bootstrap client for requests\n"
72         unless OpenSRF::Transport::PeerHandle->retrieve;
73
74     load_settings() if $service eq 'opensrf.settings';
75
76     my $sclient = OpenSRF::Utils::SettingsClient->new;
77     my $apps = $sclient->config_value("activeapps", "appname");
78     OpenSRF::Transport::PeerHandle->retrieve->disconnect;
79
80     if($apps) {
81         $apps = [$apps] unless ref $apps;
82         for my $app (@$apps) {
83             if($app eq $service) {
84                 if($sclient->config_value('apps', $app, 'language') =~ /perl/i) {
85                     do_daemon() unless $no_daemon;
86                     launch_net_server();
87                     launch_listener();
88                     $0 = "OpenSRF controller [$service]";
89                     while(my $pid = waitpid(-1, 0)) {
90                         $logger->debug("Cleaning up Perl $service process $pid");
91                     }
92                 }
93             }
94         }
95     }
96
97     msg("$service is not configured to run on $hostname");
98 }
99
100 # daemonize us
101 sub do_daemon {
102     exit if OpenSRF::Utils::safe_fork();
103     chdir('/');
104     setsid();
105     close STDIN;
106     close STDOUT;
107     close STDERR;
108     `echo $$ > $pid_file`;
109 }
110
111 # parses the local settings file
112 sub load_settings {
113     my $conf = OpenSRF::Utils::Config->current;
114     my $cfile = $conf->bootstrap->settings_config;
115     my $parser = OpenSRF::Utils::SettingsParser->new();
116     $parser->initialize( $cfile );
117     $OpenSRF::Utils::SettingsClient::host_config =
118         $parser->get_server_config($conf->env->hostname);
119 }
120
121 # starts up the unix::server master process
122 sub launch_net_server {
123     push @OpenSRF::UnixServer::ISA, 'Net::Server::PreFork';
124     unless(OpenSRF::Utils::safe_fork()) {
125         $0 = "OpenSRF Drone [$service]";
126         OpenSRF::UnixServer->new($service)->serve;
127         exit;
128     }
129     return 1;
130 }
131
132 # starts up the inbound listener process
133 sub launch_listener {
134     unless(OpenSRF::Utils::safe_fork()) {
135         $0 = "OpenSRF listener [$service]";
136         OpenSRF::Transport::Listener->new($service)->initialize->listen;
137         exit;
138     }
139     return 1;
140 }
141
142 sub msg {
143     my $m = shift;
144     print "* $m\n";
145 }
146
147 sub do_help {
148     print <<HELP;
149
150     Usage: perl $0 --pid_dir /var/run/opensrf --config /etc/opensrf/opensrf_core.xml --service opensrf.settings --action start
151
152     --action <action>
153         Actions include start, stop, restart, and start_all, stop_all, and restart_all
154
155     --service <service>
156         Specifies which OpenSRF service to control
157
158     --config <file>
159         OpenSRF configuration file 
160         
161     --pid_dir <dir>
162         Directory where process-specific PID files are kept
163         
164     --no_daemon
165         Do not detach and run as a daemon process.  Useful for debugging.
166         
167     --help
168         Print this help message
169 HELP
170 exit;
171 }
172
173
174 do_help() if $help or not $action;
175 do_start() if $action eq 'start';
176 do_stop() if $action eq 'stop';
177 do_stop() and do_start() if $action eq 'restart';
178
179