/
mongomgr.py
executable file
·111 lines (93 loc) · 3.86 KB
/
mongomgr.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
import os
import subprocess
import time
import sys
import socket
class mongod(object):
def __init__(self, mongod="mongod", port=27017, **kwargs):
self.kwargs = kwargs
self.proc = None
self.mongod = mongod
self.port = port
def check_mongo_port(self, port=27017):
sock = socket.socket()
sock.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1)
sock.settimeout(1)
sock.connect(("localhost", int(port)))
sock.close()
def did_mongod_start(self, port=27017, timeout=3):
while timeout > 0:
time.sleep(1)
try:
self.check_mongo_port(int(port))
return True
except Exception,e:
print >> sys.stderr, e
timeout = timeout - 1
print >> sys.stderr, "timeout starting mongod"
return False
def start(self):
if self.proc:
print >> sys.stderr, "probable bug: self.proc already set in start()"
raise Exception("Failed to start mongod")
if not os.path.exists(self.mongod):
raise Exception("no mongod found in this directory.")
path = "/data/db"
mkdir = ["mkdir", "-p", path]
subprocess.Popen(mkdir).communicate()
argv = [self.mongod, "--port", self.port]
print "running " + " ".join(argv)
self.proc = self._start(argv)
if not self.did_mongod_start(self.port):
raise Exception("Failed to start mongod")
def _start(self, argv):
"""In most cases, just call subprocess.Popen(). On windows,
add the started process to a new Job Object, so that any
child processes of this process can be killed with a single
call to TerminateJobObject (see self.stop()).
"""
proc = subprocess.Popen(argv)
if os.sys.platform.startswith( "win" ):
# Create a job object with the "kill on job close"
# flag; this is inherited by child processes (ie
# the mongod started on our behalf by buildlogger)
# and lets us terminate the whole tree of processes
# rather than orphaning the mongod.
import win32job
self.job_object = win32job.CreateJobObject(None, '')
job_info = win32job.QueryInformationJobObject(
self.job_object, win32job.JobObjectExtendedLimitInformation)
job_info['BasicLimitInformation']['LimitFlags'] |= win32job.JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE
win32job.SetInformationJobObject(
self.job_object,
win32job.JobObjectExtendedLimitInformation,
job_info)
win32job.AssignProcessToJobObject(self.job_object, proc._handle)
return proc
def stop(self):
if not self.proc:
print >> sys.stderr, "probable bug: self.proc unset in stop()"
raise Exception("Failed to stop mongod")
return
try:
if os.sys.platform == "win32":
import win32job
win32job.TerminateJobObject(self.job_object, -1)
import time
# Windows doesn't seem to kill the process immediately, so give it some time to die
time.sleep(5)
else:
# This function not available in Python 2.5
self.proc.terminate()
# The above didn't work on Mac OS X
# argv = [self.mongod, "--port", self.port, "--eval", "db.getSiblingDB('admin').shutdownServer()"]
# proc = subprocess.Popen(argv)
except AttributeError:
from os import kill
kill(self.proc.pid, 15)
except Exception, e:
print >> sys.stderr, "error shutting down mongod"
print >> sys.stderr, e
self.proc.wait()
sys.stderr.flush()
sys.stdout.flush()