qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
* [Qemu-devel] [PATCH] qmp: add test tool for QMP
@ 2011-11-07 15:11 Anthony Liguori
  2011-11-07 16:08 ` Luiz Capitulino
  2011-11-08  8:36 ` Mark Wu
  0 siblings, 2 replies; 10+ messages in thread
From: Anthony Liguori @ 2011-11-07 15:11 UTC (permalink / raw)
  To: qemu-devel; +Cc: Anthony Liguori, Luiz Capitulino

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>
---
 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:]))
-- 
1.7.4.1

^ permalink raw reply related	[flat|nested] 10+ messages in thread

* Re: [Qemu-devel] [PATCH] qmp: add test tool for QMP
  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
  2011-11-08  8:36 ` Mark Wu
  1 sibling, 1 reply; 10+ messages in thread
From: Luiz Capitulino @ 2011-11-07 16:08 UTC (permalink / raw)
  To: Anthony Liguori; +Cc: qemu-devel

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>

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

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [Qemu-devel] [PATCH] qmp: add test tool for QMP
  2011-11-07 16:08 ` Luiz Capitulino
@ 2011-11-07 16:09   ` Anthony Liguori
  2011-11-07 16:30     ` Luiz Capitulino
  0 siblings, 1 reply; 10+ messages in thread
From: Anthony Liguori @ 2011-11-07 16:09 UTC (permalink / raw)
  To: Luiz Capitulino; +Cc: Anthony Liguori, qemu-devel

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

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [Qemu-devel] [PATCH] qmp: add test tool for QMP
  2011-11-07 16:09   ` Anthony Liguori
@ 2011-11-07 16:30     ` Luiz Capitulino
  2011-11-07 16:35       ` Anthony Liguori
  0 siblings, 1 reply; 10+ messages in thread
From: Luiz Capitulino @ 2011-11-07 16:30 UTC (permalink / raw)
  To: Anthony Liguori; +Cc: Anthony Liguori, qemu-devel

On Mon, 07 Nov 2011 10:09:55 -0600
Anthony Liguori <anthony@codemonkey.ws> wrote:

> 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.

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

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [Qemu-devel] [PATCH] qmp: add test tool for QMP
  2011-11-07 16:30     ` Luiz Capitulino
@ 2011-11-07 16:35       ` Anthony Liguori
  2011-11-07 16:39         ` Luiz Capitulino
  0 siblings, 1 reply; 10+ messages in thread
From: Anthony Liguori @ 2011-11-07 16:35 UTC (permalink / raw)
  To: Luiz Capitulino; +Cc: Anthony Liguori, qemu-devel

On 11/07/2011 10:30 AM, Luiz Capitulino wrote:
> On Mon, 07 Nov 2011 10:09:55 -0600
> Anthony Liguori<anthony@codemonkey.ws>  wrote:
>
>> 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.
>
> 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.

What do you want to do with qmp.py?  Do you feel comfortable installing it in 
$PYTHONPATH and treating it as a supported API?

Regards,

Anthony Liguori

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [Qemu-devel] [PATCH] qmp: add test tool for QMP
  2011-11-07 16:35       ` Anthony Liguori
@ 2011-11-07 16:39         ` Luiz Capitulino
  2011-11-07 17:26           ` Alon Levy
  0 siblings, 1 reply; 10+ messages in thread
From: Luiz Capitulino @ 2011-11-07 16:39 UTC (permalink / raw)
  To: Anthony Liguori; +Cc: Anthony Liguori, qemu-devel

On Mon, 07 Nov 2011 10:35:51 -0600
Anthony Liguori <anthony@codemonkey.ws> wrote:

> On 11/07/2011 10:30 AM, Luiz Capitulino wrote:
> > On Mon, 07 Nov 2011 10:09:55 -0600
> > Anthony Liguori<anthony@codemonkey.ws>  wrote:
> >
> >> 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.
> >
> > 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.
> 
> What do you want to do with qmp.py?  Do you feel comfortable installing it in 
> $PYTHONPATH and treating it as a supported API?

I probably don't. I coded it as demo in the very beginning of QMP, maybe
we should first define what we expect from a QMP Python class then we
can see whether it fits or not... I feel it needs to be revamped.

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [Qemu-devel] [PATCH] qmp: add test tool for QMP
  2011-11-07 16:39         ` Luiz Capitulino
