#!/usr/bin/env python3 # # QMP command line tool # # Copyright IBM, Corp. 2011 # # Authors: # Anthony Liguori # # This work is licensed under the terms of the GNU GPLv2 or later. # See the COPYING file in the top-level directory. import sys, os from qmp import QEMUMonitorProtocol def print_response(rsp, prefix=[]): if type(rsp) == list: i = 0 for item in rsp: if prefix == []: prefix = ['item'] print_response(item, prefix[:-1] + ['%s[%d]' % (prefix[-1], i)]) i += 1 elif type(rsp) == dict: for key in rsp.keys(): print_response(rsp[key], prefix + [key]) else: if len(prefix): print('%s: %s' % ('.'.join(prefix), rsp)) else: print('%s' % (rsp)) def main(args): path = None # Use QMP_PATH if it's set if 'QMP_PATH' in os.environ: path = os.environ['QMP_PATH'] while len(args): arg = args[0] if arg.startswith('--'): arg = arg[2:] if arg.find('=') == -1: value = True else: arg, value = arg.split('=', 1) if arg in ['path']: if type(value) == str: path = value elif arg in ['help']: os.execlp('man', 'man', 'qmp') else: print('Unknown argument "%s"' % arg) args = args[1:] else: break if not path: print("QMP path isn't set, use --path=qmp-monitor-address or set QMP_PATH") return 1 if len(args): command, args = args[0], args[1:] else: print('No command found') print('Usage: "qmp [--path=qmp-monitor-address] qmp-cmd arguments"') return 1 if command in ['help']: os.execlp('man', 'man', 'qmp') srv = QEMUMonitorProtocol(path) srv.connect() def do_command(srv, cmd, **kwds): rsp = srv.cmd(cmd, kwds) if 'error' in rsp: raise Exception(rsp['error']['desc']) return rsp['return'] commands = map(lambda x: x['name'], do_command(srv, 'query-commands')) srv.close() if command not in commands: fullcmd = 'qmp-%s' % command try: os.environ['QMP_PATH'] = path os.execvp(fullcmd, [fullcmd] + args) except OSError as exc: if exc.errno == 2: print('Command "%s" not found.' % (fullcmd)) return 1 raise return 0 srv = QEMUMonitorProtocol(path) srv.connect() arguments = {} for arg in args: if not arg.startswith('--'): print('Unknown argument "%s"' % arg) return 1 arg = arg[2:] if arg.find('=') == -1: value = True else: arg, value = arg.split('=', 1) if arg in ['help']: os.execlp('man', 'man', 'qmp-%s' % command) return 1 arguments[arg] = value rsp = do_command(srv, command, **arguments) print_response(rsp) if __name__ == '__main__': sys.exit(main(sys.argv[1:]))