From 187a3150529714888a46dd2845c994a315033d72 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=91=A8=E5=AD=90=E8=B4=A4?= <2367744612@qq.com> Date: Thu, 2 Jul 2020 15:59:58 +0800 Subject: [PATCH] normative questions and transferred meaning --- common_utils.py | 10 ++++----- config.py | 42 ++++++++++++++++++------------------ ha-api.mo | Bin 86258 -> 86949 bytes node.py | 20 ++++++++--------- resource.py | 56 ++++++++++++++++++++---------------------------- scripts.py | 4 ++-- zh_CN.po | 18 ++++++++++++++++ 7 files changed, 79 insertions(+), 71 deletions(-) diff --git a/common_utils.py b/common_utils.py index d911d5a..b752482 100644 --- a/common_utils.py +++ b/common_utils.py @@ -446,7 +446,7 @@ def get_resource_info_from_xml(cl, et): "provider": et.get("provider", "") } if cl == "clone": - #如果是组资源 + # 如果是组资源 if et.find("group"): return get_resource_info_from_xml("group", et.find("group")) else: @@ -476,25 +476,25 @@ def get_resource_info(ct, xml_data): etree = ET.fromstring(xml_data) try: data = {} - #根据分类 + # 根据分类 if ct == "primitive": data = get_resource_info_from_xml("primitive", etree) if ct == "group": data["rscs"] = get_resource_info_from_xml("group", etree) if ct == "clone": data["rsc_id"] = get_resource_info_from_xml("clone", etree) - #获取meta_attributes + # 获取meta_attributes e = etree.find("meta_attributes") if e: prop = get_resource_info_from_xml("meta", e) data["meta_attributes"] = prop - #获取instance_attributes + # 获取instance_attributes e = etree.find("instance_attributes") if e: prop = get_resource_info_from_xml("inst", e) data["instance_attributes"] = prop - #获取actions + # 获取actions e = etree.find("operations") if e: prop = get_resource_info_from_xml("operations", e) diff --git a/config.py b/config.py index ee2336c..47c28e7 100644 --- a/config.py +++ b/config.py @@ -44,7 +44,7 @@ import re def get_node_list(): - #读取文件 + # 读取文件 filename = "/etc/corosync/corosync.conf" try: read = open(filename) @@ -53,19 +53,19 @@ def get_node_list(): 'action': False, 'error': "File " + filename + " doesn't exist!" } - node_list = [] #存储文件内数据 - line = read.readline() #按行读取文件内容 + node_list = [] # 存储文件内数据 + line = read.readline() # 按行读取文件内容 while line and not "nodelist {" in line: line = read.readline() - #读到nodelist - #node_list.append(line) + # 读到nodelist + # node_list.append(line) while line: if "quorum {" in line: break node_list.append(line.strip()) line = read.readline() read.close - #修改格式 + # 修改格式 while "nodelist {" in node_list: node_list.remove("nodelist {") while "" in node_list: @@ -109,12 +109,12 @@ def get_node_list(): # return {'action': True, "data": data} -#判断集群是否存在 +# 判断集群是否存在 def is_cluster_exist(): return os.path.exists("/etc/corosync/corosync.conf") -#通过/var/lib/pcsd/known-hosts获取hb信息 +# 通过/var/lib/pcsd/known-hosts获取hb信息 def get_hb_by_hosts(): cmd_str = "cat /var/lib/pcsd/known-hosts" status, output = common_utils.run_cmd(cmd_str) @@ -126,7 +126,7 @@ def get_hb_by_hosts(): _("No node in the Cluster, please run \'pcs host auth $nodename\' to add node" ) } - #解析json为字典 + # 解析json为字典 info = json.loads(str(output)) ret = {} if "known_hosts" in info.keys(): @@ -149,7 +149,7 @@ def get_hb_by_hosts(): def get_hb_conf(): - #判断集群是否存在 + # 判断集群是否存在 if is_cluster_exist(): return get_hb_dict() else: @@ -165,7 +165,7 @@ def get_hb_dict(): index = 0 while index < len(node_list): if node_list[index] == "node {": - #开始按照node {进行分割遍历每个node + # 开始按照node {进行分割遍历每个node index += 1 node_info = {} while index < len(node_list) and node_list[index] != "node {": @@ -184,7 +184,7 @@ def get_hb_dict(): ] """ res = {} - #形成指定格式 + # 形成指定格式 for i in nodes: """ {'ring0_addr': 'ha3', 'ring1_addr': 'ha4', 'name': 'ha3', 'nodeid': '1'} @@ -192,23 +192,23 @@ def get_hb_dict(): name = i.get("name", "") for k, v in i.items(): if k != "name" and k != "nodeid": - #只选取ip + # 只选取ip """ {'ring0_addr': 'ha3'} """ info = {} info["nodeid"] = name info["ip"] = v - #判断属于哪个心跳 + # 判断属于哪个心跳 hb = str(k) if hb in res.keys(): - #如果存在,向其中添加 + # 如果存在,向其中添加 res[hb].append(info) else: - #如果不存在,新建 + # 如果不存在,新建 res[hb] = [] res[hb].append(info) - #将res里的所有ringx_addr重命名为hbaddrsx + # 将res里的所有ringx_addr重命名为hbaddrsx ret = {} count = 0 for key, value in res.items(): @@ -252,11 +252,11 @@ def edit_hb_info(data): for v in value: addr = "addr=" + str(v) cmd = cmd + " " + addr - cmd = cmd + cmd2 #pcs cluster setup hacluster ha1 addr=10.1.167.86 ha2 addr=10.1.167.81 + cmd = cmd + cmd2 + # pcs cluster setup hacluster ha1 addr=10.1.167.86 ha2 addr=10.1.167.81 cmd_resource = "crm_mon -1 --as-xml" status, output = common_utils.run_cmd(cmd_resource) if status == 0: - xml_nodes = parseString(output).documentElement json_str = json.dumps(xmltodict.parse(output)) json_dict = json.loads(json_str) run_resources = json_dict['crm_mon']['resources'] @@ -269,9 +269,9 @@ def edit_hb_info(data): status, output = common_utils.run_cmd("pcs cluster destroy --all") status, output = common_utils.run_cmd(cmd) status, output = common_utils.run_cmd("pcs cluster cib-push ra-cfg") - return {"action": True, "info": "Change cluster success"} + return {"action": True, "info": _("Change cluster success")} else: - return {"action": False, "error": "集群中有运行的资源,请先关闭"} + return {"action": False, "error": _("There")} if __name__ == '__main__': diff --git a/ha-api.mo b/ha-api.mo index ed5750255b93f1d9e12e4f8d2b6b665d807d515e..f113aa7c4119a9c9da9164f090d6381e6daa9f2d 100644 GIT binary patch delta 24637 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 aFgDR_Uxk1wTmG#O@Kxe1i)#hMP53_mqE|Zr diff --git a/node.py b/node.py index fee3651..88c598d 100644 --- a/node.py +++ b/node.py @@ -84,7 +84,7 @@ def get_node_info(): if data != []: return {"action": True, "data": data} else: - return {"action": False, "data": "Get node failed!"} + return {"action": False, "data": _("Get node failed!")} def get_nodeid_info(nodeid): @@ -93,34 +93,34 @@ def get_nodeid_info(nodeid): "|awk -F ' ' '{print $1}'") nodeip = str(output) if nameid == {}: - return {'action': False, "data": "Get nodeid failed!"} + return {'action': False, "data": _("Get nodeid failed!")} else: return {'action': True, 'data': {'ips': nodeip}} def get_nodes_action(node_id, action): nodeid = str(node_id) - #节点未开启 + # 节点未开启 if nodeid == {} or nodeid is None: return {'action': False, 'error': _("Cannot find the")} - #备用 + # 备用 if action == 'standby': status, output = common_utils.run_cmd("pcs node standby " + nodeid) - #不备用 + # 不备用 if action == 'unstandby': status, output = common_utils.run_cmd("pcs node unstandby " + nodeid) - #启动 + # 启动 if action == 'start': status, output = common_utils.run_cmd("pcs cluster start " + nodeid + " &sleep 5") - #停止 + # 停止 if action == 'stop': status, output = common_utils.run_cmd("pcs cluster stop " + nodeid) - #重启 + # 重启 if action == 'restart': status, output = common_utils.run_cmd("pcs cluster restart " + nodeid) if action == {} or action is None: - return {"action": False, "error": "error info"} + return {"action": False, "error": _("error info")} else: - return {"action": True, "info": "Change node status success"} + return {"action": True, "info": _("Change node status success")} diff --git a/resource.py b/resource.py index 823f329..667dbe8 100644 --- a/resource.py +++ b/resource.py @@ -562,7 +562,6 @@ def get_all_rsc_status(): 4:_('Stop Failed'), 5:_('running (Master)'), 6:_('running (Slave)')} - rsc_info = { "hj1": {"status": 0 , "status_message": "test", running_node: []} "hj2": {"status": 0 , "status_message": "test", running_node: []} @@ -1305,12 +1304,12 @@ def update_resource_attributes(rsc_id, data): return {'action': True, 'info': _("Update resource attributes Success")} -#获取rsc已有的op列表(仅属性名,如start) +# 获取rsc已有的op列表(仅属性名,如start) def get_all_ops(rsc_id): op_list = [] cmd_str = "crm_resource --resource " + str(rsc_id) + " --query-xml" - status, output = common_utils.run_cmd(cmd_str) #输出为xml格式 - #format + status, output = common_utils.run_cmd(cmd_str) # 输出为xml格式 + # format xml_data = output.split(":\n") xml = xml_data[1] etree = ET.fromstring(xml) @@ -1322,13 +1321,13 @@ def get_all_ops(rsc_id): return op_list -#获取组资源的rscs列表 +# 获取组资源的rscs列表 def get_group_rscs(group_id): cmd_str = "crm_resource --resource " + str(group_id) + " --query-xml" - status, output = common_utils.run_cmd(cmd_str) #输出为xml格式 + status, output = common_utils.run_cmd(cmd_str) # 输出为xml格式 if status != 0: return {'action': False, 'error': _(output)} - #format + # format xml_data = output.split(":\n") xml = xml_data[1] etree = ET.fromstring(xml) @@ -1339,13 +1338,13 @@ def get_group_rscs(group_id): return rscs -#获取资源category(primitive, group, clone) +# 获取资源category(primitive, group, clone) def get_rsc_category(rsc_id): cmd_str = "crm_resource --resource " + str(rsc_id) + " --query-xml" - status, output = common_utils.run_cmd(cmd_str) #输出为xml格式 + status, output = common_utils.run_cmd(cmd_str) # 输出为xml格式 if status != 0: return {'action': False, 'error': _(output)} - #format + # format xml_data = output.split(":\n") xml = xml_data[1] etree = ET.fromstring(xml) @@ -1354,7 +1353,7 @@ def get_rsc_category(rsc_id): def del_pri_attrib(rsc_id): - #删除之前所有的属性 + # 删除之前所有的属性 attrib = [] attrib = get_meta_and_inst(rsc_id) if "meta_attributes" in attrib: @@ -1532,10 +1531,6 @@ def create_resource(data): def unmigrate_rsc(is_all_rscs, rsc_id): # 保留标签 is_all_rscs = False - - # if rsc_id not in get_all_rsc(): - # return {'action': False, 'error': _("Cannot find the %s: %s") % (_("resource"), str(rsc_id))} - rsc_locations = {} for rsc_location in get_all_migrate_rscs(): id = str(rsc_location.getAttribute("id")) @@ -1573,7 +1568,7 @@ def unmigrate_rsc(is_all_rscs, rsc_id): def get_all_rsc_metas(): - #获取支持的资源代理标准 + # 获取支持的资源代理标准 standards = [] status, output = common_utils.run_cmd("crm_resource --list-standards") if status != 0: @@ -1583,14 +1578,14 @@ def get_all_rsc_metas(): res = {} for st in standards: if st == "ocf": - #获取providers列表 + # 获取providers列表 status, output = common_utils.run_cmd( "crm_resource --list-ocf-providers") if status != 0: return {'action': False, 'error': _(output)} pvds = [] pvds = str(output).split("\n") - #根据providers列出所有资源 + # 根据providers列出所有资源 for p in pvds: status, output = common_utils.run_cmd( "crm_resource --list-agents ocf:" + str(p)) @@ -1603,7 +1598,7 @@ def get_all_rsc_metas(): res[str(p)] = ag # 去除重复项 data["ocf"] = res - #lsb目前没有 + # lsb目前没有 elif st == "lsb": continue else: @@ -1619,7 +1614,7 @@ def get_all_rsc_metas(): return {'action': True, 'data': data} -#获取资源元属性 +# 获取资源元属性 def get_rsc_meta_attributes(category): ''' { @@ -1746,15 +1741,15 @@ def get_rsc_meta_attributes(category): def get_resource_info_by_rsc_id(rsc_id): cmd_str = "crm_resource --resource " + str(rsc_id) + " --query-xml" - status, output = common_utils.run_cmd(cmd_str) #输出为xml格式 + status, output = common_utils.run_cmd(cmd_str) # 输出为xml格式 if status != 0: return {'action': False, 'error': _(output)} - #format + # format xml_data = output.split(":\n") xml = xml_data[1] etree = ET.fromstring(xml) ct = etree.tag - data = common_utils.get_resource_info(ct, xml) #获取资源信息并按格式输出 + data = common_utils.get_resource_info(ct, xml) # 获取资源信息并按格式输出 data["id"] = str(rsc_id) data["category"] = str(ct) ret = {} @@ -1775,25 +1770,25 @@ def get_resource_info_by_rsc_id(rsc_id): return ret -#获取资源已有元属性和实例属性 +# 获取资源已有元属性和实例属性 def get_meta_and_inst(rsc_id): cmd_str = "crm_resource --resource " + str(rsc_id) + " --query-xml" - status, output = common_utils.run_cmd(cmd_str) #输出为xml格式 + status, output = common_utils.run_cmd(cmd_str) # 输出为xml格式 if status != 0: return {'action': False, 'error': _(output)} - #format + # format xml_data = output.split(":\n") xml = xml_data[1] etree = ET.fromstring(xml) data = {} - #获取meta_attributes + # 获取meta_attributes e = etree.find("meta_attributes") if e: prop = [] for item in e.findall("./nvpair"): prop.append(item.get("name")) data["meta_attributes"] = prop - #获取instance_attributes + # 获取instance_attributes e = etree.find("instance_attributes") if e: prop = [] @@ -1944,10 +1939,5 @@ def del_colocation_by_id_action(source_id, target_id): if __name__ == '__main__': print(get_all_rsc_status()) - # print(get_resource_info_by_rsc_id("q11")) - # print(get_resource_info()) print(get_sub_rscs("dummyx-clone")) print(get_sub_rscs("dummy1-clone")) - - # get_rsc_category("q11") - # print(get_resource_svc("q3")) diff --git a/scripts.py b/scripts.py index b21a836..5aa5672 100644 --- a/scripts.py +++ b/scripts.py @@ -21,14 +21,14 @@ def generate_scripts(data): if status != 0: return {'action': False, 'error': output} localnodeid = str(output).strip() - #configdata = get_hb_config_org(True) + # configdata = get_hb_config_org(True) configdata = None hbs = configdata['data'] hbaddrs = [] for hb in hbs: if 'hbaddrs' in hb: - hbaddrs = hb['hbaddrs'] + hbaddrs = hb['hbaddrs'] for node in hbaddrs: nodeid = node['nodeid'] diff --git a/zh_CN.po b/zh_CN.po index 586d972..8ec6762 100644 --- a/zh_CN.po +++ b/zh_CN.po @@ -22,6 +22,9 @@ msgstr "即使" msgid "\tThis will prevent" msgstr "这将阻止" +msgid "Update cluster properties Success" +msgstr "更新集群属性成功" + #: pacemaker-mgmt.new/mgmt/client/haclient.py.in:3180 #: pacemaker-mgmt.new/mgmt/client/haclient.py.in:3369 #: pacemaker-mgmt.new/mgmt/client/haclient.py.in:19263 @@ -3168,6 +3171,21 @@ msgstr "然后" msgid "Then Action" msgstr "然后操作" +msgid "There" +msgstr "集群中有运行的资源,请先关闭" + +msgid "Change cluster success" +msgstr "改变集群成功" + +msgid "Change node status success" +msgstr "更改节点状态成功" + +msgid "error info" +msgstr "更改节点信息错误" + +msgid "Get nodeid failed!" +msgstr "得到nodeid失败!" + #: pacemaker-mgmt.new/mgmt/client/haclient.py.in:2859 #: pacemaker-mgmt.new/mgmt/client/haclient.py.in:3099 #: pacemaker-mgmt.new/mgmt/client/haclient.py.in:8357 -- Gitee