@ 2011-11-07 17:26           ` Alon Levy
  0 siblings, 0 replies; 10+ messages in thread
From: Alon Levy @ 2011-11-07 17:26 UTC (permalink / raw)
  To: Luiz Capitulino; +Cc: Anthony Liguori, qemu-devel

On Mon, Nov 07, 2011 at 02:39:29PM -0200, Luiz Capitulino wrote:
> On Mon, 07 Nov 2011 10:35:51 -0600
> Anthony Liguori <anthony@codemonkey.ws> wrote:
> 
> > On 11/07/2011 10:30 AM, Luiz Capitulino wrote:
> > > On Mon, 07 Nov 2011 10:09:55 -0600
> > > Anthony Liguori<anthony@codemonkey.ws>  wrote:
> > >
> > >> 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.
> > >
> > > 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.
> > 
> > What do you want to do with qmp.py?  Do you feel comfortable installing it in 
> > $PYTHONPATH and treating it as a supported API?
> 
> I probably don't. I coded it as demo in the very beginning of QMP, maybe
> we should first define what we expect from a QMP Python class then we
> can see whether it fits or not... I feel it needs to be revamped.
> 

It should not blocking, i.e. for event notification. I have a patch that
fixes that but breaks tab-completion.

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [Qemu-devel] [PATCH] qmp: add test tool for QMP
  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-08  8:36 ` Mark Wu
  2011-11-08 11:56   ` Luiz Capitulino
  2011-11-08 13:57   ` Anthony Liguori
  1 sibling, 2 replies; 10+ messages in thread
From: Mark Wu @ 2011-11-08  8:36 UTC (permalink / raw)
  To: Anthony Liguori; +Cc: qemu-devel, Luiz Capitulino

When I run this tool, I got two python exceptions. It turned out that 
both of them were caused by wrong usage.  Do you think we need add 
validation for input to handle these cases?

Thanks.

1. Not using '=' for path:
  $ ./QMP/qmp --path monitor-address
Traceback (most recent call last):
   File "./QMP/qmp", line 120, in <module>
     sys.exit(main(sys.argv[1:]))
   File "./QMP/qmp", line 71, in main
     srv.connect()
   File "/home/mark/work/source/qemu/QMP/qmp.py", line 85, in connect
     self.__sock.connect(self.__address)
   File "<string>", line 1, in connect
TypeError: argument must be string or read-only character buffer, not bool

Proposed patch:

@@ -48,7 +48,8 @@ def main(args):
                  arg, value = arg.split('=', 1)

              if arg in ['path']:
-                path = value
+               if isinstance(value, basestring):
+                    path = value


2. No qmp comand given in command line
$ ./QMP/qmp --path=monitor-address
Traceback (most recent call last):
   File "./QMP/qmp", line 120, in <module>
     sys.exit(main(sys.argv[1:]))
   File "./QMP/qmp", line 65, in main
     command, args = args[0], args[1:]
IndexError: list index out of range

@@ -62,11 +63,17 @@ def main(args):
          print "QMP path isn't set, use --path or set QMP_PATH"
          return 1

Proposed patch:
-    command, args = args[0], args[1:]
+    if len(args):
+       command, args = args[0], args[1:]
+    else:
+       print 'No command found'
+       print 'Usage: "qmp [--path=monitor-address] qmp-cmd arguments"'
+       return 1








