XenAPI 1.2__tar.gz → 23.8.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
XenAPI-23.8.0/Makefile ADDED
@@ -0,0 +1,12 @@
1
+ PROFILE=release
2
+ SETUPTOOLS_SCM_PRETEND_VERSION ?= ""
3
+
4
+ .PHONY: build clean
5
+
6
+ build:
7
+ SETUPTOOLS_SCM_PRETEND_VERSION=$(XAPI_VERSION) python -m build --wheel .
8
+ SETUPTOOLS_SCM_PRETEND_VERSION=$(XAPI_VERSION) python -m build --sdist .
9
+
10
+ clean:
11
+ dune clean
12
+ rm -rf dist/ build/ XenAPI.egg-info/
XenAPI-23.8.0/PKG-INFO ADDED
@@ -0,0 +1,37 @@
1
+ Metadata-Version: 2.1
2
+ Name: XenAPI
3
+ Version: 23.8.0
4
+ Summary: XenAPI SDK, for communication with XenServer.
5
+ Home-page: https://www.citrix.com/community/citrix-developer/citrix-hypervisor-developer/
6
+ Author: Citrix Systems, Inc.
7
+ Author-email: xen-api@lists.xenproject.org
8
+ License: BSD-2-Clause
9
+ Project-URL: Bug Tracker, https://github.com/xapi-project/xen-api/issues
10
+ Project-URL: Source Code, https://github.com/xapi-project/xen-api
11
+ Classifier: License :: OSI Approved :: BSD License
12
+ Classifier: Development Status :: 6 - Mature
13
+ Classifier: Intended Audience :: Developers
14
+ Classifier: Topic :: System :: Systems Administration
15
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
16
+ Requires-Python: !=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,<4,>=2.7
17
+ Description-Content-Type: text/markdown; charset=UTF-8
18
+
19
+ Usage
20
+ =====
21
+
22
+ To install the package, enable the virtual environment where it's going to be used and run
23
+ `$ pip install XenAPI`
24
+
25
+ Examples
26
+ --------
27
+
28
+ The [examples](https://github.com/xapi-project/xen-api/tree/master/scripts/examples/python) will not work unless they have been placed in the same directory as `XenAPI.py` or `XenAPI` package from PyPI has been installed (`pip install XenAPI`)
29
+
30
+ Packaging
31
+ =========
32
+
33
+ `setup.py` is generated using an ocaml binary that fetches the api version string from xapi. An opam switch with the [xs-opam](https://github.com/xapi-project/xs-opam) repository is needed in order to build the binary.
34
+
35
+ To build the package `setuptools>=38.6.0` and `wheel` need to be installed in the system or in the active python virtualenv.
36
+
37
+ To build, use the command `make`.
@@ -0,0 +1,19 @@
1
+ Usage
2
+ =====
3
+
4
+ To install the package, enable the virtual environment where it's going to be used and run
5
+ `$ pip install XenAPI`
6
+
7
+ Examples
8
+ --------
9
+
10
+ The [examples](https://github.com/xapi-project/xen-api/tree/master/scripts/examples/python) will not work unless they have been placed in the same directory as `XenAPI.py` or `XenAPI` package from PyPI has been installed (`pip install XenAPI`)
11
+
12
+ Packaging
13
+ =========
14
+
15
+ `setup.py` is generated using an ocaml binary that fetches the api version string from xapi. An opam switch with the [xs-opam](https://github.com/xapi-project/xs-opam) repository is needed in order to build the binary.
16
+
17
+ To build the package `setuptools>=38.6.0` and `wheel` need to be installed in the system or in the active python virtualenv.
18
+
19
+ To build, use the command `make`.
@@ -1,20 +1,30 @@
1
- #============================================================================
2
- # This library is free software; you can redistribute it and/or
3
- # modify it under the terms of version 2.1 of the GNU Lesser General Public
4
- # License as published by the Free Software Foundation.
1
+ # Copyright (c) Citrix Systems, Inc.
2
+ # All rights reserved.
5
3
  #
6
- # This library is distributed in the hope that it will be useful,
7
- # but WITHOUT ANY WARRANTY; without even the implied warranty of
8
- # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
9
- # Lesser General Public License for more details.
4
+ # Redistribution and use in source and binary forms, with or without
5
+ # modification, are permitted provided that the following conditions are
6
+ # met:
10
7
  #
11
- # You should have received a copy of the GNU Lesser General Public
12
- # License along with this library; if not, write to the Free Software
13
- # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
14
- #============================================================================
15
- # Copyright (C) 2006-2007 XenSource Inc.
16
- #============================================================================
8
+ # 1) Redistributions of source code must retain the above copyright
9
+ # notice, this list of conditions and the following disclaimer.
17
10
  #
11
+ # 2) Redistributions in binary form must reproduce the above copyright
12
+ # notice, this list of conditions and the following disclaimer in
13
+ # the documentation and/or other materials provided with the
14
+ # distribution.
15
+ #
16
+ # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17
+ # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18
+ # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19
+ # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20
+ # HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21
+ # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22
+ # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23
+ # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24
+ # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25
+ # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26
+ # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27
+ # --------------------------------------------------------------------
18
28
  # Parts of this file are based upon xmlrpclib.py, the XML-RPC client
19
29
  # interface included in the Python distribution.
20
30
  #
@@ -45,9 +55,16 @@
45
55
  # --------------------------------------------------------------------
46
56
 
47
57
  import gettext
48
- import xmlrpclib
49
- import httplib
50
58
  import socket
59
+ import sys
60
+
61
+ if sys.version_info[0] == 2:
62
+ import httplib as httplib
63
+ import xmlrpclib as xmlrpclib
64
+ else:
65
+ import http.client as httplib
66
+ import xmlrpc.client as xmlrpclib
67
+
51
68
 
52
69
  translation = gettext.translation('xen-xm', fallback = True)
53
70
 
@@ -61,17 +78,18 @@ class Failure(Exception):
61
78
  def __str__(self):
62
79
  try:
63
80
  return str(self.details)
64
- except Exception, exn:
65
- import sys
66
- print >>sys.stderr, exn
67
- return "Xen-API failure: %s" % str(self.details)
81
+ except Exception as exn:
82
+ msg = "Xen-API failure: %s" % exn
83
+ sys.stderr.write(msg)
84
+ return msg
68
85
 
69
86
  def _details_map(self):
70
87
  return dict([(str(i), self.details[i])
71
88
  for i in range(len(self.details))])
72
89
 
73
90
 
74
- _RECONNECT_AND_RETRY = (lambda _ : ())
91
+ # Just a "constant" that we use to decide whether to retry the RPC
92
+ _RECONNECT_AND_RETRY = object()
75
93
 
76
94
  class UDSHTTPConnection(httplib.HTTPConnection):
77
95
  """HTTPConnection subclass to allow HTTP over Unix domain sockets. """
@@ -80,22 +98,15 @@ class UDSHTTPConnection(httplib.HTTPConnection):
80
98
  self.sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
81
99
  self.sock.connect(path)
82
100
 
83
- class UDSHTTP(httplib.HTTP):
84
- _connection_class = UDSHTTPConnection
85
-
86
101
  class UDSTransport(xmlrpclib.Transport):
87
- def __init__(self, use_datetime=0):
88
- self._use_datetime = use_datetime
89
- self._extra_headers=[]
90
102
  def add_extra_header(self, key, value):
91
103
  self._extra_headers += [ (key,value) ]
92
104
  def make_connection(self, host):
93
- return UDSHTTP(host)
94
- def send_request(self, connection, handler, request_body):
95
- connection.putrequest("POST", handler)
96
- for key, value in self._extra_headers:
97
- connection.putheader(key, value)
98
-
105
+ return UDSHTTPConnection(host)
106
+
107
+ def notimplemented(name, *args, **kwargs):
108
+ raise NotImplementedError("XMLRPC proxies do not support python magic methods", name, *args, **kwargs)
109
+
99
110
  class Session(xmlrpclib.ServerProxy):
100
111
  """A server proxy and session manager for communicating with xapi using
101
112
  the Xen-API.
@@ -103,15 +114,25 @@ class Session(xmlrpclib.ServerProxy):
103
114
  Example:
104
115
 
105
116
  session = Session('http://localhost/')
106
- session.login_with_password('me', 'mypassword')
117
+ session.login_with_password('me', 'mypassword', '1.0', 'xen-api-scripts-xenapi.py')
107
118
  session.xenapi.VM.start(vm_uuid)
108
119
  session.xenapi.session.logout()
109
120
  """
110
121
 
111
122
  def __init__(self, uri, transport=None, encoding=None, verbose=0,
112
- allow_none=1):
113
- xmlrpclib.ServerProxy.__init__(self, uri, transport, encoding,
114
- verbose, allow_none)
123
+ allow_none=1, ignore_ssl=False):
124
+
125
+ # Fix for CA-172901 (+ Python 2.4 compatibility)
126
+ # Fix for context=ctx ( < Python 2.7.9 compatibility)
127
+ if not (sys.version_info[0] <= 2 and sys.version_info[1] <= 7 and sys.version_info[2] <= 9 ) \
128
+ and ignore_ssl:
129
+ import ssl
130
+ ctx = ssl._create_unverified_context()
131
+ xmlrpclib.ServerProxy.__init__(self, uri, transport, encoding,
132
+ verbose, allow_none, context=ctx)
133
+ else:
134
+ xmlrpclib.ServerProxy.__init__(self, uri, transport, encoding,
135
+ verbose, allow_none)
115
136
  self.transport = transport
116
137
  self._session = None
117
138
  self.last_login_method = None
@@ -131,7 +152,7 @@ class Session(xmlrpclib.ServerProxy):
131
152
  while retry_count < 3:
132
153
  full_params = (self._session,) + params
133
154
  result = _parse_result(getattr(self, methodname)(*full_params))
134
- if result == _RECONNECT_AND_RETRY:
155
+ if result is _RECONNECT_AND_RETRY:
135
156
  retry_count += 1
136
157
  if self.last_login_method:
137
158
  self._login(self.last_login_method,
@@ -143,16 +164,22 @@ class Session(xmlrpclib.ServerProxy):
143
164
  raise xmlrpclib.Fault(
144
165
  500, 'Tried 3 times to get a valid session, but failed')
145
166
 
146
-
147
167
  def _login(self, method, params):
148
- result = _parse_result(getattr(self, 'session.%s' % method)(*params))
149
- if result == _RECONNECT_AND_RETRY:
150
- raise xmlrpclib.Fault(
151
- 500, 'Received SESSION_INVALID when logging in')
152
- self._session = result
153
- self.last_login_method = method
154
- self.last_login_params = params
155
- self.API_version = self._get_api_version()
168
+ try:
169
+ result = _parse_result(
170
+ getattr(self, 'session.%s' % method)(*params))
171
+ if result is _RECONNECT_AND_RETRY:
172
+ raise xmlrpclib.Fault(
173
+ 500, 'Received SESSION_INVALID when logging in')
174
+ self._session = result
175
+ self.last_login_method = method
176
+ self.last_login_params = params
177
+ self.API_version = self._get_api_version()
178
+ except socket.error as e:
179
+ if e.errno == socket.errno.ETIMEDOUT:
180
+ raise xmlrpclib.Fault(504, 'The connection timed out')
181
+ else:
182
+ raise e
156
183
 
157
184
  def _logout(self):
158
185
  try:
@@ -180,11 +207,15 @@ class Session(xmlrpclib.ServerProxy):
180
207
  return _Dispatcher(self.API_version, self.xenapi_request, None)
181
208
  elif name.startswith('login') or name.startswith('slave_local'):
182
209
  return lambda *params: self._login(name, params)
210
+ elif name == 'logout':
211
+ return _Dispatcher(self.API_version, self.xenapi_request, "logout")
212
+ elif name.startswith('__') and name.endswith('__'):
213
+ return lambda *args, **kwargs: notimplemented(name, args, kwargs)
183
214
  else:
184
215
  return xmlrpclib.ServerProxy.__getattr__(self, name)
185
216
 
186
217
  def xapi_local():
187
- return Session("http://_var_xapi_xapi/", transport=UDSTransport())
218
+ return Session("http://_var_lib_xcp_xapi/", transport=UDSTransport())
188
219
 
189
220
  def _parse_result(result):
190
221
  if type(result) != dict or 'Status' not in result:
@@ -0,0 +1 @@
1
+ from .XenAPI import *
@@ -0,0 +1,37 @@
1
+ Metadata-Version: 2.1
2
+ Name: XenAPI
3
+ Version: 23.8.0
4
+ Summary: XenAPI SDK, for communication with XenServer.
5
+ Home-page: https://www.citrix.com/community/citrix-developer/citrix-hypervisor-developer/
6
+ Author: Citrix Systems, Inc.
7
+ Author-email: xen-api@lists.xenproject.org
8
+ License: BSD-2-Clause
9
+ Project-URL: Bug Tracker, https://github.com/xapi-project/xen-api/issues
10
+ Project-URL: Source Code, https://github.com/xapi-project/xen-api
11
+ Classifier: License :: OSI Approved :: BSD License
12
+ Classifier: Development Status :: 6 - Mature
13
+ Classifier: Intended Audience :: Developers
14
+ Classifier: Topic :: System :: Systems Administration
15
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
16
+ Requires-Python: !=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,<4,>=2.7
17
+ Description-Content-Type: text/markdown; charset=UTF-8
18
+
19
+ Usage
20
+ =====
21
+
22
+ To install the package, enable the virtual environment where it's going to be used and run
23
+ `$ pip install XenAPI`
24
+
25
+ Examples
26
+ --------
27
+
28
+ The [examples](https://github.com/xapi-project/xen-api/tree/master/scripts/examples/python) will not work unless they have been placed in the same directory as `XenAPI.py` or `XenAPI` package from PyPI has been installed (`pip install XenAPI`)
29
+
30
+ Packaging
31
+ =========
32
+
33
+ `setup.py` is generated using an ocaml binary that fetches the api version string from xapi. An opam switch with the [xs-opam](https://github.com/xapi-project/xs-opam) repository is needed in order to build the binary.
34
+
35
+ To build the package `setuptools>=38.6.0` and `wheel` need to be installed in the system or in the active python virtualenv.
36
+
37
+ To build, use the command `make`.
@@ -0,0 +1,21 @@
1
+ Makefile
2
+ README.md
3
+ XenAPIPlugin.py
4
+ echo.py
5
+ exportimport.py
6
+ inventory.py
7
+ lvhd-api-test.py
8
+ mini-xenrt.py
9
+ monitor-unwanted-domains.py
10
+ provision.py
11
+ pyproject.toml
12
+ renameif.py
13
+ setup.cfg
14
+ shell.py
15
+ xva.py
16
+ XenAPI/XenAPI.py
17
+ XenAPI/__init__.py
18
+ XenAPI.egg-info/PKG-INFO
19
+ XenAPI.egg-info/SOURCES.txt
20
+ XenAPI.egg-info/dependency_links.txt
21
+ XenAPI.egg-info/top_level.txt
@@ -0,0 +1,54 @@
1
+ #!/usr/bin/python
2
+
3
+ # XenAPI python plugin boilerplate code
4
+
5
+ from __future__ import print_function
6
+
7
+ import sys
8
+
9
+ import XenAPI
10
+
11
+ if sys.version_info[0] == 2:
12
+ import xmlrpclib as xmlrpclib
13
+ else:
14
+ import xmlrpc.client as xmlrpclib
15
+
16
+ class Failure(Exception):
17
+ """Provide compatibilty with plugins written against XenServer 5.5 API"""
18
+
19
+ def __init__(self, code, params):
20
+ Exception.__init__(self)
21
+ self.params = [ code ] + params
22
+ def __str__(self):
23
+ return str(self.params)
24
+
25
+ def success_message(result):
26
+ rpcparams = { 'Status': 'Success', 'Value': result }
27
+ return xmlrpclib.dumps((rpcparams, ), '', True)
28
+
29
+ def failure_message(description):
30
+ rpcparams = { 'Status': 'Failure', 'ErrorDescription': description }
31
+ return xmlrpclib.dumps((rpcparams, ), '', True)
32
+
33
+ def dispatch(fn_table):
34
+ if len(sys.argv) != 2:
35
+ raise Exception("Incorrect number of commandline arguments")
36
+ params, methodname = xmlrpclib.loads(sys.argv[1])
37
+ session_id = params[0]
38
+ args = params[1]
39
+ if methodname in fn_table:
40
+ x = XenAPI.xapi_local()
41
+ x._session = session_id
42
+ try:
43
+ result = fn_table[methodname](x, args)
44
+ print(success_message(result))
45
+ except SystemExit:
46
+ # SystemExit should not be caught, as it is handled elsewhere in the plugin system.
47
+ raise
48
+ except Failure as e:
49
+ print(failure_message(e.params))
50
+ except Exception as e:
51
+ print(failure_message(['XENAPI_PLUGIN_FAILURE',
52
+ methodname, e.__class__.__name__, str(e)]))
53
+ else:
54
+ print(failure_message(['UNKNOWN_XENAPI_PLUGIN_FUNCTION', methodname]))
XenAPI-23.8.0/echo.py ADDED
@@ -0,0 +1,15 @@
1
+ #!/usr/bin/env python
2
+
3
+ # Simple XenAPI plugin
4
+ import XenAPIPlugin, time
5
+
6
+ def main(session, args):
7
+ if "sleep" in args:
8
+ secs = int(args["sleep"])
9
+ time.sleep(secs)
10
+ return "args were: %s" % (repr(args))
11
+
12
+ if __name__ == "__main__":
13
+ XenAPIPlugin.dispatch({"main": main})
14
+
15
+
@@ -0,0 +1,142 @@
1
+ #!/usr/bin/env python
2
+
3
+ # Copyright (c) 2014 Citrix, Inc.
4
+ #
5
+ # Permission to use, copy, modify, and distribute this software for any
6
+ # purpose with or without fee is hereby granted, provided that the above
7
+ # copyright notice and this permission notice appear in all copies.
8
+ #
9
+ # THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10
+ # WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11
+ # MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12
+ # ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13
+ # WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14
+ # ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15
+ # OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16
+
17
+ # Demonstrate how to
18
+ # - export raw disk images
19
+ # - import raw disk images
20
+ # - connect an export to an import to copy a raw disk image
21
+
22
+ from __future__ import print_function
23
+ import sys, os, socket, urllib2, urlparse, XenAPI, traceback, ssl, time
24
+
25
+ def exportimport(url, xapi, session, src_vdi, dst_vdi):
26
+ # If an HTTP operation fails then it will record the error on the task
27
+ # object. Note you can't use the HTTP response code for this because
28
+ # it must be sent *before* the stream is processed.
29
+ import_task = xapi.xenapi.task.create("import " + dst_vdi, "")
30
+ export_task = xapi.xenapi.task.create("export " + src_vdi, "")
31
+ try:
32
+ # an HTTP GET of this will export a disk:
33
+ get_url = "/export_raw_vdi?session_id=%s&vdi=%s&task_id=%s" % (session, src_vdi, export_task)
34
+ # an HTTP PUT to this will import a disk:
35
+ put_url = "/import_raw_vdi?session_id=%s&vdi=%s&task_id=%s" % (session, dst_vdi, import_task)
36
+
37
+ # 'data' is the stream of raw data:
38
+ data = urllib2.urlopen(url + get_url)
39
+
40
+ # python's builtin library doesn't support HTTP PUT very well
41
+ # so we do it manually. Note xapi doesn't support Transfer-encoding:
42
+ # chunked so we must send the data raw.
43
+ url = urlparse.urlparse(url)
44
+ host = url.netloc.split(":")[0] # assume port 443
45
+ if url.scheme != "https":
46
+ print("Sorry, this example only supports HTTPS (not HTTP)", file=sys.stderr)
47
+ print("Plaintext HTTP has the following problems:", file=sys.stderr)
48
+ print(" - the data can be captured by other programs on the network", file=sys.stderr)
49
+ print(" - some network middleboxes will mangle the data", file=sys.stderr)
50
+ # time wasted debugging a problem caused by a middlebox: 3hrs
51
+ # Just use HTTPS!
52
+ return
53
+
54
+ s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
55
+ output = ssl.wrap_socket(s)
56
+ output.connect((host, 443))
57
+
58
+ # HTTP/1.0 with no transfer-encoding
59
+ headers = [
60
+ "PUT %s HTTP/1.0" % put_url,
61
+ "Connection:close",
62
+ ""
63
+ ]
64
+ print("Sending HTTP request:")
65
+ for h in headers:
66
+ output.send("%s\r\n" % h)
67
+ print("%s\r\n" % h)
68
+ result = output.recv(1024)
69
+ print("Received HTTP response:")
70
+ print(result)
71
+ if "200 OK" not in result:
72
+ print("Expected an HTTP 200, got %s" % result, file=sys.stderr)
73
+ return
74
+
75
+ # Copy the raw bytes, signal completion by closing the socket
76
+ virtual_size = long(xapi.xenapi.VDI.get_virtual_size(src_vdi))
77
+ print("Copying %Ld bytes" % virtual_size)
78
+ left = virtual_size
79
+ while left > 0:
80
+ block = data.read(min(65536, left))
81
+ if block is None:
82
+ break
83
+ output.send(block)
84
+ left = left - len(block)
85
+ output.close()
86
+
87
+ # Wait for the tasks to complete and check whether they both
88
+ # succeeded. It takes a few seconds to detach the disk etc.
89
+ finished = False
90
+ while not finished:
91
+ import_status = xapi.xenapi.task.get_status(import_task)
92
+ export_status = xapi.xenapi.task.get_status(export_task)
93
+ finished = import_status != "pending" and export_task != "pending"
94
+ time.sleep(1)
95
+ if import_status == "success" and export_status == "success":
96
+ print("OK")
97
+ else:
98
+ print("FAILED")
99
+ if import_status != "success":
100
+ print("The import task failed with: ", " ".join(xapi.xenapi.task.get_error_info(import_task)))
101
+ if export_status != "success":
102
+ print("The export task failed with: ", " ".join(xapi.xenapi.task.get_error_info(export_task)))
103
+
104
+ finally:
105
+ # The task creator has to destroy them at the end:
106
+ xapi.xenapi.task.destroy(import_task)
107
+ xapi.xenapi.task.destroy(export_task)
108
+
109
+ if __name__ == "__main__":
110
+ if len(sys.argv) != 5:
111
+ print("Usage:")
112
+ print(sys.argv[0], " <url> <username> <password> <vdi-uuid>")
113
+ print(" -- creates a fresh VDI and streams the contents of <vdi-uuid> into it.")
114
+ print()
115
+ print("Example:")
116
+ print("SR=$(xe pool-list params=default-SR --minimal)")
117
+ print("VDI=$(xe vdi-create sr-uuid=$SR name-label=test virtual-size=128MiB type=user)")
118
+ print(sys.argv[0], "https://localhost password $VDI")
119
+ sys.exit(1)
120
+ url = sys.argv[1]
121
+ username = sys.argv[2]
122
+ password = sys.argv[3]
123
+ vdi_uuid = sys.argv[4]
124
+ # First acquire a valid session by logging in:
125
+ xapi = XenAPI.Session(url)
126
+ xapi.xenapi.login_with_password(username, password, '1.0', 'xen-api-scripts-exportimport.py')
127
+ dst_vdi = None
128
+ try:
129
+ src_vdi = xapi.xenapi.VDI.get_by_uuid(vdi_uuid)
130
+ sr = xapi.xenapi.VDI.get_SR(src_vdi)
131
+ # Create an empty VDI with the same initial parameters (e.g. size)
132
+ # to upload into
133
+ vdi_args = xapi.xenapi.VDI.get_record(src_vdi)
134
+ dst_vdi = xapi.xenapi.VDI.create(vdi_args)
135
+ exportimport(url, xapi, xapi._session, src_vdi, dst_vdi)
136
+ except Exception as e:
137
+ print("Caught %s: trying to clean up" % str(e))
138
+ traceback.print_exc()
139
+ if dst_vdi:
140
+ xapi.xenapi.VDI.destroy(dst_vdi)
141
+ finally:
142
+ xapi.xenapi.logout()
@@ -0,0 +1,32 @@
1
+ # Simple functions to read the constants from the xensource-inventory file
2
+
3
+ INVENTORY="@INVENTORY@"
4
+ INSTALLATION_UUID="INSTALLATION_UUID"
5
+
6
+
7
+ def read_kvpairs(filename):
8
+ """Read in a file of key-value pairs in the format used by the inventory file"""
9
+ f = open(filename)
10
+ all_entries = {}
11
+ try:
12
+ for line in f.readlines():
13
+ equals = line.index("=")
14
+ key = line[0:equals]
15
+ value = line[equals+1:].strip().strip("'")
16
+ all_entries[key] = value
17
+ finally:
18
+ f.close()
19
+ return all_entries
20
+
21
+
22
+ def parse():
23
+ """Return the contents of the xensource inventory file as a dictionary"""
24
+ try:
25
+ return read_kvpairs(INVENTORY)
26
+ except:
27
+ return {}
28
+
29
+
30
+ def get_localhost_uuid():
31
+ """Return the UUID of the local host"""
32
+ return parse()[INSTALLATION_UUID]
@@ -0,0 +1,29 @@
1
+ #!/usr/bin/env python
2
+
3
+ from __future__ import print_function
4
+ import XenAPI, sys
5
+
6
+ def go(x, name):
7
+ vm = x.xenapi.VM.get_by_name_label(name)[0]
8
+ vbds = x.xenapi.VM.get_VBDs(vm)
9
+ non_empty = filter(lambda y:not(x.xenapi.VBD.get_empty(y)), vbds)
10
+ vdis = map(lambda y:x.xenapi.VBD.get_VDI(y), non_empty)
11
+
12
+ print("Calling API call on %s" % (repr(vdis)))
13
+ result = x.xenapi.SR.lvhd_stop_using_these_vdis_and_call_script(vdis, "echo", "main", { "hello": "there", "sleep": "10" })
14
+ print(repr(result))
15
+
16
+
17
+ if __name__ == "__main__":
18
+ if len(sys.argv) != 2:
19
+ print("Usage:", file=sys.stderr)
20
+ print(" %s <VM name-label>" % (sys.argv[0]), file=sys.stderr)
21
+ print(" -- Call SR.lvhd_stop_using_these_vdis_and_call_script with all VDIs with VBDs (attached or not) linking to specified VM", file=sys.stderr)
22
+ sys.exit(1)
23
+ name = sys.argv[1]
24
+ x = XenAPI.xapi_local()
25
+ x.xenapi.login_with_password("root", "", "1.0", "xen-api-scripts-lvhd-api-test.py")
26
+ try:
27
+ go(x, name)
28
+ finally:
29
+ x.xenapi.logout()