From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([140.186.70.92]:42414) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ROEYY-0002RT-4j for qemu-devel@nongnu.org; Wed, 09 Nov 2011 15:15:35 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1ROEYW-000715-Mc for qemu-devel@nongnu.org; Wed, 09 Nov 2011 15:15:34 -0500 Received: from e5.ny.us.ibm.com ([32.97.182.145]:51051) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ROEYW-00070p-4h for qemu-devel@nongnu.org; Wed, 09 Nov 2011 15:15:32 -0500 Received: from /spool/local by e5.ny.us.ibm.com with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted for from ; Wed, 9 Nov 2011 15:15:29 -0500 Received: from d01av01.pok.ibm.com (d01av01.pok.ibm.com [9.56.224.215]) by d01relay01.pok.ibm.com (8.13.8/8.13.8/NCO v10.0) with ESMTP id pA9KF7QA277864 for ; Wed, 9 Nov 2011 15:15:07 -0500 Received: from d01av01.pok.ibm.com (loopback [127.0.0.1]) by d01av01.pok.ibm.com (8.14.4/8.13.1/NCO v10.0 AVout) with ESMTP id pA9KF6Vf000346 for ; Wed, 9 Nov 2011 15:15:07 -0500 Message-ID: <4EBADF48.906@us.ibm.com> Date: Wed, 09 Nov 2011 14:15:04 -0600 From: Anthony Liguori MIME-Version: 1.0 References: <1320818133-8930-1-git-send-email-wudxw@linux.vnet.ibm.com> In-Reply-To: <1320818133-8930-1-git-send-email-wudxw@linux.vnet.ibm.com> Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit Subject: Re: [Qemu-devel] [PATCH v2] qmp: add test tool for QMP List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: Mark Wu Cc: qemu-devel@nongnu.org, Luiz Capitulino On 11/08/2011 11:55 PM, Mark Wu wrote: > 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 > Signed-off-by: Mark Wu > Acked-by: Luiz Capitulino Looks good. I'll apply this once the 1.1 window opens up. Regards, Anthony Liguori > --- > QMP/qmp | 126 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ > 1 files changed, 126 insertions(+), 0 deletions(-) > create mode 100755 QMP/qmp > > diff --git a/QMP/qmp b/QMP/qmp > new file mode 100755 > index 0000000..1db3c7f > --- /dev/null > +++ b/QMP/qmp > @@ -0,0 +1,126 @@ > +#!/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']: > + 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:]))