From 4fe757d176060089e46f76d66ef20918b65e1f7f Mon Sep 17 00:00:00 2001 From: Ivan Devat 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[^"]+)":$') 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