def move_dbs_primary(self, db_names, dest_shard): log_info("Moving databases %s primary to shard '%s'" % (db_names, dest_shard.id)) mongos = self.get_any_online_mongos() for db_name in db_names: move_cmd = {"movePrimary": db_name, "to": dest_shard.id} log_info( "Executing movePrimary command:\n%s\non mongos '%s'" % (document_pretty_string(move_cmd), mongos.id) ) result = mongos.db_command(move_cmd, "admin") log_info("Move result: %s" % document_pretty_string(result))
def move_dbs_primary(self, db_names, dest_shard): log_info("Moving databases %s primary to shard '%s'" % (db_names, dest_shard.id)) mongos = self.get_any_online_mongos() for db_name in db_names: move_cmd = {"movePrimary": db_name, "to": dest_shard.id} log_info("Executing movePrimary command:\n%s\non mongos '%s'" % (document_pretty_string(move_cmd), mongos.id)) result = mongos.db_command(move_cmd, "admin") log_info("Move result: %s" % document_pretty_string(result))
def _do_remove_shard(self, shard, unsharded_data_dest_id=None): cmd = self.get_validate_remove_shard_command(shard) mongos = self.get_any_online_mongos() log_info("Executing command \n%s\non mongos '%s'" % (document_pretty_string(cmd), mongos.id)) result = mongos.db_command(cmd, "admin") log_info("Command result: \n%s" % result) if "dbsToMove" in result and unsharded_data_dest_id: dest_shard_member = self.get_shard_member_by_shard_id( unsharded_data_dest_id) if not dest_shard_member: raise Exception("No such shard '%s' in shardset '%s' " % (unsharded_data_dest_id, self.id)) dest_shard = dest_shard_member.get_shard() self.move_dbs_primary(result["dbsToMove"], dest_shard) if result.get('state') == "completed": log_info("Shard '%s' removed successfully!" % self.id) return result
def status_command(parsed_options): # we need to print status json to stdout so that its seperate from all # other messages that are printed on stderr. This is so scripts can read # status json and parse it if it needs id = parsed_options.id server = repository.lookup_server(id) if server: # log_info("Status for server '%s':" % id) print "Server Info:" print server status = server.get_status(admin=True) else: cluster = repository.lookup_cluster(id) if cluster: # log_info("Status for cluster '%s':" % id) status = cluster.get_status() else: raise MongoctlException("Cannot find a server or a cluster with" " id '%s'" % id) status_str = document_pretty_string(status) # if mongoctl.is_service() is False: # stdout_log(status_str) return status_str
def dry_run_add_shard(shard, sharded_cluster): log_info("\n************ Dry Run ************\n") shard_member = sharded_cluster.get_shard_member(shard) db_command = sharded_cluster.get_add_shard_command(shard_member) log_info("Executing the following command") log_info(document_pretty_string(db_command))
def dry_run_configure_sharded_cluster(cluster): log_info("\n************ Dry Run ************\n") db_command = cluster.get_shardset_configure_command() log_info("Executing the following command") log_info(document_pretty_string(db_command))
def add_shard(self, shard): log_info("Adding shard '%s' to shardset '%s' " % (shard.id, self.id)) if self.is_shard_configured(shard): log_info("Shard '%s' already added! Nothing to do..." % shard.id) return mongos = self.get_any_online_mongos() shard_member = self.get_shard_member(shard) cmd = self.get_add_shard_command(shard_member) configured_shards = self.list_shards() log_info("Current configured shards: \n%s" % document_pretty_string(configured_shards)) log_info("Executing command \n%s\non mongos '%s'" % (document_pretty_string(cmd), mongos.id)) mongos.db_command(cmd, "admin") log_info("Shard '%s' added successfully!" % self.id)
def remove_shard(self, shard, unsharded_data_dest_id=None, synchronized=False): log_info("Removing shard '%s' from shardset '%s' " % (shard.id, self.id)) configured_shards = self.list_shards() log_info("Current configured shards: \n%s" % document_pretty_string(configured_shards)) completed = False while not completed: result = self._do_remove_shard(shard, unsharded_data_dest_id) completed = synchronized and (result["state"] == "completed" or not self.is_shard_configured(shard)) if not completed: time.sleep(2)
def log_server_activity(self, activity): if is_logging_activity(): log_record = {"op": activity, "ts": datetime.datetime.utcnow(), "serverDoc": self.get_document(), "server": self.id, "serverDisplayName": self.get_description()} log_verbose("Logging server activity \n%s" % document_pretty_string(log_record)) repository.get_activity_collection().insert(log_record)
def timeout_maybe_db_command(self, cmd, dbname): try: result = self.db_command(cmd, dbname) return result except Exception, e: log_exception(e) if "timed out" in str(e): log_warning("Command %s is taking a while to complete. " "This is not necessarily bad. " % document_pretty_string(cmd)) else: raise
def dry_run_configure_cluster(cluster, force_primary_server_id=None): log_info("\n************ Dry Run ************\n") db_command = None force = force_primary_server_id is not None if cluster.is_replicaset_initialized(): log_info("Replica set already initialized. " "Making the replSetReconfig command...") db_command = cluster.get_replicaset_reconfig_db_command(force=force) else: log_info("Replica set has not yet been initialized." " Making the replSetInitiate command...") db_command = cluster.get_replicaset_init_all_db_command() log_info("Executing the following command on the current primary:") log_info(document_pretty_string(db_command))
def db_command(self, cmd, dbname): # try without auth first if server allows it (i.e. version >= 3.0.0) if self.try_on_auth_failures(): need_auth = False else: need_auth = self.command_needs_auth(dbname, cmd) log_verbose("Server '%s': DB Command requested on db %s, need auth ? %s, command: %s" % (self.id, dbname, need_auth, document_pretty_string(cmd))) db = self.get_db(dbname, no_auth=not need_auth) try: return db.command(cmd) except (RuntimeError,Exception), e: if is_auth_error(e) and self.try_on_auth_failures(): db = self.get_db(dbname, no_auth=False) return db.command(cmd) else: raise
def status_command(parsed_options): # we need to print status json to stdout so that its seperate from all # other messages that are printed on stderr. This is so scripts can read # status json and parse it if it needs id = parsed_options.id server = repository.lookup_server(id) if server: log_info("Status for server '%s':" % id) status = server.get_status(admin=True) else: cluster = repository.lookup_cluster(id) if cluster: log_info("Status for cluster '%s':" % id) status = cluster.get_status() else: raise MongoctlException("Cannot find a server or a cluster with" " id '%s'" % id) status_str = document_pretty_string(status) stdout_log(status_str) return status
def mongo_stop_server(server, pid, force=False): try: shutdown_cmd = SON([('shutdown', 1), ('force', force)]) log_info("\nSending the following command to %s:\n%s\n" % (server.get_connection_address(), document_pretty_string(shutdown_cmd))) server.disconnecting_db_command(shutdown_cmd, "admin") log_info("Will now wait for server '%s' to stop." % server.id) # Check that the server has stopped stop_pred = server_stopped_predicate(server, pid) wait_for(stop_pred, timeout=MAX_SHUTDOWN_WAIT) if not stop_pred(): log_error("Shutdown command failed...") return False else: return True except Exception, e: log_exception(e) log_error("Failed to gracefully stop server '%s'. Cause: %s" % (server.id, e)) return False
def _dict_list_to_option_str(dict_list): return json_minify(document_pretty_string(dict_list))
def _dict_list_to_option_str(dict_list): return "'%s'" % minify_json.json_minify(document_pretty_string(dict_list))
def __str__(self): return document_pretty_string(self.__document__)
if self.version_greater_than_3_0(): rs_conf = self.db_command(SON([('replSetGetConfig', 1)]), "admin")["config"] else: rs_conf = self.get_db('local')['system.replset'].find_one() except (Exception,RuntimeError), e: log_debug("Error whille trying to read rs config from " "server '%s': %s" % (self.id, e)) log_exception(e) if type(e) == MongoctlException: raise e else: log_verbose("Cannot get rs config from server '%s'. " "cause: %s" % (self.id, e)) log_verbose("get_rs_config() for server '%s': Returning: %s" % (self.id, document_pretty_string(rs_conf))) return rs_conf ########################################################################### def validate_local_op(self, op): # If the server has been assumed to be local then skip validation if is_assumed_local_server(self.id): log_verbose("Skipping validation of server's '%s' address '%s' to be" " local because --assume-local is on" % (self.id, self.get_host_address())) return log_verbose("Validating server address: " "Ensuring that server '%s' address '%s' is local on this "
"admin")["config"] else: rs_conf = self.get_db('local')['system.replset'].find_one() except (Exception, RuntimeError), e: log_debug("Error whille trying to read rs config from " "server '%s': %s" % (self.id, e)) log_exception(e) if type(e) == MongoctlException: raise e else: log_verbose("Cannot get rs config from server '%s'. " "cause: %s" % (self.id, e)) log_verbose("get_rs_config() for server '%s': Returning: %s" % (self.id, document_pretty_string(rs_conf))) return rs_conf ########################################################################### def validate_local_op(self, op): # If the server has been assumed to be local then skip validation if is_assumed_local_server(self.id): log_verbose( "Skipping validation of server's '%s' address '%s' to be" " local because --assume-local is on" % (self.id, self.get_host_address())) return log_verbose("Validating server address: "