Skip to contentSkip to conversation

New fencing script for Citrix XenServer and XCP.

PATCH New Matt Clark 2 participants 10 messages Apr 20, 2011

lore
Share & tools
lore

Matt Clark

author
#0 lore raw

PATCH 1/5 New fencing script for Citrix XenServer and XCP.

Fencing script that uses the XenAPI to allow remote switch, status and list of virtual machines running on Citrix XenServer and Xen Cloud Platform hosts.

---
 fence/agents/xenapi/Makefile.am     |   17 +++
 fence/agents/xenapi/XenAPI.py       |  209 ++++++++++++++++++++++++++++++++
 fence/agents/xenapi/fence_xenapi.py |  227 +++++++++++++++++++++++++++++++++++
 3 files changed, 453 insertions(+), 0 deletions(-)
 create mode 100644 fence/agents/xenapi/Makefile.am
 create mode 100755 fence/agents/xenapi/XenAPI.py
 create mode 100644 fence/agents/xenapi/fence_xenapi.py
fence/agents/xenapi/Makefile.am new file +17 -0
new file mode 100644
index 0000000..781975e
@@ -0,0 +1,17 @@
+MAINTAINERCLEANFILES	= Makefile.in
+
+TARGET			= fence_xenapi
+
+SRC			= $(TARGET).py
+
+EXTRA_DIST		= $(SRC)
+
+sbin_SCRIPTS		= $(TARGET)
+
+man_MANS		= $(TARGET).8
+
+include $(top_srcdir)/make/fencebuild.mk
+include $(top_srcdir)/make/fenceman.mk
+
+clean-local: clean-man
+	rm -f $(TARGET)
fence/agents/xenapi/XenAPI.py new file +209 -0

209 lines not on this page · raw message

fence/agents/xenapi/fence_xenapi.py new file +227 -0

227 lines not on this page · raw message

Signature · 1 line
1.7.0.4
author
#1 lore raw

PATCH 2/5 Updated to include xenapi script.

---
 configure.ac |    1 +
 1 files changed, 1 insertions(+), 0 deletions(-)
configure.ac +1 -0
index d8994d2..d71f6e4 100644
@@ -256,6 +256,7 @@ AC_CONFIG_FILES([Makefile
 		 fence/agents/vmware_soap/Makefile
 		 fence/agents/wti/Makefile
 		 fence/agents/xcat/Makefile
+		 fence/agents/xenapi/Makefile
 		 fence/agents/zvm/Makefile
 		 doc/Makefile])
 
Signature · 1 line
1.7.0.4
author
#2 lore raw

PATCH 3/5 Updated to include xenapi script in Makefile.am.

In reply to Matt Clark
---
 fence/agents/Makefile.am            |    1 +
 1 files changed, 1 insertions(+), 0 deletions(-)
 mode change 100644 => 100755 fence/agents/xenapi/fence_xenapi.py
fence/agents/Makefile.am +1 -0
index e2f445f..ff3dbf7 100644
@@ -40,4 +40,5 @@ SUBDIRS 		= lib \
 			  vmware_soap \
 			  wti \
 			  xcat \
+			  xenapi \
 			  zvm
fence/agents/xenapi/fence_xenapi.py +0 -0
old mode 100644
new mode 100755
Signature · 1 line
1.7.0.4
author
#3 lore raw

PATCH 4/5 Clean up of fence_xenapi patches. Moved XenAPI.py to lib directory and added to Makefile.am.

In reply to Matt Clark
---
 fence/agents/lib/XenAPI.py.py |  209 +++++++++++++++++++++++++++++++++++++++++
 fence/agents/xenapi/XenAPI.py |  209 -----------------------------------------
 2 files changed, 209 insertions(+), 209 deletions(-)
 create mode 100755 fence/agents/lib/XenAPI.py.py
 delete mode 100755 fence/agents/xenapi/XenAPI.py
