diff options
author | Hugh Han <hughhan1@gmail.com> | 2017-07-26 13:28:57 -0400 |
---|---|---|
committer | Hugh Han <hughhan1@gmail.com> | 2017-08-15 12:11:40 -0400 |
commit | f14037e54577ce79cec00e06735f914c01b3f80e (patch) | |
tree | 1ed1025a3a4d5dd7594716fd46c711ab638d091a /src/mongo/db | |
parent | 578e5c4f168db90ebb7ec661831363575d801f5b (diff) | |
download | mongo-f14037e54577ce79cec00e06735f914c01b3f80e.tar.gz |
SERVER-30324 Move cluster_remove_shard_cmd to mongod
Diffstat (limited to 'src/mongo/db')
-rw-r--r-- | src/mongo/db/s/config/configsvr_remove_shard_command.cpp | 106 |
1 files changed, 105 insertions, 1 deletions
diff --git a/src/mongo/db/s/config/configsvr_remove_shard_command.cpp b/src/mongo/db/s/config/configsvr_remove_shard_command.cpp index 5ac9d2dc224..d24516b0a9c 100644 --- a/src/mongo/db/s/config/configsvr_remove_shard_command.cpp +++ b/src/mongo/db/s/config/configsvr_remove_shard_command.cpp @@ -42,6 +42,7 @@ #include "mongo/s/catalog/sharding_catalog_manager.h" #include "mongo/s/catalog/type_database.h" #include "mongo/s/catalog_cache.h" +#include "mongo/s/client/shard_registry.h" #include "mongo/s/grid.h" #include "mongo/util/log.h" #include "mongo/util/scopeguard.h" @@ -65,7 +66,7 @@ public: } virtual bool supportsWriteConcern(const BSONObj& cmd) const override { - return false; + return true; } virtual void help(std::stringstream& help) const override { @@ -73,11 +74,114 @@ public: "directly. Removes a shard from the cluster."; } + Status checkAuthForCommand(Client* client, + const std::string& dbname, + const BSONObj& cmdObj) override { + if (!AuthorizationSession::get(client)->isAuthorizedForActionsOnResource( + ResourcePattern::forClusterResource(), ActionType::internal)) { + return Status(ErrorCodes::Unauthorized, "Unauthorized"); + } + return Status::OK(); + } + bool run(OperationContext* opCtx, const std::string& dbname, const BSONObj& cmdObj, BSONObjBuilder& result) { + uassert(ErrorCodes::IllegalOperation, + "_configsvrRemoveShard can only be run on config servers", + serverGlobalParams.clusterRole == ClusterRole::ConfigServer); + + uassert(ErrorCodes::TypeMismatch, + str::stream() << "Field '" << cmdObj.firstElement().fieldName() + << "' must be of type string", + cmdObj.firstElement().type() == BSONType::String); + const std::string target = cmdObj.firstElement().str(); + + const auto shardStatus = grid.shardRegistry()->getShard(opCtx, ShardId(target)); + if (!shardStatus.isOK()) { + std::string msg(str::stream() << "Could not drop shard '" << target + << "' because it does not exist"); + log() << msg; + return appendCommandStatus(result, Status(ErrorCodes::ShardNotFound, msg)); + } + const auto shard = shardStatus.getValue(); + + const auto shardingCatalogManager = ShardingCatalogManager::get(opCtx); + + StatusWith<ShardDrainingStatus> removeShardResult = + shardingCatalogManager->removeShard(opCtx, shard->getId()); + if (!removeShardResult.isOK()) { + return appendCommandStatus(result, removeShardResult.getStatus()); + } + + std::vector<std::string> databases; + Status status = + shardingCatalogManager->getDatabasesForShard(opCtx, shard->getId(), &databases); + if (!status.isOK()) { + return appendCommandStatus(result, status); + } + + // Get BSONObj containing: + // 1) note about moving or dropping databases in a shard + // 2) list of databases (excluding 'local' database) that need to be moved + BSONObj dbInfo; + { + BSONObjBuilder dbInfoBuilder; + dbInfoBuilder.append("note", "you need to drop or movePrimary these databases"); + BSONArrayBuilder dbs(dbInfoBuilder.subarrayStart("dbsToMove")); + for (std::vector<std::string>::const_iterator it = databases.begin(); + it != databases.end(); + it++) { + if (*it != "local") { + dbs.append(*it); + } + } + dbs.doneFast(); + dbInfo = dbInfoBuilder.obj(); + } + + // TODO: Standardize/Seperate how we append to the result object + switch (removeShardResult.getValue()) { + case ShardDrainingStatus::STARTED: + result.append("msg", "draining started successfully"); + result.append("state", "started"); + result.append("shard", shard->getId().toString()); + result.appendElements(dbInfo); + break; + case ShardDrainingStatus::ONGOING: { + std::vector<ChunkType> chunks; + Status status = Grid::get(opCtx)->catalogClient()->getChunks( + opCtx, + BSON(ChunkType::shard(shard->getId().toString())), + BSONObj(), + boost::none, // return all + &chunks, + nullptr, + repl::ReadConcernLevel::kMajorityReadConcern); + if (!status.isOK()) { + return appendCommandStatus(result, status); + } + + result.append("msg", "draining ongoing"); + result.append("state", "ongoing"); + { + BSONObjBuilder inner; + inner.append("chunks", static_cast<long long>(chunks.size())); + inner.append("dbs", static_cast<long long>(databases.size())); + BSONObj b = inner.obj(); + result.append("remaining", b); + } + result.appendElements(dbInfo); + break; + } + case ShardDrainingStatus::COMPLETED: + result.append("msg", "removeshard completed successfully"); + result.append("state", "completed"); + result.append("shard", shard->getId().toString()); + } + return true; } |