def run_delete(cluster_id=None): if not cluster_id: cluster_id = config.get_cur_cluster_id() valid = cluster_util.validate_id(cluster_id) if not valid: logger.error('Invalid cluster id: {}'.format(cluster_id)) return if cluster_id not in cluster_util.get_cluster_list(): logger.error('Cluster not exist: {}'.format(cluster_id)) return cluster = Cluster() cluster.stop(force=True, reset=True) # delete cluster folder cli_cluster_path = config.get_path_of_cli(cluster_id)["cluster_path"] path_of_fb = config.get_path_of_fb(cluster_id) fb_cluster_path = path_of_fb["cluster_path"] props_path = path_of_fb['redis_properties'] key = 'sr2_redis_master_hosts' nodes = config.get_props(props_path, key, []) for node in nodes: client = get_ssh(node) cmd = [ 'rm -rf {};'.format(fb_cluster_path), 'rm -rf {}'.format(cli_cluster_path), ] ssh_execute(client=client, command=' '.join(cmd)) client.close() if config.get_cur_cluster_id() == cluster_id: cluster.use(-1)
def conf_restore(self, host, cluster_id, tag): logger.debug('Restore conf to cluster {}...'.format(cluster_id)) # prepare path_of_fb = config.get_path_of_fb(cluster_id) path_of_cli = config.get_path_of_cli(cluster_id) conf_path = path_of_fb['conf_path'] conf_backup_path = path_of_cli['conf_backup_path'] conf_backup_tag_path = path_join(conf_backup_path, tag) # restore conf client = get_ssh(host) net.copy_dir_to_remote(client, conf_backup_tag_path, conf_path) client.close() logger.debug('OK')
def conf_backup(self, host, cluster_id, tag): logger.info('Backup conf of cluster {}...'.format(cluster_id)) # prepare path_of_fb = config.get_path_of_fb(cluster_id) conf_path = path_of_fb['conf_path'] path_of_cli = config.get_path_of_cli(cluster_id) conf_backup_path = path_of_cli['conf_backup_path'] conf_backup_tag_path = path_join(conf_backup_path, tag) if not os.path.isdir(conf_backup_path): os.mkdir(conf_backup_path) # back up conf os.mkdir(conf_backup_tag_path) client = get_ssh(host) net.copy_dir_from_remote(client, conf_path, conf_backup_tag_path) client.close() logger.info('OK, {}'.format(tag))
def _installer(self): path_of_cli = config.get_path_of_cli(None) release_path = path_of_cli['release_path'] installer_list = os.listdir(release_path) installer_list = list( filter(lambda x: x != '.gitignore', installer_list)) installer_list.sort(reverse=True) for i, v in enumerate(installer_list): installer_list[i] = '\t({}) {}'.format(i, v) ''' Select installer [ INSTALLER LIST ] (1) tsr2-installer.bin.flashbase_v1.1.12.centos (2) tsr2-installer.bin.flashbase_v1.1.11.centos (3) tsr2-installer.bin.flashbase_v1.1.10.centos Please enter the number or the path of the installer you want to use ''' msg = [ 'Select installer', '[ INSTALLER LIST ]', '\n'.join(installer_list), '\n', 'Please enter the number or the path of the installer you want to use', ] '\n'.join(msg) t = '[ INSTALLER LIST ]\n{}\n'.format('\n'.join(installer_list)) name = ask( text= 'Please type installer. if you want another, type absolute path of installer.\n\n{}' .format(t), ) while True: if name in installer_list: break flag = os.path.exists(name) if flag: break name = ask(text='File not existed. Please confirm and type again') self._print('Ok, {}'.format(name)) return name
def installer(): ''' Select installer from list of '$FBPATH/releases' or input absolute path of file directly return installer path ''' logger.debug('ask installer') path_of_cli = config.get_path_of_cli(None) release_path = path_of_cli['release_path'] if not os.path.exists(release_path): os.mkdir(release_path) installer_list = os.listdir(release_path) installer_list = list(filter(lambda x: x != '.gitignore', installer_list)) installer_list.sort(reverse=True) # formatting msg formatted = [] for i, name in enumerate(installer_list): formatted.append(' ({index}) {name}'.format(index=i + 1, name=name)) msg = [ 'Select installer', '', ' [ INSTALLER LIST ]', '{}\n'.format('\n'.join(formatted)), 'Please enter the number or the path of the installer you want to use', "you can also add file in list by copy to '$FBPATH/releases/'", ] if not installer_list: msg = [ 'Select installer', '', ' [ INSTALLER LIST ]', ' (empty)\n\n' 'Please enter the path of the installer you want to use', "you can also add file in list by copy to '$FBPATH/releases/'", ] result = ask('\n'.join(msg)) while True: if installer_list and result.decode('utf-8').isdecimal(): # case: select in list result = int(result) - 1 if result in range(0, len(installer_list)): ret = path_join(release_path, installer_list[result]) logger.debug('Select insaller in list: {}'.format(ret)) logger.info('OK, {}'.format(installer_list[result])) return os.path.expanduser(ret) msg = [ 'Choose a number ', 'between 1 and {}'.format(len(installer_list)), ', please try again' ] logger.error(''.join(msg)) elif result.startswith(('~', '/')): # case: type path if os.path.isfile(os.path.expanduser(result)): logger.debug('Select insaller by path: {}'.format(result)) logger.info('OK, {}'.format(os.path.basename(result))) return os.path.expanduser(result) msg = [ "File not existed: '{}'".format(result), ', please try again' ] logger.error(''.join(msg)) else: msg = [ "Invalid input: '{}', ".format(result), "please try again", ] logger.error(''.join(msg)) result = ask('')
def _deploy(cluster_id, history_save): deploy_state = DeployUtil().get_state(cluster_id) if deploy_state == DEPLOYED: q = [ color.YELLOW, '(Watch out) ', 'Cluster {} is already deployed. '.format(cluster_id), 'Do you want to deploy again?', color.ENDC, ] yes = askBool(''.join(q), default='n') if not yes: logger.info('Cancel deploy.') return restore_yes = None current_time = strftime("%Y%m%d%H%M%s", gmtime()) cluster_backup_dir = 'cluster_{}_bak_{}'.format(cluster_id, current_time) conf_backup_dir = 'cluster_{}_conf_bak_{}'.format(cluster_id, current_time) tmp_backup_dir = 'cluster_{}_conf_bak_{}'.format(cluster_id, 'tmp') meta = [['NAME', 'VALUE']] path_of_fb = config.get_path_of_fb(cluster_id) conf_path = path_of_fb['conf_path'] props_path = path_of_fb['redis_properties'] cluster_path = path_of_fb['cluster_path'] path_of_cli = config.get_path_of_cli(cluster_id) conf_backup_path = path_of_cli['conf_backup_path'] tmp_backup_path = path_join(conf_backup_path, tmp_backup_dir) local_ip = config.get_local_ip() # ask installer installer_path = ask_util.installer() installer_name = os.path.basename(installer_path) meta.append(['installer', installer_name]) # ask restore conf if deploy_state == DEPLOYED: restore_yes = ask_util.askBool('Do you want to restore conf?') meta.append(['restore', restore_yes]) # input props hosts = [] if deploy_state == DEPLOYED: if restore_yes: meta += DeployUtil().get_meta_from_props(props_path) hosts = config.get_props(props_path, 'sr2_redis_master_hosts') else: if os.path.exists(tmp_backup_path): q = 'There is a history of modification. Do you want to load?' yes = ask_util.askBool(q) if not yes: shutil.rmtree(tmp_backup_path) if not os.path.exists(tmp_backup_path): shutil.copytree(conf_path, tmp_backup_path) tmp_props_path = path_join(tmp_backup_path, 'redis.properties') editor.edit(tmp_props_path, syntax='sh') meta += DeployUtil().get_meta_from_props(tmp_props_path) hosts = config.get_props(tmp_props_path, 'sr2_redis_master_hosts') else: props_dict = ask_util.props(cluster_id, save=history_save) hosts = props_dict['hosts'] meta += DeployUtil().get_meta_from_dict(props_dict) utils.print_table(meta) msg = [ 'Do you want to proceed with the deploy ', 'accroding to the above information?', ] yes = askBool(''.join(msg)) if not yes: logger.info("Cancel deploy.") return # check node status logger.info('Check status of hosts...') success = Center().check_hosts_connection(hosts, True) if not success: logger.error('There are unavailable host') return logger.debug('Connection of all hosts ok') success = Center().check_include_localhost(hosts) if not success: logger.error('Must include localhost') return # if pending, delete legacy on each hosts for host in hosts: if DeployUtil().get_state(cluster_id, host) == PENDING: client = get_ssh(host) command = 'rm -rf {}'.format(cluster_path) ssh_execute(client=client, command=command) client.close() # added_hosts = post_hosts - pre_hosts logger.info('Checking for cluster exist...') meta = [['HOST', 'STATUS']] added_hosts = set(hosts) if deploy_state == DEPLOYED: pre_hosts = config.get_props(props_path, 'sr2_redis_master_hosts') added_hosts -= set(pre_hosts) can_deploy = True for host in added_hosts: client = get_ssh(host) if net.is_exist(client, cluster_path): meta.append([host, color.red('CLUSTER EXIST')]) can_deploy = False continue meta.append([host, color.green('CLEAN')]) utils.print_table(meta) if not can_deploy: logger.error('Cluster information exist on some hosts.') return # if not force: # logger.error("If you trying to force, use option '--force'") # return # backup conf if deploy_state == DEPLOYED: Center().conf_backup(local_ip, cluster_id, conf_backup_dir) # backup cluster backup_hosts = [] if deploy_state == DEPLOYED: backup_hosts += set(pre_hosts) # if force: # backup_hosts += added_hosts for host in backup_hosts: cluster_path = path_of_fb['cluster_path'] client = get_ssh(host) Center().cluster_backup(host, cluster_id, cluster_backup_dir) client.close() # transfer & install logger.info('Transfer installer and execute...') for host in hosts: logger.info(host) client = get_ssh(host) cmd = 'mkdir -p {0} && touch {0}/.deploy.state'.format(cluster_path) ssh_execute(client=client, command=cmd) client.close() DeployUtil().transfer_installer(host, cluster_id, installer_path) DeployUtil().install(host, cluster_id, installer_name) # setup props if deploy_state == DEPLOYED: if restore_yes: tag = conf_backup_dir else: tag = tmp_backup_dir Center().conf_restore(local_ip, cluster_id, tag) else: key = 'sr2_redis_master_hosts' config.make_key_enable(props_path, key) config.set_props(props_path, key, props_dict['hosts']) key = 'sr2_redis_master_ports' config.make_key_enable(props_path, key) value = cluster_util.convert_list_2_seq(props_dict['master_ports']) config.set_props(props_path, key, value) key = 'sr2_redis_slave_hosts' config.make_key_enable(props_path, key) config.set_props(props_path, key, props_dict['hosts']) config.make_key_disable(props_path, key) if props_dict['replicas'] > 0: key = 'sr2_redis_slave_hosts' config.make_key_enable(props_path, key) key = 'sr2_redis_slave_ports' config.make_key_enable(props_path, key) value = cluster_util.convert_list_2_seq(props_dict['slave_ports']) config.set_props(props_path, key, value) key = 'ssd_count' config.make_key_enable(props_path, key) config.set_props(props_path, key, props_dict['ssd_count']) key = 'sr2_redis_data' config.make_key_enable(props_path, key, v1_flg=True) config.make_key_enable(props_path, key, v1_flg=True) config.make_key_disable(props_path, key) config.set_props(props_path, key, props_dict['prefix_of_rdp']) key = 'sr2_redis_db_path' config.make_key_enable(props_path, key, v1_flg=True) config.make_key_enable(props_path, key, v1_flg=True) config.make_key_disable(props_path, key) config.set_props(props_path, key, props_dict['prefix_of_rdbp']) key = 'sr2_flash_db_path' config.make_key_enable(props_path, key, v1_flg=True) config.make_key_enable(props_path, key, v1_flg=True) config.make_key_disable(props_path, key) config.set_props(props_path, key, props_dict['prefix_of_fdbp']) # synk props logger.info('Sync conf...') for node in hosts: if socket.gethostbyname(node) in config.get_local_ip_list(): continue client = get_ssh(node) if not client: logger.error("ssh connection fail: '{}'".format(node)) return net.copy_dir_to_remote(client, conf_path, conf_path) client.close() # set deploy state complete if os.path.exists(tmp_backup_path): shutil.rmtree(tmp_backup_path) for node in hosts: home_path = net.get_home_path(node) if not home_path: return path_of_fb = config.get_path_of_fb(cluster_id) cluster_path = path_of_fb['cluster_path'] client = get_ssh(node) command = 'rm -rf {}'.format(path_join(cluster_path, '.deploy.state')) ssh_execute(client=client, command=command) client.close() logger.info('Complete to deploy cluster {}'.format(cluster_id)) Cluster().use(cluster_id)