aetherscale

[unmaintained] code for a cloud provider tutorial
Log | Files | Refs | README | LICENSE

commit 6fae20cefad1b7333f0663e6d1cbd93d60ba3b1c
parent c65193913e9e1fbb915448baba1372763da396a5
Author: Stefan Koch <programming@stefan-koch.name>
Date:   Thu,  3 Dec 2020 20:21:56 +0100

create a systemd unit file before VM start

Diffstat:
Maetherscale/computing.py | 58+++++++++++++++++++++++++++++++++++++++++++++++++---------
1 file changed, 49 insertions(+), 9 deletions(-)

diff --git a/aetherscale/computing.py b/aetherscale/computing.py @@ -1,3 +1,4 @@ +from dataclasses import dataclass import logging import json import os @@ -5,11 +6,13 @@ from pathlib import Path import pika import psutil import random +import shlex import string import subprocess import sys +import tempfile import time -from typing import List, Optional +from typing import List, Optional, IO from . import interfaces from . import execution @@ -73,6 +76,37 @@ def get_process_for_vm(vm_id: str) -> Optional[psutil.Process]: return None +@dataclass +class QemuStartupConfig: + vm_id: str + hda: Path + mac_addr: str + netdev: str + + +def create_qemu_systemd_unit( + unit_file: IO[str], qemu_config: QemuStartupConfig): + hda_quoted = shlex.quote(str(qemu_config.hda.absolute())) + device_quoted = shlex.quote( + f'virtio-net-pci,netdev=pubnet,mac={qemu_config.mac_addr}') + netdev_quoted = shlex.quote(qemu_config.netdev) + name = f'qemu-vm-{qemu_config.vm_id},process=vm-{qemu_config.vm_id}' + name_quoted = shlex.quote(name) + + command = f'qemu-system-x86_64 -m 4096 -accel kvm -hda {hda_quoted} ' \ + f'-device {device_quoted} -netdev {netdev_quoted} ' \ + f'-name {name_quoted}' + + unit_file.write('[Unit]\n') + unit_file.write(f'Description=aetherscale VM {qemu_config.vm_id}\n') + unit_file.write('\n') + unit_file.write('[Service]\n') + unit_file.write(f'ExecStart={command}\n') + unit_file.write('\n') + unit_file.write('[Install]\n') + unit_file.write('WantedBy=default.target\n') + + def callback(ch, method, properties, body): message = body.decode('utf-8') print('Received message: ' + message) @@ -138,14 +172,20 @@ def callback(ch, method, properties, body): netdev = \ f'tap,id=pubnet,ifname={tap_device},script=no,downscript=no' - p = subprocess.Popen([ - 'qemu-system-x86_64', '-m', '4096', '-accel', 'kvm', - '-hda', str(user_image), - '-device', f'virtio-net-pci,netdev=pubnet,mac={mac_addr}', - '-netdev', netdev, - '-name', f'qemu-vm-{vm_id},process=vm-{vm_id}', - ]) - print(f'Started VM "{vm_id}" as process ID {p.pid}') + qemu_config = QemuStartupConfig( + vm_id=vm_id, + hda=user_image, + mac_addr=mac_addr, + netdev=netdev) + unit_name = f'aetherscale-vm-{vm_id}.service' + + with tempfile.NamedTemporaryFile(mode='w+t', delete=False) as f: + create_qemu_systemd_unit(f, qemu_config) + execution.copy_systemd_unit(Path(f.name), unit_name) + os.remove(f.name) + execution.start_systemd_unit(unit_name) + + print(f'Started VM "{vm_id}"') ch.basic_ack(delivery_tag=method.delivery_tag)