#!/usr/bin/python3 import sys, os, struct, subprocess, json, socket TYPE_MASK = 0x80000000 def parse_block_header(data): res = struct.unpack('!I', data) size = res[0] if size & TYPE_MASK: size -= TYPE_MASK tp = 'err' else: tp = 'out' return (size, tp) def recv_block(sock): hdr = sock.recv(4) if not hdr: print('ERROR: header receiving') sys.exit(-1) size, tp = parse_block_header(hdr) res = b'' received = 0 while size > 0: part = sock.recv(size) res += part size -= len(part) return (res, tp) def guest_exec(vm_name): print('run guest-exec command...') cmd = ['virsh', 'qemu-agent-command', vm_name, '{"execute":"guest-exec", "arguments":{"path": "bash", "capture-output": "interactive"}}'] p = subprocess.run(cmd, stdout=subprocess.PIPE) response = p.stdout.decode('utf-8') print('response: %s' % response.strip()) response = json.loads(response)['return'] cid = int(response['cid']) port = int(response['port']) return (cid, port) def srv_conn(cid, port): sock = socket.socket(socket.AF_VSOCK, socket.SOCK_STREAM) print('connect...') sock.connect((cid, port)) print('connected') return sock def main(): if len(sys.argv) != 2: print('Usage:\n\t%s ' % sys.argv[0]) return vm_name = sys.argv[1] cid, port = guest_exec(vm_name) sock = srv_conn(cid, port) sock.send(b'echo "Hello world!"\n') data, tp = recv_block(sock) print('Received from %s: "%s"' % (tp, data.decode('utf-8'))) main()