Skip to content

Commit e561d4d

Browse files
author
Tim Vaillancourt
committed
adding functionality to get true/false for checking if a host is a config server
1 parent 031309e commit e561d4d

File tree

6 files changed

+123
-99
lines changed

6 files changed

+123
-99
lines changed

MongoBackup/Backup.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,8 @@
1313
from Methods import Dumper
1414
from Notify import NotifyNSCA
1515
from Oplog import OplogTailer, OplogResolver
16-
from Replset import Replset, ReplsetSharded
16+
from Replset import Replset
17+
from ReplsetSharded import ReplsetSharded
1718
from Sharding import Sharding
1819
from Upload import UploadS3
1920

MongoBackup/Common/DB.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -44,10 +44,10 @@ def auth_if_required(self):
4444
else:
4545
pass
4646

47-
def admin_command(self, admin_command):
47+
def admin_command(self, admin_command, retry=True):
4848
tries = 0
4949
status = None
50-
while not status and tries < self.retries:
50+
while retry and not status and tries < self.retries:
5151
try:
5252
status = self._conn['admin'].command(admin_command)
5353
if not status:
@@ -57,7 +57,7 @@ def admin_command(self, admin_command):
5757
tries += 1
5858
sleep(1)
5959
if not status:
60-
raise Exception, "Could not get output from command: '%s' after %i retries!" % (admin_command, self.retries), None
60+
raise Exception, "Could not get output from command: '%s' after %i retries!" % (admin_command, retries), None
6161
return status
6262

6363
def server_version(self):

