diff --git a/mtools/mlaunch/mlaunch.py b/mtools/mlaunch/mlaunch.py index 8473ac6a..544c6d08 100755 --- a/mtools/mlaunch/mlaunch.py +++ b/mtools/mlaunch/mlaunch.py @@ -290,10 +290,13 @@ def run(self, arguments=None): 'several singles or replica sets. ' 'Provide either list of shard names or ' 'number of shards.')) - init_parser.add_argument('--config', action='store', default=1, + init_parser.add_argument('--config', action='store', default=-1, type=int, metavar='NUM', help=('adds NUM config servers to sharded ' 'setup (requires --sharded, default=1)')) + + init_parser.add_argument('--embeddedcsrs', default=False, action='store_true', + help=('use embedded CSRS (only for MongoDB 8.0.0+), default=False')) # As of MongoDB 3.6, all config servers must be CSRS init_parser.add_argument('--csrs', default=True, action='store_true', @@ -660,14 +663,28 @@ def init(self): sys.stderr.write('warning: server requires certificates but no' ' --tlsClientCertificateKeyFile provided\n') # number of default config servers - if self.args['config'] == -1: - self.args['config'] = 1 + if self.args['config'] == -1 and self.args["sharded"]: + if self.args['embeddedcsrs']: + print("Config members set to: " + str(self.args['nodes'])) + self.args['config'] = self.args['nodes'] + else: + print("Config members set to: 1") + self.args['config'] = 1 # add the 'csrs' parameter as default for MongoDB >= 3.3.0 if (version.parse(self.current_version) >= version.parse("3.3.0") or version.parse(self.current_version) == version.parse("0.0.0")): self.args['csrs'] = True + if self.args['embeddedcsrs'] and version.parse(self.current_version) < version.parse("8.0.0"): + print("--embeddedcsrs can only be used with MongoDB 8.0.0+") + sys.exit(1) + + # Check if embedded is used, if it's the case the number of shards should be decremented by 1 + if self.args['embeddedcsrs'] and 'sharded' in self.args and self.args['sharded']: + if len(self.args['sharded']) == 1: + self.args['sharded'][0] = str(int(self.args['sharded'][0]) - 1) + # construct startup strings self._construct_cmdlines() @@ -720,7 +737,7 @@ def init(self): errmsg += (" * You can also specify a different port range with " "an additional '--port '\n") raise SystemExit(errmsg) - + if self.args['sharded']: shard_names = self._get_shard_names(self.args) @@ -791,6 +808,11 @@ def init(self): print('Shard addition failed: ' + res + ' - will retry') time.sleep(1) + + if self.args['embeddedcsrs']: + print("Configuring embedded config servers") + con = self.client('localhost:%i' % mongos[0]) + con.admin.command({'transitionFromDedicatedConfigServer': 1}) elif self.args['single']: # just start node @@ -1029,12 +1051,26 @@ def list(self): print_docs.append(None) # configs + # temporary list used to find the list of running nodes + tmp_config_list = [] + string_config = "config server" for node in sorted(self.get_tagged(['config'])): - doc = OrderedDict([('process', 'config server'), + if self.cluster_running[node]: + status = 'running' + if self._check_if_embeddedcsrs(): + string_config = "config shard" + else: + status = 'down' + + doc = OrderedDict([('process', string_config), ('port', node), - ('status', 'running' - if self.cluster_running[node] else 'down')]) - print_docs.append(doc) + ('status', status)]) + tmp_config_list.append(doc) + + # construct the final list with the right config type + for item in tmp_config_list: + item['process'] = string_config + print_docs.append(item) if len(self.get_tagged(['config'])) > 0: print_docs.append(None) @@ -1740,6 +1776,7 @@ def _get_shard_names(self, args): # --sharded was a number, name shards shard01, shard02, # ... (only works with replica sets) n_shards = int(args['sharded'][0]) + shard_names = ['shard%.2i' % (i + 1) for i in range(n_shards)] except ValueError: @@ -2186,6 +2223,20 @@ def _read_key_file(self, keyfile=None): with open(keyfile, 'rb') as f: return ''.join(f.readlines()) + def _check_if_embeddedcsrs(self) -> bool: + """ + Returns True if embedded CSRS is used + """ + mongos = sorted(self.get_tagged(['mongos'])) + con = self.client('localhost:%i' % mongos[0], readPreference="primaryPreferred") + try: + if con['config']['shards'].find_one({ '_id': 'config' }): + return True + return False + except OperationFailure: + print("WARNING: Unable to check if config server is embedded") + return False + def main(): tool = MLaunchTool() tool.run()