Lines 6-48
Link Here
|
6 |
# Date Created: 2004-05-04 11:14:05 |
6 |
# Date Created: 2004-05-04 11:14:05 |
7 |
# Revision: $FreeBSD: ports/www/cocoon/files/cocoonctl,v 1.1 2004/07/01 22:30:19 glewis Exp $ |
7 |
# Revision: $FreeBSD: ports/www/cocoon/files/cocoonctl,v 1.1 2004/07/01 22:30:19 glewis Exp $ |
8 |
################################################################################ |
8 |
################################################################################ |
|
|
9 |
# Copyright (c) 2004, Jean-Baptiste Quenot <jb.quenot@caraldi.com> |
10 |
# All rights reserved. |
11 |
# |
12 |
# Redistribution and use in source and binary forms, with or without |
13 |
# modification, are permitted provided that the following conditions are met: |
14 |
# |
15 |
# * Redistributions of source code must retain the above copyright notice, this |
16 |
# list of conditions and the following disclaimer. |
17 |
# * Redistributions in binary form must reproduce the above copyright notice, |
18 |
# this list of conditions and the following disclaimer in the documentation |
19 |
# and/or other materials provided with the distribution. |
20 |
# * The name of the contributors may not be used to endorse or promote products |
21 |
# derived from this software without specific prior written permission. |
22 |
# |
23 |
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" |
24 |
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
25 |
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE |
26 |
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE |
27 |
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
28 |
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR |
29 |
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER |
30 |
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, |
31 |
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
32 |
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
33 |
################################################################################ |
34 |
# |
35 |
# Files handled by this script (pid file, log files) must reside in a writable |
36 |
# directory, ie the directory must be owned by the user running the program. |
37 |
|
38 |
import sys, os, signal, time, stat, re |
39 |
|
40 |
def readProcessId(): |
41 |
f = open(PID_FILE, 'r') |
42 |
pid = int(f.readline()) |
43 |
f.close() |
44 |
return pid |
45 |
|
46 |
def isProgramRunning(pid): |
47 |
# Send a dummy signal to the process. If it died, an exception is |
48 |
# thrown |
49 |
try: |
50 |
os.kill(pid, signal.SIGCONT) |
51 |
return 1 |
52 |
except OSError: |
53 |
return 0 |
54 |
|
55 |
def usage(): |
56 |
print >> sys.stderr, "Usage: %s {start|stop|restart}" % sys.argv[0] |
57 |
|
58 |
def start(): |
59 |
cwd = os.getcwd() |
60 |
if os.path.exists(PID_FILE): |
61 |
# Read the process id |
62 |
pid = readProcessId() |
9 |
|
63 |
|
10 |
import sys, os, signal, time |
64 |
if isProgramRunning(pid): |
|
|
65 |
print >> sys.stderr, '%s already started' % APP_NAME |
66 |
sys.exit(3) |
67 |
|
68 |
if not(os.path.exists(COMMAND)): |
69 |
print >> sys.stderr, '%s cannot be found' % COMMAND |
70 |
sys.exit(3) |
71 |
|
72 |
# Append program output to a log file |
73 |
l = open(LOG_FILE, 'a') |
74 |
orig_stderr = os.dup(sys.stderr.fileno()) |
75 |
os.dup2(l.fileno(), sys.stdout.fileno()) |
76 |
os.dup2(l.fileno(), sys.stderr.fileno()) |
77 |
|
78 |
finfo = os.stat(COMMAND)[stat.ST_MODE] |
79 |
executable = stat.S_IMODE(finfo) & 0111 |
80 |
if not(executable): |
81 |
sys.stderr = os.fdopen(orig_stderr, 'w') |
82 |
print >> sys.stderr, 'Cannot run %s, execute bit is missing' % COMMAND |
83 |
sys.exit(5) |
84 |
|
85 |
if APP_HOME: |
86 |
# Change current directory to APP_HOME |
87 |
os.chdir(APP_HOME) |
88 |
|
89 |
# Start program in the background |
90 |
pid = os.spawnv(os.P_NOWAIT, COMMAND, ARGS) |
91 |
|
92 |
# Wait a little |
93 |
time.sleep(.4) |
94 |
(status_pid, status) = os.waitpid(pid, os.WNOHANG) |
95 |
|
96 |
# Check program exit status, if available |
97 |
if status_pid != 0 and os.WIFEXITED(status): |
98 |
sys.stderr = os.fdopen(orig_stderr, 'w') |
99 |
print >> sys.stderr, 'Could not start %s. Check %s for errors.' % (APP_NAME, LOG_FILE) |
100 |
sys.exit(2) |
101 |
|
102 |
# It's alive, so write down the process id |
103 |
os.chdir(cwd) |
104 |
f = open(PID_FILE, 'w') |
105 |
print >> f, pid |
106 |
f.close() |
107 |
|
108 |
def warnNotRunning(): |
109 |
if sys.argv[1] == "stop": |
110 |
print >> sys.stderr, '%s is not running' % APP_NAME |
111 |
else: |
112 |
print >> sys.stderr, 'Warning: %s was not running' % APP_NAME |
11 |
|
113 |
|
12 |
LOGFILE = "%%LOGFILE%%" |
114 |
def cleanup(): |
13 |
PREFIX = "%%PREFIX%%" |
115 |
os.unlink(PID_FILE) |
14 |
APP_NAME = "%%APP_NAME%%" |
|
|
15 |
PID_FILE = "%%PID_FILE%%" |
16 |
|
116 |
|
17 |
if __name__ == '__main__': |
117 |
def stop(): |
18 |
if sys.argv[1] == "start": |
118 |
if os.path.exists(PID_FILE): |
19 |
# Append cocoon output to a log file |
119 |
# Read the process id |
20 |
l = open(LOGFILE, 'a') |
120 |
pid = readProcessId() |
21 |
os.dup2(l.fileno(), sys.stdout.fileno()) |
121 |
else: |
22 |
os.dup2(l.fileno(), sys.stderr.fileno()) |
122 |
warnNotRunning() |
23 |
|
123 |
return |
24 |
# Start cocoon in the background |
|
|
25 |
command = PREFIX + "/sbin/" + APP_NAME + ".sh" |
26 |
pid = os.spawnl(os.P_NOWAIT, command, command, "servlet") |
27 |
|
124 |
|
28 |
# Wait a little |
125 |
if not(isProgramRunning(pid)): |
29 |
time.sleep(0.4) |
126 |
warnNotRunning() |
|
|
127 |
cleanup() |
128 |
return |
30 |
|
129 |
|
31 |
# Send a dummy signal to the process. If it died, an exception is |
130 |
# Terminate program |
32 |
# thrown |
131 |
os.kill(pid, signal.SIGTERM) |
33 |
os.kill(pid, signal.SIGCONT) |
132 |
|
|
|
133 |
while isProgramRunning(pid): |
134 |
time.sleep(.1) |
135 |
|
136 |
cleanup() |
137 |
|
138 |
if __name__ == '__main__': |
139 |
LOG_FILE = "%%LOG_FILE%%" |
140 |
APP_NAME = "%%APP_NAME%%" |
141 |
APP_HOME = "%%APP_HOME%%" |
142 |
PID_FILE = "%%PID_FILE%%" |
143 |
COMMAND = "%%PREFIX%%/sbin/%%APP_NAME%%.sh" |
144 |
ARGS = [COMMAND, "servlet"] |
145 |
|
146 |
if len(sys.argv) != 2: |
147 |
usage() |
148 |
sys.exit(1) |
149 |
|
150 |
if sys.argv[1] == "start": |
151 |
start() |
34 |
|
152 |
|
35 |
# It's alive, so write down the process id |
|
|
36 |
f = open(PID_FILE, 'w') |
37 |
print >> f, pid |
38 |
f.close() |
39 |
elif sys.argv[1] == "stop": |
153 |
elif sys.argv[1] == "stop": |
40 |
# Read the process id |
154 |
stop() |
41 |
f = open(PID_FILE, 'r') |
155 |
|
42 |
pid = int(f.readline()) |
156 |
elif sys.argv[1] == "restart": |
43 |
f.close() |
157 |
stop() |
|
|
158 |
start() |
44 |
|
159 |
|
45 |
# Terminate cocoon |
|
|
46 |
os.kill(pid, signal.SIGTERM) |
47 |
else: |
160 |
else: |
48 |
print "Usage: %s start|stop" % sys.argv[0] |
161 |
usage() |
|
|
162 |
sys.exit(1) |