6

I'm looking to automate the process of setting up a MongoDb replica set via a sidecar when using Docker and Kubernetes.

The above setup isn't terribly important, what it boils down to is that I need to be able to call the mongo replica set commands (e.g. rs.initiate(), rs.add('anotherserver'), rs.conf(), rs.reconfig(), etc) from a node.js application.

Note: it doesn't have to be from a node application, if someone knows of another way of getting the same thing done, please share your thoughts.

UPDATE: I was able to get this working and have made the sidecar open source for others to use.

Charlino
  • 15,802
  • 3
  • 58
  • 74

1 Answers1

15

How are the replica set admin helpers implemented?

The rs.* replica set admin helpers in the mongo shell are wrappers for MongoDB commands which you can send from any driver.

You can see which command(s) each shell helper wraps by referring to the MongoDB documentation:

Note that the mongo shell helpers may do some extra validation or manipulation of configs as they are intended to be used via the interactive mongo shell.

You can confirm how any of the shell helpers are implemented by invoking the command in the shell without trailing parentheses, eg:

> rs.initiate
function (c) { return db._adminCommand({ replSetInitiate: c }); }

Calling replica set database commands from Node.js

The equivalent logic can be implemented via the Node.js driver API using command():

// Rough equivalent of rs.initiate()
var MongoClient = require('mongodb').MongoClient;

MongoClient.connect('mongodb://localhost:27017/test', function(err, db) {

  // Use the admin database for commands
  var adminDb = db.admin();

  // Default replica set conf
  var conf = {};

  adminDb.command({replSetInitiate: conf}, function(err, info) {
     console.log(info);
  });
});

Note: it doesn't have to be from a node application, if someone knows of another way of getting the same thing done, please share your thoughts.

Rather than reimplementing the replica set helpers in Node.js, you could invoke a mongo shell with the --eval command to run the shell helper (tip: include --quiet to suppress unnecessary messages).

For example, calling from your Node app:

var exec = require('child_process').exec;
var rsAdmin = exec('mongo --eval "var res = rs.initiate(); printjson(res)" --quiet', function (error, stdout, stderr) {
   // output is in stdout
   console.log(stdout);
});
Stennie
  • 63,885
  • 14
  • 149
  • 175
  • 1
    +1 Thanks @Stennie, I actually stumbled across one of your other answers on this topic and am in the process of implementing it... works like a treat. Stay tuned! – Charlino May 05 '15 at 06:01
  • 1
    Managed to get all this working thanks @Stennie, see my question edit for more info if you were interested. – Charlino May 06 '15 at 06:08
  • 1
    Super helpful, I wish I could give you 5 upvotes for that one! – Addo Solutions Aug 24 '17 at 17:56