99def node_name (node_name ):
1010return node_name .split ('.production' ).pop (0 )
1111
12- def strip_isodate (raw_output ):
13- return re .sub (r'ISODate\((.*?)\)' ,r'\1' ,raw_output )
12+ def strip_dates (raw_output ):
13+ stripped_isodates = re .sub (r'ISODate\((.*?)\)' ,r'\1' ,raw_output )
14+ return re .sub (r'Timestamp\((.*?)\)' ,r'"\1"' ,stripped_isodates )
1415
1516def mongo_command (command ):
1617return "mongo --quiet --eval 'printjson(%s)'" % command
1718
18- def run_mongo_command (command ):
19- return json .loads (
20- strip_isodate (
21- run (mongo_command (command ))))
19+ def run_mongo_command (command ,command_warn_only = False ):
20+ if command_warn_only :
21+ with settings (warn_only = True ):
22+ response = run (mongo_command (command ))
23+ else :
24+ response = run (mongo_command (command ))
25+
26+ if response .return_code == 252 :
27+ dict_response = {"return_code" :252 }
28+ else :
29+ dict_response = json .loads (strip_dates (response ))
30+
31+ return dict_response
2232
2333@task (default = True )
2434@roles ('class-mongo' )
@@ -39,20 +49,32 @@ def status():
3949with hide ('output' ):
4050status = run_mongo_command ("rs.status()" )
4151print ("Status at %s" % status ['date' ])
52+ parsed_statuses = []
53+ parsed_statuses .append (['Name' ,'Health' ,'State' ,'Heartbeat' ])
54+
4255for member_status in status ['members' ]:
4356name = node_name (member_status ['name' ])
4457health = "OK" if member_status ['health' ]== 1 else "ERROR"
4558state = member_status ['stateStr' ]
4659heartbeat = member_status .get ('lastHeartbeat' ,'' )
47- print ("%s %s % -10s %s" % (name ,health ,state ,heartbeat ))
60+ parsed_statuses .append ([name ,health ,state ,heartbeat ])
61+
62+ for status in parsed_statuses :
63+ print ("| {0:<22} | {1:<8} | {2:<10} | {3:<22} |" .format (status [0 ],status [1 ],status [2 ],status [3 ]))
4864
4965@task
5066def step_down_primary (seconds = '100' ):
5167"""Step down as primary for a given number of seconds (default: 100)"""
5268with hide ('output' ):
53- result = run_mongo_command ("rs.stepDown(%s)" % seconds )
54- if result ['ok' ]== 1 :
55- print ("Stepped down for %s seconds" % seconds )
56- else :
69+ # Mongo returns an exit code of 252 when the primary steps down, as well as disconnecting
70+ # the current console session. This means that we have to run the command with Fabric's
71+ # warn_only enabled, or Fabric will error.
72+ result = run_mongo_command ("rs.stepDown(%s)" % seconds ,command_warn_only = True )
73+
74+ if 'ok' in result and result ['ok' ]== 0 :
5775print ("Failed to step down: %s\n Try running mongo.find_primary" % result ['errmsg' ])
76+ return 0
5877
78+ if 'return_code' in result and result ['return_code' ]== 252 :
79+ print "Received a 252 exit code from Mongo. There may have been disconnection warnings"
80+ print "during the step down from primary that caused this. Verify the primary with mongo.find_primary."