fence/agents/lib/XenAPI.py.py new file +209 -0
new file mode 100755
index 0000000..4f27ef5
@@ -0,0 +1,209 @@
+#============================================================================
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of version 2.1 of the GNU Lesser General Public
+# License as published by the Free Software Foundation.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+#============================================================================
+# Copyright (C) 2006 XenSource Inc.
+#============================================================================
+#
+# Parts of this file are based upon xmlrpclib.py, the XML-RPC client
+# interface included in the Python distribution.
+#
+# Copyright (c) 1999-2002 by Secret Labs AB
+# Copyright (c) 1999-2002 by Fredrik Lundh
+#
+# By obtaining, using, and/or copying this software and/or its
+# associated documentation, you agree that you have read, understood,
+# and will comply with the following terms and conditions:
+#
+# Permission to use, copy, modify, and distribute this software and
+# its associated documentation for any purpose and without fee is
+# hereby granted, provided that the above copyright notice appears in
+# all copies, and that both that copyright notice and this permission
+# notice appear in supporting documentation, and that the name of
+# Secret Labs AB or the author not be used in advertising or publicity
+# pertaining to distribution of the software without specific, written
+# prior permission.
+#
+# SECRET LABS AB AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD
+# TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANT-
+# ABILITY AND FITNESS.  IN NO EVENT SHALL SECRET LABS AB OR THE AUTHOR
+# BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY
+# DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+# WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
+# ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
+# OF THIS SOFTWARE.
+# --------------------------------------------------------------------
+
+import gettext
+import xmlrpclib
+import httplib
+import socket
+
+translation = gettext.translation('xen-xm', fallback = True)
+
+class Failure(Exception):
+    def __init__(self, details):
+        try:
+            # If this failure is MESSAGE_PARAMETER_COUNT_MISMATCH, then we
+            # correct the return values here, to account for the fact that we
+            # transparently add the session handle as the first argument.
+            if details[0] == 'MESSAGE_PARAMETER_COUNT_MISMATCH':
+                details[2] = str(int(details[2]) - 1)
+                details[3] = str(int(details[3]) - 1)
+
+            self.details = details
+        except Exception, exn:
+            self.details = ['INTERNAL_ERROR', 'Client-side: ' + str(exn)]
+
+    def __str__(self):
+        try:
+            return translation.ugettext(self.details[0]) % self._details_map()
+        except TypeError, exn:
+            return "Message database broken: %s.\nXen-API failure: %s" % \
+                   (exn, str(self.details))
+        except Exception, exn:
+            import sys
+            print >>sys.stderr, exn
+            return "Xen-API failure: %s" % str(self.details)
+
+    def _details_map(self):
+        return dict([(str(i), self.details[i])
+                     for i in range(len(self.details))])
+
+
+_RECONNECT_AND_RETRY = (lambda _ : ())
+
+class UDSHTTPConnection(httplib.HTTPConnection):
+    """ Stupid hacked up HTTPConnection subclass to allow HTTP over Unix domain
+    sockets. """
+    def connect(self):
+        path = self.host.replace("_", "/")
+        self.sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
+        self.sock.connect(path)
+
+class UDSHTTP(httplib.HTTP):
+    _connection_class = UDSHTTPConnection
+
+class UDSTransport(xmlrpclib.Transport):
+    def make_connection(self, host):
+        return UDSHTTP(host)
+
+class Session(xmlrpclib.ServerProxy):
+    """A server proxy and session manager for communicating with Xend using
+    the Xen-API.
+
+    Example:
+
+    session = Session('http://localhost:9363/')
+    session.login_with_password('me', 'mypassword')
+    session.xenapi.VM.start(vm_uuid)
+    session.xenapi.session.logout()
+
+    For now, this class also supports the legacy XML-RPC API, using
+    session.xend.domain('Domain-0') and similar.  This support will disappear
+    once there is a working Xen-API replacement for every call in the legacy
+    API.
+    """
+
+    def __init__(self, uri, transport=None, encoding=None, verbose=0,
+                 allow_none=1):
+        xmlrpclib.ServerProxy.__init__(self, uri, transport, encoding,
+                                       verbose, allow_none)
+        self._session = None
+        self.last_login_method = None
+        self.last_login_params = None
+
+
+    def xenapi_request(self, methodname, params):
+        if methodname.startswith('login'):
+            self._login(methodname, params)
+            return None
+        else:
+            retry_count = 0
+            while retry_count < 3:
+                full_params = (self._session,) + params
+                result = _parse_result(getattr(self, methodname)(*full_params))
+                if result == _RECONNECT_AND_RETRY:
+                    retry_count += 1
+                    if self.last_login_method:
+                        self._login(self.last_login_method,
+                                    self.last_login_params)
+                    else:
+                        raise xmlrpclib.Fault(401, 'You must log in')
+                else:
+                    return result
+            raise xmlrpclib.Fault(
+                500, 'Tried 3 times to get a valid session, but failed')
+
+
+    def _login(self, method, params):
+        result = _parse_result(getattr(self, 'session.%s' % method)(*params))
+        if result == _RECONNECT_AND_RETRY:
+            raise xmlrpclib.Fault(
+                500, 'Received SESSION_INVALID when logging in')
+        self._session = result
+        self.last_login_method = method
+        self.last_login_params = params
+
+
+    def __getattr__(self, name):
+        if name == 'xenapi':
+            return _Dispatcher(self.xenapi_request, None)
+        elif name.startswith('login'):
+            return lambda *params: self._login(name, params)
+        else:
+            return xmlrpclib.ServerProxy.__getattr__(self, name)
+
+def xapi_local():
+    return Session("http://_var_xapi_xapi/", transport=UDSTransport())
+
+def _parse_result(result):
+    if type(result) != dict or 'Status' not in result:
+        raise xmlrpclib.Fault(500, 'Missing Status in response from server' + result)
+    if result['Status'] == 'Success':
+        if 'Value' in result:
+            return result['Value']
+        else:
+            raise xmlrpclib.Fault(500,
+                                  'Missing Value in response from server')
+    else:
+        if 'ErrorDescription' in result:
+            if result['ErrorDescription'][0] == 'SESSION_INVALID':
+                return _RECONNECT_AND_RETRY
+            else:
+                raise Failure(result['ErrorDescription'])
+        else:
+            raise xmlrpclib.Fault(
+                500, 'Missing ErrorDescription in response from server')
+
+
+# Based upon _Method from xmlrpclib.
+class _Dispatcher:
+    def __init__(self, send, name):
+        self.__send = send
+        self.__name = name
+
+    def __repr__(self):
+        if self.__name:
+            return '<XenAPI._Dispatcher for %s>' % self.__name
+        else:
+            return '<XenAPI._Dispatcher>'
+
+    def __getattr__(self, name):
+        if self.__name is None:
+            return _Dispatcher(self.__send, name)
+        else:
+            return _Dispatcher(self.__send, "%s.%s" % (self.__name, name))
+
+    def __call__(self, *args):
+        return self.__send(self.__name, args)
fence/agents/xenapi/XenAPI.py deleted +0 -209

