#!/usr/bin/env python3 # Fetch a file from the guest via the QEMU guest agent protocol # (/tmp/qemu-guest-agent.sock, the virtio-serial QGA chardev - the same # socket vgpu_vm.py exec uses). Usage: qga_fetch.py [chunk] import base64 import json import socket import sys GUEST = sys.argv[1] HOST = sys.argv[2] CHUNK = int(sys.argv[3]) if len(sys.argv) > 3 else 1 << 20 SOCK = "/tmp/qemu-guest-agent.sock" def recv_line(s): buf = b"" while b"\n" not in buf: chunk = s.recv(65536) if not chunk: break buf += chunk return buf.split(b"\n", 1)[0] def cmd(s, obj): s.sendall((json.dumps(obj) + "\r\n").encode()) line = recv_line(s) return json.loads(line) s = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) s.settimeout(30.0) s.connect(SOCK) r = cmd(s, {"execute": "guest-file-open", "arguments": {"path": GUEST, "mode": "r"}}) h = r["return"] print(f"handle={h}") total = 0 with open(HOST, "wb") as out: while True: r = cmd(s, {"execute": "guest-file-read", "arguments": {"handle": h, "count": CHUNK}}) d = r["return"] buf = base64.b64decode(d.get("buf-b64", "")) if buf: out.write(buf) total += len(buf) print(f"\r{total}", end="", flush=True) if d.get("eof"): break cmd(s, {"execute": "guest-file-close", "arguments": {"handle": h}}) print(f"\nFETCHED {total} bytes -> {HOST}")