def create_res_manual(self, res, size, node, sp): dict_all_fail = {} dict_args = self.collect_args(node,sp) if self.linstor_create_rd(res) is True and self.linstor_create_vd(res, size) is True: pass else: s.prt_log('The resource already exists',1) return ('The resource already exists') for node_one,sp_one in dict_args.items(): dict_one_result = self.execute_create_res(res,node_one,sp_one) dict_all_fail.update(dict_one_result) if len(dict_all_fail.keys()) == len(node): self.linstor_delete_rd(res) if len(dict_all_fail.keys()): fail_info = (f"Creation failure on {' '.join(dict_all_fail.keys())}\n") for node, cause in dict_all_fail.items(): fail_cause = f"{node}:{cause}\n" fail_info = fail_info + fail_cause s.prt_log(fail_info,2) return dict_all_fail else: return True
def sycn_data(self, args): # 添加前置检查 obj_crm = CRMData() js = iscsi_json.JsonOperation() # 获取数据 vip = obj_crm.get_vip() portblock = obj_crm.get_portblock() order = obj_crm.get_order() colocation = obj_crm.get_colocation() target = obj_crm.get_target() iscsilogicalunit = obj_crm.get_iscsi_logical_unit() # 检查 obj_crm.check_portal_component(vip, portblock, order, colocation) portal = obj_crm.get_conf_portal(vip,portblock,target) js.cover_data('Portal',portal) target = obj_crm.get_conf_target(vip,target,iscsilogicalunit) js.cover_data('Target',target) logical = obj_crm.get_conf_lun(target,iscsilogicalunit) js.cover_data('LogicalUnit',logical) js.commit_data() sd.prt_log('Configuration file data update completed', 1)
def delete_res(self, res, type): # 删除一个crm res,完整的流程 if self.stop_res(res): if self.monitor_status(res, type, 'Stopped'): if self.execute_delete(res): return True s.prt_log(f"Delete {res} fail", 1)
def check_and_get_size(self, data, size, type): """ 计算创建thinpool的可用空间大小,与用户输入的大小值进行比较 data: vg_name or list device size: the size that user input type: vg or device """ real_size = 0 if type == "vg": real_size = real_size + int(self.get_vg_free_pe(data)) * 4 - ( math.ceil((int(self.get_vg_free_pe(data)) * 4) / 4096) * 8) if type == "device": real_size = self.get_device_size(data) real_size = real_size - 4 - (math.ceil(real_size / 4096) * 8) available_size = real_size - 4 if available_size <= 0: s.prt_log("No available space.", 2) if size: size = size_conversion(size) if size <= available_size: return size else: s.prt_log( f"The size that you input is out of the actual available range (0,{available_size}M]", 2) else: return available_size
def delete(self, name): obj_crm = CRMConfig() result = obj_crm.delete_res(name, type='iSCSITarget') if not result: raise consts.CmdError else: s.prt_log(f'Delete iSCSITarget:{name} successfully', 0) return True
def stop_res(self, res): # 执行停用res cmd = f'crm res stop {res}' result = execute_crm_cmd(cmd) if result['sts']: return True else: s.prt_log(f"Stop {res} fail", 1)
def delete_vg(self, vg): if not self.check_vg(vg): pv_dict = self.get_pv_via_vg(vg) if self.del_vg(vg): for pv in pv_dict.keys(): self.del_pv(pv) else: s.prt_log(f"{vg} is in used", 1)
def modify_portal(self, name, ip, port): cmd = f'crm cof set {name}.portals {ip}:{port}' cmd_result = execute_crm_cmd(cmd) if not cmd_result['sts']: s.prt_log(cmd_result['rst'], 1) raise consts.CmdError else: s.prt_log(f"Modify iSCSITarget:{name} (portal) successfully", 0) return True
def modify(self, args): crm = ex.CRMData() crm.check() if any([args.ip, args.port, args.netmask]): portal = ex.Portal() portal.modify(args.portal, args.ip, args.port, args.netmask) else: s.prt_log('Please specify at least one data to be modified', 1)
def show_all_sp(self,no_color='no'): collector = linstordb.CollectData() if no_color == 'no': data = s.deco_color(collector.get_all_sp)() else: data = collector.get_all_sp() header = ['stp_name','node_name','res_num','driver','pool_name','free_size','total_size','snapshots','status'] table = s.make_table(header, data) s.prt_log(table,0)
def show_all_node(self, no_color='no'): collecter = linstordb.CollectData() if no_color == 'no': data = s.deco_color(collecter.get_all_node)() else: data = collecter.get_all_node() header = ["node", "node type", "res num", "stp num", "addr", "status"] table = s.make_table(header, data) s.prt_log(table,0)
def show_all_res(self,no_color='no'): collecter = linstordb.CollectData() if no_color == 'no': data = s.deco_color(collecter.get_all_res)() else: data = collecter.get_all_res() header = ["resource", "mirror_way", "size", "device_name", "used"] table = s.make_table(header,data) s.prt_log(table,0)
def modify_iqn(self, name, iqn): cmd = f'crm conf set {name}.iqn {iqn}' cmd_result = execute_crm_cmd(cmd) if not cmd_result['sts']: s.prt_log(cmd_result['rst'], 1) raise consts.CmdError else: s.prt_log(f"Modify iSCSITarget:{name} (iqn) successfully", 0) return True
def __init__(self): self.crm_conf_data = self.get_crm_conf() self.vip = None self.portblock = None self.target = None if 'ERROR' in self.crm_conf_data: s.prt_log("Could not perform requested operations, are you root?", 2) self.crm_st = None
def modify_target_iqn(self, name, target_iqn): # 适用于target_iqn只有一个的情况(一个target只使用一个portal) cmd = f"crm config set {name}.target_iqn \"{target_iqn}\"" result = execute_crm_cmd(cmd) if result['sts']: s.prt_log(f"Modify the target iqn of {name} successfully", 0) return True else: s.prt_log(result['rst'], 1) raise consts.CmdError
def create(self, name, iqn, ip, port): cmd = f'crm cof primitive {name} iSCSITarget params iqn="{iqn}" implementation=lio-t portals="{ip}:{port}" op start timeout=50 stop timeout=40 op monitor interval=15 timeout=40 meta target-role=Stopped' cmd_result = execute_crm_cmd(cmd) if not cmd_result['sts']: # 创建失败,输出原命令报错信息 s.prt_log(cmd_result['rst'], 1) raise consts.CmdError else: # s.prt_log(f'Create iscsitarget:{name} successfully',0) return True
def create(cls, name, target1, target2): cmd = f'crm cof order {name} {target1} {target2}' cmd_result = execute_crm_cmd(cmd) if not cmd_result['sts']: # 创建失败,输出原命令报错信息 s.prt_log(cmd_result['rst'], 1) raise consts.CmdError else: s.prt_log(f'Create order:{name} successfully', 0) return True
def test_prt_log(): """打印语句并记录log""" with patch('builtins.print') as terminal_print: sundry.prt_log('test_prt_log', 0) terminal_print.assert_called_with('test_prt_log') with pytest.raises(SystemExit) as exsinfo: with patch('builtins.print') as terminal_print: sundry.prt_log('test_prt_log', 2) terminal_print.assert_called_with('test_prt_log') assert exsinfo.type == SystemExit
def del_pv(self, name): """删除PV""" cmd = f"pvremove {name} -y" result = utils.exec_cmd(cmd, self.conn) if result["st"]: s.prt_log(f"Success in deleting PV: {name}", 0) return True else: s.prt_log(f"Failed to delete PV {name}", 1) return False
def get_pv_via_vg(self, vg): """通过VG名获取对应的PV""" pv_dict = {} if self.pv_list: for pv in self.pv_list: if pv[1] == vg: pv_dict[pv[0]] = pv[2] if not pv_dict: s.prt_log(f"{vg} is not vg resource", 2) return pv_dict
def create_thinlv(self, name, size, vg, thinpool): """创建thinlv""" cmd = f"lvcreate -V {size} -n {name} {vg}/{thinpool} -y" result = utils.exec_cmd(cmd, self.conn) if result["st"]: s.prt_log(f"Success in createing Thin LV: {name}", 0) return True else: s.prt_log(f"Failed to create Thin LV {name}", 1) return False
def create_lv(self, name, size, vg): """创建lv""" cmd = f"lvcreate -n {name} -L {size} {vg} -y" result = utils.exec_cmd(cmd, self.conn) if result["st"]: s.prt_log(f"Success in createing LV: {name}", 0) return True else: s.prt_log(f"Failed to create LV: {name}", 1) return False
def create_pv(self, device): """创建pv""" cmd = f"pvcreate {device} -y" result = utils.exec_cmd(cmd, self.conn) if result["st"]: s.prt_log(f"Success in createing PV: {device}", 0) return True else: s.prt_log(f"Failed to create PV {device}", 1) return False
def check_portal_component(self, vip, portblock, order, colocation): """ 对目前环境的portal组件(ipaddr,portblock)的检查,需满足: 1.不存在单独的portblock/vip 2.已存在的ipaddr,必须有对应的portblock组(block,unblock)以及对应的order和colocation 不满足条件时提示并退出 :param vip_all: dict :param portblock_all: dict :return:None """ dict_portal = {} list_normal_portblock = [] for vip_name, vip_data in list(vip.items()): dict_portal.update({vip_name: {}}) #error/normal for pb_name, pb_data in list(portblock.items()): if vip_data['ip'] == pb_data['ip']: dict_portal[vip_name].update({pb_name: pb_data['type']}) list_normal_portblock.append(pb_name) if len(dict_portal[vip_name]) == 2: if 'block' and 'unblock' in dict_portal[vip_name].values(): dict_portal[vip_name] = { pb_type: pb for pb, pb_type in dict_portal[vip_name].items() } for ord_name, ord_data in list(order.items()): if [dict_portal[vip_name]['block'], vip_name] == ord_data: # 这里没考虑符合条件的多个order的这种情况 dict_portal[vip_name].update({'order': ord_name}) for col_name, col_data in list(colocation.items()): # 这里同样没考虑多个符合条件的colocatin这种情况 if {vip_name, dict_portal[vip_name]['block']} == col_data: dict_portal[vip_name].update( {'colocation_block': col_name}) if {vip_name, dict_portal[vip_name]['unblock']} == col_data: dict_portal[vip_name].update( {'colocation_unblock': col_name}) error_portblock = set(portblock.keys()) - set(list_normal_portblock) if error_portblock: s.prt_log( f'Portblock:{",".join(error_portblock)} do not have corresponding VIP, please proceed', 2) list_portal = [] # portal如果没有block和unblock,则会加进这个列表 for portal_name, portal_data in list(dict_portal.items()): if len(dict_portal[portal_name]) != 5: list_portal.append(portal_name) if list_portal: s.prt_log( f'Portal:{",".join(list_portal)} can not be used normally, please proceed', 2)
def modify_initiators(self, name, list_iqns): iqns = ' '.join(list_iqns) cmd = f"crm config set {name}.allowed_initiators \"{iqns}\"" result = execute_crm_cmd(cmd) if result['sts']: s.prt_log(f"Modify the allowed initiators of {name} successfully", 0) return True else: s.prt_log(result['rst'], 1) raise consts.CmdError
def create_vg(self, name, list_pv): """创建vg""" pv = ' '.join(list_pv) cmd = f"vgcreate {name} {pv} -y" result = utils.exec_cmd(cmd, self.conn) if result["st"]: s.prt_log(f"Success in createing VG: {name}", 0) return True else: s.prt_log(f"Failed to create VG {name}", 1) return False
def linstor_create_rd(self, res): cmd = f'linstor rd c {res}' result = execute_linstor_cmd(cmd) if result['sts'] == 0: return True elif result['sts'] == 2: s.prt_log(f"FAIL\n{result['rst']}", 1) return result else: s.prt_log(f"FAIL\n{result['rst']}", 1) return result
def linstor_create_vd(self, res, size): cmd = f'linstor vd c {res} {size}' result = execute_linstor_cmd(cmd) if result['sts'] == 0: return True elif result['sts'] == 2: s.prt_log(f"FAIL\n{result['rst']}", 1) self.linstor_delete_rd(res) else: s.prt_log(f"FAIL\n{result['rst']}", 1) self.linstor_delete_rd(res) return result
def check_pv_exit(self, device_list): pv_in_use = [] if self.pv_list: for pv in self.pv_list: if pv[0] in device_list: pv_in_use.append(pv[0]) if pv_in_use: pv_in_use_str = ",".join(pv_in_use) s.prt_log(f'{pv_in_use_str} have been used to create PV.', 1) return False else: return True
def del_thinpool(self, vg, thinpool): """删除thinpool""" # lvremove /dev/linstor_vtel_pool/vtel_pool cmd = f"lvremove /dev/{vg}/{thinpool} -y" result = utils.exec_cmd(cmd, self.conn) if result["st"]: s.prt_log(f"Success in deleting Thinpool: {vg}/{thinpool}", 0) return True else: s.prt_log(f"Failed to delete Thinpool: {vg}/{thinpool}", 1) return False pass