From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([140.186.70.92]:34913) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1RNS5q-0003mR-AZ for qemu-devel@nongnu.org; Mon, 07 Nov 2011 11:30:46 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1RNS5l-0001CQ-8D for qemu-devel@nongnu.org; Mon, 07 Nov 2011 11:30:42 -0500 Received: from mx1.redhat.com ([209.132.183.28]:55036) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1RNS5k-0001CL-RB for qemu-devel@nongnu.org; Mon, 07 Nov 2011 11:30:37 -0500 Date: Mon, 7 Nov 2011 14:30:20 -0200 From: Luiz Capitulino Message-ID: <20111107143020.74c678ec@doriath> In-Reply-To: <4EB802D3.4080108@codemonkey.ws> References: <1320678675-21379-1-git-send-email-aliguori@us.ibm.com> <20111107140801.7f1c6cdd@doriath> <4EB802D3.4080108@codemonkey.ws> Mime-Version: 1.0 Content-Type: text/plain; charset=US-ASCII Content-Transfer-Encoding: 7bit Subject: Re: [Qemu-devel] [PATCH] qmp: add test tool for QMP List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: Anthony Liguori Cc: Anthony Liguori , qemu-devel@nongnu.org On Mon, 07 Nov 2011 10:09:55 -0600 Anthony Liguori wrote: > On 11/07/2011 10:08 AM, Luiz Capitulino wrote: > > On Mon, 7 Nov 2011 09:11:15 -0600 > > Anthony Liguori wrote: > > > >> I 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 > > > > Acked-by: Luiz Capitulino > > BTW, one thing I'd like to try at some point soon is to generate man pages from > qapi-schema.json. If you notice in the script, it does online help by invoking man. Yes, I did notice it. I didn't comment on it because I imagined you had plans about it. PS: I don't think this needs to go through my tree. > > Regards, > > Anthony Liguori > > > > >> --- > >> QMP/qmp | 120 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ > >> 1 files changed, 120 insertions(+), 0 deletions(-) > >> create mode 100755 QMP/qmp > >> > >> diff --git a/QMP/qmp b/QMP/qmp > >> new file mode 100755 > >> index 0000000..7b2a3c7 > >> --- /dev/null > >> +++ b/QMP/qmp > >> @@ -0,0 +1,120 @@ > >> +#!/usr/bin/python > >> +# > >> +# 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 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']: > >> + 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 or set QMP_PATH" > >> + return 1 > >> + > >> + command, args = args[0], args[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:])) > > > > >