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