summaryrefslogtreecommitdiffstats
path: root/scripts/run-qemu-ota
diff options
context:
space:
mode:
authorPhil Wise <phil@advancedtelematic.com>2017-07-20 10:20:31 +0200
committerPhil Wise <phil@advancedtelematic.com>2017-07-20 10:20:31 +0200
commit5ec153ae190020bfc5a75b5064348d45a565d21b (patch)
tree6377bd535ba93e3e7a77819021f3cd1e98eea762 /scripts/run-qemu-ota
parent6f7f86bf7d71d31bfc5407d2a97eeab3ec18dc36 (diff)
downloadmeta-updater-5ec153ae190020bfc5a75b5064348d45a565d21b.tar.gz
Copy run-qemu script over from meta-updater-qemux86-64
Also remove old bash scripts for running inside qemu
Diffstat (limited to 'scripts/run-qemu-ota')
-rwxr-xr-xscripts/run-qemu-ota150
1 files changed, 150 insertions, 0 deletions
diff --git a/scripts/run-qemu-ota b/scripts/run-qemu-ota
new file mode 100755
index 0000000..181558c
--- /dev/null
+++ b/scripts/run-qemu-ota
@@ -0,0 +1,150 @@
1#! /usr/bin/env python
2
3from argparse import ArgumentParser
4from subprocess import Popen
5from os.path import exists, join, realpath
6from os import listdir
7import random
8import sys
9import socket
10
11DEFAULT_DIR = 'tmp/deploy/images'
12
13EXTENSIONS = {
14 'intel-corei7-64': 'wic',
15 'qemux86-64': 'otaimg'
16}
17
18
19def find_local_port(start_port):
20 """"
21 Find the next free TCP port after 'start_port'.
22 """
23
24 for port in range(start_port, start_port + 10):
25 try:
26 s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
27 s.bind(('', port))
28 return port
29 except socket.error:
30 print("Skipping port %d" % port)
31 finally:
32 s.close()
33 raise Exception("Could not find a free TCP port")
34
35
36def random_mac():
37 """Return a random Ethernet MAC address
38 @link https://www.iana.org/assignments/ethernet-numbers/ethernet-numbers.xhtml#ethernet-numbers-2
39 """
40 head = "ca:fe:"
41 hex_digits = '0123456789abcdef'
42 tail = ':'.join([random.choice(hex_digits) + random.choice(hex_digits) for _ in range(4)])
43 return head + tail
44
45
46class QemuCommand(object):
47 def __init__(self, args):
48 if args.machine:
49 self.machine = args.machine
50 else:
51 machines = listdir(args.dir)
52 if len(machines) == 1:
53 self.machine = machines[0]
54 else:
55 raise ValueError("Could not autodetect machine type from %s" % args.dir)
56 if args.efi:
57 self.bios = 'OVMF.fd'
58 else:
59 uboot = join(args.dir, self.machine, 'u-boot-qemux86-64.rom')
60 if not exists(uboot):
61 raise ValueError("U-Boot image %s does not exist" % uboot)
62 self.bios = uboot
63 ext = EXTENSIONS.get(self.machine, 'wic')
64 image = join(args.dir, self.machine, '%s-%s.%s' % (args.imagename, self.machine, ext))
65 self.image = realpath(image)
66 if not exists(self.image):
67 raise ValueError("OS image %s does not exist" % self.image)
68 if args.mac:
69 self.mac_address = args.mac
70 else:
71 self.mac_address = random_mac()
72 self.serial_port = find_local_port(8990)
73 self.ssh_port = find_local_port(2222)
74 self.kvm = not args.no_kvm
75 self.gui = not args.no_gui
76 self.gdb = args.gdb
77 self.pcap = args.pcap
78
79 def command_line(self):
80 netuser = 'user,hostfwd=tcp:0.0.0.0:%d-:22,restrict=off' % self.ssh_port
81 if self.gdb:
82 netuser += ',hostfwd=tcp:0.0.0.0:2159-:2159'
83 cmdline = [
84 "qemu-system-x86_64",
85 "-bios", self.bios,
86 "-drive", "file=%s,if=ide,format=raw,snapshot=on" % self.image,
87 "-serial", "tcp:127.0.0.1:%d,server,nowait" % self.serial_port,
88 "-m", "1G",
89 "-usb",
90 "-usbdevice", "tablet",
91 "-show-cursor",
92 "-vga", "std",
93 "-net", netuser,
94 "-net", "nic,macaddr=%s" % self.mac_address
95 ]
96 if self.pcap:
97 cmdline += ['-net', 'dump,file=' + self.pcap]
98 if self.gui:
99 cmdline += ["-serial", "stdio"]
100 else:
101 cmdline.append('-nographic')
102 if self.kvm:
103 cmdline.append('-enable-kvm')
104 else:
105 cmdline += ['-cpu', 'Haswell']
106 return cmdline
107
108
109def main():
110 parser = ArgumentParser(description='Run meta-updater image in qemu')
111 parser.add_argument('imagename', default='core-image-minimal', nargs='?')
112 parser.add_argument('mac', default=None, nargs='?')
113 parser.add_argument('--dir', default=DEFAULT_DIR,
114 help='Path to build directory containing the image and u-boot-qemux86-64.rom')
115 parser.add_argument('--efi',
116 help='Boot using UEFI rather than U-Boot. This requires the image to be built with ' +
117 'OSTREE_BOOTLOADER = "grub" and OVMF.fd firmware to be installed (try "apt install ovmf")',
118 action='store_true')
119 parser.add_argument('--machine', default=None, help="Target MACHINE")
120 parser.add_argument('--no-kvm', help='Disable KVM in QEMU', action='store_true')
121 parser.add_argument('--no-gui', help='Disable GUI', action='store_true')
122 parser.add_argument('--gdb', help='Export gdbserver port 2159 from the image', action='store_true')
123 parser.add_argument('--pcap', default=None, help='Dump all network traffic')
124 parser.add_argument('-n', '--dry-run', help='Print qemu command line rather then run it', action='store_true')
125 args = parser.parse_args()
126 try:
127 qemu_command = QemuCommand(args)
128 except ValueError as e:
129 print(e.message)
130 sys.exit(1)
131
132 print("Launching %s with mac address %s" % (args.imagename, qemu_command.mac_address))
133 print("To connect via SSH:")
134 print(" ssh -o StrictHostKeyChecking=no root@localhost -p %d" % qemu_command.ssh_port)
135 print("To connect to the serial console:")
136 print(" nc localhost %d" % qemu_command.serial_port)
137
138 cmdline = qemu_command.command_line()
139 if args.dry_run:
140 print(" ".join(cmdline))
141 else:
142 s = Popen(cmdline)
143 try:
144 s.wait()
145 except KeyboardInterrupt:
146 pass
147
148
149if __name__ == '__main__':
150 main()