From bdcee4d4acbd5ec629a95b00f7947eec28389b52 Mon Sep 17 00:00:00 2001 From: Jan Pokorny Date: Sep 13 2018 14:13:32 +0000 Subject: Now posible to use additional disks - additional disks for qemu can be specified using FMF --- diff --git a/README.md b/README.md index 063aa86..6b66597 100644 --- a/README.md +++ b/README.md @@ -55,6 +55,10 @@ standard-inventory-qcow2: m: 3G net_nic: model: e1000 + drive: + - size: 11000000000 + path: /home/vader + - size: 2000000000 standard-inventory-docker: dumb_option: dumb_parameter @@ -67,6 +71,11 @@ standard-inventory-docker: * `qemu.m` - RAM size in megabytes. Optionally, a suffix of `M` or `G`. * `qemu.net_nic.model` - Use `qemu-system-x86_64 -net nic,model=help` for a list of available devices. +* `drive` - has to contain dict of additional drive(s) +* `drive.size` - allows to specify additional drive with size in bytes + (default size: 2G) +* `drive.path` - allows to specify additional drive with custom path to its backing file + (default path: /tmp) You can open a RFE ticket to extend supported parameters according to https://qemu.weilnetz.de/doc/qemu-doc.html diff --git a/inventory/standard-inventory-qcow2 b/inventory/standard-inventory-qcow2 index 0d87bad..b47e5fa 100755 --- a/inventory/standard-inventory-qcow2 +++ b/inventory/standard-inventory-qcow2 @@ -1,6 +1,7 @@ #!/usr/bin/python2 import argparse +import atexit import errno import json import os @@ -248,6 +249,52 @@ def fmf_get(path, default=None): return value +class AdditionalDrives(object): + """Prepare additional drives options for qemu + + Based on FMF config creates temporary sparse files and returns + corresponding qemu command options. + cleanup() will be called eventually to close the files. + """ + + _tempfiles = list() + + @classmethod + def generate(cls): + """Generate sparse files and return drive qemu options + Returns + ------- + list of str + qemu -drive options + """ + drives = fmf_get(['qemu', 'drive'], list()) + result = [] + for drive in drives: + # create temporary sparse file + size = int(drive.get('size', 2 * 1024 ** 3)) # default size: 2G + path = drive.get('path', None) + path = str(path) if path is not None else None + drive_file = tempfile.NamedTemporaryFile(dir=path) + drive_file.truncate(size) + cls._tempfiles.append({'file': drive_file, 'path': path}) + logger.info("Created temporary sparse file '%s'." %drive_file.name) + + # translate data into qemu command options + result += ["-drive", "file=%s,media=disk,if=virtio" % drive_file.name] + atexit.register(cls.cleanup) + return result + + @classmethod + def cleanup(cls): + """Close all temporary files created by this class + """ + for tempfile in cls._tempfiles: + fullname = os.path.join(tempfile['path'], tempfile['file'].name) + logger.info("Closing and removing temporary sparse file '%s'" % fullname) + if os.path.isfile(fullname): + tempfile['file'].close() + + def start_qemu(image, cloudinit, portrange=(2222, 5555)): for _ in range(10): port = random.randint(*portrange) @@ -270,10 +317,11 @@ def start_qemu(image, cloudinit, portrange=(2222, 5555)): # Log from qemu itself. log_qemu = log_guest.replace(".guest.log", ".qemu.log") # Parameters from FMF: - param_m = fmf_get(['qemu', 'm'], "1024") - param_net_nic_model = fmf_get(['qemu', 'net_nic', 'model'], 'virtio') + param_m = str(fmf_get(['qemu', 'm'], "1024")) + param_net_nic_model = str(fmf_get(['qemu', 'net_nic', 'model'], 'virtio')) # Use -cpu host and -smp by default. # virtio-rng-pci: https://wiki.qemu.org/Features/VirtIORNG + qemu_cmd = ["/usr/bin/qemu-system-x86_64", "-cpu", "host", "-smp", get_qemu_smp_arg(), "-m", param_m, image, "-enable-kvm", "-snapshot", "-cdrom", cloudinit, @@ -282,10 +330,13 @@ def start_qemu(image, cloudinit, portrange=(2222, 5555)): "-device", "isa-serial,chardev=pts2", "-chardev", "file,id=pts2,path=" + log_guest, "-display", "none"] + qemu_cmd += AdditionalDrives.generate() + if diagnose: qemu_cmd += ["-vnc", DEF_HOST + ":1,to=4095"] qemu_proc = subprocess.Popen(qemu_cmd, stdout=open(log_qemu, 'a'), stderr=subprocess.STDOUT) + time.sleep(5) if qemu_proc and diagnose: logger.info("qemu-kvm is running with VNC server. PID: {}".format(qemu_proc.pid))