55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
|
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
|
-
+
-
+
-
+
|
# There can be stray (qemu) prompt in the socket. Try to drain
# it
try:
sock.recv(64, socket.MSG_DONTWAIT)
except socket.error as ex:
if ex.errno != errno.EAGAIN and ex.errno != errno.EWOULDBLOCK:
raise ex
sock.send(command + "\n")
sock.send((command + "\n").encode("utf-8"))
answer = ""
while not answer.endswith("(qemu) "):
chunk = sock.recv(1024)
if chunk == '':
if chunk == b'':
raise IOError("Unexpected EOF from monitor")
answer += chunk
answer += chunk.decode("utf-8")
finally:
fcntl.flock(sock, fcntl.LOCK_UN)
return answer
def spiceurl(sock):
""" Returns spice URI for given (as set of parsed args) VM """
output = send_command(sock, "info spice")
|
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
|
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
|
-
+
|
return lst
def parse_arp(iface):
"""
Returns map which maps mac addresses to IPs for specified interface"
"""
addr_map = {}
pipe = os.popen("%s -n -u %s" % (config.get("tools", "arp"), iface), "r")
pipe = os.popen("%s -n -i %s" % (config.get("tools", "arp"), iface), "r")
for line in pipe:
data = line.split()
mac = data[2]
if mac == "HWAddress":
continue
if mac == iface:
# Foind line with (incomplete) entry
|
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
|
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
|
-
+
|
answer = send_command(sock, "info block")
return re.search(": /tmp", answer) is not None
def read_netinfo(filename):
""" Reads network information from start script """
with open(filename, "r") as f:
for line in f:
match = re.search("-net nic,macaddr=(\\S+) -net ([^, ]+)", line)
match = re.search("-net nic,(?:\S*,)?macaddr=(\\S+) -net ([^, ]+)", line)
if match:
f = {"mac":match.group(1)}
if match.group(2) == "user":
f["iface"] = "user"
elif match.group(2) == "bridge":
f["iface"] = re.search("br=(\\S+)", line).group(1)
else:
|
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
|
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
|
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
-
+
-
+
-
-
|
f["uri"] = uri[uri.rindex(":")+1:]
f.update(get_netinfo(sock))
sock.shutdown(socket.SHUT_RDWR)
sock.close()
f["state"] = "running"
return f
def matches(name, patterns):
""" checks if name matches one of patterns """
import fnmatch
for pattern in patterns:
if fnmatch.fnmatch(name, pattern):
return True
return False
def add_ip_address(listing):
""" Adds IP addresses from ARP into VM listing """
bridges = set()
for vminfo in listing:
if "ip" not in vminfo:
bridges.add(vminfo["iface"])
arp_data = {}
for bridge in bridges:
arp_data.update(parse_arp(bridge))
for vminfo in listing:
if "mac" in vminfo and not "ip" in vminfo:
if vminfo["mac"] in arp_data:
vminfo["ip"] = arp_data[vminfo["mac"]]
else:
vminfo["ip"] = "-"
def all_vms():
def all_vms(patterns=["*"]):
"""
Returns list of tuples vmname, vmtype, directory
for all vms
"""
import fnmatch
search_path = [("private", os.path.join(pwd.getpwuid(os.getuid()).pw_dir,
"VWs")),
("shared", config.get("directories", "SharedVMs")),
("autostart", config.get("directories", "AutostartVMs"))]
vmlist = []
for (vmtype, dirname) in search_path:
if not os.access(dirname, os.X_OK):
continue
for vmname in os.listdir(dirname):
if not os.access(os.path.join(dirname, vmname, "start"), os.X_OK):
continue
matches = False
for pattern in patterns:
if fnmatch.fnmatch(vmname, pattern):
matches = True
break
if matches:
vmlist.append((vmname, vmtype, os.path.join(dirname, vmname)))
vmlist.append((vmname, vmtype, os.path.join(dirname, vmname)))
return vmlist
def cmd_list(options):
""" vws list """
count = 0
maxlen = 0
vms = []
for vmname, vmtype, dirname in all_vms():
for vmname, vmtype, dirname in all_vms(options.pattern):
if not matches(vmname, options.pattern):
continue
count += 1
if maxlen < len(vmname):
maxlen = len(vmname)
if options.state:
vms.append(make_vm_listing(vmname, dirname, vmtype))
else:
vms.append({"name":vmname})
|
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
|
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
|
+
+
+
+
-
+
|
os.system("qemu-img create -f qcow2 -b \"%s\" \"%s\"" %
(newnames[i], i))
os.chmod(i, 0o664)
return 0
def cmd_snapshots(options):
""" vws snapshots - list existing snapshots """
if not options.stopped:
print("Cannot list snapshots of running VW", file=sys.stderr)
sys.exit(1)
os.chdir(options.dir)
drives = get_drives(options.dir)
lst = []
info = {}
with os.popen("qemu-img info --backing-chain " + drives[0], "r") as f:
for line in f:
if line.find(": ") != -1:
var, val = line.strip().split(": ")
if val != "":
info[var] = val
elif line[0] == '\n':
lst.append(info)
info = {}
if info:
lst.append(info)
lst.append(info)
for snap in lst:
print("%-30s %+8s %+8s" % (snap["image"], snap["virtual size"],
snap["disk size"]))
def get_backing(drive):
""" find if partucular virtual drive has backing file and returns
|