From 8c6272759b703c8ee275d02579ca0104151d7363 Mon Sep 17 00:00:00 2001 From: Michael Ablassmeier Date: Tue, 30 Jan 2024 19:46:48 +0100 Subject: [PATCH] improved error handling, show vm name if set --- libqmpbackup/qmpcommon.py | 29 +++++++++++++++++++++++++++++ libqmpbackup/version.py | 2 +- qmpbackup | 31 ++++++++++++++----------------- t/runtest | 2 +- 4 files changed, 45 insertions(+), 19 deletions(-) diff --git a/libqmpbackup/qmpcommon.py b/libqmpbackup/qmpcommon.py index 4e0fa53..c7ce8fd 100644 --- a/libqmpbackup/qmpcommon.py +++ b/libqmpbackup/qmpcommon.py @@ -22,6 +22,35 @@ def __init__(self, qmp): self.qmp = qmp self.log = logging.getLogger(__name__) + async def show_vm_state(self): + """Show and check if virtual machine is in required + state""" + status = await self.qmp.execute("query-status") + if status["running"] is False and not status["status"] in ( + "prelaunch", + "paused", + ): + raise RuntimeError(f"VM not ready for backup, state: [{status}]") + self.log.info("VM is in state: [%s]", status["status"]) + + async def show_name(self): + """Show qemu version""" + name = await self.qmp.execute("query-name") + if name: + self.log.info("VM Name: [%s]", name["name"]) + + def show_version(self): + """Show name of VM; if setn""" + hv_version = self.qmp._greeting._raw["QMP"] # pylint: disable=W0212 + qemu = hv_version["version"]["qemu"] + self.log.info( + "Qemu version: [%s.%s.%s] [%s]", + qemu["major"], + qemu["micro"], + qemu["minor"], + hv_version["version"]["package"], + ) + @staticmethod def transaction_action(action, **kwargs): """Return transaction action object""" diff --git a/libqmpbackup/version.py b/libqmpbackup/version.py index 81b1669..008b9ec 100644 --- a/libqmpbackup/version.py +++ b/libqmpbackup/version.py @@ -10,4 +10,4 @@ This work is licensed under the terms of the GNU GPL, version 3. See the LICENSE file in the top-level directory. """ -VERSION = "0.28" +VERSION = "0.29" diff --git a/qmpbackup b/qmpbackup index 68fd8c8..462a714 100755 --- a/qmpbackup +++ b/qmpbackup @@ -19,6 +19,7 @@ import argparse from datetime import datetime from dataclasses import asdict from qemu.qmp import protocol, QMPClient +from qemu.qmp.error import QMPError from libqmpbackup.qmpcommon import QmpCommon from libqmpbackup import lib @@ -200,24 +201,17 @@ async def main(): log.fatal("Can't connect QMP socket [%s]: %s", argv.socket, errmsg) sys.exit(1) - status = await qmp.execute("query-status") - if status["running"] is False and not status["status"] in ("prelaunch", "paused"): - log.fatal("VM not ready for backup, state: [%s]", status) - sys.exit(1) + qemu_client = QmpCommon(qmp) - log.info("VM is in state: [%s]", status["status"]) + try: + await qemu_client.show_vm_state() + except RuntimeError as errmsg: + log.fatal(errmsg) + sys.exit(1) qemu_client = QmpCommon(qmp) - - hv_version = qmp._greeting._raw["QMP"] - qemu = hv_version["version"]["qemu"] - log.info( - "Qemu version: [%s.%s.%s] [%s]", - qemu["major"], - qemu["micro"], - qemu["minor"], - hv_version["version"]["package"], - ) + qemu_client.show_version() + await qemu_client.show_name() excluded_disks = None included_disks = None @@ -360,11 +354,14 @@ async def main(): try: await qemu_client.prepare_target_devices(blockdev, target_files) await qemu_client.backup(argv, blockdev, qga) - except Exception as errmsg: + except QMPError as errmsg: log.fatal("Error executing backup: %s", errmsg) sys.exit(1) finally: - await qemu_client.remove_target_devices(blockdev) + try: + await qemu_client.remove_target_devices(blockdev) + except QMPError as errmsg: + log.warning("Unable to cleanup: %s", errmsg) if qga is not False: fs.thaw(qga) diff --git a/t/runtest b/t/runtest index 4ae54c2..4ab23c4 100755 --- a/t/runtest +++ b/t/runtest @@ -49,7 +49,7 @@ fi echo "Starting qemu process" KVMOPT="" [ -e /dev/kvm ] && KVMOPT="--enable-kvm" && echo "with kvm" -qemu-system-x86_64 $KVMOPT -smp "$(nproc)" -daemonize -display none -m 1024 \ +qemu-system-x86_64 -name "testvm" $KVMOPT -smp "$(nproc)" -daemonize -display none -m 1024 \ -hda /tmp/disk1.qcow2 \ -hdb /tmp/disk2.qcow2 \ -hdc /tmp/disk3.raw \