From 10e163c0395f5c9460ec2f2fe7947a1d056cda30 Mon Sep 17 00:00:00 2001 From: Wainer dos Santos Moschetta Date: Fri, 27 Dec 2019 10:40:57 -0300 Subject: python/qemu: qmp: Replace socket.error with OSError MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The socket.error is deprecated from Python 3.3, instead it is made a link to OSError. This change replaces the occurences of socket.error with OSError. Signed-off-by: Wainer dos Santos Moschetta Reviewed-by: John Snow Message-Id: <20191227134101.244496-2-wainersm@redhat.com> Signed-off-by: Philippe Mathieu-Daudé --- python/qemu/qmp.py | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) (limited to 'python/qemu/qmp.py') diff --git a/python/qemu/qmp.py b/python/qemu/qmp.py index 5c8cf6a..8c6c984 100644 --- a/python/qemu/qmp.py +++ b/python/qemu/qmp.py @@ -47,7 +47,7 @@ class QEMUMonitorProtocol(object): or a tuple in the form ( address, port ) for a TCP connection @param server: server mode listens on the socket (bool) - @raise socket.error on socket connection errors + @raise OSError on socket connection errors @note No connection is established, this is done by the connect() or accept() methods """ @@ -107,8 +107,8 @@ class QEMUMonitorProtocol(object): self.__sock.setblocking(0) try: self.__json_read() - except socket.error as err: - if err[0] == errno.EAGAIN: + except OSError as err: + if err.errno == errno.EAGAIN: # No data available pass self.__sock.setblocking(1) @@ -133,7 +133,7 @@ class QEMUMonitorProtocol(object): Connect to the QMP Monitor and perform capabilities negotiation. @return QMP greeting dict - @raise socket.error on socket connection errors + @raise OSError on socket connection errors @raise QMPConnectError if the greeting is not received @raise QMPCapabilitiesError if fails to negotiate capabilities """ @@ -147,7 +147,7 @@ class QEMUMonitorProtocol(object): Await connection from QMP Monitor and perform capabilities negotiation. @return QMP greeting dict - @raise socket.error on socket connection errors + @raise OSError on socket connection errors @raise QMPConnectError if the greeting is not received @raise QMPCapabilitiesError if fails to negotiate capabilities """ @@ -167,10 +167,10 @@ class QEMUMonitorProtocol(object): self.logger.debug(">>> %s", qmp_cmd) try: self.__sock.sendall(json.dumps(qmp_cmd).encode('utf-8')) - except socket.error as err: - if err[0] == errno.EPIPE: + except OSError as err: + if err.errno == errno.EPIPE: return - raise socket.error(err) + raise err resp = self.__json_read() self.logger.debug("<<< %s", resp) return resp -- cgit v1.1 From a0a261e47252f2b7b44cbb0999cdafeb6b01bdbb Mon Sep 17 00:00:00 2001 From: Wainer dos Santos Moschetta Date: Fri, 27 Dec 2019 10:40:58 -0300 Subject: python/qemu: Delint the qmp module MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This clean up the pylint-3 report on qmp: ************* Module qemu.qmp python/qemu/qmp.py:1:0: C0111: Missing module docstring (missing-docstring) python/qemu/qmp.py:17:0: C0111: Missing class docstring (missing-docstring) python/qemu/qmp.py:21:0: C0111: Missing class docstring (missing-docstring) python/qemu/qmp.py:25:0: C0111: Missing class docstring (missing-docstring) python/qemu/qmp.py:29:0: C0111: Missing class docstring (missing-docstring) python/qemu/qmp.py:33:0: C0111: Missing class docstring (missing-docstring) python/qemu/qmp.py:33:0: R0205: Class 'QEMUMonitorProtocol' inherits from object, can be safely removed from bases in python3 (useless-object-inheritance) python/qemu/qmp.py:80:4: R1710: Either all return statements in a function should return an expression, or none of them should. (inconsistent-return-statements) python/qemu/qmp.py:131:4: R1710: Either all return statements in a function should return an expression, or none of them should. (inconsistent-return-statements) python/qemu/qmp.py:159:4: R1710: Either all return statements in a function should return an expression, or none of them should. (inconsistent-return-statements) python/qemu/qmp.py:245:4: C0111: Missing method docstring (missing-docstring) python/qemu/qmp.py:249:4: C0111: Missing method docstring (missing-docstring) python/qemu/qmp.py:252:4: C0111: Missing method docstring (missing-docstring) python/qemu/qmp.py:255:4: C0111: Missing method docstring (missing-docstring) Signed-off-by: Wainer dos Santos Moschetta Reviewed-by: John Snow Reviewed-by: Philippe Mathieu-Daudé Message-Id: <20191227134101.244496-3-wainersm@redhat.com> Signed-off-by: Philippe Mathieu-Daudé --- python/qemu/qmp.py | 51 +++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 41 insertions(+), 10 deletions(-) (limited to 'python/qemu/qmp.py') diff --git a/python/qemu/qmp.py b/python/qemu/qmp.py index 8c6c984..f4e04a6 100644 --- a/python/qemu/qmp.py +++ b/python/qemu/qmp.py @@ -1,5 +1,4 @@ -# QEMU Monitor Protocol Python class -# +""" QEMU Monitor Protocol Python class """ # Copyright (C) 2009, 2010 Red Hat Inc. # # Authors: @@ -15,22 +14,34 @@ import logging class QMPError(Exception): - pass + """ + QMP base exception + """ class QMPConnectError(QMPError): - pass + """ + QMP connection exception + """ class QMPCapabilitiesError(QMPError): - pass + """ + QMP negotiate capabilities exception + """ class QMPTimeoutError(QMPError): - pass + """ + QMP timeout exception + """ -class QEMUMonitorProtocol(object): +class QEMUMonitorProtocol: + """ + Provide an API to connect to QEMU via QEMU Monitor Protocol (QMP) and then + allow to handle commands and events. + """ #: Logger object for debugging messages logger = logging.getLogger('QMP') @@ -81,7 +92,7 @@ class QEMUMonitorProtocol(object): while True: data = self.__sockfile.readline() if not data: - return + return None resp = json.loads(data) if 'event' in resp: self.logger.debug("<<< %s", resp) @@ -132,7 +143,7 @@ class QEMUMonitorProtocol(object): """ Connect to the QMP Monitor and perform capabilities negotiation. - @return QMP greeting dict + @return QMP greeting dict, or None if negotiate is false @raise OSError on socket connection errors @raise QMPConnectError if the greeting is not received @raise QMPCapabilitiesError if fails to negotiate capabilities @@ -141,6 +152,7 @@ class QEMUMonitorProtocol(object): self.__sockfile = self.__sock.makefile() if negotiate: return self.__negotiate_capabilities() + return None def accept(self): """ @@ -169,7 +181,7 @@ class QEMUMonitorProtocol(object): self.__sock.sendall(json.dumps(qmp_cmd).encode('utf-8')) except OSError as err: if err.errno == errno.EPIPE: - return + return None raise err resp = self.__json_read() self.logger.debug("<<< %s", resp) @@ -243,14 +255,33 @@ class QEMUMonitorProtocol(object): self.__events = [] def close(self): + """ + Close the socket and socket file. + """ self.__sock.close() self.__sockfile.close() def settimeout(self, timeout): + """ + Set the socket timeout. + + @param timeout (float): timeout in seconds, or None. + @note This is a wrap around socket.settimeout + """ self.__sock.settimeout(timeout) def get_sock_fd(self): + """ + Get the socket file descriptor. + + @return The file descriptor number. + """ return self.__sock.fileno() def is_scm_available(self): + """ + Check if the socket allows for SCM_RIGHTS. + + @return True if SCM_RIGHTS is available, otherwise False. + """ return self.__sock.family == socket.AF_UNIX -- cgit v1.1 From 54aafc2fc65231871e744308705c4aa6d283a22d Mon Sep 17 00:00:00 2001 From: Wainer dos Santos Moschetta Date: Tue, 4 Feb 2020 11:11:09 -0300 Subject: python/qemu: qmp: Make accept()'s timeout configurable MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Currently the timeout of QEMUMonitorProtocol.accept() is hard-coded to 15.0 seconds. This added the parameter `timeout` so the value can be configured by the user. Signed-off-by: Wainer dos Santos Moschetta Reviewed-by: Philippe Mathieu-Daudé Reviewed-by: John Snow Message-Id: <20200204141111.3207-4-wainersm@redhat.com> Signed-off-by: Philippe Mathieu-Daudé --- python/qemu/qmp.py | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) (limited to 'python/qemu/qmp.py') diff --git a/python/qemu/qmp.py b/python/qemu/qmp.py index f4e04a6..0e07d80 100644 --- a/python/qemu/qmp.py +++ b/python/qemu/qmp.py @@ -154,16 +154,23 @@ class QEMUMonitorProtocol: return self.__negotiate_capabilities() return None - def accept(self): + def accept(self, timeout=15.0): """ Await connection from QMP Monitor and perform capabilities negotiation. + @param timeout: timeout in seconds (nonnegative float number, or + None). The value passed will set the behavior of the + underneath QMP socket as described in [1]. Default value + is set to 15.0. @return QMP greeting dict @raise OSError on socket connection errors @raise QMPConnectError if the greeting is not received @raise QMPCapabilitiesError if fails to negotiate capabilities + + [1] + https://docs.python.org/3/library/socket.html#socket.socket.settimeout """ - self.__sock.settimeout(15) + self.__sock.settimeout(timeout) self.__sock, _ = self.__sock.accept() self.__sockfile = self.__sock.makefile() return self.__negotiate_capabilities() -- cgit v1.1 From 07608e807d4e7bd2daa7fe154bd9dc2235c1a323 Mon Sep 17 00:00:00 2001 From: Wainer dos Santos Moschetta Date: Tue, 4 Feb 2020 11:11:10 -0300 Subject: python/qemu: qmp: Make QEMUMonitorProtocol a context manager MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This implement the __enter__ and __exit__ functions on QEMUMonitorProtocol class so that it can be used on 'with' statement and the resources will be free up on block end: with QEMUMonitorProtocol(socket_path) as qmp: qmp.connect() qmp.command('query-status') Signed-off-by: Wainer dos Santos Moschetta Reviewed-by: John Snow Message-Id: <20200204141111.3207-5-wainersm@redhat.com> Signed-off-by: Philippe Mathieu-Daudé --- python/qemu/qmp.py | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) (limited to 'python/qemu/qmp.py') diff --git a/python/qemu/qmp.py b/python/qemu/qmp.py index 0e07d80..486a566 100644 --- a/python/qemu/qmp.py +++ b/python/qemu/qmp.py @@ -139,6 +139,15 @@ class QEMUMonitorProtocol: raise QMPConnectError("Error while reading from socket") self.__sock.settimeout(None) + def __enter__(self): + # Implement context manager enter function. + return self + + def __exit__(self, exc_type, exc_value, exc_traceback): + # Implement context manager exit function. + self.close() + return False + def connect(self, negotiate=True): """ Connect to the QMP Monitor and perform capabilities negotiation. @@ -265,8 +274,10 @@ class QEMUMonitorProtocol: """ Close the socket and socket file. """ - self.__sock.close() - self.__sockfile.close() + if self.__sock: + self.__sock.close() + if self.__sockfile: + self.__sockfile.close() def settimeout(self, timeout): """ -- cgit v1.1 From 50d189c97ab8ed3de80d0ed22a867e1d5361fd02 Mon Sep 17 00:00:00 2001 From: Wainer dos Santos Moschetta Date: Fri, 27 Dec 2019 10:41:01 -0300 Subject: python/qemu: qmp: Remove unnused attributes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The `error` and `timeout` attributes in QEMUMonitorProtocol are not used, so this delete them. Signed-off-by: Wainer dos Santos Moschetta Reviewed-by: John Snow Reviewed-by: Philippe Mathieu-Daudé Message-Id: <20191227134101.244496-6-wainersm@redhat.com> Signed-off-by: Philippe Mathieu-Daudé --- python/qemu/qmp.py | 4 ---- 1 file changed, 4 deletions(-) (limited to 'python/qemu/qmp.py') diff --git a/python/qemu/qmp.py b/python/qemu/qmp.py index 486a566..4b9a362 100644 --- a/python/qemu/qmp.py +++ b/python/qemu/qmp.py @@ -45,10 +45,6 @@ class QEMUMonitorProtocol: #: Logger object for debugging messages logger = logging.getLogger('QMP') - #: Socket's error class - error = socket.error - #: Socket's timeout - timeout = socket.timeout def __init__(self, address, server=False): """ -- cgit v1.1 From 52c68b8abb614a744fd1d2099bbb3768a6aad8ee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luk=C3=A1=C5=A1=20Doktor?= Date: Mon, 20 Jan 2020 08:12:02 +0100 Subject: python: Treat None-return of greeting cmd MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In case qemu process dies the "monitor.cmd" returns None which gets passed to the "__negotiate_capabilities" and leads to unhandled exception. Let's only check the resp in case it has a value. Signed-off-by: Lukáš Doktor Reviewed-by: Philippe Mathieu-Daudé Reviewed-by: Wainer dos Santos Moschetta Message-Id: <20200120071202.30646-1-ldoktor@redhat.com> Signed-off-by: Philippe Mathieu-Daudé --- python/qemu/qmp.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'python/qemu/qmp.py') diff --git a/python/qemu/qmp.py b/python/qemu/qmp.py index 4b9a362..f40586e 100644 --- a/python/qemu/qmp.py +++ b/python/qemu/qmp.py @@ -80,7 +80,7 @@ class QEMUMonitorProtocol: raise QMPConnectError # Greeting seems ok, negotiate capabilities resp = self.cmd('qmp_capabilities') - if "return" in resp: + if resp and "return" in resp: return greeting raise QMPCapabilitiesError -- cgit v1.1