1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
|
#!/usr/bin/env python3
"""
List active domains of an ESX host and print some info.
"""
# also demonstrates how to use the libvirt.openAuth() method
import libvirt
import libxml2
import getpass
from argparse import ArgumentParser
from typing import Any, List
# This is the callback method passed to libvirt.openAuth() (see below).
#
# The credentials argument is a list of credentials that libvirt (actually
# the ESX driver) would like to request. An element of this list is itself a
# list containing 5 items (4 inputs, 1 output):
# - the credential type, e.g. libvirt.VIR_CRED_AUTHNAME
# - a prompt to be displayed to the user
# - a challenge, the ESX driver sets this to the hostname to allow automatic
# distinction between requests for ESX and vCenter credentials
# - a default result for the request
# - a place to store the actual result for the request
#
# The user_data argument is the user data item of the auth argument (see below)
# passed to libvirt.openAuth().
def request_credentials(credentials: List[List], user_data: Any) -> int:
for credential in credentials:
if credential[0] == libvirt.VIR_CRED_AUTHNAME:
# prompt the user to input a authname. display the provided message
credential[4] = input(credential[1] + ": ")
# if the user just hits enter raw_input() returns an empty string.
# in this case return the default result through the last item of
# the list
if len(credential[4]) == 0:
credential[4] = credential[3]
elif credential[0] == libvirt.VIR_CRED_NOECHOPROMPT:
# use the getpass module to prompt the user to input a password.
# display the provided message and return the result through the
# last item of the list
credential[4] = getpass.getpass(credential[1] + ": ")
else:
return -1
return 0
def print_section(title: str) -> None:
print("\n%s" % title)
print("=" * 60)
def print_entry(key: str, value: Any) -> None:
print("%-10s %-10s" % (key, value))
def print_xml(key: str, ctx, path: str) -> str:
res = ctx.xpathEval(path)
if res is None or len(res) == 0:
value = "Unknown"
else:
value = res[0].content
print_entry(key, value)
return value
parser = ArgumentParser(description=__doc__)
parser.add_argument("hostname")
args = parser.parse_args()
# Connect to libvirt
uri = "esx://%s/?no_verify=1" % args.hostname
# The auth argument is a list that contains 3 items:
# - a list of supported credential types
# - a callable that takes 2 arguments
# - user data that will be passed to the callable as second argument
#
# In this example the supported credential types are VIR_CRED_AUTHNAME and
# VIR_CRED_NOECHOPROMPT, the callable is the unbound method request_credentials
# (see above) and the user data is None.
#
# libvirt (actually the ESX driver) will call the callable to request
# credentials in order to log into the ESX host. The callable would also be
# called if the connection URI would reference a vCenter to request credentials
# in order to log into the vCenter
auth = [[libvirt.VIR_CRED_AUTHNAME, libvirt.VIR_CRED_NOECHOPROMPT],
request_credentials, None]
try:
conn = libvirt.openAuth(uri, auth, 0)
except libvirt.libvirtError:
print("Failed to open connection to %s" % args.hostname)
exit(1)
state_names = {
libvirt.VIR_DOMAIN_RUNNING: "running",
libvirt.VIR_DOMAIN_BLOCKED: "idle",
libvirt.VIR_DOMAIN_PAUSED: "paused",
libvirt.VIR_DOMAIN_SHUTDOWN: "in shutdown",
libvirt.VIR_DOMAIN_SHUTOFF: "shut off",
libvirt.VIR_DOMAIN_CRASHED: "crashed",
libvirt.VIR_DOMAIN_NOSTATE: "no state",
}
for id in conn.listDomainsID():
domain = conn.lookupByID(id)
info = domain.info()
print_section("Domain " + domain.name())
print_entry("ID:", id)
print_entry("UUID:", domain.UUIDString())
print_entry("State:", state_names[info[0]])
print_entry("MaxMem:", info[1])
print_entry("UsedMem:", info[2])
print_entry("VCPUs:", info[3])
# Read some info from the XML desc
print_section("Devices of " + domain.name())
xmldesc = domain.XMLDesc(0)
doc = libxml2.parseDoc(xmldesc)
ctx = doc.xpathNewContext()
devs = ctx.xpathEval("/domain/devices/*")
first = True
for d in devs:
ctx.setContextNode(d)
if not first:
print("------------------------------------------------------------")
else:
first = False
print_entry("Device", d.name)
type = print_xml("Type:", ctx, "@type")
if type == "file":
print_xml("Source:", ctx, "source/@file")
print_xml("Target:", ctx, "target/@dev")
elif type == "block":
print_xml("Source:", ctx, "source/@dev")
print_xml("Target:", ctx, "target/@dev")
elif type == "bridge":
print_xml("Source:", ctx, "source/@bridge")
print_xml("MAC Addr:", ctx, "mac/@address")
|