def apply_numactl(command): numactl_exe = get_numactl_exe() if numactl_exe: log_info("Using numactl '%s'" % numactl_exe) return [numactl_exe, "--interleave=all"] + command else: msg = ("You are running on a NUMA machine. It is recommended to run " "your server using numactl but we cannot find a numactl " "executable in your PATH. Proceeding might cause problems that" " will manifest in strange ways, such as massive slow downs for" " periods of time or high system cpu time. Proceed?") if not prompt_confirm(msg): exit(0)
def configure_replicaset(self, add_server=None, force_primary_server=None): # Check if this is an init VS an update if not self.is_replicaset_initialized(): self.initialize_replicaset() return primary_member = self.get_primary_member() # force server validation and setup if force_primary_server: force_primary_member = self.get_member_for(force_primary_server) # validate is cluster member if not force_primary_member: msg = ("Server '%s' is not a member of cluster '%s'" % (force_primary_server.id, self.id)) raise MongoctlException(msg) # validate is administrable if not force_primary_server.is_administrable(): msg = ("Server '%s' is not running or has connection problems." " For more details, Run 'mongoctl status %s'" % (force_primary_server.id, force_primary_server.id)) raise MongoctlException(msg) if not force_primary_member.can_become_primary(): msg = ("Server '%s' cannot become primary. Reconfiguration of" " a replica set must be sent to a node that can become" " primary" % force_primary_server.id) raise MongoctlException(msg) if primary_member: msg = ("Cluster '%s' currently has server '%s' as primary. " "Proceed with force-reconfigure on server '%s'?" % (self.id, primary_member.get_server().id, force_primary_server.id)) if not prompt_confirm(msg): return else: log_info("No primary server found for cluster '%s'" % self.id) elif primary_member is None: raise MongoctlException("Unable to determine primary server" " for replica set cluster '%s'" % self.id) cmd_server = (force_primary_server if force_primary_server else primary_member.get_server()) log_info("Re-configuring replica set cluster '%s'..." % self.id) force = force_primary_server is not None rs_reconfig_cmd = \ self.get_replicaset_reconfig_db_command(add_server=add_server, force=force) desired_config = rs_reconfig_cmd['replSetReconfig'] try: log_info("Executing the following command on server '%s':" "\n%s" % (cmd_server.id, document_pretty_string(rs_reconfig_cmd))) cmd_server.disconnecting_db_command(rs_reconfig_cmd, "admin") log_info("Re-configuration command for replica set cluster '%s'" " issued successfully." % self.id) # Probably need to reconnect. May not be primary any more. realized_config = self.read_rs_config() if realized_config['version'] != desired_config['version']: log_verbose("Really? Config version unchanged? " "Let me double-check that ...") def got_the_memo(): version_diff = (self.read_rs_config()['version'] - desired_config['version']) return ((version_diff == 0) or # force => mongo adds large random # to 'version'. (force and version_diff >= 0)) if not wait_for(got_the_memo, timeout=45, sleep_duration=5): raise Exception("New config version not detected!") # Finally! Resample. realized_config = self.read_rs_config() log_info("New replica set configuration:\n %s" % document_pretty_string(realized_config)) return True except Exception, e: log_exception(e) raise MongoctlException("Unable to reconfigure " "replica set cluster '%s'. Cause: %s " % (self.id,e) )
def configure_replicaset(self, add_server=None, force_primary_server=None): # Check if this is an init VS an update if not self.is_replicaset_initialized(): self.initialize_replicaset() return primary_member = self.get_primary_member() # force server validation and setup if force_primary_server: force_primary_member = self.get_member_for(force_primary_server) # validate is cluster member if not force_primary_member: msg = ("Server '%s' is not a member of cluster '%s'" % (force_primary_server.id, self.id)) raise MongoctlException(msg) # validate is administrable if not force_primary_server.is_administrable(): msg = ("Server '%s' is not running or has connection problems." " For more details, Run 'mongoctl status %s'" % (force_primary_server.id, force_primary_server.id)) raise MongoctlException(msg) if not force_primary_member.can_become_primary(): msg = ("Server '%s' cannot become primary. Reconfiguration of" " a replica set must be sent to a node that can become" " primary" % force_primary_server.id) raise MongoctlException(msg) if primary_member: msg = ("Cluster '%s' currently has server '%s' as primary. " "Proceed with force-reconfigure on server '%s'?" % (self.id, primary_member.get_server().id, force_primary_server.id)) if not prompt_confirm(msg): return else: log_info("No primary server found for cluster '%s'" % self.id) elif primary_member is None: raise MongoctlException("Unable to determine primary server" " for replica set cluster '%s'" % self.id) cmd_server = (force_primary_server if force_primary_server else primary_member.get_server()) log_info("Re-configuring replica set cluster '%s'..." % self.id) force = force_primary_server is not None rs_reconfig_cmd = \ self.get_replicaset_reconfig_db_command(add_server=add_server, force=force) desired_config = rs_reconfig_cmd['replSetReconfig'] try: log_info("Executing the following command on server '%s':" "\n%s" % (cmd_server.id, document_pretty_string(rs_reconfig_cmd))) cmd_server.disconnecting_db_command(rs_reconfig_cmd, "admin") log_info("Re-configuration command for replica set cluster '%s'" " issued successfully." % self.id) # wait until there is a primary log_info("Wait for the new primary to be elected...") def has_primary(): return self.get_primary_member() is not None if not wait_for(has_primary, timeout=60, sleep_duration=1): raise Exception( "No primary elected 60 seconds after reconfiguration!") # Probably need to reconnect. May not be primary any more. desired_cfg_version = desired_config['version'] def got_the_memo(cur_cfg=None): current_config = cur_cfg or self.read_rs_config() # might've gotten None if nobody answers & tells us, so: current_cfg_version = (current_config['version'] if current_config else 0) version_diff = (current_cfg_version - desired_cfg_version) return ((version_diff == 0) or # force => mongo adds large random # to 'version'. (force and version_diff >= 0)) realized_config = self.read_rs_config() if not got_the_memo(realized_config): log_verbose("Really? Config version %s? " "Let me double-check that ..." % "unchanged" if realized_config else "unavailable") if not wait_for(got_the_memo, timeout=45, sleep_duration=5): raise Exception("New config version not detected!") # Finally! Resample. realized_config = self.read_rs_config() log_info("New replica set configuration:\n %s" % document_pretty_string(realized_config)) return True except Exception, e: log_exception(e) raise MongoctlException("Unable to reconfigure " "replica set cluster '%s'. Cause: %s " % (self.id, e))