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
|
from os.path import exists, join, realpath, abspath
from os import listdir
import random
import socket
from subprocess import check_output, CalledProcessError
EXTENSIONS = {
'intel-corei7-64': 'wic',
'qemux86-64': 'otaimg'
}
def find_local_port(start_port):
""""
Find the next free TCP port after 'start_port'.
"""
for port in range(start_port, start_port + 10):
try:
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind(('', port))
return port
except socket.error:
print("Skipping port %d" % port)
finally:
s.close()
raise Exception("Could not find a free TCP port")
def random_mac():
"""Return a random Ethernet MAC address
@link https://www.iana.org/assignments/ethernet-numbers/ethernet-numbers.xhtml#ethernet-numbers-2
"""
head = "ca:fe:"
hex_digits = '0123456789abcdef'
tail = ':'.join([random.choice(hex_digits) + random.choice(hex_digits) for _ in range(4)])
return head + tail
class QemuCommand(object):
def __init__(self, args):
if args.machine:
self.machine = args.machine
else:
machines = listdir(args.dir)
if len(machines) == 1:
self.machine = machines[0]
else:
raise ValueError("Could not autodetect machine type. More than one entry in %s. Maybe --machine qemux86-64?" % args.dir)
if args.efi:
self.bios = 'OVMF.fd'
else:
uboot = abspath(join(args.dir, self.machine, 'u-boot-qemux86-64.rom'))
if not exists(uboot):
raise ValueError("U-Boot image %s does not exist" % uboot)
self.bios = uboot
if exists(args.imagename):
image = args.imagename
else:
ext = EXTENSIONS.get(self.machine, 'wic')
image = join(args.dir, self.machine, '%s-%s.%s' % (args.imagename, self.machine, ext))
self.image = realpath(image)
if not exists(self.image):
raise ValueError("OS image %s does not exist" % self.image)
if args.mac:
self.mac_address = args.mac
else:
self.mac_address = random_mac()
self.serial_port = find_local_port(8990)
self.ssh_port = find_local_port(2222)
if args.kvm is None:
# Autodetect KVM using 'kvm-ok'
try:
check_output(['kvm-ok'])
self.kvm = True
except CalledProcessError:
self.kvm = False
else:
self.kvm = args.kvm
self.gui = not args.no_gui
self.gdb = args.gdb
self.pcap = args.pcap
self.overlay = args.overlay
def command_line(self):
netuser = 'user,hostfwd=tcp:0.0.0.0:%d-:22,restrict=off' % self.ssh_port
if self.gdb:
netuser += ',hostfwd=tcp:0.0.0.0:2159-:2159'
cmdline = [
"qemu-system-x86_64",
"-bios", self.bios
]
if not self.overlay:
cmdline += ["-drive", "file=%s,if=ide,format=raw,snapshot=on" % self.image]
cmdline += [
"-serial", "tcp:127.0.0.1:%d,server,nowait" % self.serial_port,
"-m", "1G",
"-usb",
"-usbdevice", "tablet",
"-show-cursor",
"-vga", "std",
"-net", netuser,
"-net", "nic,macaddr=%s" % self.mac_address
]
if self.pcap:
cmdline += ['-net', 'dump,file=' + self.pcap]
if self.gui:
cmdline += ["-serial", "stdio"]
else:
cmdline.append('-nographic')
if self.kvm:
cmdline.append('-enable-kvm')
else:
cmdline += ['-cpu', 'Haswell']
if self.overlay:
cmdline.append(self.overlay)
return cmdline
def img_command_line(self):
cmdline = [
"qemu-img", "create",
"-o", "backing_file=%s" % self.image,
"-f", "qcow2",
self.overlay]
return cmdline
|