summaryrefslogtreecommitdiff
path: root/src/mongo/shell/shell_utils.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/mongo/shell/shell_utils.cpp')
-rw-r--r--src/mongo/shell/shell_utils.cpp506
1 files changed, 252 insertions, 254 deletions
diff --git a/src/mongo/shell/shell_utils.cpp b/src/mongo/shell/shell_utils.cpp
index b70146559de..81dd1d5225f 100644
--- a/src/mongo/shell/shell_utils.cpp
+++ b/src/mongo/shell/shell_utils.cpp
@@ -48,330 +48,328 @@
namespace mongo {
- using std::set;
- using std::map;
- using std::string;
-
- namespace JSFiles {
- extern const JSFile servers;
- extern const JSFile shardingtest;
- extern const JSFile servers_misc;
- extern const JSFile replsettest;
- extern const JSFile replsetbridge;
- }
+using std::set;
+using std::map;
+using std::string;
+
+namespace JSFiles {
+extern const JSFile servers;
+extern const JSFile shardingtest;
+extern const JSFile servers_misc;
+extern const JSFile replsettest;
+extern const JSFile replsetbridge;
+}
- namespace shell_utils {
+namespace shell_utils {
- std::string _dbConnect;
- std::string _dbAuth;
+std::string _dbConnect;
+std::string _dbAuth;
- const char *argv0 = 0;
- void RecordMyLocation( const char *_argv0 ) { argv0 = _argv0; }
+const char* argv0 = 0;
+void RecordMyLocation(const char* _argv0) {
+ argv0 = _argv0;
+}
- // helpers
+// helpers
- BSONObj makeUndefined() {
- BSONObjBuilder b;
- b.appendUndefined( "" );
- return b.obj();
- }
- const BSONObj undefinedReturn = makeUndefined();
+BSONObj makeUndefined() {
+ BSONObjBuilder b;
+ b.appendUndefined("");
+ return b.obj();
+}
+const BSONObj undefinedReturn = makeUndefined();
- BSONElement singleArg(const BSONObj& args) {
- uassert( 12597 , "need to specify 1 argument" , args.nFields() == 1 );
- return args.firstElement();
- }
+BSONElement singleArg(const BSONObj& args) {
+ uassert(12597, "need to specify 1 argument", args.nFields() == 1);
+ return args.firstElement();
+}
- const char* getUserDir() {
+const char* getUserDir() {
#ifdef _WIN32
- return getenv( "USERPROFILE" );
+ return getenv("USERPROFILE");
#else
- return getenv( "HOME" );
+ return getenv("HOME");
#endif
- }
+}
- // real methods
+// real methods
- BSONObj Quit(const BSONObj& args, void* data) {
- // If no arguments are given first element will be EOO, which
- // converts to the integer value 0.
- goingAwaySoon();
- int exit_code = int( args.firstElement().number() );
- quickExit(exit_code);
- return undefinedReturn;
- }
+BSONObj Quit(const BSONObj& args, void* data) {
+ // If no arguments are given first element will be EOO, which
+ // converts to the integer value 0.
+ goingAwaySoon();
+ int exit_code = int(args.firstElement().number());
+ quickExit(exit_code);
+ return undefinedReturn;
+}
- BSONObj JSGetMemInfo( const BSONObj& args, void* data ) {
- ProcessInfo pi;
- uassert( 10258 , "processinfo not supported" , pi.supported() );
+BSONObj JSGetMemInfo(const BSONObj& args, void* data) {
+ ProcessInfo pi;
+ uassert(10258, "processinfo not supported", pi.supported());
- BSONObjBuilder e;
- e.append( "virtual" , pi.getVirtualMemorySize() );
- e.append( "resident" , pi.getResidentSize() );
+ BSONObjBuilder e;
+ e.append("virtual", pi.getVirtualMemorySize());
+ e.append("resident", pi.getResidentSize());
- BSONObjBuilder b;
- b.append( "ret" , e.obj() );
+ BSONObjBuilder b;
+ b.append("ret", e.obj());
- return b.obj();
- }
+ return b.obj();
+}
#if !defined(_WIN32)
- ThreadLocalValue< unsigned int > _randomSeed;
+ThreadLocalValue<unsigned int> _randomSeed;
#endif
- BSONObj JSSrand( const BSONObj &a, void* data ) {
- uassert( 12518, "srand requires a single numeric argument",
- a.nFields() == 1 && a.firstElement().isNumber() );
+BSONObj JSSrand(const BSONObj& a, void* data) {
+ uassert(12518,
+ "srand requires a single numeric argument",
+ a.nFields() == 1 && a.firstElement().isNumber());
#if !defined(_WIN32)
- _randomSeed.set( static_cast< unsigned int >( a.firstElement().numberLong() ) ); // grab least significant digits
+ _randomSeed.set(
+ static_cast<unsigned int>(a.firstElement().numberLong())); // grab least significant digits
#else
- srand( static_cast< unsigned int >( a.firstElement().numberLong() ) );
+ srand(static_cast<unsigned int>(a.firstElement().numberLong()));
#endif
- return undefinedReturn;
- }
+ return undefinedReturn;
+}
- BSONObj JSRand( const BSONObj &a, void* data ) {
- uassert( 12519, "rand accepts no arguments", a.nFields() == 0 );
- unsigned r;
+BSONObj JSRand(const BSONObj& a, void* data) {
+ uassert(12519, "rand accepts no arguments", a.nFields() == 0);
+ unsigned r;
#if !defined(_WIN32)
- r = rand_r( &_randomSeed.getRef() );
+ r = rand_r(&_randomSeed.getRef());
#else
- r = rand();
+ r = rand();
#endif
- return BSON( "" << double( r ) / ( double( RAND_MAX ) + 1 ) );
- }
+ return BSON("" << double(r) / (double(RAND_MAX) + 1));
+}
- BSONObj isWindows(const BSONObj& a, void* data) {
- uassert( 13006, "isWindows accepts no arguments", a.nFields() == 0 );
+BSONObj isWindows(const BSONObj& a, void* data) {
+ uassert(13006, "isWindows accepts no arguments", a.nFields() == 0);
#ifdef _WIN32
- return BSON( "" << true );
+ return BSON("" << true);
#else
- return BSON( "" << false );
+ return BSON("" << false);
#endif
- }
+}
- BSONObj isAddressSanitizerActive(const BSONObj& a, void* data) {
- bool isSanitized = false;
- // See the following for information on how we detect address sanitizer in clang and gcc.
- //
- // - http://clang.llvm.org/docs/AddressSanitizer.html#has-feature-address-sanitizer
- // - https://gcc.gnu.org/ml/gcc-patches/2012-11/msg01827.html
- //
+BSONObj isAddressSanitizerActive(const BSONObj& a, void* data) {
+ bool isSanitized = false;
+// See the following for information on how we detect address sanitizer in clang and gcc.
+//
+// - http://clang.llvm.org/docs/AddressSanitizer.html#has-feature-address-sanitizer
+// - https://gcc.gnu.org/ml/gcc-patches/2012-11/msg01827.html
+//
#if defined(__has_feature)
#if __has_feature(address_sanitizer)
- isSanitized = true;
+ isSanitized = true;
#endif
#elif defined(__SANITIZE_ADDRESS__)
- isSanitized = true;
+ isSanitized = true;
#endif
- return BSON( "" << isSanitized );
- }
+ return BSON("" << isSanitized);
+}
- BSONObj getBuildInfo(const BSONObj& a, void* data) {
- uassert( 16822, "getBuildInfo accepts no arguments", a.nFields() == 0 );
- BSONObjBuilder b;
- appendBuildInfo(b);
- return BSON( "" << b.done() );
- }
+BSONObj getBuildInfo(const BSONObj& a, void* data) {
+ uassert(16822, "getBuildInfo accepts no arguments", a.nFields() == 0);
+ BSONObjBuilder b;
+ appendBuildInfo(b);
+ return BSON("" << b.done());
+}
- BSONObj isKeyTooLarge(const BSONObj& a, void* data) {
- uassert(17428, "keyTooLarge takes exactly 2 arguments", a.nFields() == 2);
- BSONObjIterator i(a);
- BSONObj index = i.next().Obj();
- BSONObj doc = i.next().Obj();
+BSONObj isKeyTooLarge(const BSONObj& a, void* data) {
+ uassert(17428, "keyTooLarge takes exactly 2 arguments", a.nFields() == 2);
+ BSONObjIterator i(a);
+ BSONObj index = i.next().Obj();
+ BSONObj doc = i.next().Obj();
- return BSON("" << isAnyIndexKeyTooLarge(index, doc));
- }
+ return BSON("" << isAnyIndexKeyTooLarge(index, doc));
+}
- BSONObj validateIndexKey(const BSONObj& a, void* data) {
- BSONObj key = a[0].Obj();
- Status indexValid = validateKeyPattern(key);
- if (!indexValid.isOK()) {
- return BSON("" << BSON("ok" << false << "type"
- << indexValid.codeString() << "errmsg" << indexValid.reason()));
- }
- return BSON("" << BSON("ok" << true));
- }
+BSONObj validateIndexKey(const BSONObj& a, void* data) {
+ BSONObj key = a[0].Obj();
+ Status indexValid = validateKeyPattern(key);
+ if (!indexValid.isOK()) {
+ return BSON("" << BSON("ok" << false << "type" << indexValid.codeString() << "errmsg"
+ << indexValid.reason()));
+ }
+ return BSON("" << BSON("ok" << true));
+}
- BSONObj replMonitorStats(const BSONObj& a, void* data) {
- uassert(17134, "replMonitorStats requires a single string argument (the ReplSet name)",
- a.nFields() == 1 && a.firstElement().type() == String);
+BSONObj replMonitorStats(const BSONObj& a, void* data) {
+ uassert(17134,
+ "replMonitorStats requires a single string argument (the ReplSet name)",
+ a.nFields() == 1 && a.firstElement().type() == String);
- ReplicaSetMonitorPtr rsm = ReplicaSetMonitor::get(a.firstElement().valuestrsafe());
- if (!rsm) {
- return BSON("" << "no ReplSetMonitor exists by that name");
- }
+ ReplicaSetMonitorPtr rsm = ReplicaSetMonitor::get(a.firstElement().valuestrsafe());
+ if (!rsm) {
+ return BSON(""
+ << "no ReplSetMonitor exists by that name");
+ }
- BSONObjBuilder result;
- rsm->appendInfo(result);
- return result.obj();
- }
+ BSONObjBuilder result;
+ rsm->appendInfo(result);
+ return result.obj();
+}
- BSONObj useWriteCommandsDefault(const BSONObj& a, void* data) {
- return BSON("" << shellGlobalParams.useWriteCommandsDefault);
- }
+BSONObj useWriteCommandsDefault(const BSONObj& a, void* data) {
+ return BSON("" << shellGlobalParams.useWriteCommandsDefault);
+}
- BSONObj writeMode(const BSONObj&, void*) {
- return BSON("" << shellGlobalParams.writeMode);
- }
+BSONObj writeMode(const BSONObj&, void*) {
+ return BSON("" << shellGlobalParams.writeMode);
+}
- BSONObj readMode(const BSONObj&, void*) {
- return BSON("" << shellGlobalParams.readMode);
- }
+BSONObj readMode(const BSONObj&, void*) {
+ return BSON("" << shellGlobalParams.readMode);
+}
- BSONObj interpreterVersion(const BSONObj& a, void* data) {
- uassert( 16453, "interpreterVersion accepts no arguments", a.nFields() == 0 );
- return BSON( "" << globalScriptEngine->getInterpreterVersionString() );
- }
+BSONObj interpreterVersion(const BSONObj& a, void* data) {
+ uassert(16453, "interpreterVersion accepts no arguments", a.nFields() == 0);
+ return BSON("" << globalScriptEngine->getInterpreterVersionString());
+}
- void installShellUtils( Scope& scope ) {
- scope.injectNative( "quit", Quit );
- scope.injectNative( "getMemInfo" , JSGetMemInfo );
- scope.injectNative( "_replMonitorStats" , replMonitorStats );
- scope.injectNative( "_srand" , JSSrand );
- scope.injectNative( "_rand" , JSRand );
- scope.injectNative( "_isWindows" , isWindows );
- scope.injectNative( "_isAddressSanitizerActive", isAddressSanitizerActive );
- scope.injectNative( "interpreterVersion", interpreterVersion );
- scope.injectNative( "getBuildInfo", getBuildInfo );
- scope.injectNative( "isKeyTooLarge", isKeyTooLarge );
- scope.injectNative( "validateIndexKey", validateIndexKey );
+void installShellUtils(Scope& scope) {
+ scope.injectNative("quit", Quit);
+ scope.injectNative("getMemInfo", JSGetMemInfo);
+ scope.injectNative("_replMonitorStats", replMonitorStats);
+ scope.injectNative("_srand", JSSrand);
+ scope.injectNative("_rand", JSRand);
+ scope.injectNative("_isWindows", isWindows);
+ scope.injectNative("_isAddressSanitizerActive", isAddressSanitizerActive);
+ scope.injectNative("interpreterVersion", interpreterVersion);
+ scope.injectNative("getBuildInfo", getBuildInfo);
+ scope.injectNative("isKeyTooLarge", isKeyTooLarge);
+ scope.injectNative("validateIndexKey", validateIndexKey);
#ifndef MONGO_SAFE_SHELL
- //can't launch programs
- installShellUtilsLauncher( scope );
- installShellUtilsExtended( scope );
+ // can't launch programs
+ installShellUtilsLauncher(scope);
+ installShellUtilsExtended(scope);
#endif
- }
+}
- void initScope( Scope &scope ) {
- // Need to define this method before JSFiles::utils is executed.
- scope.injectNative("_useWriteCommandsDefault", useWriteCommandsDefault);
- scope.injectNative("_writeMode", writeMode);
- scope.injectNative("_readMode", readMode);
- scope.externalSetup();
- mongo::shell_utils::installShellUtils( scope );
- scope.execSetup(JSFiles::servers);
- scope.execSetup(JSFiles::shardingtest);
- scope.execSetup(JSFiles::servers_misc);
- scope.execSetup(JSFiles::replsettest);
- scope.execSetup(JSFiles::replsetbridge);
-
- scope.injectNative("benchRun", BenchRunner::benchRunSync);
- scope.injectNative("benchRunSync", BenchRunner::benchRunSync);
- scope.injectNative("benchStart", BenchRunner::benchStart);
- scope.injectNative("benchFinish", BenchRunner::benchFinish);
-
- if ( !_dbConnect.empty() ) {
- uassert( 12513, "connect failed", scope.exec( _dbConnect , "(connect)" , false , true , false ) );
- }
- if ( !_dbAuth.empty() ) {
- uassert( 12514, "login failed", scope.exec( _dbAuth , "(auth)" , true , true , false ) );
- }
- }
+void initScope(Scope& scope) {
+ // Need to define this method before JSFiles::utils is executed.
+ scope.injectNative("_useWriteCommandsDefault", useWriteCommandsDefault);
+ scope.injectNative("_writeMode", writeMode);
+ scope.injectNative("_readMode", readMode);
+ scope.externalSetup();
+ mongo::shell_utils::installShellUtils(scope);
+ scope.execSetup(JSFiles::servers);
+ scope.execSetup(JSFiles::shardingtest);
+ scope.execSetup(JSFiles::servers_misc);
+ scope.execSetup(JSFiles::replsettest);
+ scope.execSetup(JSFiles::replsetbridge);
+
+ scope.injectNative("benchRun", BenchRunner::benchRunSync);
+ scope.injectNative("benchRunSync", BenchRunner::benchRunSync);
+ scope.injectNative("benchStart", BenchRunner::benchStart);
+ scope.injectNative("benchFinish", BenchRunner::benchFinish);
+
+ if (!_dbConnect.empty()) {
+ uassert(12513, "connect failed", scope.exec(_dbConnect, "(connect)", false, true, false));
+ }
+ if (!_dbAuth.empty()) {
+ uassert(12514, "login failed", scope.exec(_dbAuth, "(auth)", true, true, false));
+ }
+}
- Prompter::Prompter( const string &prompt ) :
- _prompt( prompt ),
- _confirmed() {
- }
+Prompter::Prompter(const string& prompt) : _prompt(prompt), _confirmed() {}
- bool Prompter::confirm() {
- if ( _confirmed ) {
- return true;
- }
+bool Prompter::confirm() {
+ if (_confirmed) {
+ return true;
+ }
- // The printf and scanf functions provide thread safe i/o.
-
- printf( "\n%s (y/n): ", _prompt.c_str() );
-
- char yn = '\0';
- int nScanMatches = scanf( "%c", &yn );
- bool matchedY = ( nScanMatches == 1 && ( yn == 'y' || yn == 'Y' ) );
-
- return _confirmed = matchedY;
- }
+ // The printf and scanf functions provide thread safe i/o.
- ConnectionRegistry::ConnectionRegistry() = default;
+ printf("\n%s (y/n): ", _prompt.c_str());
- void ConnectionRegistry::registerConnection( DBClientWithCommands &client ) {
- BSONObj info;
- if ( client.runCommand( "admin", BSON( "whatsmyuri" << 1 ), info ) ) {
- string connstr = dynamic_cast<DBClientBase&>( client ).getServerAddress();
- stdx::lock_guard<stdx::mutex> lk( _mutex );
- _connectionUris[ connstr ].insert( info[ "you" ].str() );
- }
- }
+ char yn = '\0';
+ int nScanMatches = scanf("%c", &yn);
+ bool matchedY = (nScanMatches == 1 && (yn == 'y' || yn == 'Y'));
- void ConnectionRegistry::killOperationsOnAllConnections( bool withPrompt ) const {
- Prompter prompter( "do you want to kill the current op(s) on the server?" );
- stdx::lock_guard<stdx::mutex> lk( _mutex );
- for( map<string,set<string> >::const_iterator i = _connectionUris.begin();
- i != _connectionUris.end(); ++i ) {
+ return _confirmed = matchedY;
+}
- auto status = ConnectionString::parse(i->first);
- if (!status.isOK()) {
- continue;
- }
+ConnectionRegistry::ConnectionRegistry() = default;
- const ConnectionString cs(status.getValue());
+void ConnectionRegistry::registerConnection(DBClientWithCommands& client) {
+ BSONObj info;
+ if (client.runCommand("admin", BSON("whatsmyuri" << 1), info)) {
+ string connstr = dynamic_cast<DBClientBase&>(client).getServerAddress();
+ stdx::lock_guard<stdx::mutex> lk(_mutex);
+ _connectionUris[connstr].insert(info["you"].str());
+ }
+}
- string errmsg;
- std::unique_ptr<DBClientWithCommands> conn( cs.connect( errmsg ) );
- if ( !conn ) {
- continue;
- }
-
- const set<string>& uris = i->second;
-
- BSONObj currentOpRes;
- conn->runPseudoCommand("admin",
- "currentOp",
- "$cmd.sys.inprog", {}, currentOpRes);
- auto inprog = currentOpRes["inprog"].embeddedObject();
- BSONForEach( op, inprog ) {
- if ( uris.count( op[ "client" ].String() ) ) {
- if ( !withPrompt || prompter.confirm() ) {
- BSONObjBuilder cmdBob;
- BSONObj info;
- cmdBob.append("op", op["opid"]);
- auto cmdArgs = cmdBob.done();
- conn->runPseudoCommand("admin", "killOp", "$cmd.sys.killop",
- cmdArgs, info);
- }
- else {
- return;
- }
- }
- }
- }
+void ConnectionRegistry::killOperationsOnAllConnections(bool withPrompt) const {
+ Prompter prompter("do you want to kill the current op(s) on the server?");
+ stdx::lock_guard<stdx::mutex> lk(_mutex);
+ for (map<string, set<string>>::const_iterator i = _connectionUris.begin();
+ i != _connectionUris.end();
+ ++i) {
+ auto status = ConnectionString::parse(i->first);
+ if (!status.isOK()) {
+ continue;
+ }
+
+ const ConnectionString cs(status.getValue());
+
+ string errmsg;
+ std::unique_ptr<DBClientWithCommands> conn(cs.connect(errmsg));
+ if (!conn) {
+ continue;
}
-
- ConnectionRegistry connectionRegistry;
- bool _nokillop = false;
- void onConnect( DBClientWithCommands &c ) {
- if ( _nokillop ) {
- return;
+ const set<string>& uris = i->second;
+
+ BSONObj currentOpRes;
+ conn->runPseudoCommand("admin", "currentOp", "$cmd.sys.inprog", {}, currentOpRes);
+ auto inprog = currentOpRes["inprog"].embeddedObject();
+ BSONForEach(op, inprog) {
+ if (uris.count(op["client"].String())) {
+ if (!withPrompt || prompter.confirm()) {
+ BSONObjBuilder cmdBob;
+ BSONObj info;
+ cmdBob.append("op", op["opid"]);
+ auto cmdArgs = cmdBob.done();
+ conn->runPseudoCommand("admin", "killOp", "$cmd.sys.killop", cmdArgs, info);
+ } else {
+ return;
+ }
}
- c.setClientRPCProtocols(shellGlobalParams.rpcProtocols);
- connectionRegistry.registerConnection( c );
}
+ }
+}
- bool fileExists(const std::string& file) {
- try {
+ConnectionRegistry connectionRegistry;
+
+bool _nokillop = false;
+void onConnect(DBClientWithCommands& c) {
+ if (_nokillop) {
+ return;
+ }
+ c.setClientRPCProtocols(shellGlobalParams.rpcProtocols);
+ connectionRegistry.registerConnection(c);
+}
+
+bool fileExists(const std::string& file) {
+ try {
#ifdef _WIN32
- boost::filesystem::path p(toWideString(file.c_str()));
+ boost::filesystem::path p(toWideString(file.c_str()));
#else
- boost::filesystem::path p(file);
+ boost::filesystem::path p(file);
#endif
- return boost::filesystem::exists(p);
- }
- catch ( ... ) {
- return false;
- }
- }
+ return boost::filesystem::exists(p);
+ } catch (...) {
+ return false;
+ }
+}
- stdx::mutex &mongoProgramOutputMutex(*(new stdx::mutex()));
- }
+stdx::mutex& mongoProgramOutputMutex(*(new stdx::mutex()));
+}
}