830e6fd3 | 25-Feb-2022 |
John Snow <jsnow@redhat.com> |
python/aqmp: split _client_connected_cb() out as _incoming()
As part of disentangling the monolithic nature of _do_accept(), split out the incoming callback to prepare for factoring out the "wait fo
python/aqmp: split _client_connected_cb() out as _incoming()
As part of disentangling the monolithic nature of _do_accept(), split out the incoming callback to prepare for factoring out the "wait for a peer" step. Namely, this means using an event signal we can wait on from outside of this method.
Signed-off-by: John Snow <jsnow@redhat.com> Acked-by: Kevin Wolf <kwolf@redhat.com> Reviewed-by: Daniel P. Berrangé <berrange@redhat.com> Message-id: 20220225205948.3693480-5-jsnow@redhat.com Signed-off-by: John Snow <jsnow@redhat.com>
show more ...
|
68a6cf3f | 25-Feb-2022 |
John Snow <jsnow@redhat.com> |
python/aqmp: remove _new_session and _establish_connection
These two methods attempted to entirely envelop the logic of establishing a connection to a peer start to finish. However, we need to break
python/aqmp: remove _new_session and _establish_connection
These two methods attempted to entirely envelop the logic of establishing a connection to a peer start to finish. However, we need to break apart the incoming connection step into more granular steps. We will no longer be able to reasonably constrain the logic inside of these helper functions.
So, remove them - with _session_guard(), they no longer serve a real purpose.
Although the public API doesn't change, the internal API does. Now that there are no intermediary methods between e.g. connect() and _do_connect(), there's no hook where the runstate is set. As a result, the test suite changes a little to cope with the new semantics of _do_accept() and _do_connect().
Lastly, take some pieces of the now-deleted docstrings and move them up to the public interface level. They were a little more detailed, and it won't hurt to keep them.
Signed-off-by: John Snow <jsnow@redhat.com> Acked-by: Kevin Wolf <kwolf@redhat.com> Reviewed-by: Daniel P. Berrangé <berrange@redhat.com> Message-id: 20220225205948.3693480-4-jsnow@redhat.com Signed-off-by: John Snow <jsnow@redhat.com>
show more ...
|
0ba4e76b | 25-Feb-2022 |
John Snow <jsnow@redhat.com> |
python/aqmp: rename 'accept()' to 'start_server_and_accept()'
Previously, I had a method named "accept()" that under-the-hood calls bind(2), listen(2) *and* accept(2). I meant this as a simplificati
python/aqmp: rename 'accept()' to 'start_server_and_accept()'
Previously, I had a method named "accept()" that under-the-hood calls bind(2), listen(2) *and* accept(2). I meant this as a simplification and counterpart to the one-shot "connect()" method.
This is confusing to readers who expect accept() to mean *just* accept(2). Since I need to split apart the "accept()" method into multiple methods anyway (one of which strongly resembling accept(2)), it feels pertinent to rename this method *now*.
Rename this all-in-one method "start_server_and_accept()" instead.
Signed-off-by: John Snow <jsnow@redhat.com> Acked-by: Kevin Wolf <kwolf@redhat.com> Reviewed-by: Daniel P. Berrangé <berrange@redhat.com> Message-id: 20220225205948.3693480-3-jsnow@redhat.com Signed-off-by: John Snow <jsnow@redhat.com>
show more ...
|
40196c23 | 25-Feb-2022 |
John Snow <jsnow@redhat.com> |
python/aqmp: add _session_guard()
In _new_session, there's a fairly complex except clause that's used to give semantic errors to callers of accept() and connect(). We need to create a new two-step r
python/aqmp: add _session_guard()
In _new_session, there's a fairly complex except clause that's used to give semantic errors to callers of accept() and connect(). We need to create a new two-step replacement for accept(), so factoring out this piece of logic will be useful.
Bolster the comments and docstring here to try and demystify what's going on in this fairly delicate piece of Python magic.
(If we were using Python 3.7+, this would be an @asynccontextmanager. We don't have that very nice piece of magic, however, so this must take an Awaitable to manage the Exception contexts properly. We pay the price for platform compatibility.)
Signed-off-by: John Snow <jsnow@redhat.com> Acked-by: Kevin Wolf <kwolf@redhat.com> Reviewed-by: Daniel P. Berrangé <berrange@redhat.com> Message-id: 20220225205948.3693480-2-jsnow@redhat.com Signed-off-by: John Snow <jsnow@redhat.com>
show more ...
|
43a1119e | 04-Feb-2022 |
John Snow <jsnow@redhat.com> |
Revert "python: pin setuptools below v60.0.0"
This reverts commit 1e4d8b31be35e54b6429fea54f5ecaa0083f91e7.
Signed-off-by: John Snow <jsnow@redhat.com> Message-id: 20220204221804.2047468-3-jsnow@re
Revert "python: pin setuptools below v60.0.0"
This reverts commit 1e4d8b31be35e54b6429fea54f5ecaa0083f91e7.
Signed-off-by: John Snow <jsnow@redhat.com> Message-id: 20220204221804.2047468-3-jsnow@redhat.com Signed-off-by: John Snow <jsnow@redhat.com>
show more ...
|
762c280d | 04-Feb-2022 |
John Snow <jsnow@redhat.com> |
Python: add setuptools v60.0 workaround
Setuptools v60 and later include a bundled version of distutils, a deprecated standard library scheduled for removal in future versions of Python. Setuptools
Python: add setuptools v60.0 workaround
Setuptools v60 and later include a bundled version of distutils, a deprecated standard library scheduled for removal in future versions of Python. Setuptools v60 is only possible to install for Python 3.7 and later.
Python has a distutils.sysconfig.get_python_lib() function that returns '/usr/lib/pythonX.Y' on posix systems. RPM-based systems actually use '/usr/lib64/pythonX.Y' instead, so Fedora patches stdlib distutils for Python 3.7 and Python 3.8 to return the correct value.
Python 3.9 and later introduce a sys.platlibdir property, which returns the correct value on RPM-based systems.
The change to a distutils package not provided by Fedora on Python 3.7 and 3.8 causes a regression in distutils.sysconfig.get_python_lib() that ultimately causes false positives to be emitted by pylint, because it can no longer find the system source libraries.
Many Python tools are fairly aggressive about updating setuptools packages, and so even though this package is a fair bit newer than Python 3.7/3.8, it's not entirely unreasonable for a given user to have such a modern package with a fairly old Python interpreter.
Updates to Python 3.7 and Python 3.8 are being produced for Fedora which will fix the problem on up-to-date systems. Until then, we can force the loading of platform-provided distutils when running the pylint test. This is the least-invasive yet most comprehensive fix.
References: https://github.com/pypa/setuptools/pull/2896 https://github.com/PyCQA/pylint/issues/5704 https://github.com/pypa/distutils/issues/110
Signed-off-by: John Snow <jsnow@redhat.com> Message-id: 20220204221804.2047468-2-jsnow@redhat.com Signed-off-by: John Snow <jsnow@redhat.com>
show more ...
|
2ddaeb7b | 07-Feb-2022 |
John Snow <jsnow@redhat.com> |
Python: discourage direct setup.py install
When invoking setup.py directly, the default behavior for 'install' is to run the bdist_egg installation hook, which is ... actually deprecated by setuptoo
Python: discourage direct setup.py install
When invoking setup.py directly, the default behavior for 'install' is to run the bdist_egg installation hook, which is ... actually deprecated by setuptools. It doesn't seem to work quite right anymore.
By contrast, 'pip install' will invoke the bdist_wheel hook instead. This leads to differences in behavior for the two approaches. I advocate using pip in the documentation in this directory, but the 'setup.py' which has been used for quite a long time in the Python world may deceptively appear to work at first glance.
Add an error message that will save a bit of time and frustration that points the user towards using the supported installation invocation.
Reported-by: Daniel P. Berrangé <berrange@redhat.com> Signed-off-by: John Snow <jsnow@redhat.com> Reviewed-by: Beraldo Leal <bleal@redhat.com> Message-id: 20220207213039.2278569-1-jsnow@redhat.com Signed-off-by: John Snow <jsnow@redhat.com>
show more ...
|
5c66d7d8 | 28-Jan-2022 |
Daniel P. Berrangé <berrange@redhat.com> |
python: support recording QMP session to a file
When running QMP commands with very large response payloads, it is often not easy to spot the info you want. If we can save the response to a file the
python: support recording QMP session to a file
When running QMP commands with very large response payloads, it is often not easy to spot the info you want. If we can save the response to a file then tools like 'grep' or 'jq' can be used to extract information.
For convenience of processing, we merge the QMP command and response dictionaries together:
{ "arguments": {}, "execute": "query-kvm", "return": { "enabled": false, "present": true } }
Example usage
$ ./scripts/qmp/qmp-shell-wrap -l q.log -p -- ./build/qemu-system-x86_64 -display none Welcome to the QMP low-level shell! Connected (QEMU) query-kvm { "return": { "enabled": false, "present": true } } (QEMU) query-mice { "return": [ { "absolute": false, "current": true, "index": 2, "name": "QEMU PS/2 Mouse" } ] }
$ jq --slurp '. | to_entries[] | select(.value.execute == "query-kvm") | .value.return.enabled' < q.log false
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org> Signed-off-by: Daniel P. Berrangé <berrange@redhat.com> Message-id: 20220128161157.36261-3-berrange@redhat.com Signed-off-by: John Snow <jsnow@redhat.com>
show more ...
|
43912529 | 28-Jan-2022 |
Daniel P. Berrangé <berrange@redhat.com> |
python: introduce qmp-shell-wrap convenience tool
With the current 'qmp-shell' tool developers must first spawn QEMU with a suitable -qmp arg and then spawn qmp-shell in a separate terminal pointing
python: introduce qmp-shell-wrap convenience tool
With the current 'qmp-shell' tool developers must first spawn QEMU with a suitable -qmp arg and then spawn qmp-shell in a separate terminal pointing to the right socket.
With 'qmp-shell-wrap' developers can ignore QMP sockets entirely and just pass the QEMU command and arguments they want. The program will listen on a UNIX socket and tell QEMU to connect QMP to that.
For example, this:
# qmp-shell-wrap -- qemu-system-x86_64 -display none
Is roughly equivalent of running:
# qemu-system-x86_64 -display none -qmp qmp-shell-1234 & # qmp-shell qmp-shell-1234
Except that 'qmp-shell-wrap' switches the socket peers around so that it is the UNIX socket server and QEMU is the socket client. This makes QEMU reliably go away when qmp-shell-wrap exits, closing the server socket.
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com> Message-id: 20220128161157.36261-2-berrange@redhat.com [Edited for rebase. --js] Signed-off-by: John Snow <jsnow@redhat.com>
show more ...
|
b0b662bb | 31-Jan-2022 |
John Snow <jsnow@redhat.com> |
python/aqmp: add socket bind step to legacy.py
The synchronous QMP library would bind to the server address during __init__(). The new library delays this to the accept() call, because binding occur
python/aqmp: add socket bind step to legacy.py
The synchronous QMP library would bind to the server address during __init__(). The new library delays this to the accept() call, because binding occurs inside of the call to start_[unix_]server(), which is an async method -- so it cannot happen during __init__ anymore.
Python 3.7+ adds the ability to create the server (and thus the bind() call) and begin the active listening in separate steps, but we don't have that functionality in 3.6, our current minimum.
Therefore ... Add a temporary workaround that allows the synchronous version of the client to bind the socket in advance, guaranteeing that there will be a UNIX socket in the filesystem ready for the QEMU client to connect to without a race condition.
(Yes, it's a bit ugly. Fixing it more nicely will have to wait until our minimum Python version is 3.7+.)
Signed-off-by: John Snow <jsnow@redhat.com> Reviewed-by: Kevin Wolf <kwolf@redhat.com> Message-id: 20220201041134.1237016-5-jsnow@redhat.com Signed-off-by: John Snow <jsnow@redhat.com>
show more ...
|
74a1505d | 31-Jan-2022 |
John Snow <jsnow@redhat.com> |
python: upgrade mypy to 0.780
We need a slightly newer version of mypy in order to use some features of the asyncio server functions in the next commit.
(Note: pipenv is not really suited to upgrad
python: upgrade mypy to 0.780
We need a slightly newer version of mypy in order to use some features of the asyncio server functions in the next commit.
(Note: pipenv is not really suited to upgrading individual packages; I need to replace this tool with something better for the task. For now, the miscellaneous updates not related to the mypy upgrade are simply beyond my control. It's on my list to take care of soon.)
Signed-off-by: John Snow <jsnow@redhat.com> Reviewed-by: Kevin Wolf <kwolf@redhat.com> Message-id: 20220201041134.1237016-4-jsnow@redhat.com Signed-off-by: John Snow <jsnow@redhat.com>
show more ...
|
50465f94 | 31-Jan-2022 |
John Snow <jsnow@redhat.com> |
python/machine: raise VMLaunchFailure exception from launch()
This allows us to pack in some extra information about the failure, which guarantees that if the caller did not *intentionally* cause a
python/machine: raise VMLaunchFailure exception from launch()
This allows us to pack in some extra information about the failure, which guarantees that if the caller did not *intentionally* cause a failure (by capturing this Exception), some pretty good clues will be printed at the bottom of the traceback information.
This will help make failures in the event of a non-negative return code more obvious when they go unhandled; the current behavior in _post_shutdown() is to print a warning message only in the event of signal-based terminations (for negative return codes).
(Note: In Python, catching BaseException instead of Exception catches a broader array of Exception events, including SystemExit and KeyboardInterrupt. We do not want to "wrap" such exceptions as a VMLaunchFailure, because that will 'downgrade' the exception from a BaseException to a regular Exception. We do, however, want to perform cleanup in either case, so catch on the broadest scope and wrap-and-re-raise only in the more targeted scope.)
Signed-off-by: John Snow <jsnow@redhat.com> Reviewed-by: Hanna Reitz <hreitz@redhat.com> Reviewed-by: Kevin Wolf <kwolf@redhat.com> Message-id: 20220201041134.1237016-3-jsnow@redhat.com Signed-off-by: John Snow <jsnow@redhat.com>
show more ...
|
fa73e6e4 | 31-Jan-2022 |
John Snow <jsnow@redhat.com> |
python/aqmp: Fix negotiation with pre-"oob" QEMU
QEMU versions prior to the "oob" capability *also* can't accept the "enable" keyword argument at all. Fix the handshake process with older QEMU versi
python/aqmp: Fix negotiation with pre-"oob" QEMU
QEMU versions prior to the "oob" capability *also* can't accept the "enable" keyword argument at all. Fix the handshake process with older QEMU versions.
Signed-off-by: John Snow <jsnow@redhat.com> Reviewed-by: Hanna Reitz <hreitz@redhat.com> Reviewed-by: Kevin Wolf <kwolf@redhat.com> Message-id: 20220201041134.1237016-2-jsnow@redhat.com Signed-off-by: John Snow <jsnow@redhat.com>
show more ...
|
fd9c3a62 | 10-Jan-2022 |
John Snow <jsnow@redhat.com> |
python: move qmp-shell under the AQMP package
Signed-off-by: John Snow <jsnow@redhat.com> Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com> Reviewed-by: Beraldo Leal <bleal@redhat
python: move qmp-shell under the AQMP package
Signed-off-by: John Snow <jsnow@redhat.com> Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com> Reviewed-by: Beraldo Leal <bleal@redhat.com>
show more ...
|
0347c4c4 | 10-Jan-2022 |
John Snow <jsnow@redhat.com> |
python: move qmp utilities to python/qemu/utils
In order to upload a QMP package to PyPI, I want to remove any scripts that I am not 100% confident I want to support upstream, beyond our castle wall
python: move qmp utilities to python/qemu/utils
In order to upload a QMP package to PyPI, I want to remove any scripts that I am not 100% confident I want to support upstream, beyond our castle walls.
Move most of our QMP utilities into the utils package so we can split them out from the PyPI upload.
Signed-off-by: John Snow <jsnow@redhat.com> Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com> Reviewed-by: Beraldo Leal <bleal@redhat.com>
show more ...
|
f3efd129 | 10-Jan-2022 |
John Snow <jsnow@redhat.com> |
python/qmp: switch qmp-shell to AQMP
We have a replacement for async QMP, but it doesn't have feature parity yet. For now, then, port the old tool onto the new backend.
Signed-off-by: John Snow <js
python/qmp: switch qmp-shell to AQMP
We have a replacement for async QMP, but it doesn't have feature parity yet. For now, then, port the old tool onto the new backend.
Signed-off-by: John Snow <jsnow@redhat.com> Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
show more ...
|
8d6cdc51 | 10-Jan-2022 |
John Snow <jsnow@redhat.com> |
python/qmp: switch qom tools to AQMP
Signed-off-by: John Snow <jsnow@redhat.com> Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com> Reviewed-by: Beraldo Leal <bleal@redhat.com> |
26db0751 | 10-Jan-2022 |
John Snow <jsnow@redhat.com> |
python/qmp: switch qemu-ga-client to AQMP
Async QMP always raises a "ConnectError" on any connection error which houses the cause in a second exception. We can check if this root cause was python's
python/qmp: switch qemu-ga-client to AQMP
Async QMP always raises a "ConnectError" on any connection error which houses the cause in a second exception. We can check if this root cause was python's ConnectionError to determine a fairly similar condition to the original error check here.
Signed-off-by: John Snow <jsnow@redhat.com> Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com> Reviewed-by: Beraldo Leal <bleal@redhat.com>
show more ...
|
7017f385 | 10-Jan-2022 |
John Snow <jsnow@redhat.com> |
python/qemu-ga-client: don't use deprecated CLI syntax in usage comment
Cleanup related to commit ccd3b3b8112b670f, "qemu-option: warn for short-form boolean options".
Signed-off-by: John Snow <jsn
python/qemu-ga-client: don't use deprecated CLI syntax in usage comment
Cleanup related to commit ccd3b3b8112b670f, "qemu-option: warn for short-form boolean options".
Signed-off-by: John Snow <jsnow@redhat.com> Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com> Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
show more ...
|
6e7751dc | 10-Jan-2022 |
John Snow <jsnow@redhat.com> |
python/aqmp: rename AQMPError to QMPError
This is in preparation for renaming qemu.aqmp to qemu.qmp. I should have done this from this from the very beginning, but it's a convenient time to make sur
python/aqmp: rename AQMPError to QMPError
This is in preparation for renaming qemu.aqmp to qemu.qmp. I should have done this from this from the very beginning, but it's a convenient time to make sure this churn is taken care of.
Signed-off-by: John Snow <jsnow@redhat.com> Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
show more ...
|
728dcac5 | 10-Jan-2022 |
John Snow <jsnow@redhat.com> |
python/aqmp: add SocketAddrT to package root
It's a commonly needed definition, it can be re-exported by the root.
Signed-off-by: John Snow <jsnow@redhat.com> Reviewed-by: Vladimir Sementsov-Ogievs
python/aqmp: add SocketAddrT to package root
It's a commonly needed definition, it can be re-exported by the root.
Signed-off-by: John Snow <jsnow@redhat.com> Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com> Reviewed-by: Beraldo Leal <bleal@redhat.com>
show more ...
|
0e6bfd8b | 10-Jan-2022 |
John Snow <jsnow@redhat.com> |
python/aqmp: copy type definitions from qmp
Copy the remaining type definitions from QMP into the qemu.aqmp.legacy module. Now, users that require the legacy interface don't need to import anything
python/aqmp: copy type definitions from qmp
Copy the remaining type definitions from QMP into the qemu.aqmp.legacy module. Now, users that require the legacy interface don't need to import anything else but qemu.aqmp.legacy wrapper.
Signed-off-by: John Snow <jsnow@redhat.com> Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com> Reviewed-by: Beraldo Leal <bleal@redhat.com>
show more ...
|
3b5bf136 | 10-Jan-2022 |
John Snow <jsnow@redhat.com> |
python/aqmp: handle asyncio.TimeoutError on execute()
This exception can be injected into any await statement. If we are canceled via timeout, we want to clear the pending execution record on our wa
python/aqmp: handle asyncio.TimeoutError on execute()
This exception can be injected into any await statement. If we are canceled via timeout, we want to clear the pending execution record on our way out.
Signed-off-by: John Snow <jsnow@redhat.com> Reviewed-by: Beraldo Leal <bleal@redhat.com> Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
show more ...
|
3bc72e3a | 10-Jan-2022 |
John Snow <jsnow@redhat.com> |
python/aqmp: add __del__ method to legacy interface
asyncio can complain *very* loudly if you forget to back out of things gracefully before the garbage collector starts destroying objects that cont
python/aqmp: add __del__ method to legacy interface
asyncio can complain *very* loudly if you forget to back out of things gracefully before the garbage collector starts destroying objects that contain live references to asyncio Tasks.
The usual fix is just to remember to call aqmp.disconnect(), but for the sake of the legacy wrapper and quick, one-off scripts where a graceful shutdown is not necessarily of paramount imporance, add a courtesy cleanup that will trigger prior to seeing screenfuls of confusing asyncio tracebacks.
Note that we can't *always* save you from yourself; depending on when the GC runs, you might just seriously be out of luck. The best we can do in this case is to gently remind you to clean up after yourself.
(Still much better than multiple pages of incomprehensible python warnings for the crime of forgetting to put your toys away.)
Signed-off-by: John Snow <jsnow@redhat.com> Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com> Reviewed-by: Beraldo Leal <bleal@redhat.com>
show more ...
|
dc6877bd | 10-Jan-2022 |
John Snow <jsnow@redhat.com> |
python/aqmp: fix docstring typo
Reported-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com> Signed-off-by: John Snow <jsnow@redhat.com> Reviewed-by: Beraldo Leal <bleal@redhat.com> |