MongoBackup/Methods/Dumper.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ def __init__(self, secondaries, base_dir, binary, dump_gzip=False, user=None, pa
2020
self.config_server = config_server
2121
self.verbose = verbose
2222

23+
self.config_replset = False
2324
self.response_queue = Queue()
2425
self.threads = []
2526
self._summary = {}

MongoBackup/Replset.py

Lines changed: 4 additions & 80 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,6 @@
22

33
from math import ceil
44

5-
from Common import DB
6-
from Sharding import Sharding
7-
85

96
class Replset:
107
def __init__(self, db, user=None, password=None, authdb='admin', max_lag_secs=5):
@@ -31,18 +28,18 @@ def __init__(self, db, user=None, password=None, authdb='admin', max_lag_secs=5)
3128
def close(self):
3229
pass
3330

34-
def get_rs_status(self, force=False):
31+
def get_rs_status(self, force=False, retry=True):
3532
try:
3633
if force or not self.rs_status:
37-
self.rs_status = self.db.admin_command('replSetGetStatus')
34+
self.rs_status = self.db.admin_command('replSetGetStatus', retry)
3835
return self.rs_status
3936
except Exception, e:
4037
raise Exception, "Error getting replica set status! Error: %s" % e, None
4138

42-
def get_rs_config(self):
39+
def get_rs_config(self, retry=True):
4340
try:
4441
if self.db.server_version() >= tuple("3.0.0".split(".")):
45-
output = self.db.admin_command('replSetGetConfig')
42+
output = self.db.admin_command('replSetGetConfig', retry)
4643
return output['config']
4744
else:
4845
return self.connection['local'].system.replset.find_one()
@@ -133,76 +130,3 @@ def primary_optime(self):
133130
rs_primary = self.find_primary(True)
134131
if 'optime' in rs_primary:
135132
return rs_primary['optime']
136-
137-
138-
class ReplsetSharded:
139-
def __init__(self, sharding, db, user=None, password=None, authdb='admin', max_lag_secs=5):
140-
self.sharding = sharding
141-
self.db = db
142-
self.user = user
143-
self.password = password
144-
self.authdb = authdb
145-
self.max_lag_secs = max_lag_secs
146-
147-
self.replsets = {}
148-
self.replset_conns = {}
149-
150-
# Check Sharding class:
151-
if not self.sharding.__class__.__name__ == "Sharding":
152-
raise Exception, "'sharding' field is an instance of %s, not 'Sharding'!" % self.sharding.__class__.__name__, None
153-
154-
# Get a DB connection
155-
try:
156-
if self.db.__class__.__name__ == "DB":
157-
self.connection = self.db.connection()
158-
if not self.connection.is_mongos:
159-
raise Exception, 'MongoDB connection is not to a mongos!', None
160-
else:
161-
raise Exception, "'db' field is an instance of %s, not 'DB'!" % self.db.__class__.__name__, None
162-
except Exception, e:
163-
logging.fatal("Could not get DB connection! Error: %s" % e)
164-
raise e
165-
166-
def get_replset_connection(self, host, port, force=False):
167-
conn_name = "%s-%i" % (host, port)
168-
if force or not conn_name in self.replset_conns:
169-
try:
170-
self.replset_conns[conn_name] = DB(host, port, self.user, self.password, self.authdb)
171-
except Exception, e:
172-
logging.fatal("Could not get DB connection to %s:%i! Error: %s" % (host, port, e))
173-
raise e
174-
return self.replset_conns[conn_name]
175-
176-
def get_replsets(self, force=False):
177-
for shard in self.sharding.shards():
178-
shard_name, members = shard['host'].split('/')
179-
host, port = members.split(',')[0].split(":")
180-
port = int(port)
181-
if force or not shard_name in self.replsets:
182-
try:
183-
rs_db = self.get_replset_connection(host, port)
184-
self.replsets[shard_name] = Replset(rs_db, self.user, self.password, self.authdb, self.max_lag_secs)
185-
except Exception, e:
186-
logging.fatal("Could not get Replset class object for replset %s! Error: %s" % (rs_name, e))
187-
raise e
188-
return self.replsets
189-
190-
def find_secondaries(self):
191-
shard_secondaries = {}
192-
for rs_name in self.get_replsets():
193-
replset = self.replsets[rs_name]
194-
shard_secondaries[rs_name] = replset.find_secondary()
195-
return shard_secondaries
196-
197-
def primary_optimes(self):
198-
primary_optimes = {}
199-
for rs_name in self.get_replsets():
200-
replset = self.replsets[rs_name]
201-
primary_optimes[rs_name] = replset.primary_optime()
202-
return primary_optimes
203-
204-
def close(self):
205-
for rs_name in self.replsets:
206-
self.replsets[rs_name].close()
207-
for conn_name in self.replset_conns:
208-
self.replset_conns[conn_name].close()

MongoBackup/ReplsetSharded.py

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
import logging
2+
3+
from Common import DB
4+
from Sharding import Sharding
5+
6+
7+
class ReplsetSharded:
8+
def __init__(self, sharding, db, user=None, password=None, authdb='admin', max_lag_secs=5):
9+
self.sharding = sharding
10+
self.db = db
11+
self.user = user
12+
self.password = password
13+
self.authdb = authdb
14+
self.max_lag_secs = max_lag_secs
15+
16+
self.replsets = {}
17+
self.replset_conns = {}
18+
19+
# Check Sharding class:
20+
if not self.sharding.__class__.__name__ == "Sharding":
21+
raise Exception, "'sharding' field is an instance of %s, not 'Sharding'!" % self.sharding.__class__.__name__, None
22+
23+
# Get a DB connection
24+
try:
25+
if self.db.__class__.__name__ == "DB":
26+
self.connection = self.db.connection()
27+
if not self.connection.is_mongos:
28+
raise Exception, 'MongoDB connection is not to a mongos!', None
29+
else:
30+
raise Exception, "'db' field is an instance of %s, not 'DB'!" % self.db.__class__.__name__, None
31+
except Exception, e:
32+
logging.fatal("Could not get DB connection! Error: %s" % e)
33+
raise e
34+
35+
def get_replset_connection(self, host, port, force=False):
36+
conn_name = "%s-%i" % (host, port)
37+
if force or not conn_name in self.replset_conns:
38+
try:
39+
self.replset_conns[conn_name] = DB(host, port, self.user, self.password, self.authdb)
40+
except Exception, e:
41+
logging.fatal("Could not get DB connection to %s:%i! Error: %s" % (host, port, e))
42+
raise e
43+
return self.replset_conns[conn_name]
44+
45+
def get_replsets(self, force=False):
46+
for shard in self.sharding.shards():
47+
shard_name, members = shard['host'].split('/')
48+
host, port = members.split(',')[0].split(":")
49+
port = int(port)
50+
if force or not shard_name in self.replsets:
51+
try:
52+
rs_db = self.get_replset_connection(host, port)
53+
self.replsets[shard_name] = Replset(rs_db, self.user, self.password, self.authdb, self.max_lag_secs)
54+
except Exception, e:
55+
logging.fatal("Could not get Replset class object for replset %s! Error: %s" % (rs_name, e))
56+
raise e
57+
return self.replsets
58+
59+
def find_secondaries(self):
60+
shard_secondaries = {}
61+
for rs_name in self.get_replsets():
62+
replset = self.replsets[rs_name]
63+
shard_secondaries[rs_name] = replset.find_secondary()
64+
return shard_secondaries
65+
66+
def primary_optimes(self):
67+
primary_optimes = {}
68+
for rs_name in self.get_replsets():
69+
replset = self.replsets[rs_name]
70+
primary_optimes[rs_name] = replset.primary_optime()
71+
return primary_optimes
72+
73+
def close(self):
74+
for rs_name in self.replsets:
75+
self.replsets[rs_name].close()
76+
for conn_name in self.replset_conns:
77+
self.replset_conns[conn_name].close()

MongoBackup/Sharding.py

Lines changed: 36 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,9 @@
22

33
from time import sleep
44

5+
from Common import DB
6+
from Replset import Replset
7+
58

69
class Sharding:
710
def __init__(self, db, user=None, password=None, authdb='admin', balancer_wait_secs=300, balancer_sleep=5):
@@ -12,6 +15,7 @@ def __init__(self, db, user=None, password=None, authdb='admin', balancer_wait_s
1215
self.balancer_wait_secs = balancer_wait_secs
1316
self.balancer_sleep = balancer_sleep
1417

18+
self.config_server = None
1519
self._balancer_state_start = None
1620

1721
# Get a DB connection
@@ -94,20 +98,37 @@ def stop_balancer(self):
9498
logging.fatal("Could not stop balancer: %s:%i!" % (self.host, self.port))
9599
raise Exception, "Could not stop balancer: %s:%i" % (self.host, self.port), None
96100

97-
def get_configserver(self):
98-
cmdlineopts = self.db.admin_command("getCmdLineOpts")
99-
config_string = None
100-
if cmdlineopts.get('parsed').get('configdb'):
101-
config_string = cmdlineopts.get('parsed').get('configdb')
102-
elif cmdlineopts.get('parsed').get('sharding').get('configDB'):
103-
config_string = cmdlineopts.get('parsed').get('sharding').get('configDB')
104-
if config_string:
105-
# noinspection PyBroadException
101+
def get_configserver(self, force=False):
102+
if force or not self.config_server:
103+
cmdlineopts = self.db.admin_command("getCmdLineOpts")
104+
config_string = None
105+
if cmdlineopts.get('parsed').get('configdb'):
106+
config_string = cmdlineopts.get('parsed').get('configdb')
107+
elif cmdlineopts.get('parsed').get('sharding').get('configDB'):
108+
config_string = cmdlineopts.get('parsed').get('sharding').get('configDB')
109+
if config_string:
110+
# noinspection PyBroadException
111+
try:
112+
config_list = config_string.split(",")
113+
except Exception:
114+
config_list = [config_string]
115+
self.config_server = config_list[0]
116+
else:
117+
logging.fatal("Unable to locate config servers for %s:%i!" % (self.host, self.port))
118+
raise Exception, "Unable to locate config servers for %s:%i!" % (self.host, self.port), None
119+
return self.config_server
120+
121+
def is_config_replset(self):
122+
try:
123+
config_server = self.get_configserver()
124+
config_host, config_port = config_server.split(":")
125+
db = DB(config_host, config_port, self.user, self.password, self.authdb)
126+
rs = Replset(db, self.user, self.password, self.authdb)
106127
try:
107-
config_list = config_string.split(",")
128+
rs.get_rs_status(True, False)
129+
return
108130
except Exception:
109-
config_list = [config_string]
110-
return config_list[0]
111-
else:
112-
logging.fatal("Unable to locate config servers for %s:%i!" % (self.host, self.port))
113-
raise Exception, "Unable to locate config servers for %s:%i!" % (self.host, self.port), None
131+
return False
132+
except Exception, e:
133+
raise e
134+

0 commit comments

Comments
 (0)