cluster-devel.redhat.com archive mirror
 help / color / mirror / Atom feed
* [Cluster-devel] [PATCH] fence_zvmip: Port fence agent to fencing library
@ 2014-12-22  9:07 Marek 'marx' Grac
  0 siblings, 0 replies; 2+ messages in thread
From: Marek 'marx' Grac @ 2014-12-22  9:07 UTC (permalink / raw)
  To: cluster-devel.redhat.com

This rewrite adds a correct result codes, support for 'list' action and
autogenerated manual page. The original code is still part of codebase as
new agent requires additional testing.
---
 fence/agents/lib/fencing.py.py  |   4 +
 fence/agents/zvm/Makefile.am    |  26 ++-----
 fence/agents/zvm/fence_zvmip.8  |  92 -----------------------
 fence/agents/zvm/fence_zvmip.py | 162 ++++++++++++++++++++++++++++++++++++++++
 4 files changed, 174 insertions(+), 110 deletions(-)
 delete mode 100644 fence/agents/zvm/fence_zvmip.8
 create mode 100644 fence/agents/zvm/fence_zvmip.py

diff --git a/fence/agents/lib/fencing.py.py b/fence/agents/lib/fencing.py.py
index a8ea448..83bbfcd 100644
--- a/fence/agents/lib/fencing.py.py
+++ b/fence/agents/lib/fencing.py.py
@@ -7,6 +7,7 @@ import subprocess
 import threading
 import shlex
 import exceptions
+import socket
 import __main__
 
 ## do not add code here.
