From 4fe757d176060089e46f76d66ef20918b65e1f7f Mon Sep 17 00:00:00 2001
From: Ivan Devat <idevat@redhat.com>
Date: Tue, 20 Sep 2016 08:20:29 +0200
Subject: [PATCH] squash bz1158805 Add support for qdevice/qnetd pro
66e72fa18ddb lib: do not error out in "qdevice stop" if qdevice is stopped already
788407652f58 lib: fix removing qdevice from a cluster
---
pcs/common/report_codes.py | 1 +
pcs/lib/commands/qdevice.py | 22 +++++++++++++++-------
pcs/lib/commands/quorum.py | 7 +++----
pcs/lib/corosync/qdevice_net.py | 32 +++++++++++++++++++++++++-------
pcs/lib/reports.py | 13 +++++++++++++
5 files changed, 57 insertions(+), 18 deletions(-)
diff --git a/pcs/common/report_codes.py b/pcs/common/report_codes.py
index 23e931f..9b05951 100644
--- a/pcs/common/report_codes.py
+++ b/pcs/common/report_codes.py
@@ -134,6 +134,7 @@ QDEVICE_INITIALIZATION_ERROR = "QDEVICE_INITIALIZATION_ERROR"
QDEVICE_INITIALIZATION_SUCCESS = "QDEVICE_INITIALIZATION_SUCCESS"
QDEVICE_NOT_DEFINED = "QDEVICE_NOT_DEFINED"
QDEVICE_NOT_INITIALIZED = "QDEVICE_NOT_INITIALIZED"
+QDEVICE_NOT_RUNNING = "QDEVICE_NOT_RUNNING"
QDEVICE_CLIENT_RELOAD_STARTED = "QDEVICE_CLIENT_RELOAD_STARTED"
QDEVICE_REMOVE_OR_CLUSTER_STOP_NEEDED = "QDEVICE_REMOVE_OR_CLUSTER_STOP_NEEDED"
QDEVICE_USED_BY_CLUSTERS = "QDEVICE_USED_BY_CLUSTERS"
diff --git a/pcs/lib/commands/qdevice.py b/pcs/lib/commands/qdevice.py
index ca0ae86..119c51d 100644
--- a/pcs/lib/commands/qdevice.py
+++ b/pcs/lib/commands/qdevice.py
@@ -61,11 +61,16 @@ def qdevice_status_text(lib_env, model, verbose=False, cluster=None):
_ensure_not_cman(lib_env)
_check_model(model)
runner = lib_env.cmd_runner()
- return (
- qdevice_net.qdevice_status_generic_text(runner, verbose)
- +
- qdevice_net.qdevice_status_cluster_text(runner, cluster, verbose)
- )
+ try:
+ return (
+ qdevice_net.qdevice_status_generic_text(runner, verbose)
+ +
+ qdevice_net.qdevice_status_cluster_text(runner, cluster, verbose)
+ )
+ except qdevice_net.QnetdNotRunningException:
+ raise LibraryError(
+ reports.qdevice_not_running(model)
+ )
def qdevice_enable(lib_env, model):
"""
@@ -196,8 +201,11 @@ def _check_qdevice_not_used(reporter, runner, model, force=False):
_check_model(model)
connected_clusters = []
if model == "net":
- status = qdevice_net.qdevice_status_cluster_text(runner)
- connected_clusters = qdevice_net.qdevice_connected_clusters(status)
+ try:
+ status = qdevice_net.qdevice_status_cluster_text(runner)
+ connected_clusters = qdevice_net.qdevice_connected_clusters(status)
+ except qdevice_net.QnetdNotRunningException:
+ pass
if connected_clusters:
reporter.process(reports.qdevice_used_by_clusters(
connected_clusters,
diff --git a/pcs/lib/commands/quorum.py b/pcs/lib/commands/quorum.py
index 8390fc6..aa98e61 100644
--- a/pcs/lib/commands/quorum.py
+++ b/pcs/lib/commands/quorum.py
@@ -285,6 +285,7 @@ def remove_device(lib_env, skip_offline_nodes=False):
cfg.remove_quorum_device()
if lib_env.is_corosync_conf_live:
+ communicator = lib_env.node_communicator()
# fix quorum options for SBD to work properly
if sbd.atb_has_to_be_enabled(lib_env.cmd_runner(), cfg):
lib_env.report_processor.process(reports.sbd_requires_atb())
@@ -292,10 +293,6 @@ def remove_device(lib_env, skip_offline_nodes=False):
lib_env.report_processor, {"auto_tie_breaker": "1"}
)
- lib_env.push_corosync_conf(cfg, skip_offline_nodes)
-
- if lib_env.is_corosync_conf_live:
- communicator = lib_env.node_communicator()
# disable qdevice
lib_env.report_processor.process(
reports.service_disable_started("corosync-qdevice")
@@ -330,6 +327,8 @@ def remove_device(lib_env, skip_offline_nodes=False):
skip_offline_nodes
)
+ lib_env.push_corosync_conf(cfg, skip_offline_nodes)
+
def _remove_device_model_net(lib_env, cluster_nodes, skip_offline_nodes):
"""
remove configuration used by qdevice model net
diff --git a/pcs/lib/corosync/qdevice_net.py b/pcs/lib/corosync/qdevice_net.py
index 200e45a..fa44923 100644
--- a/pcs/lib/corosync/qdevice_net.py
+++ b/pcs/lib/corosync/qdevice_net.py
@@ -35,6 +35,9 @@ __qdevice_certutil = os.path.join(
"corosync-qdevice-net-certutil"
)
+class QnetdNotRunningException(Exception):
+ pass
+
def qdevice_setup(runner):
"""
initialize qdevice on local host
@@ -79,10 +82,10 @@ def qdevice_status_generic_text(runner, verbose=False):
get qdevice runtime status in plain text
bool verbose get more detailed output
"""
- cmd = [__qnetd_tool, "-s"]
+ args = ["-s"]
if verbose:
- cmd.append("-v")
- stdout, stderr, retval = runner.run(cmd)
+ args.append("-v")
+ stdout, stderr, retval = _qdevice_run_tool(runner, args)
if retval != 0:
raise LibraryError(
reports.qdevice_get_status_error(
@@ -98,12 +101,12 @@ def qdevice_status_cluster_text(runner, cluster=None, verbose=False):
bool verbose get more detailed output
string cluster show information only about specified cluster
"""
- cmd = [__qnetd_tool, "-l"]
+ args = ["-l"]
if verbose:
- cmd.append("-v")
+ args.append("-v")
if cluster:
- cmd.extend(["-c", cluster])
- stdout, stderr, retval = runner.run(cmd)
+ args.extend(["-c", cluster])
+ stdout, stderr, retval = _qdevice_run_tool(runner, args)
if retval != 0:
raise LibraryError(
reports.qdevice_get_status_error(
@@ -114,6 +117,10 @@ def qdevice_status_cluster_text(runner, cluster=None, verbose=False):
return stdout
def qdevice_connected_clusters(status_cluster_text):
+ """
+ parse qnetd cluster status listing and return connected clusters' names
+ string status_cluster_text output of corosync-qnetd-tool -l
+ """
connected_clusters = []
regexp = re.compile(r'^Cluster "(?P<cluster>[^"]+)":$')
for line in status_cluster_text.splitlines():
@@ -122,6 +129,17 @@ def qdevice_connected_clusters(status_cluster_text):
connected_clusters.append(match.group("cluster"))
return connected_clusters
+def _qdevice_run_tool(runner, args):
+ """
+ run corosync-qnetd-tool, raise QnetdNotRunningException if qnetd not running
+ CommandRunner runner
+ iterable args corosync-qnetd-tool arguments
+ """
+ stdout, stderr, retval = runner.run([__qnetd_tool] + args)
+ if retval == 3 and "is qnetd running?" in stderr.lower():
+ raise QnetdNotRunningException()
+ return stdout, stderr, retval
+
def qdevice_enable(runner):
"""
make qdevice start automatically on boot on local host
diff --git a/pcs/lib/reports.py b/pcs/lib/reports.py
index b9e9a66..cff491c 100644
--- a/pcs/lib/reports.py
+++ b/pcs/lib/reports.py
@@ -842,6 +842,19 @@ def qdevice_destroy_error(model, reason):
}
)
+def qdevice_not_running(model):
+ """
+ qdevice is expected to be running but is not running
+ string model qdevice model
+ """
+ return ReportItem.error(
+ report_codes.QDEVICE_NOT_RUNNING,
+ "Quorum device '{model}' is not running",
+ info={
+ "model": model,
+ }
+ )
+
def qdevice_get_status_error(model, reason):
"""
unable to get runtime status of qdevice
--
1.8.3.1