7211601e432495fadc9808eedb8eb472021b5a44
[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         waitpid($pid, 0);
61         unlink $pid_file;
62     } else {
63         msg("$service not running");
64     }
65 }
66
67 # start a specific service
68 sub do_start {
69
70     OpenSRF::System->bootstrap_client(config_file => $config);
71
72     die "Unable to bootstrap client for requests\n"
73         unless OpenSRF::Transport::PeerHandle->retrieve;
74
75     load_settings() if $service eq 'opensrf.settings';
76
77     my $sclient = OpenSRF::Utils::SettingsClient->new;
78     my $apps = $sclient->config_value("activeapps", "appname");
79     OpenSRF::Transport::PeerHandle->retrieve->disconnect;
80
81     if($apps) {
82         $apps = [$apps] unless ref $apps;
83         for my $app (@$apps) {
84             if($app eq $service) {
85                 if($sclient->config_value('apps', $app, 'language') =~ /perl/i) {
86                     do_daemon() unless $no_daemon;
87                     launch_net_server();
88                     launch_listener();
89                     $0 = "OpenSRF controller [$service]";
90                     while(my $pid = waitpid(-1, 0)) {
91                         $logger->debug("Cleaning up Perl $service process $pid");
92                     }
93                 }
94             }
95         }
96     }
97
98     msg("$service is not configured to run on $hostname");
99 }
100
101 # daemonize us
102 sub do_daemon {
103     exit if OpenSRF::Utils::safe_fork();
104     chdir('/');
105     setsid();
106     close STDIN;
107     close STDOUT;
108     close STDERR;
109     `echo $$ > $pid_file`;
110 }
111
112 # parses the local settings file
113 sub load_settings {
114     my $conf = OpenSRF::Utils::Config->current;
115     my $cfile = $conf->bootstrap->settings_config;
116     my $parser = OpenSRF::Utils::SettingsParser->new();
117     $parser->initialize( $cfile );
118     $OpenSRF::Utils::SettingsClient::host_config =
119         $parser->get_server_config($conf->env->hostname);
120 }
121
122 # starts up the unix::server master process
123 sub launch_net_server {
124     push @OpenSRF::UnixServer::ISA, 'Net::Server::PreFork';
125     unless(OpenSRF::Utils::safe_fork()) {
126         $0 = "OpenSRF Drone [$service]";
127         OpenSRF::UnixServer->new($service)->serve;
128         exit;
129     }
130     return 1;
131 }
132
133 # starts up the inbound listener process
134 sub launch_listener {
135     unless(OpenSRF::Utils::safe_fork()) {
136         $0 = "OpenSRF listener [$service]";
137         OpenSRF::Transport::Listener->new($service)->initialize->listen;
138         exit;
139     }
140     return 1;
141 }
142
143 sub msg {
144     my $m = shift;
145     print "* $m\n";
146 }
147
148 sub do_help {
149     print <<HELP;
150
151     Usage: perl $0 --pid_dir /var/run/opensrf --config /etc/opensrf/opensrf_core.xml --service opensrf.settings --action start
152
153     --action <action>
154         Actions include start, stop, restart, and start_all, stop_all, and restart_all
155
156     --service <service>
157         Specifies which OpenSRF service to control
158
159     --config <file>
160         OpenSRF configuration file 
161         
162     --pid_dir <dir>
163         Directory where process-specific PID files are kept
164         
165     --no_daemon
166         Do not detach and run as a daemon process.  Useful for debugging.
167         
168     --help
169         Print this help message
170 HELP
171 exit;
172 }
173
174
175 do_help() if $help or not $action;
176 do_start() if $action eq 'start';
177 do_stop() if $action eq 'stop';
178 do_stop() and do_start() if $action eq 'restart';
179
180