@@ -805,6 +806,9 @@ def fence_action(connection, options, set_power_fn, get_power_fn, get_outlet_lis
 	except pycurl.error, ex:
 		logging.error("%s\n", str(ex))
 		fail(EC_TIMED_OUT)
+	except socket.timeout, ex:
+		logging.error("%s\n", str(ex))
+		fail(EC_TIMED_OUT)
 
 	return result
 
diff --git a/fence/agents/zvm/Makefile.am b/fence/agents/zvm/Makefile.am
index 62eb862..a29754d 100644
--- a/fence/agents/zvm/Makefile.am
+++ b/fence/agents/zvm/Makefile.am
@@ -2,26 +2,16 @@ MAINTAINERCLEANFILES	= Makefile.in
 
 TARGET			= fence_zvmip
 
-sbin_PROGRAMS		= fence_zvm fence_zvmip
+SRC			= $(TARGET).py
 
-noinst_HEADERS		= fence_zvm.h
+EXTRA_DIST		= $(SRC)
 
-fence_zvm_SOURCES	= fence_zvm.c
-fence_zvm_CFLAGS	= -D_GNU_SOURCE
+sbin_SCRIPTS		= $(TARGET)
 
-fence_zvmip_SOURCES	= fence_zvmip.c
-fence_zvmip_CFLAGS	= -D_GNU_SOURCE
+man_MANS		= $(TARGET).8
 
-dist_man_MANS		= fence_zvm.8 fence_zvmip.8
+FENCE_TEST_ARGS         = -l test -p test -a test -n 1
 
-#include $(top_srcdir)/make/fencemanc.mk
-
-clean-local:
-	rm -f $(sbin_PROGRAMS)
-
-FENCE_TEST_ARGS		= -n test -a test -p test -u test
-
-include $(top_srcdir)/make/agentccheck.mk
-
-# we do not test fence_zvm because it can be compiled only on specific architecture
-check: xml-check.fence_zvmip delay-check.fence_zvmip
\ No newline at end of file
+include $(top_srcdir)/make/fencebuild.mk
+include $(top_srcdir)/make/fenceman.mk
+include $(top_srcdir)/make/agentpycheck.mk
diff --git a/fence/agents/zvm/fence_zvmip.8 b/fence/agents/zvm/fence_zvmip.8
deleted file mode 100644
index 6b01425..0000000
--- a/fence/agents/zvm/fence_zvmip.8
+++ /dev/null
@@ -1,92 +0,0 @@
-.TH fence_zvmip 8
-
-.SH NAME
-fence_zvmip - Power Fencing agent for GFS on System z z/VM Clusters using IP interface to SMAPI
-
-.SH SYNOPSIS
-.B
-fence_zvmip
-[\fIOPTION\fR]...
-
-.SH DESCRIPTION
-fence_zvmip is a Power Fencing agent used on a GFS virtual machine in a System z z/VM cluster.
-It uses the TCP/IP SMAPI interface to recycle an active image.
-
-fence_zvmip accepts options on the command line as well as from stdin.
-fence_node sends the options through stdin when it execs the agent.
-fence_zvmip can be run by itself with command line options which is useful
-for testing.
-
-Vendor URL: http://www.sinenomine.net
-
-.SH OPTIONS
-.TP
-\fB-o --action\fP
-Fencing action: "off" - deactivate virtual machine; "on" - activate virtual machine; "metadata" - display device metadata" - describe fence agent parameters; "status" - state of virtual machine
-.TP
-\fB--delay\fP \fIseconds\fP
-Time to delay fencing action in seconds
-.TP
-\fB-n --plug\fP \fItarget\fP
-Name of target virtual machine to fence
-.TP
-\fB-h --help\fP
-Print out a help message describing available options, then exit.
-.TP
-\fB-a --ip\fP \fIsmapi Server\fP
-Host name or IP address of SMAPI server
-.TP
-\fB-u --username\fP \fISMAPI authorized user\fP
-Name of an authorized SMAPI user
-.TP
-\fB-p --password\fP \fISMAPI authorized user's password\fP
-Password of the authorized SMAPI user
-.TP
-\fB-t --timeout\fP \fIRecycle timeout\fP
-Amount of \fIgrace\fP time to give the virtual machine to shutdown cleanly before being
-forcibly terminated. Currently this is ignored.
-.TP
-\fB-h --help\fP
-Display usage information
-
-.SH STDIN PARAMETERS
-.TP
-\fIagent = < param >\fP
-This option is used by fence_node(8) and is ignored by fence_zvmip.
-.TP
-\fIaction = < action >\fP
-Fencing action: "off" - deactivate virtual machine; "on" - activate virtual machine; "metadata" - display device metadata" - describe fence agent parameters; "status" - state of virtual machine
-.TP
-\fIplug = < plug >\fP
-Name of virtual machine to recycle.
-.TP
-\fIipaddr = < server host name or IP address >\fP
-Host name or IP address of SMAPI server
-.TP
-\fIlogin = < SMAPI authorized user >\fP
-Name of an authorized SMAPI user
-.TP
-\fIpasswd = < SMAPI authorized user's password >\fP
-Password of the authorized SMAPI user
-.TP
-\fItimeout = < shutdown timeout >\fP
-Amount of \fIgrace\fP time to give the virtual machine to shutdown cleanly before being
-forcibly terminated. Currently this is ignored.
-
-.SH SEE ALSO
-fence(8), fenced(8), fence_node(8)
-
-.SH NOTES
-To use this agent the z/VM SMAPI service needs to be configured to allow the virtual
-machine running this agent to connect to it and issue the image_recycle operation.
-This involves updating the VSMWORK1 AUTHLIST VMSYS:VSMWORK1. file. The entry should look
-something similar to this:
-
-.nf
-Column 1                   Column 66                Column 131
-|                          |                        |
-V                          V                        V
-XXXXXXXX                   ALL                      IMAGE_OPERATIONS
-.fi
-
-Where XXXXXXX is the name of the virtual machine used in the authuser field of the request. 
diff --git a/fence/agents/zvm/fence_zvmip.py b/fence/agents/zvm/fence_zvmip.py
new file mode 100644
index 0000000..c494d1d
--- /dev/null
+++ b/fence/agents/zvm/fence_zvmip.py
@@ -0,0 +1,162 @@
+#!/usr/bin/python -tt
+
+import sys
+import atexit
+import socket
+import struct
+import logging
+sys.path.append("@FENCEAGENTSLIBDIR@")
+from fencing import *
+from fencing import fail_usage
+
+#BEGIN_VERSION_GENERATION
+RELEASE_VERSION=""
+REDHAT_COPYRIGHT=""
+BUILD_DATE=""
+#END_VERSION_GENERATION
+
+INT4 = 4
+
+def open_socket(options):
+	try:
+		if "--inet6-only" in options:
+			protocol = socket.AF_INET6
+		elif "--inet4-only" in options:
+			protocol = socket.AF_INET
+		else:
+			protocol = 0
+		(_, _, _, _, addr) = socket.getaddrinfo( \
+				options["--ip"], options["--ipport"], protocol,
+				0, socket.IPPROTO_TCP, socket.AI_PASSIVE
+				)[0]
+	except socket.gaierror:
+		fail_usage("Failed: Unable to create connection")
+
+	conn = socket.socket()
+	conn.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
+	conn.settimeout(float(options["--shell-timeout"]))
+	try:
+		conn.connect(addr)
+	except socket.error:
+		fail_usage("Failed: Unable to open connection")
+
+	return conn
+
+def smapi_pack_string(string):
+	return struct.pack("!i%ds" % (len(string)), len(string), string)
+
+def prepare_smapi_command(options, smapi_function, additional_args):
+	packet_size = 3*INT4 + len(smapi_function) + len(options["--username"]) + len(options["--password"])
+	for arg in additional_args:
+		packet_size += INT4 + len(arg)
+
+	command = struct.pack("!i", packet_size)
+	command += smapi_pack_string(smapi_function)
+	command += smapi_pack_string(options["--username"])
+	command += smapi_pack_string(options["--password"])
+	for arg in additional_args:
+		command += smapi_pack_string(arg)
+
+	return command
+
+def get_power_status(conn, options):
+	del conn
+
+	# '*' = list all active images
+	(return_code, reason_code, images_active) = \
+			get_list_of_images(options, "Image_Status_Query", "*")
+	logging.debug("Image_Status_Query results are (%d,%d)", return_code, reason_code)
+	(return_code, reason_code, images_defined) = \
+			get_list_of_images(options, "Image_Name_Query_DM", options["--username"])
+	logging.debug("Image_Name_Query_DM results are (%d,%d)", return_code, reason_code)
+
+	if ["list", "monitor"].count(options["--action"]) == 1:
+		return dict([(i, ("", "on" if i in images_active else "off")) for i in images_defined])
+	else:
+		status = "error"
+		if options["--plug"].upper() in images_defined:
+			if options["--plug"].upper() in images_active:
+				status = "on"
+			else:
+				status = "off"
+		return status
+
+def set_power_status(conn, options):
+	conn = open_socket(options)
+
+	packet = None
+	if options["--action"] == "on":
+		packet = prepare_smapi_command(options, "Image_Activate", [options["--plug"]])
+	elif options["--action"] == "off":
+		packet = prepare_smapi_command(options, "Image_Deactivate", [options["--plug"], "IMMED"])
+	conn.send(packet)
+
+	request_id = struct.unpack("!i", conn.recv(INT4))[0]
+	(output_len, request_id, return_code, reason_code) = struct.unpack("!iiii", conn.recv(INT4 * 4))
+	logging.debug("Image_(De)Activate results are (%d,%d)", return_code, reason_code)
+
+	conn.close()
+	return
+
+def get_list_of_images(options, command, data_as_plug):
+	conn = open_socket(options)
+
+	packet = prepare_smapi_command(options, command, [data_as_plug])
+	conn.send(packet)
+
+	request_id = struct.unpack("!i", conn.recv(INT4))[0]
+	(output_len, request_id, return_code, reason_code) = struct.unpack("!iiii", conn.recv(INT4 * 4))
+	images = set()
+
+	if output_len > 3*INT4:
+		data = conn.recv(output_len - 3*INT4)
+		array_len = struct.unpack("!i", data[:INT4])[0]
+		parsed_len = INT4
+
+		while parsed_len < array_len:
+			string_len = struct.unpack("!i", data[parsed_len:parsed_len+INT4])[0]
+			parsed_len += INT4
+			image_name = struct.unpack("!%ds" % (string_len), data[parsed_len:parsed_len+string_len])[0]
+			parsed_len += string_len
+			images.add(image_name)
+
+	conn.close()
+	return (return_code, reason_code, images)
+
+def main():
+	device_opt = ["ipaddr", "login", "passwd", "port", "method"]
+
+	atexit.register(atexit_handler)
+
+	all_opt["ipport"]["default"] = "44444"
+	all_opt["shell_timeout"]["default"] = "5.0"
+	options = check_input(device_opt, process_input(device_opt))
+
+	if len(options.get("--plug", "")) > 8:
+		fail_usage("Failed: Name of image can not be longer than 8 characters")
+
+	docs = {}
+	docs["shortdesc"] = "Fence agent for use with z/VM Virtual Machines"
+	docs["longdesc"] = """The fence_zvm agent is intended to be used with with z/VM SMAPI service via TCP/IP
+
+To  use this agent the z/VM SMAPI service needs to be configured to allow the virtual machine running this agent to connect to it and issue
+the image_recycle operation.  This involves updating the VSMWORK1 AUTHLIST VMSYS:VSMWORK1. file. The entry should look something similar to
+this:
+
+Column 1                   Column 66                Column 131
+
+   |                          |                        |
+   V                          V                        V
+
+XXXXXXXX                      ALL                      IMAGE_OPERATIONS
+
+Where XXXXXXX is the name of the virtual machine used in the authuser field of the request.
+"""
+	docs["vendorurl"] = "http://www.ibm.com"
+	show_docs(options, docs)
+
+	result = fence_action(None, options, set_power_status, get_power_status, get_power_status)
+	sys.exit(result)
+
+if __name__ == "__main__":
+	main()
-- 
1.9.3



^ permalink raw reply related	[flat|nested] 2+ messages in thread

* [Cluster-devel] [PATCH] fence_zvmip: Port fence agent to fencing library
@ 2014-12-22 11:25 Marek 'marx' Grac
  0 siblings, 0 replies; 2+ messages in thread
From: Marek 'marx' Grac @ 2014-12-22 11:25 UTC (permalink / raw)
  To: cluster-devel.redhat.com

This rewrite adds a correct result codes, support for 'list' action and
autogenerated manual page. The original code is still part of codebase as
new agent requires additional testing.

Additional fix that makes fence agent work if output information is longer than
MTU.
---
 fence/agents/lib/fencing.py.py  |   4 +
 fence/agents/zvm/Makefile.am    |  26 ++----
 fence/agents/zvm/fence_zvmip.8  |  92 ---------------------
 fence/agents/zvm/fence_zvmip.py | 171 ++++++++++++++++++++++++++++++++++++++++
 4 files changed, 183 insertions(+), 110 deletions(-)
 delete mode 100644 fence/agents/zvm/fence_zvmip.8
 create mode 100644 fence/agents/zvm/fence_zvmip.py

diff --git a/fence/agents/lib/fencing.py.py b/fence/agents/lib/fencing.py.py
index 5449373..c122d96 100644
--- a/fence/agents/lib/fencing.py.py
+++ b/fence/agents/lib/fencing.py.py
@@ -7,6 +7,7 @@ import subprocess
 import threading
 import shlex
 import exceptions
+import socket
 import __main__
 
 ## do not add code here.
@@ -805,6 +806,9 @@ def fence_action(connection, options, set_power_fn, get_power_fn, get_outlet_lis
 	except pycurl.error, ex:
 		logging.error("%s\n", str(ex))
 		fail(EC_TIMED_OUT)
+	except socket.timeout, ex:
+		logging.error("%s\n", str(ex))
+		fail(EC_TIMED_OUT)
 
 	return result
 
diff --git a/fence/agents/zvm/Makefile.am b/fence/agents/zvm/Makefile.am
index 62eb862..a29754d 100644
--- a/fence/agents/zvm/Makefile.am
+++ b/fence/agents/zvm/Makefile.am
@@ -2,26 +2,16 @@ MAINTAINERCLEANFILES	= Makefile.in
 
 TARGET			= fence_zvmip
 
-sbin_PROGRAMS		= fence_zvm fence_zvmip
+SRC			= $(TARGET).py
 
-noinst_HEADERS		= fence_zvm.h
+EXTRA_DIST		= $(SRC)
 
-fence_zvm_SOURCES	= fence_zvm.c
-fence_zvm_CFLAGS	= -D_GNU_SOURCE
+sbin_SCRIPTS		= $(TARGET)
 
-fence_zvmip_SOURCES	= fence_zvmip.c
-fence_zvmip_CFLAGS	= -D_GNU_SOURCE
+man_MANS		= $(TARGET).8
 
-dist_man_MANS		= fence_zvm.8 fence_zvmip.8
+FENCE_TEST_ARGS         = -l test -p test -a test -n 1
 
-#include $(top_srcdir)/make/fencemanc.mk
-
-clean-local:
-	rm -f $(sbin_PROGRAMS)
-
-FENCE_TEST_ARGS		= -n test -a test -p test -u test
-
-include $(top_srcdir)/make/agentccheck.mk
-
-# we do not test fence_zvm because it can be compiled only on specific architecture
-check: xml-check.fence_zvmip delay-check.fence_zvmip
\ No newline at end of file
+include $(top_srcdir)/make/fencebuild.mk
+include $(top_srcdir)/make/fenceman.mk
+include $(top_srcdir)/make/agentpycheck.mk
diff --git a/fence/agents/zvm/fence_zvmip.8 b/fence/agents/zvm/fence_zvmip.8
deleted file mode 100644
index 6b01425..0000000
--- a/fence/agents/zvm/fence_zvmip.8
+++ /dev/null
@@ -1,92 +0,0 @@
-.TH fence_zvmip 8
-
-.SH NAME
-fence_zvmip - Power Fencing agent for GFS on System z z/VM Clusters using IP interface to SMAPI
-
-.SH SYNOPSIS
-.B
-fence_zvmip
-[\fIOPTION\fR]...
-
-.SH DESCRIPTION
-fence_zvmip is a Power Fencing agent used on a GFS virtual machine in a System z z/VM cluster.
-It uses the TCP/IP SMAPI interface to recycle an active image.
-
-fence_zvmip accepts options on the command line as well as from stdin.
-fence_node sends the options through stdin when it execs the agent.
-fence_zvmip can be run by itself with command line options which is useful
-for testing.
-
-Vendor URL: http://www.sinenomine.net
-
-.SH OPTIONS
-.TP
-\fB-o --action\fP
-Fencing action: "off" - deactivate virtual machine; "on" - activate virtual machine; "metadata" - display device metadata" - describe fence agent parameters; "status" - state of virtual machine
-.TP
-\fB--delay\fP \fIseconds\fP
-Time to delay fencing action in seconds
-.TP
-\fB-n --plug\fP \fItarget\fP
-Name of target virtual machine to fence
-.TP
-\fB-h --help\fP
-Print out a help message describing available options, then exit.
-.TP
-\fB-a --ip\fP \fIsmapi Server\fP
-Host name or IP address of SMAPI server
-.TP
-\fB-u --username\fP \fISMAPI authorized user\fP
-Name of an authorized SMAPI user
-.TP
-\fB-p --password\fP \fISMAPI authorized user's password\fP
-Password of the authorized SMAPI user
-.TP
-\fB-t --timeout\fP \fIRecycle timeout\fP
-Amount of \fIgrace\fP time to give the virtual machine to shutdown cleanly before being
-forcibly terminated. Currently this is ignored.
-.TP
-\fB-h --help\fP
-Display usage information
-
-.SH STDIN PARAMETERS
-.TP
-\fIagent = < param >\fP
-This option is used by fence_node(8) and is ignored by fence_zvmip.
-.TP
-\fIaction = < action >\fP
-Fencing action: "off" - deactivate virtual machine; "on" - activate virtual machine; "metadata" - display device metadata" - describe fence agent parameters; "status" - state of virtual machine
-.TP
-\fIplug = < plug >\fP
-Name of virtual machine to recycle.
-.TP
-\fIipaddr = < server host name or IP address >\fP
-Host name or IP address of SMAPI server
-.TP
-\fIlogin = < SMAPI authorized user >\fP
-Name of an authorized SMAPI user
-.TP
-\fIpasswd = < SMAPI authorized user's password >\fP
-Password of the authorized SMAPI user
-.TP
-\fItimeout = < shutdown timeout >\fP
-Amount of \fIgrace\fP time to give the virtual machine to shutdown cleanly before being
-forcibly terminated. Currently this is ignored.
-
-.SH SEE ALSO
-fence(8), fenced(8), fence_node(8)
-
-.SH NOTES
-To use this agent the z/VM SMAPI service needs to be configured to allow the virtual
-machine running this agent to connect to it and issue the image_recycle operation.
-This involves updating the VSMWORK1 AUTHLIST VMSYS:VSMWORK1. file. The entry should look
-something similar to this:
-
-.nf
-Column 1                   Column 66                Column 131
-|                          |                        |
-V                          V                        V
-XXXXXXXX                   ALL                      IMAGE_OPERATIONS
-.fi
-
-Where XXXXXXX is the name of the virtual machine used in the authuser field of the request. 
diff --git a/fence/agents/zvm/fence_zvmip.py b/fence/agents/zvm/fence_zvmip.py
new file mode 100644
index 0000000..797186a
--- /dev/null
+++ b/fence/agents/zvm/fence_zvmip.py
@@ -0,0 +1,171 @@
+#!/usr/bin/python -tt
+
+import sys
+import atexit
+import socket
+import struct
+import logging
+sys.path.append("@FENCEAGENTSLIBDIR@")
+from fencing import *
+from fencing import fail, EC_LOGIN_DENIED, EC_TIMED_OUT
+
+#BEGIN_VERSION_GENERATION
+RELEASE_VERSION=""
+REDHAT_COPYRIGHT=""
+BUILD_DATE=""
+#END_VERSION_GENERATION
+
+INT4 = 4
+
+def open_socket(options):
+	try:
+		if "--inet6-only" in options:
+			protocol = socket.AF_INET6
+		elif "--inet4-only" in options:
+			protocol = socket.AF_INET
+		else:
+			protocol = 0
+		(_, _, _, _, addr) = socket.getaddrinfo( \
+				options["--ip"], options["--ipport"], protocol,
+				0, socket.IPPROTO_TCP, socket.AI_PASSIVE
+				)[0]
+	except socket.gaierror:
+		fail(EC_LOGIN_DENIED)
+
+	conn = socket.socket()
+	conn.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
+	conn.settimeout(float(options["--shell-timeout"]))
+	try:
+		conn.connect(addr)
+	except socket.error:
+		fail(EC_LOGIN_DENIED)
+
+	return conn
+
+def smapi_pack_string(string):
+	return struct.pack("!i%ds" % (len(string)), len(string), string)
+
+def prepare_smapi_command(options, smapi_function, additional_args):
+	packet_size = 3*INT4 + len(smapi_function) + len(options["--username"]) + len(options["--password"])
+	for arg in additional_args:
+		packet_size += INT4 + len(arg)
+
+	command = struct.pack("!i", packet_size)
+	command += smapi_pack_string(smapi_function)
+	command += smapi_pack_string(options["--username"])
+	command += smapi_pack_string(options["--password"])
+	for arg in additional_args:
+		command += smapi_pack_string(arg)
+
+	return command
+
+def get_power_status(conn, options):
+	del conn
+
+	# '*' = list all active images
+	(return_code, reason_code, images_active) = \
+			get_list_of_images(options, "Image_Status_Query", "*")
+	logging.debug("Image_Status_Query results are (%d,%d)", return_code, reason_code)
+	(return_code, reason_code, images_defined) = \
+			get_list_of_images(options, "Image_Name_Query_DM", options["--username"])
+	logging.debug("Image_Name_Query_DM results are (%d,%d)", return_code, reason_code)
+
+	if ["list", "monitor"].count(options["--action"]) == 1:
+		return dict([(i, ("", "on" if i in images_active else "off")) for i in images_defined])
+	else:
+		status = "error"
+		if options["--plug"].upper() in images_defined:
+			if options["--plug"].upper() in images_active:
+				status = "on"
+			else:
+				status = "off"
+		return status
+
+def set_power_status(conn, options):
+	conn = open_socket(options)
+
+	packet = None
+	if options["--action"] == "on":
+		packet = prepare_smapi_command(options, "Image_Activate", [options["--plug"]])
+	elif options["--action"] == "off":
+		packet = prepare_smapi_command(options, "Image_Deactivate", [options["--plug"], "IMMED"])
+	conn.send(packet)
+
+	request_id = struct.unpack("!i", conn.recv(INT4))[0]
+	(output_len, request_id, return_code, reason_code) = struct.unpack("!iiii", conn.recv(INT4 * 4))
+	logging.debug("Image_(De)Activate results are (%d,%d)", return_code, reason_code)
+
+	conn.close()
+	return
+
+def get_list_of_images(options, command, data_as_plug):
+	conn = open_socket(options)
+
+	packet = prepare_smapi_command(options, command, [data_as_plug])
+	conn.send(packet)
+
+	request_id = struct.unpack("!i", conn.recv(INT4))[0]
+	(output_len, request_id, return_code, reason_code) = struct.unpack("!iiii", conn.recv(INT4 * 4))
+	images = set()
+
+	if output_len > 3*INT4:
+		array_len = struct.unpack("!i", conn.recv(INT4))[0]
+		data = ""
+
+		while True:
+			read_data = conn.recv(1024, socket.MSG_WAITALL)
+			data += read_data
+			if array_len == len(data):
+				break
+			elif not read_data:
+				logging.error("Failed: Not enough data read from socket")
+				fail(EC_TIMED_OUT)
+
+		parsed_len = 0
+		while parsed_len < array_len:
+			string_len = struct.unpack("!i", data[parsed_len:parsed_len+INT4])[0]
+			parsed_len += INT4
+			image_name = struct.unpack("!%ds" % (string_len), data[parsed_len:parsed_len+string_len])[0]
+			parsed_len += string_len
+			images.add(image_name)
+
+	conn.close()
+	return (return_code, reason_code, images)
+
+def main():
+	device_opt = ["ipaddr", "login", "passwd", "port", "method"]
+
+	atexit.register(atexit_handler)
+
+	all_opt["ipport"]["default"] = "44444"
+	all_opt["shell_timeout"]["default"] = "5.0"
+	options = check_input(device_opt, process_input(device_opt))
+
+	if len(options.get("--plug", "")) > 8:
+		fail_usage("Failed: Name of image can not be longer than 8 characters")
+
+	docs = {}
+	docs["shortdesc"] = "Fence agent for use with z/VM Virtual Machines"
+	docs["longdesc"] = """The fence_zvm agent is intended to be used with with z/VM SMAPI service via TCP/IP
+
+To  use this agent the z/VM SMAPI service needs to be configured to allow the virtual machine running this agent to connect to it and issue
+the image_recycle operation.  This involves updating the VSMWORK1 AUTHLIST VMSYS:VSMWORK1. file. The entry should look something similar to
+this:
+
+Column 1                   Column 66                Column 131
+
+   |                          |                        |
+   V                          V                        V
+
+XXXXXXXX                      ALL                      IMAGE_OPERATIONS
+
+Where XXXXXXX is the name of the virtual machine used in the authuser field of the request.
+"""
+	docs["vendorurl"] = "http://www.ibm.com"
+	show_docs(options, docs)
+
+	result = fence_action(None, options, set_power_status, get_power_status, get_power_status)
+	sys.exit(result)
+
+if __name__ == "__main__":
+	main()
-- 
1.9.3



^ permalink raw reply related	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2014-12-22 11:25 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2014-12-22 11:25 [Cluster-devel] [PATCH] fence_zvmip: Port fence agent to fencing library Marek 'marx' Grac
  -- strict thread matches above, loose matches on Subject: below --
2014-12-22  9:07 Marek 'marx' Grac

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