On 11/07/2011 11:11 PM, 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<aliguori@us.ibm.com>
> ---
>   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:]))

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [Qemu-devel] [PATCH] qmp: add test tool for QMP
  2011-11-08  8:36 ` Mark Wu
@ 2011-11-08 11:56   ` Luiz Capitulino
  2011-11-08 13:57   ` Anthony Liguori
  1 sibling, 0 replies; 10+ messages in thread
From: Luiz Capitulino @ 2011-11-08 11:56 UTC (permalink / raw)
  To: Mark Wu; +Cc: Anthony Liguori, qemu-devel

On Tue, 08 Nov 2011 16:36:55 +0800
Mark Wu <wudxw@linux.vnet.ibm.com> wrote:

> When I run this tool, I got two python exceptions. It turned out that 
> both of them were caused by wrong usage.  Do you think we need add 
> validation for input to handle these cases?

Yes.

> 
> Thanks.
> 
> 1. Not using '=' for path:
>   $ ./QMP/qmp --path monitor-address
> Traceback (most recent call last):
>    File "./QMP/qmp", line 120, in <module>
>      sys.exit(main(sys.argv[1:]))
>    File "./QMP/qmp", line 71, in main
>      srv.connect()
>    File "/home/mark/work/source/qemu/QMP/qmp.py", line 85, in connect
>      self.__sock.connect(self.__address)
>    File "<string>", line 1, in connect
> TypeError: argument must be string or read-only character buffer, not bool
> 
> Proposed patch:
> 
> @@ -48,7 +48,8 @@ def main(args):
>                   arg, value = arg.split('=', 1)
> 
>               if arg in ['path']:
> -                path = value
> +               if isinstance(value, basestring):
> +                    path = value
> 
> 
> 2. No qmp comand given in command line
> $ ./QMP/qmp --path=monitor-address
> Traceback (most recent call last):
>    File "./QMP/qmp", line 120, in <module>
>      sys.exit(main(sys.argv[1:]))
>    File "./QMP/qmp", line 65, in main
>      command, args = args[0], args[1:]
> IndexError: list index out of range
> 
> @@ -62,11 +63,17 @@ def main(args):
>           print "QMP path isn't set, use --path or set QMP_PATH"
>           return 1
> 
> Proposed patch:
> -    command, args = args[0], args[1:]
> +    if len(args):
> +       command, args = args[0], args[1:]
> +    else:
> +       print 'No command found'
> +       print 'Usage: "qmp [--path=monitor-address] qmp-cmd arguments"'
> +       return 1
> 
> 
> 
> 
> 
> 
> 
> 
> On 11/07/2011 11:11 PM, 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<aliguori@us.ibm.com>
> > ---
> >   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:]))
> 

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [Qemu-devel] [PATCH] qmp: add test tool for QMP
  2011-11-08  8:36 ` Mark Wu
  2011-11-08 11:56   ` Luiz Capitulino
@ 2011-11-08 13:57   ` Anthony Liguori
  1 sibling, 0 replies; 10+ messages in thread
From: Anthony Liguori @ 2011-11-08 13:57 UTC (permalink / raw)
  To: Mark Wu; +Cc: qemu-devel, Luiz Capitulino

On 11/08/2011 02:36 AM, Mark Wu wrote:
> When I run this tool, I got two python exceptions. It turned out that both of
> them were caused by wrong usage. Do you think we need add validation for input
> to handle these cases?

Definitely.  Could you just send out a version of the patch with your changes, a 
(v2) in the subject, and your Signed-off-by?

Thanks!

Regards,

Anthony Liguori

>
> Thanks.
>
> 1. Not using '=' for path:
> $ ./QMP/qmp --path monitor-address
> Traceback (most recent call last):
> File "./QMP/qmp", line 120, in <module>
> sys.exit(main(sys.argv[1:]))
> File "./QMP/qmp", line 71, in main
> srv.connect()
> File "/home/mark/work/source/qemu/QMP/qmp.py", line 85, in connect
> self.__sock.connect(self.__address)
> File "<string>", line 1, in connect
> TypeError: argument must be string or read-only character buffer, not bool
>
> Proposed patch:
>
> @@ -48,7 +48,8 @@ def main(args):
> arg, value = arg.split('=', 1)
>
> if arg in ['path']:
> - path = value
> + if isinstance(value, basestring):
> + path = value
>
>
> 2. No qmp comand given in command line
> $ ./QMP/qmp --path=monitor-address
> Traceback (most recent call last):
> File "./QMP/qmp", line 120, in <module>
> sys.exit(main(sys.argv[1:]))
> File "./QMP/qmp", line 65, in main
> command, args = args[0], args[1:]
> IndexError: list index out of range
>
> @@ -62,11 +63,17 @@ def main(args):
> print "QMP path isn't set, use --path or set QMP_PATH"
> return 1
>
> Proposed patch:
> - command, args = args[0], args[1:]
> + if len(args):
> + command, args = args[0], args[1:]
> + else:
> + print 'No command found'
> + print 'Usage: "qmp [--path=monitor-address] qmp-cmd arguments"'
> + return 1
>
>
>
>
>
>
>
>
> On 11/07/2011 11:11 PM, 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<aliguori@us.ibm.com>
>> ---
>> 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:]))
>
>

^ permalink raw reply	[flat|nested] 10+ messages in thread

end of thread, other threads:[~2011-11-08 13:57 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
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
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

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).