summaryrefslogtreecommitdiffstats
path: root/scripts/qemucommand.py
diff options
context:
space:
mode:
Diffstat (limited to 'scripts/qemucommand.py')
-rw-r--r--scripts/qemucommand.py132
1 files changed, 132 insertions, 0 deletions
diff --git a/scripts/qemucommand.py b/scripts/qemucommand.py
new file mode 100644
index 0000000..86362f7
--- /dev/null
+++ b/scripts/qemucommand.py
@@ -0,0 +1,132 @@
1from os.path import exists, join, realpath, abspath
2from os import listdir
3import random
4import socket
5from subprocess import check_output, CalledProcessError
6
7EXTENSIONS = {
8 'intel-corei7-64': 'wic',
9 'qemux86-64': 'otaimg'
10}
11
12
13def find_local_port(start_port):
14 """"
15 Find the next free TCP port after 'start_port'.
16 """
17
18 for port in range(start_port, start_port + 10):
19 try:
20 s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
21 s.bind(('', port))
22 return port
23 except socket.error:
24 print("Skipping port %d" % port)
25 finally:
26 s.close()
27 raise Exception("Could not find a free TCP port")
28
29
30def random_mac():
31 """Return a random Ethernet MAC address
32 @link https://www.iana.org/assignments/ethernet-numbers/ethernet-numbers.xhtml#ethernet-numbers-2
33 """
34 head = "ca:fe:"
35 hex_digits = '0123456789abcdef'
36 tail = ':'.join([random.choice(hex_digits) + random.choice(hex_digits) for _ in range(4)])
37 return head + tail
38
39
40class QemuCommand(object):
41 def __init__(self, args):
42 if args.machine:
43 self.machine = args.machine
44 else:
45 machines = listdir(args.dir)
46 if len(machines) == 1:
47 self.machine = machines[0]
48 else:
49 raise ValueError("Could not autodetect machine type. More than one entry in %s. Maybe --machine qemux86-64?" % args.dir)
50 if args.efi:
51 self.bios = 'OVMF.fd'
52 else:
53 uboot = abspath(join(args.dir, self.machine, 'u-boot-qemux86-64.rom'))
54 if not exists(uboot):
55 raise ValueError("U-Boot image %s does not exist" % uboot)
56 self.bios = uboot
57 if exists(args.imagename):
58 image = args.imagename
59 else:
60 ext = EXTENSIONS.get(self.machine, 'wic')
61 image = join(args.dir, self.machine, '%s-%s.%s' % (args.imagename, self.machine, ext))
62 self.image = realpath(image)
63 if not exists(self.image):
64 raise ValueError("OS image %s does not exist" % self.image)
65 if args.mac:
66 self.mac_address = args.mac
67 else:
68 self.mac_address = random_mac()
69 self.serial_port = find_local_port(8990)
70 self.ssh_port = find_local_port(2222)
71 if args.kvm is None:
72 # Autodetect KVM using 'kvm-ok'
73 try:
74 check_output(['kvm-ok'])
75 self.kvm = True
76 except Exception:
77 self.kvm = False
78 else:
79 self.kvm = args.kvm
80 self.gui = not args.no_gui
81 self.gdb = args.gdb
82 self.pcap = args.pcap
83 self.overlay = args.overlay
84 self.secondary_network = args.secondary_network
85
86 def command_line(self):
87 netuser = 'user,hostfwd=tcp:0.0.0.0:%d-:22,restrict=off' % self.ssh_port
88 if self.gdb:
89 netuser += ',hostfwd=tcp:0.0.0.0:2159-:2159'
90 cmdline = [
91 "qemu-system-x86_64",
92 "-bios", self.bios
93 ]
94 if not self.overlay:
95 cmdline += ["-drive", "file=%s,if=ide,format=raw,snapshot=on" % self.image]
96 cmdline += [
97 "-serial", "tcp:127.0.0.1:%d,server,nowait" % self.serial_port,
98 "-m", "1G",
99 "-usb",
100 "-device", "usb-tablet",
101 "-show-cursor",
102 "-vga", "std",
103 "-net", netuser,
104 "-net", "nic,macaddr=%s" % self.mac_address
105 ]
106 if self.pcap:
107 cmdline += ['-net', 'dump,file=' + self.pcap]
108 if self.secondary_network:
109 cmdline += [
110 '-net', 'nic,vlan=1,macaddr='+random_mac(),
111 '-net', 'socket,vlan=1,mcast=230.0.0.1:1234,localaddr=127.0.0.1',
112 ]
113 if self.gui:
114 cmdline += ["-serial", "stdio"]
115 else:
116 cmdline.append('-nographic')
117 if self.kvm:
118 cmdline += ['-enable-kvm', '-cpu', 'host']
119 else:
120 cmdline += ['-cpu', 'Haswell']
121 if self.overlay:
122 cmdline.append(self.overlay)
123 return cmdline
124
125 def img_command_line(self):
126 cmdline = [
127 "qemu-img", "create",
128 "-o", "backing_file=%s" % self.image,
129 "-f", "qcow2",
130 self.overlay]
131 return cmdline
132