qmp: add test tool for QMP
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> Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com>
This commit is contained in:
parent
4b389b5d6e
commit
1c1d46cc0b
126
QMP/qmp
Executable file
126
QMP/qmp
Executable file
@ -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:]))
|
Loading…
Reference in New Issue
Block a user