def generate_root_ca(dir, gm=False): """[generate root cert] Arguments: dir {[path]} -- [root cert path] """ try: dir = os.path.abspath(dir) if gm: (status, result) = utils.getstatusoutput( 'bash ' + path.get_path() + '/scripts/ca/gm/cts.sh gen_chain_cert ' + dir) else: (status, result ) = utils.getstatusoutput('bash ' + path.get_path() + '/scripts/ca/cts.sh gen_chain_cert ' + dir) if status != 0: logger.warn( ' cts.sh failed! status is %d, output is %s, dir is %s.', status, result, dir) raise MCError( 'cts.sh failed! status is %d, output is %s, dir is %s.' % (status, result, dir)) logger.info(' cts.sh success! status is %d, output is %s, dir is %s.', status, result, dir) logger.info(' Generate root cert success, dir is %s', dir) consoler.info(' Generate root cert success, dir is %s' % dir) 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 push_package(dir, host, chain_id, version, meta, force = True): """push install package of one server Arguments: dir {string} -- package install dir host {string} -- server host chain_id {string} -- chain id version {string} -- chain version force {string} -- is push all node dir or not published Returns: [bool] -- success return True, if not False will return. """ # check if common dir exist. if not os.path.exists(dir + '/common'): logger.warn(' common dir is not exist, dir is %s, host is %s', dir, host) return False # check if host dir exist. if not os.path.exists(dir + '/' + host): logger.warn(' host dir is not exist, dir is %s, host is %s', dir, host) return False try: if meta.get_host_nodes(host): pass except MCError as me: # create dir on the target server ret = ansible.mkdir_module(host, ansible.get_dir() + '/' + chain_id) if not ret: return ret # push common package ret = ansible.copy_module(host, dir + '/common/', ansible.get_dir() + '/' + chain_id) if not ret: return ret if force: logger.debug(' force is set, push all package, chain_id is %s, chain_version is %s, host is %s',chain_id, version, host) # push host dir ret = ansible.copy_module(host, dir + '/' + host + '/', ansible.get_dir() + '/' + chain_id) if not ret: return ret else: # push node${index} dir in host dir not published hnd = HostNodeDirs(chain_id, version, host) for node_dir in hnd.get_node_dirs(): if meta.host_node_exist(host, node_dir): logger.info(' %s already published, skip', node_dir) continue logger.info(' publish nodedir, chain_id is %s, chain_version is %s, node is %s', chain_id, version, node_dir) # push host dir ret = ansible.copy_module(host, dir + '/' + host + '/' + node_dir, ansible.get_dir() + '/' + chain_id) if not ret: return ret logger.info('push package success, dir is %s, host is %s, chain_id is %s, chain_version is %s', dir, host, chain_id, version) return True
def unarchive_module(ip, src, dest): """[Using ansible.sh unarchive_module, compress files to the corresponding server and extract it] Arguments: ip {[string]} -- [corresponding server host ip] src {[string]} -- [files dir path] dest {[string]} -- [corresponding server dir path] Returns: [bool] -- [true or false] """ (status, result) = utils.getstatusoutput('bash ' + path.get_path() + '/scripts/ansible.sh unarchive ' + ip + ' ' + src + ' ' + dest) logger.debug('unarchive action , status %s, output %s' % (status, result)) if status: logger.warn('unarchive action failed, status %s' % (status)) consoler.warn(' ansible unarchive failed, host is %s, src is %s, dst is %s, status is %s, output is %s.', ip, src, dest, status, result) elif result.find('SUCCESS') == -1 and result.find('CHANGED') == -1: logger.warn('unarchive action failed, output %s' % (result)) consoler.warn(' ansible unarchive failed, host is %s, src is %s, dst is %s, status is %s, output is %s.', ip, src, dest, status, result) else: consoler.info(' ansible unarchive success, host is %s, src is %s, dst is %s.', ip, src, dest) return True return False
def copy_module(ip, src, dest): """[Using ansible.sh copy_module, push package to servers] Arguments: ip {string} -- corresponding server host ip src {string} -- files which push dest {string} -- corresponding server dir path Returns: bool -- true or false. """ (status, result) = utils.getstatusoutput('bash ' + path.get_path() + '/scripts/ansible.sh copy ' + ip + ' ' + src + ' ' + dest) logger.debug('copy action , status %s, output %s' % (status, result)) if status: logger.warn('copy action failed, status %s' % (status)) consoler.warn(' ansible copy failed, host is %s, src is %s, dst is %s, status is %s, output is %s.', ip, src, dest, status, result) elif result.find('SUCCESS') == -1 and result.find('CHANGED') == -1: consoler.warn(' ansible copy failed, host is %s, src is %s, dst is %s, status is %s, output is %s.', ip, src, dest, status, result) logger.warn('copy action failed, output %s' % (result)) else: consoler.info(' ansible copy success, host is %s, src is %s, dst is %s.', ip, src, dest) return True return False
def check_module(ip, dest): """Using ansible.sh check_module, check chain status Arguments: ip {string} -- corresponding server host ip dest {string} -- corresponding server dir path Returns: bool -- true or false """ (status, result) = utils.getstatusoutput('bash ' + path.get_path() + '/scripts/ansible.sh check ' + ip + ' ' + dest) logger.debug('check action , status %s, output %s' % (status, result)) if status: logger.warn('check action failed, status %s' % (status)) consoler.warn(' ansible check failed, host is %s, dst is %s, status is %s, output is %s.', ip, dest, status, result) elif result.find('SUCCESS') == -1 and result.find('CHANGED') == -1: logger.warn('check action failed, output %s' % (result)) consoler.warn(' ansible check failed, host is %s, dst is %s, status is %s, output is %s.', ip, dest, status, result) else: consoler.info(' ansible check success, host is %s, output is %s.', ip, result) return True return False
def parser(self): self.clear() if os.path.exists(self.cfg) and os.path.isfile(self.cfg): logger.info(' single config is %s', self.cfg) # resolve one config.json try: self.append(ConfigConf(self.cfg)) except Exception as e: logger.warn('parser cfg %s end exception, e is %s ', self.cfg, e) raise MCError(' parser config failed, invalid format, config is %s, exception is %s' % (self.cfg, e)) elif os.path.isdir(self.cfg): logger.info(' config dir is %s', self.cfg) # resolve dir, if not config.json goto next for c in os.listdir(self.cfg): try: logger.debug(' config dir is %s, config file is %s', self.cfg, c) cc = ConfigConf(self.cfg + '/' + c) chain = cc.get_chain() if not self.append(cc): cc = self.get_cc(chain) logger.error(' chain_id: %s and chain_version: %s duplicate, config is %s:%s', chain.get_id(), chain.get_version(), cc.get_cfg(), c) raise MCError(' chain_id: %s and chain_version: %s duplicate, config is %s:%s' % (chain.get_id(), chain.get_version(), cc.get_cfg(), c)) logger.debug(' append cc, cc is %s', cc) consoler.info(' parser config %s success, chain_id is %s, chain_version is %s', c, chain.get_id(), chain.get_version()) except Exception as e: consoler.error( ' \033[1;31m skip config %s, invalid config format parser failed, exception is %s \033[0m', c, e) logger.warn(' parser cfg %s end exception, e %s ', c, e) else: raise MCError(' invalid config, %s not exist' % self.cfg)
def init_ansible(hosts_conf, add_opr=False): try: if not os.path.exists(hosts_conf): raise MCError('hosts_conf not exisits! ') if add_opr: src = '/etc/ansible/hosts' dst = '/etc/ansible/hosts.bak' if not os.path.exists(src): raise MCError('/etc/ansible/hosts not exisits! ') os.rename(src, dst) f = open(src, 'w') f.close() for line in open(hosts_conf): line = line.strip() host_value = line.split() if len(host_value) != 4: raise Exception('hosts_conf type error ,host_line -> %s', host_value) user = host_value[0] ip = host_value[1] port = host_value[2] passwd = host_value[3] if not utils.valid_string(user): raise Exception( 'user type error ,user -> %s, host_line -> %s' % (user, host_value)) if not utils.valid_ip(ip): raise Exception('ip type error ,ip -> %s, host_line -> %s' % (ip, host_value)) if not utils.valid_port(int(port)): raise Exception( 'port type error ,port -> %s, host_line -> %s' % (port, host_value)) if not utils.valid_string(passwd): raise Exception( 'passwd type error ,passwd -> %s, host_line -> %s' % (passwd, host_value)) (status, result) = utils.getstatusoutput('bash ' + path.get_path() + '/scripts/ansible_init.sh' + ' ' + user + ' ' + ip + ' ' + port + ' ' + passwd) if status != 0: logger.warn( ' ansible_init failed! status is %d, output is %s.', status, result) raise MCError( 'ansible_init failed! status is %d, output is %s.' % (status, result)) result = [] result.append(ip) opr_tools.telnet_ansible(result) logger.info(' ansible_init success! status is %d, output is %s', status, result) except MCError as me: consoler.error(' \033[1;31m %s \033[0m', me) except Exception as e: consoler.error( ' \033[1;31m ansible_init failed! excepion is %s.\033[0m', e)
def publish_server(chain_id, chain_version, force=False): """publish one chain. Arguments: chain_id {string} -- chain id. chain_version {string} -- chain version. force {bool} """ chain = Chain(chain_id, chain_version) dir = chain.data_dir() if not os.path.isdir(dir): consoler.info( ' No build version exist for chain_id:%s chain_version:%s, do nothing.', chain_id, chain_version) logger.warn( ' No build version exist for chain_id:%s chain_version:%s, do nothing.', chain_id, chain_version) return mm = meta.Meta(chain_id) if force: # force is set, publish this chain again. mm.clear() mm.set_chain_version(chain_version) else: if mm.exist(): if chain_version != mm.get_chain_version(): consoler.error( ' \033[1;31m chain %s already publish %s version, if you want publish annother version, --force/-f need to be set.\033[0m ', chain_id, mm.get_chain_version()) return else: mm.set_chain_version(chain_version) consoler.info(' publish package for chain %s version %s begin.', chain_id, chain_version) for host in os.listdir(dir): if not utils.valid_ip(host): logger.debug(' skip, not invalid host_ip ' + host) continue ret = push_package(dir, host, chain_id, chain_version, mm, force) if ret: hp = HostPort(chain_id, chain_version, host) for node_dir, p in hp.get_ports().items(): logger.debug(' node_dir is %s, port is %s', node_dir, p) if not mm.host_node_exist(host, node_dir): mm.append(meta.MetaNode(host, p.get_rpc_port(), p.get_p2p_port(), p.get_channel_port(), node_dir)) consoler.info(' \t push package : %s success.', host) else: consoler.error(' \033[1;31m \t push package : %s failed. \033[0m', host) # record meta info, write meta.json file mm.write_to_file() consoler.info(' publish package for chain %s version %s end.', chain_id, chain_version)
def check_server(chain_id): """[Using scheck.sh check 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 check action, chain_id is %s', chain_id) return logger.info('check action, chain_id is ' + chain_id) consoler.info(' => check all node of chain %s', chain_id) for k in mm.get_nodes().keys(): logger.debug('host ip is ' + k) ansible.check_module(k, ansible.get_dir() + '/' + chain_id)
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 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 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 mkdir_module(ip, dest): """[Using ansible.sh mkdir_module create dictionary ] Arguments: ip {string} -- corresponding server host ip dest {string} -- dir path Returns: int -- success return True, else return False. """ (status, result) = utils.getstatusoutput('bash ' + path.get_path() + '/scripts/ansible.sh mkdir ' + ip + ' ' + dest) logger.debug('mkdir action , status %s, output %s' % (status, result)) if status: consoler.warn(' ansible mkdir failed, host is %s, dst is %s, status is %s, output is %s.', ip, dest, status, result) logger.warn('mkdir action failed, status %s, result %s ' % (status, result)) elif result.find('SUCCESS') == -1 and result.find('CHANGED') == -1: consoler.warn(' ansible mkdir failed, host is %s, dst is %s, status is %s, output is %s.', ip, dest, status, result) logger.warn('mkdir action failed, output %s' % (result)) else: return True return False
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. ')