1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
|
//
// Utility functions for multi-version replica sets
//
/**
* @param options {Object} see ReplSetTest.start & MongoRunner.runMongod.
* @param user {string} optional, user name for authentication.
* @param pwd {string} optional, password for authentication. Must be set if user is set.
*/
ReplSetTest.prototype.upgradeSet = function(options, user, pwd) {
options = options || {};
var primary = this.getPrimary();
// Upgrade secondaries first
var nodesToUpgrade = this.getSecondaries();
// Then upgrade primaries
nodesToUpgrade.push(primary);
// We can upgrade with no primary downtime if we have enough nodes
var noDowntimePossible = this.nodes.length > 2;
for (var i = 0; i < nodesToUpgrade.length; i++) {
var node = nodesToUpgrade[ i ];
if (node == primary) {
node = this.stepdown(node);
primary = this.getPrimary();
}
var prevPrimaryId = this.getNodeId(primary);
//merge new options into node settings...
for (var nodeName in this.nodeOptions) {
this.nodeOptions[nodeName] = Object.merge(this.nodeOptions[nodeName], options);
}
this.upgradeNode(node, options, user, pwd);
if (noDowntimePossible)
assert.eq(this.getNodeId(primary), prevPrimaryId);
}
};
ReplSetTest.prototype.upgradeNode = function(node, opts, user, pwd) {
if (user != undefined) {
assert.eq(1, node.getDB("admin").auth(user, pwd));
}
var isMaster = node.getDB('admin').runCommand({ isMaster: 1 });
if (!isMaster.arbiterOnly) {
assert.commandWorked(node.adminCommand("replSetMaintenance"));
this.waitForState(node, ReplSetTest.State.RECOVERING);
}
var newNode = this.restart(node, opts);
if (user != undefined) {
newNode.getDB("admin").auth(user, pwd);
}
var waitForStates = [ ReplSetTest.State.PRIMARY,
ReplSetTest.State.SECONDARY,
ReplSetTest.State.ARBITER ];
this.waitForState(newNode, waitForStates);
return newNode;
};
ReplSetTest.prototype.stepdown = function(nodeId) {
nodeId = this.getNodeId(nodeId);
assert.eq(this.getNodeId(this.getPrimary()), nodeId);
var node = this.nodes[nodeId];
try {
node.getDB("admin").runCommand({ replSetStepDown: 50, force: true });
assert(false);
}
catch (ex) {
print('Caught exception after stepDown cmd: ' + tojson(ex));
}
return this.reconnect(node);
};
ReplSetTest.prototype.reconnect = function(node) {
var nodeId = this.getNodeId(node);
this.nodes[nodeId] = new Mongo(node.host);
var except = {};
for (var i in node) {
if (typeof(node[i]) == "function") continue;
this.nodes[nodeId][i] = node[i];
}
return this.nodes[nodeId];
};
ReplSetTest.prototype.conf = function () {
var admin = this.getPrimary().getDB('admin');
var resp = admin.runCommand({replSetGetConfig:1});
if (resp.ok && !(resp.errmsg) && resp.config)
return resp.config;
else if (resp.errmsg && resp.errmsg.startsWith("no such cmd"))
return admin.getSisterDB("local").system.replset.findOne();
throw new Error("Could not retrieve replica set config: " + tojson(resp));
};
|