* [Qemu-devel] [PATCH v2] qmp: add test tool for QMP
@ 2011-11-09 5:55 Mark Wu
2011-11-09 20:15 ` Anthony Liguori
0 siblings, 1 reply; 4+ messages in thread
From: Mark Wu @ 2011-11-09 5:55 UTC (permalink / raw)
To: Anthony Liguori, Luiz Capitulino; +Cc: qemu-devel
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 <aliguori@us.ibm.com>
Signed-off-by: Mark Wu <wudxw@linux.vnet.ibm.com>
Acked-by: Luiz Capitulino <lcapitulino@redhat.com>
---
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 <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']:
+ 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:]))
--
1.7.1
^ permalink raw reply related [flat|nested] 4+ messages in thread
* Re: [Qemu-devel] [PATCH v2] qmp: add test tool for QMP
2011-11-09 5:55 [Qemu-devel] [PATCH v2] qmp: add test tool for QMP Mark Wu
@ 2011-11-09 20:15 ` Anthony Liguori
2011-11-09 23:58 ` Luiz Capitulino
0 siblings, 1 reply; 4+ messages in thread
From: Anthony Liguori @ 2011-11-09 20:15 UTC (permalink / raw)
To: Mark Wu; +Cc: qemu-devel, 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<aliguori@us.ibm.com>
> Signed-off-by: Mark Wu<wudxw@linux.vnet.ibm.com>
> Acked-by: Luiz Capitulino<lcapitulino@redhat.com>
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<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']:
> + 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:]))
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [Qemu-devel] [PATCH v2] qmp: add test tool for QMP
2011-11-09 20:15 ` Anthony Liguori
@ 2011-11-09 23:58 ` Luiz Capitulino
2011-11-10 0:45 ` Anthony Liguori
0 siblings, 1 reply; 4+ messages in thread
From: Luiz Capitulino @ 2011-11-09 23:58 UTC (permalink / raw)
To: Anthony Liguori; +Cc: Mark Wu, qemu-devel
On Wed, 09 Nov 2011 14:15:04 -0600
Anthony Liguori <aliguori@us.ibm.com> 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<aliguori@us.ibm.com>
> > Signed-off-by: Mark Wu<wudxw@linux.vnet.ibm.com>
> > Acked-by: Luiz Capitulino<lcapitulino@redhat.com>
>
> 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.
As that's not the case I've applied it in my qmp-next queue.
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<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']:
> > + 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:]))
>
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [Qemu-devel] [PATCH v2] qmp: add test tool for QMP
2011-11-09 23:58 ` Luiz Capitulino
@ 2011-11-10 0:45 ` Anthony Liguori
0 siblings, 0 replies; 4+ messages in thread
From: Anthony Liguori @ 2011-11-10 0:45 UTC (permalink / raw)
To: Luiz Capitulino; +Cc: Mark Wu, qemu-devel
On 11/09/2011 05:58 PM, Luiz Capitulino wrote:
> On Wed, 09 Nov 2011 14:15:04 -0600
> Anthony Liguori<aliguori@us.ibm.com> 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<aliguori@us.ibm.com>
>>> Signed-off-by: Mark Wu<wudxw@linux.vnet.ibm.com>
>>> Acked-by: Luiz Capitulino<lcapitulino@redhat.com>
>>
>> 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<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']:
>>> + 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:]))
>>
>
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2011-11-10 0:45 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2011-11-09 5:55 [Qemu-devel] [PATCH v2] qmp: add test tool for QMP Mark Wu
2011-11-09 20:15 ` Anthony Liguori
2011-11-09 23:58 ` Luiz Capitulino
2011-11-10 0:45 ` 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).