diff options
author | A. Jesse Jiryu Davis <jesse@mongodb.com> | 2021-05-12 14:03:05 -0400 |
---|---|---|
committer | Evergreen Agent <no-reply@evergreen.mongodb.com> | 2021-05-12 18:57:08 +0000 |
commit | 270908b05b9f98709a85faffe624aaf175707ecc (patch) | |
tree | 0dfd0bac16fd2dd09c0348a5a820f5bfb7b7f459 /src/mongo | |
parent | 265ba00b96161463bc2a6d8640098d3ac4e4b70a (diff) | |
download | mongo-270908b05b9f98709a85faffe624aaf175707ecc.tar.gz |
SERVER-55596 Remove isMaster from API Version 1
Diffstat (limited to 'src/mongo')
-rw-r--r-- | src/mongo/client/dbclient_base.cpp | 5 | ||||
-rw-r--r-- | src/mongo/client/dbclient_connection.cpp | 2 | ||||
-rw-r--r-- | src/mongo/client/scanning_replica_set_monitor.cpp | 2 | ||||
-rw-r--r-- | src/mongo/db/repl/replication_info.cpp | 6 | ||||
-rw-r--r-- | src/mongo/s/commands/cluster_hello_cmd.cpp | 6 | ||||
-rw-r--r-- | src/mongo/shell/bridge.js | 3 | ||||
-rw-r--r-- | src/mongo/shell/db.js | 40 | ||||
-rw-r--r-- | src/mongo/shell/replsettest.js | 31 | ||||
-rw-r--r-- | src/mongo/shell/session.js | 4 | ||||
-rw-r--r-- | src/mongo/shell/shardingtest.js | 2 | ||||
-rw-r--r-- | src/mongo/shell/utils.js | 55 | ||||
-rw-r--r-- | src/mongo/shell/utils_sh.js | 2 |
12 files changed, 93 insertions, 65 deletions
diff --git a/src/mongo/client/dbclient_base.cpp b/src/mongo/client/dbclient_base.cpp index b6944cc64c4..8af0924768d 100644 --- a/src/mongo/client/dbclient_base.cpp +++ b/src/mongo/client/dbclient_base.cpp @@ -580,7 +580,7 @@ void DBClientBase::logout(const string& dbname, BSONObj& info) { bool DBClientBase::isPrimary(bool& isPrimary, BSONObj* info) { BSONObjBuilder bob; - bob.append("ismaster", 1); + bob.append(_apiParameters.getVersion() ? "hello" : "ismaster", 1); if (auto wireSpec = WireSpec::instance().get(); wireSpec->isInternalClient) { WireSpec::appendInternalClientWireVersion(wireSpec->outgoing, &bob); } @@ -589,7 +589,8 @@ bool DBClientBase::isPrimary(bool& isPrimary, BSONObj* info) { if (info == nullptr) info = &o; bool ok = runCommand("admin", bob.obj(), *info); - isPrimary = info->getField("ismaster").trueValue(); + isPrimary = + info->getField(_apiParameters.getVersion() ? "isWritablePrimary" : "ismaster").trueValue(); return ok; } diff --git a/src/mongo/client/dbclient_connection.cpp b/src/mongo/client/dbclient_connection.cpp index a42865be5be..f40b32e76a6 100644 --- a/src/mongo/client/dbclient_connection.cpp +++ b/src/mongo/client/dbclient_connection.cpp @@ -186,7 +186,7 @@ executor::RemoteCommandResponse initWireVersion( ScopedForceOpQuery forceOpQuery{conn}; BSONObjBuilder bob; - bob.append("isMaster", 1); + bob.append(conn->getApiParameters().getVersion() ? "hello" : "isMaster", 1); if (uri.isHelloOk()) { // Attach "helloOk: true" to the initial handshake to indicate that the client supports the diff --git a/src/mongo/client/scanning_replica_set_monitor.cpp b/src/mongo/client/scanning_replica_set_monitor.cpp index daef814d55c..afe643a8d14 100644 --- a/src/mongo/client/scanning_replica_set_monitor.cpp +++ b/src/mongo/client/scanning_replica_set_monitor.cpp @@ -988,7 +988,7 @@ void IsMasterReply::parse(const BSONObj& obj) { maxWireVersion = raw["maxWireVersion"].numberInt(); // hidden nodes can't be master, even if they claim to be. - isMaster = !hidden && raw["ismaster"].trueValue(); + isMaster = !hidden && (raw["isWritablePrimary"].trueValue() || raw["ismaster"].trueValue()); if (isMaster && raw.hasField("electionId")) { electionId = raw["electionId"].OID(); diff --git a/src/mongo/db/repl/replication_info.cpp b/src/mongo/db/repl/replication_info.cpp index 1bae39415cf..77ebda6ca44 100644 --- a/src/mongo/db/repl/replication_info.cpp +++ b/src/mongo/db/repl/replication_info.cpp @@ -247,7 +247,7 @@ class CmdHello : public BasicCommandWithReplyBuilderInterface { public: CmdHello() : CmdHello(kHelloString, {}) {} - const std::set<std::string>& apiVersions() const final { + const std::set<std::string>& apiVersions() const override { return kApiVersions1; } @@ -501,6 +501,10 @@ class CmdIsMaster : public CmdHello { public: CmdIsMaster() : CmdHello(kCamelCaseIsMasterString, {kLowerCaseIsMasterString}) {} + const std::set<std::string>& apiVersions() const final { + return kNoApiVersions; + } + std::string help() const final { return "Check if this server is primary for a replica set\n" "{ isMaster : 1 }"; diff --git a/src/mongo/s/commands/cluster_hello_cmd.cpp b/src/mongo/s/commands/cluster_hello_cmd.cpp index c2ad55c4ba7..f6cc0344504 100644 --- a/src/mongo/s/commands/cluster_hello_cmd.cpp +++ b/src/mongo/s/commands/cluster_hello_cmd.cpp @@ -70,7 +70,7 @@ class CmdHello : public BasicCommandWithReplyBuilderInterface { public: CmdHello() : CmdHello(kHelloString, {}) {} - const std::set<std::string>& apiVersions() const final { + const std::set<std::string>& apiVersions() const override { return kApiVersions1; } @@ -263,6 +263,10 @@ class CmdIsMaster : public CmdHello { public: CmdIsMaster() : CmdHello(kCamelCaseIsMasterString, {kLowerCaseIsMasterString}) {} + const std::set<std::string>& apiVersions() const final { + return kNoApiVersions; + } + protected: bool useLegacyResponseFields() const final { return true; diff --git a/src/mongo/shell/bridge.js b/src/mongo/shell/bridge.js index 73306c6a99b..588989a86d5 100644 --- a/src/mongo/shell/bridge.js +++ b/src/mongo/shell/bridge.js @@ -189,8 +189,7 @@ function MongoBridge(options) { }; // All *From functions require that test commands be enabled on the mongod - // instance (which populates the hostInfo field). Verify that they're - // enabled by sending isMaster + // instance (which populates the hostInfo field). function checkTestCommandsEnabled(fn_name) { return function(bridge) { assert(bridge._testCommandsEnabledAtInit, diff --git a/src/mongo/shell/db.js b/src/mongo/shell/db.js index 53a18150595..1a41c93969c 100644 --- a/src/mongo/shell/db.js +++ b/src/mongo/shell/db.js @@ -197,6 +197,14 @@ DB.prototype.adminCommand = function(obj, extra) { DB.prototype._adminCommand = DB.prototype.adminCommand; // alias old name +DB.prototype._helloOrLegacyHello = function(args) { + let cmd = this.getMongo().getApiParameters().version ? {hello: 1} : {isMaster: 1}; + if (args) { + Object.assign(cmd, args); + } + return this.runCommand(cmd); +}; + DB.prototype._runCommandWithoutApiStrict = function(command) { let commandWithoutApiStrict = Object.assign({}, command); if (this.getMongo().getApiParameters().strict) { @@ -1003,11 +1011,19 @@ DB.prototype.getReplicationInfo = function() { DB.prototype.printReplicationInfo = function() { var result = this.getReplicationInfo(); if (result.errmsg) { - var isMaster = this.isMaster(); - if (isMaster.arbiterOnly) { + let reply, isPrimary; + if (this.getMongo().getApiParameters().apiVersion) { + reply = this.hello(); + isPrimary = reply.isWritablePrimary; + } else { + reply = this.isMaster(); + isPrimary = reply.ismaster; + } + + if (reply.arbiterOnly) { print("cannot provide replication status from an arbiter."); return; - } else if (!isMaster.ismaster) { + } else if (!isPrimary) { print("this is a secondary, printing secondary replication info."); this.printSecondaryReplicationInfo(); return; @@ -1475,7 +1491,7 @@ DB.prototype._defaultAuthenticationMechanism = null; DB.prototype._getDefaultAuthenticationMechanism = function(username, database) { if (username !== undefined) { const userid = database + "." + username; - const result = this.runCommand({isMaster: 1, saslSupportedMechs: userid}); + const result = this._helloOrLegacyHello({saslSupportedMechs: userid}); if (result.ok && (result.saslSupportedMechs !== undefined)) { const mechs = result.saslSupportedMechs; if (!Array.isArray(mechs)) { @@ -1544,8 +1560,8 @@ DB.prototype._authOrThrow = function() { params.db = this.getName(); var good = this.getMongo().auth(params); if (good) { - // auth enabled, and should try to use isMaster and replSetGetStatus to build prompt - this.getMongo().authStatus = {authRequired: true, isMaster: true, replSetGetStatus: true}; + // auth enabled, and should try to use hello and replSetGetStatus to build prompt + this.getMongo().authStatus = {authRequired: true, hello: true, replSetGetStatus: true}; } return good; @@ -1798,8 +1814,16 @@ DB.prototype.getFreeMonitoringStatus = function() { DB.prototype.enableFreeMonitoring = function() { 'use strict'; - const isMaster = this.isMaster(); - if (isMaster.ismaster == false) { + let reply, isPrimary; + if (this.getMongo().getApiParameters().apiVersion) { + reply = this.hello(); + isPrimary = reply.isWritablePrimary; + } else { + reply = this.isMaster(); + isPrimary = reply.ismaster; + } + + if (!isPrimary) { print("ERROR: db.enableFreeMonitoring() may only be run on a primary"); return; } diff --git a/src/mongo/shell/replsettest.js b/src/mongo/shell/replsettest.js index d55d7c845fd..963a5f587ee 100644 --- a/src/mongo/shell/replsettest.js +++ b/src/mongo/shell/replsettest.js @@ -126,8 +126,8 @@ var ReplSetTest = function(opts) { } /** - * Invokes the 'hello' command via it's alias 'ismaster' on each individual node and returns the - * current primary, or false if none is found. Populates the following cached values: + * Invokes the 'hello' command on each individual node and returns the current primary, or false + * if none is found. Populates the following cached values: * '_primary': the current primary * '_secondaries': all nodes other than '_primary' (note this includes arbiters) * '_liveNodes': all currently reachable nodes @@ -143,7 +143,7 @@ var ReplSetTest = function(opts) { self.nodes.forEach(function(node) { try { node.setSecondaryOk(); - var n = node.getDB('admin').runCommand({ismaster: 1}); + var n = node.getDB('admin')._helloOrLegacyHello(); self._liveNodes.push(node); // We verify that the node has a valid config by checking if n.me exists. Then, we // check to see if the node is in primary state. @@ -152,13 +152,14 @@ var ReplSetTest = function(opts) { twoPrimaries = true; } else { self._primary = node; - canAcceptWrites = n.ismaster; + canAcceptWrites = n.isWritablePrimary || n.ismaster; } } else { self._secondaries.push(node); } } catch (err) { - print("ReplSetTest Could not call ismaster on node " + node + ": " + tojson(err)); + print("ReplSetTest Could not call hello/ismaster on node " + node + ": " + + tojson(err)); self._secondaries.push(node); } }); @@ -733,10 +734,7 @@ var ReplSetTest = function(opts) { var ready = true; for (var i = 0; i < len; i++) { - // Our testing framework must be backwards compatible - // for multiversion testing, so we are using the 'hello' - // command's alias 'ismaster'. - var hello = secondariesToCheck[i].adminCommand({ismaster: 1}); + var hello = secondariesToCheck[i].getDB('admin')._helloOrLegacyHello(); var arbiter = (hello.arbiterOnly === undefined ? false : hello.arbiterOnly); ready = ready && (hello.secondary || arbiter); } @@ -950,10 +948,7 @@ var ReplSetTest = function(opts) { var primary; for (var i = 0; i < nodes.length; i++) { - // Our testing framework must be backwards compatible - // for multiversion testing, so we are using the 'hello' - // command's alias 'ismaster'. - var hello = assert.commandWorked(nodes[i].adminCommand({ismaster: 1})); + var hello = assert.commandWorked(nodes[i].getDB('admin')._helloOrLegacyHello()); var nodesPrimary = hello.primary; // Node doesn't see a primary. if (!nodesPrimary) { @@ -1086,7 +1081,7 @@ var ReplSetTest = function(opts) { }; function isNodeArbiter(node) { - return node.getDB('admin').isMaster('admin').arbiterOnly; + return node.getDB('admin')._helloOrLegacyHello().arbiterOnly; } this.getArbiters = function() { @@ -1099,7 +1094,7 @@ var ReplSetTest = function(opts) { assert.retryNoExcept(() => { isArbiter = isNodeArbiter(node); return true; - }, `Could not call 'isMaster' on ${node}.`, 3, 1000); + }, `Could not call hello/isMaster on ${node}.`, 3, 1000); if (isArbiter) { arbiters.push(node); @@ -1804,10 +1799,10 @@ var ReplSetTest = function(opts) { timeout = timeout || this.kDefaultTimeoutMS; assert.soonNoExcept(function() { - var primaryVersion = self.getPrimary().adminCommand({ismaster: 1}).setVersion; + var primaryVersion = self.getPrimary().getDB('admin')._helloOrLegacyHello().setVersion; for (var i = 0; i < self.nodes.length; i++) { - var version = self.nodes[i].adminCommand({ismaster: 1}).setVersion; + var version = self.nodes[i].getDB('admin')._helloOrLegacyHello().setVersion; assert.eq(version, primaryVersion, "waiting for secondary node " + self.nodes[i].host + @@ -2248,7 +2243,7 @@ var ReplSetTest = function(opts) { const sessions = [ self._primary, ...secondaries.filter(conn => { - return !conn.adminCommand({isMaster: 1}).arbiterOnly; + return !conn.getDB('admin')._helloOrLegacyHello().arbiterOnly; }) ].map(conn => conn.getDB('test').getSession()); diff --git a/src/mongo/shell/session.js b/src/mongo/shell/session.js index d73f1d2d467..d7a3ad831f7 100644 --- a/src/mongo/shell/session.js +++ b/src/mongo/shell/session.js @@ -374,9 +374,9 @@ var { throw e; } - // We run an "isMaster" command explicitly to force the underlying + // We run a "hello" command explicitly to force the underlying // DBClient to reconnect to the server. - const res = client.adminCommand({isMaster: 1}); + const res = client.getDB('admin')._helloOrLegacyHello(); if (res.ok !== 1) { throw e; } diff --git a/src/mongo/shell/shardingtest.js b/src/mongo/shell/shardingtest.js index 2e39ec890e0..064d67bf23b 100644 --- a/src/mongo/shell/shardingtest.js +++ b/src/mongo/shell/shardingtest.js @@ -775,7 +775,7 @@ var ShardingTest = function(params) { diff = (new Date()).getTime() - start.getTime(); var currNode = nodes[j]; // Skip arbiters - if (currNode.adminCommand({isMaster: 1}).arbiterOnly) { + if (currNode.getDB('admin')._helloOrLegacyHello().arbiterOnly) { continue; } diff --git a/src/mongo/shell/utils.js b/src/mongo/shell/utils.js index 8a1b5721a04..c115bb58313 100644 --- a/src/mongo/shell/utils.js +++ b/src/mongo/shell/utils.js @@ -441,7 +441,7 @@ jsTest.authenticateNodes = function(nodes) { for (var i = 0; i < nodes.length; i++) { // Don't try to authenticate to arbiters try { - res = nodes[i].getDB("admin").runCommand({replSetGetStatus: 1}); + res = nodes[i].getDB("admin")._runCommandWithoutApiStrict({replSetGetStatus: 1}); } catch (e) { // ReplicaSet tests which don't use auth are allowed to have nodes crash during // startup. To allow tests which use to behavior to work with auth, @@ -461,7 +461,7 @@ jsTest.authenticateNodes = function(nodes) { }; jsTest.isMongos = function(conn) { - return conn.getDB('admin').isMaster().msg == 'isdbgrid'; + return conn.getDB('admin')._helloOrLegacyHello().msg == 'isdbgrid'; }; defaultPrompt = function() { @@ -470,7 +470,7 @@ defaultPrompt = function() { if (typeof prefix == 'undefined') { prefix = ""; - var buildInfo = db.runCommand({buildInfo: 1}); + var buildInfo = db._runCommandWithoutApiStrict({buildInfo: 1}); try { if (buildInfo.modules.indexOf("enterprise") > -1) { prefix += "MongoDB Enterprise "; @@ -478,9 +478,9 @@ defaultPrompt = function() { } catch (e) { // Don't do anything here. Just throw the error away. } - var isMasterRes = db.runCommand({isMaster: 1, forShell: 1}); + var hello = db._helloOrLegacyHello({forShell: 1}); try { - if (isMasterRes.hasOwnProperty("automationServiceDescriptor")) { + if (hello.hasOwnProperty("automationServiceDescriptor")) { prefix += "[automated] "; } } catch (e) { @@ -495,12 +495,12 @@ defaultPrompt = function() { try { var prompt = replSetMemberStatePrompt(); // set our status that it was good - db.getMongo().authStatus = {replSetGetStatus: true, isMaster: true}; + db.getMongo().authStatus = {replSetGetStatus: true, hello: true}; return prefix + prompt; } catch (e) { // don't have permission to run that, or requires auth // print(e); - status = {authRequired: true, replSetGetStatus: false, isMaster: true}; + status = {authRequired: true, replSetGetStatus: false, hello: true}; } } // auth detected @@ -521,22 +521,22 @@ defaultPrompt = function() { } } - // try to use isMaster? - if (status.isMaster) { + // try to use hello? + if (status.hello) { try { - var prompt = isMasterStatePrompt(isMasterRes); - status.isMaster = true; + var prompt = helloStatePrompt(hello); + status.hello = true; db.getMongo().authStatus = status; return prefix + prompt; } catch (e) { status.authRequired = true; - status.isMaster = false; + status.hello = false; } } } catch (ex) { printjson(ex); // reset status and let it figure it out next time. - status = {isMaster: true}; + status = {hello: true}; } db.getMongo().authStatus = status; @@ -545,7 +545,8 @@ defaultPrompt = function() { replSetMemberStatePrompt = function() { var state = ''; - var stateInfo = db.getSiblingDB('admin').runCommand({replSetGetStatus: 1, forShell: 1}); + var stateInfo = + db.getSiblingDB('admin')._runCommandWithoutApiStrict({replSetGetStatus: 1, forShell: 1}); if (stateInfo.ok) { // Report the self member's stateStr if it's present. stateInfo.members.forEach(function(member) { @@ -569,31 +570,31 @@ replSetMemberStatePrompt = function() { return state + '> '; }; -isMasterStatePrompt = function(isMasterResponse) { +helloStatePrompt = function(helloReply) { var state = ''; - var isMaster = isMasterResponse || db.runCommand({isMaster: 1, forShell: 1}); - if (isMaster.ok) { + var hello = helloReply || db._helloOrLegacyHello({forShell: 1}); + if (hello.ok) { var role = ""; - if (isMaster.msg == "isdbgrid") { + if (hello.msg == "isdbgrid") { role = "mongos"; } - if (isMaster.setName) { - if (isMaster.ismaster) + if (hello.setName) { + if (hello.isWritablePrimary || hello.ismaster) role = "PRIMARY"; - else if (isMaster.secondary) + else if (hello.secondary) role = "SECONDARY"; - else if (isMaster.arbiterOnly) + else if (hello.arbiterOnly) role = "ARBITER"; else { role = "OTHER"; } - state = isMaster.setName + ':'; + state = hello.setName + ':'; } state = state + role; } else { - throw _getErrorWithCode(isMaster, "Failed: " + tojson(isMaster)); + throw _getErrorWithCode(hello, "Failed: " + tojson(hello)); } return state + '> '; }; @@ -1091,7 +1092,7 @@ shellHelper.show = function(what) { } if (dbDeclared) { - var res = db.runCommand({isMaster: 1, forShell: 1}); + var res = db._helloOrLegacyHello({forShell: 1}); if (!res.ok) { print("Note: Cannot determine if automation is active"); return ""; @@ -1165,7 +1166,7 @@ shellHelper.show = function(what) { // A MongoDB emulation service offered by a company // responsible for a certain disk operating system. try { - const buildInfo = db.runCommand({buildInfo: 1}); + const buildInfo = db._runCommandWithoutApiStrict({buildInfo: 1}); if (buildInfo.hasOwnProperty('_t')) { matchesKnownImposterSignature = true; } @@ -1221,7 +1222,7 @@ __promptWrapper__ = function(promptFunction) { try { db = originalDB.getMongo().getDB(originalDB.getName()); // Setting db._session to be a _DummyDriverSession instance makes it so that - // a logical session id isn't included in the isMaster and replSetGetStatus + // a logical session id isn't included in the hello and replSetGetStatus // commands and therefore won't interfere with the session associated with the // global "db" object. db._session = new _DummyDriverSession(db.getMongo()); diff --git a/src/mongo/shell/utils_sh.js b/src/mongo/shell/utils_sh.js index 272ade772bc..d5b6103da4c 100644 --- a/src/mongo/shell/utils_sh.js +++ b/src/mongo/shell/utils_sh.js @@ -3,7 +3,7 @@ sh = function() { }; sh._checkMongos = function() { - var x = db.runCommand("ismaster"); + var x = db._helloOrLegacyHello(); if (x.msg != "isdbgrid") throw Error("not connected to a mongos"); }; |