qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Qemu-devel] [PATCH 14/15] QMP: Introduce qmp-shell


From: Luiz Capitulino
Subject: [Qemu-devel] [PATCH 14/15] QMP: Introduce qmp-shell
Date: Thu, 19 Nov 2009 13:13:42 -0200

This is a very simple shell written in Python which works
on top of QMP.

Unfortunately it's a bit awkward right now, as the user has
to specify the arguments names, for example:

(QEMU) info item=version
0.11.50
(QEMU)

Also, if the output is not a string or integer, the user is
is going to get a low-level dictionary or list.

It's worth to note that the shell is broken into two files.
One is the shell itself, the other is the QMP class which
handles the communication with QEMU.

Signed-off-by: Luiz Capitulino <address@hidden>
---
 QMP/qmp-shell |   66 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 QMP/qmp.py    |   54 ++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 120 insertions(+), 0 deletions(-)
 create mode 100755 QMP/qmp-shell
 create mode 100644 QMP/qmp.py

diff --git a/QMP/qmp-shell b/QMP/qmp-shell
new file mode 100755
index 0000000..2faf79b
--- /dev/null
+++ b/QMP/qmp-shell
@@ -0,0 +1,66 @@
+#!/usr/bin/python
+#
+# Simple QEMU shell on top of QMP
+#
+# Usage:
+#
+# Start QEMU with:
+#
+# $ qemu [...] -monitor control,unix:./qmp,server
+#
+# Run the shell:
+#
+# $ qmp-shell ./qmp
+#
+# Commands have the following format:
+#
+# < command-name > [ arg-name1=arg1 ] ... [ arg-nameN=argN ]
+#
+# For example:
+#
+# (QEMU) info item=network
+#
+# Luiz Capitulino <address@hidden>
+
+import qmp
+import readline
+from sys import argv,exit
+
+def shell_help():
+    print 'bye  exit from the shell'
+
+def main():
+    if len(argv) != 2:
+        print 'qemu-shell <unix-socket>'
+        exit(1)
+
+    qemu = qmp.QEMUMonitorProtocol(argv[1])
+    qemu.connect()
+
+    print 'Connected!'
+
+    while True:
+        try:
+            cmd = raw_input('(QEMU) ')
+        except EOFError:
+            print
+            break
+        if cmd == '':
+            continue
+        elif cmd == 'bye':
+            break
+        elif cmd == 'help':
+            shell_help()
+        else:
+            try:
+                resp = qemu.send(cmd)
+                if resp == None:
+                    print 'Disconnected'
+                    break
+                print resp
+            except IndexError:
+                print '-> command format: <command-name> ',
+                print '[arg-name1=arg1] ... [arg-nameN=argN]'
+
+if __name__ == '__main__':
+    main()
diff --git a/QMP/qmp.py b/QMP/qmp.py
new file mode 100644
index 0000000..c56f143
--- /dev/null
+++ b/QMP/qmp.py
@@ -0,0 +1,54 @@
+import socket, json
+
+class QMPError(Exception):
+    pass
+
+class QMPConnectError(QMPError):
+    pass
+
+class QEMUMonitorProtocol:
+    def connect(self):
+        self.sock.connect(self.filename)
+        data = self.__json_read()
+        if data == None:
+            raise QMPConnectError
+        if not data.has_key('QMP'):
+            raise QMPConnectError
+        return data['QMP']['capabilities']
+
+    def send(self, cmdline):
+        cmd = self.__build_cmd(cmdline)
+        self.__json_send(cmd)
+        resp = self.__json_read()
+        if resp == None:
+            return
+        elif resp.has_key('error'):
+            return resp['error']
+        else:
+            return resp['return']
+
+    def __build_cmd(self, cmdline):
+        cmdargs = cmdline.split()
+        qmpcmd = { 'execute': cmdargs[0], 'arguments': {} }
+        for arg in cmdargs[1:]:
+            opt = arg.split('=')
+            try:
+                value = int(opt[1])
+            except ValueError:
+                value = opt[1]
+            qmpcmd['arguments'][opt[0]] = value
+        return qmpcmd
+
+    def __json_send(self, cmd):
+        self.sock.send(json.dumps(cmd) + '\n')
+
+    def __json_read(self):
+        try:
+            return json.loads(self.sock.recv(1024))
+        except ValueError:
+            return
+
+    def __init__(self, filename):
+        self.filename = filename
+        self.sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
+
-- 
1.6.5.3.148.g785c5





reply via email to

[Prev in Thread] Current Thread [Next in Thread]