diff options
author | Mark Wu <wudxw@linux.vnet.ibm.com> | 2011-11-09 13:55:33 +0800 |
---|---|---|
committer | Luiz Capitulino <lcapitulino@redhat.com> | 2011-12-06 11:40:00 -0200 |
commit | 1c1d46cc0bb66394feba2e37a6b0196021e8d736 (patch) | |
tree | 0c41d410771489cf1c80ab338559a64ed10df933 | |
parent | 4b389b5d6e4ccda94297142cc27ddcdb3a4667dc (diff) |
qmp: add test tool for QMP
Anthony wrote this quickly to aid in testing. It's similar to qmp-shell with
a few important differences:
1) It is not interactive. That makes it useful for scripting.
2) qmp-shell:
(QEMU) set_password protocol=vnc password=foo
3) qmp:
$ qmp set_password --protocol=vnc --password=foo
4) Extensible, git-style interface. If an invalid command name is
passed, it will try to exec qmp-$1.
5) It attempts to pretty print the JSON responses in a shell friendly
format such that tools can work with the output.
Hope others will also find it useful.
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
Signed-off-by: Mark Wu <wudxw@linux.vnet.ibm.com>
Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com>
-rwxr-xr-x | QMP/qmp | 126 |
1 files changed, 126 insertions, 0 deletions
diff --git a/QMP/qmp b/QMP/qmp new file mode 100755 index 0000000000..1db3c7ffeb --- /dev/null +++ b/QMP/qmp @@ -0,0 +1,126 @@ +#!/usr/bin/python +# +# QMP command line tool +# +# Copyright IBM, Corp. 2011 +# +# Authors: +# Anthony Liguori <aliguori@us.ibm.com> +# +# 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 os.environ.has_key('QMP_PATH'): + 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 rsp.has_key('error'): + 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, (errno, msg): + if 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:])) |