Message ID | 1320818133-8930-1-git-send-email-wudxw@linux.vnet.ibm.com |
---|---|
State | New |
Headers | show |
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:]))
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:])) >
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:])) >> >
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:]))