aboutsummaryrefslogtreecommitdiff
path: root/python
AgeCommit message (Collapse)AuthorFilesLines
2023-05-18mkvenv: add --diagnose option to explain "ensure" failuresJohn Snow1-1/+169
This is a routine that is designed to print some usable info for human beings back out to the terminal if/when "mkvenv ensure" fails to locate or install a package during configure time, such as meson or sphinx. Since we are requiring that "meson" and "sphinx" are installed to the same Python environment as QEMU is configured to build with, this can produce some surprising failures when things are mismatched. This method is here to try and ease that sting by offering some actionable diagnosis. Signed-off-by: John Snow <jsnow@redhat.com> Message-Id: <20230511035435.734312-8-jsnow@redhat.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2023-05-18mkvenv: add ensure subcommandJohn Snow3-3/+145
This command is to be used to add various packages (or ensure they're already present) into the configure-provided venv in a modular fashion. Examples: mkvenv ensure --online --dir "${source_dir}/python/wheels/" "meson>=0.61.5" mkvenv ensure --online "sphinx>=1.6.0" mkvenv ensure "qemu.qmp==0.0.2" It's designed to look for packages in three places, in order: (1) In system packages, if the version installed is already good enough. This way your distribution-provided meson, sphinx, etc are always used as first preference. (2) In a vendored packages directory. Here I am suggesting qemu.git/python/wheels/ as that directory. This is intended to serve as a replacement for vendoring the meson source for QEMU tarballs. It is also highly likely to be extremely useful for packaging the "qemu.qmp" package in source distributions for platforms that do not yet package qemu.qmp separately. (3) Online, via PyPI, ***only when "--online" is passed***. This is only ever used as a fallback if the first two sources do not have an appropriate package that meets the requirement. The ability to build QEMU and run tests *completely offline* is not impinged. Signed-off-by: Paolo Bonzini <pbonzini@redhat.com> Signed-off-by: John Snow <jsnow@redhat.com> Message-Id: <20230511035435.734312-7-jsnow@redhat.com> [Use distlib to lookup distributions. - Paolo] Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2023-05-18mkvenv: add nested venv workaroundJohn Snow1-5/+86
Python virtual environments do not typically nest; they may inherit from the top-level system packages or not at all. For our purposes, it would be convenient to emulate "nested" virtual environments to allow callers of the configure script to install specific versions of python utilities in order to test build system features, utility version compatibility, etc. While it is possible to install packages into the system environment (say, by using the --user flag), it's nicer to install test packages into a totally isolated environment instead. As detailed in https://www.qemu.org/2023/03/24/python/, Emulate a nested venv environment by using .pth files installed into the site-packages folder that points to the parent environment when appropriate. Signed-off-by: Paolo Bonzini <pbonzini@redhat.com> Signed-off-by: John Snow <jsnow@redhat.com> Message-Id: <20230511035435.734312-6-jsnow@redhat.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2023-05-18mkvenv: add better error message for broken or missing ensurepipJohn Snow1-0/+37
Debian debundles ensurepip for python; NetBSD debundles pyexpat but ensurepip needs pyexpat. Try our best to offer a helpful error message instead of just failing catastrophically. Signed-off-by: John Snow <jsnow@redhat.com> Message-Id: <20230511035435.734312-5-jsnow@redhat.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2023-05-18python: add mkvenv.pyJohn Snow6-0/+260
This script will be responsible for building a lightweight Python virtual environment at configure time. It works with Python 3.6 or newer. It has been designed to: - work *offline*, no PyPI required. - work *quickly*, The fast path is only ~65ms on my machine. - work *robustly*, with multiple fallbacks to keep things working. - work *cooperatively*, using system packages where possible. (You can use your distro's meson, no problem.) Due to its unique position in the build chain, it exists outside of the installable python packages in-tree and *must* be runnable without any third party dependencies. Under normal circumstances, the only dependency required to execute this script is Python 3.6+ itself. The script is *faster* by several seconds when setuptools and pip are installed in the host environment, which is probably the case for a typical multi-purpose developer workstation. In the event that pip/setuptools are missing or not usable, additional dependencies may be required on some distributions which remove certain Python stdlib modules to package them separately: - Debian may require python3-venv to provide "ensurepip" - NetBSD may require py310-expat to provide "pyexpat" * (* Or whichever version is current for NetBSD.) Signed-off-by: Paolo Bonzini <pbonzini@redhat.com> Signed-off-by: John Snow <jsnow@redhat.com> Message-Id: <20230511035435.734312-4-jsnow@redhat.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2023-05-18python: update pylint configurationJohn Snow1-0/+1
Pylint 2.17.x decided that SocketAddrT was a bad name for a Type Alias for some reason. Sure, fine, whatever. Signed-off-by: John Snow <jsnow@redhat.com> Reviewed-by: Daniel P. Berrangé <berrange@redhat.com> Message-Id: <20230511035435.734312-3-jsnow@redhat.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2023-05-18python: shut up "pip install" during "make check-minreqs"Paolo Bonzini1-3/+6
"make check-minreqs" runs pip without the --disable-pip-version-check option, which causes the obnoxious "A new release of pip available" message. Recent versions of pip also complain that some of the dependencies in our virtual environment rely on "setup.py install" instead of providing a pyproject.toml file; apparently it is deprecated to install them directly from pip instead of letting the "wheel" package take care of them. So, install "wheel" in the virtual environment. Signed-off-by: Paolo Bonzini <pbonzini@redhat.com> Signed-off-by: John Snow <jsnow@redhat.com> Message-Id: <20230511035435.734312-2-jsnow@redhat.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2023-02-22python: drop pipenvJohn Snow7-385/+84
The pipenv tool was nice in theory, but in practice it's just too hard to update selectively, and it makes using it a pain. The qemu.qmp repo dropped pipenv support a while back and it's been functioning just fine, so I'm backporting that change here to qemu.git. Signed-off-by: John Snow <jsnow@redhat.com> Message-id: 20230210003147.1309376-3-jsnow@redhat.com Signed-off-by: John Snow <jsnow@redhat.com>
2023-02-22python: support pylint 2.16John Snow3-5/+5
Pylint 2.16 adds a few new checks that cause the optional check-tox CI job to fail. 1. The superfluous-parens check seems to be a bit more aggressive, 2. broad-exception-raised is new; it discourages "raise Exception". Fix these minor issues and turn the lights green. Signed-off-by: John Snow <jsnow@redhat.com> Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org> Reviewed-by: Beraldo Leal <bleal@redhat.com> Message-id: 20230210003147.1309376-2-jsnow@redhat.com Signed-off-by: John Snow <jsnow@redhat.com>
2023-01-24python/qemu/machine: use socketpair() for QMP by defaultMarc-André Lureau1-8/+17
When no monitor address is given, establish the QMP communication through a socketpair() (API is also supported on Windows since Python 3.5) Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com> Reviewed-by: Daniel P. Berrangé <berrange@redhat.com> Message-id: 20230111080101.969151-4-marcandre.lureau@redhat.com [Resolved conflicts, fixed typing error. --js] Signed-off-by: John Snow <jsnow@redhat.com>
2023-01-24python/qmp/legacy: make QEMUMonitorProtocol accept a socketMarc-André Lureau1-3/+15
Teach QEMUMonitorProtocol to accept an exisiting socket. Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com> Reviewed-by: Daniel P. Berrangé <berrange@redhat.com> Message-id: 20230111080101.969151-3-marcandre.lureau@redhat.com Signed-off-by: John Snow <jsnow@redhat.com>
2023-01-24python/qmp/protocol: add open_with_socket()Marc-André Lureau1-5/+20
Instead of listening for incoming connections with a SocketAddr, add a new method open_with_socket() that accepts an existing socket. Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com> Reviewed-by: Daniel P. Berrangé <berrange@redhat.com> Message-id: 20230111080101.969151-2-marcandre.lureau@redhat.com Signed-off-by: John Snow <jsnow@redhat.com>
2023-01-24python/qmp: increase read buffer sizeMaksim Davydov1-2/+2
Current 256KB is not enough for some real cases. As a possible solution limit can be chosen to be the same as libvirt (10MB) Signed-off-by: Maksim Davydov <davydov-max@yandex-team.ru> Reviewed-by: John Snow <jsnow@redhat.com> Message-id: 20230112152805.33109-3-davydov-max@yandex-team.ru Signed-off-by: John Snow <jsnow@redhat.com>
2023-01-24python/machine: Fix AF_UNIX path too long on macOSPeter Delevoryas1-3/+3
On macOS, private $TMPDIR's are the default. These $TMPDIR's are generated from a user's unix UID and UUID [1], which can create a relatively long path: /var/folders/d7/rz20f6hd709c1ty8f6_6y_z40000gn/T/ QEMU's avocado tests create a temporary directory prefixed by "avo_qemu_sock_", and create QMP sockets within _that_ as well. The QMP socket is unnecessarily long, because a temporary directory is created for every QEMUMachine object. /avo_qemu_sock_uh3w_dgc/qemu-37331-10bacf110-monitor.sock The path limit for unix sockets on macOS is 104: [2] /* * [XSI] Definitions for UNIX IPC domain. */ struct sockaddr_un { unsigned char sun_len; /* sockaddr len including null */ sa_family_t sun_family; /* [XSI] AF_UNIX */ char sun_path[104]; /* [XSI] path name (gag) */ }; This results in avocado tests failing on macOS because the QMP unix socket can't be created, because the path is too long: ERROR| Failed to establish connection: OSError: AF_UNIX path too long This change resolves by reducing the size of the socket directory prefix and the suffix on the QMP and console socket names. The result is paths like this: pdel@pdel-mbp:/var/folders/d7/rz20f6hd709c1ty8f6_6y_z40000gn/T $ tree qemu* qemu_df4evjeq qemu_jbxel3gy qemu_ml9s_gg7 qemu_oc7h7f3u qemu_oqb1yf97 ├── 10a004050.con └── 10a004050.qmp [1] https://apple.stackexchange.com/questions/353832/why-is-mac-osx-temp-directory-in-weird-path [2] /Library/Developer/CommandLineTools/SDKs/MacOSX12.3.sdk/usr/include/sys/un.h Signed-off-by: Peter Delevoryas <peter@pjd.dev> Reviewed-by: Daniel P. Berrangé <berrange@redhat.com> Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org> Message-id: 20230110082930.42129-2-peter@pjd.dev Signed-off-by: John Snow <jsnow@redhat.com>
2023-01-24python: QEMUMachine: enable qmp accept timeout by defaultVladimir Sementsov-Ogievskiy1-1/+1
I've spent much time trying to debug hanging pipeline in gitlab. I started from and idea that I have problem in code in my series (which has some timeouts). Finally I found that the problem is that I've used QEMUMachine class directly to avoid qtest, and didn't add necessary arguments. Qemu fails and we wait for qmp accept endlessly. In gitlab it's just stopped by timeout (one hour) with no sign of what's going wrong. With timeout enabled, gitlab don't wait for an hour and prints all needed information. Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@yandex-team.ru> Reviewed-by: John Snow <jsnow@redhat.com> Message-Id: <20220624195252.175249-1-vsementsov@yandex-team.ru> [Fixed typing. --js] Signed-off-by: John Snow <jsnow@redhat.com>
2023-01-24Fix some typosDongdong Zhang4-6/+6
Fix some typos in 'python' directory. Signed-off-by: Dongdong Zhang <zhangdongdong@eswincomputing.com> Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org> Message-id: 20221130015358.6998-2-zhangdongdong@eswincomputing.com [Fixed additional typo spotted by Max Filippov. --js] Reviewed-by: John Snow <jsnow@redhat.com> Signed-off-by: John Snow <jsnow@redhat.com>
2023-01-04python: add 3.11 to supported listJohn Snow1-1/+2
Signed-off-by: John Snow <jsnow@redhat.com> Reviewed-by: Wilfred Mallawa <wilfred.mallawa@wdc.com> Message-id: 20221203005234.620788-4-jsnow@redhat.com Signed-off-by: John Snow <jsnow@redhat.com>
2023-01-04Python: fix flake8 configJohn Snow1-1/+2
Newer flake8 versions are a bit pickier about the config file, and my in-line comment confuses the parser. Fix it. Signed-off-by: John Snow <jsnow@redhat.com> Reviewed-by: Wilfred Mallawa <wilfred.mallawa@wdc.com> Message-id: 20221203005234.620788-2-jsnow@redhat.com Signed-off-by: John Snow <jsnow@redhat.com>
2023-01-04python/machine: Handle termination cases without QMPJohn Snow1-0/+6
If we request a shutdown of a VM without a QMP console, we'll just hang waiting. Not ideal. Add in code that attempts graceful termination in these cases. Tested lightly; it appears to work and I doubt we rely on this case anywhere, but it's a corner you're allowed to wedge yourself in, so it should be handled. Signed-off-by: John Snow <jsnow@redhat.com>
2023-01-04python/machine: Add debug logging to key state changesJohn Snow1-0/+25
When key decisions are made about the lifetime of the VM process being managed, there's no log entry. Juxtaposed with the very verbose runstate change logging of the QMP module, machine seems a bit too introverted now. Season the machine.py module with logging statements to taste to help make a tastier soup. Signed-off-by: John Snow <jsnow@redhat.com>
2022-08-01misc: fix commonly doubled up wordsDaniel P. Berrangé2-2/+2
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com> Message-Id: <20220707163720.1421716-5-berrange@redhat.com> Reviewed-by: Peter Maydell <peter.maydell@linaro.org> Signed-off-by: Thomas Huth <thuth@redhat.com>
2022-07-18python/qemu/qmp/legacy: Replace 'returns-whitelist' with the correct typeThomas Huth1-1/+1
'returns-whitelist' has been renamed to 'command-returns-exceptions' in commit b86df3747848 ("qapi: Rename pragma *-whitelist to *-exceptions"). Message-Id: <20220711095721.61280-1-thuth@redhat.com> Reviewed-by: John Snow <jsnow@redhat.com> Signed-off-by: Thomas Huth <thuth@redhat.com>
2022-06-08Fix 'writeable' typosPeter Maydell1-1/+1
We have about 30 instances of the typo/variant spelling 'writeable', and over 500 of the more common 'writable'. Standardize on the latter. Change produced with: sed -i -e 's/\([Ww][Rr][Ii][Tt]\)[Ee]\([Aa][Bb][Ll][Ee]\)/\1\2/g' $(git grep -il writeable) and then hand-undoing the instance in linux-headers/linux/kvm.h. Most of these changes are in comments or documentation; the exceptions are: * a local variable in accel/hvf/hvf-accel-ops.c * a local variable in accel/kvm/kvm-all.c * the PMCR_WRITABLE_MASK macro in target/arm/internals.h * the EPT_VIOLATION_GPA_WRITABLE macro in target/i386/hvf/vmcs.h (which is never used anywhere) * the AR_TYPE_WRITABLE_MASK macro in target/i386/hvf/vmx.h (which is never used anywhere) Signed-off-by: Peter Maydell <peter.maydell@linaro.org> Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org> Reviewed-by: Stefan Weil <sw@weilnetz.de> Message-id: 20220505095015.2714666-1-peter.maydell@linaro.org
2022-06-06python: update for mypy 0.950John Snow2-1/+4
typeshed (included in mypy) recently updated to improve the typing for WriteTransport objects. I was working around this, but now there's a version where I shouldn't work around it. Unfortunately this creates some minor ugliness if I want to support both pre- and post-0.950 versions. For now, for my sanity, just disable the unused-ignores warning. Signed-off-by: John Snow <jsnow@redhat.com> Reviewed-by: Paolo Bonzini <pbonzini@redhat.com> Message-Id: <20220526000921.1581503-2-jsnow@redhat.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2022-04-21python/qmp: remove pylint workaround from legacy.pyJohn Snow1-2/+0
Pylint upgraded recently (2.13.z) and having a pylint: disable comment in the middle of an argument field causes it some grief (It appears to stop parsing when it encounters it, causing some syntax problems). Since the duplicate line threshold was bumped up in 22305c2a081b, we don't need this workaround anymore. Drop it. Signed-off-by: John Snow <jsnow@redhat.com> Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@openvz.org> Message-id: 20220330172812.3427355-10-jsnow@redhat.com Signed-off-by: John Snow <jsnow@redhat.com>
2022-04-21python: rename 'aqmp-tui' to 'qmp-tui'John Snow2-9/+9
This is the last vestige of the "aqmp" moniker surviving in the tree; remove it. Signed-off-by: John Snow <jsnow@redhat.com> Reviewed-by: Beraldo Leal <bleal@redhat.com> Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@openvz.org> Message-id: 20220330172812.3427355-9-jsnow@redhat.com Signed-off-by: John Snow <jsnow@redhat.com>
2022-04-21python: rename qemu.aqmp to qemu.qmpJohn Snow22-60/+60
Now that we are fully switched over to the new QMP library, move it back over the old namespace. This is being done primarily so that we may upload this package simply as "qemu.qmp" without introducing confusion over whether or not "aqmp" is a new protocol or not. The trade-off is increased confusion inside the QEMU developer tree. Sorry! Note: the 'private' member "_aqmp" in legacy.py also changes to "_qmp"; not out of necessity, but just to remove any traces of the "aqmp" name. Signed-off-by: John Snow <jsnow@redhat.com> Reviewed-by: Beraldo Leal <bleal@redhat.com> Acked-by: Hanna Reitz <hreitz@redhat.com> Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@openvz.org> Message-id: 20220330172812.3427355-8-jsnow@redhat.com Signed-off-by: John Snow <jsnow@redhat.com>
2022-04-21python: re-enable pylint duplicate-code warningsJohn Snow1-1/+0
With the old library gone, there's nothing duplicated in the tree, so the warning suppression can be removed. Signed-off-by: John Snow <jsnow@redhat.com> Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com> Reviewed-by: Beraldo Leal <bleal@redhat.com> Message-id: 20220330172812.3427355-7-jsnow@redhat.com Signed-off-by: John Snow <jsnow@redhat.com>
2022-04-21python: remove the old QMP packageJohn Snow6-410/+4
Thank you for your service! Signed-off-by: John Snow <jsnow@redhat.com> Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com> Reviewed-by: Beraldo Leal <bleal@redhat.com> Message-id: 20220330172812.3427355-6-jsnow@redhat.com Signed-off-by: John Snow <jsnow@redhat.com>
2022-04-21python/aqmp: copy qmp docstrings to qemu.aqmp.legacyJohn Snow1-8/+90
Copy the docstrings out of qemu.qmp, adjusting them as necessary to more accurately reflect the current state of this class. (Licensing: This is copying and modifying GPLv2-only licensed docstrings into a GPLv2-only file.) Signed-off-by: John Snow <jsnow@redhat.com> Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com> Reviewed-by: Beraldo Leal <bleal@redhat.com> Message-id: 20220330172812.3427355-5-jsnow@redhat.com Signed-off-by: John Snow <jsnow@redhat.com>
2022-04-21python/aqmp: fully separate from qmp.QEMUMonitorProtocolJohn Snow1-6/+31
After this patch, qemu.aqmp.legacy.QEMUMonitorProtocol no longer inherits from qemu.qmp.QEMUMonitorProtocol. To do this, several inherited methods need to be explicitly re-defined. (Licensing: This is copying and modifying GPLv2-only code into a GPLv2-only file.) Signed-off-by: John Snow <jsnow@redhat.com> Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com> Reviewed-by: Beraldo Leal <bleal@redhat.com> Message-id: 20220330172812.3427355-4-jsnow@redhat.com Signed-off-by: John Snow <jsnow@redhat.com>
2022-04-21python/aqmp: take QMPBadPortError and parse_address from qemu.qmpJohn Snow3-32/+27
Shift these definitions over from the qmp package to the async qmp package. (Licensing: this is a lateral move, from GPLv2 (only) to GPLv2 (only)) Signed-off-by: John Snow <jsnow@redhat.com> Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com> Reviewed-by: Beraldo Leal <bleal@redhat.com> Message-id: 20220330172812.3427355-3-jsnow@redhat.com Signed-off-by: John Snow <jsnow@redhat.com>
2022-04-21python: temporarily silence pylint duplicate-code warningsJohn Snow1-0/+1
The next several commits copy some code from qemu.qmp to qemu.aqmp, then delete qemu.qmp. In the interim, to prevent test failures, the duplicate code detection needs to be silenced to prevent bisect problems with CI testing. Signed-off-by: John Snow <jsnow@redhat.com> Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com> Message-id: 20220330172812.3427355-2-jsnow@redhat.com Signed-off-by: John Snow <jsnow@redhat.com>
2022-04-21python/aqmp-tui: relicense as LGPLv2+John Snow1-1/+1
aqmp-tui, the async QMP text user interface tool, is presently licensed as GPLv2+. I intend to include this tool as an add-on to an LGPLv2+ library package hosted on PyPI.org. I've selected LGPLv2+ to maximize compatibility with other licenses while retaining a copyleft license. To keep licensing matters simple, I'd like to relicense this tool as LGPLv2+ as well in order to keep the resultant license of the hosted release files simple -- even if library users won't "link against" this command line tool. Therefore, I am asking permission to loosen the license. Niteesh is effectively the sole author of this code, with scattered lines from myself. Signed-off-by: John Snow <jsnow@redhat.com> Reviewed-by: G S Niteesh Babu <niteesh.gs@gmail.com> Message-id: 20220325200438.2556381-5-jsnow@redhat.com Signed-off-by: John Snow <jsnow@redhat.com>
2022-04-21python/qmp-shell: relicense as LGPLv2+John Snow1-3/+4
qmp-shell is presently licensed as GPLv2 (only). I intend to include this tool as an add-on to an LGPLv2+ library package hosted on PyPI.org. I've selected LGPLv2+ to maximize compatibility with other licenses while retaining a copyleft license. To keep licensing matters simple, I'd like to relicense this tool as LGPLv2+ as well in order to keep the resultant license of the hosted release files simple -- even if library users won't "link against" this command line tool. Therefore, I am asking permission from the current authors of this tool to loosen the license. At present, those people are: - John Snow (me!), 411/609 - Luiz Capitulino, Author, 97/609 - Daniel Berrangé, 81/609 - Eduardo Habkost, 10/609 - Marc-André Lureau, 6/609 - Fam Zheng, 3/609 - Cleber Rosa, 1/609 (All of which appear to have been written under redhat.com addresses.) Eduardo's fixes are largely automated from 2to3 conversion tools and may not necessarily constitute authorship, but his signature would put to rest any questions. Cleber's changes concern a single import statement change. Also won't hurt to ask. Signed-off-by: John Snow <jsnow@redhat.com> Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com> Acked-by: Fam Zheng <fam@euphon.net> Acked-by: Luiz Capitulino <lcapitulino@redhat.com> Acked-by: Eduardo Habkost <eduardo@habkost.net> Acked-by: Daniel P. Berrangé <berrange@redhat.com> Acked-by: Cleber Rosa <crosa@redhat.com> Message-id: 20220325200438.2556381-4-jsnow@redhat.com Signed-off-by: John Snow <jsnow@redhat.com>
2022-04-21python/aqmp: relicense as LGPLv2+John Snow1-3/+3
I am the sole author of all of the async QMP code (python/qemu/aqmp) with the following exceptions: python/qemu/aqmp/qmp_shell.py and python/qemu/aqmp/legacy.py were written by Luiz Capitulino (et al) and are already licensed separately as GPLv2 (only). aqmp_tui.py was written by Niteesh Babu G S and is licensed as GPLv2+. I wish to relicense as LGPLv2+ in order to provide as much flexibility as I reasonably can, while retaining a copyleft license. It is my belief that LGPLv2+ is a suitable license for the Python ecosystem that aligns with the goals and philosophy of the QEMU project. The intent is to eventually drop legacy.py, leaving only library code that is LGPLv2+. Signed-off-by: John Snow <jsnow@redhat.com> Message-id: 20220325200438.2556381-3-jsnow@redhat.com Signed-off-by: John Snow <jsnow@redhat.com>
2022-04-21python/aqmp: add explicit GPLv2 license to legacy.pyJohn Snow1-0/+11
The legacy.py module is heavily based on the QMP module by Luiz Capitulino (et al) which is licensed as explicit GPLv2-only. The async QMP package is currently licensed similarly, but I intend to relicense the async package to the more flexible LGPLv2+. In preparation for that change, make the license on legacy.py explicit. Signed-off-by: John Snow <jsnow@redhat.com> Message-id: 20220325200438.2556381-2-jsnow@redhat.com Signed-off-by: John Snow <jsnow@redhat.com>
2022-04-21python/machine: permanently switch to AQMPJohn Snow2-12/+8
Remove the QEMU_PYTHON_LEGACY_QMP environment variable, making the switch from sync qmp to async qmp permanent. Update exceptions and import paths as necessary. Signed-off-by: John Snow <jsnow@redhat.com> Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com> Reviewed-by: Beraldo Leal <bleal@redhat.com> Acked-by: Hanna Reitz <hreitz@redhat.com> Message-id: 20220321203315.909411-2-jsnow@redhat.com Signed-off-by: John Snow <jsnow@redhat.com>
2022-03-22python/utils: add VerboseProcessErrorJohn Snow1-0/+39
This adds an Exception that extends the Python stdlib subprocess.CalledProcessError. The difference is that the str() method of this exception also adds the stdout/stderr logs. In effect, if this exception goes unhandled, Python will print the output in a visually distinct wrapper to the terminal so that it's easy to spot in a sea of traceback information. Signed-off-by: John Snow <jsnow@redhat.com> Reviewed-by: Eric Blake <eblake@redhat.com> Reviewed-by: Hanna Reitz <hreitz@redhat.com> Message-Id: <20220321201618.903471-3-jsnow@redhat.com> Signed-off-by: Hanna Reitz <hreitz@redhat.com>
2022-03-22python/utils: add add_visual_margin() text decoration utilityJohn Snow1-0/+78
>>> print(add_visual_margin(msg, width=72, name="Commit Message")) ┏━ Commit Message ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ ┃ add_visual_margin() takes a chunk of text and wraps it in a visual ┃ container that force-wraps to a specified width. An optional title ┃ label may be given, and any of the individual glyphs used to draw the ┃ box may be replaced or specified as well. ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ Signed-off-by: John Snow <jsnow@redhat.com> Reviewed-by: Eric Blake <eblake@redhat.com> Acked-by: Hanna Reitz <hreitz@redhat.com> Message-Id: <20220321201618.903471-2-jsnow@redhat.com> Signed-off-by: Hanna Reitz <hreitz@redhat.com>
2022-03-07python/aqmp: drop _bind_hack()John Snow2-39/+4
_bind_hack() was a quick fix to allow async QMP to call bind(2) prior to calling listen(2) and accept(2). This wasn't sufficient to fully address the race condition present in synchronous clients. With the race condition in legacy.py fixed (see the previous commit), there are no longer any users of _bind_hack(). Drop it. Fixes: b0b662bb2b3 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-11-jsnow@redhat.com [Expanded commit message. --js] Signed-off-by: John Snow <jsnow@redhat.com>
2022-03-07python/aqmp: fix race condition in legacy.pyJohn Snow1-5/+2
legacy.py provides a synchronous model. iotests frequently uses this paradigm: - create QMP client object - start QEMU process - await connection from QEMU process In the switch from sync to async QMP, the QMP client object stopped calling bind() and listen() during the QMP object creation step, which creates a race condition if the QEMU process dials in too quickly. With refactoring out of the way, restore the former behavior of calling bind() and listen() during __init__() to fix this race condition. 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-10-jsnow@redhat.com [Expanded commit message. --js] Signed-off-by: John Snow <jsnow@redhat.com>
2022-03-07python/aqmp: add start_server() and accept() methodsJohn Snow2-5/+69
Add start_server() and accept() methods that can be used instead of start_server_and_accept() to allow more fine-grained control over the incoming connection process. (Eagle-eyed reviewers will surely notice that it's a bit weird that "CONNECTING" is a state that's shared between both the start_server() and connect() states. That's absolutely true, and it's very true that checking on the presence of _accepted as an indicator of state is a hack. That's also very certainly true. But ... this keeps client code an awful lot simpler, as it doesn't have to care exactly *how* the connection is being made, just that it *is*. Is it worth disrupting that simplicity in order to provide a better state guard on `accept()`? Hm.) 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-9-jsnow@redhat.com Signed-off-by: John Snow <jsnow@redhat.com>
2022-03-07python/aqmp: stop the server during disconnect()John Snow1-1/+5
Before we allow the full separation of starting the server and accepting new connections, make sure that the disconnect cleans up the server and its new state, too. 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-8-jsnow@redhat.com Signed-off-by: John Snow <jsnow@redhat.com>
2022-03-07python/aqmp: refactor _do_accept() into two distinct stepsJohn Snow2-7/+26
Refactor _do_accept() into _do_start_server() and _do_accept(). As of this commit, the former calls the latter, but in subsequent commits they'll be split apart. (So please forgive the misnomer for _do_start_server(); it will live up to its name shortly, and the docstring will be updated then too. I'm just cutting down on some churn.) 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-7-jsnow@redhat.com Signed-off-by: John Snow <jsnow@redhat.com>
2022-03-07python/aqmp: squelch pylint warning for too many linesJohn Snow1-0/+3
I would really like to keep this under 1000 lines, I promise. Doesn't look like it's gonna happen. 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-6-jsnow@redhat.com Signed-off-by: John Snow <jsnow@redhat.com>
2022-03-07python/aqmp: split _client_connected_cb() out as _incoming()John Snow1-25/+58
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>
2022-03-07python/aqmp: remove _new_session and _establish_connectionJohn Snow2-74/+53
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>
2022-03-07python/aqmp: rename 'accept()' to 'start_server_and_accept()'John Snow3-15/+17
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>
2022-03-07python/aqmp: add _session_guard()John Snow1-27/+62
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>