1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
#!/usr/bin/env python3
# -*- encoding: utf-8 -*-
""" vws - script to control QEMU/KVM virtual workstations """
# pylint: disable=too-many-lines
from configparser import ConfigParser
from argparse import ArgumentParser, Namespace
import fcntl
import socket
import select
import errno
import re
import os
import os.path
import sys
import time
import pwd
VERSION = 0.8
def find_vm(name):
""" Search and return VM directory """
search_path = [os.path.join(pwd.getpwuid(os.getuid()).pw_dir, "VWs"),
config.get("directories", "SharedVMs"),
config.get("directories", "AutostartVMs")]
|
>
>
>
>
|
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
|
#!/usr/bin/env python3
# -*- encoding: utf-8 -*-
""" vws - script to control QEMU/KVM virtual workstations """
# pylint: disable=too-many-lines
from configparser import ConfigParser
from argparse import ArgumentParser, Namespace
import fcntl
import socket
import select
import errno
import re
import os
import os.path
import fnmatch
import shlex
import shutil
import sys
import time
import pwd
import grp
VERSION = 0.8
def find_vm(name):
""" Search and return VM directory """
search_path = [os.path.join(pwd.getpwuid(os.getuid()).pw_dir, "VWs"),
config.get("directories", "SharedVMs"),
config.get("directories", "AutostartVMs")]
|
︙ | | | ︙ | |
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
|
try:
sock.connect(monitor_path)
except IOError as ex:
if ex.errno == errno.ECONNREFUSED:
# virtal machine is not running
return None
raise ex
readfd, dummy_w, dummy_x = select.select([sock], [], [], 0.1)
if sock in readfd:
dummy_greeting = sock.recv(1024)
return sock
def send_command(sock, command):
""" Sends monitor command to given socket and returns answer """
if sock is None:
raise RuntimeError("None socket is passed to send_command")
fcntl.flock(sock, fcntl.LOCK_EX)
|
|
|
|
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
|
try:
sock.connect(monitor_path)
except IOError as ex:
if ex.errno == errno.ECONNREFUSED:
# virtal machine is not running
return None
raise ex
readfd, _, _ = select.select([sock], [], [], 0.1)
if sock in readfd:
_ = sock.recv(1024)
return sock
def send_command(sock, command):
""" Sends monitor command to given socket and returns answer """
if sock is None:
raise RuntimeError("None socket is passed to send_command")
fcntl.flock(sock, fcntl.LOCK_EX)
|
︙ | | | ︙ | |
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
|
return None
def make_start_cmdline(options):
"""
Append options passed from vws commandline to start script
commandline
"""
arg = ""
if options.cdrom:
arg = " -cdrom " + os.path.abspath(options.cdrom[0])
if options.snapshot:
arg = arg+" -snapshot"
if options.args:
arg = arg + " " + "".join(options.args)
if options.password:
os.environ["SPICE_PASSWORD"] = options.password[0]
return arg
def cmd_start(options):
""" vws start """
if not "DISPLAY" in os.environ:
# If cannot start GUI just don't do it.
options.gui = False
if options.stopped:
arg = make_start_cmdline(options)
cwd = os.getcwd()
os.chdir(options.dir)
# Check for snapshot
snapshot_id = check_for_snapshot(options.dir)
if snapshot_id is not None:
arg = arg + " -loadvm " + snapshot_id
# Check for correct brige name
try:
os.stat("monitor")
except FileNotFoundError:
# We cannot find monitor socket. So this machine might be
# never run on this host
fix_bridge_name("start")
|
|
>
|
|
|
>
>
|
|
|
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
|
return None
def make_start_cmdline(options):
"""
Append options passed from vws commandline to start script
commandline
"""
arg = []
if options.cdrom:
arg.append("-cdrom")
arg.append(os.path.abspath(options.cdrom[0]))
if options.snapshot:
arg.append("-snapshot")
if options.args:
arg.append( "".join(options.args))
if options.password:
os.environ["SPICE_PASSWORD"] = options.password[0]
if arg:
return shlex.join(arg)
return ""
def cmd_start(options):
""" vws start """
if not "DISPLAY" in os.environ:
# If cannot start GUI just don't do it.
options.gui = False
if options.stopped:
arg = make_start_cmdline(options)
cwd = os.getcwd()
os.chdir(options.dir)
# Check for snapshot
snapshot_id = check_for_snapshot(options.dir)
if snapshot_id is not None:
arg = arg + " " + shlex.join(["-loadvm", snapshot_id])
# Check for correct brige name
try:
os.stat("monitor")
except FileNotFoundError:
# We cannot find monitor socket. So this machine might be
# never run on this host
fix_bridge_name("start")
|
︙ | | | ︙ | |
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
|
idx = answer.index('\n')
print(answer[idx+1:], end="")
eol = answer.endswith("\n")
sys.stdout.flush()
elif options.sock in readfd:
print("UNSOLICITED MESSAGE %" +
options.sock.recv(1000).decode("utf-8").rstrip())
eol = True
except KeyboardInterrupt:
if not eol:
print("")
eol = True
print("Keyboard interrupt")
if not eol:
print("")
|
|
|
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
|
idx = answer.index('\n')
print(answer[idx+1:], end="")
eol = answer.endswith("\n")
sys.stdout.flush()
elif options.sock in readfd:
print("UNSOLICITED MESSAGE %" +
options.sock.recv(1000).decode("utf-8").rstrip())
eol = True
except KeyboardInterrupt:
if not eol:
print("")
eol = True
print("Keyboard interrupt")
if not eol:
print("")
|
︙ | | | ︙ | |
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
|
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(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):
|
|
<
|
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
|
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(patterns=("*",)):
"""
Returns list of tuples vmname, vmtype, directory
for all vms
"""
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):
|
︙ | | | ︙ | |
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
|
else:
print(f["name"])
if not count:
sys.exit(1)
def cmd_screenshot(options):
""" vws screenshot """
from os.path import abspath
filename = abspath(options.filename)
print(send_command(options.sock, "screendump " + filename))
def cmd_record(options):
""" vws record """
from os.path import abspath
filename = abspath(options.filename)
print(send_command(options.sock, "wavcapture " + filename))
def cmd_stoprecord(options):
""" vws stoprecord """
answer = send_command(options.sock, "info capture")
match = re.search('\\[(\\d+)\\]: ', answer)
if not match:
|
<
|
<
|
|
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
|
else:
print(f["name"])
if not count:
sys.exit(1)
def cmd_screenshot(options):
""" vws screenshot """
filename = os.path.abspath(options.filename)
print(send_command(options.sock, "screendump " + filename))
def cmd_record(options):
""" vws record """
filename = os.path.abspath(options.filename)
print(send_command(options.sock, "wavcapture " + filename))
def cmd_stoprecord(options):
""" vws stoprecord """
answer = send_command(options.sock, "info capture")
match = re.search('\\[(\\d+)\\]: ', answer)
if not match:
|
︙ | | | ︙ | |
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
|
print("")
def cmd_shutdown(options):
""" Search for all running machines and stops all of them """
dirlist = [config.get("directories", "AutostartVMs"),
config.get("directories", "SharedVms")]
if os.getresuid()[1] == 0:
import grp
dirlist += map(lambda x: os.path.expanduser("~"+x)+"/VWs",
grp.getgrnam(config.get("permissions",
"vm_group")).gr_mem)
else:
dirlist.append(os.path.expanduser("~")+"/VWs")
count = 1 #Fake positive values for there is not postcondition loop in the python
forced_finish = time.time() + options.timeout
|
<
|
712
713
714
715
716
717
718
719
720
721
722
723
724
725
|
print("")
def cmd_shutdown(options):
""" Search for all running machines and stops all of them """
dirlist = [config.get("directories", "AutostartVMs"),
config.get("directories", "SharedVms")]
if os.getresuid()[1] == 0:
dirlist += map(lambda x: os.path.expanduser("~"+x)+"/VWs",
grp.getgrnam(config.get("permissions",
"vm_group")).gr_mem)
else:
dirlist.append(os.path.expanduser("~")+"/VWs")
count = 1 #Fake positive values for there is not postcondition loop in the python
forced_finish = time.time() + options.timeout
|
︙ | | | ︙ | |
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
|
options["memory"] = parsed_args.mem
if parsed_args.localtime:
options["rtc"] = "-rtc base=localtime,clock=host \\\n"
if os.path.exists(machinedir):
if os.path.exists(os.path.join(machinedir, "start")):
raise OSError("Virtual Worstation %s already exists" %
parsed_args.machine)
else:
raise OSError("Cannot create VW directory, " +
"something on the way")
# Creating directory for VM
os.makedirs(machinedir, dirmode)
parsed_args.dir = machinedir
if parsed_args.shared:
import grp
gid = grp.getgrnam(config.get("permissions", "vm_group")).gr_gid
uid = os.getuid()
os.chown(machinedir, uid, gid)
if config.getboolean("permissions", "setgid_vm"):
os.chmod(machinedir, 0o2775)
driveopts = {"interface":parsed_args.diskif, "image":drivename}
if parsed_args.install:
|
|
|
>
<
|
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
|
options["memory"] = parsed_args.mem
if parsed_args.localtime:
options["rtc"] = "-rtc base=localtime,clock=host \\\n"
if os.path.exists(machinedir):
if os.path.exists(os.path.join(machinedir, "start")):
exc = OSError("Virtual Worstation %s already exists" %
parsed_args.machine)
else:
exc = OSError("Cannot create VW directory, " +
"something on the way")
raise exc
# Creating directory for VM
os.makedirs(machinedir, dirmode)
parsed_args.dir = machinedir
if parsed_args.shared:
gid = grp.getgrnam(config.get("permissions", "vm_group")).gr_gid
uid = os.getuid()
os.chown(machinedir, uid, gid)
if config.getboolean("permissions", "setgid_vm"):
os.chmod(machinedir, 0o2775)
driveopts = {"interface":parsed_args.diskif, "image":drivename}
if parsed_args.install:
|
︙ | | | ︙ | |
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
|
'permissions':{'vm_group':'kvm',
'autostart_user':'root',
'setgid_vm':'yes'}})
def read_config(conf):
""" Read configration files """
if os.getuid() != 0:
conf.read(['/etc/vws.conf',
os.path.join(pwd.getpwuid(os.getuid()).pw_dir, '.vwsrc')])
else:
conf.read(['/etc/vws.conf'])
def main():
""" Parse an arguments and execute everything """
global config
config_defaults(config)
read_config(config)
|
>
>
|
|
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
|
'permissions':{'vm_group':'kvm',
'autostart_user':'root',
'setgid_vm':'yes'}})
def read_config(conf):
""" Read configration files """
if os.getuid() != 0:
home = pwd.getpwuid(os.getuid()).pw_dir
conf.read(['/etc/vws.conf',
os.path.join(home, ".config", "vws", "vws.conf"),
os.path.join(home, '.vwsrc')])
else:
conf.read(['/etc/vws.conf'])
def main():
""" Parse an arguments and execute everything """
global config
config_defaults(config)
read_config(config)
|
︙ | | | ︙ | |
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
|
# Create command is totally different, so it is handled separately
if parsed_args.command == 'create':
try:
cmd_create(parsed_args)
except Exception as ex: # pylint: disable=broad-except
print(str(ex), file=sys.stderr)
if hasattr(parsed_args, "dir"):
import shutil
shutil.rmtree(parsed_args.dir)
sys.exit(1)
sys.exit(0)
if parsed_args.command is None:
args.print_help()
sys.exit(0)
|
<
|
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
|
# Create command is totally different, so it is handled separately
if parsed_args.command == 'create':
try:
cmd_create(parsed_args)
except Exception as ex: # pylint: disable=broad-except
print(str(ex), file=sys.stderr)
if hasattr(parsed_args, "dir"):
shutil.rmtree(parsed_args.dir)
sys.exit(1)
sys.exit(0)
if parsed_args.command is None:
args.print_help()
sys.exit(0)
|
︙ | | | ︙ | |