From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([140.186.70.92]:53391) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ROImB-00070K-ML for qemu-devel@nongnu.org; Wed, 09 Nov 2011 19:45:56 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1ROImA-0002Zq-Dz for qemu-devel@nongnu.org; Wed, 09 Nov 2011 19:45:55 -0500 Received: from e38.co.us.ibm.com ([32.97.110.159]:50165) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ROImA-0002Z1-4z for qemu-devel@nongnu.org; Wed, 09 Nov 2011 19:45:54 -0500 Received: from /spool/local by e38.co.us.ibm.com with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted for from ; Wed, 9 Nov 2011 17:45:49 -0700 Received: from d03av01.boulder.ibm.com (d03av01.boulder.ibm.com [9.17.195.167]) by d03relay05.boulder.ibm.com (8.13.8/8.13.8/NCO v10.0) with ESMTP id pAA0jhxM160372 for ; Wed, 9 Nov 2011 17:45:45 -0700 Received: from d03av01.boulder.ibm.com (loopback [127.0.0.1]) by d03av01.boulder.ibm.com (8.14.4/8.13.1/NCO v10.0 AVout) with ESMTP id pAA0jg1i030251 for ; Wed, 9 Nov 2011 17:45:42 -0700 Message-ID: <4EBB1EB5.2090902@us.ibm.com> Date: Wed, 09 Nov 2011 18:45:41 -0600 From: Anthony Liguori MIME-Version: 1.0 References: <1320818133-8930-1-git-send-email-wudxw@linux.vnet.ibm.com> <4EBADF48.906@us.ibm.com> <20111109215842.5b433c2c@doriath> In-Reply-To: <20111109215842.5b433c2c@doriath> 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: Luiz Capitulino Cc: Mark Wu , qemu-devel@nongnu.org On 11/09/2011 05:58 PM, Luiz Capitulino wrote: > On Wed, 09 Nov 2011 14:15:04 -0600 > Anthony Liguori wrote: > >> 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. > > I thought you were planning to use it for 1.0 testing and so wanted it > merged in 1.0. It doesn't need to be in the tree for that. Yes, I am using it for testing though. > As that's not the case I've applied it in my qmp-next queue. Even better! Thanks. Regards, Anthony Liguori > Thanks Mark. > >> >> 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:])) >> >