qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
From: Anthony Liguori <anthony@codemonkey.ws>
To: Luiz Capitulino <lcapitulino@redhat.com>
Cc: Anthony Liguori <aliguori@us.ibm.com>, qemu-devel@nongnu.org
Subject: Re: [Qemu-devel] [PATCH] qmp: add test tool for QMP
Date: Mon, 07 Nov 2011 10:09:55 -0600	[thread overview]
Message-ID: <4EB802D3.4080108@codemonkey.ws> (raw)
In-Reply-To: <20111107140801.7f1c6cdd@doriath>

On 11/07/2011 10:08 AM, Luiz Capitulino wrote:
> On Mon,  7 Nov 2011 09:11:15 -0600
> Anthony Liguori<aliguori@us.ibm.com>  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<aliguori@us.ibm.com>
>
> Acked-by: Luiz Capitulino<lcapitulino@redhat.com>

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.

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<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']:
>> +                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:]))
>
>

  reply	other threads:[~2011-11-07 16:10 UTC|newest]

Thread overview: 10+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2011-11-07 15:11 [Qemu-devel] [PATCH] qmp: add test tool for QMP Anthony Liguori
2011-11-07 16:08 ` Luiz Capitulino
2011-11-07 16:09   ` Anthony Liguori [this message]
2011-11-07 16:30     ` Luiz Capitulino
2011-11-07 16:35       ` Anthony Liguori
2011-11-07 16:39         ` Luiz Capitulino
2011-11-07 17:26           ` Alon Levy
2011-11-08  8:36 ` Mark Wu
2011-11-08 11:56   ` Luiz Capitulino
2011-11-08 13:57   ` Anthony Liguori

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=4EB802D3.4080108@codemonkey.ws \
    --to=anthony@codemonkey.ws \
    --cc=aliguori@us.ibm.com \
    --cc=lcapitulino@redhat.com \
    --cc=qemu-devel@nongnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).