On Mon, 20 Aug 2012 15:02:23 +0100 "Daniel P. Berrange" <berra...@redhat.com> wrote:
> From: "Daniel P. Berrange" <berra...@redhat.com> > > By default, the JSON reply is parsed and the corresponding python > object printed on the console. When developing JSON client apps > for QEMU though, it is handy to see the raw JSON document instead. > Add a '-r' option that will cause the raw JSON to be printed, > instead of the parsed object. eg Looks good, but depends on the previous patch (which is being discussed). Btw, I wonder if we should make this the default, or add -v (instead of -r) which would allow for extra verbosity by printing both: the reply as read by qmp-shell and the parsed. > > $ qmp-shell -r /tmp/qemu > Welcome to the QMP low-level shell! > Connected to QEMU 1.1.50 > > (QEMU) stop > { > "return": { > } > } > > (QEMU) > { > "timestamp": { > "seconds": 1345471168, > "microseconds": 493463 > }, > "event": "STOP" > } > > Signed-off-by: Daniel P. Berrange <berra...@redhat.com> > --- > QMP/qmp-shell | 40 +++++++++++++++++++++++++++------------- > QMP/qmp.py | 12 ++++++------ > 2 files changed, 33 insertions(+), 19 deletions(-) > > diff --git a/QMP/qmp-shell b/QMP/qmp-shell > index 24b665c..6c7d8c3 100755 > --- a/QMP/qmp-shell > +++ b/QMP/qmp-shell > @@ -53,11 +53,12 @@ class QMPShellBadPort(QMPShellError): > # TODO: QMPShell's interface is a bit ugly (eg. _fill_completion() and > # _execute_cmd()). Let's design a better one. > class QMPShell(qmp.QEMUMonitorProtocol): > - def __init__(self, address, pp=None): > + def __init__(self, address, pp=None, raw=False): > qmp.QEMUMonitorProtocol.__init__(self, self.__get_address(address)) > self._greeting = None > self._completer = None > self._pp = pp > + self._raw = raw > > def __get_address(self, arg): > """ > @@ -75,7 +76,8 @@ class QMPShell(qmp.QEMUMonitorProtocol): > return arg > > def _fill_completion(self): > - for cmd in self.cmd('query-commands')['return']: > + cmds = self.cmd('query-commands') > + for cmd in cmds[0]['return']: > self._completer.append(cmd['name']) > > def __completer_setup(self): > @@ -105,6 +107,15 @@ class QMPShell(qmp.QEMUMonitorProtocol): > qmpcmd['arguments'][opt[0]] = value > return qmpcmd > > + def _print(self, data): > + if self._raw: > + print data[1] > + else: > + if self._pp is not None: > + self._pp.pprint(data[0]) > + else: > + print data[0] > + > def _execute_cmd(self, cmdline): > try: > qmpcmd = self.__build_cmd(cmdline) > @@ -113,14 +124,12 @@ class QMPShell(qmp.QEMUMonitorProtocol): > print '[arg-name1=arg1] ... [arg-nameN=argN]' > return True > resp = self.cmd_obj(qmpcmd) > - if resp is None: > + if resp[0] is None: > print 'Disconnected' > return False > > - if self._pp is not None: > - self._pp.pprint(resp) > - else: > - print resp > + self._print(resp) > + > return True > > def connect(self): > @@ -144,8 +153,9 @@ class QMPShell(qmp.QEMUMonitorProtocol): > print > return False > if cmdline == '': > - for ev in self.get_events(): > - print ev > + events = self.get_events() > + for ev in events: > + self._print(ev) > self.clear_events() > return True > else: > @@ -188,9 +198,10 @@ class HMPShell(QMPShell): > 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 } }) > + resp = self.cmd_obj({ 'execute': 'human-monitor-command', > 'arguments': > + { 'command-line': cmdline, > + 'cpu-index': cpu_index } }) > + return resp[0] > > def _execute_cmd(self, cmdline): > if cmdline.split()[0] == "cpu": > @@ -236,6 +247,7 @@ def main(): > qemu = None > hmp = False > pp = None > + raw = False > > try: > for arg in sys.argv[1:]: > @@ -247,13 +259,15 @@ def main(): > if pp is not None: > fail_cmdline(arg) > pp = pprint.PrettyPrinter(indent=4) > + elif arg == "-r": > + raw = True > else: > if qemu is not None: > fail_cmdline(arg) > if hmp: > qemu = HMPShell(arg) > else: > - qemu = QMPShell(arg, pp) > + qemu = QMPShell(arg, pp, raw) > addr = arg > > if qemu is None: > diff --git a/QMP/qmp.py b/QMP/qmp.py > index 464a01a..3a0efd8 100644 > --- a/QMP/qmp.py > +++ b/QMP/qmp.py > @@ -50,13 +50,13 @@ class QEMUMonitorProtocol: > > def __negotiate_capabilities(self): > self.__sockfile = self.__sock.makefile() > - greeting = self.__json_read() > - if greeting is None or not greeting.has_key('QMP'): > + greeting = self.__json_read() > + if greeting[0] is None or not greeting[0].has_key('QMP'): > raise QMPConnectError > # Greeting seems ok, negotiate capabilities > resp = self.cmd('qmp_capabilities') > - if "return" in resp: > - return greeting > + if "return" in resp[0]: > + return greeting[0] > raise QMPCapabilitiesError > > def __json_read(self, only_event=False): > @@ -74,10 +74,10 @@ class QEMUMonitorProtocol: > pass > > if 'event' in resp: > - self.__events.append(resp) > + self.__events.append((resp, data)) > if not only_event: > continue > - return resp > + return (resp, data) > > error = socket.error >