From: Bogdan Dobrelya <bdobrelia@mirantis.com>
To: cluster-devel.redhat.com
Subject: [Cluster-devel] Fwd: some fence_virsh, fene_apc patches for RHEL6 backports
Date: Wed, 11 Dec 2013 11:28:39 +0200 [thread overview]
Message-ID: <52A83047.3000908@mirantis.com> (raw)
In-Reply-To: <52A82671.1000604@mirantis.com>
Hello.
Description for suggested patches:
fence_virsh: I believe the uuid support is a good idea, cuz every
spawned VM would have an UUID in its dmidecode, equal to its `virsh
domuuid`. Thus, to fence it, we should not either know the domain name,
nor query libvirt to find it out.
fence_apc: As I can see from my research activities, fence_apc is quite
a vendor specific agent, thus it would require custom options for
command-prompt as well as ssh-options.
--
Best regards,
Bogdan Dobrelya,
Researcher TechLead, Mirantis, Inc.
+38 (066) 051 07 53
Skype bogdando_at_yahoo.com
38, Lenina ave.
Kharkov, Ukraine
www.mirantis.com
www.mirantis.ru
bdobrelia at mirantis.com
-------------- next part --------------
From d95896825c89085b7d516547406454b7b21ffc17 Mon Sep 17 00:00:00 2001
From: Bogdan Dobrelya <bogdando@mail.ru>
Date: Tue, 10 Dec 2013 14:32:26 +0200
Subject: [PATCH 1/2] Add uuid support for fence_virsh
Signed-off-by: Bogdan Dobrelya <bogdando@mail.ru>
---
fence/agents/virsh/fence_virsh.py | 89 +++++++++++++++++++++++++++++++++----
1 file changed, 80 insertions(+), 9 deletions(-)
diff --git a/fence/agents/virsh/fence_virsh.py b/fence/agents/virsh/fence_virsh.py
index 13099da..80242ab 100644
--- a/fence/agents/virsh/fence_virsh.py
+++ b/fence/agents/virsh/fence_virsh.py
@@ -3,6 +3,7 @@
# The Following Agent Has Been Tested On:
#
# Virsh 0.3.3 on RHEL 5.2 with xen-3.0.3-51
+# Virsh 0.9.13,0.10.2 on Ubuntu 12.10 with qemu-kvm-1.2.0
#
import sys, re, pexpect, exceptions
@@ -13,11 +14,15 @@ from fencing import *
RELEASE_VERSION="Virsh fence agent"
REDHAT_COPYRIGHT=""
BUILD_DATE=""
+UUID_PATTERN=r"^\w{8}-\w{4}-\w{4}-\w{4}-\w{12}$"
+STATE_PATTERN=r"^(\b\w+)\s?(\b\w+)?$"
#END_VERSION_GENERATION
def get_outlets_status(conn, options):
- try:
- conn.sendline("virsh list --all")
+ if options.has_key("-n"):
+ try:
+ #Restrict virsh list by header and by matched domain name only (if any), assumes it would be unique
+ conn.sendline("virsh list --all|awk '/Name|%s/'"%(options["-n"]))
conn.log_expect(options, options["-c"], int(options["-Y"]))
except pexpect.EOF:
fail(EC_CONNECTION_LOST)
@@ -38,32 +43,98 @@ def get_outlets_status(conn, options):
elif (fa_status==1):
result[domain.group(2)]=("",(domain.group(3).lower() in ["running","blocked","idle","no state","paused"] and "on" or "off"))
return result
+ elif options.has_key("-U"):
+ return get_outlets_status_by_uuid(conn, options)
+ else: # other cases , f.e. action list
+ try:
+ conn.sendline("virsh list --all")
+ conn.log_expect(options, options["-c"], int(options["-Y"]))
+ except pexpect.EOF:
+ fail(EC_CONNECTION_LOST)
+ except pexpect.TIMEOUT:
+ fail(EC_TIMED_OUT)
+
+ result={}
+
+ #This is status of mini finite automata. 0 = we didn't found Id and Name, 1 = we did
+ fa_status=0
+
+ for line in conn.before.splitlines():
+ domain=re.search("^\s*(\S+)\s+(\S+)\s+(\S+).*$",line)
+ if (domain!=None):
+ if ((fa_status==0) and (domain.group(1).lower()=="id") and (domain.group(2).lower()=="name")):
+ fa_status=1
+ elif (fa_status==1):
+ result[domain.group(2)]=("",(domain.group(3).lower() in ["running","blocked","idle","no state","paused"] and "on" or "off"))
+ return result
+
+#Do the same as get_outlets_status, but using -U <uuid> option
+def get_outlets_status_by_uuid(conn, options):
+ try:
+ #Restrict virsh list by matched domain uuid only (if any), assumes it would be unique
+ conn.sendline("virsh list --all --uuid|awk '/%s/'"%(options["-U"].lower()))
+ conn.log_expect(options, options["-c"], int(options["-Y"]))
+ except pexpect.EOF:
+ fail(EC_CONNECTION_LOST)
+ except pexpect.TIMEOUT:
+ fail(EC_TIMED_OUT)
+
+ result={}
+
+ for line in conn.before.splitlines():
+ uuid=re.search(UUID_PATTERN,line)
+ if (uuid!=None):
+ result[uuid.group().lower()]=("",get_domstate(conn,options,uuid.group().lower()).lower() in ["running","blocked","idle","no state","paused"] and "on" or "off")
+ return result
+
+#Get virsh domstate by uuid
+def get_domstate(conn, options, uuid):
+ try:
+ conn.sendline("virsh domstate %s"%(uuid))
+ conn.log_expect(options, options["-c"], int(options["-Y"]))
+ except pexpect.EOF:
+ fail(EC_CONNECTION_LOST)
+ except pexpect.TIMEOUT:
+ fail(EC_TIMED_OUT)
+
+ for line in conn.before.splitlines():
+ #Search for domain state
+ state=re.search(STATE_PATTERN,line)
+ if (state!=None):
+ return state.group()
+
+#Return domain name/port, if -n was specified, otherwise assume -U was used instead and return domain uuid.
+def get_name_or_uuid(options):
+ if options.has_key("-n"):
+ return options["-n"]
+ else:
+ return options["-U"].lower()
def get_power_status(conn, options):
outlets=get_outlets_status(conn,options)
-
- if (not (options["-n"] in outlets)):
- fail_usage("Failed: You have to enter existing name of virtual machine!")
+ if (not (get_name_or_uuid(options) in outlets)):
+ fail_usage("Failed: You have to enter existing name/uuid of virtual machine!")
else:
- return outlets[options["-n"]][1]
+ return outlets[get_name_or_uuid(options)][1]
def set_power_status(conn, options):
try:
- conn.sendline("virsh %s "%(options["-o"] == "on" and "start" or "destroy")+options["-n"])
+ conn.sendline("virsh %s "%(options["-o"] == "on" and "start" or "destroy")+get_name_or_uuid(options))
conn.log_expect(options, options["-c"], int(options["-g"]))
- time.sleep(1)
+ time.sleep(int(options["-G"]))
except pexpect.EOF:
fail(EC_CONNECTION_LOST)
except pexpect.TIMEOUT:
fail(EC_TIMED_OUT)
+# Add uuid support
def main():
device_opt = [ "help", "version", "agent", "quiet", "verbose", "debug",
"action", "ipaddr", "login", "passwd", "passwd_script",
"secure", "identity_file", "test", "port", "separator",
- "inet4_only", "inet6_only", "ipport",
+ "inet4_only", "inet6_only", "ipport", "uuid",
"power_timeout", "shell_timeout", "login_timeout", "power_wait" ]
atexit.register(atexit_handler)
--
1.7.10.4
-------------- next part --------------
From 199b1374e0d6fcd70e0275ad6ecd0af2271293b3 Mon Sep 17 00:00:00 2001
From: Bogdan Dobrelya <bogdando@mail.ru>
Date: Mon, 9 Dec 2013 19:16:56 +0200
Subject: [PATCH 2/2] Add command_prompt, ssh-options to fence_apc
Signed-off-by: Bogdan Dobrelya <bogdando@mail.ru>
Conflicts:
usr/sbin/fence_apc
Signed-off-by: Bogdan Dobrelya <bogdando@mail.ru>
Conflicts:
README.md
Signed-off-by: Bogdan Dobrelya <bogdando@mail.ru>
---
fence/agents/apc/fence_apc.py | 7 ++++---
fence/agents/lib/fencing.py.py | 7 +++++++
2 files changed, 11 insertions(+), 3 deletions(-)
diff --git a/fence/agents/apc/fence_apc.py b/fence/agents/apc/fence_apc.py
index 78e709f..cf56a65 100644
--- a/fence/agents/apc/fence_apc.py
+++ b/fence/agents/apc/fence_apc.py
@@ -218,18 +218,19 @@ def main():
device_opt = [ "help", "version", "agent", "quiet", "verbose", "debug",
"action", "ipaddr", "login", "passwd", "passwd_script",
"secure", "port", "identity_file", "switch", "test", "separator",
- "inet4_only", "inet6_only", "ipport", "cmd_prompt",
+ "inet4_only", "inet6_only", "ipport", "cmd_prompt", "ssh_options",
"power_timeout", "shell_timeout", "login_timeout", "power_wait" ]
atexit.register(atexit_handler)
- all_opt["cmd_prompt"]["default"] = [ "\n>", "\napc>" ]
+ all_opt["cmd_prompt"]["default"] = [ "\n>", "\napc>" ]
+ all_opt["ssh_options"]["default"] = "-1 -c blowfish"
+
options = check_input(device_opt, process_input(device_opt))
##
## Fence agent specific defaults
#####
- options["ssh_options"] = "-1 -c blowfish"
docs = { }
docs["shortdesc"] = "Fence agent for APC over telnet/ssh"
diff --git a/fence/agents/lib/fencing.py.py b/fence/agents/lib/fencing.py.py
index 1de9a15..a7f1548 100644
--- a/fence/agents/lib/fencing.py.py
+++ b/fence/agents/lib/fencing.py.py
@@ -189,6 +189,13 @@ all_opt = {
"shortdesc" : "SSH connection",
"required" : "0",
"order" : 1 },
+ "ssh_options" : {
+ "getopt" : "X:",
+ "longopt" : "ssh-options",
+ "help" : "--ssh-options=[options] SSH options to use",
+ "shortdesc" : "SSH options to use",
+ "required" : "0",
+ "order" : 1 },
"ssl" : {
"getopt" : "z",
"longopt" : "ssl",
--
1.7.10.4
next parent reply other threads:[~2013-12-11 9:28 UTC|newest]
Thread overview: 9+ messages / expand[flat|nested] mbox.gz Atom feed top
[not found] <52A74740.8020904@redhat.com>
[not found] ` <52A82671.1000604@mirantis.com>
2013-12-11 9:28 ` Bogdan Dobrelya [this message]
2013-12-16 15:14 ` [Cluster-devel] Fw: some fence_virsh, fene_apc patches for RHEL6 backports Marek Grac
2013-12-16 16:10 ` Bogdan Dobrelya
2013-12-19 13:31 ` [Cluster-devel] Fence agent for Tripplite PDU Marek Grac
2013-12-24 13:36 ` Bogdan Dobrelya
2014-01-06 13:01 ` Marek Grac
2013-12-18 13:42 ` [Cluster-devel] Fw: some fence_virsh, fene_apc patches for RHEL6 backports Bogdan Dobrelya
2013-12-19 13:13 ` Marek Grac
2013-12-24 13:23 ` Bogdan Dobrelya
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=52A83047.3000908@mirantis.com \
--to=bdobrelia@mirantis.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).