209 lines not on this page · raw message

Signature · 1 line
1.7.0.4
author
#4 lore raw

PATCH 5/5 Cleanup of fence_xenapi patches. Added copyright information to doc/COPYRIGHT. Fixed static reference to lib directory in fence_xenapi.py. Fixed static reference to RELEASE_VERSION and BUILD_DATE in fence_xenapi.py.

In reply to Matt Clark
---
 doc/COPYRIGHT                       |    4 ++++
 fence/agents/lib/Makefile.am        |    4 ++--
 fence/agents/xenapi/fence_xenapi.py |   12 ++++++++----
 3 files changed, 14 insertions(+), 6 deletions(-)
doc/COPYRIGHT +4 -0
index b10071c..5afc642 100644
@@ -5,6 +5,10 @@ Copyright (C) 2004-2011 Red Hat, Inc.  All rights reserved.
 
 Exceptions:
 
+fence/agents/xenapi/*:
+ Copyright (C) 2011 Matthew Clark.
+ Author: Matthew Clark <[email protected]>
+ 
 fence/agents/apc_snmp/powernet369.mib:
  Copyright (c) 2005 American Power Conversion, Inc.
  PowerNet is a Trademark of American Power Conversion Corp.
fence/agents/lib/Makefile.am +2 -2
index b42fc12..aa6d072 100644
@@ -1,8 +1,8 @@
 MAINTAINERCLEANFILES	= Makefile.in
 
-TARGET			= fencing.py fencing_snmp.py
+TARGET			= fencing.py fencing_snmp.py XenAPI.py
 
-SRC			= fencing.py.py fencing_snmp.py.py
+SRC			= fencing.py.py fencing_snmp.py.py XenAPI.py.py
 
 EXTRA_DIST		= $(SRC) fence2man.xsl
 
fence/agents/xenapi/fence_xenapi.py +8 -4
index 0657f4e..cae53e6 100755
@@ -1,7 +1,7 @@
 #!/usr/bin/python
 #
 #############################################################################
-# Copyright 2011 Matt Clark
+# Copyright 2011 Matthew Clark
 # This file is part of fence-xenserver
 #
 # fence-xenserver is free software: you can redistribute it and/or modify
@@ -32,10 +32,16 @@
 # whether I should continue support for it. mattjclark0407 at hotmail dot com
 
 import sys
-sys.path.append("/usr/lib/fence")
+sys.path.append("@FENCEAGENTSLIBDIR@")
 from fencing import *
 import XenAPI
 
+#BEGIN_VERSION_GENERATION
+RELEASE_VERSION=""
+REDHAT_COPYRIGHT=""
+BUILD_DATE=""
+#END_VERSION_GENERATION
+
 EC_BAD_SESSION 		= 1
 # Find the status of the port given in the -U flag of options.
 def get_power_fn(session, options):
@@ -223,5 +229,3 @@ the status of virtual machines running on the host."
 
 if __name__ == "__main__":
 	main()
-RELEASE_VERSION="3.1.2.11-2b5b-dirty"
-BUILD_DATE="(built Fri Mar 25 22:57:28 EST 2011)"
Signature · 1 line
1.7.0.4
#5 lore raw

PATCH 5/5 Cleanup of fence_xenapi patches. Added copyright information to doc/COPYRIGHT. Fixed static reference to lib directory in fence_xenapi.py. Fixed static reference to RELEASE_VERSION and BUILD_DATE in fence_xenapi.py.

Quoted 5 lines · Matt Clark
---
 doc/COPYRIGHT                       |    4 ++++
 fence/agents/lib/Makefile.am        |    4 ++--
 fence/agents/xenapi/fence_xenapi.py |   12 ++++++++----
 3 files changed, 14 insertions(+), 6 deletions(-)

You forgot to move the xenapi file in lib/ ?

Fabio

author
#6 lore raw

PATCH 5/5 Cleanup of fence_xenapi patches. Added copyright information to doc/COPYRIGHT. Fixed static reference to lib directory in fence_xenapi.py. Fixed static reference to RELEASE_VERSION and BUILD_DATE in fence_xenapi.py.

Patch 4/5 takes care of that. At least it should have...

Quoted 12 lines

Date: Wed, 20 Apr 2011 16:04:46 +0200
From: fdinitto at redhat.com
To: cluster-devel at redhat.com
Subject: Re: [Cluster-devel] [PATCH 5/5] Cleanup of fence_xenapi patches. Added copyright information to doc/COPYRIGHT. Fixed static reference to lib directory in fence_xenapi.py. Fixed static reference to RELEASE_VERSION and BUILD_DATE in fence_xenapi.py.

Quoted 5 lines · Matt Clark
---
 doc/COPYRIGHT                       |    4 ++++
 fence/agents/lib/Makefile.am        |    4 ++--
 fence/agents/xenapi/fence_xenapi.py |   12 ++++++++----
 3 files changed, 14 insertions(+), 6 deletions(-)
Quoted 4 lines

You forgot to move the xenapi file in lib/ ?

Fabio

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://listman.redhat.com/archives/cluster-devel/attachments/20110421/221e4271/attachment.htm>

#7 lore raw

PATCH 5/5 Cleanup of fence_xenapi patches. Added copyright information to doc/COPYRIGHT. Fixed static reference to lib directory in fence_xenapi.py. Fixed static reference to RELEASE_VERSION and BUILD_DATE in fence_xenapi.py.

Quoted 2 lines · Matt Clark

Patch 4/5 takes care of that. At least it should have...

Then something is wrong with the patch ordering because 4/4 renames but 5 changes the old path?

Fabio

Quoted 19 lines
Quoted 4 lines

Date: Wed, 20 Apr 2011 16:04:46 +0200
From: fdinitto at redhat.com
To: cluster-devel at redhat.com
Subject: Re: [Cluster-devel] [PATCH 5/5] Cleanup of fence_xenapi

patches. Added copyright information to doc/COPYRIGHT. Fixed static reference to lib directory in fence_xenapi.py. Fixed static reference to RELEASE_VERSION and BUILD_DATE in fence_xenapi.py.

Quoted 12 lines · Matt Clark
Quoted 5 lines

---
doc/COPYRIGHT | 4 ++++ fence/agents/lib/Makefile.am | 4 ++-- fence/agents/xenapi/fence_xenapi.py | 12 ++++++++----

3 files changed, 14 insertions(+), 6 deletions(-)

You forgot to move the xenapi file in lib/ ?

Fabio

author
#8 lore raw

PATCH 5/5 Cleanup of fence_xenapi patches. Added copyright information to doc/COPYRIGHT. Fixed static reference to lib directory in fence_xenapi.py. Fixed static reference to RELEASE_VERSION and BUILD_DATE in fence_xenapi.py.

Patch 5/5 only touches the 3 files listed in your original email.
The script fence_xenapi.py is the script that does the fencing, not the library.
XenAPI.py is the underlying library which is now located in lib/ as of patch 4/50004-Clean-up-of-fence_xenapi-patches.patch: fence/agents/lib/XenAPI.py.py | 209 +++++++++++++++++++++++++++++++++++++++++0004-Clean-up-of-fence_xenapi-patches.patch: fence/agents/xenapi/XenAPI.py | 209 ----------------------------------------- Unless I am missing something... Which is quite possible.

Quoted 5 lines

Date: Wed, 20 Apr 2011 17:32:23 +0200
From: fdinitto at redhat.com
To: cluster-devel at redhat.com
Subject: Re: [Cluster-devel] [PATCH 5/5] Cleanup of fence_xenapi patches. Added copyright information to doc/COPYRIGHT. Fixed static reference to lib directory in fence_xenapi.py. Fixed static reference to RELEASE_VERSION and BUILD_DATE in fence_xenapi.py.

Quoted 29 lines
Quoted 2 lines · Matt Clark

Patch 4/5 takes care of that. At least it should have...

Then something is wrong with the patch ordering because 4/4 renames but 5 changes the old path?

Fabio

Quoted 19 lines
Quoted 4 lines

Date: Wed, 20 Apr 2011 16:04:46 +0200
From: fdinitto at redhat.com
To: cluster-devel at redhat.com
Subject: Re: [Cluster-devel] [PATCH 5/5] Cleanup of fence_xenapi

patches. Added copyright information to doc/COPYRIGHT. Fixed static reference to lib directory in fence_xenapi.py. Fixed static reference to RELEASE_VERSION and BUILD_DATE in fence_xenapi.py.

Quoted 12 lines · Matt Clark
Quoted 5 lines

---
doc/COPYRIGHT | 4 ++++ fence/agents/lib/Makefile.am | 4 ++-- fence/agents/xenapi/fence_xenapi.py | 12 ++++++++----

3 files changed, 14 insertions(+), 6 deletions(-)

You forgot to move the xenapi file in lib/ ?

Fabio

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://listman.redhat.com/archives/cluster-devel/attachments/20110421/223cfd1a/attachment.htm>

#9 lore raw

PATCH 5/5 Cleanup of fence_xenapi patches. Added copyright information to doc/COPYRIGHT. Fixed static reference to lib directory in fence_xenapi.py. Fixed static reference to RELEASE_VERSION and BUILD_DATE in fence_xenapi.py.

Quoted 14 lines · Matt Clark

Patch 5/5 only touches the 3 files listed in your original email.

The script fence_xenapi.py is the script that does the fencing, not the library.

XenAPI.py is the underlying library which is now located in lib/ as of patch 4/5
0004-Clean-up-of-fence_xenapi-patches.patch:
fence/agents/lib/XenAPI.py.py | 209
+++++++++++++++++++++++++++++++++++++++++
0004-Clean-up-of-fence_xenapi-patches.patch:
fence/agents/xenapi/XenAPI.py | 209
-----------------------------------------

Quoted 1 line

Unless I am missing something... Which is quite possible.

Whooops... I got confused by the two names...

Ok time for me to go on vacation and relax.

Marek, can you please merge the patchset when you are around (git am ..) ?

Thanks
Fabio