Blame SOURCES/bz1214359-2-fence_compute.patch

02611b
From 21c2154bedceb6ebef1cae369768280d4b0f8652 Mon Sep 17 00:00:00 2001
02611b
From: Marek 'marx' Grac <mgrac@redhat.com>
02611b
Date: Fri, 5 Jun 2015 18:07:55 +0200
02611b
Subject: [PATCH 2/4] fence_compute: Improvement of fence agent
02611b
02611b
---
02611b
 fence/agents/compute/fence_compute.py | 73 ++++++++++++++++++++++-------------
02611b
 fence/agents/lib/fencing.py.py        |  6 ++-
02611b
 2 files changed, 50 insertions(+), 29 deletions(-)
02611b
02611b
diff --git a/fence/agents/compute/fence_compute.py b/fence/agents/compute/fence_compute.py
02611b
index 2b37de7..66cf08f 100644
02611b
--- a/fence/agents/compute/fence_compute.py
02611b
+++ b/fence/agents/compute/fence_compute.py
02611b
@@ -4,11 +4,11 @@ import sys
02611b
 import time
02611b
 import atexit
02611b
 import logging
02611b
+import requests.exceptions
02611b
 
02611b
 sys.path.append("@FENCEAGENTSLIBDIR@")
02611b
 from fencing import *
02611b
 from fencing import fail_usage, is_executable, run_command, run_delay
02611b
-from novaclient import client as nova_client
02611b
 
02611b
 #BEGIN_VERSION_GENERATION
02611b
 RELEASE_VERSION="4.0.11"
02611b
@@ -32,18 +32,18 @@ def get_power_status(_, options):
02611b
 	if nova:
02611b
 		try:
02611b
 			services = nova.services.list(host=options["--plug"])
02611b
-		except Exception, e:
02611b
-			fail_usage(str(e))
02611b
-
02611b
-		for service in services:
02611b
-			if service.binary == "nova-compute":
02611b
-				if service.state == "up":
02611b
-					status = "on"
02611b
-				elif service.state == "down":
02611b
-					status = "down"
02611b
-				else:
02611b
-					logging.debug("Unknown status detected from nova: " + service.state)
02611b
-				break
02611b
+
02611b
+			for service in services:
02611b
+				if service.binary == "nova-compute":
02611b
+					if service.state == "up":
02611b
+						status = "on"
02611b
+					elif service.state == "down":
02611b
+						status = "off"
02611b
+					else:
02611b
+						logging.debug("Unknown status detected from nova: " + service.state)
02611b
+					break
02611b
+		except ConnectionError as (err):
02611b
+			logging.warning("Nova connection failed: " + str(err))
02611b
 	return status
02611b
 
02611b
 # NOTE(sbauza); We mimic the host-evacuate module since it's only a contrib
02611b
@@ -143,15 +143,6 @@ def define_new_opts():
02611b
 		"default" : "",
02611b
 		"order": 1,
02611b
 	}
02611b
-	all_opt["novatool-path"] = {
02611b
-		"getopt" : "i:",
02611b
-		"longopt" : "novatool-path",
02611b
-		"help" : "-i, --novatool-path=[path]     Path to nova binary",
02611b
-		"required" : "0",
02611b
-		"shortdesc" : "Path to nova binary",
02611b
-		"default" : "@NOVA_PATH@",
02611b
-		"order": 6,
02611b
-	}
02611b
 	all_opt["domain"] = {
02611b
 		"getopt" : "d:",
02611b
 		"longopt" : "domain",
02611b
@@ -177,7 +168,7 @@ def main():
02611b
 	atexit.register(atexit_handler)
02611b
 
02611b
 	device_opt = ["login", "passwd", "tenant-name", "auth-url",
02611b
-		"novatool-path", "no_login", "no_password", "port", "domain", "no-shared-storage"]
02611b
+		"no_login", "no_password", "port", "domain", "no-shared-storage"]
02611b
 	define_new_opts()
