|
|
15f218 |
From 5d8bab038a7aa64c38b79e5de9579af4c73e70a2 Mon Sep 17 00:00:00 2001
|
|
|
15f218 |
From: Tomas Jelinek <tojeline@redhat.com>
|
|
|
15f218 |
Date: Thu, 14 Jul 2016 17:04:04 +0200
|
|
|
15f218 |
Subject: [PATCH] fixes for pcs cli running on a remote node
|
|
|
15f218 |
|
|
|
15f218 |
---
|
|
|
15f218 |
pcs/acl.py | 2 +-
|
|
|
15f218 |
pcs/cluster.py | 13 ++++++-
|
|
|
15f218 |
pcs/config.py | 37 +++++++++++++-----
|
|
|
15f218 |
pcs/constraint.py | 2 +-
|
|
|
15f218 |
pcs/prop.py | 16 +-------
|
|
|
15f218 |
pcs/quorum.py | 3 +-
|
|
|
15f218 |
pcs/status.py | 29 +++++---------
|
|
|
15f218 |
pcs/stonith.py | 12 +++++-
|
|
|
15f218 |
pcs/utils.py | 104 +++++++++++++++++++++++++++++++------------------
|
|
|
15f218 |
pcsd/cluster_entity.rb | 4 +-
|
|
|
15f218 |
pcsd/pcs.rb | 4 ++
|
|
|
15f218 |
pcsd/remote.rb | 14 ++++++-
|
|
|
15f218 |
12 files changed, 149 insertions(+), 91 deletions(-)
|
|
|
15f218 |
|
|
|
15f218 |
diff --git a/pcs/acl.py b/pcs/acl.py
|
|
|
15f218 |
index 118ceed..0378c10 100644
|
|
|
15f218 |
--- a/pcs/acl.py
|
|
|
15f218 |
+++ b/pcs/acl.py
|
|
|
15f218 |
@@ -55,7 +55,7 @@ def acl_cmd(argv):
|
|
|
15f218 |
def acl_show(argv):
|
|
|
15f218 |
dom = utils.get_cib_dom()
|
|
|
15f218 |
|
|
|
15f218 |
- properties = prop.get_set_properties(defaults=prop.get_default_properties())
|
|
|
15f218 |
+ properties = utils.get_set_properties(defaults=prop.get_default_properties())
|
|
|
15f218 |
acl_enabled = properties.get("enable-acl", "").lower()
|
|
|
15f218 |
if is_true(acl_enabled):
|
|
|
15f218 |
print("ACLs are enabled")
|
|
|
15f218 |
diff --git a/pcs/cluster.py b/pcs/cluster.py
|
|
|
15f218 |
index 4155103..13446d4 100644
|
|
|
15f218 |
--- a/pcs/cluster.py
|
|
|
15f218 |
+++ b/pcs/cluster.py
|
|
|
15f218 |
@@ -1157,7 +1157,18 @@ def stop_cluster_corosync():
|
|
|
15f218 |
utils.err("unable to stop {0}".format(service))
|
|
|
15f218 |
|
|
|
15f218 |
def kill_cluster(argv):
|
|
|
15f218 |
- daemons = ["crmd", "pengine", "attrd", "lrmd", "stonithd", "cib", "pacemakerd", "corosync-qdevice", "corosync"]
|
|
|
15f218 |
+ daemons = [
|
|
|
15f218 |
+ "crmd",
|
|
|
15f218 |
+ "pengine",
|
|
|
15f218 |
+ "attrd",
|
|
|
15f218 |
+ "lrmd",
|
|
|
15f218 |
+ "stonithd",
|
|
|
15f218 |
+ "cib",
|
|
|
15f218 |
+ "pacemakerd",
|
|
|
15f218 |
+ "pacemaker_remoted",
|
|
|
15f218 |
+ "corosync-qdevice",
|
|
|
15f218 |
+ "corosync",
|
|
|
15f218 |
+ ]
|
|
|
15f218 |
dummy_output, dummy_retval = utils.run(["killall", "-9"] + daemons)
|
|
|
15f218 |
# if dummy_retval != 0:
|
|
|
15f218 |
# print "Error: unable to execute killall -9"
|
|
|
15f218 |
diff --git a/pcs/config.py b/pcs/config.py
|
|
|
15f218 |
index 3d86b39..9119c3c 100644
|
|
|
15f218 |
--- a/pcs/config.py
|
|
|
15f218 |
+++ b/pcs/config.py
|
|
|
15f218 |
@@ -95,14 +95,22 @@ def config_show(argv):
|
|
|
15f218 |
print()
|
|
|
15f218 |
config_show_cib()
|
|
|
15f218 |
if (
|
|
|
15f218 |
- utils.is_rhel6()
|
|
|
15f218 |
- or
|
|
|
15f218 |
- (not utils.usefile and "--corosync_conf" not in utils.pcs_options)
|
|
|
15f218 |
+ utils.hasCorosyncConf()
|
|
|
15f218 |
+ and
|
|
|
15f218 |
+ (
|
|
|
15f218 |
+ utils.is_rhel6()
|
|
|
15f218 |
+ or
|
|
|
15f218 |
+ (not utils.usefile and "--corosync_conf" not in utils.pcs_options)
|
|
|
15f218 |
+ )
|
|
|
15f218 |
):
|
|
|
15f218 |
# with corosync 1 and cman, uid gid is part of cluster.conf file
|
|
|
15f218 |
# with corosync 2, uid gid is in a separate directory
|
|
|
15f218 |
cluster.cluster_uidgid([], True)
|
|
|
15f218 |
- if "--corosync_conf" in utils.pcs_options or not utils.is_rhel6():
|
|
|
15f218 |
+ if (
|
|
|
15f218 |
+ "--corosync_conf" in utils.pcs_options
|
|
|
15f218 |
+ or
|
|
|
15f218 |
+ (not utils.is_rhel6() and utils.hasCorosyncConf())
|
|
|
15f218 |
+ ):
|
|
|
15f218 |
print()
|
|
|
15f218 |
print("Quorum:")
|
|
|
15f218 |
try:
|
|
|
15f218 |
@@ -267,7 +275,16 @@ def config_restore_remote(infile_name, infile_obj):
|
|
|
15f218 |
err_msgs.append(output)
|
|
|
15f218 |
continue
|
|
|
15f218 |
status = json.loads(output)
|
|
|
15f218 |
- if status["corosync"] or status["pacemaker"] or status["cman"]:
|
|
|
15f218 |
+ if (
|
|
|
15f218 |
+ status["corosync"]
|
|
|
15f218 |
+ or
|
|
|
15f218 |
+ status["pacemaker"]
|
|
|
15f218 |
+ or
|
|
|
15f218 |
+ status["cman"]
|
|
|
15f218 |
+ or
|
|
|
15f218 |
+ # not supported by older pcsd, do not fail if not present
|
|
|
15f218 |
+ status.get("pacemaker_remote", False)
|
|
|
15f218 |
+ ):
|
|
|
15f218 |
err_msgs.append(
|
|
|
15f218 |
"Cluster is currently running on node %s. You need to stop "
|
|
|
15f218 |
"the cluster in order to restore the configuration."
|
|
|
15f218 |
@@ -286,7 +303,7 @@ def config_restore_remote(infile_name, infile_obj):
|
|
|
15f218 |
# If node returns HTTP 404 it does not support config syncing at all.
|
|
|
15f218 |
for node in node_list:
|
|
|
15f218 |
retval, output = utils.pauseConfigSyncing(node, 10 * 60)
|
|
|
15f218 |
- if not (retval == 0 or output.endswith("(HTTP error: 404)")):
|
|
|
15f218 |
+ if not (retval == 0 or "(HTTP error: 404)" in output):
|
|
|
15f218 |
utils.err(output)
|
|
|
15f218 |
|
|
|
15f218 |
if infile_obj:
|
|
|
15f218 |
@@ -306,11 +323,13 @@ def config_restore_remote(infile_name, infile_obj):
|
|
|
15f218 |
|
|
|
15f218 |
def config_restore_local(infile_name, infile_obj):
|
|
|
15f218 |
if (
|
|
|
15f218 |
- status.is_cman_running()
|
|
|
15f218 |
+ status.is_service_running("cman")
|
|
|
15f218 |
+ or
|
|
|
15f218 |
+ status.is_service_running("corosync")
|
|
|
15f218 |
or
|
|
|
15f218 |
- status.is_corosyc_running()
|
|
|
15f218 |
+ status.is_service_running("pacemaker")
|
|
|
15f218 |
or
|
|
|
15f218 |
- status.is_pacemaker_running()
|
|
|
15f218 |
+ status.is_service_running("pacemaker_remote")
|
|
|
15f218 |
):
|
|
|
15f218 |
utils.err(
|
|
|
15f218 |
"Cluster is currently running on this node. You need to stop "
|
|
|
15f218 |
diff --git a/pcs/constraint.py b/pcs/constraint.py
|
|
|
15f218 |
index 5d9b0df..e32f1a3 100644
|
|
|
15f218 |
--- a/pcs/constraint.py
|
|
|
15f218 |
+++ b/pcs/constraint.py
|
|
|
15f218 |
@@ -593,7 +593,7 @@ def location_show(argv):
|
|
|
15f218 |
print(" Node: " + node)
|
|
|
15f218 |
|
|
|
15f218 |
nodehash_label = (
|
|
|
15f218 |
- (nodehashon, " Allowed to run:")
|
|
|
15f218 |
+ (nodehashon, " Allowed to run:"),
|
|
|
15f218 |
(nodehashoff, " Not allowed to run:")
|
|
|
15f218 |
)
|
|
|
15f218 |
for nodehash, label in nodehash_label:
|
|
|
15f218 |
diff --git a/pcs/prop.py b/pcs/prop.py
|
|
|
15f218 |
index 3a65990..36eba60 100644
|
|
|
15f218 |
--- a/pcs/prop.py
|
|
|
15f218 |
+++ b/pcs/prop.py
|
|
|
15f218 |
@@ -7,7 +7,6 @@ from __future__ import (
|
|
|
15f218 |
|
|
|
15f218 |
import sys
|
|
|
15f218 |
import json
|
|
|
15f218 |
-from xml.dom.minidom import parseString
|
|
|
15f218 |
|
|
|
15f218 |
from pcs import usage
|
|
|
15f218 |
from pcs import utils
|
|
|
15f218 |
@@ -116,7 +115,7 @@ def list_property(argv):
|
|
|
15f218 |
properties = {}
|
|
|
15f218 |
|
|
|
15f218 |
if "--defaults" not in utils.pcs_options:
|
|
|
15f218 |
- properties = get_set_properties(
|
|
|
15f218 |
+ properties = utils.get_set_properties(
|
|
|
15f218 |
None if print_all else argv[0],
|
|
|
15f218 |
properties
|
|
|
15f218 |
)
|
|
|
15f218 |
@@ -141,16 +140,3 @@ def get_default_properties():
|
|
|
15f218 |
parameters[name] = prop["default"]
|
|
|
15f218 |
return parameters
|
|
|
15f218 |
|
|
|
15f218 |
-def get_set_properties(prop_name=None, defaults=None):
|
|
|
15f218 |
- properties = {} if defaults is None else dict(defaults)
|
|
|
15f218 |
- (output, retVal) = utils.run(["cibadmin","-Q","--scope", "crm_config"])
|
|
|
15f218 |
- if retVal != 0:
|
|
|
15f218 |
- utils.err("unable to get crm_config\n"+output)
|
|
|
15f218 |
- dom = parseString(output)
|
|
|
15f218 |
- de = dom.documentElement
|
|
|
15f218 |
- crm_config_properties = de.getElementsByTagName("nvpair")
|
|
|
15f218 |
- for prop in crm_config_properties:
|
|
|
15f218 |
- if prop_name is None or (prop_name == prop.getAttribute("name")):
|
|
|
15f218 |
- properties[prop.getAttribute("name")] = prop.getAttribute("value")
|
|
|
15f218 |
- return properties
|
|
|
15f218 |
-
|
|
|
15f218 |
diff --git a/pcs/quorum.py b/pcs/quorum.py
|
|
|
15f218 |
index a849282..1c2d41d 100644
|
|
|
15f218 |
--- a/pcs/quorum.py
|
|
|
15f218 |
+++ b/pcs/quorum.py
|
|
|
15f218 |
@@ -8,7 +8,6 @@ from __future__ import (
|
|
|
15f218 |
import sys
|
|
|
15f218 |
|
|
|
15f218 |
from pcs import (
|
|
|
15f218 |
- prop,
|
|
|
15f218 |
stonith,
|
|
|
15f218 |
usage,
|
|
|
15f218 |
utils,
|
|
|
15f218 |
@@ -234,7 +233,7 @@ def quorum_unblock_cmd(argv):
|
|
|
15f218 |
utils.err("unable to cancel waiting for nodes")
|
|
|
15f218 |
print("Quorum unblocked")
|
|
|
15f218 |
|
|
|
15f218 |
- startup_fencing = prop.get_set_properties().get("startup-fencing", "")
|
|
|
15f218 |
+ startup_fencing = utils.get_set_properties().get("startup-fencing", "")
|
|
|
15f218 |
utils.set_cib_property(
|
|
|
15f218 |
"startup-fencing",
|
|
|
15f218 |
"false" if startup_fencing.lower() != "false" else "true"
|
|
|
15f218 |
diff --git a/pcs/status.py b/pcs/status.py
|
|
|
15f218 |
index bdfcc85..86216ea 100644
|
|
|
15f218 |
--- a/pcs/status.py
|
|
|
15f218 |
+++ b/pcs/status.py
|
|
|
15f218 |
@@ -103,7 +103,7 @@ def full_status():
|
|
|
15f218 |
print(output)
|
|
|
15f218 |
|
|
|
15f218 |
if not utils.usefile:
|
|
|
15f218 |
- if "--full" in utils.pcs_options:
|
|
|
15f218 |
+ if "--full" in utils.pcs_options and utils.hasCorosyncConf():
|
|
|
15f218 |
print_pcsd_daemon_status()
|
|
|
15f218 |
print()
|
|
|
15f218 |
utils.serviceStatus(" ")
|
|
|
15f218 |
@@ -121,7 +121,10 @@ def nodes_status(argv):
|
|
|
15f218 |
return
|
|
|
15f218 |
|
|
|
15f218 |
if len(argv) == 1 and (argv[0] == "config"):
|
|
|
15f218 |
- corosync_nodes = utils.getNodesFromCorosyncConf()
|
|
|
15f218 |
+ if utils.hasCorosyncConf():
|
|
|
15f218 |
+ corosync_nodes = utils.getNodesFromCorosyncConf()
|
|
|
15f218 |
+ else:
|
|
|
15f218 |
+ corosync_nodes = []
|
|
|
15f218 |
try:
|
|
|
15f218 |
pacemaker_nodes = sorted([
|
|
|
15f218 |
node.attrs.name for node
|
|
|
15f218 |
@@ -244,7 +247,7 @@ def cluster_status(argv):
|
|
|
15f218 |
else:
|
|
|
15f218 |
print("",line)
|
|
|
15f218 |
|
|
|
15f218 |
- if not utils.usefile:
|
|
|
15f218 |
+ if not utils.usefile and utils.hasCorosyncConf():
|
|
|
15f218 |
print()
|
|
|
15f218 |
print_pcsd_daemon_status()
|
|
|
15f218 |
|
|
|
15f218 |
@@ -262,25 +265,11 @@ def xml_status():
|
|
|
15f218 |
utils.err("running crm_mon, is pacemaker running?")
|
|
|
15f218 |
print(output, end="")
|
|
|
15f218 |
|
|
|
15f218 |
-def is_cman_running():
|
|
|
15f218 |
- if utils.is_systemctl():
|
|
|
15f218 |
- dummy_output, retval = utils.run(["systemctl", "status", "cman.service"])
|
|
|
15f218 |
- else:
|
|
|
15f218 |
- dummy_output, retval = utils.run(["service", "cman", "status"])
|
|
|
15f218 |
- return retval == 0
|
|
|
15f218 |
-
|
|
|
15f218 |
-def is_corosyc_running():
|
|
|
15f218 |
- if utils.is_systemctl():
|
|
|
15f218 |
- dummy_output, retval = utils.run(["systemctl", "status", "corosync.service"])
|
|
|
15f218 |
- else:
|
|
|
15f218 |
- dummy_output, retval = utils.run(["service", "corosync", "status"])
|
|
|
15f218 |
- return retval == 0
|
|
|
15f218 |
-
|
|
|
15f218 |
-def is_pacemaker_running():
|
|
|
15f218 |
+def is_service_running(service):
|
|
|
15f218 |
if utils.is_systemctl():
|
|
|
15f218 |
- dummy_output, retval = utils.run(["systemctl", "status", "pacemaker.service"])
|
|
|
15f218 |
+ dummy_output, retval = utils.run(["systemctl", "status", service])
|
|
|
15f218 |
else:
|
|
|
15f218 |
- dummy_output, retval = utils.run(["service", "pacemaker", "status"])
|
|
|
15f218 |
+ dummy_output, retval = utils.run(["service", service, "status"])
|
|
|
15f218 |
return retval == 0
|
|
|
15f218 |
|
|
|
15f218 |
def print_pcsd_daemon_status():
|
|
|
15f218 |
diff --git a/pcs/stonith.py b/pcs/stonith.py
|
|
|
15f218 |
index ab9e926..c02f35a 100644
|
|
|
15f218 |
--- a/pcs/stonith.py
|
|
|
15f218 |
+++ b/pcs/stonith.py
|
|
|
15f218 |
@@ -225,7 +225,11 @@ def stonith_level_add(level, node, devices):
|
|
|
15f218 |
for dev in devices.split(","):
|
|
|
15f218 |
if not utils.is_stonith_resource(dev):
|
|
|
15f218 |
utils.err("%s is not a stonith id (use --force to override)" % dev)
|
|
|
15f218 |
- if not utils.is_pacemaker_node(node) and not utils.is_corosync_node(node):
|
|
|
15f218 |
+ corosync_nodes = []
|
|
|
15f218 |
+ if utils.hasCorosyncConf():
|
|
|
15f218 |
+ corosync_nodes = utils.getNodesFromCorosyncConf()
|
|
|
15f218 |
+ pacemaker_nodes = utils.getNodesFromPacemaker()
|
|
|
15f218 |
+ if node not in corosync_nodes and node not in pacemaker_nodes:
|
|
|
15f218 |
utils.err("%s is not currently a node (use --force to override)" % node)
|
|
|
15f218 |
|
|
|
15f218 |
ft = dom.getElementsByTagName("fencing-topology")
|
|
|
15f218 |
@@ -321,6 +325,10 @@ def stonith_level_clear(node = None):
|
|
|
15f218 |
|
|
|
15f218 |
def stonith_level_verify():
|
|
|
15f218 |
dom = utils.get_cib_dom()
|
|
|
15f218 |
+ corosync_nodes = []
|
|
|
15f218 |
+ if utils.hasCorosyncConf():
|
|
|
15f218 |
+ corosync_nodes = utils.getNodesFromCorosyncConf()
|
|
|
15f218 |
+ pacemaker_nodes = utils.getNodesFromPacemaker()
|
|
|
15f218 |
|
|
|
15f218 |
fls = dom.getElementsByTagName("fencing-level")
|
|
|
15f218 |
for fl in fls:
|
|
|
15f218 |
@@ -329,7 +337,7 @@ def stonith_level_verify():
|
|
|
15f218 |
for dev in devices.split(","):
|
|
|
15f218 |
if not utils.is_stonith_resource(dev):
|
|
|
15f218 |
utils.err("%s is not a stonith id" % dev)
|
|
|
15f218 |
- if not utils.is_corosync_node(node) and not utils.is_pacemaker_node(node):
|
|
|
15f218 |
+ if node not in corosync_nodes and node not in pacemaker_nodes:
|
|
|
15f218 |
utils.err("%s is not currently a node" % node)
|
|
|
15f218 |
|
|
|
15f218 |
def stonith_level_show():
|
|
|
15f218 |
diff --git a/pcs/utils.py b/pcs/utils.py
|
|
|
15f218 |
index 2cfb693..3970eff 100644
|
|
|
15f218 |
--- a/pcs/utils.py
|
|
|
15f218 |
+++ b/pcs/utils.py
|
|
|
15f218 |
@@ -301,6 +301,8 @@ def canAddNodeToCluster(node):
|
|
|
15f218 |
return (False, "unable to authenticate to node")
|
|
|
15f218 |
if "node_available" in myout and myout["node_available"] == True:
|
|
|
15f218 |
return (True, "")
|
|
|
15f218 |
+ elif myout.get("pacemaker_remote", False):
|
|
|
15f218 |
+ return (False, "node is running pacemaker_remote")
|
|
|
15f218 |
else:
|
|
|
15f218 |
return (False, "node is already in a cluster")
|
|
|
15f218 |
except ValueError:
|
|
|
15f218 |
@@ -465,6 +467,14 @@ def getNodesFromPacemaker():
|
|
|
15f218 |
except LibraryError as e:
|
|
|
15f218 |
process_library_reports(e.args)
|
|
|
15f218 |
|
|
|
15f218 |
+def hasCorosyncConf(conf=None):
|
|
|
15f218 |
+ if not conf:
|
|
|
15f218 |
+ if is_rhel6():
|
|
|
15f218 |
+ conf = settings.cluster_conf_file
|
|
|
15f218 |
+ else:
|
|
|
15f218 |
+ conf = settings.corosync_conf_file
|
|
|
15f218 |
+ return os.path.isfile(conf)
|
|
|
15f218 |
+
|
|
|
15f218 |
def getCorosyncConf(conf=None):
|
|
|
15f218 |
if not conf:
|
|
|
15f218 |
if is_rhel6():
|
|
|
15f218 |
@@ -1071,18 +1081,6 @@ def does_exist(xpath_query):
|
|
|
15f218 |
return False
|
|
|
15f218 |
return True
|
|
|
15f218 |
|
|
|
15f218 |
-def is_pacemaker_node(node):
|
|
|
15f218 |
- p_nodes = getNodesFromPacemaker()
|
|
|
15f218 |
- if node in p_nodes:
|
|
|
15f218 |
- return True
|
|
|
15f218 |
- return False
|
|
|
15f218 |
-
|
|
|
15f218 |
-def is_corosync_node(node):
|
|
|
15f218 |
- c_nodes = getNodesFromCorosyncConf()
|
|
|
15f218 |
- if node in c_nodes:
|
|
|
15f218 |
- return True
|
|
|
15f218 |
- return False
|
|
|
15f218 |
-
|
|
|
15f218 |
def get_group_children(group_id):
|
|
|
15f218 |
child_resources = []
|
|
|
15f218 |
dom = get_cib_dom()
|
|
|
15f218 |
@@ -1838,7 +1836,7 @@ def getCorosyncNodesID(allow_failure=False):
|
|
|
15f218 |
err_msgs, retval, output, dummy_std_err = call_local_pcsd(
|
|
|
15f218 |
['status', 'nodes', 'corosync-id'], True
|
|
|
15f218 |
)
|
|
|
15f218 |
- if err_msgs:
|
|
|
15f218 |
+ if err_msgs and not allow_failure:
|
|
|
15f218 |
for msg in err_msgs:
|
|
|
15f218 |
err(msg, False)
|
|
|
15f218 |
sys.exit(1)
|
|
|
15f218 |
@@ -1866,6 +1864,7 @@ def getCorosyncNodesID(allow_failure=False):
|
|
|
15f218 |
|
|
|
15f218 |
# Warning, if a node has never started the hostname may be '(null)'
|
|
|
15f218 |
#TODO This doesn't work on CMAN clusters at all and should be removed completely
|
|
|
15f218 |
+# Doesn't work on pacemaker-remote nodes either
|
|
|
15f218 |
def getPacemakerNodesID(allow_failure=False):
|
|
|
15f218 |
if os.getuid() == 0:
|
|
|
15f218 |
(output, retval) = run(['crm_node', '-l'])
|
|
|
15f218 |
@@ -1873,7 +1872,7 @@ def getPacemakerNodesID(allow_failure=False):
|
|
|
15f218 |
err_msgs, retval, output, dummy_std_err = call_local_pcsd(
|
|
|
15f218 |
['status', 'nodes', 'pacemaker-id'], True
|
|
|
15f218 |
)
|
|
|
15f218 |
- if err_msgs:
|
|
|
15f218 |
+ if err_msgs and not allow_failure:
|
|
|
15f218 |
for msg in err_msgs:
|
|
|
15f218 |
err(msg, False)
|
|
|
15f218 |
sys.exit(1)
|
|
|
15f218 |
@@ -1893,9 +1892,11 @@ def getPacemakerNodesID(allow_failure=False):
|
|
|
15f218 |
return pm_nodes
|
|
|
15f218 |
|
|
|
15f218 |
def corosyncPacemakerNodeCheck():
|
|
|
15f218 |
- # does not work on CMAN clusters
|
|
|
15f218 |
- pm_nodes = getPacemakerNodesID()
|
|
|
15f218 |
- cs_nodes = getCorosyncNodesID()
|
|
|
15f218 |
+ # does not work on CMAN clusters and pacemaker-remote nodes
|
|
|
15f218 |
+ # we do not want a failure to exit pcs as this is only a minor information
|
|
|
15f218 |
+ # function
|
|
|
15f218 |
+ pm_nodes = getPacemakerNodesID(allow_failure=True)
|
|
|
15f218 |
+ cs_nodes = getCorosyncNodesID(allow_failure=True)
|
|
|
15f218 |
|
|
|
15f218 |
for node_id in pm_nodes:
|
|
|
15f218 |
if pm_nodes[node_id] == "(null)":
|
|
|
15f218 |
@@ -1920,10 +1921,9 @@ def getClusterName():
|
|
|
15f218 |
if is_rhel6():
|
|
|
15f218 |
try:
|
|
|
15f218 |
dom = parse(settings.cluster_conf_file)
|
|
|
15f218 |
+ return dom.documentElement.getAttribute("name")
|
|
|
15f218 |
except (IOError,xml.parsers.expat.ExpatError):
|
|
|
15f218 |
- return ""
|
|
|
15f218 |
-
|
|
|
15f218 |
- return dom.documentElement.getAttribute("name")
|
|
|
15f218 |
+ pass
|
|
|
15f218 |
else:
|
|
|
15f218 |
try:
|
|
|
15f218 |
f = open(settings.corosync_conf_file,'r')
|
|
|
15f218 |
@@ -1937,7 +1937,15 @@ def getClusterName():
|
|
|
15f218 |
if cluster_name:
|
|
|
15f218 |
return cluster_name
|
|
|
15f218 |
except (IOError, corosync_conf_parser.CorosyncConfParserException):
|
|
|
15f218 |
- return ""
|
|
|
15f218 |
+ pass
|
|
|
15f218 |
+
|
|
|
15f218 |
+ # there is no corosync.conf or cluster.conf on remote nodes, we can try to
|
|
|
15f218 |
+ # get cluster name from pacemaker
|
|
|
15f218 |
+ try:
|
|
|
15f218 |
+ return get_set_properties("cluster-name")["cluster-name"]
|
|
|
15f218 |
+ except:
|
|
|
15f218 |
+ # we need to catch SystemExit (from utils.err), parse errors and so on
|
|
|
15f218 |
+ pass
|
|
|
15f218 |
|
|
|
15f218 |
return ""
|
|
|
15f218 |
|
|
|
15f218 |
@@ -2024,23 +2032,30 @@ def serviceStatus(prefix):
|
|
|
15f218 |
if not is_systemctl():
|
|
|
15f218 |
return
|
|
|
15f218 |
print("Daemon Status:")
|
|
|
15f218 |
- for service in ["corosync", "pacemaker", "pcsd"]:
|
|
|
15f218 |
- print('{0}{1}: {2}/{3}'.format(
|
|
|
15f218 |
- prefix, service,
|
|
|
15f218 |
- run(["systemctl", 'is-active', service])[0].strip(),
|
|
|
15f218 |
- run(["systemctl", 'is-enabled', service])[0].strip()
|
|
|
15f218 |
- ))
|
|
|
15f218 |
- try:
|
|
|
15f218 |
- sbd_running = is_service_running(cmd_runner(), "sbd")
|
|
|
15f218 |
- sbd_enabled = is_service_enabled(cmd_runner(), "sbd")
|
|
|
15f218 |
- if sbd_enabled or sbd_running:
|
|
|
15f218 |
- print("{prefix}sbd: {active}/{enabled}".format(
|
|
|
15f218 |
- prefix=prefix,
|
|
|
15f218 |
- active=("active" if sbd_running else "inactive"),
|
|
|
15f218 |
- enabled=("enabled" if sbd_enabled else "disabled")
|
|
|
15f218 |
- ))
|
|
|
15f218 |
- except LibraryError:
|
|
|
15f218 |
- pass
|
|
|
15f218 |
+ service_def = [
|
|
|
15f218 |
+ # (
|
|
|
15f218 |
+ # service name,
|
|
|
15f218 |
+ # display even if not enabled nor running
|
|
|
15f218 |
+ # )
|
|
|
15f218 |
+ ("corosync", True),
|
|
|
15f218 |
+ ("pacemaker", True),
|
|
|
15f218 |
+ ("pacemaker_remote", False),
|
|
|
15f218 |
+ ("pcsd", True),
|
|
|
15f218 |
+ ("sbd", False),
|
|
|
15f218 |
+ ]
|
|
|
15f218 |
+ for service, display_always in service_def:
|
|
|
15f218 |
+ try:
|
|
|
15f218 |
+ running = is_service_running(cmd_runner(), service)
|
|
|
15f218 |
+ enabled = is_service_enabled(cmd_runner(), service)
|
|
|
15f218 |
+ if display_always or enabled or running:
|
|
|
15f218 |
+ print("{prefix}{service}: {active}/{enabled}".format(
|
|
|
15f218 |
+ prefix=prefix,
|
|
|
15f218 |
+ service=service,
|
|
|
15f218 |
+ active=("active" if running else "inactive"),
|
|
|
15f218 |
+ enabled=("enabled" if enabled else "disabled")
|
|
|
15f218 |
+ ))
|
|
|
15f218 |
+ except LibraryError:
|
|
|
15f218 |
+ pass
|
|
|
15f218 |
|
|
|
15f218 |
def enableServices():
|
|
|
15f218 |
# do NOT handle SBD in here, it is started by pacemaker not systemd or init
|
|
|
15f218 |
@@ -2677,3 +2692,16 @@ def exit_on_cmdline_input_errror(error, main_name, usage_name):
|
|
|
15f218 |
|
|
|
15f218 |
def get_report_processor():
|
|
|
15f218 |
return LibraryReportProcessorToConsole(debug=("--debug" in pcs_options))
|
|
|
15f218 |
+
|
|
|
15f218 |
+def get_set_properties(prop_name=None, defaults=None):
|
|
|
15f218 |
+ properties = {} if defaults is None else dict(defaults)
|
|
|
15f218 |
+ (output, retVal) = run(["cibadmin","-Q","--scope", "crm_config"])
|
|
|
15f218 |
+ if retVal != 0:
|
|
|
15f218 |
+ err("unable to get crm_config\n"+output)
|
|
|
15f218 |
+ dom = parseString(output)
|
|
|
15f218 |
+ de = dom.documentElement
|
|
|
15f218 |
+ crm_config_properties = de.getElementsByTagName("nvpair")
|
|
|
15f218 |
+ for prop in crm_config_properties:
|
|
|
15f218 |
+ if prop_name is None or (prop_name == prop.getAttribute("name")):
|
|
|
15f218 |
+ properties[prop.getAttribute("name")] = prop.getAttribute("value")
|
|
|
15f218 |
+ return properties
|
|
|
15f218 |
diff --git a/pcsd/cluster_entity.rb b/pcsd/cluster_entity.rb
|
|
|
15f218 |
index f54cd30..fa56fe2 100644
|
|
|
15f218 |
--- a/pcsd/cluster_entity.rb
|
|
|
15f218 |
+++ b/pcsd/cluster_entity.rb
|
|
|
15f218 |
@@ -1011,7 +1011,9 @@ module ClusterEntity
|
|
|
15f218 |
@uptime = 'unknown'
|
|
|
15f218 |
@name = nil
|
|
|
15f218 |
@services = {}
|
|
|
15f218 |
- [:pacemaker, :corosync, :pcsd, :cman, :sbd].each do |service|
|
|
|
15f218 |
+ [
|
|
|
15f218 |
+ :pacemaker, :pacemaker_remote, :corosync, :pcsd, :cman, :sbd
|
|
|
15f218 |
+ ].each do |service|
|
|
|
15f218 |
@services[service] = {
|
|
|
15f218 |
:installed => nil,
|
|
|
15f218 |
:running => nil,
|
|
|
15f218 |
diff --git a/pcsd/pcs.rb b/pcsd/pcs.rb
|
|
|
15f218 |
index 57082be..0956de9 100644
|
|
|
15f218 |
--- a/pcsd/pcs.rb
|
|
|
15f218 |
+++ b/pcsd/pcs.rb
|
|
|
15f218 |
@@ -892,6 +892,10 @@ def pacemaker_running?()
|
|
|
15f218 |
is_service_running?('pacemaker')
|
|
|
15f218 |
end
|
|
|
15f218 |
|
|
|
15f218 |
+def pacemaker_remote_running?()
|
|
|
15f218 |
+ is_service_running?('pacemaker_remote')
|
|
|
15f218 |
+end
|
|
|
15f218 |
+
|
|
|
15f218 |
def get_pacemaker_version()
|
|
|
15f218 |
begin
|
|
|
15f218 |
stdout, stderror, retval = run_cmd(
|
|
|
15f218 |
diff --git a/pcsd/remote.rb b/pcsd/remote.rb
|
|
|
15f218 |
index 75c9465..6a3a692 100644
|
|
|
15f218 |
--- a/pcsd/remote.rb
|
|
|
15f218 |
+++ b/pcsd/remote.rb
|
|
|
15f218 |
@@ -769,9 +769,19 @@ def get_sw_versions(params, request, auth_user)
|
|
|
15f218 |
end
|
|
|
15f218 |
|
|
|
15f218 |
def remote_node_available(params, request, auth_user)
|
|
|
15f218 |
- if (not ISRHEL6 and File.exist?(Cfgsync::CorosyncConf.file_path)) or (ISRHEL6 and File.exist?(Cfgsync::ClusterConf.file_path)) or File.exist?("/var/lib/pacemaker/cib/cib.xml")
|
|
|
15f218 |
+ if (
|
|
|
15f218 |
+ (not ISRHEL6 and File.exist?(Cfgsync::CorosyncConf.file_path)) or
|
|
|
15f218 |
+ (ISRHEL6 and File.exist?(Cfgsync::ClusterConf.file_path)) or
|
|
|
15f218 |
+ File.exist?("/var/lib/pacemaker/cib/cib.xml")
|
|
|
15f218 |
+ )
|
|
|
15f218 |
return JSON.generate({:node_available => false})
|
|
|
15f218 |
end
|
|
|
15f218 |
+ if pacemaker_remote_running?()
|
|
|
15f218 |
+ return JSON.generate({
|
|
|
15f218 |
+ :node_available => false,
|
|
|
15f218 |
+ :pacemaker_remote => true,
|
|
|
15f218 |
+ })
|
|
|
15f218 |
+ end
|
|
|
15f218 |
return JSON.generate({:node_available => true})
|
|
|
15f218 |
end
|
|
|
15f218 |
|
|
|
15f218 |
@@ -1038,6 +1048,8 @@ def node_status(params, request, auth_user)
|
|
|
15f218 |
:cman => node.cman,
|
|
|
15f218 |
:corosync_enabled => node.corosync_enabled,
|
|
|
15f218 |
:pacemaker_enabled => node.pacemaker_enabled,
|
|
|
15f218 |
+ :pacemaker_remote => node.services[:pacemaker_remote][:running],
|
|
|
15f218 |
+ :pacemaker_remote_enabled => node.services[:pacemaker_remote][:enabled],
|
|
|
15f218 |
:pcsd_enabled => node.pcsd_enabled,
|
|
|
15f218 |
:corosync_online => status[:corosync_online],
|
|
|
15f218 |
:corosync_offline => status[:corosync_offline],
|
|
|
15f218 |
--
|
|
|
15f218 |
1.8.3.1
|
|
|
15f218 |
|