Python: synchronize python-qemu-qmp
-----BEGIN PGP SIGNATURE----- iQIzBAABCAAdFiEE+ber27ys35W+dsvQfe+BBqr8OQ4FAmR3sUwACgkQfe+BBqr8 OQ75GA/+NkO60LR6G7M68Wk2eaLlArlpWKa66lVTUPzIV+ERTzccjzFmEFhYM42z lJkkVieysuW/cFpjQqILSokfjiMOEH0XqC2R545vx0shZlExG6j6ky74jpFXxLCY 1tnZ/wOB97D1nO273T6taGfS6ZPBULaL+J2iCBuruEQiM9OKDQTjojLQYn+hRokL BZHF5fkMDts92GHBJdUo8ftYDyblDQ2SUQqdq0pgBgkt+kHlQ4wFB7O39HUwKwT7 rnAYz7EGbumYGwDkuNSIbpJ2pPiX7SxSPmmrebVPlQ79town3XATLraVbllls5eO 8BvvkDakO7GvTkzcRvqcFnsnytWJvbEr0jPs1m8lQ2dMTv+NdZmsoItqGDP3LzVZ RU/Dr/8biKAbMXpSRH0Waddvmpb18I9I4U2NrVWDZ/vp6DqOFMgx/wUAVz0y0+3O M9o9Bj93YZhqBXhpShc75xjvaqJ10IzqG0roR0JbbskdbPmtIEvFlparxGDyH3cX UaQPKk8WdRCVOjtodqM28C441zMSUdL5ZCHB1LnMEhbTeV/MkR8W5KAXcYIzy2ay gh0FBYoiI8QNBGMR5AEpxdc3XKSSYFXlPGMz74yhlO1hWP1KZM1rE8OWHVfAPcwl T4xkw+Hoio9T6SlOWH4qwANaiaX9BII5Dv+L+UqqYt4+neeN8yk= =FvG2 -----END PGP SIGNATURE----- Merge tag 'python-pull-request' of https://gitlab.com/jsnow/qemu into staging Python: synchronize python-qemu-qmp # -----BEGIN PGP SIGNATURE----- # # iQIzBAABCAAdFiEE+ber27ys35W+dsvQfe+BBqr8OQ4FAmR3sUwACgkQfe+BBqr8 # OQ75GA/+NkO60LR6G7M68Wk2eaLlArlpWKa66lVTUPzIV+ERTzccjzFmEFhYM42z # lJkkVieysuW/cFpjQqILSokfjiMOEH0XqC2R545vx0shZlExG6j6ky74jpFXxLCY # 1tnZ/wOB97D1nO273T6taGfS6ZPBULaL+J2iCBuruEQiM9OKDQTjojLQYn+hRokL # BZHF5fkMDts92GHBJdUo8ftYDyblDQ2SUQqdq0pgBgkt+kHlQ4wFB7O39HUwKwT7 # rnAYz7EGbumYGwDkuNSIbpJ2pPiX7SxSPmmrebVPlQ79town3XATLraVbllls5eO # 8BvvkDakO7GvTkzcRvqcFnsnytWJvbEr0jPs1m8lQ2dMTv+NdZmsoItqGDP3LzVZ # RU/Dr/8biKAbMXpSRH0Waddvmpb18I9I4U2NrVWDZ/vp6DqOFMgx/wUAVz0y0+3O # M9o9Bj93YZhqBXhpShc75xjvaqJ10IzqG0roR0JbbskdbPmtIEvFlparxGDyH3cX # UaQPKk8WdRCVOjtodqM28C441zMSUdL5ZCHB1LnMEhbTeV/MkR8W5KAXcYIzy2ay # gh0FBYoiI8QNBGMR5AEpxdc3XKSSYFXlPGMz74yhlO1hWP1KZM1rE8OWHVfAPcwl # T4xkw+Hoio9T6SlOWH4qwANaiaX9BII5Dv+L+UqqYt4+neeN8yk= # =FvG2 # -----END PGP SIGNATURE----- # gpg: Signature made Wed 31 May 2023 01:42:52 PM PDT # gpg: using RSA key F9B7ABDBBCACDF95BE76CBD07DEF8106AAFC390E # gpg: Good signature from "John Snow (John Huston) <jsnow@redhat.com>" [unknown] # gpg: WARNING: This key is not certified with a trusted signature! # gpg: There is no indication that the signature belongs to the owner. # Primary key fingerprint: FAEB 9711 A12C F475 812F 18F2 88A9 064D 1835 61EB # Subkey fingerprint: F9B7 ABDB BCAC DF95 BE76 CBD0 7DEF 8106 AAFC 390E * tag 'python-pull-request' of https://gitlab.com/jsnow/qemu: Revert "python/qmp/protocol: add open_with_socket()" python/qmp/legacy: remove open_with_socket() calls python/machine: use connect-based interface for existing sockets python/qmp/legacy: allow using sockets for connect() python/qmp: allow sockets to be passed to connect() Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
This commit is contained in:
commit
9824490ded
@ -337,18 +337,18 @@ class QEMUMachine:
|
||||
self._remove_files.append(self._console_address)
|
||||
|
||||
if self._qmp_set:
|
||||
monitor_address = None
|
||||
sock = None
|
||||
if self._monitor_address is None:
|
||||
self._sock_pair = socket.socketpair()
|
||||
sock = self._sock_pair[1]
|
||||
if isinstance(self._monitor_address, str):
|
||||
self._remove_files.append(self._monitor_address)
|
||||
monitor_address = self._monitor_address
|
||||
|
||||
sock_or_addr = self._monitor_address or sock
|
||||
assert sock_or_addr is not None
|
||||
|
||||
self._qmp_connection = QEMUMonitorProtocol(
|
||||
address=monitor_address,
|
||||
sock=sock,
|
||||
server=True,
|
||||
sock_or_addr,
|
||||
server=bool(self._monitor_address),
|
||||
nickname=self._name
|
||||
)
|
||||
|
||||
@ -370,7 +370,10 @@ class QEMUMachine:
|
||||
if self._sock_pair:
|
||||
self._sock_pair[0].close()
|
||||
if self._qmp_connection:
|
||||
self._qmp.accept(self._qmp_timer)
|
||||
if self._sock_pair:
|
||||
self._qmp.connect()
|
||||
else:
|
||||
self._qmp.accept(self._qmp_timer)
|
||||
|
||||
def _close_qemu_log_file(self) -> None:
|
||||
if self._qemu_log_file is not None:
|
||||
|
@ -68,34 +68,31 @@ class QEMUMonitorProtocol:
|
||||
Provide an API to connect to QEMU via QEMU Monitor Protocol (QMP)
|
||||
and then allow to handle commands and events.
|
||||
|
||||
:param address: QEMU address, can be either a unix socket path (string)
|
||||
or a tuple in the form ( address, port ) for a TCP
|
||||
connection or None
|
||||
:param sock: a socket or None
|
||||
:param address: QEMU address, can be a unix socket path (string), a tuple
|
||||
in the form ( address, port ) for a TCP connection, or an
|
||||
existing `socket.socket` object.
|
||||
:param server: Act as the socket server. (See 'accept')
|
||||
Not applicable when passing a socket directly.
|
||||
:param nickname: Optional nickname used for logging.
|
||||
"""
|
||||
|
||||
def __init__(self,
|
||||
address: Optional[SocketAddrT] = None,
|
||||
sock: Optional[socket.socket] = None,
|
||||
address: Union[SocketAddrT, socket.socket],
|
||||
server: bool = False,
|
||||
nickname: Optional[str] = None):
|
||||
|
||||
assert address or sock
|
||||
if server and isinstance(address, socket.socket):
|
||||
raise ValueError(
|
||||
"server argument should be False when passing a socket")
|
||||
|
||||
self._qmp = QMPClient(nickname)
|
||||
self._aloop = asyncio.get_event_loop()
|
||||
self._address = address
|
||||
self._sock = sock
|
||||
self._timeout: Optional[float] = None
|
||||
|
||||
if server:
|
||||
if sock:
|
||||
assert self._sock is not None
|
||||
self._sync(self._qmp.open_with_socket(self._sock))
|
||||
else:
|
||||
assert self._address is not None
|
||||
self._sync(self._qmp.start_server(self._address))
|
||||
assert not isinstance(self._address, socket.socket)
|
||||
self._sync(self._qmp.start_server(self._address))
|
||||
|
||||
_T = TypeVar('_T')
|
||||
|
||||
@ -150,7 +147,6 @@ class QEMUMonitorProtocol:
|
||||
:return: QMP greeting dict, or None if negotiate is false
|
||||
:raise ConnectError: on connection errors
|
||||
"""
|
||||
assert self._address is not None
|
||||
self._qmp.await_greeting = negotiate
|
||||
self._qmp.negotiate = negotiate
|
||||
|
||||
|
@ -297,19 +297,6 @@ class AsyncProtocol(Generic[T]):
|
||||
await self.accept()
|
||||
assert self.runstate == Runstate.RUNNING
|
||||
|
||||
@upper_half
|
||||
@require(Runstate.IDLE)
|
||||
async def open_with_socket(self, sock: socket.socket) -> None:
|
||||
"""
|
||||
Start connection with given socket.
|
||||
|
||||
:param sock: A socket.
|
||||
|
||||
:raise StateError: When the `Runstate` is not `IDLE`.
|
||||
"""
|
||||
self._reader, self._writer = await asyncio.open_connection(sock=sock)
|
||||
self._set_state(Runstate.CONNECTING)
|
||||
|
||||
@upper_half
|
||||
@require(Runstate.IDLE)
|
||||
async def start_server(self, address: SocketAddrT,
|
||||
@ -357,12 +344,11 @@ class AsyncProtocol(Generic[T]):
|
||||
protocol-level failure occurs while establishing a new
|
||||
session, the wrapped error may also be an `QMPError`.
|
||||
"""
|
||||
if not self._reader:
|
||||
if self._accepted is None:
|
||||
raise QMPError("Cannot call accept() before start_server().")
|
||||
await self._session_guard(
|
||||
self._do_accept(),
|
||||
'Failed to establish connection')
|
||||
if self._accepted is None:
|
||||
raise QMPError("Cannot call accept() before start_server().")
|
||||
await self._session_guard(
|
||||
self._do_accept(),
|
||||
'Failed to establish connection')
|
||||
await self._session_guard(
|
||||
self._establish_session(),
|
||||
'Failed to establish session')
|
||||
@ -370,7 +356,7 @@ class AsyncProtocol(Generic[T]):
|
||||
|
||||
@upper_half
|
||||
@require(Runstate.IDLE)
|
||||
async def connect(self, address: SocketAddrT,
|
||||
async def connect(self, address: Union[SocketAddrT, socket.socket],
|
||||
ssl: Optional[SSLContext] = None) -> None:
|
||||
"""
|
||||
Connect to the server and begin processing message queues.
|
||||
@ -615,7 +601,7 @@ class AsyncProtocol(Generic[T]):
|
||||
self.logger.debug("Connection accepted.")
|
||||
|
||||
@upper_half
|
||||
async def _do_connect(self, address: SocketAddrT,
|
||||
async def _do_connect(self, address: Union[SocketAddrT, socket.socket],
|
||||
ssl: Optional[SSLContext] = None) -> None:
|
||||
"""
|
||||
Acting as the transport client, initiate a connection to a server.
|
||||
@ -634,9 +620,17 @@ class AsyncProtocol(Generic[T]):
|
||||
# otherwise yield.
|
||||
await asyncio.sleep(0)
|
||||
|
||||
self.logger.debug("Connecting to %s ...", address)
|
||||
|
||||
if isinstance(address, tuple):
|
||||
if isinstance(address, socket.socket):
|
||||
self.logger.debug("Connecting with existing socket: "
|
||||
"fd=%d, family=%r, type=%r",
|
||||
address.fileno(), address.family, address.type)
|
||||
connect = asyncio.open_connection(
|
||||
limit=self._limit,
|
||||
ssl=ssl,
|
||||
sock=address,
|
||||
)
|
||||
elif isinstance(address, tuple):
|
||||
self.logger.debug("Connecting to %s ...", address)
|
||||
connect = asyncio.open_connection(
|
||||
address[0],
|
||||
address[1],
|
||||
@ -644,13 +638,14 @@ class AsyncProtocol(Generic[T]):
|
||||
limit=self._limit,
|
||||
)
|
||||
else:
|
||||
self.logger.debug("Connecting to file://%s ...", address)
|
||||
connect = asyncio.open_unix_connection(
|
||||
path=address,
|
||||
ssl=ssl,
|
||||
limit=self._limit,
|
||||
)
|
||||
self._reader, self._writer = await connect
|
||||
|
||||
self._reader, self._writer = await connect
|
||||
self.logger.debug("Connected.")
|
||||
|
||||
@upper_half
|
||||
|
Loading…
Reference in New Issue
Block a user