XenAPI 24.26.0__tar.gz → 24.27.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-24.26.0 → xenapi-24.27.0}/Makefile +0 -1
- {xenapi-24.26.0/XenAPI.egg-info → xenapi-24.27.0}/PKG-INFO +2 -2
- {xenapi-24.26.0 → xenapi-24.27.0}/XenAPI/XenAPI.py +7 -17
- {xenapi-24.26.0 → xenapi-24.27.0/XenAPI.egg-info}/PKG-INFO +2 -2
- {xenapi-24.26.0 → xenapi-24.27.0}/XenAPI.egg-info/SOURCES.txt +0 -9
- {xenapi-24.26.0 → xenapi-24.27.0}/XenAPIPlugin.py +2 -10
- {xenapi-24.26.0 → xenapi-24.27.0}/pyproject.toml +1 -1
- {xenapi-24.26.0 → xenapi-24.27.0}/setup.cfg +1 -4
- xenapi-24.26.0/echo.py +0 -17
- xenapi-24.26.0/exportimport.py +0 -142
- xenapi-24.26.0/inventory.py +0 -32
- xenapi-24.26.0/lvhd-api-test.py +0 -29
- xenapi-24.26.0/mini-xenrt.py +0 -141
- xenapi-24.26.0/monitor-unwanted-domains.py +0 -89
- xenapi-24.26.0/provision.py +0 -111
- xenapi-24.26.0/renameif.py +0 -167
- xenapi-24.26.0/shell.py +0 -118
- {xenapi-24.26.0 → xenapi-24.27.0}/PACKAGING.md +0 -0
- {xenapi-24.26.0 → xenapi-24.27.0}/README.md +0 -0
- {xenapi-24.26.0 → xenapi-24.27.0}/XenAPI/__init__.py +0 -0
- {xenapi-24.26.0 → xenapi-24.27.0}/XenAPI.egg-info/dependency_links.txt +0 -0
- {xenapi-24.26.0 → xenapi-24.27.0}/XenAPI.egg-info/top_level.txt +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: XenAPI
|
|
3
|
-
Version: 24.
|
|
3
|
+
Version: 24.27.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:
|
|
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
|
-
|
|
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=
|
|
151
|
-
allow_none=
|
|
145
|
+
def __init__(self, uri, transport=None, encoding=None, verbose=False,
|
|
146
|
+
allow_none=True, ignore_ssl=False):
|
|
152
147
|
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
verbose = bool(verbose)
|
|
156
|
-
allow_none = bool(allow_none)
|
|
148
|
+
verbose = bool(verbose)
|
|
149
|
+
allow_none = bool(allow_none)
|
|
157
150
|
|
|
158
|
-
|
|
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.
|
|
3
|
+
Version: 24.27.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:
|
|
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
|
|
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:
|
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})
|
xenapi-24.26.0/exportimport.py
DELETED
|
@@ -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()
|
xenapi-24.26.0/inventory.py
DELETED
|
@@ -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]
|
xenapi-24.26.0/lvhd-api-test.py
DELETED
|
@@ -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()
|
xenapi-24.26.0/mini-xenrt.py
DELETED
|
@@ -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
|
-
|
xenapi-24.26.0/provision.py
DELETED
|
@@ -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)")
|
xenapi-24.26.0/renameif.py
DELETED
|
@@ -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
|
|
File without changes
|
|
File without changes
|