vms/run: better defaults for run api

This commit is contained in:
Jörg Thalheim
2024-10-08 19:11:35 +02:00
committed by Mic92
parent 112d7bf2be
commit 9e5de5c8f0
4 changed files with 54 additions and 47 deletions

View File

@@ -1,11 +1,19 @@
import base64
import time
import types
from dataclasses import dataclass
from clan_cli.errors import ClanError
from clan_cli.qemu.qmp import QEMUMonitorProtocol
@dataclass
class VmCommandResult:
returncode: int
stdout: str | None
stderr: str | None
# qga is almost like qmp, but not quite, because:
# - server doesn't send initial message
# - no need to initialize by asking for capabilities
@@ -35,10 +43,17 @@ class QgaSession:
if result_pid is None:
msg = "Could not get PID from QGA"
raise ClanError(msg)
return result_pid["return"]["pid"]
try:
return result_pid["return"]["pid"]
except KeyError as e:
if "error" in result_pid:
msg = f"Could not run command: {result_pid['error']['desc']}"
raise ClanError(msg) from e
msg = f"PID could not be found: {result_pid}"
raise ClanError(msg) from e
# run, wait for result, return exitcode and output
def run(self, cmd: list[str], check: bool = False) -> tuple[int, str, str]:
def run(self, cmd: list[str], check: bool = True) -> VmCommandResult:
pid = self.run_nonblocking(cmd)
# loop until exited=true
while True:
@@ -54,17 +69,14 @@ class QgaSession:
time.sleep(0.1)
exitcode = result["return"]["exitcode"]
stdout = (
""
if "out-data" not in result["return"]
else base64.b64decode(result["return"]["out-data"]).decode("utf-8")
)
stderr = (
""
if "err-data" not in result["return"]
else base64.b64decode(result["return"]["err-data"]).decode("utf-8")
)
err_data = result["return"].get("err-data")
stdout = None
stderr = None
if out_data := result["return"].get("out-data"):
stdout = base64.b64decode(out_data).decode("utf-8")
if err_data is not None:
stderr = base64.b64decode(err_data).decode("utf-8")
if check and exitcode != 0:
msg = f"Command on guest failed\nCommand: {cmd}\nExitcode {exitcode}\nStdout: {stdout}\nStderr: {stderr}"
raise ClanError(msg)
return exitcode, stdout, stderr
return VmCommandResult(exitcode, stdout, stderr)