Blob Blame History Raw
From 32d9dde2936b9f8b690ce3dd6c9bdc685f3ac5f0 Mon Sep 17 00:00:00 2001
From: Tomas Jelinek <tojeline@redhat.com>
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 <device model>
 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 <device model> [\fB\-\-full\fR] [<cluster name>]
+Show runtime status of specified model of quorum device provider.  Using \fB\-\-full\fR will give more detailed output.  If <cluster name> 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 <device model> [--full] [<cluster name>]
+        Show runtime status of specified model of quorum device provider.  Using
+        --full will give more detailed output.  If <cluster name> 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 <command>
 Manage cluster quorum settings.
 
 Commands:
-    config
+    [config]
         Show quorum configuration.
 
     status
-- 
1.8.3.1