forked from doccaz/kvm-scripts
-
Notifications
You must be signed in to change notification settings - Fork 0
/
qemu-hook-script-python
executable file
·134 lines (106 loc) · 4.68 KB
/
qemu-hook-script-python
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
#!/usr/bin/python3
# Hook script for QEMU
#
# adds port forwards via IPtables to your VMs
# starts websocket daemons for the SPICE web client
#
# Erico Mendonca ([email protected])
# dec/2018
import os
import sys
import syslog
import subprocess
from subprocess import Popen
from lxml import etree
# global variable that holds the XML that QEMU gives us
MACHINE_INFO = ''
def getAttribute(searchstr, attrname):
global MACHINE_INFO
found = MACHINE_INFO.findall(searchstr)
try:
for i in found:
syslog.syslog("found = %s" % i.attrib[attrname])
return i.attrib[attrname]
except KeyError as e:
return ""
def runCommand(cmdargs):
syslog.syslog("Running command: %s" % cmdargs)
p = Popen(cmdargs, bufsize=1, stdin=subprocess.PIPE, stdout=subprocess.PIPE)
(child_stdout, child_stdin) = Popen.communicate(p)
#syslog.syslog("stdout: %s" % child_stdout)
#syslog.syslog("stdin: %s" % child_stdin)
#syslog.syslog("return code: %s" % p.returncode)
return (p.returncode, child_stdout, child_stdin)
def getPID(process_name):
try:
(rc, stdout, stdin) = runCommand(['/usr/bin/pgrep', '-f', '%s' % process_name])
if stdout:
return stdout.split('\n')
else:
return []
except TypeError as e:
return []
def addForward(VM, HOST_PORT, GUEST_IP, GUEST_PORT):
IPTABLES="/usr/sbin/iptables"
global ACTION, VM_NAME, SUBACTION
if (ACTION == "stopped") | (ACTION == "reconnect"):
IPTABLES_ACTION="-D"
end
if (ACTION == "start") | (ACTION == "reconnect"):
IPTABLES_ACTION="-I"
end
if VM == VM_NAME:
HOST_BRIDGE=getAttribute('/domain/devices/interface[1]/source', 'bridge')
if HOST_BRIDGE == "":
syslog.syslog("Could not identify bridge interface for VM " % VM % ", skipping")
sys.exit(0)
end
syslog.syslog("adding forwarding rules for VM %s" % VM_NAME % ": host port %s" % HOST_PORT % " will be redirected to %s" % GUEST_IP % ":" % GUEST_PORT % " on interface %s" % HOST_BRIDGE)
runCommand([IPTABLES, IPTABLES_ACTION, 'FORWARD', '-o', HOST_BRIDGE, '-d', GUEST_IP, '-j', 'ACCEPT'])
runCommand([IPTABLES, '-t', 'nat', IPTABLES_ACTION, 'PREROUTING', '-p', 'tcp', '--dport', HOST_PORT, '-j', 'DNAT', '--to', GUEST_IP % ':' % GUEST_PORT])
end
return
def main():
global MACHINE_INFO
syslog.openlog('qemu-hook')
VM_NAME=sys.argv[1]
ACTION=sys.argv[2]
SUBACTION=sys.argv[3]
MACHINE_INFO = etree.parse(sys.stdin)
SPICEPORT = getAttribute("./devices/graphics[@type='spice']", 'port')
VNCPORT = getAttribute("./devices/graphics[@type='vnc']", 'port')
#syslog.syslog("Spice port = %s" % SPICEPORT)
#syslog.syslog("action = %s, subaction = %s" % (ACTION, SUBACTION))
#syslog.syslog("vm name = %s" % VM_NAME)
if (ACTION == "stopped") & (SUBACTION == "end"):
if SPICEPORT != "":
DAEMONPID=getPID('.*websockify.*1%s.*' % SPICEPORT)
#syslog.syslog("action = stopped, pids to kill: %s" % DAEMONPID)
for pid in DAEMONPID:
if pid != "":
syslog.syslog("killing PID: %s" % pid)
os.kill(int(pid), 15)
runCommand(['firewall-cmd', '--permanent', '--remove-port=1%s/tcp' % SPICEPORT])
runCommand(['firewall-cmd', '--remove-port=1%s/tcp' % SPICEPORT])
if VNCPORT != "":
DAEMONPID=getPID('.*websockify.*1%s.*' % VNCPORT)
#syslog.syslog("action = stopped, pids to kill: %s" % DAEMONPID)
for pid in DAEMONPID:
if pid != "":
syslog.syslog("killing PID: %s" % pid)
os.kill(int(pid), 15)
runCommand(['firewall-cmd', '--permanent', '--remove-port=2%s/tcp' % VNCPORT])
runCommand(['firewall-cmd', '--remove-port=2%s/tcp' % VNCPORT])
if (ACTION == "started") & (SUBACTION == "begin"):
if SPICEPORT != "":
syslog.syslog("action = start, starting websockify on port 1%s" % SPICEPORT)
runCommand(['websockify', '-D', '1%s' % SPICEPORT, 'localhost:%s' % SPICEPORT])
runCommand(['firewall-cmd', '--permanent', '--add-port=1%s/tcp' % SPICEPORT])
runCommand(['firewall-cmd', '--add-port=1%s/tcp' % SPICEPORT])
if VNCPORT != "":
syslog.syslog("action = start, starting websockify on port 2%s" % VNCPORT)
runCommand(['websockify', '-D', '2%s' % VNCPORT, 'localhost:%s' % VNCPORT])
runCommand(['firewall-cmd', '--permanent', '--add-port=2%s/tcp' % VNCPORT])
runCommand(['firewall-cmd', '--add-port=2%s/tcp' % VNCPORT])
if __name__ == "__main__":
main()