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