XenAPI 24.26.0__tar.gz → 24.28.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.
@@ -8,5 +8,4 @@ build:
8
8
  SETUPTOOLS_SCM_PRETEND_VERSION=$(XAPI_VERSION) python -m build --sdist .
9
9
 
10
10
  clean:
11
- dune clean
12
11
  rm -rf dist/ build/ XenAPI.egg-info/
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: XenAPI
3
- Version: 24.26.0
3
+ Version: 24.28.0
4
4
  Summary: XenAPI SDK, for communication with XenServer.
5
5
  Home-page: https://xapi-project.github.io/
6
6
  Author: Xapi project developers and maintainers
@@ -13,7 +13,7 @@ Classifier: Development Status :: 6 - Mature
13
13
  Classifier: Intended Audience :: Developers
14
14
  Classifier: Topic :: System :: Systems Administration
15
15
  Classifier: Topic :: Software Development :: Libraries :: Python Modules
16
- Requires-Python: !=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,<4,>=2.7
16
+ Requires-Python: <4,>=3.6
17
17
  Description-Content-Type: text/markdown; charset=UTF-8
18
18
 
19
19
  Usage
@@ -58,13 +58,8 @@ import gettext
58
58
  import os
59
59
  import socket
60
60
  import sys
61
-
62
- if sys.version_info[0] == 2:
63
- import httplib as httplib
64
- import xmlrpclib as xmlrpclib
65
- else:
66
- import http.client as httplib
67
- import xmlrpc.client as xmlrpclib
61
+ import http.client as httplib
62
+ import xmlrpc.client as xmlrpclib
68
63
 
69
64
  otel = False
70
65
  try:
@@ -147,18 +142,13 @@ class Session(xmlrpclib.ServerProxy):
147
142
  session.xenapi.session.logout()
