QMP/qmp-shell: Introduce HMP mode
In which qmp-shell will exclusively use the HMP passthrough feature, this is useful for testing. Example: # ./qmp-shell -H qmp-sock Welcome to the HMP shell! Connected to QEMU 0.13.50 (QEMU) info network VLAN 0 devices: user.0: net=10.0.2.0, restricted=n e1000.0: model=e1000,macaddr=52:54:00:12:34:56 Devices not on any VLAN: (QEMU) Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com>
This commit is contained in:
parent
0268d97c51
commit
11217a757e
@ -145,6 +145,76 @@ class QMPShell(qmp.QEMUMonitorProtocol):
|
|||||||
else:
|
else:
|
||||||
return self._execute_cmd(cmdline)
|
return self._execute_cmd(cmdline)
|
||||||
|
|
||||||
|
class HMPShell(QMPShell):
|
||||||
|
def __init__(self, address):
|
||||||
|
QMPShell.__init__(self, address)
|
||||||
|
self.__cpu_index = 0
|
||||||
|
|
||||||
|
def __cmd_completion(self):
|
||||||
|
for cmd in self.__cmd_passthrough('help')['return'].split('\r\n'):
|
||||||
|
if cmd and cmd[0] != '[' and cmd[0] != '\t':
|
||||||
|
name = cmd.split()[0] # drop help text
|
||||||
|
if name == 'info':
|
||||||
|
continue
|
||||||
|
if name.find('|') != -1:
|
||||||
|
# Command in the form 'foobar|f' or 'f|foobar', take the
|
||||||
|
# full name
|
||||||
|
opt = name.split('|')
|
||||||
|
if len(opt[0]) == 1:
|
||||||
|
name = opt[1]
|
||||||
|
else:
|
||||||
|
name = opt[0]
|
||||||
|
self._completer.append(name)
|
||||||
|
self._completer.append('help ' + name) # help completion
|
||||||
|
|
||||||
|
def __info_completion(self):
|
||||||
|
for cmd in self.__cmd_passthrough('info')['return'].split('\r\n'):
|
||||||
|
if cmd:
|
||||||
|
self._completer.append('info ' + cmd.split()[1])
|
||||||
|
|
||||||
|
def __other_completion(self):
|
||||||
|
# special cases
|
||||||
|
self._completer.append('help info')
|
||||||
|
|
||||||
|
def _fill_completion(self):
|
||||||
|
self.__cmd_completion()
|
||||||
|
self.__info_completion()
|
||||||
|
self.__other_completion()
|
||||||
|
|
||||||
|
def __cmd_passthrough(self, cmdline, cpu_index = 0):
|
||||||
|
return self.cmd_obj({ 'execute': 'human-monitor-command', 'arguments':
|
||||||
|
{ 'command-line': cmdline,
|
||||||
|
'cpu-index': cpu_index } })
|
||||||
|
|
||||||
|
def _execute_cmd(self, cmdline):
|
||||||
|
if cmdline.split()[0] == "cpu":
|
||||||
|
# trap the cpu command, it requires special setting
|
||||||
|
try:
|
||||||
|
idx = int(cmdline.split()[1])
|
||||||
|
if not 'return' in self.__cmd_passthrough('info version', idx):
|
||||||
|
print 'bad CPU index'
|
||||||
|
return True
|
||||||
|
self.__cpu_index = idx
|
||||||
|
except ValueError:
|
||||||
|
print 'cpu command takes an integer argument'
|
||||||
|
return True
|
||||||
|
resp = self.__cmd_passthrough(cmdline, self.__cpu_index)
|
||||||
|
if resp is None:
|
||||||
|
print 'Disconnected'
|
||||||
|
return False
|
||||||
|
assert 'return' in resp or 'error' in resp
|
||||||
|
if 'return' in resp:
|
||||||
|
# Success
|
||||||
|
if len(resp['return']) > 0:
|
||||||
|
print resp['return'],
|
||||||
|
else:
|
||||||
|
# Error
|
||||||
|
print '%s: %s' % (resp['error']['class'], resp['error']['desc'])
|
||||||
|
return True
|
||||||
|
|
||||||
|
def show_banner(self):
|
||||||
|
QMPShell.show_banner(self, msg='Welcome to the HMP shell!')
|
||||||
|
|
||||||
def die(msg):
|
def die(msg):
|
||||||
sys.stderr.write('ERROR: %s\n' % msg)
|
sys.stderr.write('ERROR: %s\n' % msg)
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
@ -156,9 +226,16 @@ def fail_cmdline(option=None):
|
|||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
|
addr = ''
|
||||||
try:
|
try:
|
||||||
if len(sys.argv) == 2:
|
if len(sys.argv) == 2:
|
||||||
qemu = QMPShell(sys.argv[1])
|
qemu = QMPShell(sys.argv[1])
|
||||||
|
addr = sys.argv[1]
|
||||||
|
elif len(sys.argv) == 3:
|
||||||
|
if sys.argv[1] != '-H':
|
||||||
|
fail_cmdline(sys.argv[1])
|
||||||
|
qemu = HMPShell(sys.argv[2])
|
||||||
|
addr = sys.argv[2]
|
||||||
else:
|
else:
|
||||||
fail_cmdline()
|
fail_cmdline()
|
||||||
except QMPShellBadPort:
|
except QMPShellBadPort:
|
||||||
@ -171,7 +248,7 @@ def main():
|
|||||||
except qmp.QMPCapabilitiesError:
|
except qmp.QMPCapabilitiesError:
|
||||||
die('Could not negotiate capabilities')
|
die('Could not negotiate capabilities')
|
||||||
except qemu.error:
|
except qemu.error:
|
||||||
die('Could not connect to %s' % sys.argv[1])
|
die('Could not connect to %s' % addr)
|
||||||
|
|
||||||
qemu.show_banner()
|
qemu.show_banner()
|
||||||
while qemu.read_exec_command('(QEMU) '):
|
while qemu.read_exec_command('(QEMU) '):
|
||||||
|
Loading…
x
Reference in New Issue
Block a user