def expand_host_dir(chain, node, port, fisco): """expand install pacakge of the server. Arguments: chain {Chain} -- chain info, chain id and chain version. node {Node} -- node info. port {Port} -- port info. Raises: Exception -- exception description """ logger.info(' chain is %s, node is %s, port is %s', chain, node, port) h = HostNodeDirs(chain.get_id(), chain.get_version(), node.get_host_ip()) index = h.get_max_index() append_host_dir = False if not h.exist(): h.create() append_host_dir = True logger.info(' append host dir, chain is %s, node is %s, index is %s.', chain, node, index) else: logger.info(' append node dir, chain is %s, node is %s, index is %s.', chain, node, index) try: # create node dir for i in range(node.get_node_num()): build_node_dir(chain, node, fisco, port.to_port(i), index + i + 1) except Exception as e: logger.error( ' expand operation failed, chain is %s, node is %s, append_host is %s, e is %s ', chain, node, append_host_dir, e) # Delete the created folder if append_host_dir: h.remove() else: for i in range(node.get_node_num()): # remove node dir node_dir = chain.data_dir() + '/' + node.get_host_ip( ) + '/' + str(index + i) if os.path.exists(node_dir): shutil.rmtree(node_dir) # raise exception again raise e logger.info(' expand_host_dir end.')
def start_server(chain_id): """[Using start.sh start all nodes of a chain] Arguments: chain_id {[string]} -- [chain_id:version] """ mm = Meta(chain_id) if not mm.exist(): logger.warn( 'chain meta is not exist, maybe the chain is not published, chain_id is %s', chain_id) consoler.warn( 'chain is not published, can not start action, chain_id is %s', chain_id) return logger.info('start action, chain_id is ' + chain_id) consoler.info(' => start all node of chain %s', chain_id) for k in mm.get_nodes().keys(): logger.debug('host ip is ' + k) ansible.start_module(k, ansible.get_dir() + '/' + chain_id)
def check_java(self): cmd = 'java -version' status, output = utils.getstatusoutput(cmd) if status != 0: logger.error(' java -version failed , status is %d, output is %s', status, output) raise MCError(' java -version failed , java not installed.') version_str = output.split("\"") if not len(version_str) > 1: logger.error( ' cannot get java version, status is %d, output is %s', status, output) raise MCError( ' cannot get java version, oracle jdk need >=1.8 or openjdk need >= 1.9, please try \'java -version\'. ' ) version_arr = version_str[1].split('.') if not len(version_arr) > 2: logger.error( ' cannot get java version, status is %d, output is %s', status, output) raise MCError( ' cannot get java version, oracle jdk need >=1.8 or openjdk need >= 1.9, please try \'java -version\' ' ) self.major = version_arr[0] self.minor = version_arr[1] if output.lower().find('openjdk') != -1: self.openjdk = True else: self.openjdk = False if not self.is_suitable(): raise MCError( ' invalid java version, oracle jdk need >=1.8 or openjdk need >= 1.9, now %s ' % self) logger.info(' java version is %s ', self)
def generator_node_ca(agent, dir, node, gm=False): """[generate node cert ] Arguments: agent {[path]} -- [agency cert path] node {[string]} -- [node name] dir {[path]} -- [node cert path] """ _dir = os.path.abspath(dir) agent = os.path.abspath(agent) try: if gm: (status, result ) = utils.getstatusoutput('bash ' + path.get_path() + '/scripts/ca/gm/cts.sh gen_node_cert ' + agent + ' ' + _dir + '/ ' + node) else: (status, result ) = utils.getstatusoutput('bash ' + path.get_path() + '/scripts/ca/cts.sh gen_node_cert ' + agent + ' ' + _dir + '/ ' + node) if not status: logger.info(' Generate %s cert successful! dir is %s.', node, _dir + '/' + node) else: consoler.error( ' \033[1;31m Generate node cert failed! Please check your network, and try to check your opennssl version.\033[0m' ) logger.error(' Generate %s cert failed! Result is %s' % (node, result)) raise MCError(' Generate %s cert failed! Result is %s' % (node, result)) except MCError as me: consoler.error(' \033[1;31m %s \033[0m', me) except Exception as e: consoler.error( ' \033[1;31m Generate root cert failed! excepion is %s.\033[0m', e) logger.error(' Generate root cert failed! Result is %s' % result)
def pub_list(chains): """[List the nodes in package corresponding to the --publishi chain:version] Arguments: chains {[list]} -- [chain id] """ logger.info('list begin, chains is %s', chains) consoler.info(' chains is %s' % chains) ns = Names() meta_list = [] if chains[0] == 'all': dir = data.meta_dir_base() if os.path.exists(dir): for chain_id in os.listdir(dir): m = Meta(chain_id) if not m.empty(): meta_list.append(m) else: consoler.info(' No published chain exist, do nothing.') else: for chain_id in chains: m = Meta(chain_id) if not m.empty(): meta_list.append(m) for m in meta_list: consoler.info( ' => chain id :%s chain name : %s published version : %s', m.get_chain_id(), ns.get_name(m.get_chain_id()), m.get_chain_version()) nodes = m.get_nodes() for host, nodes in nodes.items(): consoler.info('\t host => %s', host) for node in nodes: consoler.info('\t\t node => %s', node.get_node()) logger.info('list end.')
def generator_agent_ca(dir, ca, agent, gm=False): """[generate agency cert] Arguments: dir {[path]} -- [agency cert path] ca {[path]} -- [root cert path] agent {[string]} -- [agency name] """ try: ca = os.path.abspath(ca) dir = os.path.abspath(dir) if gm: (status, result) = utils.getstatusoutput( 'bash ' + path.get_path() + '/scripts/ca/gm/cts.sh gen_agency_cert ' + ca + ' ' + dir + ' ' + agent) else: (status, result ) = utils.getstatusoutput('bash ' + path.get_path() + '/scripts/ca/cts.sh gen_agency_cert ' + ca + ' ' + dir + ' ' + agent) if not status: logger.info(' Generate %s cert successful! dir is %s.' % (agent, dir + '/' + agent)) else: consoler.error( ' \033[1;31m Generate %s cert failed! Please check your network, and try to check your opennssl version.\033[0m' ) logger.error(' Generate %s cert failed! Result is %s' % (agent, result)) raise MCError(' Generate %s cert failed! Result is %s' % (agent, result)) except MCError as me: consoler.error(' \033[1;31m %s \033[0m', me) except Exception as e: consoler.error( ' \033[1;31m Generate root cert failed! excepion is %s.\033[0m', e) logger.error(' Generate root cert failed! Result is %s' % result)
def diagnose_server(chain_id): """[Using diagnose.sh diagnose all nodes of a chain] Arguments: chain_id {[string]} -- [chain_id:version] """ mm = Meta(chain_id) if not mm.exist(): logger.warn( 'chain meta is not exist, maybe the chain is not published, chain_id is %s', chain_id) consoler.warn( ' chain is not published, can not diagnose action, chain_id is %s', chain_id) return consoler.info(' ==> diagnose chain %s', chain_id) logger.info('diagnose_server action, chain_id is ' + chain_id) for k in mm.get_nodes().keys(): logger.debug('host ip is ' + k) ansible.diagnose_module(k, ansible.get_dir() + '/' + chain_id)
def load(self): self.clear() host_dir = Chain(self.chain_id, self.chain_version).data_dir() + '/' + self.host + '/' if not os.path.exists(host_dir): logger.info( ' host dir not exist, chain_id is %s, chain_version is %s, host is %s', self.chain_id, self.chain_version, self.host) return logger.debug( 'load begin, chain_id is %s, chain_version is %s, host is %s', self.chain_id, self.chain_version, self.host) for list_dir in os.listdir(host_dir): if 'node' in list_dir: self.node_dirs.append(list_dir) index = int(list_dir[4:]) if index > self.max_index: self.max_index = index logger.debug(' append node%d, dir is %s', index, list_dir) logger.info(' load end, info %s', self)
def write_to_file(self): #if len(self.nodes) == 0: # logger.debug('nodes empty, write return') # return if not data.meta_dir_exist(self.chain_id): data.create_meta_dir(self.chain_id) meta_file = data.meta_dir(self.chain_id) + '/meta.json' meta_bak_file = meta_file + '_bak_' + \ time.strftime("%Y-%m-%d_%H-%M%S", time.localtime()) if os.path.exists(meta_file): shutil.copy(meta_file, meta_bak_file) logger.info( 'meta.json is exist, backup it, name is ' + meta_bak_file) try: with open(data.meta_dir(self.chain_id) + '/meta.json', "w+") as f: f.write(self.to_json()) logger.info( 'write info meta.json, content is ' + self.to_json()) except Exception as e: logger.error( ' write meta failed, chaind id is %s, exception is %s', self.chain_id, e) # raise or not ??? raise MCError(' write meta.json failed, chain id is %s, exception is %s' % (self.chain_id, e))
def load(self): self.clear() if not self.exist(): logger.info('dir not exist, chain_id is %s, chain_version is %s', self.chain_id, self.chain_version) return dir = self.chain.data_dir() logger.debug( 'load begin, chain_id is %s, chain_version is %s, dir is %s', self.chain_id, self.chain_version, dir) for host in os.listdir(dir): if utils.valid_ip(host): self.append(host) logger.debug(' chain id %s, chain version %s, host is %s', self.chain_id, self.chain_version, host) else: logger.debug( ' skip, not invalid host_ip, chain id is %s, chain version is %s, host is %s', self.chain_id, self.chain_version, host) logger.info('load end, len is %d', len(self.get_pkg_list()))
def build_host_dir(chain, node, port, fisco, temp=None): """build install pacakge of one server. Arguments: chain {Chain} -- chain info, chain id and chain version. node {Node} -- node info. port {Port} -- port info. fisco {Fisco} -- fisco info. temp {Temp} -- temp node, if temp is not None, register the node info to the node manager info. Raises: Exception -- exception description """ logger.info('chain => %s, node => %s, port => %s', chain, node, port) host_dir = chain.data_dir() + '/' + node.get_host_ip() if os.path.exists(host_dir): logger.warn('%s dir already exist, chain is %s', node.get_host_ip(), chain) return os.makedirs(host_dir) for index in range(node.get_node_num()): # create dir for every node on the server build_node_dir(chain, node, fisco, port.to_port(index), index) # register node info to node manager contract if not temp is None: if fisco.is_gm(): temp.register(host_dir + ('/node%d' % index) + '/data/gmnode.json') else: temp.register(host_dir + ('/node%d' % index) + '/data/node.json') logger.info('build_host_dir end.')
def export(self): try: if self.fisco.is_gm(): shutil.move(get_gm_god_path() + '/godInfo.txt', get_gm_god_path() + '/godInfo.txt.bak') cmd = self.fisco.get_fisco_path() + ' --newaccount ' + get_gm_god_path() + '/godInfo.txt' status, result = utils.getstatusoutput(cmd) logger.debug(' start status, status is %d, output is %s', status, result) else: shutil.move(get_god_path() + '/godInfo.txt', get_god_path() + '/godInfo.txt.bak') cmd = self.fisco.get_fisco_path() + ' --newaccount ' + get_god_path() + '/godInfo.txt' status, result = utils.getstatusoutput(cmd) logger.debug(' start status, status is %d, output is %s', status, result) if status != 0: logger.warn(' export godInfo.txt failed! status is %d, output is %s.', status, result) raise MCError('godInfo.txt failed! status is %d, output is %s.' % (status, result)) logger.info(' export godInfo.txt status is %d, output is %s.', status, result) consoler.info(' export godInfo.txt success') except MCError as me: consoler.error(' \033[1;31m %s \033[0m', me) except Exception as e: consoler.error(' \033[1;31m export godInfo.txt failed! excepion is %s.\033[0m', e) logger.error(' export godInfo.txt failed!')
def init_ca(cert_path): """[init users' agenct ca] Arguments: cert_path {[dir]} -- [usrs' cert path] Raises: Exception -- [normal error] Returns: [bool] -- [true or flase] """ if check_ca_exist(cert_path) and check_agent_ca_exist(cert_path): shutil.copytree(cert_path, get_ca_path()) logger.info("Init cert, copy cert to cert_path") elif check_gmca_exist(cert_path) and check_agent_gmca_exist(cert_path): shutil.copytree(cert_path, get_GM_ca_path()) logger.info("Init gm cert, copy gm cert to cert_path") else: logger.error("Init cert failed! files not completed") raise Exception("Init cert failed! files not completed") return 0
def port_conflicts_inside_chain(self, host, port, chain_id, chain_version): hps = self.get_all_ports_by_host(host) for hp in hps: if (not (chain_id == hp.get_chain_id() and chain_version == hp.get_chain_version())): continue for node in hp.get_ports().values(): if port.in_use(node.get_rpc_port()): logger.info( ' rpc port(%s) used by annother chain, host is %s, chain id is %s, chain version is %s, port is %s', str(node.get_rpc_port()), host, hp.get_chain_id(), hp.get_chain_version(), port) raise MCError( ' rpc port(%s) used by annother chain, host is %s, chain id is %s, chain version is %s, port is %s' % (str(node.get_rpc_port()), host, hp.get_chain_id(), hp.get_chain_version(), port)) if port.in_use(node.get_p2p_port()): logger.info( ' p2p port(%s) used by annother chain, host is %s, chain id is %s, chain version is %s, port is %s', str(node.get_p2p_port()), host, hp.get_chain_id(), hp.get_chain_version(), port) raise MCError( ' p2p port(%s) used by annother chain, host is %s, chain id is %s, chain version is %s, port is %s' % (str(node.get_p2p_port()), host, hp.get_chain_id(), hp.get_chain_version(), port)) if port.in_use(node.get_channel_port()): logger.info( ' channel port(%s) used by annother chain, host is %s, chain id is %s, chain version is %s, port is %s', str(node.get_channel_port()), host, hp.get_chain_id(), hp.get_chain_version(), port) raise MCError( ' channel port(%s) used by annother chain, host is %s, chain id is %s, chain version is %s, port is %s' % (str(node.get_channel_port()), host, hp.get_chain_id(), hp.get_chain_version(), port))
def parser(self): ''' resolve config.conf, return object[Config.conf] ''' cfg = self.cfg logger.info('cfg parser %s', cfg) # read and parser config file cf = configparser.ConfigParser() with codecs.open(cfg, 'r', encoding='utf-8') as f: cf.readfp(f) chain_id = cf.get('chain', 'chainid') if not utils.valid_string(chain_id): raise Exception('chain_id empty.') if not utils.valid_chain_id(chain_id): raise Exception('invalid chain_id, ', chain_id) chain_version = cf.get('chain', 'version') if not utils.valid_string(chain_id): raise Exception('chain_version empty.') chain_name = str(chain_id) try: chain_name = cf.get('chain', 'chainname') if not utils.valid_string(chain_name): chain_name = str(id) except Exception as e: pass self.set_chain(Chain(chain_id, chain_version, chain_name)) rpc_port = cf.getint('ports', 'rpc_port') if not utils.valid_port(rpc_port): raise Exception('invalid rpc_port, ', rpc_port) p2p_port = cf.getint('ports', 'p2p_port') if not utils.valid_port(p2p_port): raise Exception('invalid p2p_port, ', p2p_port) channel_port = cf.getint('ports', 'channel_port') if not utils.valid_port(channel_port): raise Exception('invalid channel_port, ', channel_port) port = Port(rpc_port, p2p_port, channel_port) if port.check_port(): raise Exception('port config dup, ', port) self.set_port(port) index = 0 while True: try: n = NodeEle(cf.get('pkgs', 'pkg%u' % index)) index += 1 n.do_parser() except Exception as e: logger.info('cfg parser end, e is %s, result is %s', e, self) break else: if not self.add_node(n): raise Exception(' duplicate host ip, host is ', n.get_host_ip()) if len(self.get_nodes()) == 0: raise Exception('invalid cfg format, nodes empty') logger.info('cfg parser end, result is %s', self)
def opr_god(fisco_path): logger.info('god start.') opr_god = god.God(fisco_path) opr_god.export() opr_god.replace() logger.info('god end.')
def build_node_dir(chain, node, fisco, port, index): """create node${index} dir. Arguments: chain {Chain} -- chain info node {Node} -- node info fisco {Fisco} -- fisco info port {Port} -- port info index {int} -- index info Raises: Exception -- exception description one node directory structure is as: node${index}/ ├── config.json ├── genesis.json ├── data ├── log ├── log.conf ├── start.sh └── stop.sh ├── check.sh """ logger.info('chain is %s, node is %s, index is %s', chain, node, index) node_dir = chain.data_dir() + '/' + node.get_host_ip() + \ '/node' + str(index) + '/' if os.path.exists(node_dir): logger.warn(' skip, node%d already exist, chain is %s, node is %s', index, chain, node) return os.makedirs(node_dir) shutil.copy(path.get_path() + '/tpl/log.conf', node_dir) shutil.copy(path.get_path() + '/scripts/node/node_start.sh', node_dir + '/start.sh') shutil.copy(path.get_path() + '/scripts/node/node_stop.sh', node_dir + '/stop.sh') shutil.copy(path.get_path() + '/scripts/node/node_check.sh', node_dir + '/check.sh') shutil.copy(path.get_path() + '/scripts/node/node_diagnose.sh', node_dir + '/diagnose.sh') cfg = Config(chain.get_id(), port.get_rpc_port(), port.get_p2p_port(), port.get_channel_port(), fisco.is_gm()) cfg.writeFile(node_dir + '/config.json') os.makedirs(node_dir + '/data') os.makedirs(node_dir + '/log') # copy bootstrapnodes.json、genesis.json to correspond dir if os.path.exists(chain.data_dir() + '/bootstrapnodes.json'): shutil.copy(chain.data_dir() + '/bootstrapnodes.json', node_dir + '/data') if os.path.exists(chain.data_dir() + '/genesis.json'): shutil.copy(chain.data_dir() + '/genesis.json', node_dir + '/') if fisco.is_gm(): ca.generator_node_ca(ca.get_GM_agent_path(), node_dir + '/data', 'node' + str(index), True) shutil.copytree(ca.get_GM_agent_path() + '/sdk', node_dir + '/data/sdk') shutil.copy(ca.get_GM_agent_path() + '/sdk/ca.crt', node_dir + '/data/') shutil.copy(ca.get_GM_agent_path() + '/sdk/ca.key', node_dir + '/data/') shutil.copy(ca.get_GM_agent_path() + '/sdk/server.crt', node_dir + '/data/') shutil.copy(ca.get_GM_agent_path() + '/sdk/server.key', node_dir + '/data/') else: ca.generator_node_ca(ca.get_agent_ca_path(), node_dir + '/data', 'node' + str(index)) logger.info(' build_node_dir end. ')
def build(cc, fisco): """build all install package for one chain base on cc Arguments: cc {ConfigConf} -- ConfigConf object fisco {Fisco} -- Fisco object Raises: Exception -- exception description """ logger.info('building, cc is %s, fisco is %s', cc, fisco) port = cc.get_port() chain = cc.get_chain() chain_id = chain.get_id() chain_version = chain.get_version() # create dir base on version of the chain. if os.path.isdir(chain.data_dir()): raise MCError('chain_id:%s chain_version:%s aleady exist !!!.' % (chain_id, chain_version)) try: temp = None acp = AllChainPort() # port check for node in cc.get_nodes(): for index in range(node.get_node_num()): # create dir for every node on the server acp.port_conflicts_outside_chain(chain.get_id(), node.get_host_ip(), port.to_port(index)) dir = chain.data_dir() os.makedirs(dir) # generate bootstrapsnode.json cc.to_p2p_nodes().writeFile(dir + '/bootstrapnodes.json') # create common dir build_pkg.build_common_dir(chain, fisco) # build and start temp node for node info register temp = Temp(chain, fisco, port) # build install dir for every server for node in cc.get_nodes(): build_pkg.build_host_dir(chain, node, port, fisco, temp) # export for genesis.json file temp.export() temp.clean() # copy genesis.json bootstrapnodes.json for node in cc.get_nodes(): for index in range(node.get_node_num()): shutil.copy( dir + '/genesis.json', dir + '/' + node.get_host_ip() + '/node' + str(index)) # web3sdk conf web3_conf_by_chain(chain, fisco.is_gm()) logger.info(' build end ok, chain is %s', chain) except Exception as e: if not temp is None: temp.clean() if os.path.exists(dir): shutil.rmtree(dir) raise MCError( ' build package for chain %s version %s failed, exception is %s' % (chain_id, chain_version, e))