From patchwork Mon Mar 21 21:08:38 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: John Snow X-Patchwork-Id: 12787782 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id B2104C433EF for ; Mon, 21 Mar 2022 21:10:41 +0000 (UTC) Received: from localhost ([::1]:58858 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1nWPIW-00052P-9d for qemu-devel@archiver.kernel.org; Mon, 21 Mar 2022 17:10:40 -0400 Received: from eggs.gnu.org ([209.51.188.92]:45278) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1nWPGo-0002Jb-EH for qemu-devel@nongnu.org; Mon, 21 Mar 2022 17:08:54 -0400 Received: from us-smtp-delivery-124.mimecast.com ([170.10.129.124]:23836) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1nWPGm-0006Oq-So for qemu-devel@nongnu.org; Mon, 21 Mar 2022 17:08:54 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1647896932; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=Lc26QvUYuD/ggpnziqYCPZkStalesLBBtLlXQ42K8Ks=; b=QfX3tA3+qK1kvaoABHyEqVUzWbbVBhOt03/N6piVIluF9lmeSc/CBWZ4/eHowACDM3AqJ0 RuVl0yFu74qM3UoSfMhrzsB6o5gCKf49OiT5MUHfWwHccuiedx7jTmhktB5QzA07NmJ9lT b1VCUvaCxg2Tx0wf5wBF32RYB25Jn/A= Received: from mimecast-mx02.redhat.com (mx3-rdu2.redhat.com [66.187.233.73]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-3-sx9eWq7wOZ2yMEK_MGEWLQ-1; Mon, 21 Mar 2022 17:08:49 -0400 X-MC-Unique: sx9eWq7wOZ2yMEK_MGEWLQ-1 Received: from smtp.corp.redhat.com (int-mx03.intmail.prod.int.rdu2.redhat.com [10.11.54.3]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id B61081C05AF2; Mon, 21 Mar 2022 21:08:48 +0000 (UTC) Received: from scv.redhat.com (unknown [10.22.16.64]) by smtp.corp.redhat.com (Postfix) with ESMTP id 5E12C1121314; Mon, 21 Mar 2022 21:08:48 +0000 (UTC) From: John Snow To: qemu-devel@nongnu.org Subject: [PATCH 01/10] python/aqmp: add explicit GPLv2 license to legacy.py Date: Mon, 21 Mar 2022 17:08:38 -0400 Message-Id: <20220321210847.914787-2-jsnow@redhat.com> In-Reply-To: <20220321210847.914787-1-jsnow@redhat.com> References: <20220321210847.914787-1-jsnow@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.78 on 10.11.54.3 Authentication-Results: relay.mimecast.com; auth=pass smtp.auth=CUSA124A263 smtp.mailfrom=jsnow@redhat.com X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Received-SPF: pass client-ip=170.10.129.124; envelope-from=jsnow@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -21 X-Spam_score: -2.2 X-Spam_bar: -- X-Spam_report: (-2.2 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.082, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H4=0.001, RCVD_IN_MSPIKE_WL=0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001, T_SCC_BODY_TEXT_LINE=-0.01 autolearn=unavailable autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Kevin Wolf , Vladimir Sementsov-Ogievskiy , Beraldo Leal , qemu-block@nongnu.org, Markus Armbruster , Hanna Reitz , Cleber Rosa , John Snow Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: "Qemu-devel" 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 GPLv2+. In preparation for that change, make the license on legacy.py explicit. Signed-off-by: John Snow --- python/qemu/aqmp/legacy.py | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/python/qemu/aqmp/legacy.py b/python/qemu/aqmp/legacy.py index 46026e9fdc..f86cb29804 100644 --- a/python/qemu/aqmp/legacy.py +++ b/python/qemu/aqmp/legacy.py @@ -4,6 +4,17 @@ This class pretends to be qemu.qmp.QEMUMonitorProtocol. """ +# +# Copyright (C) 2009-2022 Red Hat Inc. +# +# Authors: +# Luiz Capitulino +# John Snow +# +# This work is licensed under the terms of the GNU GPL, version 2. See +# the COPYING file in the top-level directory. +# + import asyncio from typing import ( Any, From patchwork Mon Mar 21 21:08:39 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: John Snow X-Patchwork-Id: 12787786 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id B332CC433EF for ; Mon, 21 Mar 2022 21:13:51 +0000 (UTC) Received: from localhost ([::1]:39850 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1nWPLa-0002rs-Nb for qemu-devel@archiver.kernel.org; Mon, 21 Mar 2022 17:13:50 -0400 Received: from eggs.gnu.org ([209.51.188.92]:45276) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1nWPGp-0002Ja-MO for qemu-devel@nongnu.org; Mon, 21 Mar 2022 17:08:55 -0400 Received: from us-smtp-delivery-124.mimecast.com ([170.10.133.124]:34839) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1nWPGm-0006Oi-Cq for qemu-devel@nongnu.org; Mon, 21 Mar 2022 17:08:54 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1647896931; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=+UAlWaiiO9GDCpJFqS1hhFGf5shB3KchWo7krY0FEKA=; b=Zf+fzAEpR95UnwJp08XrTf5hkwXfOyclCnHh6eg2gIH0bK77hEyH1x2+ln8Ay53apGw29p RxHkdlDyn68KZVtXfZ5lKTaxDuuo5hyFNyqtpf2I18/bY+AXDQMNOMev4RV0tHbH9aSVPg kKM4NRV/OKLrOBQM1tcg/4KSuGTzv28= Received: from mimecast-mx02.redhat.com (mx3-rdu2.redhat.com [66.187.233.73]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-546-SWeNdj7BOriqWKRe0IQ7Pw-1; Mon, 21 Mar 2022 17:08:50 -0400 X-MC-Unique: SWeNdj7BOriqWKRe0IQ7Pw-1 Received: from smtp.corp.redhat.com (int-mx03.intmail.prod.int.rdu2.redhat.com [10.11.54.3]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id 281321C05AFF; Mon, 21 Mar 2022 21:08:50 +0000 (UTC) Received: from scv.redhat.com (unknown [10.22.16.64]) by smtp.corp.redhat.com (Postfix) with ESMTP id C549E1121314; Mon, 21 Mar 2022 21:08:48 +0000 (UTC) From: John Snow To: qemu-devel@nongnu.org Subject: [PATCH 02/10] python/aqmp: relicense as GPLv2+ Date: Mon, 21 Mar 2022 17:08:39 -0400 Message-Id: <20220321210847.914787-3-jsnow@redhat.com> In-Reply-To: <20220321210847.914787-1-jsnow@redhat.com> References: <20220321210847.914787-1-jsnow@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.78 on 10.11.54.3 Authentication-Results: relay.mimecast.com; auth=pass smtp.auth=CUSA124A263 smtp.mailfrom=jsnow@redhat.com X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Received-SPF: pass client-ip=170.10.133.124; envelope-from=jsnow@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -21 X-Spam_score: -2.2 X-Spam_bar: -- X-Spam_report: (-2.2 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.082, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H5=0.001, RCVD_IN_MSPIKE_WL=0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001, T_SCC_BODY_TEXT_LINE=-0.01 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Kevin Wolf , Vladimir Sementsov-Ogievskiy , Beraldo Leal , qemu-block@nongnu.org, Markus Armbruster , Hanna Reitz , Cleber Rosa , John Snow Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: "Qemu-devel" 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 already licensed as GPLv2+. I wish to relicense as GPLv2+ in order to provide as much flexibility as I reasonably can, while retaining a strong copyleft license. It is my belief that GPLv2+ is a suitable license for the Python ecosystem that aligns with the goals and philosophy of the QEMU project. Signed-off-by: John Snow --- python/qemu/aqmp/__init__.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/python/qemu/aqmp/__init__.py b/python/qemu/aqmp/__init__.py index 4c22c38079..2e4478ac05 100644 --- a/python/qemu/aqmp/__init__.py +++ b/python/qemu/aqmp/__init__.py @@ -11,15 +11,15 @@ managing QMP events. """ -# Copyright (C) 2020, 2021 John Snow for Red Hat, Inc. +# Copyright (C) 2020-2022 John Snow for Red Hat, Inc. # # Authors: # John Snow # # Based on earlier work by Luiz Capitulino . # -# This work is licensed under the terms of the GNU GPL, version 2. See -# the COPYING file in the top-level directory. +# This work is licensed under the terms of the GNU GPL, version 2 or +# later. See the COPYING file in the top-level directory. import logging From patchwork Mon Mar 21 21:08:40 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: John Snow X-Patchwork-Id: 12787783 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 3B959C433EF for ; Mon, 21 Mar 2022 21:10:50 +0000 (UTC) Received: from localhost ([::1]:59734 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1nWPIf-0005cR-7u for qemu-devel@archiver.kernel.org; Mon, 21 Mar 2022 17:10:49 -0400 Received: from eggs.gnu.org ([209.51.188.92]:45332) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1nWPGp-0002KP-UX for qemu-devel@nongnu.org; Mon, 21 Mar 2022 17:08:55 -0400 Received: from us-smtp-delivery-124.mimecast.com ([170.10.129.124]:26176) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1nWPGn-0006PC-Rt for qemu-devel@nongnu.org; Mon, 21 Mar 2022 17:08:55 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1647896933; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=3Rh2PqKLn1WtX5VPupoQMBse2oAT2O3EOfDswiXPVQY=; b=Q27MV8eNCMnZsm9NCcq/msb1Mw058mjjWR2b2JDJqHns7KrUlxG0ezgCEFUapbzRiaBNTS tm3nctnEh+uWNCSRXIEZzrYYzkVWJj8LQ704CiGmRHmZgkTdD0zZbk7On3Bgyh5nKxEUTw dEVVpzohUqrXZO7xaxlZD3PhcpmlI1g= Received: from mimecast-mx02.redhat.com (mimecast-mx02.redhat.com [66.187.233.88]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-19-2j1UfxlXMpqN_7GhLSjOuA-1; Mon, 21 Mar 2022 17:08:49 -0400 X-MC-Unique: 2j1UfxlXMpqN_7GhLSjOuA-1 Received: from smtp.corp.redhat.com (int-mx03.intmail.prod.int.rdu2.redhat.com [10.11.54.3]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id 8CBDA899EC2; Mon, 21 Mar 2022 21:08:49 +0000 (UTC) Received: from scv.redhat.com (unknown [10.22.16.64]) by smtp.corp.redhat.com (Postfix) with ESMTP id 37E331121321; Mon, 21 Mar 2022 21:08:49 +0000 (UTC) From: John Snow To: qemu-devel@nongnu.org Subject: [PATCH 03/10] python: temporarily silence pylint duplicate-code warnings Date: Mon, 21 Mar 2022 17:08:40 -0400 Message-Id: <20220321210847.914787-4-jsnow@redhat.com> In-Reply-To: <20220321210847.914787-1-jsnow@redhat.com> References: <20220321210847.914787-1-jsnow@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.78 on 10.11.54.3 Authentication-Results: relay.mimecast.com; auth=pass smtp.auth=CUSA124A263 smtp.mailfrom=jsnow@redhat.com X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Received-SPF: pass client-ip=170.10.129.124; envelope-from=jsnow@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -21 X-Spam_score: -2.2 X-Spam_bar: -- X-Spam_report: (-2.2 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.082, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H4=0.001, RCVD_IN_MSPIKE_WL=0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001, T_SCC_BODY_TEXT_LINE=-0.01 autolearn=unavailable autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Kevin Wolf , Vladimir Sementsov-Ogievskiy , Beraldo Leal , qemu-block@nongnu.org, Markus Armbruster , Hanna Reitz , Cleber Rosa , John Snow Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: "Qemu-devel" 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 Reviewed-by: Vladimir Sementsov-Ogievskiy --- python/setup.cfg | 1 + 1 file changed, 1 insertion(+) diff --git a/python/setup.cfg b/python/setup.cfg index 241f243e8b..cdeced44d2 100644 --- a/python/setup.cfg +++ b/python/setup.cfg @@ -119,6 +119,7 @@ disable=consider-using-f-string, too-many-function-args, # mypy handles this with less false positives. too-many-instance-attributes, no-member, # mypy also handles this better. + duplicate-code, # To be removed by the end of this patch series. [pylint.basic] # Good variable names which should always be accepted, separated by a comma. From patchwork Mon Mar 21 21:08:41 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: John Snow X-Patchwork-Id: 12787785 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 2AC89C433F5 for ; Mon, 21 Mar 2022 21:10:53 +0000 (UTC) Received: from localhost ([::1]:59850 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1nWPIi-0005ii-8o for qemu-devel@archiver.kernel.org; Mon, 21 Mar 2022 17:10:52 -0400 Received: from eggs.gnu.org ([209.51.188.92]:45344) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1nWPGq-0002M4-84 for qemu-devel@nongnu.org; Mon, 21 Mar 2022 17:08:56 -0400 Received: from us-smtp-delivery-124.mimecast.com ([170.10.129.124]:41382) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1nWPGo-0006PK-0V for qemu-devel@nongnu.org; Mon, 21 Mar 2022 17:08:55 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1647896933; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=cPhW8sF+67MJRLnLSzs3HBXt2hGS4K5U20OrkkIb1DA=; b=UnSuZ2fjQBKztKRtI9+CFqiGvHu2hsv+9lEaq/FeFjr8fPUFSSxpuc0yxs/FjfAVjjxdyE DwTcAGoX3hcmFkdhrSBeXNkB2AJmmtYOux2TJ42VzRED9sa0NRyLdfJhh0AWUJimVv8itU SlIu3Zg3tMW31ufY3Cu0vzI9VUGYM1g= Received: from mimecast-mx02.redhat.com (mimecast-mx02.redhat.com [66.187.233.88]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-111-fEUPysa9PLGhgHvLrLL4xw-1; Mon, 21 Mar 2022 17:08:50 -0400 X-MC-Unique: fEUPysa9PLGhgHvLrLL4xw-1 Received: from smtp.corp.redhat.com (int-mx03.intmail.prod.int.rdu2.redhat.com [10.11.54.3]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id 00BB3811E75; Mon, 21 Mar 2022 21:08:50 +0000 (UTC) Received: from scv.redhat.com (unknown [10.22.16.64]) by smtp.corp.redhat.com (Postfix) with ESMTP id 9C8781121321; Mon, 21 Mar 2022 21:08:49 +0000 (UTC) From: John Snow To: qemu-devel@nongnu.org Subject: [PATCH 04/10] python/aqmp: take QMPBadPortError and parse_address from qemu.qmp Date: Mon, 21 Mar 2022 17:08:41 -0400 Message-Id: <20220321210847.914787-5-jsnow@redhat.com> In-Reply-To: <20220321210847.914787-1-jsnow@redhat.com> References: <20220321210847.914787-1-jsnow@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.78 on 10.11.54.3 Authentication-Results: relay.mimecast.com; auth=pass smtp.auth=CUSA124A263 smtp.mailfrom=jsnow@redhat.com X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Received-SPF: pass client-ip=170.10.129.124; envelope-from=jsnow@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -21 X-Spam_score: -2.2 X-Spam_bar: -- X-Spam_report: (-2.2 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.082, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H4=0.001, RCVD_IN_MSPIKE_WL=0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001, T_SCC_BODY_TEXT_LINE=-0.01 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Kevin Wolf , Vladimir Sementsov-Ogievskiy , Beraldo Leal , qemu-block@nongnu.org, Markus Armbruster , Hanna Reitz , Cleber Rosa , John Snow Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: "Qemu-devel" 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 Reviewed-by: Vladimir Sementsov-Ogievskiy Reviewed-by: Beraldo Leal --- python/qemu/aqmp/aqmp_tui.py | 3 +-- python/qemu/aqmp/legacy.py | 30 ++++++++++++++++++++++++++---- python/qemu/qmp/__init__.py | 26 -------------------------- 3 files changed, 27 insertions(+), 32 deletions(-) diff --git a/python/qemu/aqmp/aqmp_tui.py b/python/qemu/aqmp/aqmp_tui.py index f1e926dd75..184a3e4690 100644 --- a/python/qemu/aqmp/aqmp_tui.py +++ b/python/qemu/aqmp/aqmp_tui.py @@ -35,9 +35,8 @@ import urwid import urwid_readline -from qemu.qmp import QEMUMonitorProtocol, QMPBadPortError - from .error import ProtocolError +from .legacy import QEMUMonitorProtocol, QMPBadPortError from .message import DeserializationError, Message, UnexpectedTypeError from .protocol import ConnectError, Runstate from .qmp_client import ExecInterruptedError, QMPClient diff --git a/python/qemu/aqmp/legacy.py b/python/qemu/aqmp/legacy.py index f86cb29804..f026274949 100644 --- a/python/qemu/aqmp/legacy.py +++ b/python/qemu/aqmp/legacy.py @@ -33,9 +33,6 @@ from .qmp_client import QMPClient -# (Temporarily) Re-export QMPBadPortError -QMPBadPortError = qemu.qmp.QMPBadPortError - #: QMPMessage is an entire QMP message of any kind. QMPMessage = Dict[str, Any] @@ -56,6 +53,12 @@ # pylint: disable=missing-docstring +class QMPBadPortError(QMPError): + """ + Unable to parse socket address: Port was non-numerical. + """ + + class QEMUMonitorProtocol(qemu.qmp.QEMUMonitorProtocol): def __init__(self, address: SocketAddrT, server: bool = False, @@ -86,7 +89,26 @@ def _get_greeting(self) -> Optional[QMPMessage]: return None # __enter__ and __exit__ need no changes - # parse_address needs no changes + + @classmethod + def parse_address(cls, address: str) -> SocketAddrT: + """ + Parse a string into a QMP address. + + Figure out if the argument is in the port:host form. + If it's not, it's probably a file path. + """ + components = address.split(':') + if len(components) == 2: + try: + port = int(components[1]) + except ValueError: + msg = f"Bad port: '{components[1]}' in '{address}'." + raise QMPBadPortError(msg) from None + return (components[0], port) + + # Treat as filepath. + return address def connect(self, negotiate: bool = True) -> Optional[QMPMessage]: self._aqmp.await_greeting = negotiate diff --git a/python/qemu/qmp/__init__.py b/python/qemu/qmp/__init__.py index 358c0971d0..4e08641154 100644 --- a/python/qemu/qmp/__init__.py +++ b/python/qemu/qmp/__init__.py @@ -102,12 +102,6 @@ def __init__(self, reply: QMPMessage): self.reply = reply -class QMPBadPortError(QMPError): - """ - Unable to parse socket address: Port was non-numerical. - """ - - class QEMUMonitorProtocol: """ Provide an API to connect to QEMU via QEMU Monitor Protocol (QMP) and then @@ -237,26 +231,6 @@ def __exit__(self, # Implement context manager exit function. self.close() - @classmethod - def parse_address(cls, address: str) -> SocketAddrT: - """ - Parse a string into a QMP address. - - Figure out if the argument is in the port:host form. - If it's not, it's probably a file path. - """ - components = address.split(':') - if len(components) == 2: - try: - port = int(components[1]) - except ValueError: - msg = f"Bad port: '{components[1]}' in '{address}'." - raise QMPBadPortError(msg) from None - return (components[0], port) - - # Treat as filepath. - return address - def connect(self, negotiate: bool = True) -> Optional[QMPMessage]: """ Connect to the QMP Monitor and perform capabilities negotiation. From patchwork Mon Mar 21 21:08:42 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: John Snow X-Patchwork-Id: 12787787 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id B5110C433F5 for ; Mon, 21 Mar 2022 21:13:53 +0000 (UTC) Received: from localhost ([::1]:39966 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1nWPLc-0002wb-Pp for qemu-devel@archiver.kernel.org; Mon, 21 Mar 2022 17:13:52 -0400 Received: from eggs.gnu.org ([209.51.188.92]:45338) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1nWPGq-0002LV-2R for qemu-devel@nongnu.org; Mon, 21 Mar 2022 17:08:56 -0400 Received: from us-smtp-delivery-124.mimecast.com ([170.10.133.124]:26991) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1nWPGn-0006PA-PA for qemu-devel@nongnu.org; Mon, 21 Mar 2022 17:08:55 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1647896933; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=CnNxbzqBswk82ioPa3i+Nzp7T3FK3kKJ1gdGf2o/Yh4=; b=bawLhN1nKHdYWtUOlQWg3bPqOEsKpGRBhTF1Y0e/U3RtjpfX1KWkEV5DDDNCz6qavk6vgm oY+AY8ymBHzYycOvPvweHWPnNfMZlisR6pJmMI0d4bZHs2B3/nYCFvU2DhBl65zTeREv6X Ok2TNzNyNxH7kiO1/XXUnypBxup7NVk= Received: from mimecast-mx02.redhat.com (mimecast-mx02.redhat.com [66.187.233.88]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-364-bs3WWVJ8OL28isJM1D9_4g-1; Mon, 21 Mar 2022 17:08:50 -0400 X-MC-Unique: bs3WWVJ8OL28isJM1D9_4g-1 Received: from smtp.corp.redhat.com (int-mx03.intmail.prod.int.rdu2.redhat.com [10.11.54.3]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id 63EB380231F; Mon, 21 Mar 2022 21:08:50 +0000 (UTC) Received: from scv.redhat.com (unknown [10.22.16.64]) by smtp.corp.redhat.com (Postfix) with ESMTP id 0E3081121321; Mon, 21 Mar 2022 21:08:50 +0000 (UTC) From: John Snow To: qemu-devel@nongnu.org Subject: [PATCH 05/10] python/aqmp: fully separate from qmp.QEMUMonitorProtocol Date: Mon, 21 Mar 2022 17:08:42 -0400 Message-Id: <20220321210847.914787-6-jsnow@redhat.com> In-Reply-To: <20220321210847.914787-1-jsnow@redhat.com> References: <20220321210847.914787-1-jsnow@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.78 on 10.11.54.3 Authentication-Results: relay.mimecast.com; auth=pass smtp.auth=CUSA124A263 smtp.mailfrom=jsnow@redhat.com X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Received-SPF: pass client-ip=170.10.133.124; envelope-from=jsnow@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -21 X-Spam_score: -2.2 X-Spam_bar: -- X-Spam_report: (-2.2 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.082, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H5=0.001, RCVD_IN_MSPIKE_WL=0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001, T_SCC_BODY_TEXT_LINE=-0.01 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Kevin Wolf , Vladimir Sementsov-Ogievskiy , Beraldo Leal , qemu-block@nongnu.org, Markus Armbruster , Hanna Reitz , Cleber Rosa , John Snow Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: "Qemu-devel" 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 Reviewed-by: Vladimir Sementsov-Ogievskiy Reviewed-by: Beraldo Leal --- python/qemu/aqmp/legacy.py | 37 +++++++++++++++++++++++++++++++------ 1 file changed, 31 insertions(+), 6 deletions(-) diff --git a/python/qemu/aqmp/legacy.py b/python/qemu/aqmp/legacy.py index f026274949..10c7c99c4f 100644 --- a/python/qemu/aqmp/legacy.py +++ b/python/qemu/aqmp/legacy.py @@ -16,18 +16,18 @@ # import asyncio +from types import TracebackType from typing import ( Any, Awaitable, Dict, List, Optional, + Type, TypeVar, Union, ) -import qemu.qmp - from .error import QMPError from .protocol import Runstate, SocketAddrT from .qmp_client import QMPClient @@ -59,12 +59,11 @@ class QMPBadPortError(QMPError): """ -class QEMUMonitorProtocol(qemu.qmp.QEMUMonitorProtocol): +class QEMUMonitorProtocol: def __init__(self, address: SocketAddrT, server: bool = False, nickname: Optional[str] = None): - # pylint: disable=super-init-not-called self._aqmp = QMPClient(nickname) self._aloop = asyncio.get_event_loop() self._address = address @@ -88,7 +87,18 @@ def _get_greeting(self) -> Optional[QMPMessage]: return self._aqmp.greeting._asdict() return None - # __enter__ and __exit__ need no changes + def __enter__(self: _T) -> _T: + # Implement context manager enter function. + return self + + def __exit__(self, + # pylint: disable=duplicate-code + # see https://github.com/PyCQA/pylint/issues/3619 + exc_type: Optional[Type[BaseException]], + exc_val: Optional[BaseException], + exc_tb: Optional[TracebackType]) -> None: + # Implement context manager exit function. + self.close() @classmethod def parse_address(cls, address: str) -> SocketAddrT: @@ -142,7 +152,22 @@ def cmd_obj(self, qmp_cmd: QMPMessage) -> QMPMessage: ) ) - # Default impl of cmd() delegates to cmd_obj + def cmd(self, name: str, + args: Optional[Dict[str, object]] = None, + cmd_id: Optional[object] = None) -> QMPMessage: + """ + Build a QMP command and send it to the QMP Monitor. + + @param name: command name (string) + @param args: command arguments (dict) + @param cmd_id: command id (dict, list, string or int) + """ + qmp_cmd: QMPMessage = {'execute': name} + if args: + qmp_cmd['arguments'] = args + if cmd_id: + qmp_cmd['id'] = cmd_id + return self.cmd_obj(qmp_cmd) def command(self, cmd: str, **kwds: object) -> QMPReturnValue: return self._sync( From patchwork Mon Mar 21 21:08:43 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: John Snow X-Patchwork-Id: 12787788 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 335DAC433EF for ; Mon, 21 Mar 2022 21:14:04 +0000 (UTC) Received: from localhost ([::1]:41032 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1nWPLn-0003f2-Ai for qemu-devel@archiver.kernel.org; Mon, 21 Mar 2022 17:14:03 -0400 Received: from eggs.gnu.org ([209.51.188.92]:45460) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1nWPGt-0002VU-Hp for qemu-devel@nongnu.org; Mon, 21 Mar 2022 17:08:59 -0400 Received: from us-smtp-delivery-124.mimecast.com ([170.10.129.124]:20406) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1nWPGq-0006R2-S3 for qemu-devel@nongnu.org; Mon, 21 Mar 2022 17:08:59 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1647896936; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=LMLkPlbq1PsL4QiS159ja+HX/uSWiDyTAnlrh5F8cp0=; b=BBmklbM+gZ+EKIwdsRmydzEY1wkqGW1np9WGf25g6f+Lw0OMooiiNWq4RtD8nKR+HJabDi hB9h/RQ/LTUnQQou6rxSDPlnoW3OFRe8ssdUWisuyJLKtMOwcq6772DaKDrMRMzuGDFEr4 oDFRuElA1tZqcKPbO+aAEhiVaVRQB8o= Received: from mimecast-mx02.redhat.com (mx3-rdu2.redhat.com [66.187.233.73]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-467-Y8oFCyNSMh2rfTLipJ-BOg-1; Mon, 21 Mar 2022 17:08:51 -0400 X-MC-Unique: Y8oFCyNSMh2rfTLipJ-BOg-1 Received: from smtp.corp.redhat.com (int-mx03.intmail.prod.int.rdu2.redhat.com [10.11.54.3]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id CB51F3804061; Mon, 21 Mar 2022 21:08:50 +0000 (UTC) Received: from scv.redhat.com (unknown [10.22.16.64]) by smtp.corp.redhat.com (Postfix) with ESMTP id 715101121314; Mon, 21 Mar 2022 21:08:50 +0000 (UTC) From: John Snow To: qemu-devel@nongnu.org Subject: [PATCH 06/10] python/aqmp: copy qmp docstrings to qemu.aqmp.legacy Date: Mon, 21 Mar 2022 17:08:43 -0400 Message-Id: <20220321210847.914787-7-jsnow@redhat.com> In-Reply-To: <20220321210847.914787-1-jsnow@redhat.com> References: <20220321210847.914787-1-jsnow@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.78 on 10.11.54.3 Authentication-Results: relay.mimecast.com; auth=pass smtp.auth=CUSA124A263 smtp.mailfrom=jsnow@redhat.com X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Received-SPF: pass client-ip=170.10.129.124; envelope-from=jsnow@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -21 X-Spam_score: -2.2 X-Spam_bar: -- X-Spam_report: (-2.2 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.082, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H4=0.001, RCVD_IN_MSPIKE_WL=0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001, T_SCC_BODY_TEXT_LINE=-0.01 autolearn=unavailable autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Kevin Wolf , Vladimir Sementsov-Ogievskiy , Beraldo Leal , qemu-block@nongnu.org, Markus Armbruster , Hanna Reitz , Cleber Rosa , John Snow Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: "Qemu-devel" 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 Reviewed-by: Vladimir Sementsov-Ogievskiy Reviewed-by: Beraldo Leal --- python/qemu/aqmp/legacy.py | 102 ++++++++++++++++++++++++++++++++++--- 1 file changed, 94 insertions(+), 8 deletions(-) diff --git a/python/qemu/aqmp/legacy.py b/python/qemu/aqmp/legacy.py index 10c7c99c4f..20ffdd8956 100644 --- a/python/qemu/aqmp/legacy.py +++ b/python/qemu/aqmp/legacy.py @@ -1,7 +1,13 @@ """ -Sync QMP Wrapper +(Legacy) Sync QMP Wrapper -This class pretends to be qemu.qmp.QEMUMonitorProtocol. +This module provides the `QEMUMonitorProtocol` class, which is a +synchronous wrapper around `QMPClient`. + +Its design closely resembles that of the original QEMUMonitorProtocol +class, originally written by Luiz Capitulino. It is provided here for +compatibility with scripts inside the QEMU source tree that expect the +old interface. """ # @@ -50,9 +56,6 @@ # {} is the QMPReturnValue. -# pylint: disable=missing-docstring - - class QMPBadPortError(QMPError): """ Unable to parse socket address: Port was non-numerical. @@ -60,6 +63,21 @@ class QMPBadPortError(QMPError): 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 + :param server: Deprecated, ignored. (See 'accept') + :param nickname: Optional nickname used for logging. + + ..note:: + No connection is established during `__init__`, this is done by + the `connect()` or `accept()` methods. + """ + def __init__(self, address: SocketAddrT, server: bool = False, nickname: Optional[str] = None): @@ -121,6 +139,12 @@ def parse_address(cls, address: str) -> SocketAddrT: return address def connect(self, negotiate: bool = True) -> Optional[QMPMessage]: + """ + Connect to the QMP Monitor and perform capabilities negotiation. + + :return: QMP greeting dict, or None if negotiate is false + :raise ConnectError: on connection errors + """ self._aqmp.await_greeting = negotiate self._aqmp.negotiate = negotiate @@ -130,6 +154,16 @@ def connect(self, negotiate: bool = True) -> Optional[QMPMessage]: return self._get_greeting() def accept(self, timeout: Optional[float] = 15.0) -> QMPMessage: + """ + Await connection from QMP Monitor and perform capabilities negotiation. + + :param timeout: + timeout in seconds (nonnegative float number, or None). + If None, there is no timeout, and this may block forever. + + :return: QMP greeting dict + :raise ConnectError: on connection errors + """ self._aqmp.await_greeting = True self._aqmp.negotiate = True @@ -140,6 +174,12 @@ def accept(self, timeout: Optional[float] = 15.0) -> QMPMessage: return ret def cmd_obj(self, qmp_cmd: QMPMessage) -> QMPMessage: + """ + Send a QMP command to the QMP Monitor. + + :param qmp_cmd: QMP command to be sent as a Python dict + :return: QMP response as a Python dict + """ return dict( self._sync( # pylint: disable=protected-access @@ -158,9 +198,9 @@ def cmd(self, name: str, """ Build a QMP command and send it to the QMP Monitor. - @param name: command name (string) - @param args: command arguments (dict) - @param cmd_id: command id (dict, list, string or int) + :param name: command name (string) + :param args: command arguments (dict) + :param cmd_id: command id (dict, list, string or int) """ qmp_cmd: QMPMessage = {'execute': name} if args: @@ -170,6 +210,9 @@ def cmd(self, name: str, return self.cmd_obj(qmp_cmd) def command(self, cmd: str, **kwds: object) -> QMPReturnValue: + """ + Build and send a QMP command to the monitor, report errors if any + """ return self._sync( self._aqmp.execute(cmd, kwds), self._timeout @@ -177,6 +220,19 @@ def command(self, cmd: str, **kwds: object) -> QMPReturnValue: def pull_event(self, wait: Union[bool, float] = False) -> Optional[QMPMessage]: + """ + Pulls a single event. + + :param wait: + If False or 0, do not wait. Return None if no events ready. + If True, wait forever until the next event. + Otherwise, wait for the specified number of seconds. + + :raise asyncio.TimeoutError: + When a timeout is requested and the timeout period elapses. + + :return: The first available QMP event, or None. + """ if not wait: # wait is False/0: "do not wait, do not except." if self._aqmp.events.empty(): @@ -197,6 +253,20 @@ def pull_event(self, ) def get_events(self, wait: Union[bool, float] = False) -> List[QMPMessage]: + """ + Get a list of QMP events and clear all pending events. + + :param wait: + If False or 0, do not wait. Return None if no events ready. + If True, wait until we have at least one event. + Otherwise, wait for up to the specified number of seconds for at + least one event. + + :raise asyncio.TimeoutError: + When a timeout is requested and the timeout period elapses. + + :return: A list of QMP events. + """ events = [dict(x) for x in self._aqmp.events.clear()] if events: return events @@ -205,17 +275,33 @@ def get_events(self, wait: Union[bool, float] = False) -> List[QMPMessage]: return [event] if event is not None else [] def clear_events(self) -> None: + """Clear current list of pending events.""" self._aqmp.events.clear() def close(self) -> None: + """Close the connection.""" self._sync( self._aqmp.disconnect() ) def settimeout(self, timeout: Optional[float]) -> None: + """ + Set the timeout for QMP RPC execution. + + This timeout affects the `cmd`, `cmd_obj`, and `command` methods. + The `accept`, `pull_event` and `get_event` methods have their + own configurable timeouts. + + :param timeout: + timeout in seconds, or None. + None will wait indefinitely. + """ self._timeout = timeout def send_fd_scm(self, fd: int) -> None: + """ + Send a file descriptor to the remote via SCM_RIGHTS. + """ self._aqmp.send_fd_scm(fd) def __del__(self) -> None: From patchwork Mon Mar 21 21:08:44 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: John Snow X-Patchwork-Id: 12787793 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 3BA33C433F5 for ; Mon, 21 Mar 2022 21:18:40 +0000 (UTC) Received: from localhost ([::1]:53390 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1nWPQF-0003oy-EA for qemu-devel@archiver.kernel.org; Mon, 21 Mar 2022 17:18:39 -0400 Received: from eggs.gnu.org ([209.51.188.92]:45442) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1nWPGt-0002U3-0j for qemu-devel@nongnu.org; Mon, 21 Mar 2022 17:08:59 -0400 Received: from us-smtp-delivery-124.mimecast.com ([170.10.129.124]:22390) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1nWPGq-0006QQ-85 for qemu-devel@nongnu.org; Mon, 21 Mar 2022 17:08:58 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1647896935; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=YTOvoVXVMP6xTslDgzp3Zv9F61J0wHQs5Z0ssiyIID8=; b=NbcP8v8SvFlVmhvFrdA/rnkLzNT0aLbMqtmRBd03GCW5ulAYPgf0LwoEk6s5LjlrqKVzCN E4jRHA0x9d4XRHG+I4KBQdjvV7KwNcHwW+r5jIXmLfRCMSoSFKnyyzlJV+VHTeJxo6D1qj viZD/J9NY8Qgdl/lLbFm4CXMAmNWL9c= Received: from mimecast-mx02.redhat.com (mimecast-mx02.redhat.com [66.187.233.88]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-507-o0QAc6n9PHiIXK9PpSQQYA-1; Mon, 21 Mar 2022 17:08:51 -0400 X-MC-Unique: o0QAc6n9PHiIXK9PpSQQYA-1 Received: from smtp.corp.redhat.com (int-mx03.intmail.prod.int.rdu2.redhat.com [10.11.54.3]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id 4B7B5801585; Mon, 21 Mar 2022 21:08:51 +0000 (UTC) Received: from scv.redhat.com (unknown [10.22.16.64]) by smtp.corp.redhat.com (Postfix) with ESMTP id DDE201121314; Mon, 21 Mar 2022 21:08:50 +0000 (UTC) From: John Snow To: qemu-devel@nongnu.org Subject: [PATCH 07/10] python: remove the old QMP package Date: Mon, 21 Mar 2022 17:08:44 -0400 Message-Id: <20220321210847.914787-8-jsnow@redhat.com> In-Reply-To: <20220321210847.914787-1-jsnow@redhat.com> References: <20220321210847.914787-1-jsnow@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.78 on 10.11.54.3 Authentication-Results: relay.mimecast.com; auth=pass smtp.auth=CUSA124A263 smtp.mailfrom=jsnow@redhat.com X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Received-SPF: pass client-ip=170.10.129.124; envelope-from=jsnow@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -21 X-Spam_score: -2.2 X-Spam_bar: -- X-Spam_report: (-2.2 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.082, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H4=0.001, RCVD_IN_MSPIKE_WL=0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001, T_SCC_BODY_TEXT_LINE=-0.01 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Kevin Wolf , Vladimir Sementsov-Ogievskiy , Beraldo Leal , qemu-block@nongnu.org, Markus Armbruster , Hanna Reitz , Cleber Rosa , John Snow Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: "Qemu-devel" Thank you for your service! Signed-off-by: John Snow Reviewed-by: Vladimir Sementsov-Ogievskiy Reviewed-by: Beraldo Leal --- python/PACKAGE.rst | 4 +- python/README.rst | 2 +- python/qemu/qmp/README.rst | 9 - python/qemu/qmp/__init__.py | 396 ------------------------------------ python/qemu/qmp/py.typed | 0 python/setup.cfg | 3 +- 6 files changed, 4 insertions(+), 410 deletions(-) delete mode 100644 python/qemu/qmp/README.rst delete mode 100644 python/qemu/qmp/__init__.py delete mode 100644 python/qemu/qmp/py.typed diff --git a/python/PACKAGE.rst b/python/PACKAGE.rst index b0b86cc4c3..ddfa9ba3f5 100644 --- a/python/PACKAGE.rst +++ b/python/PACKAGE.rst @@ -8,11 +8,11 @@ to change at any time. Usage ----- -The ``qemu.qmp`` subpackage provides a library for communicating with +The ``qemu.aqmp`` subpackage provides a library for communicating with QMP servers. The ``qemu.machine`` subpackage offers rudimentary facilities for launching and managing QEMU processes. Refer to each package's documentation -(``>>> help(qemu.qmp)``, ``>>> help(qemu.machine)``) +(``>>> help(qemu.aqmp)``, ``>>> help(qemu.machine)``) for more information. Contributing diff --git a/python/README.rst b/python/README.rst index fcf74f69ea..eb5213337d 100644 --- a/python/README.rst +++ b/python/README.rst @@ -3,7 +3,7 @@ QEMU Python Tooling This directory houses Python tooling used by the QEMU project to build, configure, and test QEMU. It is organized by namespace (``qemu``), and -then by package (e.g. ``qemu/machine``, ``qemu/qmp``, etc). +then by package (e.g. ``qemu/machine``, ``qemu/aqmp``, etc). ``setup.py`` is used by ``pip`` to install this tooling to the current environment. ``setup.cfg`` provides the packaging configuration used by diff --git a/python/qemu/qmp/README.rst b/python/qemu/qmp/README.rst deleted file mode 100644 index 5bfb82535f..0000000000 --- a/python/qemu/qmp/README.rst +++ /dev/null @@ -1,9 +0,0 @@ -qemu.qmp package -================ - -This package provides a library used for connecting to and communicating -with QMP servers. It is used extensively by iotests, vm tests, -avocado tests, and other utilities in the ./scripts directory. It is -not a fully-fledged SDK and is subject to change at any time. - -See the documentation in ``__init__.py`` for more information. diff --git a/python/qemu/qmp/__init__.py b/python/qemu/qmp/__init__.py deleted file mode 100644 index 4e08641154..0000000000 --- a/python/qemu/qmp/__init__.py +++ /dev/null @@ -1,396 +0,0 @@ -""" -QEMU Monitor Protocol (QMP) development library & tooling. - -This package provides a fairly low-level class for communicating to QMP -protocol servers, as implemented by QEMU, the QEMU Guest Agent, and the -QEMU Storage Daemon. This library is not intended for production use. - -`QEMUMonitorProtocol` is the primary class of interest, and all errors -raised derive from `QMPError`. -""" - -# Copyright (C) 2009, 2010 Red Hat Inc. -# -# Authors: -# Luiz Capitulino -# -# This work is licensed under the terms of the GNU GPL, version 2. See -# the COPYING file in the top-level directory. - -import errno -import json -import logging -import socket -import struct -from types import TracebackType -from typing import ( - Any, - Dict, - List, - Optional, - TextIO, - Tuple, - Type, - TypeVar, - Union, - cast, -) - - -#: QMPMessage is an entire QMP message of any kind. -QMPMessage = Dict[str, Any] - -#: QMPReturnValue is the 'return' value of a command. -QMPReturnValue = object - -#: QMPObject is any object in a QMP message. -QMPObject = Dict[str, object] - -# QMPMessage can be outgoing commands or incoming events/returns. -# QMPReturnValue is usually a dict/json object, but due to QAPI's -# 'returns-whitelist', it can actually be anything. -# -# {'return': {}} is a QMPMessage, -# {} is the QMPReturnValue. - - -InternetAddrT = Tuple[str, int] -UnixAddrT = str -SocketAddrT = Union[InternetAddrT, UnixAddrT] - - -class QMPError(Exception): - """ - QMP base exception - """ - - -class QMPConnectError(QMPError): - """ - QMP connection exception - """ - - -class QMPCapabilitiesError(QMPError): - """ - QMP negotiate capabilities exception - """ - - -class QMPTimeoutError(QMPError): - """ - QMP timeout exception - """ - - -class QMPProtocolError(QMPError): - """ - QMP protocol error; unexpected response - """ - - -class QMPResponseError(QMPError): - """ - Represents erroneous QMP monitor reply - """ - def __init__(self, reply: QMPMessage): - try: - desc = reply['error']['desc'] - except KeyError: - desc = reply - super().__init__(desc) - self.reply = reply - - -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') - - def __init__(self, address: SocketAddrT, - server: bool = False, - nickname: Optional[str] = None): - """ - Create a QEMUMonitorProtocol class. - - @param address: QEMU address, can be either a unix socket path (string) - or a tuple in the form ( address, port ) for a TCP - connection - @param server: server mode listens on the socket (bool) - @raise OSError on socket connection errors - @note No connection is established, this is done by the connect() or - accept() methods - """ - self.__events: List[QMPMessage] = [] - self.__address = address - self.__sock = self.__get_sock() - self.__sockfile: Optional[TextIO] = None - self._nickname = nickname - if self._nickname: - self.logger = logging.getLogger('QMP').getChild(self._nickname) - if server: - self.__sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) - self.__sock.bind(self.__address) - self.__sock.listen(1) - - def __get_sock(self) -> socket.socket: - if isinstance(self.__address, tuple): - family = socket.AF_INET - else: - family = socket.AF_UNIX - return socket.socket(family, socket.SOCK_STREAM) - - def __negotiate_capabilities(self) -> QMPMessage: - greeting = self.__json_read() - if greeting is None or "QMP" not in greeting: - raise QMPConnectError - # Greeting seems ok, negotiate capabilities - resp = self.cmd('qmp_capabilities') - if resp and "return" in resp: - return greeting - raise QMPCapabilitiesError - - def __json_read(self, only_event: bool = False) -> Optional[QMPMessage]: - assert self.__sockfile is not None - while True: - data = self.__sockfile.readline() - if not data: - return None - # By definition, any JSON received from QMP is a QMPMessage, - # and we are asserting only at static analysis time that it - # has a particular shape. - resp: QMPMessage = json.loads(data) - if 'event' in resp: - self.logger.debug("<<< %s", resp) - self.__events.append(resp) - if not only_event: - continue - return resp - - def __get_events(self, wait: Union[bool, float] = False) -> None: - """ - Check for new events in the stream and cache them in __events. - - @param wait (bool): block until an event is available. - @param wait (float): If wait is a float, treat it as a timeout value. - - @raise QMPTimeoutError: If a timeout float is provided and the timeout - period elapses. - @raise QMPConnectError: If wait is True but no events could be - retrieved or if some other error occurred. - """ - - # Current timeout and blocking status - current_timeout = self.__sock.gettimeout() - - # Check for new events regardless and pull them into the cache: - self.__sock.settimeout(0) # i.e. setblocking(False) - try: - self.__json_read() - except OSError as err: - # EAGAIN: No data available; not critical - if err.errno != errno.EAGAIN: - raise - finally: - self.__sock.settimeout(current_timeout) - - # Wait for new events, if needed. - # if wait is 0.0, this means "no wait" and is also implicitly false. - if not self.__events and wait: - if isinstance(wait, float): - self.__sock.settimeout(wait) - try: - ret = self.__json_read(only_event=True) - except socket.timeout as err: - raise QMPTimeoutError("Timeout waiting for event") from err - except Exception as err: - msg = "Error while reading from socket" - raise QMPConnectError(msg) from err - finally: - self.__sock.settimeout(current_timeout) - - if ret is None: - raise QMPConnectError("Error while reading from socket") - - T = TypeVar('T') - - def __enter__(self: T) -> T: - # Implement context manager enter function. - return self - - def __exit__(self, - # pylint: disable=duplicate-code - # see https://github.com/PyCQA/pylint/issues/3619 - exc_type: Optional[Type[BaseException]], - exc_val: Optional[BaseException], - exc_tb: Optional[TracebackType]) -> None: - # Implement context manager exit function. - self.close() - - def connect(self, negotiate: bool = True) -> Optional[QMPMessage]: - """ - Connect to the QMP Monitor and perform capabilities negotiation. - - @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 - """ - self.__sock.connect(self.__address) - self.__sockfile = self.__sock.makefile(mode='r') - if negotiate: - return self.__negotiate_capabilities() - return None - - def accept(self, timeout: Optional[float] = 15.0) -> QMPMessage: - """ - 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(timeout) - self.__sock, _ = self.__sock.accept() - self.__sockfile = self.__sock.makefile(mode='r') - return self.__negotiate_capabilities() - - def cmd_obj(self, qmp_cmd: QMPMessage) -> QMPMessage: - """ - Send a QMP command to the QMP Monitor. - - @param qmp_cmd: QMP command to be sent as a Python dict - @return QMP response as a Python dict - """ - self.logger.debug(">>> %s", qmp_cmd) - self.__sock.sendall(json.dumps(qmp_cmd).encode('utf-8')) - resp = self.__json_read() - if resp is None: - raise QMPConnectError("Unexpected empty reply from server") - self.logger.debug("<<< %s", resp) - return resp - - def cmd(self, name: str, - args: Optional[Dict[str, object]] = None, - cmd_id: Optional[object] = None) -> QMPMessage: - """ - Build a QMP command and send it to the QMP Monitor. - - @param name: command name (string) - @param args: command arguments (dict) - @param cmd_id: command id (dict, list, string or int) - """ - qmp_cmd: QMPMessage = {'execute': name} - if args: - qmp_cmd['arguments'] = args - if cmd_id: - qmp_cmd['id'] = cmd_id - return self.cmd_obj(qmp_cmd) - - def command(self, cmd: str, **kwds: object) -> QMPReturnValue: - """ - Build and send a QMP command to the monitor, report errors if any - """ - ret = self.cmd(cmd, kwds) - if 'error' in ret: - raise QMPResponseError(ret) - if 'return' not in ret: - raise QMPProtocolError( - "'return' key not found in QMP response '{}'".format(str(ret)) - ) - return cast(QMPReturnValue, ret['return']) - - def pull_event(self, - wait: Union[bool, float] = False) -> Optional[QMPMessage]: - """ - Pulls a single event. - - @param wait (bool): block until an event is available. - @param wait (float): If wait is a float, treat it as a timeout value. - - @raise QMPTimeoutError: If a timeout float is provided and the timeout - period elapses. - @raise QMPConnectError: If wait is True but no events could be - retrieved or if some other error occurred. - - @return The first available QMP event, or None. - """ - self.__get_events(wait) - - if self.__events: - return self.__events.pop(0) - return None - - def get_events(self, wait: bool = False) -> List[QMPMessage]: - """ - Get a list of available QMP events and clear all pending events. - - @param wait (bool): block until an event is available. - @param wait (float): If wait is a float, treat it as a timeout value. - - @raise QMPTimeoutError: If a timeout float is provided and the timeout - period elapses. - @raise QMPConnectError: If wait is True but no events could be - retrieved or if some other error occurred. - - @return The list of available QMP events. - """ - self.__get_events(wait) - events = self.__events - self.__events = [] - return events - - def clear_events(self) -> None: - """ - Clear current list of pending events. - """ - self.__events = [] - - def close(self) -> None: - """ - Close the socket and socket file. - """ - if self.__sock: - self.__sock.close() - if self.__sockfile: - self.__sockfile.close() - - def settimeout(self, timeout: Optional[float]) -> None: - """ - Set the socket timeout. - - @param timeout (float): timeout in seconds (non-zero), or None. - @note This is a wrap around socket.settimeout - - @raise ValueError: if timeout was set to 0. - """ - if timeout == 0: - msg = "timeout cannot be 0; this engages non-blocking mode." - msg += " Use 'None' instead to disable timeouts." - raise ValueError(msg) - self.__sock.settimeout(timeout) - - def send_fd_scm(self, fd: int) -> None: - """ - Send a file descriptor to the remote via SCM_RIGHTS. - """ - if self.__sock.family != socket.AF_UNIX: - raise RuntimeError("Can't use SCM_RIGHTS on non-AF_UNIX socket.") - - self.__sock.sendmsg( - [b' '], - [(socket.SOL_SOCKET, socket.SCM_RIGHTS, struct.pack('@i', fd))] - ) diff --git a/python/qemu/qmp/py.typed b/python/qemu/qmp/py.typed deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/python/setup.cfg b/python/setup.cfg index cdeced44d2..4340c29a24 100644 --- a/python/setup.cfg +++ b/python/setup.cfg @@ -24,10 +24,9 @@ classifiers = [options] python_requires = >= 3.6 packages = - qemu.qmp + qemu.aqmp qemu.machine qemu.utils - qemu.aqmp [options.package_data] * = py.typed From patchwork Mon Mar 21 21:08:45 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: John Snow X-Patchwork-Id: 12787791 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 4BAFFC433EF for ; Mon, 21 Mar 2022 21:16:17 +0000 (UTC) Received: from localhost ([::1]:47972 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1nWPNw-000088-AX for qemu-devel@archiver.kernel.org; Mon, 21 Mar 2022 17:16:16 -0400 Received: from eggs.gnu.org ([209.51.188.92]:45402) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1nWPGr-0002Pf-DK for qemu-devel@nongnu.org; Mon, 21 Mar 2022 17:08:57 -0400 Received: from us-smtp-delivery-124.mimecast.com ([170.10.129.124]:47605) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1nWPGo-0006PO-65 for qemu-devel@nongnu.org; Mon, 21 Mar 2022 17:08:57 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1647896933; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=7rWYoLS7QN0QosLm8H3hsIX4tGumRcHbXeEoA0PCoek=; b=WUlfrQyx8+26RhLgMn0Cv9Dxl4+nopnEIlSWJE/9lfvv2ZsDgAcdVe/2Ri0ZrKqPiPWU8Q WBsxysiR4AaSrGRY3oh+Z42pjtBy3RljO+5Tkyt7I4iLG46R9ZOtVgwQasmbqdx4o5wev9 AuPkoQFyivXlhU0M1qrl2hIRJUgYnCE= Received: from mimecast-mx02.redhat.com (mimecast-mx02.redhat.com [66.187.233.88]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-323-fSRpgtVoOJuoQsh-vetSOg-1; Mon, 21 Mar 2022 17:08:52 -0400 X-MC-Unique: fSRpgtVoOJuoQsh-vetSOg-1 Received: from smtp.corp.redhat.com (int-mx03.intmail.prod.int.rdu2.redhat.com [10.11.54.3]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id B69C01010369; Mon, 21 Mar 2022 21:08:51 +0000 (UTC) Received: from scv.redhat.com (unknown [10.22.16.64]) by smtp.corp.redhat.com (Postfix) with ESMTP id 5B0B61121314; Mon, 21 Mar 2022 21:08:51 +0000 (UTC) From: John Snow To: qemu-devel@nongnu.org Subject: [PATCH 08/10] python: re-enable pylint duplicate-code warnings Date: Mon, 21 Mar 2022 17:08:45 -0400 Message-Id: <20220321210847.914787-9-jsnow@redhat.com> In-Reply-To: <20220321210847.914787-1-jsnow@redhat.com> References: <20220321210847.914787-1-jsnow@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.78 on 10.11.54.3 Authentication-Results: relay.mimecast.com; auth=pass smtp.auth=CUSA124A263 smtp.mailfrom=jsnow@redhat.com X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Received-SPF: pass client-ip=170.10.129.124; envelope-from=jsnow@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -21 X-Spam_score: -2.2 X-Spam_bar: -- X-Spam_report: (-2.2 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.082, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H4=0.001, RCVD_IN_MSPIKE_WL=0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001, T_SCC_BODY_TEXT_LINE=-0.01 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Kevin Wolf , Vladimir Sementsov-Ogievskiy , Beraldo Leal , qemu-block@nongnu.org, Markus Armbruster , Hanna Reitz , Cleber Rosa , John Snow Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: "Qemu-devel" With the old library gone, there's nothing duplicated in the tree, so the warning suppression can be removed. Signed-off-by: John Snow Reviewed-by: Vladimir Sementsov-Ogievskiy Reviewed-by: Beraldo Leal --- python/setup.cfg | 1 - 1 file changed, 1 deletion(-) diff --git a/python/setup.cfg b/python/setup.cfg index 4340c29a24..49e3c285f1 100644 --- a/python/setup.cfg +++ b/python/setup.cfg @@ -118,7 +118,6 @@ disable=consider-using-f-string, too-many-function-args, # mypy handles this with less false positives. too-many-instance-attributes, no-member, # mypy also handles this better. - duplicate-code, # To be removed by the end of this patch series. [pylint.basic] # Good variable names which should always be accepted, separated by a comma. From patchwork Mon Mar 21 21:08:46 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: John Snow X-Patchwork-Id: 12787792 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 0B06EC433F5 for ; Mon, 21 Mar 2022 21:17:08 +0000 (UTC) Received: from localhost ([::1]:48584 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1nWPOl-0000a3-3x for qemu-devel@archiver.kernel.org; Mon, 21 Mar 2022 17:17:07 -0400 Received: from eggs.gnu.org ([209.51.188.92]:45492) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1nWPGu-0002Yn-Er for qemu-devel@nongnu.org; Mon, 21 Mar 2022 17:09:00 -0400 Received: from us-smtp-delivery-124.mimecast.com ([170.10.133.124]:22837) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1nWPGq-0006QX-FF for qemu-devel@nongnu.org; Mon, 21 Mar 2022 17:09:00 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1647896935; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=IXfFfDTXb82KGmvLdClRAvTi4+pKhDp6aRdOisiZnpQ=; b=JILezDh5feq4e87SMooGa+v2L+UbAwiDIzy2QtsxpJGbFO5irVk2ZW3u3Nxky6xr2pRTx5 y247TTURarE++2Y0nuy8+dXeCr+vvyLbwpCmQ2NR43epkI45Bb03KOXML/hZA/xBPkE1eF V3vd7iws2fQ2dJSFR59o6jiEi2lBqO0= Received: from mimecast-mx02.redhat.com (mimecast-mx02.redhat.com [66.187.233.88]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-18-3Grp9JeWMYmBkXdSCcLg3A-1; Mon, 21 Mar 2022 17:08:53 -0400 X-MC-Unique: 3Grp9JeWMYmBkXdSCcLg3A-1 Received: from smtp.corp.redhat.com (int-mx03.intmail.prod.int.rdu2.redhat.com [10.11.54.3]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id 3905180005D; Mon, 21 Mar 2022 21:08:53 +0000 (UTC) Received: from scv.redhat.com (unknown [10.22.16.64]) by smtp.corp.redhat.com (Postfix) with ESMTP id CCFBE1121314; Mon, 21 Mar 2022 21:08:51 +0000 (UTC) From: John Snow To: qemu-devel@nongnu.org Subject: [PATCH 09/10] python: rename qemu.aqmp to qemu.qmp Date: Mon, 21 Mar 2022 17:08:46 -0400 Message-Id: <20220321210847.914787-10-jsnow@redhat.com> In-Reply-To: <20220321210847.914787-1-jsnow@redhat.com> References: <20220321210847.914787-1-jsnow@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.78 on 10.11.54.3 Authentication-Results: relay.mimecast.com; auth=pass smtp.auth=CUSA124A263 smtp.mailfrom=jsnow@redhat.com X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Received-SPF: pass client-ip=170.10.133.124; envelope-from=jsnow@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -21 X-Spam_score: -2.2 X-Spam_bar: -- X-Spam_report: (-2.2 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.082, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H5=0.001, RCVD_IN_MSPIKE_WL=0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001, T_SCC_BODY_TEXT_LINE=-0.01 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Kevin Wolf , Vladimir Sementsov-Ogievskiy , Beraldo Leal , qemu-block@nongnu.org, Markus Armbruster , Hanna Reitz , Cleber Rosa , John Snow Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: "Qemu-devel" 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 Reviewed-by: Beraldo Leal Acked-by: Hanna Reitz --- python/PACKAGE.rst | 4 +-- python/README.rst | 4 +-- python/qemu/machine/machine.py | 4 +-- python/qemu/machine/qtest.py | 2 +- python/qemu/{aqmp => qmp}/__init__.py | 6 ++-- python/qemu/{aqmp => qmp}/aqmp_tui.py | 0 python/qemu/{aqmp => qmp}/error.py | 0 python/qemu/{aqmp => qmp}/events.py | 2 +- python/qemu/{aqmp => qmp}/legacy.py | 38 +++++++++++------------ python/qemu/{aqmp => qmp}/message.py | 0 python/qemu/{aqmp => qmp}/models.py | 0 python/qemu/{aqmp => qmp}/protocol.py | 4 +-- python/qemu/{aqmp => qmp}/py.typed | 0 python/qemu/{aqmp => qmp}/qmp_client.py | 16 +++++----- python/qemu/{aqmp => qmp}/qmp_shell.py | 4 +-- python/qemu/{aqmp => qmp}/util.py | 0 python/qemu/utils/qemu_ga_client.py | 4 +-- python/qemu/utils/qom.py | 2 +- python/qemu/utils/qom_common.py | 4 +-- python/qemu/utils/qom_fuse.py | 2 +- python/setup.cfg | 10 +++--- python/tests/protocol.py | 14 ++++----- scripts/cpu-x86-uarch-abi.py | 2 +- scripts/device-crash-test | 4 +-- scripts/qmp/qmp-shell | 2 +- scripts/qmp/qmp-shell-wrap | 2 +- scripts/render_block_graph.py | 4 +-- scripts/simplebench/bench_block_job.py | 2 +- tests/qemu-iotests/iotests.py | 2 +- tests/qemu-iotests/tests/mirror-top-perms | 2 +- 30 files changed, 70 insertions(+), 70 deletions(-) rename python/qemu/{aqmp => qmp}/__init__.py (87%) rename python/qemu/{aqmp => qmp}/aqmp_tui.py (100%) rename python/qemu/{aqmp => qmp}/error.py (100%) rename python/qemu/{aqmp => qmp}/events.py (99%) rename python/qemu/{aqmp => qmp}/legacy.py (91%) rename python/qemu/{aqmp => qmp}/message.py (100%) rename python/qemu/{aqmp => qmp}/models.py (100%) rename python/qemu/{aqmp => qmp}/protocol.py (99%) rename python/qemu/{aqmp => qmp}/py.typed (100%) rename python/qemu/{aqmp => qmp}/qmp_client.py (97%) rename python/qemu/{aqmp => qmp}/qmp_shell.py (99%) rename python/qemu/{aqmp => qmp}/util.py (100%) diff --git a/python/PACKAGE.rst b/python/PACKAGE.rst index ddfa9ba3f5..b0b86cc4c3 100644 --- a/python/PACKAGE.rst +++ b/python/PACKAGE.rst @@ -8,11 +8,11 @@ to change at any time. Usage ----- -The ``qemu.aqmp`` subpackage provides a library for communicating with +The ``qemu.qmp`` subpackage provides a library for communicating with QMP servers. The ``qemu.machine`` subpackage offers rudimentary facilities for launching and managing QEMU processes. Refer to each package's documentation -(``>>> help(qemu.aqmp)``, ``>>> help(qemu.machine)``) +(``>>> help(qemu.qmp)``, ``>>> help(qemu.machine)``) for more information. Contributing diff --git a/python/README.rst b/python/README.rst index eb5213337d..9c1fceaee7 100644 --- a/python/README.rst +++ b/python/README.rst @@ -3,7 +3,7 @@ QEMU Python Tooling This directory houses Python tooling used by the QEMU project to build, configure, and test QEMU. It is organized by namespace (``qemu``), and -then by package (e.g. ``qemu/machine``, ``qemu/aqmp``, etc). +then by package (e.g. ``qemu/machine``, ``qemu/qmp``, etc). ``setup.py`` is used by ``pip`` to install this tooling to the current environment. ``setup.cfg`` provides the packaging configuration used by @@ -59,7 +59,7 @@ Package installation also normally provides executable console scripts, so that tools like ``qmp-shell`` are always available via $PATH. To invoke them without installation, you can invoke e.g.: -``> PYTHONPATH=~/src/qemu/python python3 -m qemu.aqmp.qmp_shell`` +``> PYTHONPATH=~/src/qemu/python python3 -m qemu.qmp.qmp_shell`` The mappings between console script name and python module path can be found in ``setup.cfg``. diff --git a/python/qemu/machine/machine.py b/python/qemu/machine/machine.py index 41be025ac7..07ac5a710b 100644 --- a/python/qemu/machine/machine.py +++ b/python/qemu/machine/machine.py @@ -40,8 +40,8 @@ TypeVar, ) -from qemu.aqmp import SocketAddrT -from qemu.aqmp.legacy import ( +from qemu.qmp import SocketAddrT +from qemu.qmp.legacy import ( QEMUMonitorProtocol, QMPMessage, QMPReturnValue, diff --git a/python/qemu/machine/qtest.py b/python/qemu/machine/qtest.py index 13e0aaff84..1a1fc6c9b0 100644 --- a/python/qemu/machine/qtest.py +++ b/python/qemu/machine/qtest.py @@ -26,7 +26,7 @@ TextIO, ) -from qemu.aqmp import SocketAddrT +from qemu.qmp import SocketAddrT from .machine import QEMUMachine diff --git a/python/qemu/aqmp/__init__.py b/python/qemu/qmp/__init__.py similarity index 87% rename from python/qemu/aqmp/__init__.py rename to python/qemu/qmp/__init__.py index 2e4478ac05..3e13f23ed7 100644 --- a/python/qemu/aqmp/__init__.py +++ b/python/qemu/qmp/__init__.py @@ -6,8 +6,8 @@ QEMU Guest Agent, and the QEMU Storage Daemon. `QMPClient` provides the main functionality of this package. All errors -raised by this library derive from `QMPError`, see `aqmp.error` for -additional detail. See `aqmp.events` for an in-depth tutorial on +raised by this library derive from `QMPError`, see `qmp.error` for +additional detail. See `qmp.events` for an in-depth tutorial on managing QMP events. """ @@ -36,7 +36,7 @@ # Suppress logging unless an application engages it. -logging.getLogger('qemu.aqmp').addHandler(logging.NullHandler()) +logging.getLogger('qemu.qmp').addHandler(logging.NullHandler()) # The order of these fields impact the Sphinx documentation order. diff --git a/python/qemu/aqmp/aqmp_tui.py b/python/qemu/qmp/aqmp_tui.py similarity index 100% rename from python/qemu/aqmp/aqmp_tui.py rename to python/qemu/qmp/aqmp_tui.py diff --git a/python/qemu/aqmp/error.py b/python/qemu/qmp/error.py similarity index 100% rename from python/qemu/aqmp/error.py rename to python/qemu/qmp/error.py diff --git a/python/qemu/aqmp/events.py b/python/qemu/qmp/events.py similarity index 99% rename from python/qemu/aqmp/events.py rename to python/qemu/qmp/events.py index f3d4e2b5e8..6199776cc6 100644 --- a/python/qemu/aqmp/events.py +++ b/python/qemu/qmp/events.py @@ -1,5 +1,5 @@ """ -AQMP Events and EventListeners +QMP Events and EventListeners Asynchronous QMP uses `EventListener` objects to listen for events. An `EventListener` is a FIFO event queue that can be pre-filtered to listen diff --git a/python/qemu/aqmp/legacy.py b/python/qemu/qmp/legacy.py similarity index 91% rename from python/qemu/aqmp/legacy.py rename to python/qemu/qmp/legacy.py index 20ffdd8956..0815b03dd2 100644 --- a/python/qemu/aqmp/legacy.py +++ b/python/qemu/qmp/legacy.py @@ -82,13 +82,13 @@ def __init__(self, address: SocketAddrT, server: bool = False, nickname: Optional[str] = None): - self._aqmp = QMPClient(nickname) + self._qmp = QMPClient(nickname) self._aloop = asyncio.get_event_loop() self._address = address self._timeout: Optional[float] = None if server: - self._sync(self._aqmp.start_server(self._address)) + self._sync(self._qmp.start_server(self._address)) _T = TypeVar('_T') @@ -100,9 +100,9 @@ def _sync( ) def _get_greeting(self) -> Optional[QMPMessage]: - if self._aqmp.greeting is not None: + if self._qmp.greeting is not None: # pylint: disable=protected-access - return self._aqmp.greeting._asdict() + return self._qmp.greeting._asdict() return None def __enter__(self: _T) -> _T: @@ -145,11 +145,11 @@ def connect(self, negotiate: bool = True) -> Optional[QMPMessage]: :return: QMP greeting dict, or None if negotiate is false :raise ConnectError: on connection errors """ - self._aqmp.await_greeting = negotiate - self._aqmp.negotiate = negotiate + self._qmp.await_greeting = negotiate + self._qmp.negotiate = negotiate self._sync( - self._aqmp.connect(self._address) + self._qmp.connect(self._address) ) return self._get_greeting() @@ -164,10 +164,10 @@ def accept(self, timeout: Optional[float] = 15.0) -> QMPMessage: :return: QMP greeting dict :raise ConnectError: on connection errors """ - self._aqmp.await_greeting = True - self._aqmp.negotiate = True + self._qmp.await_greeting = True + self._qmp.negotiate = True - self._sync(self._aqmp.accept(), timeout) + self._sync(self._qmp.accept(), timeout) ret = self._get_greeting() assert ret is not None @@ -187,7 +187,7 @@ def cmd_obj(self, qmp_cmd: QMPMessage) -> QMPMessage: # _raw() isn't a public API, because turning off # automatic ID assignment is discouraged. For # compatibility with iotests *only*, do it anyway. - self._aqmp._raw(qmp_cmd, assign_id=False), + self._qmp._raw(qmp_cmd, assign_id=False), self._timeout ) ) @@ -214,7 +214,7 @@ def command(self, cmd: str, **kwds: object) -> QMPReturnValue: Build and send a QMP command to the monitor, report errors if any """ return self._sync( - self._aqmp.execute(cmd, kwds), + self._qmp.execute(cmd, kwds), self._timeout ) @@ -235,7 +235,7 @@ def pull_event(self, """ if not wait: # wait is False/0: "do not wait, do not except." - if self._aqmp.events.empty(): + if self._qmp.events.empty(): return None # If wait is 'True', wait forever. If wait is False/0, the events @@ -247,7 +247,7 @@ def pull_event(self, return dict( self._sync( - self._aqmp.events.get(), + self._qmp.events.get(), timeout ) ) @@ -267,7 +267,7 @@ def get_events(self, wait: Union[bool, float] = False) -> List[QMPMessage]: :return: A list of QMP events. """ - events = [dict(x) for x in self._aqmp.events.clear()] + events = [dict(x) for x in self._qmp.events.clear()] if events: return events @@ -276,12 +276,12 @@ def get_events(self, wait: Union[bool, float] = False) -> List[QMPMessage]: def clear_events(self) -> None: """Clear current list of pending events.""" - self._aqmp.events.clear() + self._qmp.events.clear() def close(self) -> None: """Close the connection.""" self._sync( - self._aqmp.disconnect() + self._qmp.disconnect() ) def settimeout(self, timeout: Optional[float]) -> None: @@ -302,10 +302,10 @@ def send_fd_scm(self, fd: int) -> None: """ Send a file descriptor to the remote via SCM_RIGHTS. """ - self._aqmp.send_fd_scm(fd) + self._qmp.send_fd_scm(fd) def __del__(self) -> None: - if self._aqmp.runstate == Runstate.IDLE: + if self._qmp.runstate == Runstate.IDLE: return if not self._aloop.is_running(): diff --git a/python/qemu/aqmp/message.py b/python/qemu/qmp/message.py similarity index 100% rename from python/qemu/aqmp/message.py rename to python/qemu/qmp/message.py diff --git a/python/qemu/aqmp/models.py b/python/qemu/qmp/models.py similarity index 100% rename from python/qemu/aqmp/models.py rename to python/qemu/qmp/models.py diff --git a/python/qemu/aqmp/protocol.py b/python/qemu/qmp/protocol.py similarity index 99% rename from python/qemu/aqmp/protocol.py rename to python/qemu/qmp/protocol.py index 36fae57f27..6ea86650ad 100644 --- a/python/qemu/aqmp/protocol.py +++ b/python/qemu/qmp/protocol.py @@ -196,9 +196,9 @@ class AsyncProtocol(Generic[T]): :param name: Name used for logging messages, if any. By default, messages - will log to 'qemu.aqmp.protocol', but each individual connection + will log to 'qemu.qmp.protocol', but each individual connection can be given its own logger by giving it a name; messages will - then log to 'qemu.aqmp.protocol.${name}'. + then log to 'qemu.qmp.protocol.${name}'. """ # pylint: disable=too-many-instance-attributes diff --git a/python/qemu/aqmp/py.typed b/python/qemu/qmp/py.typed similarity index 100% rename from python/qemu/aqmp/py.typed rename to python/qemu/qmp/py.typed diff --git a/python/qemu/aqmp/qmp_client.py b/python/qemu/qmp/qmp_client.py similarity index 97% rename from python/qemu/aqmp/qmp_client.py rename to python/qemu/qmp/qmp_client.py index 90a8737f03..5dcda04a75 100644 --- a/python/qemu/aqmp/qmp_client.py +++ b/python/qemu/qmp/qmp_client.py @@ -192,7 +192,7 @@ async def run(self, address='/tmp/qemu.socket'): await self.qmp.runstate_changed.wait() await self.disconnect() - See `aqmp.events` for more detail on event handling patterns. + See `qmp.events` for more detail on event handling patterns. """ #: Logger object used for debugging messages. logger = logging.getLogger(__name__) @@ -416,7 +416,7 @@ def _do_send(self, msg: Message) -> None: @upper_half def _get_exec_id(self) -> str: - exec_id = f"__aqmp#{self._execute_id:05d}" + exec_id = f"__qmp#{self._execute_id:05d}" self._execute_id += 1 return exec_id @@ -476,7 +476,7 @@ async def _execute(self, msg: Message, assign_id: bool = True) -> Message: An execution ID will be assigned if assign_id is `True`. It can be disabled, but this requires that an ID is manually assigned instead. For manually assigned IDs, you must not use the string - '__aqmp#' anywhere in the ID. + '__qmp#' anywhere in the ID. :param msg: The QMP `Message` to execute. :param assign_id: If True, assign a new execution ID. @@ -490,7 +490,7 @@ async def _execute(self, msg: Message, assign_id: bool = True) -> Message: msg['id'] = self._get_exec_id() elif 'id' in msg: assert isinstance(msg['id'], str) - assert '__aqmp#' not in msg['id'] + assert '__qmp#' not in msg['id'] exec_id = await self._issue(msg) return await self._reply(exec_id) @@ -512,7 +512,7 @@ async def _raw( Assign an arbitrary execution ID to this message. If `False`, the existing id must either be absent (and no other such pending execution may omit an ID) or a string. If it is - a string, it must not start with '__aqmp#' and no other such + a string, it must not start with '__qmp#' and no other such pending execution may currently be using that ID. :return: Execution reply from the server. @@ -524,7 +524,7 @@ async def _raw( When assign_id is `False`, an ID is given, and it is not a string. :raise ValueError: When assign_id is `False`, but the ID is not usable; - Either because it starts with '__aqmp#' or it is already in-use. + Either because it starts with '__qmp#' or it is already in-use. """ # 1. convert generic Mapping or bytes to a QMP Message # 2. copy Message objects so that we assign an ID only to the copy. @@ -534,9 +534,9 @@ async def _raw( if not assign_id and 'id' in msg: if not isinstance(exec_id, str): raise TypeError(f"ID ('{exec_id}') must be a string.") - if exec_id.startswith('__aqmp#'): + if exec_id.startswith('__qmp#'): raise ValueError( - f"ID ('{exec_id}') must not start with '__aqmp#'." + f"ID ('{exec_id}') must not start with '__qmp#'." ) if not assign_id and exec_id in self._pending: diff --git a/python/qemu/aqmp/qmp_shell.py b/python/qemu/qmp/qmp_shell.py similarity index 99% rename from python/qemu/aqmp/qmp_shell.py rename to python/qemu/qmp/qmp_shell.py index 35691494d0..8b09bc38a2 100644 --- a/python/qemu/aqmp/qmp_shell.py +++ b/python/qemu/qmp/qmp_shell.py @@ -97,8 +97,8 @@ Sequence, ) -from qemu.aqmp import ConnectError, QMPError, SocketAddrT -from qemu.aqmp.legacy import ( +from qemu.qmp import ConnectError, QMPError, SocketAddrT +from qemu.qmp.legacy import ( QEMUMonitorProtocol, QMPBadPortError, QMPMessage, diff --git a/python/qemu/aqmp/util.py b/python/qemu/qmp/util.py similarity index 100% rename from python/qemu/aqmp/util.py rename to python/qemu/qmp/util.py diff --git a/python/qemu/utils/qemu_ga_client.py b/python/qemu/utils/qemu_ga_client.py index 15ed430c61..8c38a7ac9c 100644 --- a/python/qemu/utils/qemu_ga_client.py +++ b/python/qemu/utils/qemu_ga_client.py @@ -50,8 +50,8 @@ Sequence, ) -from qemu.aqmp import ConnectError, SocketAddrT -from qemu.aqmp.legacy import QEMUMonitorProtocol +from qemu.qmp import ConnectError, SocketAddrT +from qemu.qmp.legacy import QEMUMonitorProtocol # This script has not seen many patches or careful attention in quite diff --git a/python/qemu/utils/qom.py b/python/qemu/utils/qom.py index bb5d1a78f5..bcf192f477 100644 --- a/python/qemu/utils/qom.py +++ b/python/qemu/utils/qom.py @@ -32,7 +32,7 @@ import argparse -from qemu.aqmp import ExecuteError +from qemu.qmp import ExecuteError from .qom_common import QOMCommand diff --git a/python/qemu/utils/qom_common.py b/python/qemu/utils/qom_common.py index e034a6f247..80da1b2304 100644 --- a/python/qemu/utils/qom_common.py +++ b/python/qemu/utils/qom_common.py @@ -27,8 +27,8 @@ TypeVar, ) -from qemu.aqmp import QMPError -from qemu.aqmp.legacy import QEMUMonitorProtocol +from qemu.qmp import QMPError +from qemu.qmp.legacy import QEMUMonitorProtocol class ObjectPropertyInfo: diff --git a/python/qemu/utils/qom_fuse.py b/python/qemu/utils/qom_fuse.py index 653a76b93b..8dcd59fcde 100644 --- a/python/qemu/utils/qom_fuse.py +++ b/python/qemu/utils/qom_fuse.py @@ -48,7 +48,7 @@ import fuse from fuse import FUSE, FuseOSError, Operations -from qemu.aqmp import ExecuteError +from qemu.qmp import ExecuteError from .qom_common import QOMCommand diff --git a/python/setup.cfg b/python/setup.cfg index 49e3c285f1..773e51b34e 100644 --- a/python/setup.cfg +++ b/python/setup.cfg @@ -24,7 +24,7 @@ classifiers = [options] python_requires = >= 3.6 packages = - qemu.aqmp + qemu.qmp qemu.machine qemu.utils @@ -66,9 +66,9 @@ console_scripts = qom-tree = qemu.utils.qom:QOMTree.entry_point qom-fuse = qemu.utils.qom_fuse:QOMFuse.entry_point [fuse] qemu-ga-client = qemu.utils.qemu_ga_client:main - qmp-shell = qemu.aqmp.qmp_shell:main - qmp-shell-wrap = qemu.aqmp.qmp_shell:main_wrap - aqmp-tui = qemu.aqmp.aqmp_tui:main [tui] + qmp-shell = qemu.qmp.qmp_shell:main + qmp-shell-wrap = qemu.qmp.qmp_shell:main_wrap + aqmp-tui = qemu.qmp.aqmp_tui:main [tui] [flake8] extend-ignore = E722 # Prefer pylint's bare-except checks to flake8's @@ -84,7 +84,7 @@ namespace_packages = True # fusepy has no type stubs: allow_subclassing_any = True -[mypy-qemu.aqmp.aqmp_tui] +[mypy-qemu.qmp.aqmp_tui] # urwid and urwid_readline have no type stubs: allow_subclassing_any = True diff --git a/python/tests/protocol.py b/python/tests/protocol.py index d6849ad306..56c4d441f9 100644 --- a/python/tests/protocol.py +++ b/python/tests/protocol.py @@ -6,9 +6,9 @@ import avocado -from qemu.aqmp import ConnectError, Runstate -from qemu.aqmp.protocol import AsyncProtocol, StateError -from qemu.aqmp.util import asyncio_run, create_task +from qemu.qmp import ConnectError, Runstate +from qemu.qmp.protocol import AsyncProtocol, StateError +from qemu.qmp.util import asyncio_run, create_task class NullProtocol(AsyncProtocol[None]): @@ -183,7 +183,7 @@ def testDefaultName(self): def testLogger(self): self.assertEqual( self.proto.logger.name, - 'qemu.aqmp.protocol' + 'qemu.qmp.protocol' ) def testName(self): @@ -196,7 +196,7 @@ def testName(self): self.assertEqual( self.proto.logger.name, - 'qemu.aqmp.protocol.Steve' + 'qemu.qmp.protocol.Steve' ) self.assertEqual( @@ -431,7 +431,7 @@ async def _bad_connection(self, family: str): await self.proto.start_server_and_accept('/dev/null') async def _hanging_connection(self): - with TemporaryDirectory(suffix='.aqmp') as tmpdir: + with TemporaryDirectory(suffix='.qmp') as tmpdir: sock = os.path.join(tmpdir, type(self.proto).__name__ + ".sock") await self.proto.start_server_and_accept(sock) @@ -587,7 +587,7 @@ async def _asyncTearDown(self): @TestBase.async_test async def testSmoke(self): - with TemporaryDirectory(suffix='.aqmp') as tmpdir: + with TemporaryDirectory(suffix='.qmp') as tmpdir: sock = os.path.join(tmpdir, type(self.proto).__name__ + ".sock") server_task = create_task(self.server.start_server_and_accept(sock)) diff --git a/scripts/cpu-x86-uarch-abi.py b/scripts/cpu-x86-uarch-abi.py index c262d2f027..82ff07582f 100644 --- a/scripts/cpu-x86-uarch-abi.py +++ b/scripts/cpu-x86-uarch-abi.py @@ -6,7 +6,7 @@ # compatibility levels for each CPU model. # -from qemu.aqmp.legacy import QEMUMonitorProtocol +from qemu.qmp.legacy import QEMUMonitorProtocol import sys if len(sys.argv) != 2: diff --git a/scripts/device-crash-test b/scripts/device-crash-test index 7fbd99158b..4bfc68c008 100755 --- a/scripts/device-crash-test +++ b/scripts/device-crash-test @@ -36,7 +36,7 @@ from itertools import chain sys.path.append(os.path.join(os.path.dirname(__file__), '..', 'python')) from qemu.machine import QEMUMachine -from qemu.aqmp import ConnectError +from qemu.qmp import ConnectError logger = logging.getLogger('device-crash-test') dbg = logger.debug @@ -517,7 +517,7 @@ def main(): # Async QMP, when in use, is chatty about connection failures. # This script knowingly generates a ton of connection errors. # Silence this logger. - logging.getLogger('qemu.aqmp.qmp_client').setLevel(logging.CRITICAL) + logging.getLogger('qemu.qmp.qmp_client').setLevel(logging.CRITICAL) fatal_failures = [] wl_stats = {} diff --git a/scripts/qmp/qmp-shell b/scripts/qmp/qmp-shell index 31b19d73e2..4a20f97db7 100755 --- a/scripts/qmp/qmp-shell +++ b/scripts/qmp/qmp-shell @@ -4,7 +4,7 @@ import os import sys sys.path.append(os.path.join(os.path.dirname(__file__), '..', '..', 'python')) -from qemu.aqmp import qmp_shell +from qemu.qmp import qmp_shell if __name__ == '__main__': diff --git a/scripts/qmp/qmp-shell-wrap b/scripts/qmp/qmp-shell-wrap index 66846e36d1..9e94da114f 100755 --- a/scripts/qmp/qmp-shell-wrap +++ b/scripts/qmp/qmp-shell-wrap @@ -4,7 +4,7 @@ import os import sys sys.path.append(os.path.join(os.path.dirname(__file__), '..', '..', 'python')) -from qemu.aqmp import qmp_shell +from qemu.qmp import qmp_shell if __name__ == '__main__': diff --git a/scripts/render_block_graph.py b/scripts/render_block_graph.py index b33fb70d5e..8f731a5cfe 100755 --- a/scripts/render_block_graph.py +++ b/scripts/render_block_graph.py @@ -25,8 +25,8 @@ from graphviz import Digraph sys.path.append(os.path.join(os.path.dirname(__file__), '..', 'python')) -from qemu.aqmp import QMPError -from qemu.aqmp.legacy import QEMUMonitorProtocol +from qemu.qmp import QMPError +from qemu.qmp.legacy import QEMUMonitorProtocol def perm(arr): diff --git a/scripts/simplebench/bench_block_job.py b/scripts/simplebench/bench_block_job.py index af9d1646a4..56191db44b 100755 --- a/scripts/simplebench/bench_block_job.py +++ b/scripts/simplebench/bench_block_job.py @@ -27,7 +27,7 @@ sys.path.append(os.path.join(os.path.dirname(__file__), '..', '..', 'python')) from qemu.machine import QEMUMachine -from qemu.aqmp import ConnectError +from qemu.qmp import ConnectError def bench_block_job(cmd, cmd_args, qemu_args): diff --git a/tests/qemu-iotests/iotests.py b/tests/qemu-iotests/iotests.py index 8760e2c310..9563749709 100644 --- a/tests/qemu-iotests/iotests.py +++ b/tests/qemu-iotests/iotests.py @@ -38,7 +38,7 @@ from contextlib import contextmanager from qemu.machine import qtest -from qemu.aqmp.legacy import QMPMessage, QEMUMonitorProtocol +from qemu.qmp.legacy import QMPMessage, QEMUMonitorProtocol # Use this logger for logging messages directly from the iotests module logger = logging.getLogger('qemu.iotests') diff --git a/tests/qemu-iotests/tests/mirror-top-perms b/tests/qemu-iotests/tests/mirror-top-perms index 223f3c1620..d538579961 100755 --- a/tests/qemu-iotests/tests/mirror-top-perms +++ b/tests/qemu-iotests/tests/mirror-top-perms @@ -99,7 +99,7 @@ class TestMirrorTopPerms(iotests.QMPTestCase): self.vm_b.add_device('virtio-blk,drive=drive0,share-rw=on') try: # Silence AQMP logging errors temporarily. - with change_log_level('qemu.aqmp'): + with change_log_level('qemu.qmp'): self.vm_b.launch() print('ERROR: VM B launched successfully, ' 'this should not have happened') From patchwork Mon Mar 21 21:08:47 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: John Snow X-Patchwork-Id: 12787790 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id A0787C433EF for ; Mon, 21 Mar 2022 21:14:27 +0000 (UTC) Received: from localhost ([::1]:43102 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1nWPMA-00050W-NG for qemu-devel@archiver.kernel.org; Mon, 21 Mar 2022 17:14:26 -0400 Received: from eggs.gnu.org ([209.51.188.92]:45496) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1nWPGu-0002Z4-Fx for qemu-devel@nongnu.org; Mon, 21 Mar 2022 17:09:00 -0400 Received: from us-smtp-delivery-124.mimecast.com ([170.10.129.124]:47682) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1nWPGr-0006RD-6W for qemu-devel@nongnu.org; Mon, 21 Mar 2022 17:09:00 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1647896936; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=HKAfjHtn8UUB73F9UHR+E76cyc9RjB2B+V5NLEEKJL0=; b=EAgV67D+ro3xMrrzSLafNiLEQyIa5gmhjLWVw7PdzbBeLwdE9CBE53ZTbvVEtcaQ+Anqmn kj3ez4dYtxDGqRd2oOMWBmMykvyEAsCGsdVGiSIhf4PuT0HphID+xukNe5DccgqkAXHfvM A2RwSyGPqHw2Fr5Fz7RYqAVnGaxxBLY= Received: from mimecast-mx02.redhat.com (mimecast-mx02.redhat.com [66.187.233.88]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-127-qsoldZy_NrGK4TpuMSyycw-1; Mon, 21 Mar 2022 17:08:53 -0400 X-MC-Unique: qsoldZy_NrGK4TpuMSyycw-1 Received: from smtp.corp.redhat.com (int-mx03.intmail.prod.int.rdu2.redhat.com [10.11.54.3]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id A13D582A6C2; Mon, 21 Mar 2022 21:08:52 +0000 (UTC) Received: from scv.redhat.com (unknown [10.22.16.64]) by smtp.corp.redhat.com (Postfix) with ESMTP id 480F21121321; Mon, 21 Mar 2022 21:08:52 +0000 (UTC) From: John Snow To: qemu-devel@nongnu.org Subject: [PATCH 10/10] python: rename 'aqmp-tui' to 'qmp-tui' Date: Mon, 21 Mar 2022 17:08:47 -0400 Message-Id: <20220321210847.914787-11-jsnow@redhat.com> In-Reply-To: <20220321210847.914787-1-jsnow@redhat.com> References: <20220321210847.914787-1-jsnow@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.78 on 10.11.54.3 Authentication-Results: relay.mimecast.com; auth=pass smtp.auth=CUSA124A263 smtp.mailfrom=jsnow@redhat.com X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Received-SPF: pass client-ip=170.10.129.124; envelope-from=jsnow@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -21 X-Spam_score: -2.2 X-Spam_bar: -- X-Spam_report: (-2.2 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.082, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H4=0.001, RCVD_IN_MSPIKE_WL=0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001, T_SCC_BODY_TEXT_LINE=-0.01 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Kevin Wolf , Vladimir Sementsov-Ogievskiy , Beraldo Leal , qemu-block@nongnu.org, Markus Armbruster , Hanna Reitz , Cleber Rosa , John Snow Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: "Qemu-devel" This is the last vestige of the "aqmp" moniker surviving in the tree; remove it. Signed-off-by: John Snow Reviewed-by: Beraldo Leal --- python/qemu/qmp/{aqmp_tui.py => qmp_tui.py} | 12 ++++++------ python/setup.cfg | 6 +++--- 2 files changed, 9 insertions(+), 9 deletions(-) rename python/qemu/qmp/{aqmp_tui.py => qmp_tui.py} (98%) diff --git a/python/qemu/qmp/aqmp_tui.py b/python/qemu/qmp/qmp_tui.py similarity index 98% rename from python/qemu/qmp/aqmp_tui.py rename to python/qemu/qmp/qmp_tui.py index 184a3e4690..17dc94e7c3 100644 --- a/python/qemu/qmp/aqmp_tui.py +++ b/python/qemu/qmp/qmp_tui.py @@ -6,13 +6,13 @@ # This work is licensed under the terms of the GNU GPL, version 2 or # later. See the COPYING file in the top-level directory. """ -AQMP TUI +QMP TUI -AQMP TUI is an asynchronous interface built on top the of the AQMP library. +QMP TUI is an asynchronous interface built on top the of the QMP library. It is the successor of QMP-shell and is bought-in as a replacement for it. -Example Usage: aqmp-tui -Full Usage: aqmp-tui --help +Example Usage: qmp-tui +Full Usage: qmp-tui --help """ import argparse @@ -129,7 +129,7 @@ def has_handler_type(logger: logging.Logger, class App(QMPClient): """ - Implements the AQMP TUI. + Implements the QMP TUI. Initializes the widgets and starts the urwid event loop. @@ -612,7 +612,7 @@ def main() -> None: Driver of the whole script, parses arguments, initialize the TUI and the logger. """ - parser = argparse.ArgumentParser(description='AQMP TUI') + parser = argparse.ArgumentParser(description='QMP TUI') parser.add_argument('qmp_server', help='Address of the QMP server. ' 'Format ') parser.add_argument('--num-retries', type=int, default=10, diff --git a/python/setup.cfg b/python/setup.cfg index 773e51b34e..e877ea5647 100644 --- a/python/setup.cfg +++ b/python/setup.cfg @@ -51,7 +51,7 @@ devel = fuse = fusepy >= 2.0.4 -# AQMP TUI dependencies +# QMP TUI dependencies tui = urwid >= 2.1.2 urwid-readline >= 0.13 @@ -68,7 +68,7 @@ console_scripts = qemu-ga-client = qemu.utils.qemu_ga_client:main qmp-shell = qemu.qmp.qmp_shell:main qmp-shell-wrap = qemu.qmp.qmp_shell:main_wrap - aqmp-tui = qemu.qmp.aqmp_tui:main [tui] + qmp-tui = qemu.qmp.qmp_tui:main [tui] [flake8] extend-ignore = E722 # Prefer pylint's bare-except checks to flake8's @@ -84,7 +84,7 @@ namespace_packages = True # fusepy has no type stubs: allow_subclassing_any = True -[mypy-qemu.qmp.aqmp_tui] +[mypy-qemu.qmp.qmp_tui] # urwid and urwid_readline have no type stubs: allow_subclassing_any = True