Annotation of qemu/QMP/qmp.py, revision 1.1.1.3

1.1       root        1: # QEMU Monitor Protocol Python class
                      2: # 
1.1.1.3 ! root        3: # Copyright (C) 2009, 2010 Red Hat Inc.
1.1       root        4: #
                      5: # Authors:
                      6: #  Luiz Capitulino <[email protected]>
                      7: #
                      8: # This work is licensed under the terms of the GNU GPL, version 2.  See
                      9: # the COPYING file in the top-level directory.
                     10: 
1.1.1.3 ! root       11: import json
        !            12: import errno
        !            13: import socket
1.1       root       14: 
                     15: class QMPError(Exception):
                     16:     pass
                     17: 
                     18: class QMPConnectError(QMPError):
                     19:     pass
                     20: 
1.1.1.3 ! root       21: class QMPCapabilitiesError(QMPError):
        !            22:     pass
        !            23: 
1.1       root       24: class QEMUMonitorProtocol:
1.1.1.3 ! root       25:     def __init__(self, address):
        !            26:         """
        !            27:         Create a QEMUMonitorProtocol class.
        !            28: 
        !            29:         @param address: QEMU address, can be either a unix socket path (string)
        !            30:                         or a tuple in the form ( address, port ) for a TCP
        !            31:                         connection
        !            32:         @note No connection is established, this is done by the connect() method
        !            33:         """
        !            34:         self.__events = []
        !            35:         self.__address = address
        !            36:         self.__sock = self.__get_sock()
        !            37:         self.__sockfile = self.__sock.makefile()
        !            38: 
        !            39:     def __get_sock(self):
        !            40:         if isinstance(self.__address, tuple):
        !            41:             family = socket.AF_INET
        !            42:         else:
        !            43:             family = socket.AF_UNIX
        !            44:         return socket.socket(family, socket.SOCK_STREAM)
1.1       root       45: 
1.1.1.3 ! root       46:     def __json_read(self):
        !            47:         while True:
        !            48:             data = self.__sockfile.readline()
        !            49:             if not data:
        !            50:                 return
        !            51:             resp = json.loads(data)
        !            52:             if 'event' in resp:
        !            53:                 self.__events.append(resp)
        !            54:                 continue
        !            55:             return resp
1.1       root       56: 
1.1.1.3 ! root       57:     error = socket.error
1.1       root       58: 
1.1.1.3 ! root       59:     def connect(self):
        !            60:         """
        !            61:         Connect to the QMP Monitor and perform capabilities negotiation.
1.1       root       62: 
1.1.1.3 ! root       63:         @return QMP greeting dict
        !            64:         @raise socket.error on socket connection errors
        !            65:         @raise QMPConnectError if the greeting is not received
        !            66:         @raise QMPCapabilitiesError if fails to negotiate capabilities
        !            67:         """
        !            68:         self.__sock.connect(self.__address)
        !            69:         greeting = self.__json_read()
        !            70:         if greeting is None or not greeting.has_key('QMP'):
        !            71:             raise QMPConnectError
        !            72:         # Greeting seems ok, negotiate capabilities
        !            73:         resp = self.cmd('qmp_capabilities')
        !            74:         if "return" in resp:
        !            75:             return greeting
        !            76:         raise QMPCapabilitiesError
        !            77: 
        !            78:     def cmd_obj(self, qmp_cmd):
        !            79:         """
        !            80:         Send a QMP command to the QMP Monitor.
        !            81: 
        !            82:         @param qmp_cmd: QMP command to be sent as a Python dict
        !            83:         @return QMP response as a Python dict or None if the connection has
        !            84:                 been closed
        !            85:         """
        !            86:         try:
        !            87:             self.__sock.sendall(json.dumps(qmp_cmd))
        !            88:         except socket.error, err:
        !            89:             if err[0] == errno.EPIPE:
        !            90:                 return
        !            91:             raise socket.error(err)
        !            92:         return self.__json_read()
1.1       root       93: 
1.1.1.3 ! root       94:     def cmd(self, name, args=None, id=None):
        !            95:         """
        !            96:         Build a QMP command and send it to the QMP Monitor.
        !            97: 
        !            98:         @param name: command name (string)
        !            99:         @param args: command arguments (dict)
        !           100:         @param id: command id (dict, list, string or int)
        !           101:         """
        !           102:         qmp_cmd = { 'execute': name }
        !           103:         if args:
        !           104:             qmp_cmd['arguments'] = args
        !           105:         if id:
        !           106:             qmp_cmd['id'] = id
        !           107:         return self.cmd_obj(qmp_cmd)
        !           108: 
        !           109:     def get_events(self):
        !           110:         """
        !           111:         Get a list of available QMP events.
        !           112:         """
        !           113:         self.__sock.setblocking(0)
1.1       root      114:         try:
1.1.1.3 ! root      115:             self.__json_read()
        !           116:         except socket.error, err:
        !           117:             if err[0] == errno.EAGAIN:
        !           118:                 # No data available
        !           119:                 pass
        !           120:         self.__sock.setblocking(1)
        !           121:         return self.__events
        !           122: 
        !           123:     def clear_events(self):
        !           124:         """
        !           125:         Clear current list of pending events.
        !           126:         """
        !           127:         self.__events = []
        !           128: 
        !           129:     def close(self):
        !           130:         self.__sock.close()
        !           131:         self.__sockfile.close()

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.