From nobody Mon Feb 9 14:24:56 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1645459342242907.7291782362247; Mon, 21 Feb 2022 08:02:22 -0800 (PST) Received: from localhost ([::1]:44654 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1nMB8m-0002SE-UD for importer@patchew.org; Mon, 21 Feb 2022 11:02:21 -0500 Received: from eggs.gnu.org ([209.51.188.92]:55168) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1nMB2G-0006cb-PK for qemu-devel@nongnu.org; Mon, 21 Feb 2022 10:55:37 -0500 Received: from beetle.greensocs.com ([5.135.226.135]:35542) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1nMB2D-0002At-MO for qemu-devel@nongnu.org; Mon, 21 Feb 2022 10:55:36 -0500 Received: from crumble.bar.greensocs.com (unknown [172.17.10.6]) by beetle.greensocs.com (Postfix) with ESMTPS id B46CF21C36; Mon, 21 Feb 2022 15:55:31 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=greensocs.com; s=mail; t=1645458931; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=zDC9u9lt816558qvQ9zL3iwMJrJG4eLRj8Dgvj9bAM0=; b=ROLmkmxqyOTK9XOTfCKXt5z7e61sPx4keR5EVNW6B3EoEbVRORcM2STu+0zThKaRU0U+SI UgfTCRdRuak4AQlh07Hru6lJuLG/eD+aBSYQAty+6xqgfMTv3BP8tfV2rrIFxhxFxIA51W TgG0Y/bt/9OV/M6BjgXxLXPQmxLXAac= From: Damien Hedde To: qemu-devel@nongnu.org Subject: [PATCH 1/5] python: qmp_shell: don't prompt when stdin is non-interactive Date: Mon, 21 Feb 2022 16:55:15 +0100 Message-Id: <20220221155519.2367-2-damien.hedde@greensocs.com> X-Mailer: git-send-email 2.35.1 In-Reply-To: <20220221155519.2367-1-damien.hedde@greensocs.com> References: <20220221155519.2367-1-damien.hedde@greensocs.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=5.135.226.135; envelope-from=damien.hedde@greensocs.com; helo=beetle.greensocs.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, 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: Damien Hedde , Eduardo Habkost , John Snow , Cleber Rosa Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: fail (Header signature does not verify) X-ZM-MESSAGEID: 1645459344726100001 Content-Type: text/plain; charset="utf-8" In that case, there is no echo anyway. So the prompt is just garbage. Signed-off-by: Damien Hedde --- python/qemu/aqmp/qmp_shell.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/python/qemu/aqmp/qmp_shell.py b/python/qemu/aqmp/qmp_shell.py index d11bf54b00..a6e0f5af42 100644 --- a/python/qemu/aqmp/qmp_shell.py +++ b/python/qemu/aqmp/qmp_shell.py @@ -367,6 +367,8 @@ def prompt(self) -> str: """ Return the current shell prompt, including a trailing space. """ + if not sys.stdin.isatty(): + return "" if self._transmode: return 'TRANS> ' return '(QEMU) ' --=20 2.35.1 From nobody Mon Feb 9 14:24:56 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1645459963287174.22849191403373; Mon, 21 Feb 2022 08:12:43 -0800 (PST) Received: from localhost ([::1]:55500 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1nMBIo-0001st-44 for importer@patchew.org; Mon, 21 Feb 2022 11:12:42 -0500 Received: from eggs.gnu.org ([209.51.188.92]:55174) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1nMB2H-0006ci-Ok for qemu-devel@nongnu.org; Mon, 21 Feb 2022 10:55:37 -0500 Received: from beetle.greensocs.com ([5.135.226.135]:35554) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1nMB2E-0002B1-Er for qemu-devel@nongnu.org; Mon, 21 Feb 2022 10:55:36 -0500 Received: from crumble.bar.greensocs.com (unknown [172.17.10.6]) by beetle.greensocs.com (Postfix) with ESMTPS id 072F721C47; Mon, 21 Feb 2022 15:55:33 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=greensocs.com; s=mail; t=1645458933; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=3XildHfwEa3XRRUp9QR/mMklLb2sWGeGTzxz8F8pc/g=; b=O/eMeSw9wC6qBiJXIm8kOfdnv3+PB//wNT6jLv9wi279YS7aeLofYyHp+9QOA+ujiI4o5T Yck9KVBALG5TMbe9/tR9IQYzSGCNS5JXvG99qbOR5GKEbqUYU9aSX4f2vYABbG0csmq3tl /XGwoFOWUbxdRMK3jC4dGRT+ilcqG/o= From: Damien Hedde To: qemu-devel@nongnu.org Subject: [PATCH 2/5] python: qmp_shell: refactor the parsing error handling Date: Mon, 21 Feb 2022 16:55:16 +0100 Message-Id: <20220221155519.2367-3-damien.hedde@greensocs.com> X-Mailer: git-send-email 2.35.1 In-Reply-To: <20220221155519.2367-1-damien.hedde@greensocs.com> References: <20220221155519.2367-1-damien.hedde@greensocs.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=5.135.226.135; envelope-from=damien.hedde@greensocs.com; helo=beetle.greensocs.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, 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: Damien Hedde , Eduardo Habkost , John Snow , Cleber Rosa Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: fail (Header signature does not verify) X-ZM-MESSAGEID: 1645459965401100003 Content-Type: text/plain; charset="utf-8" Instead of handling these error in _excute_cmd(), now raise the exception and let read_exec_command() handle it. Introduce QMPShellParseError (subclass of QMPShellError) to replace QMPShellError. In next commit we will introduce another subclass. Introduce _print_parse_error() method because QMPShell and HMPShell handle the printing differently. Signed-off-by: Damien Hedde --- python/qemu/aqmp/qmp_shell.py | 51 +++++++++++++++++++++-------------- 1 file changed, 31 insertions(+), 20 deletions(-) diff --git a/python/qemu/aqmp/qmp_shell.py b/python/qemu/aqmp/qmp_shell.py index a6e0f5af42..a1bd7d5630 100644 --- a/python/qemu/aqmp/qmp_shell.py +++ b/python/qemu/aqmp/qmp_shell.py @@ -136,6 +136,12 @@ class QMPShellError(QMPError): """ =20 =20 +class QMPShellParseError(QMPShellError): + """ + QMP Shell Parse error class. + """ + + class FuzzyJSON(ast.NodeTransformer): """ This extension of ast.NodeTransformer filters literal "true/false/null" @@ -246,7 +252,7 @@ def _cli_expr(self, for arg in tokens: (key, sep, val) =3D arg.partition('=3D') if sep !=3D '=3D': - raise QMPShellError( + raise QMPShellParseError( f"Expected a key=3Dvalue pair, got '{arg!s}'" ) =20 @@ -258,14 +264,14 @@ def _cli_expr(self, obj =3D parent.get(path, {}) if not isinstance(obj, dict): msg =3D 'Cannot use "{:s}" as both leaf and non-leaf k= ey' - raise QMPShellError(msg.format('.'.join(curpath))) + raise QMPShellParseError(msg.format('.'.join(curpath))) parent[path] =3D obj parent =3D obj if optpath[-1] in parent: if isinstance(parent[optpath[-1]], dict): msg =3D 'Cannot use "{:s}" as both leaf and non-leaf k= ey' - raise QMPShellError(msg.format('.'.join(curpath))) - raise QMPShellError(f'Cannot set "{key}" multiple times') + raise QMPShellParseError(msg.format('.'.join(curpath))) + raise QMPShellParseError(f'Cannot set "{key}" multiple tim= es') parent[optpath[-1]] =3D value =20 def _build_cmd(self, cmdline: str) -> Optional[QMPMessage]: @@ -290,7 +296,7 @@ def _build_cmd(self, cmdline: str) -> Optional[QMPMessa= ge]: self._transmode =3D False if len(cmdargs) > 1: msg =3D 'Unexpected input after close of Transaction sub-s= hell' - raise QMPShellError(msg) + raise QMPShellParseError(msg) qmpcmd =3D { 'execute': 'transaction', 'arguments': {'actions': self._actions} @@ -323,17 +329,17 @@ def _print(self, qmp_message: object) -> None: sort_keys=3Dself.pretty) print(str(jsobj)) =20 + def _print_parse_error(self, err: QMPShellParseError) -> None: + print( + f"Error while parsing command line: {err!s}\n" + "command format: " + "[arg-name1=3Darg1] ... [arg-nameN=3DargN", + file=3Dsys.stderr + ) + def _execute_cmd(self, cmdline: str) -> bool: - try: - qmpcmd =3D self._build_cmd(cmdline) - except QMPShellError as err: - print( - f"Error while parsing command line: {err!s}\n" - "command format: " - "[arg-name1=3Darg1] ... [arg-nameN=3DargN", - file=3Dsys.stderr - ) - return True + qmpcmd =3D self._build_cmd(cmdline) + # For transaction mode, we may have just cached the action: if qmpcmd is None: return True @@ -390,7 +396,11 @@ def read_exec_command(self) -> bool: print(event) return True =20 - return self._execute_cmd(cmdline) + try: + return self._execute_cmd(cmdline) + except QMPShellParseError as err: + self._print_parse_error(err) + return True =20 def repl(self) -> Iterator[None]: """ @@ -456,18 +466,19 @@ def _cmd_passthrough(self, cmdline: str, } }) =20 + def _print_parse_error(self, err: QMPShellParseError) -> None: + print(f"{err!s}") + def _execute_cmd(self, cmdline: str) -> bool: if cmdline.split()[0] =3D=3D "cpu": # trap the cpu command, it requires special setting try: idx =3D int(cmdline.split()[1]) if 'return' not in self._cmd_passthrough('info version', i= dx): - print('bad CPU index') - return True + raise QMPShellParseError('bad CPU index') self._cpu_index =3D idx except ValueError: - print('cpu command takes an integer argument') - return True + raise QMPShellParseError('cpu command takes an integer arg= ument') resp =3D self._cmd_passthrough(cmdline, self._cpu_index) if resp is None: print('Disconnected') --=20 2.35.1 From nobody Mon Feb 9 14:24:56 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1645459961477450.51734139611256; Mon, 21 Feb 2022 08:12:41 -0800 (PST) Received: from localhost ([::1]:55356 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1nMBIm-0001md-23 for importer@patchew.org; Mon, 21 Feb 2022 11:12:40 -0500 Received: from eggs.gnu.org ([209.51.188.92]:55180) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1nMB2H-0006cj-UV for qemu-devel@nongnu.org; Mon, 21 Feb 2022 10:55:37 -0500 Received: from beetle.greensocs.com ([5.135.226.135]:35566) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1nMB2F-0002BB-BK for qemu-devel@nongnu.org; Mon, 21 Feb 2022 10:55:37 -0500 Received: from crumble.bar.greensocs.com (unknown [172.17.10.6]) by beetle.greensocs.com (Postfix) with ESMTPS id 1463B21CC4; Mon, 21 Feb 2022 15:55:34 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=greensocs.com; s=mail; t=1645458934; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=L9InGvuw5dK4vKcHkANkKnIbYK5rhAl1tiLfsUcR2vA=; b=ipK7BuuDSNtm2ro0VYVxoG+obU9SkwToaq5yuLo1oABbKhBlcuhE5WX+xJrmtDA76Xiqea B4gFmrm7gIw/dzkeMGkX0vjAFnpHFKp7Jv5AbiQK/mnx1ixg5aMj4yMyVsHt/Q9m+4nYUw 6roHKE68Fj6h0hfxu6YX1vNBP+NKoOI= From: Damien Hedde To: qemu-devel@nongnu.org Subject: [PATCH 3/5] python: qmp_shell: refactor disconnection handling Date: Mon, 21 Feb 2022 16:55:17 +0100 Message-Id: <20220221155519.2367-4-damien.hedde@greensocs.com> X-Mailer: git-send-email 2.35.1 In-Reply-To: <20220221155519.2367-1-damien.hedde@greensocs.com> References: <20220221155519.2367-1-damien.hedde@greensocs.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=5.135.226.135; envelope-from=damien.hedde@greensocs.com; helo=beetle.greensocs.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, 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: Damien Hedde , Eduardo Habkost , John Snow , Cleber Rosa Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: fail (Header signature does not verify) X-ZM-MESSAGEID: 1645459963514100001 Content-Type: text/plain; charset="utf-8" Introduce QMPShellConnectError (subclass of QMPShellError) to handle disconnection in read_exec_command(). Signed-off-by: Damien Hedde --- python/qemu/aqmp/qmp_shell.py | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/python/qemu/aqmp/qmp_shell.py b/python/qemu/aqmp/qmp_shell.py index a1bd7d5630..cce7732ba2 100644 --- a/python/qemu/aqmp/qmp_shell.py +++ b/python/qemu/aqmp/qmp_shell.py @@ -142,6 +142,12 @@ class QMPShellParseError(QMPShellError): """ =20 =20 +class QMPShellConnectError(QMPShellError): + """ + QMP Shell Connect error class. + """ + + class FuzzyJSON(ast.NodeTransformer): """ This extension of ast.NodeTransformer filters literal "true/false/null" @@ -347,8 +353,7 @@ def _execute_cmd(self, cmdline: str) -> bool: self._print(qmpcmd) resp =3D self.cmd_obj(qmpcmd) if resp is None: - print('Disconnected') - return False + raise QMPShellConnectError('Disconnected') self._print(resp) return True =20 @@ -400,6 +405,9 @@ def read_exec_command(self) -> bool: return self._execute_cmd(cmdline) except QMPShellParseError as err: self._print_parse_error(err) + except QMPShellConnectError as err: + print(f"{err!s}"); + return False return True =20 def repl(self) -> Iterator[None]: @@ -481,8 +489,7 @@ def _execute_cmd(self, cmdline: str) -> bool: raise QMPShellParseError('cpu command takes an integer arg= ument') resp =3D self._cmd_passthrough(cmdline, self._cpu_index) if resp is None: - print('Disconnected') - return False + raise QMPShellConnectError('Disconnected') assert 'return' in resp or 'error' in resp if 'return' in resp: # Success --=20 2.35.1 From nobody Mon Feb 9 14:24:56 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1645459355942751.9907666200215; Mon, 21 Feb 2022 08:02:35 -0800 (PST) Received: from localhost ([::1]:44686 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1nMB90-0002Tp-Io for importer@patchew.org; Mon, 21 Feb 2022 11:02:34 -0500 Received: from eggs.gnu.org ([209.51.188.92]:55228) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1nMB2K-0006eW-9K for qemu-devel@nongnu.org; Mon, 21 Feb 2022 10:55:40 -0500 Received: from beetle.greensocs.com ([5.135.226.135]:35576) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1nMB2H-0002BZ-Gz for qemu-devel@nongnu.org; Mon, 21 Feb 2022 10:55:39 -0500 Received: from crumble.bar.greensocs.com (unknown [172.17.10.6]) by beetle.greensocs.com (Postfix) with ESMTPS id 1C56D21CCE; Mon, 21 Feb 2022 15:55:35 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=greensocs.com; s=mail; t=1645458935; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=adKF6/kzoZwx7qMvkl5SLyG2oeu0edQPfJy1BbduMxk=; b=CN1F5PC0yF7P87NhZuM/8+v5oCp/lta5TOIMQoRCsxgon+aW0Knvqja62tWg+CBxQVw76G 2aB5iabEPmmLmNBKIjGUYhzy/EZivUsN0dlaTZ04x60MpR2/1NtyLMY36CtUk5wQWn/xCD 10AxQ4R4OXbNLGr004348GJFMlpGgp8= From: Damien Hedde To: qemu-devel@nongnu.org Subject: [PATCH 4/5] python: qmp_shell: add -e/--exit-on-error option Date: Mon, 21 Feb 2022 16:55:18 +0100 Message-Id: <20220221155519.2367-5-damien.hedde@greensocs.com> X-Mailer: git-send-email 2.35.1 In-Reply-To: <20220221155519.2367-1-damien.hedde@greensocs.com> References: <20220221155519.2367-1-damien.hedde@greensocs.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=5.135.226.135; envelope-from=damien.hedde@greensocs.com; helo=beetle.greensocs.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, 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: Damien Hedde , Eduardo Habkost , John Snow , Cleber Rosa Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: fail (Header signature does not verify) X-ZM-MESSAGEID: 1645459358187100002 Content-Type: text/plain; charset="utf-8" This option makes qmp_shell exit (with error code 1) as soon as one of the following error occurs: + command parsing error + disconnection + command failure (response is an error) _execute_cmd() method now returns None or the response so that read_exec_command() can do the last check. This is meant to be used in combination with an input file redirection. It allows to store a list of commands into a file and try to run them by qmp_shell and easily see if it failed or not. Signed-off-by: Damien Hedde --- python/qemu/aqmp/qmp_shell.py | 39 +++++++++++++++++++++++++---------- 1 file changed, 28 insertions(+), 11 deletions(-) diff --git a/python/qemu/aqmp/qmp_shell.py b/python/qemu/aqmp/qmp_shell.py index cce7732ba2..dd38ef8a13 100644 --- a/python/qemu/aqmp/qmp_shell.py +++ b/python/qemu/aqmp/qmp_shell.py @@ -11,7 +11,7 @@ """ Low-level QEMU shell on top of QMP. =20 -usage: qmp-shell [-h] [-H] [-N] [-v] [-p] qmp_server +usage: qmp-shell [-h] [-H] [-N] [-v] [-p] [-e] qmp_server =20 positional arguments: qmp_server < UNIX socket path | TCP address:port > @@ -23,6 +23,8 @@ Skip negotiate (for qemu-ga) -v, --verbose Verbose (echo commands sent and received) -p, --pretty Pretty-print JSON + -e, --exit-on-error Exit when an error occurs (command parsing, + disconnection and command failure) =20 =20 Start QEMU with: @@ -177,9 +179,11 @@ class QMPShell(QEMUMonitorProtocol): :param address: Address of the QMP server. :param pretty: Pretty-print QMP messages. :param verbose: Echo outgoing QMP messages to console. + :param raise_error: Don't continue after an error occured """ def __init__(self, address: SocketAddrT, - pretty: bool =3D False, verbose: bool =3D False): + pretty: bool =3D False, verbose: bool =3D False, + raise_error: bool =3D False): super().__init__(address) self._greeting: Optional[QMPMessage] =3D None self._completer =3D QMPCompleter() @@ -189,6 +193,7 @@ def __init__(self, address: SocketAddrT, '.qmp-shell_history') self.pretty =3D pretty self.verbose =3D verbose + self.raise_error =3D raise_error =20 def close(self) -> None: # Hook into context manager of parent to save shell history. @@ -343,19 +348,19 @@ def _print_parse_error(self, err: QMPShellParseError)= -> None: file=3Dsys.stderr ) =20 - def _execute_cmd(self, cmdline: str) -> bool: + def _execute_cmd(self, cmdline: str) -> Optional[QMPMessage]: qmpcmd =3D self._build_cmd(cmdline) =20 # For transaction mode, we may have just cached the action: if qmpcmd is None: - return True + return None if self.verbose: self._print(qmpcmd) resp =3D self.cmd_obj(qmpcmd) if resp is None: raise QMPShellConnectError('Disconnected') self._print(resp) - return True + return resp =20 def connect(self, negotiate: bool =3D True) -> None: self._greeting =3D super().connect(negotiate) @@ -401,8 +406,13 @@ def read_exec_command(self) -> bool: print(event) return True =20 + if self.raise_error: + resp =3D self._execute_cmd(cmdline) + if resp and 'error' in resp: + raise QMPShellError(f"Command failed: {resp['error']}") + return True try: - return self._execute_cmd(cmdline) + self._execute_cmd(cmdline) except QMPShellParseError as err: self._print_parse_error(err) except QMPShellConnectError as err: @@ -477,7 +487,7 @@ def _cmd_passthrough(self, cmdline: str, def _print_parse_error(self, err: QMPShellParseError) -> None: print(f"{err!s}") =20 - def _execute_cmd(self, cmdline: str) -> bool: + def _execute_cmd(self, cmdline: str) -> Optional[QMPMessage]: if cmdline.split()[0] =3D=3D "cpu": # trap the cpu command, it requires special setting try: @@ -498,7 +508,7 @@ def _execute_cmd(self, cmdline: str) -> bool: else: # Error print('%s: %s' % (resp['error']['class'], resp['error']['desc'= ])) - return True + return resp =20 def show_banner(self, msg: str =3D 'Welcome to the HMP shell!') -> Non= e: QMPShell.show_banner(self, msg) @@ -523,6 +533,9 @@ def main() -> None: help=3D'Verbose (echo commands sent and received)') parser.add_argument('-p', '--pretty', action=3D'store_true', help=3D'Pretty-print JSON') + parser.add_argument('-e', '--exit-on-error', action=3D'store_true', + help=3D'Exit when an error occurs (command parsing= ,' + ' disconnection and command failure)') =20 default_server =3D os.environ.get('QMP_SOCKET') parser.add_argument('qmp_server', action=3D'store', @@ -541,7 +554,8 @@ def main() -> None: parser.error(f"Bad port number: {args.qmp_server}") return # pycharm doesn't know error() is noreturn =20 - with shell_class(address, args.pretty, args.verbose) as qemu: + with shell_class(address, args.pretty, args.verbose, + args.exit_on_error) as qemu: try: qemu.connect(negotiate=3Dnot args.skip_negotiation) except ConnectError as err: @@ -549,8 +563,11 @@ def main() -> None: die(f"Couldn't connect to {args.qmp_server}: {err!s}") die(str(err)) =20 - for _ in qemu.repl(): - pass + try: + for _ in qemu.repl(): + pass + except QMPShellError as err: + die(str(err)) =20 =20 if __name__ =3D=3D '__main__': --=20 2.35.1 From nobody Mon Feb 9 14:24:56 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1645459653002852.8924522074927; Mon, 21 Feb 2022 08:07:33 -0800 (PST) Received: from localhost ([::1]:48368 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1nMBDn-0005BT-Pd for importer@patchew.org; Mon, 21 Feb 2022 11:07:31 -0500 Received: from eggs.gnu.org ([209.51.188.92]:55238) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1nMB2L-0006ek-0R for qemu-devel@nongnu.org; Mon, 21 Feb 2022 10:55:41 -0500 Received: from beetle.greensocs.com ([5.135.226.135]:35588) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1nMB2H-0002Bl-Tf for qemu-devel@nongnu.org; Mon, 21 Feb 2022 10:55:40 -0500 Received: from crumble.bar.greensocs.com (unknown [172.17.10.6]) by beetle.greensocs.com (Postfix) with ESMTPS id 82DEC21EBE; Mon, 21 Feb 2022 15:55:36 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=greensocs.com; s=mail; t=1645458936; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=Ye4DkYiS7T2Juwk3S1UpOfiAeeqAlWPrmNV+EwdOzhI=; b=T6RoeFbG9DO9xOhqeSGgbH1dWhdqJ3KuTFH4I40ApJTMdLjN6OC063Q7Eti1MsZmuMNi2E hC0J4VN0fp8jys/TlhFYcUkyBgMGaW2pipqYPeKxNXhbZnOEKpHztld5cmLxVCCTyR++Ke N9C9nq9bipm1LBr4gV7N35hKdVOmY/g= From: Damien Hedde To: qemu-devel@nongnu.org Subject: [PATCH 5/5] python: qmp_shell: handle comment lines and escaped eol Date: Mon, 21 Feb 2022 16:55:19 +0100 Message-Id: <20220221155519.2367-6-damien.hedde@greensocs.com> X-Mailer: git-send-email 2.35.1 In-Reply-To: <20220221155519.2367-1-damien.hedde@greensocs.com> References: <20220221155519.2367-1-damien.hedde@greensocs.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=5.135.226.135; envelope-from=damien.hedde@greensocs.com; helo=beetle.greensocs.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, 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: Damien Hedde , Eduardo Habkost , John Snow , Cleber Rosa Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: fail (Header signature does not verify) X-ZM-MESSAGEID: 1645459655142100001 Content-Type: text/plain; charset="utf-8" In order to support more user-friendly command list file, this commit adds the support for: + comment lines: line staring by '#' are ignored + escaped enf-of-line: line with trailing ' \' are continued on next one For eol: we impose a space before the '\' in order not to trigger the escape if the '\' is for example at the end of a value in a 'key=3Dvalue' sequence. Althought it does not have any real interest in interactive mode, the prompt is adapted when in that case. Signed-off-by: Damien Hedde --- python/qemu/aqmp/qmp_shell.py | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/python/qemu/aqmp/qmp_shell.py b/python/qemu/aqmp/qmp_shell.py index dd38ef8a13..64cd31dcd6 100644 --- a/python/qemu/aqmp/qmp_shell.py +++ b/python/qemu/aqmp/qmp_shell.py @@ -188,6 +188,7 @@ def __init__(self, address: SocketAddrT, self._greeting: Optional[QMPMessage] =3D None self._completer =3D QMPCompleter() self._transmode =3D False + self._escaped_eol =3D False self._actions: List[QMPMessage] =3D [] self._histfile =3D os.path.join(os.path.expanduser('~'), '.qmp-shell_history') @@ -385,6 +386,8 @@ def prompt(self) -> str: """ if not sys.stdin.isatty(): return "" + if self._escaped_eol: + return '> ' if self._transmode: return 'TRANS> ' return '(QEMU) ' @@ -397,6 +400,11 @@ def read_exec_command(self) -> bool: """ try: cmdline =3D input(self.prompt) + self._escaped_eol =3D True + while cmdline[-2:] =3D=3D ' \\': + #only remove the trailing '\', keep the space + cmdline =3D cmdline[:-1] + input(self.prompt) + self._escaped_eol =3D False except EOFError: print() return False @@ -406,6 +414,10 @@ def read_exec_command(self) -> bool: print(event) return True =20 + if cmdline[0] =3D=3D '#': + #consider these lines as comments + return True + if self.raise_error: resp =3D self._execute_cmd(cmdline) if resp and 'error' in resp: --=20 2.35.1