[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]

[Cluster-devel] Fwd: some fence_virsh, fene_apc patches for RHEL6 backports



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




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



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




[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]