From c8d72df32a96658aaf9c601e0a9093bac090cd5e Mon Sep 17 00:00:00 2001 From: Till Maas Date: May 23 2018 13:11:40 +0000 Subject: [PATCH 1/2] Use random port for hostfwd This reduces a race condition that the port allocation might fail for qemu. --- diff --git a/inventory/standard-inventory-qcow2 b/inventory/standard-inventory-qcow2 index 43af9a5..d15de7a 100755 --- a/inventory/standard-inventory-qcow2 +++ b/inventory/standard-inventory-qcow2 @@ -1,19 +1,20 @@ #!/usr/bin/env python import argparse +import distutils.util import errno import json +import multiprocessing import os -import shutil +import random import shlex +import shutil import signal -import multiprocessing import socket import subprocess import sys import tempfile import time -import distutils.util IDENTITY = """ -----BEGIN RSA PRIVATE KEY----- @@ -111,7 +112,10 @@ def inv_list(subjects): def start_qemu(image, cloudinit, log, portrange=(2222, 5555)): - for port in range(*portrange): + + tries = 0 + while tries < (portrange[1] - portrange[0]): + port = random.randrange(*portrange) sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) try: @@ -122,6 +126,7 @@ def start_qemu(image, cloudinit, log, portrange=(2222, 5555)): break finally: sock.close() + tries += 1 else: raise RuntimeError("unable to find free local port to map SSH to") From 8e70d7c2dd1ebc9729e943c17ad2416824b27ec3 Mon Sep 17 00:00:00 2001 From: Till Maas Date: May 23 2018 13:14:29 +0000 Subject: [PATCH 2/2] Use random vnc port This reduces the chances of conflicts, this addresses issue #199. However, ideally the script should retry to start qemu if a port allocation fails instead of hoping to get a free port. --- diff --git a/inventory/standard-inventory-qcow2 b/inventory/standard-inventory-qcow2 index d15de7a..7e94f2b 100755 --- a/inventory/standard-inventory-qcow2 +++ b/inventory/standard-inventory-qcow2 @@ -130,15 +130,20 @@ def start_qemu(image, cloudinit, log, portrange=(2222, 5555)): else: raise RuntimeError("unable to find free local port to map SSH to") + vncoffset = portrange[1] - port # Use -cpu host and -smp by default. # virtio-rng-pci: https://wiki.qemu.org/Features/VirtIORNG - return subprocess.Popen(["/usr/bin/qemu-system-x86_64", - "-cpu", "host", "-smp", "{}".format(multiprocessing.cpu_count()), - "-m", "1024", image, "-enable-kvm", "-snapshot", "-cdrom", cloudinit, - "-net", "nic,model=virtio", "-net", "user,hostfwd=tcp:127.0.0.3:{0}-:22".format(port), - "-device", "virtio-rng-pci", "-rtc", "base=utc", - "-device", "isa-serial,chardev=pts2", "-chardev", "file,id=pts2,path=" + log, - "-display", "none", "-vnc", ":1"], stdout=open(log, 'a'), stderr=subprocess.STDOUT), port + return subprocess.Popen( + ["/usr/bin/qemu-system-x86_64", "-cpu", "host", + "-smp", "{}".format(multiprocessing.cpu_count()), + "-m", "1024", image, "-enable-kvm", "-snapshot", "-cdrom", cloudinit, + "-net", "nic,model=virtio", + "-net", "user,hostfwd=tcp:127.0.0.3:{0}-:22".format(port), + "-device", "virtio-rng-pci", "-rtc", "base=utc", + "-device", "isa-serial,chardev=pts2", + "-chardev", "file,id=pts2,path=" + log, "-display", "none", + "-vnc", ":" + str(vncoffset) + ], stdout=open(log, 'a'), stderr=subprocess.STDOUT), port def inv_host(image):