02611b
 	all_opt["shell_timeout"]["default"] = "180"
02611b
 
02611b
@@ -192,6 +183,15 @@ def main():
02611b
 
02611b
 	run_delay(options)
02611b
 
02611b
+	try:
02611b
+		from novaclient import client as nova_client
02611b
+	except ImportError:
02611b
+		fail_usage("nova not found or not accessible")
02611b
+
02611b
+	# Potentially we should make this a pacemaker feature
02611b
+	if options["--action"] != "list" and options["--domain"] != "" and options.has_key("--plug"):
02611b
+		options["--plug"] = options["--plug"] + "." + options["--domain"]
02611b
+
02611b
 	# The first argument is the Nova client version
02611b
 	nova = nova_client.Client('2',
02611b
 		options["--username"],
02611b
@@ -199,6 +199,29 @@ def main():
02611b
 		options["--tenant-name"],
02611b
 		options["--auth-url"])
02611b
 
02611b
+	if options["--action"] in ["on", "off", "reboot" ]:
02611b
+		try:
02611b
+			nova.services.list(host=options["--plug"])
02611b
+		except ConnectionError as (err):
02611b
+			# Yes, exit(0)
02611b
+			#
02611b
+			# Its possible that the control plane on which this
02611b
+			# agent depends is not functional
02611b
+			#
02611b
+			# In this situation, fencing is waiting for resource
02611b
+			# recovery and resource recovery is waiting for
02611b
+			# fencing.
02611b
+			#
02611b
+			# To break the cycle, we all the fencing agent to
02611b
+			# return 'done' immediately so that we can recover the
02611b
+			# control plane. We then rely on the NovaCompute RA
02611b
+			# to call this agent directly once the control plane
02611b
+			# is up.
02611b
+			#
02611b
+			# Yes its horrible, but still better than nova itself.
02611b
+			logging.warning("Nova connection failed: %s " % str(err))
02611b
+			sys.exit(0)
02611b
+
02611b
 	if options["--action"] in ["off", "reboot"]:
02611b
 		# Pretend we're 'on' so that the fencing library will always call set_power_status(off)
02611b
 		override_status = "on"
02611b
@@ -207,10 +230,6 @@ def main():
02611b
 		# Pretend we're 'off' so that the fencing library will always call set_power_status(on)
02611b
 		override_status = "off"
02611b
 
02611b
-	# Potentially we should make this a pacemaker feature
02611b
-	if options["--action"] != "list" and options["--domain"] != "" and options.has_key("--plug"):
02611b
-		options["--plug"] = options["--plug"]+"."+options["--domain"]
02611b
-
02611b
 	result = fence_action(None, options, set_power_status, get_power_status, get_plugs_list, None)
02611b
 	sys.exit(result)
02611b
 
02611b
diff --git a/fence/agents/lib/fencing.py.py b/fence/agents/lib/fencing.py.py
02611b
index f893082..29b3a94 100644
02611b
--- a/fence/agents/lib/fencing.py.py
02611b
+++ b/fence/agents/lib/fencing.py.py
02611b
@@ -1109,9 +1109,11 @@ def fence_login(options, re_login_string=r"(login\s*: )|(Login Name:  )|(usernam
02611b
 					conn.log_expect(options, options["--command-prompt"], int(options["--login-timeout"]))
02611b
 			except KeyError:
02611b
 				fail(EC_PASSWORD_MISSING)
02611b
-	except pexpect.EOF:
02611b
+	except pexpect.EOF, exception:
02611b
+		logging.debug("%s", str(exception))
02611b
 		fail(EC_LOGIN_DENIED)
02611b
-	except pexpect.TIMEOUT:
02611b
+	except pexpect.TIMEOUT, exception:
02611b
+		logging.debug("%s", str(exception))
02611b
 		fail(EC_LOGIN_DENIED)
02611b
 	return conn
02611b
 
02611b
-- 
02611b
1.9.3
02611b