|
|
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 |
|