148
143
  """
149
144
 
150
- def __init__(self, uri, transport=None, encoding=None, verbose=0,
151
- allow_none=1, ignore_ssl=False):
145
+ def __init__(self, uri, transport=None, encoding=None, verbose=False,
146
+ allow_none=True, ignore_ssl=False):
152
147
 
153
- if sys.version_info[0] > 2:
154
- # this changed to be a 'bool' in Python3
155
- verbose = bool(verbose)
156
- allow_none = bool(allow_none)
148
+ verbose = bool(verbose)
149
+ allow_none = bool(allow_none)
157
150
 
158
- # Fix for CA-172901 (+ Python 2.4 compatibility)
159
- # Fix for context=ctx ( < Python 2.7.9 compatibility)
160
- if not (sys.version_info[0] <= 2 and sys.version_info[1] <= 7 and sys.version_info[2] <= 9 ) \
161
- and ignore_ssl:
151
+ if ignore_ssl:
162
152
  import ssl
163
153
  ctx = ssl._create_unverified_context()
164
154
  xmlrpclib.ServerProxy.__init__(self, uri, transport, encoding,
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: XenAPI
3
- Version: 24.26.0
3
+ Version: 24.28.0
4
4
  Summary: XenAPI SDK, for communication with XenServer.
5
5
  Home-page: https://xapi-project.github.io/
6
6
  Author: Xapi project developers and maintainers
@@ -13,7 +13,7 @@ Classifier: Development Status :: 6 - Mature
13
13
  Classifier: Intended Audience :: Developers
14
14
  Classifier: Topic :: System :: Systems Administration
15
15
  Classifier: Topic :: Software Development :: Libraries :: Python Modules
16
- Requires-Python: !=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,<4,>=2.7
16
+ Requires-Python: <4,>=3.6
17
17
  Description-Content-Type: text/markdown; charset=UTF-8
18
18
 
19
19
  Usage
@@ -2,17 +2,8 @@ Makefile
2
2
  PACKAGING.md
3
3
  README.md
4
4
  XenAPIPlugin.py
5
- echo.py
6
- exportimport.py
7
- inventory.py
8
- lvhd-api-test.py
9
- mini-xenrt.py
10
- monitor-unwanted-domains.py
11
- provision.py
12
5
  pyproject.toml
13
- renameif.py
14
6
  setup.cfg
15
- shell.py
16
7
  XenAPI/XenAPI.py
17
8
  XenAPI/__init__.py
18
9
  XenAPI.egg-info/PKG-INFO
@@ -7,16 +7,11 @@
7
7
  from __future__ import print_function
8
8
 
9
9
  import sys
10
-
10
+ import xmlrpc.client as xmlrpclib
11
11
  import XenAPI
12
12
 
13
- if sys.version_info[0] == 2:
14
- import xmlrpclib
15
- else:
16
- import xmlrpc.client as xmlrpclib
17
-
18
13
  class Failure(Exception):
19
- """Provide compatibilty with plugins written against XenServer 5.5 API"""
14
+ """Provide compatibility with plugins written against the XenServer 5.5 API"""
20
15
 
21
16
  def __init__(self, code, params):
22
17
  Exception.__init__(self)
@@ -44,9 +39,6 @@ def dispatch(fn_table):
44
39
  try:
45
40
  result = fn_table[methodname](x, args)
46
41
  print(success_message(result))
47
- except SystemExit:
48
- # SystemExit should not be caught, as it is handled elsewhere in the plugin system.
49
- raise
50
42
  except Failure as e:
51
43
  print(failure_message(e.params))
52
44
  except Exception as e:
@@ -3,4 +3,4 @@ requires = ["setuptools >= 38.6.0", "setuptools_scm[toml]", "wheel"]
3
3
  build-backend = "setuptools.build_meta"
4
4
 
5
5
  [tool.setuptools_scm]
6
- root = "../../.."
6
+ root = "../.."
@@ -19,10 +19,7 @@ classifiers =
19
19
 
20
20
  [options]
21
21
  packages = find:
22
- python_requires = >=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, <4
23
-
24
- [bdist_wheel]
25
- universal = 1
22
+ python_requires = >=3.6, <4
26
23
 
27
24
  [egg_info]
28
25
  tag_build =
xenapi-24.26.0/echo.py DELETED
@@ -1,17 +0,0 @@
1
- #!/usr/bin/env python3
2
-
3
- # Simple XenAPI plugin
4
- import time
5
-
6
- import XenAPIPlugin
7
-
8
-
9
- def main(session, args):
10
- if "sleep" in args:
11
- secs = int(args["sleep"])
12
- time.sleep(secs)
13
- return "args were: %s" % (repr(args))
14
-
15
-
16
- if __name__ == "__main__":
17
- XenAPIPlugin.dispatch({"main": main})
@@ -1,142 +0,0 @@
1
- #!/usr/bin/env python3
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, urllib.request, urllib.error, urllib.parse, 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 = urllib.request.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 = urllib.parse.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()
@@ -1,32 +0,0 @@
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]
@@ -1,29 +0,0 @@
1
- #!/usr/bin/env python3
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()
@@ -1,141 +0,0 @@
1
- #!/usr/bin/env python3
2
-
3
- # Receive multiple VMs
4
- # Issue parallel loops of: reboot, suspend/resume, migrate
5
-
6
- from __future__ import print_function
7
- import xmlrpc.client
8
- from threading import Thread
9
- import time, sys
10
-
11
- iso8601 = "%Y%m%dT%H:%M:%SZ"
12
-
13
- stop_on_first_failure = True
14
- stop = False
15
-
16
- class Operation:
17
- def __init__(self):
18
- raise NotImplementedError
19
- def execute(self, server, session_id):
20
- raise NotImplementedError
21
-
22
- class Reboot(Operation):
23
- def __init__(self, vm):
24
- self.vm = vm
25
- def execute(self, server, session_id):
26
- return server.VM.clean_reboot(session_id, self.vm)
27
- def __str__(self):
28
- return "clean_reboot(%s)" % self.vm
29
-
30
- class SuspendResume(Operation):
31
- def __init__(self, vm):
32
- self.vm = vm
33
- def execute(self, server, session_id):
34
- x = { "ErrorDescription": [ "VM_MISSING_PV_DRIVERS" ] }
35
- while "ErrorDescription" in x and x["ErrorDescription"][0] == "VM_MISSING_PV_DRIVERS":
36
- x = server.VM.suspend(session_id, self.vm)
37
- if "ErrorDescription" in x:
38
- time.sleep(1)
39
- if x["Status"] != "Success":
40
- return x
41
- return server.VM.resume(session_id, self.vm, False, False)
42
- def __str__(self):
43
- return "suspendresume(%s)" % self.vm
44
-
45
- class ShutdownStart(Operation):
46
- def __init__(self, vm):
47
- self.vm = vm
48
- def execute(self, server, session_id):
49
- x = server.VM.clean_shutdown(session_id, self.vm)
50
- if x["Status"] != "Success":
51
- return x
52
- return server.VM.start(session_id, self.vm, False, False)
53
- #return { "Status": "bad", "ErrorDescription": "foo" }
54
- def __str__(self):
55
- return "shutdownstart(%s)" % self.vm
56
-
57
- class LocalhostMigrate(Operation):
58
- def __init__(self, vm):
59
- self.vm = vm
60
- def execute(self, server, session_id):
61
- return server.VM.pool_migrate(session_id, self.vm, server.VM.get_resident_on(session_id, self.vm)["Value"], { "live": "true" } )
62
- def __str__(self):
63
- return "localhostmigrate(%s)" % self.vm
64
-
65
- # Use this to give each thread a different ID
66
- worker_count = 0
67
-
68
- class Worker(Thread):
69
- def __init__(self, server, session_id, operations):
70
- Thread.__init__(self)
71
- self.server = server
72
- self.session_id = session_id
73
- self.operations = operations
74
- self.num_successes = 0
75
- self.num_failures = 0
76
- global worker_count
77
- self.id = worker_count
78
- worker_count = worker_count + 1
79
- def run(self):
80
- global iso8601
81
- global stop_on_first_failure, stop
82
- for op in self.operations:
83
- description = str(op)
84
-
85
- if stop:
86
- return
87
-
88
- start = time.strftime(iso8601, time.gmtime(time.time ()))
89
- result = op.execute(self.server, self.session_id)
90
- end = time.strftime(iso8601, time.gmtime(time.time ()))
91
-
92
- if result["Status"] == "Success":
93
- print("SUCCESS %d %s %s %s" % (self.id, start, end, description))
94
- self.num_successes = self.num_successes + 1
95
- else:
96
- error_descr = result["ErrorDescription"]
97
- print("FAILURE %d %s %s %s %s" % (self.id, start, end, error_descr[0], description))
98
- self.num_failures = self.num_failures + 1
99
- if stop_on_first_failure:
100
- stop = True
101
-
102
- def make_operation_list(vm):
103
- return [ Reboot(vm), SuspendResume(vm), LocalhostMigrate(vm) ] * 100
104
-
105
- if __name__ == "__main__":
106
- if len(sys.argv) != 3:
107
- print("Usage:")
108
- print(" %s <URL> <other-config key>" % (sys.argv[0]))
109
- print(" -- performs parallel operations on VMs with the specified other-config key")
110
- sys.exit(1)
111
-
112
- x = xmlrpc.client.server(sys.argv[1])
113
- key = sys.argv[2]
114
- session = x.session.login_with_password("root", "xenroot", "1.0", "xen-api-scripts-minixenrt.py")["Value"]
115
- vms = x.VM.get_all_records(session)["Value"]
116
-
117
- workers = []
118
- for vm in vms.keys():
119
- if key in vms[vm]["other_config"]:
120
- allowed_ops = vms[vm]["allowed_operations"]
121
- for op in [ "clean_reboot", "suspend", "pool_migrate" ]:
122
- if op not in allowed_ops:
123
- raise RuntimeError("VM %s is not in a state where it can %s" % (vms[vm]["name_label"], op))
124
- workers.append(Worker(x, session, make_operation_list(vm)))
125
- for w in workers:
126
- w.start()
127
- for w in workers:
128
- w.join()
129
- successes = 0
130
- failures = 0
131
- for w in workers:
132
- successes = successes + w.num_successes
133
- failures = failures + w.num_failures
134
- print("Total successes = %d" % successes)
135
- print("Total failures = %d" % failures)
136
- if failures == 0:
137
- print("PASS")
138
- sys.exit(0)
139
- else:
140
- print("FAIL")
141
- sys.exit(1)
@@ -1,89 +0,0 @@
1
- #!/usr/bin/env python3
2
-
3
- from __future__ import print_function
4
- import os, subprocess, XenAPI, inventory, time, sys
5
-
6
- # Script which monitors the domains running on a host, looks for
7
- # paused domains which don't correspond to VMs which are running here
8
- # or are about to run here, logs them and optionally destroys them.
9
-
10
- # Return a list of (domid, uuid) tuples, one per paused domain on this host
11
- def list_paused_domains():
12
- results = []
13
- all = subprocess.Popen(["@OPTDIR@/bin/list_domains"], stdout=subprocess.PIPE).communicate()[0]
14
- lines = all.split("\n")
15
- for domain in lines[1:]:
16
- bits = domain.split()
17
- if bits != []:
18
- domid = bits[0]
19
- uuid = bits[2]
20
- state = bits[4]
21
- if 'P' in state:
22
- results.append( (domid, uuid) )
23
- return results
24
-
25
- # Given localhost's uuid and a (domid, uuid) tuple, return True if the domain
26
- # be somewhere else i.e. we think it may have leaked here
27
- def should_domain_be_somewhere_else(localhost_uuid, domain):
28
- (domid, uuid) = domain
29
- try:
30
- x = XenAPI.xapi_local()
31
- x.xenapi.login_with_password("root", "", "1.0", "xen-api-scripts-monitor-unwanted-domains.py")
32
- try:
33
- try:
34
- vm = x.xenapi.VM.get_by_uuid(uuid)
35
- resident_on = x.xenapi.VM.get_resident_on(vm)
36
- current_operations = x.xenapi.VM.get_current_operations(vm)
37
- result = current_operations == {} and resident_on != localhost_uuid
38
- if result:
39
- log("domid %s uuid %s: is not being operated on and is not resident here" % (domid, uuid))
40
- return result
41
- except XenAPI.Failure as e:
42
- if e.details[0] == "UUID_INVALID":
43
- # VM is totally bogus
44
- log("domid %s uuid %s: is not in the xapi database" % (domid, uuid))
45
- return True
46
- # fail safe for now
47
- return False
48
- finally:
49
- x.xenapi.logout()
50
- except:
51
- return False
52
-
53
- def log(str):
54
- print(str)
55
-
56
- # Destroy the given domain
57
- def destroy_domain(domain):
58
- (domid, uuid) = domain
59
- log("destroying domid %s uuid %s" % (domid, uuid))
60
- all = subprocess.Popen(["@OPTDIR@/debug/destroy_domain", "-domid", domid], stdout=subprocess.PIPE).communicate()[0]
61
-
62
- # Keep track of when a domain first looked like it should be here
63
- domain_first_noticed = {}
64
-
65
- # Number of seconds after which we conclude that a domain really shouldn't be here
66
- threshold = 60
67
-
68
- if __name__ == "__main__":
69
- localhost_uuid = inventory.get_localhost_uuid ()
70
- while True:
71
- time.sleep(1)
72
- paused = list_paused_domains ()
73
- # GC the domain_first_noticed map
74
- for d in domain_first_noticed.keys():
75
- if d not in paused:
76
- log("domid %s uuid %s: looks ok now, forgetting about it" % d)
77
- del domain_first_noticed[d]
78
-
79
- for d in list_paused_domains():
80
- if should_domain_be_somewhere_else(localhost_uuid, d):
81
- if d not in domain_first_noticed:
82
- domain_first_noticed[d] = time.time()
83
- noticed_for = time.time() - domain_first_noticed[d]
84
- if noticed_for > threshold:
85
- log("domid %s uuid %s: has been in bad state for over threshold" % d)
86
- if "-destroy" in sys.argv:
87
- destroy_domain(d)
88
-
89
-
@@ -1,111 +0,0 @@
1
- #!/usr/bin/env python3
2
- # Copyright (c) 2007 XenSource, Inc.
3
- #
4
- # Permission to use, copy, modify, and distribute this software for any
5
- # purpose with or without fee is hereby granted, provided that the above
6
- # copyright notice and this permission notice appear in all copies.
7
- #
8
- # THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9
- # WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10
- # MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11
- # ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12
- # WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13
- # ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14
- # OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15
-
16
- # Parse/regenerate the "disk provisioning" XML contained within templates
17
- # NB this provisioning XML refers to disks which should be created when
18
- # a VM is installed from this template. It does not apply to templates
19
- # which have been created from real VMs -- they have their own disks.
20
-
21
- from __future__ import print_function
22
- import XenAPI
23
- import xml.dom.minidom
24
-
25
- class Disk:
26
- """Represents a disk which should be created for this VM"""
27
- def __init__(self, device, size, sr, bootable):
28
- self.device = device # 0, 1, 2, ...
29
- self.size = size # in bytes
30
- self.sr = sr # uuid of SR
31
- self.bootable = bootable
32
- def toElement(self, doc):
33
- disk = doc.createElement("disk")
34
- disk.setAttribute("device", self.device)
35
- disk.setAttribute("size", self.size)
36
- disk.setAttribute("sr", self.sr)
37
- b = "false"
38
- if self.bootable: b = "true"
39
- disk.setAttribute("bootable", b)
40
- return disk
41
-
42
- def parseDisk(element):
43
- device = element.getAttribute("device")
44
- size = element.getAttribute("size")
45
- sr = element.getAttribute("sr")
46
- b = element.getAttribute("bootable") == "true"
47
- return Disk(device, size, sr, b)
48
-
49
- class ProvisionSpec:
50
- """Represents a provisioning specification: currently a list of required disks"""
51
- def __init__(self):
52
- self.disks = []
53
- def toElement(self, doc):
54
- element = doc.createElement("provision")
55
- for disk in self.disks:
56
- element.appendChild(disk.toElement(doc))
57
- return element
58
- def setSR(self, sr):
59
- """Set the requested SR for each disk"""
60
- for disk in self.disks:
61
- disk.sr = sr
62
-
63
- def parseProvisionSpec(txt):
64
- """Return an instance of type ProvisionSpec given XML text"""
65
- doc = xml.dom.minidom.parseString(txt)
66
- all = doc.getElementsByTagName("provision")
67
- if len(all) != 1:
68
- raise ValueError("Expected to find exactly one <provision> element")
69
- ps = ProvisionSpec()
70
- disks = all[0].getElementsByTagName("disk")
71
- for disk in disks:
72
- ps.disks.append(parseDisk(disk))
73
- return ps
74
-
75
- def printProvisionSpec(ps):
76
- """Return a string containing pretty-printed XML corresponding to the supplied provisioning spec"""
77
- doc = xml.dom.minidom.Document()
78
- doc.appendChild(ps.toElement(doc))
79
- return doc.toprettyxml()
80
-
81
- def getProvisionSpec(session, vm):
82
- """Read the provision spec of a template/VM"""
83
- other_config = session.xenapi.VM.get_other_config(vm)
84
- return parseProvisionSpec(other_config['disks'])
85
-
86
- def setProvisionSpec(session, vm, ps):
87
- """Set the provision spec of a template/VM"""
88
- txt = printProvisionSpec(ps)
89
- try:
90
- session.xenapi.VM.remove_from_other_config(vm, "disks")
91
- except:
92
- pass
93
- session.xenapi.VM.add_to_other_config(vm, "disks", txt)
94
-
95
- if __name__ == "__main__":
96
- print("Unit test of provision XML spec module")
97
- print("--------------------------------------")
98
- ps = ProvisionSpec()
99
- ps.disks.append(Disk("0", "1024", "0000-0000", True))
100
- ps.disks.append(Disk("1", "2048", "1111-1111", False))
101
- print("* Pretty-printing spec")
102
- txt = printProvisionSpec(ps)
103
- print(txt)
104
- print("* Re-parsing output")
105
- ps2 = parseProvisionSpec(txt)
106
- print("* Pretty-printing spec")
107
- txt2 = printProvisionSpec(ps)
108
- print(txt2)
109
- if txt != txt2:
110
- raise AssertionError("Sanity-check failed: print(parse(print(x))) <> print(x)")
111
- print("* OK: print(parse(print(x))) == print(x)")
@@ -1,167 +0,0 @@
1
- #!/usr/bin/env python3
2
- # Copyright (c) 2008 XenSource, Inc.
3
- #
4
- # Permission to use, copy, modify, and distribute this software for any
5
- # purpose with or without fee is hereby granted, provided that the above
6
- # copyright notice and this permission notice appear in all copies.
7
- #
8
- # THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9
- # WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10
- # MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11
- # ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12
- # WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13
- # ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14
- # OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15
-
16
- # Allow the user to change the MAC address -> interface mapping
17
-
18
- from __future__ import print_function
19
- import XenAPI, inventory, sys
20
-
21
- def warn(txt):
22
- print(txt, file=sys.stderr)
23
-
24
- def show_pifs(pifs):
25
- print("NIC MAC Notes")
26
- print("----------------------------------------------")
27
- for ref in pifs.keys():
28
- notes = []
29
- if pifs[ref]['management']:
30
- notes.append("management interface")
31
- nic = pifs[ref]['device'][3:]
32
- try:
33
- metrics = session.xenapi.PIF_metrics.get_record(session.xenapi.PIF.get_metrics(ref))
34
- if metrics['carrier']:
35
- notes.append("carrier detected")
36
- else:
37
- notes.append("no carrier detected")
38
- except:
39
- pass
40
-
41
- print("%3s %s %s" % (nic, pifs[ref]['MAC'], ", ".join(notes)))
42
-
43
- def select(pifs, key):
44
- """Select a PIF by device name or MAC"""
45
- for ref in pifs.keys():
46
- if pifs[ref]['device'][3:] == key:
47
- return ref
48
- if pifs[ref]['MAC'].upper() == key.upper():
49
- return ref
50
- return None
51
-
52
- def save(session, host, pifs):
53
- """Commit changes"""
54
- # Check that device names are unique
55
- devices = []
56
- for ref in pifs.keys():
57
- devices.append(pifs[ref]['device'][3:])
58
- for i in set(devices):
59
- devices.remove(i)
60
- if devices != []:
61
- print("ERROR: cannot assign two interfaces the same NIC number (%s)" % (", ".join(i)))
62
- print("Aborted.")
63
- sys.exit(1)
64
- vifs = []
65
- for ref in pifs.keys():
66
- net = pifs[ref]['network']
67
- for vif in session.xenapi.network.get_VIFs(net):
68
- if session.xenapi.VIF.get_currently_attached(vif):
69
- vifs.append(vif)
70
- if len(vifs) > 0:
71
- plural = ""
72
- if len(vifs) > 1:
73
- plural = "s"
74
- print("WARNING: this operation requires unplugging %d guest network interface%s" % (len(vifs), plural))
75
- print("Are you sure you want to continue? (yes/no) > ", end=' ')
76
- if sys.stdin.readline().strip().lower() != "yes":
77
- print("Aborted.")
78
- sys.exit(1)
79
- for vif in vifs:
80
- dev = session.xenapi.VIF.get_device(vif)
81
- vm = session.xenapi.VIF.get_VM(vif)
82
- uuid = session.xenapi.VM.get_uuid(vm)
83
- print("Hot-unplugging interface %s on VM %s" % (dev, uuid))
84
- session.xenapi.VIF.unplug(vif)
85
-
86
- for ref in pifs.keys():
87
- mac = pifs[ref]['MAC']
88
- if pifs[ref]['management']:
89
- print("Disabling management NIC (%s)" % mac)
90
- session.xenapi.host.management_disable()
91
- session.xenapi.PIF.forget(ref)
92
- for ref in pifs.keys():
93
- mac = pifs[ref]['MAC']
94
- device = pifs[ref]['device']
95
- mode = pifs[ref]['ip_configuration_mode']
96
- IP = pifs[ref]['IP']
97
- netmask = pifs[ref]['IP']
98
- gateway = pifs[ref]['gateway']
99
- DNS = pifs[ref]['DNS']
100
- new_ref = session.xenapi.PIF.introduce(host, mac, device)
101
- session.xenapi.PIF.reconfigure_ip(new_ref, mode, IP, netmask, gateway, DNS)
102
- if pifs[ref]['management']:
103
- print("Re-enabling management NIC (%s)" % mac)
104
- session.xenapi.host.management_reconfigure(new_ref)
105
-
106
- for vif in vifs:
107
- dev = session.xenapi.VIF.get_device(vif)
108
- vm = session.xenapi.VIF.get_VM(vif)
109
- uuid = session.xenapi.VM.get_uuid(vm)
110
- print("Hot-plugging interface %s on VM %s" % (dev, uuid))
111
- session.xenapi.VIF.plug(vif)
112
-
113
- def renameif(session):
114
- uuid = inventory.get_localhost_uuid ()
115
- host = session.xenapi.host.get_by_uuid(uuid)
116
- pool = session.xenapi.pool.get_all()[0]
117
- master = session.xenapi.pool.get_master(pool)
118
- if host != master:
119
- warn("This host is a slave; it is not possible to rename the management interface")
120
-
121
- pifs = session.xenapi.PIF.get_all_records()
122
- for ref in pifs.keys():
123
- if pifs[ref]['host'] != host or pifs[ref]['physical'] != True:
124
- del pifs[ref]
125
-
126
- while True:
127
- print("Current mappings:")
128
- show_pifs(pifs)
129
- print()
130
- print("Type 'quit' to quit; 'save' to save; or a NIC number or MAC address to edit")
131
- print("> ", end=' ')
132
- x = sys.stdin.readline().strip()
133
- if x.lower() == 'quit':
134
- sys.exit(0)
135
- if x.lower() == 'save':
136
- # If a slave, filter out the management PIF
137
- if host != master:
138
- for ref in pifs.keys():
139
- if pifs[ref]['management']:
140
- del pifs[ref]
141
- save(session, host, pifs)
142
- sys.exit(0)
143
- pif = select(pifs, x)
144
- if pif != None:
145
- # Make sure this is not a slave's management PIF
146
- if host != master and pifs[pif]['management']:
147
- print("ERROR: cannot modify the management interface of a slave.")
148
- else:
149
- print("Selected NIC with MAC '%s'. Enter new NIC number:" % pifs[pif]['MAC'])
150
- print("> ", end=' ')
151
- nic = sys.stdin.readline().strip()
152
- if not(nic.isdigit()):
153
- print("ERROR: must enter a number (e.g. 0, 1, 2, 3, ...)")
154
- else:
155
- pifs[pif]['device'] = "eth" + nic
156
- else:
157
- print("NIC '%s' not found" % (x))
158
- print()
159
-
160
-
161
- if __name__ == "__main__":
162
- session = XenAPI.xapi_local()
163
- session.login_with_password("", "", "1.0", "xen-api-scripts-renameifs.py")
164
- try:
165
- renameif(session)
166
- finally:
167
- session.logout()
xenapi-24.26.0/shell.py DELETED
@@ -1,118 +0,0 @@
1
- #!/usr/bin/env python3
2
- # Copyright (c) 2006-2008 Citrix Systems.
3
- #
4
- # Permission to use, copy, modify, and distribute this software for any
5
- # purpose with or without fee is hereby granted, provided that the above
6
- # copyright notice and this permission notice appear in all copies.
7
- #
8
- # THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9
- # WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10
- # MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11
- # ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12
- # WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13
- # ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14
- # OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15
-
16
- from __future__ import print_function
17
- import atexit
18
- import cmd
19
- import pprint
20
- import readline
21
- import shlex
22
- import string
23
- import sys
24
-
25
- import XenAPI
26
-
27
- def logout():
28
- try:
29
- session.xenapi.session.logout()
30
- except:
31
- pass
32
- atexit.register(logout)
33
-
34
- class Shell(cmd.Cmd):
35
- def __init__(self):
36
- cmd.Cmd.__init__(self)
37
- self.identchars = string.ascii_letters + string.digits + '_.'
38
- self.prompt = "xe> "
39
-
40
- def preloop(self):
41
- cmd.Cmd.preloop(self)
42
- readline.set_completer_delims(' ')
43
-
44
- def default(self, line):
45
- words = shlex.split(line)
46
- if len(words) > 0:
47
- res = session.xenapi_request(words[0], tuple(words[1:]))
48
- if res is not None and res != '':
49
- pprint.pprint(res)
50
- return False
51
-
52
- def completedefault(self, text, line, begidx, endidx):
53
- words = shlex.split(line[:begidx])
54
- clas, func = words[0].split('.')
55
- if len(words) > 1 or \
56
- func.startswith('get_by_') or \
57
- func == 'get_all':
58
- return []
59
- uuids = session.xenapi_request('%s.get_all' % clas, ())
60
- return [u + " " for u in uuids if u.startswith(text)]
61
-
62
- def emptyline(self):
63
- pass
64
-
65
- def do_EOF(self, line):
66
- print()
67
- sys.exit(0)
68
-
69
- def munge_types (str):
70
- if str == "True":
71
- return True
72
- elif str == "False":
73
- return False
74
-
75
- try:
76
- return int(str)
77
- except:
78
- return str
79
-
80
- if __name__ == "__main__":
81
- if len(sys.argv) < 2:
82
- print("Usage:")
83
- print(sys.argv[0], " <url> <username> <password>")
84
- sys.exit(1)
85
-
86
- if sys.argv[1] != "-" and len(sys.argv) < 4:
87
- print("Usage:")
88
- print(sys.argv[0], " <url> <username> <password>")
89
- sys.exit(1)
90
-
91
- if sys.argv[1] != "-":
92
- url = sys.argv[1]
93
- username = sys.argv[2]
94
- password = sys.argv[3]
95
- session = XenAPI.Session(url)
96
- session.xenapi.login_with_password(username, password, "1.0", "xen-api-scripts-shell.py")
97
- cmdAt = 4
98
- else:
99
- session = XenAPI.xapi_local()
100
- session.xenapi.login_with_password("", "", "1.0", "xen-api-scripts-shell.py")
101
- cmdAt = 2
102
-
103
- # We want to support directly executing the cmd line,
104
- # where appropriate
105
- if len(sys.argv) > cmdAt:
106
- cmd = sys.argv[cmdAt]
107
- params = [munge_types(x) for x in sys.argv[(cmdAt + 1):]]
108
- try:
109
- print(session.xenapi_request(cmd, tuple(params)), file=sys.stdout)
110
- except XenAPI.Failure as x:
111
- print(x, file=sys.stderr)
112
- sys.exit(2)
113
- except Exception as e:
114
- print(e, file=sys.stderr)
115
- sys.exit(3)
116
- sys.exit(0)
117
- else:
118
- Shell().cmdloop('Welcome to the XenServer shell. (Try "VM.get_all")')
File without changes
File without changes
File without changes