From 32d9dde2936b9f8b690ce3dd6c9bdc685f3ac5f0 Mon Sep 17 00:00:00 2001 From: Tomas Jelinek Date: Mon, 11 Jul 2016 15:19:30 +0200 Subject: [PATCH] cli: improve quorum device commands syntax * add alias "pcs status quorum" to "pcs quorum status" * add alias "pcs status qdevice" to "pcs qdevice status" * add alias "pcs quorum" to "pcs quorum config" --- pcs/cluster.py | 59 +++------------------------------------------------ pcs/pcs.8 | 8 ++++++- pcs/quorum.py | 67 +++++++++++++++++++++++++++++++++++++++++++++++++++++----- pcs/status.py | 25 ++++++++++++++++++++++ pcs/usage.py | 10 ++++++++- 5 files changed, 106 insertions(+), 63 deletions(-) diff --git a/pcs/cluster.py b/pcs/cluster.py index 9d4798c..4155103 100644 --- a/pcs/cluster.py +++ b/pcs/cluster.py @@ -26,7 +26,7 @@ from pcs import ( constraint, node, pcsd, - prop, + quorum, resource, settings, status, @@ -143,9 +143,9 @@ def cluster_cmd(argv): cluster_report(argv) elif (sub_cmd == "quorum"): if argv and argv[0] == "unblock": - cluster_quorum_unblock(argv[1:]) + quorum.quorum_unblock_cmd(argv[1:]) else: - usage.cluster(["quorum"]) + usage.cluster() sys.exit(1) else: usage.cluster() @@ -1890,56 +1890,3 @@ def cluster_remote_node(argv): usage.cluster(["remote-node"]) sys.exit(1) -def cluster_quorum_unblock(argv): - if len(argv) > 0: - usage.quorum(["unblock"]) - sys.exit(1) - - if utils.is_rhel6(): - utils.err("operation is not supported on CMAN clusters") - - output, retval = utils.run( - ["corosync-cmapctl", "-g", "runtime.votequorum.wait_for_all_status"] - ) - if retval != 0: - utils.err("unable to check quorum status") - if output.split("=")[-1].strip() != "1": - utils.err("cluster is not waiting for nodes to establish quorum") - - unjoined_nodes = ( - set(utils.getNodesFromCorosyncConf()) - - - set(utils.getCorosyncActiveNodes()) - ) - if not unjoined_nodes: - utils.err("no unjoined nodes found") - if "--force" not in utils.pcs_options: - answer = utils.get_terminal_input( - ( - "WARNING: If node(s) {nodes} are not powered off or they do" - + " have access to shared resources, data corruption and/or" - + " cluster failure may occur. Are you sure you want to" - + " continue? [y/N] " - ).format(nodes=", ".join(unjoined_nodes)) - ) - if answer.lower() not in ["y", "yes"]: - print("Canceled") - return - for node in unjoined_nodes: - stonith.stonith_confirm([node], skip_question=True) - - output, retval = utils.run( - ["corosync-cmapctl", "-s", "quorum.cancel_wait_for_all", "u8", "1"] - ) - if retval != 0: - utils.err("unable to cancel waiting for nodes") - print("Quorum unblocked") - - startup_fencing = prop.get_set_properties().get("startup-fencing", "") - utils.set_cib_property( - "startup-fencing", - "false" if startup_fencing.lower() != "false" else "true" - ) - utils.set_cib_property("startup-fencing", startup_fencing) - print("Waiting for nodes canceled") - diff --git a/pcs/pcs.8 b/pcs/pcs.8 index 223ef1b..a26c94b 100644 --- a/pcs/pcs.8 +++ b/pcs/pcs.8 @@ -543,7 +543,7 @@ disable Configure specified model of quorum device provider to not start on boot. .SS "quorum" .TP -config +[config] Show quorum configuration. .TP status @@ -590,6 +590,12 @@ View current cluster status. corosync View current membership information as seen by corosync. .TP +quorum +View current quorum status. +.TP +qdevice [\fB\-\-full\fR] [] +Show runtime status of specified model of quorum device provider. Using \fB\-\-full\fR will give more detailed output. If is specified, only information about the specified cluster will be displayed. +.TP nodes [corosync|both|config] View current status of nodes from pacemaker. If 'corosync' is specified, print nodes currently configured in corosync, if 'both' is specified, print nodes from both corosync & pacemaker. If 'config' is specified, print nodes from corosync & pacemaker configuration. .TP diff --git a/pcs/quorum.py b/pcs/quorum.py index 2d54ed7..a849282 100644 --- a/pcs/quorum.py +++ b/pcs/quorum.py @@ -8,10 +8,11 @@ from __future__ import ( import sys from pcs import ( + prop, + stonith, usage, utils, ) -from pcs.cluster import cluster_quorum_unblock from pcs.cli.common import parse_args from pcs.cli.common.console_report import indent from pcs.cli.common.errors import CmdLineInputError @@ -19,10 +20,10 @@ from pcs.lib.errors import LibraryError def quorum_cmd(lib, argv, modificators): if len(argv) < 1: - usage.quorum() - sys.exit(1) + sub_cmd, argv_next = "config", [] + else: + sub_cmd, argv_next = argv[0], argv[1:] - sub_cmd, argv_next = argv[0], argv[1:] try: if sub_cmd == "help": usage.quorum(argv) @@ -35,7 +36,8 @@ def quorum_cmd(lib, argv, modificators): elif sub_cmd == "device": quorum_device_cmd(lib, argv_next, modificators) elif sub_cmd == "unblock": - cluster_quorum_unblock(argv_next) + # TODO switch to new architecture + quorum_unblock_cmd(argv_next) elif sub_cmd == "update": quorum_update_cmd(lib, argv_next, modificators) else: @@ -185,3 +187,58 @@ def quorum_device_update_cmd(lib, argv, modificators): force_options=modificators["force"], skip_offline_nodes=modificators["skip_offline_nodes"] ) + +# TODO switch to new architecture, move to lib +def quorum_unblock_cmd(argv): + if len(argv) > 0: + usage.quorum(["unblock"]) + sys.exit(1) + + if utils.is_rhel6(): + utils.err("operation is not supported on CMAN clusters") + + output, retval = utils.run( + ["corosync-cmapctl", "-g", "runtime.votequorum.wait_for_all_status"] + ) + if retval != 0: + utils.err("unable to check quorum status") + if output.split("=")[-1].strip() != "1": + utils.err("cluster is not waiting for nodes to establish quorum") + + unjoined_nodes = ( + set(utils.getNodesFromCorosyncConf()) + - + set(utils.getCorosyncActiveNodes()) + ) + if not unjoined_nodes: + utils.err("no unjoined nodes found") + if "--force" not in utils.pcs_options: + answer = utils.get_terminal_input( + ( + "WARNING: If node(s) {nodes} are not powered off or they do" + + " have access to shared resources, data corruption and/or" + + " cluster failure may occur. Are you sure you want to" + + " continue? [y/N] " + ).format(nodes=", ".join(unjoined_nodes)) + ) + if answer.lower() not in ["y", "yes"]: + print("Canceled") + return + for node in unjoined_nodes: + stonith.stonith_confirm([node], skip_question=True) + + output, retval = utils.run( + ["corosync-cmapctl", "-s", "quorum.cancel_wait_for_all", "u8", "1"] + ) + if retval != 0: + utils.err("unable to cancel waiting for nodes") + print("Quorum unblocked") + + startup_fencing = prop.get_set_properties().get("startup-fencing", "") + utils.set_cib_property( + "startup-fencing", + "false" if startup_fencing.lower() != "false" else "true" + ) + utils.set_cib_property("startup-fencing", startup_fencing) + print("Waiting for nodes canceled") + diff --git a/pcs/status.py b/pcs/status.py index e1f367f..bdfcc85 100644 --- a/pcs/status.py +++ b/pcs/status.py @@ -13,6 +13,9 @@ from pcs import ( usage, utils, ) +from pcs.qdevice import qdevice_status_cmd +from pcs.quorum import quorum_status_cmd +from pcs.cli.common.errors import CmdLineInputError from pcs.lib.errors import LibraryError from pcs.lib.pacemaker_state import ClusterState @@ -38,6 +41,28 @@ def status_cmd(argv): xml_status() elif (sub_cmd == "corosync"): corosync_status() + elif sub_cmd == "qdevice": + try: + qdevice_status_cmd( + utils.get_library_wrapper(), + argv, + utils.get_modificators() + ) + except LibraryError as e: + utils.process_library_reports(e.args) + except CmdLineInputError as e: + utils.exit_on_cmdline_input_errror(e, "status", sub_cmd) + elif sub_cmd == "quorum": + try: + quorum_status_cmd( + utils.get_library_wrapper(), + argv, + utils.get_modificators() + ) + except LibraryError as e: + utils.process_library_reports(e.args) + except CmdLineInputError as e: + utils.exit_on_cmdline_input_errror(e, "status", sub_cmd) else: usage.status() sys.exit(1) diff --git a/pcs/usage.py b/pcs/usage.py index 77b496e..0605cd7 100644 --- a/pcs/usage.py +++ b/pcs/usage.py @@ -1118,6 +1118,14 @@ Commands: corosync View current membership information as seen by corosync. + quorum + View current quorum status. + + qdevice [--full] [] + Show runtime status of specified model of quorum device provider. Using + --full will give more detailed output. If is specified, + only information about the specified cluster will be displayed. + nodes [corosync|both|config] View current status of nodes from pacemaker. If 'corosync' is specified, print nodes currently configured in corosync, if 'both' @@ -1322,7 +1330,7 @@ Usage: pcs quorum Manage cluster quorum settings. Commands: - config + [config] Show quorum configuration. status -- 1.8.3.1