def _do_setup(self, cfg, node_count=5): # give defaults to teardown vars self._node_ctrl = None print 'creating', str(self.__class__.__name__) # set up our nodes (suite-internal interface) self._node_ctrl = WrappedNodeController(SubprocessNodeController()) temp_dir = self._node_ctrl.get_data_dir() file_name = os.path.join(temp_dir, "config.js") with open(file_name, 'w') as config: config.write(json.dumps(cfg)) self._nodes = [ NodeArguments('v%s' % i, 8800 + i, 9000 + i, config_files=[file_name], ledger_type=cfg["LedgerType"]) for i in range(node_count) ] # set up our urls (external interface) self.urls = ['http://localhost:%s' % x.http_port for x in self._nodes] # Make genesis block print 'creating genesis block...' self._nodes[0].genesis = True self._node_ctrl.create_genesis_block(self._nodes[0]) # Launch network (node zero will trigger bootstrapping) print 'launching network...' for x in self._nodes: self._node_ctrl.start(x)
def do_cluster_extend(args): state = load_state() node_controller = get_node_controller(state, args) node_command_generator = SimpleNodeCommandGenerator() vnm = ValidatorNetworkManager( node_controller=node_controller, node_command_generator=node_command_generator) existing_nodes = state["Nodes"] desired_stated = state["DesiredState"] if desired_stated != "Running": raise CliException( "You must have a running network.\n" + "Use the cluster start command to start a validator network.") print("Extending network by {} nodes.".format(args.count)) index_offset = len(existing_nodes) for i in xrange(0, args.count): j = i + index_offset node_name = "validator-{:0>3}".format(j) if node_name in existing_nodes and vnm.is_running(node_name): print("Already running: {}".format(node_name)) continue # genesis is true for the first node genesis = (j == 0) gossip_port = 5500 + j http_port = 8800 + j node_args = NodeArguments(node_name, http_port=http_port, gossip_port=gossip_port, genesis=genesis) node_command_generator.start(node_args) state["Nodes"][node_name] = { "Status": "Running", "Index": i, "HttpPort": str(http_port), "GossipPort": str(gossip_port) } save_state(state) try: vnm.update() except ManagementError as e: raise CliException(str(e))
def _do_setup(self): # give defaults to teardown vars self._node_ctrl = None print 'creating', str(self.__class__.__name__) # set up our nodes (suite-internal interface) self._nodes = [ NodeArguments('v%s' % i, 8800 + i, 9000 + i) for i in range(2) ] # set up our urls (external interface) self.urls = ['http://localhost:%s' % x.http_port for x in self._nodes] # Make genesis block print 'creating genesis block...' self._nodes[0].genesis = True self._node_ctrl = WrappedNodeController(SubprocessNodeController()) self._node_ctrl.create_genesis_block(self._nodes[0]) # Launch network (node zero will trigger bootstrapping) print 'launching network...' for x in self._nodes: self._node_ctrl.start(x)
def main(): node_ctrl = None try: opts = configure(sys.argv[1:]) except Exception as e: print(str(e), file=sys.stderr) sys.exit(1) try: count = opts['count'] # log_config = NEED currency_home = opts['data_dir'] http_port = int(opts['http_port']) gossip_port = int(opts['port']) try: ledger_type = opts["validator_config"]["LedgerType"] except KeyError: # None defaults to poet1 ledger_type = None node_ctrl = WrappedNodeController(SubprocessNodeController(), data_dir=currency_home) nodes = [] for idx in range(count): node = NodeArguments("validator-{:0>3}".format(idx), http_port=http_port + idx, gossip_port=gossip_port + idx, ledger_type=ledger_type) nodes.append(node) currency_home = node_ctrl.get_data_dir() if opts['log_config_dict']: file_name = 'launcher_cli_global_log_config.js' full_name = '{}/etc/{}'.format(currency_home, file_name) with open(full_name, 'w') as f: f.write(json.dumps(opts['log_config_dict'], indent=4)) opts['validator_config']['LogConfigFile'] = full_name if opts['validator_config']: file_name = 'launcher_cli_global_validator_config.js' with open('{}/etc/{}'.format(currency_home, file_name), 'w') as f: f.write(json.dumps(opts['validator_config'], indent=4)) for nd in nodes: nd.config_files.append(file_name) # set up our urls (external interface) urls = ['http://localhost:%s' % x.http_port for x in nodes] # Make genesis block print('creating genesis block...') nodes[0].genesis = True node_ctrl.create_genesis_block(nodes[0]) # Launch network (node zero will trigger bootstrapping) batch_size = 8 print('staged-launching network (batch_size: {})...' .format(batch_size)) lower_bound = 0 while lower_bound < count: upper_bound = lower_bound + min(count - lower_bound, batch_size) for idx in range(lower_bound, upper_bound): print("launching {}".format(nodes[idx].node_name)) node_ctrl.start(nodes[idx]) _poll_for_convergence(urls[lower_bound:upper_bound]) lower_bound = upper_bound run_stats(urls[0]) except KeyboardInterrupt: print("\nExiting") except ExitError as e: # this is an expected error/exit, don't print stack trace - # the code raising this exception is expected to have printed the error # details print("\nFailed!\nExiting: {}".format(e)) except: traceback.print_exc() print("\nFailed!\nExiting: {}".format(sys.exc_info()[0])) finally: if node_ctrl is not None: # stop all nodes for node_name in node_ctrl.get_node_names(): node_ctrl.stop(node_name) with Progress("terminating network") as p: to = TimeOut(16) while len(node_ctrl.get_node_names()) > 0: if to.is_timed_out(): break time.sleep(1) p.step() # force kill anything left over for node_name in node_ctrl.get_node_names(): print("%s still 'up'; sending kill..." % node_name) node_ctrl.kill(node_name) node_ctrl.archive('launcher') node_ctrl.clean()
def extend_genesis_util(self, overrides): print() vnm = None try: self._node_ctrl = None print('creating', str(self.__class__.__name__)) # set up our nodes (suite-internal interface) self._node_ctrl = WrappedNodeController(SubprocessNodeController()) cfg = overrides temp_dir = self._node_ctrl.get_data_dir() file_name = os.path.join(temp_dir, "config.js") with open(file_name, 'w') as config: config.write(json.dumps(cfg)) data_dir = os.path.join(temp_dir, "data") gblock_file = genesis_info_file_name(data_dir) self._nodes = [ NodeArguments('v%s' % i, 8800 + i, 9000 + i, config_files=[file_name], ledger_type=overrides["LedgerType"]) for i in range(2)] # set up our urls (external interface) self.urls = [ 'http://localhost:%s' % x.http_port for x in self._nodes] # Make genesis block print('creating genesis block...') self.assertFalse(os.path.exists(gblock_file)) self._nodes[0].genesis = True self._node_ctrl.create_genesis_block(self._nodes[0]) # Test genesis util self.assertTrue(os.path.exists(gblock_file)) genesis_dat = None with open(gblock_file, 'r') as f: genesis_dat = json.load(f) self.assertTrue('GenesisId' in genesis_dat.keys()) head = genesis_dat['GenesisId'] # Verify genesis tool efficacy on a minimal network # Launch network (node zero will trigger bootstrapping) print('launching network...') for x in self._nodes: self._node_ctrl.start(x) # ...verify validator is extending tgt_block to = TimeOut(64) blk_lists = None prog_str = 'testing root extension (expect root: %s)' % head with Progress(prog_str) as p: print() while not to.is_timed_out() and blk_lists is None: try: blk_lists = get_blocklists(['http://localhost:8800']) print('block_lists: %s' % blk_lists) if len(blk_lists) < 1 or len(blk_lists[0]) < 2: blk_lists = None except MessageException as e: pass time.sleep(2) p.step() self.assertIsNotNone(blk_lists) root = blk_lists[0][0] self.assertEqual(head, root) # ...verify general convergence to = TimeOut(32) with Progress('testing root convergence') as p: print() while (is_convergent(self.urls, tolerance=1, standard=1) is False and not to.is_timed_out()): time.sleep(2) p.step() # ...verify convergence on the genesis block blk_lists = get_blocklists(['http://localhost:8800']) root = blk_lists[0][0] self.assertEqual(head, root) print('network converged on root: %s' % root) finally: print('destroying', str(self.__class__.__name__)) if hasattr(self, '_node_ctrl') and self._node_ctrl is not None: # Shut down the network with Progress("terminating network") as p: for node_name in self._node_ctrl.get_node_names(): self._node_ctrl.stop(node_name) to = TimeOut(16) while len(self._node_ctrl.get_node_names()) > 0: if to.is_timed_out(): break time.sleep(1) p.step() # force kill anything left over for node_name in self._node_ctrl.get_node_names(): try: print("%s still 'up'; sending kill..." % node_name) self._node_ctrl.kill(node_name) except Exception as e: print(e.message) self._node_ctrl.archive(self.__class__.__name__) self._node_ctrl.clean()
def do_cluster_start(args): state = load_state(start=True) # Check State for Running validators, if stopped clear out nodes. if state["DesiredState"] == "Stopped": state["Nodes"] = {} manage_type = DEFAULT_MANAGE if args.manage is None else args.manage if "Manage" not in state or state["DesiredState"] == "Stopped": state['Manage'] = manage_type elif args.manage is not None and state['Manage'] != args.manage\ and state["DesiredState"] == "Running": raise CliException('Cannot use two different Manage types.' ' Already running {}'.format(state["Manage"])) state["DesiredState"] = "Running" if state["Manage"] in TNG_MANAGE: if args.processors is None: raise CliException("Use -P to specify one or more processors") state['Processors'] = args.processors node_controller = get_node_controller(state, args) node_command_generator = SimpleNodeCommandGenerator() vnm = ValidatorNetworkManager( node_controller=node_controller, node_command_generator=node_command_generator) try: existing_nodes = vnm.get_node_names() except ManagementError as e: raise CliException(str(e)) # Check for runnings nodes. If found, raise exception with message to use # sawtooth cluster extend command to add nodes to running network. for i in xrange(0, args.count): node_name = "validator-{:0>3}".format(i) if node_name in existing_nodes and vnm.is_running(node_name): print("Already running: {}".format(node_name)) raise CliException("Please use 'sawtooth cluster extend'\ to add more nodes.") for i in xrange(0, args.count): node_name = "validator-{:0>3}".format(i) if node_name in existing_nodes and vnm.is_running(node_name): print("Already running: {}".format(node_name)) continue # genesis is true for the first node genesis = (i == 0) gossip_port = 5500 + i http_port = 8800 + i node_args = NodeArguments(node_name, http_port=http_port, gossip_port=gossip_port, genesis=genesis) if node_args.genesis is True: node_controller.create_genesis_block(node_args) print("Starting: {}".format(node_name)) node_command_generator.start(node_args) state["Nodes"][node_name] = { "Status": "Running", "Index": i, "HttpPort": str(http_port), "GossipPort": str(gossip_port) } save_state(state) try: vnm.update() except ManagementError as e: raise CliException(str(e)) node_names = state['Nodes'].keys() if state["Manage"] in SUBPROCESS_MANAGE: try: while True: time.sleep(128) except KeyboardInterrupt: print() ns = Namespace(cluster_command='stop', command='cluster', node_names=node_names, verbose=None) do_cluster_stop(ns)
def do_cluster_start(args): state = load_state(start=True) # Check State for Running validators, if stopped clear out nodes. if state["DesiredState"] == "Stopped": state["Nodes"] = {} if "Manage" not in state or state["DesiredState"] == "Stopped": if args.manage == "subprocess" or args.manage is None: state["Manage"] = "subprocess" elif args.manage == "docker": state["Manage"] = "docker" elif args.manage == "daemon": state["Manage"] = "daemon" elif args.manage == "docker-tng": state["Manage"] = "docker-tng" elif args.manage is not None and state['Manage'] != args.manage\ and state["DesiredState"] == "Running": raise CliException('Cannot use two different Manage types.' ' Already running {}'.format(state["Manage"])) state["DesiredState"] = "Running" if state["Manage"] == 'docker-tng': state['Processors'] = args.processors node_controller = get_node_controller(state, args) node_command_generator = SimpleNodeCommandGenerator() vnm = ValidatorNetworkManager( node_controller=node_controller, node_command_generator=node_command_generator) try: existing_nodes = vnm.get_node_names() except ManagementError as e: raise CliException(str(e)) for i in xrange(0, args.count): node_name = "validator-{:0>3}".format(i) if node_name in existing_nodes and vnm.is_running(node_name): print "Already running: {}".format(node_name) continue # genesis is true for the first node genesis = (i == 0) gossip_port = 5500 + i http_port = 8800 + i node_args = NodeArguments(node_name, http_port=http_port, gossip_port=gossip_port, genesis=genesis) if node_args.genesis is True: node_controller.create_genesis_block(node_args) print "Starting: {}".format(node_name) node_command_generator.start(node_args) state["Nodes"][node_name] = {"Status": "Running", "Index": i} save_state(state) try: vnm.update() except ManagementError as e: raise CliException(str(e)) if state["Manage"] == 'subprocess': try: while True: time.sleep(128) except KeyboardInterrupt: print ns = Namespace(cluster_command='stop', command='cluster', node_names=[], verbose=None) do_cluster_stop(ns)