From patchwork Fri Jul 30 20:18:34 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Niteesh G. S." X-Patchwork-Id: 12411831 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-13.5 required=3.0 tests=BAYES_00, DKIM_ADSP_CUSTOM_MED,DKIM_INVALID,DKIM_SIGNED,FREEMAIL_FORGED_FROMDOMAIN, FREEMAIL_FROM,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER, INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED, USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id DE720C4338F for ; Fri, 30 Jul 2021 20:20:28 +0000 (UTC) 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 mail.kernel.org (Postfix) with ESMTPS id 7EE5A60D07 for ; Fri, 30 Jul 2021 20:20:28 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.4.1 mail.kernel.org 7EE5A60D07 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=gmail.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=nongnu.org Received: from localhost ([::1]:56922 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1m9Yzb-0006eX-Lq for qemu-devel@archiver.kernel.org; Fri, 30 Jul 2021 16:20:27 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:50754) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1m9YyG-00043t-Sp for qemu-devel@nongnu.org; Fri, 30 Jul 2021 16:19:04 -0400 Received: from mail-pj1-x1034.google.com ([2607:f8b0:4864:20::1034]:43629) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1m9YyF-0000nz-7M for qemu-devel@nongnu.org; Fri, 30 Jul 2021 16:19:04 -0400 Received: by mail-pj1-x1034.google.com with SMTP id pj14-20020a17090b4f4eb029017786cf98f9so5384832pjb.2 for ; Fri, 30 Jul 2021 13:19:02 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=Gfhflo12UGoXr97Ilr5PTd+AyNfqb0V7Rdiv5SvS+aE=; b=gKNPncPJmmnoFTo/BE5gkoQS1mC5Bg6ssSG4asfujdHLB5EKAOOukNcKHbzEyiMtaX Yj048Z8NEOCVhD8urxa3ILelis9XoJnI/i1omrdWeDKkKJfTw1sM5cQzWeQYxUFNUFd3 5Dh+JVTmKuhiyxEW4Mm09eLZFoqcsrVZo5q/5i5rI5ML/1SkHPW9HYBV42GGXp1D/lV9 dOruKuR+oi6F0pFjEgQD7p3DJXJdP2/f25nPjURMjVs7KIcpRXhEcQiwNIsyU/MSlUvU SlAZnY/SEtZsb58pwARfjZ07l/pptSJ2qztUQMwIEnoBJAEOJh6S6ftEtb+yxzsa/Tfz ATzA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=Gfhflo12UGoXr97Ilr5PTd+AyNfqb0V7Rdiv5SvS+aE=; b=ASdKaywAp6hgB2yl+QF52vIsMr8//CjKpMDc0aFhBI4OMdREl+6U5C4P8lja36Eb6k Uf68KxjSsJc5o2RhcmH9jjYcoc8TjJ527ypA/KAMJyGbRe3ySWuTSnq/zUhka+AA06zM qB6K2AUJPNROIAdzwYuMALuAYMRGzmilxJy6g7zDXGrdTBpWAgwMU/pB/ZKjQMdUHxSa IagG6hEOpWi3EdO4FW3no53oCYEhavpFVtWsG1Nn3BCw2p+he4GTFVwzgPGNNJzTCzdq MILm0Rr+tzfRBieVa8Ek3KMKWKCRndSxBA7+xFn7owBGgp43eKlFwVP00p+G4IJPNVqL GCrw== X-Gm-Message-State: AOAM532JE7vUzWi0CAUtWgfh1U4X2K7oTjpW6TaJ4UEoz4GIMRsVfj67 wZay0eRVmneIxEzvU8p9wYNdwggDPj9MoQ== X-Google-Smtp-Source: ABdhPJxN2W3AuV1wXR0rGQxRkVqT4HldzmLyUjHjMvWdV6aNVxqz1IhMxvWbnM9tR81wRprCuDDBpA== X-Received: by 2002:a17:90a:d918:: with SMTP id c24mr5037191pjv.104.1627676341748; Fri, 30 Jul 2021 13:19:01 -0700 (PDT) Received: from localhost.localdomain ([120.138.12.243]) by smtp.gmail.com with ESMTPSA id s50sm3256842pfw.212.2021.07.30.13.18.58 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 30 Jul 2021 13:19:01 -0700 (PDT) From: G S Niteesh Babu To: qemu-devel@nongnu.org Subject: [PATCH v3 01/13] python/aqmp: Fix wait_closed work-around for python 3.6 Date: Sat, 31 Jul 2021 01:48:34 +0530 Message-Id: <20210730201846.5147-2-niteesh.gs@gmail.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20210730201846.5147-1-niteesh.gs@gmail.com> References: <20210730201846.5147-1-niteesh.gs@gmail.com> Received-SPF: pass client-ip=2607:f8b0:4864:20::1034; envelope-from=niteesh.gs@gmail.com; helo=mail-pj1-x1034.google.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, FREEMAIL_FROM=0.001, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: ehabkost@redhat.com, kchamart@redhat.com, jsnow@redhat.com, armbru@redhat.com, wainersm@redhat.com, G S Niteesh Babu , stefanha@redhat.com, crosa@redhat.com, eblake@redhat.com Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: "Qemu-devel" Before this patch the wait_closed work-around for python 3.6 fails during disconnect. This is a temproray work around for which might be fixed in the future or will be completely removed when the minimum python version is raised to 3.7. This patch was originally written by John Snow Signed-off-by: G S Niteesh Babu --- python/qemu/aqmp/util.py | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/python/qemu/aqmp/util.py b/python/qemu/aqmp/util.py index de0df44cbd..eaa5fc7d5f 100644 --- a/python/qemu/aqmp/util.py +++ b/python/qemu/aqmp/util.py @@ -134,7 +134,17 @@ def is_closing(writer: asyncio.StreamWriter) -> bool: while not transport.is_closing(): await asyncio.sleep(0) - await flush(writer) + + # This is an ugly workaround, but it's the best I can come up with. + sock = transport.get_extra_info('socket') + + if sock is None: + # Our transport doesn't have a socket? ... + # Nothing we can reasonably do. + return + + while sock.fileno() != -1: + await asyncio.sleep(0) def asyncio_run(coro: Coroutine[Any, Any, T], *, debug: bool = False) -> T: From patchwork Fri Jul 30 20:18:35 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Niteesh G. S." X-Patchwork-Id: 12411835 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-13.6 required=3.0 tests=BAYES_00, DKIM_ADSP_CUSTOM_MED,DKIM_INVALID,DKIM_SIGNED,FREEMAIL_FORGED_FROMDOMAIN, FREEMAIL_FROM,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER, INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 2CB30C432BE for ; Fri, 30 Jul 2021 20:21:09 +0000 (UTC) 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 mail.kernel.org (Postfix) with ESMTPS id E6D4860D07 for ; Fri, 30 Jul 2021 20:21:08 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.4.1 mail.kernel.org E6D4860D07 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=gmail.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=nongnu.org Received: from localhost ([::1]:59578 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1m9Z0F-0008TG-SL for qemu-devel@archiver.kernel.org; Fri, 30 Jul 2021 16:21:07 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:50766) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1m9YyK-0004CJ-4e for qemu-devel@nongnu.org; Fri, 30 Jul 2021 16:19:08 -0400 Received: from mail-pj1-x102e.google.com ([2607:f8b0:4864:20::102e]:55813) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1m9YyI-0000ps-N0 for qemu-devel@nongnu.org; Fri, 30 Jul 2021 16:19:07 -0400 Received: by mail-pj1-x102e.google.com with SMTP id ca5so16807675pjb.5 for ; Fri, 30 Jul 2021 13:19:06 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=1DPcV7mS//zf94TYad0tRK5Q1rQ+GfV9pqZ5+VAHcjM=; b=ElfmrPGTMGVbnQDXfE8GsIevNXzgQuABTeZMKiXn1AVg1YP72uFBWznJjtB5i4qC5j W+InBlMbAFVetozH5jtj6cYrr8giK5HTIDCsW7oEuqulwhCA9zflnNz1CeTpUjPZMtnH obv7rtWsh+vBSs7b7JEyu5kAyQiylkEvTlniXdZmpuUUmnSGDKYOH/YkBh5Fgpw5jGnx aPjl5jEqfdSjw99J1aNZP0gDl+pb58RMcryHRcceegIBtoSFjsWKl+CeCJKJUXyA12oQ K/5Uanq5Q8ifrLp3duyUtthE4GfVam5dJeLwI3eAJg25abPfe5f6H+MIeXJNy3QHpyll Sftw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=1DPcV7mS//zf94TYad0tRK5Q1rQ+GfV9pqZ5+VAHcjM=; b=hld7ZnAWk8/g97Dk737C6r3jZnhPjfTucxLDtaVbrwD0HHbuSO3+BWnKPWh43942Iq mQ5UYLdSWHlR3VX2UmB6YzZhsMpijOYGTALfTx4kfIz4szRHXuTMoAGSW8gAVprDY+vb mz+WbvNk0x2gygjbOXAdMRz5kgZFv0fd3/xsLhN3YW7vyi1FkNbsOwfb++huten1hXRT SeOoxBPOSWcD1yr4D8M7o9nyuvVeEK0WZiexD7EJRTW2nhtkQu0U+/zUML9EXkHzPoCv okkb591dDdAlaS56xu+YhOAJQJldEg9/n4fPe2yJ7+Cy/wm+eOg/+9a0/2jnypkl0MBX +hZg== X-Gm-Message-State: AOAM530KpI4mhPx49y13tCVA59ii9jHpbO76v3On15m4xooxwWJzcfvp wRQh40yjb7TRPt+cF+JtvAHxOjfHj4Pvkw== X-Google-Smtp-Source: ABdhPJxEn/QBRBDR343a+nuWBm5jsNXo25hLrZ44CyXIB8VLwxrVNRDXOfzbmHNKmrcedDVFtJs/OQ== X-Received: by 2002:a17:90a:fef:: with SMTP id 102mr4788892pjz.148.1627676345315; Fri, 30 Jul 2021 13:19:05 -0700 (PDT) Received: from localhost.localdomain ([120.138.12.243]) by smtp.gmail.com with ESMTPSA id s50sm3256842pfw.212.2021.07.30.13.19.02 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 30 Jul 2021 13:19:05 -0700 (PDT) From: G S Niteesh Babu To: qemu-devel@nongnu.org Subject: [PATCH v3 02/13] python: disable pylint errors for aqmp-tui Date: Sat, 31 Jul 2021 01:48:35 +0530 Message-Id: <20210730201846.5147-3-niteesh.gs@gmail.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20210730201846.5147-1-niteesh.gs@gmail.com> References: <20210730201846.5147-1-niteesh.gs@gmail.com> Received-SPF: pass client-ip=2607:f8b0:4864:20::102e; envelope-from=niteesh.gs@gmail.com; helo=mail-pj1-x102e.google.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, FREEMAIL_FROM=0.001, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: ehabkost@redhat.com, kchamart@redhat.com, jsnow@redhat.com, armbru@redhat.com, wainersm@redhat.com, G S Niteesh Babu , stefanha@redhat.com, crosa@redhat.com, eblake@redhat.com Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: "Qemu-devel" Disable missing-docstring and fixme pylint warnings. This is because since the AQMP is just a prototype it is currently not documented properly and lot of todo and fixme's are still in place. Signed-off-by: G S Niteesh Babu --- python/setup.cfg | 2 ++ 1 file changed, 2 insertions(+) diff --git a/python/setup.cfg b/python/setup.cfg index 2573cd7bfb..7a30dd5b09 100644 --- a/python/setup.cfg +++ b/python/setup.cfg @@ -90,6 +90,8 @@ ignore_missing_imports = True # --disable=W". disable=too-many-function-args, # mypy handles this with less false positives. no-member, # mypy also handles this better. + missing-docstring, # FIXME + fixme, # FIXME [pylint.basic] # Good variable names which should always be accepted, separated by a comma. From patchwork Fri Jul 30 20:18:36 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Niteesh G. S." X-Patchwork-Id: 12411843 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-13.6 required=3.0 tests=BAYES_00, DKIM_ADSP_CUSTOM_MED,DKIM_INVALID,DKIM_SIGNED,FREEMAIL_FORGED_FROMDOMAIN, FREEMAIL_FROM,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER, INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 04991C4338F for ; Fri, 30 Jul 2021 20:23:13 +0000 (UTC) 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 mail.kernel.org (Postfix) with ESMTPS id BF0D960E09 for ; Fri, 30 Jul 2021 20:23:12 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.4.1 mail.kernel.org BF0D960E09 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=gmail.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=nongnu.org Received: from localhost ([::1]:39650 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1m9Z2F-0005mz-TG for qemu-devel@archiver.kernel.org; Fri, 30 Jul 2021 16:23:11 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:50778) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1m9YyN-0004NZ-N3 for qemu-devel@nongnu.org; Fri, 30 Jul 2021 16:19:11 -0400 Received: from mail-pj1-x102a.google.com ([2607:f8b0:4864:20::102a]:55143) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1m9YyM-0000rF-56 for qemu-devel@nongnu.org; Fri, 30 Jul 2021 16:19:11 -0400 Received: by mail-pj1-x102a.google.com with SMTP id b6so16832836pji.4 for ; Fri, 30 Jul 2021 13:19:09 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=JAf48jWFc6CWhxcz/To0pdxZA1eMGrXjmRvqBvFFYSU=; b=q503bZuiLhXVqah2BTSEAyopnBjkbw+au1CMnk+E9udcFYfNRPtCZzHDy2ZWtq9Q/E qIyUfO8cYlUxHU6Q/xNflyQQrNXvAjcrzlopOQwgRJUjj31IrzBEHLJgJ4wMM9PIZxow 6buqqhrWd39FRHn+nmS6IhQGDEF/cg0D6zrpFT5vJeIZ/6q2Pa4beLQoovBVweIeBrWR ZQLkXd3HaDpIY2Ux2V17fG9l2l7Jwcn9LI+QAVCcYE4QijPcnYF8lwF1BxqTs+2lKZjo EDxJEXmbAiZFvGzIWIvDc6pldwTDshftGvcNoqB4QQtqqpCz/Be3u0b4Solz9fceHAAx 90sg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=JAf48jWFc6CWhxcz/To0pdxZA1eMGrXjmRvqBvFFYSU=; b=fZ6WWQEi61j0zIPcgS42uiFy/bm8CMx/wG+ME6aXuYmEdeH97R8NR0h6+J7oLK8q+x /qgRO0veEcYtWpEkBnn5rWfsknc0FpWBos8PbX9TUf8bTQQIXIm835ZNV8FbvBtgdh3Y FCeq5moYqU3mKJ907wXzfoONc6WpEfblnQeWgKh19D7MxksjoXWSCtlI+aATj7xybZdv k8ErV5mSuN+oaszWudQ18RvOkfrqLoetwdeoijXDVlXJi3O6Gzf8CEH32VCIRhfVWQSQ aE2J7nI0i9d6WjeVVVbpV4Bal9SwteuiGhdA1w6Wg5/BVirJTAh9WO0PFgFElQ0ht9wz wrrw== X-Gm-Message-State: AOAM533VYE0xeULZG8r3ad4LRnkSeQYS32jsnLSolI8q0WudjYGTTAlP KQGaipHsN+jODVOqNTPhCop3mUDkheY9Ww== X-Google-Smtp-Source: ABdhPJyk/pUKKLGWHvwLEd370Wx77HDmf/8ZFUlwoI2lePSYu11Iad2jJ6jcXzx68KmRwnlKC/5Vxw== X-Received: by 2002:a05:6a00:2282:b029:32e:37d2:d35b with SMTP id f2-20020a056a002282b029032e37d2d35bmr4454061pfe.54.1627676348691; Fri, 30 Jul 2021 13:19:08 -0700 (PDT) Received: from localhost.localdomain ([120.138.12.243]) by smtp.gmail.com with ESMTPSA id s50sm3256842pfw.212.2021.07.30.13.19.05 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 30 Jul 2021 13:19:08 -0700 (PDT) From: G S Niteesh Babu To: qemu-devel@nongnu.org Subject: [PATCH v3 03/13] python: Add dependencies for AQMP TUI Date: Sat, 31 Jul 2021 01:48:36 +0530 Message-Id: <20210730201846.5147-4-niteesh.gs@gmail.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20210730201846.5147-1-niteesh.gs@gmail.com> References: <20210730201846.5147-1-niteesh.gs@gmail.com> Received-SPF: pass client-ip=2607:f8b0:4864:20::102a; envelope-from=niteesh.gs@gmail.com; helo=mail-pj1-x102a.google.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, FREEMAIL_FROM=0.001, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: ehabkost@redhat.com, kchamart@redhat.com, jsnow@redhat.com, armbru@redhat.com, wainersm@redhat.com, G S Niteesh Babu , stefanha@redhat.com, crosa@redhat.com, eblake@redhat.com Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: "Qemu-devel" Added dependencies for the upcoming AQMP TUI under the optional 'tui' group. The same dependencies have also been added under the devel group since no work around has been found for optional groups to imply other optional groups. Signed-off-by: G S Niteesh Babu Reviewed-by: John Snow --- python/Pipfile.lock | 12 ++++++++++++ python/setup.cfg | 8 ++++++++ 2 files changed, 20 insertions(+) diff --git a/python/Pipfile.lock b/python/Pipfile.lock index 8ab41a3f60..76cf1e4930 100644 --- a/python/Pipfile.lock +++ b/python/Pipfile.lock @@ -289,6 +289,18 @@ "markers": "python_version < '3.8'", "version": "==3.10.0.0" }, + "urwid": { + "hashes": [ + "sha256:588bee9c1cb208d0906a9f73c613d2bd32c3ed3702012f51efe318a3f2127eae" + ], + "version": "==2.1.2" + }, + "urwid-readline": { + "hashes": [ + "sha256:018020cbc864bb5ed87be17dc26b069eae2755cb29f3a9c569aac3bded1efaf4" + ], + "version": "==0.13" + }, "virtualenv": { "hashes": [ "sha256:14fdf849f80dbb29a4eb6caa9875d476ee2a5cf76a5f5415fa2f1606010ab467", diff --git a/python/setup.cfg b/python/setup.cfg index 7a30dd5b09..d106a0ed7a 100644 --- a/python/setup.cfg +++ b/python/setup.cfg @@ -44,11 +44,18 @@ devel = mypy >= 0.770 pylint >= 2.8.0 tox >= 3.18.0 + urwid >= 2.1.2 + urwid-readline >= 0.13 # Provides qom-fuse functionality fuse = fusepy >= 2.0.4 +# AQMP TUI dependencies +tui = + urwid >= 2.1.2 + urwid-readline >= 0.13 + [options.entry_points] console_scripts = qom = qemu.qmp.qom:main @@ -133,5 +140,6 @@ allowlist_externals = make deps = .[devel] .[fuse] # Workaround to trigger tox venv rebuild + .[tui] # Workaround to trigger tox venv rebuild commands = make check From patchwork Fri Jul 30 20:18:37 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Niteesh G. S." X-Patchwork-Id: 12411839 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-13.5 required=3.0 tests=BAYES_00, DKIM_ADSP_CUSTOM_MED,DKIM_INVALID,DKIM_SIGNED,FREEMAIL_FORGED_FROMDOMAIN, FREEMAIL_FROM,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER, INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED, USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id E93C4C4338F for ; Fri, 30 Jul 2021 20:22:47 +0000 (UTC) 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 mail.kernel.org (Postfix) with ESMTPS id 7DAE060F36 for ; Fri, 30 Jul 2021 20:22:47 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.4.1 mail.kernel.org 7DAE060F36 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=gmail.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=nongnu.org Received: from localhost ([::1]:37210 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1m9Z1q-00048e-Lk for qemu-devel@archiver.kernel.org; Fri, 30 Jul 2021 16:22:46 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:50800) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1m9YyR-0004bh-VX for qemu-devel@nongnu.org; Fri, 30 Jul 2021 16:19:15 -0400 Received: from mail-pj1-x1030.google.com ([2607:f8b0:4864:20::1030]:51019) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1m9YyP-0000tX-Ij for qemu-devel@nongnu.org; Fri, 30 Jul 2021 16:19:15 -0400 Received: by mail-pj1-x1030.google.com with SMTP id l19so16932774pjz.0 for ; Fri, 30 Jul 2021 13:19:13 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=eIUzvV4ImuBy5U+VPYoyF5hhFWzQ9SU4RRHMB9KUCmI=; b=iqncmCm/bqRtjScdB/J3Tw0wblsNzSVVVCe2WwcPw5dl4PpRqz7LuRzMxlkKVMa+cX psnYPMcwTHQJTPu+x9/wrmaGP+WS5wMVhBCNvWmPHGDqlX+CW5epLPyuIhNDE5czQctR Bz2j3lN3EWLzKWeBCdYViOdqIOSozE2/5UnJi7rD8bi+h9wnAYnhh1cBTJu7ZrmDmxGC cjIBNyYiJ+AnPaiSbjTCBHupfoS0w+qsqmz44/yz9yIJHxre21RhFi9h51jOl0Yiw/4c exylm8MfXH3rs+AYbeDdSaB5YCLtPn/jP8M78Xa3wHDMmo9iQkRcymLCsnYzthkeejDG 9nEA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=eIUzvV4ImuBy5U+VPYoyF5hhFWzQ9SU4RRHMB9KUCmI=; b=LguRpEFHAsevrL7biqi3q3IMOYaRtyxAW7yjpvQh7i/G15nkcFp5BgxEiSaTgCOiGa 6WJv3UxLhsnRcFHyyhLhQ7XJuz7v1WuCgcaFs3+WMDm+HF8BghjFW0ll/jsXJc54mgoc WRtD0tpS1P+h9wgRxMoReCj010YY/i08760ecxPnaY1+RSnJ9du+t8Gyu2A9CpzEGKFV bSlzIekdO3AnAWqSJWY32YHdJrIy0uMV3FWNtl5KxPoYx2Ll7nOVGzGZh00Pz2CZV68a Ob8eHNbKAsbO24jMQ09sf4PA+07CvHorXqzqEnk8pwSIZzqUOZiNI+p+tQ/htaO5ksmr 4GTg== X-Gm-Message-State: AOAM531eTvFeWSQSjNy8Jc8kdk8t9pz0uLseFMgpIaS2J86cQxNs8Cs/ T+19Bgzd6uiWMZZhbgjO4Obaq/TtK/qNXw== X-Google-Smtp-Source: ABdhPJx9s9Y230WjEf181kbFxn3OzfZi/hZHWIRuWJT7GE0s99xQGJ+N0ABZD/m/tHyv2kI7HyK3Eg== X-Received: by 2002:a62:584:0:b029:32e:3b57:a1c6 with SMTP id 126-20020a6205840000b029032e3b57a1c6mr4407975pff.13.1627676352044; Fri, 30 Jul 2021 13:19:12 -0700 (PDT) Received: from localhost.localdomain ([120.138.12.243]) by smtp.gmail.com with ESMTPSA id s50sm3256842pfw.212.2021.07.30.13.19.09 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 30 Jul 2021 13:19:11 -0700 (PDT) From: G S Niteesh Babu To: qemu-devel@nongnu.org Subject: [PATCH v3 04/13] python/aqmp-tui: Add AQMP TUI draft Date: Sat, 31 Jul 2021 01:48:37 +0530 Message-Id: <20210730201846.5147-5-niteesh.gs@gmail.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20210730201846.5147-1-niteesh.gs@gmail.com> References: <20210730201846.5147-1-niteesh.gs@gmail.com> Received-SPF: pass client-ip=2607:f8b0:4864:20::1030; envelope-from=niteesh.gs@gmail.com; helo=mail-pj1-x1030.google.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, FREEMAIL_FROM=0.001, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: ehabkost@redhat.com, kchamart@redhat.com, jsnow@redhat.com, armbru@redhat.com, wainersm@redhat.com, G S Niteesh Babu , stefanha@redhat.com, crosa@redhat.com, eblake@redhat.com Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: "Qemu-devel" Added a draft of AQMP TUI. Implements the follwing basic features: 1) Command transmission/reception. 2) Shows events asynchronously. 3) Shows server status in the bottom status bar. Also added necessary pylint, mypy configurations Signed-off-by: G S Niteesh Babu --- python/qemu/aqmp/aqmp_tui.py | 333 +++++++++++++++++++++++++++++++++++ python/setup.cfg | 16 +- 2 files changed, 348 insertions(+), 1 deletion(-) create mode 100644 python/qemu/aqmp/aqmp_tui.py diff --git a/python/qemu/aqmp/aqmp_tui.py b/python/qemu/aqmp/aqmp_tui.py new file mode 100644 index 0000000000..ec9eba0aa7 --- /dev/null +++ b/python/qemu/aqmp/aqmp_tui.py @@ -0,0 +1,333 @@ +# Copyright (c) 2021 +# +# Authors: +# Niteesh Babu G S +# +# 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 argparse +import asyncio +import logging +from logging import Handler +import signal + +import urwid +import urwid_readline + +from ..qmp import QEMUMonitorProtocol, QMPBadPortError +from .message import DeserializationError, Message, UnexpectedTypeError +from .protocol import ConnectError +from .qmp_client import ExecInterruptedError, QMPClient +from .util import create_task, pretty_traceback + + +UPDATE_MSG = 'UPDATE_MSG' + +# Using root logger to enable all loggers under qemu and asyncio +LOGGER = logging.getLogger() + + +def format_json(msg): + """ + Formats given multiline JSON message into a single line message. + Converting into single line is more asthetically pleasing when looking + along with error messages compared to multiline JSON. + """ + # FIXME: Use better formatting mechanism. Might break at more complex JSON + # data. + msg = msg.replace('\n', '') + words = msg.split(' ') + words = [word for word in words if word != ''] + return ' '.join(words) + + +class App(QMPClient): + def __init__(self, address): + urwid.register_signal(type(self), UPDATE_MSG) + self.window = Window(self) + self.address = address + self.aloop = None + super().__init__() + + def add_to_history(self, msg): + urwid.emit_signal(self, UPDATE_MSG, msg) + + def _cb_outbound(self, msg): + # FIXME: I think the ideal way to omit these messages during in-TUI + # logging will be to add a filter to the logger. We can use regex to + # filter out messages starting with 'Request:' or 'Response:' but I + # think a better approach will be encapsulate the message in an object + # and filter based on the object. Encapsulation of the message will + # also be necessary when we want different formatting of messages + # inside TUI. + handler = LOGGER.handlers[0] + if not isinstance(handler, TUILogHandler): + LOGGER.debug('Request: %s', str(msg)) + self.add_to_history('<-- ' + str(msg)) + return msg + + def _cb_inbound(self, msg): + handler = LOGGER.handlers[0] + if not isinstance(handler, TUILogHandler): + LOGGER.debug('Response: %s', str(msg)) + self.add_to_history('--> ' + str(msg)) + return msg + + async def wait_for_events(self): + async for event in self.events: + self.handle_event(event) + + async def _send_to_server(self, raw_msg): + # FIXME: Format the raw_msg in history view to one line. It is not + # pleasing to see multiple lines JSON object with an error statement. + try: + msg = Message(bytes(raw_msg, encoding='utf-8')) + # Format multiline json into a single line JSON, since it is more + # pleasing to look along with err message in TUI. + raw_msg = self.format_json(raw_msg) + await self._raw(msg, assign_id='id' not in msg) + except (ValueError, TypeError) as err: + LOGGER.info('Invalid message: %s', str(err)) + self.add_to_history(f'{raw_msg}: {err}') + except (DeserializationError, UnexpectedTypeError) as err: + LOGGER.info('Invalid message: %s', err.error_message) + self.add_to_history(f'{raw_msg}: {err.error_message}') + except ExecInterruptedError: + LOGGER.info('Error server disconnected before reply') + urwid.emit_signal(self, UPDATE_MSG, + '{"error": "Server disconnected before reply"}') + self._set_status("Server disconnected") + except Exception as err: + LOGGER.error('Exception from _send_to_server: %s', str(err)) + raise err + + def cb_send_to_server(self, msg): + create_task(self._send_to_server(msg)) + + def unhandled_input(self, key): + if key == 'esc': + self.kill_app() + + def kill_app(self): + # TODO: Work on the disconnect logic + create_task(self._kill_app()) + + async def _kill_app(self): + # It is ok to call disconnect even in disconnect state + try: + await self.disconnect() + LOGGER.debug('Disconnect finished. Exiting app') + except Exception as err: + LOGGER.info('_kill_app: %s', str(err)) + # Let the app crash after providing a proper stack trace + raise err + raise urwid.ExitMainLoop() + + def handle_event(self, event): + # FIXME: Consider all states present in qapi/run-state.json + if event['event'] == 'SHUTDOWN': + self._set_status('Server shutdown') + + def _set_status(self, msg: str) -> None: + self.window.footer.set_text(msg) + + def _get_formatted_address(self) -> str: + addr = f'{self.address}' + if isinstance(self.address, tuple): + host, port = self.address + addr = f'{host}:{port}' + return addr + + async def connect_server(self): + try: + await self.connect(self.address) + addr = self._get_formatted_address() + self._set_status(f'Connected to {addr}') + except ConnectError as err: + LOGGER.info('connect_server: ConnectError %s', str(err)) + self._set_status('Server shutdown') + + def run(self, debug=False): + self.aloop = asyncio.get_event_loop() + self.aloop.set_debug(debug) + + # Gracefully handle SIGTERM and SIGINT signals + cancel_signals = [signal.SIGTERM, signal.SIGINT] + for sig in cancel_signals: + self.aloop.add_signal_handler(sig, self.kill_app) + + event_loop = urwid.AsyncioEventLoop(loop=self.aloop) + main_loop = urwid.MainLoop(urwid.AttrMap(self.window, 'background'), + unhandled_input=self.unhandled_input, + handle_mouse=True, + event_loop=event_loop) + + create_task(self.wait_for_events(), self.aloop) + create_task(self.connect_server(), self.aloop) + try: + main_loop.run() + except Exception as err: + LOGGER.error('%s\n%s\n', str(err), pretty_traceback()) + raise err + + +class StatusBar(urwid.Text): + """ + A simple Text widget that currently only shows connection status. + """ + def __init__(self, text=''): + super().__init__(text, align='right') + + +class Editor(urwid_readline.ReadlineEdit): + """ + Support urwid_readline features along with + history support which lacks in urwid_readline + """ + def __init__(self, master): + super().__init__(caption='> ', multiline=True) + self.master = master + self.history = [] + self.last_index = -1 + self.show_history = False + + def keypress(self, size, key): + # TODO: Add some logic for down key and clean up logic if possible. + # Returning None means the key has been handled by this widget + # which otherwise is propogated to the parent widget to be + # handled + msg = self.get_edit_text() + if key == 'up' and not msg: + # Show the history when 'up arrow' is pressed with no input text. + # NOTE: The show_history logic is necessary because in 'multiline' + # mode (which we use) 'up arrow' is used to move between lines. + self.show_history = True + last_msg = self.history[self.last_index] if self.history else '' + self.set_edit_text(last_msg) + self.edit_pos = len(last_msg) + self.last_index += 1 + elif key == 'up' and self.show_history: + if self.last_index < len(self.history): + self.set_edit_text(self.history[self.last_index]) + self.edit_pos = len(self.history[self.last_index]) + self.last_index += 1 + elif key == 'meta enter': + # When using multiline, enter inserts a new line into the editor + # send the input to the server on alt + enter + self.master.cb_send_to_server(msg) + self.history.insert(0, msg) + self.set_edit_text('') + self.last_index = 0 + self.show_history = False + else: + self.show_history = False + self.last_index = 0 + return super().keypress(size, key) + return None + + +class EditorWidget(urwid.Filler): + """ + Wraps CustomEdit + """ + def __init__(self, master): + super().__init__(Editor(master), valign='top') + + +class HistoryBox(urwid.ListBox): + """ + Shows all the QMP message transmitted/received + """ + def __init__(self, master): + self.master = master + self.history = urwid.SimpleFocusListWalker([]) + super().__init__(self.history) + + def add_to_history(self, history): + self.history.append(urwid.Text(history)) + if self.history: + self.history.set_focus(len(self.history) - 1) + + +class HistoryWindow(urwid.Frame): + """ + Composes the HistoryBox and EditorWidget + """ + def __init__(self, master): + self.master = master + self.editor_widget = EditorWidget(master) + self.editor = urwid.LineBox(self.editor_widget) + self.history = HistoryBox(master) + self.body = urwid.Pile([('weight', 80, self.history), + ('weight', 20, self.editor)]) + super().__init__(self.body) + urwid.connect_signal(self.master, UPDATE_MSG, self.cb_add_to_history) + + def cb_add_to_history(self, msg): + self.history.add_to_history(msg) + + +class Window(urwid.Frame): + """ + This is going to be the main window that is going to compose other + windows. In this stage it is unnecesssary but will be necessary in + future when we will have multiple windows and want to the switch between + them and display overlays + """ + def __init__(self, master): + self.master = master + footer = StatusBar() + body = HistoryWindow(master) + super().__init__(body, footer=footer) + + +class TUILogHandler(Handler): + def __init__(self, tui): + super().__init__() + self.tui = tui + + def emit(self, record): + level = record.levelname + msg = record.getMessage() + msg = f'[{level}]: {msg}' + self.tui.add_to_history(msg) + + +def main(): + parser = argparse.ArgumentParser(description='AQMP TUI') + parser.add_argument('qmp_server', help='Address of the QMP server' + '< UNIX socket path | TCP addr:port >') + parser.add_argument('--log-file', help='The Log file name') + parser.add_argument('--log-level', default='WARNING', + help='Log level ') + parser.add_argument('--asyncio-debug', action='store_true', + help='Enable debug mode for asyncio loop' + 'Generates lot of output, makes TUI unusable when' + 'logs are logged in the TUI itself.' + 'Use only when logging to a file') + args = parser.parse_args() + + try: + address = QEMUMonitorProtocol.parse_address(args.qmp_server) + except QMPBadPortError as err: + parser.error(err) + + app = App(address) + + if args.log_file: + LOGGER.addHandler(logging.FileHandler(args.log_file)) + else: + LOGGER.addHandler(TUILogHandler(app)) + + log_level = logging.getLevelName(args.log_level) + # getLevelName returns 'Level {log_level}' when a invalid level is passed. + if log_level == f'Level {args.log_level}': + parser.error('Invalid log level') + LOGGER.setLevel(log_level) + + app.run(args.asyncio_debug) + + +if __name__ == '__main__': + main() # type: ignore diff --git a/python/setup.cfg b/python/setup.cfg index d106a0ed7a..50f9894468 100644 --- a/python/setup.cfg +++ b/python/setup.cfg @@ -81,8 +81,22 @@ namespace_packages = True # fusepy has no type stubs: allow_subclassing_any = True +[mypy-qemu.aqmp.aqmp_tui] +disallow_untyped_defs = False +disallow_incomplete_defs = False +check_untyped_defs = False +# urwid and urwid_readline have no type stubs: +allow_subclassing_any = True + +# The following missing import directives are because these libraries do not +# provide type stubs. Allow them on an as-needed basis for mypy. [mypy-fuse] -# fusepy has no type stubs: +ignore_missing_imports = True + +[mypy-urwid] +ignore_missing_imports = True + +[mypy-urwid_readline] ignore_missing_imports = True [pylint.messages control] From patchwork Fri Jul 30 20:18:38 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Niteesh G. S." X-Patchwork-Id: 12411845 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-13.6 required=3.0 tests=BAYES_00, DKIM_ADSP_CUSTOM_MED,DKIM_INVALID,DKIM_SIGNED,FREEMAIL_FORGED_FROMDOMAIN, FREEMAIL_FROM,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER, INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 5B572C4338F for ; Fri, 30 Jul 2021 20:24:44 +0000 (UTC) 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 mail.kernel.org (Postfix) with ESMTPS id 14DF860F36 for ; Fri, 30 Jul 2021 20:24:44 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.4.1 mail.kernel.org 14DF860F36 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=gmail.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=nongnu.org Received: from localhost ([::1]:45748 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1m9Z3i-0001cP-Rq for qemu-devel@archiver.kernel.org; Fri, 30 Jul 2021 16:24:42 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:50814) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1m9YyU-0004i2-5d for qemu-devel@nongnu.org; Fri, 30 Jul 2021 16:19:18 -0400 Received: from mail-pj1-x1029.google.com ([2607:f8b0:4864:20::1029]:55810) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1m9YyS-0000v7-MQ for qemu-devel@nongnu.org; Fri, 30 Jul 2021 16:19:17 -0400 Received: by mail-pj1-x1029.google.com with SMTP id ca5so16808090pjb.5 for ; Fri, 30 Jul 2021 13:19:16 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=nZM4J6JiCIrfL4/oLzRMeJRNaEbQ96TGbVpQWlNgGI0=; b=Ojlc1O0NzLFSLtLBE0JNceI71q+paL7lvyx3+5B3CDDCp7lPf2sbkotXLEV9AhHeBX XKD0nSUqdord8HpeNg48n2lj6rmlj2AuWmn1c5VTRFd4469Ey7vyV6/fieFTPfYGsiZF UkldATYD6OoO/vaAz9KdfgZJkNfqkqfdhP/1BWQT/vV2zrrUVUlQIpfWomwlwQMjkg/b i9aVLpJN7wSw4Nfz21iQbx0hSEggk3X9aRvAKFOU50pXGUzWmTF1dEYs2jcpjNHioZBh szLmVQDB69bJEUoP1UrOCZNq4D982JKEaiQu0Yk4/ZiSDa/WJnRRww6uIqomGcI8+uQO aYQg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=nZM4J6JiCIrfL4/oLzRMeJRNaEbQ96TGbVpQWlNgGI0=; b=IfnPP9nlrWRTRc8dlXQn3Y/ktl+JvslR2XuUhtCw04l3CjlnNHqhpX3CJndj+kBDB4 Rxa8U4kTX/AeQ/x7YBb1yeQBsAIZW5ZW492pU0d+CCEgjy8Culr4JQ+gNhasPiHlIzQ9 8HNV9/ihZONvwkAZTHCqx1UMaM8Sbx1iobdRgSdqbJg4jZ9iA5FBBnMR9BopV3sqUGPT urwHRHgH5ysV8SDrBChHwd9YeL0uBmq5j7GYGuI6Kppmn3Qih+s+ShgXATQnXF30fqpS uw6n+F1wP2viynIgPBC89fRu2DlpDaki301z24bON62dKX8eUUjiTmzI7g0dAtHes2rN IgAA== X-Gm-Message-State: AOAM532TtmWaxULmbDrIuN3/RP0pq3b5kuu/ZRycaFml+XWbVZmURbcL alxOn+6iwwqqoq3EIuMNEYajeH6ZIm1y0g== X-Google-Smtp-Source: ABdhPJyehhd03OpJvGCNGEBWjWsOJVL8ATsIIIkUIav48Xpby3T20fd9f0jKTohjrFrWrxW8SUxN9w== X-Received: by 2002:aa7:8246:0:b029:39a:1e0a:cd48 with SMTP id e6-20020aa782460000b029039a1e0acd48mr4648658pfn.14.1627676355252; Fri, 30 Jul 2021 13:19:15 -0700 (PDT) Received: from localhost.localdomain ([120.138.12.243]) by smtp.gmail.com with ESMTPSA id s50sm3256842pfw.212.2021.07.30.13.19.12 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 30 Jul 2021 13:19:14 -0700 (PDT) From: G S Niteesh Babu To: qemu-devel@nongnu.org Subject: [PATCH v3 05/13] python: add entry point for aqmp-tui Date: Sat, 31 Jul 2021 01:48:38 +0530 Message-Id: <20210730201846.5147-6-niteesh.gs@gmail.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20210730201846.5147-1-niteesh.gs@gmail.com> References: <20210730201846.5147-1-niteesh.gs@gmail.com> Received-SPF: pass client-ip=2607:f8b0:4864:20::1029; envelope-from=niteesh.gs@gmail.com; helo=mail-pj1-x1029.google.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, FREEMAIL_FROM=0.001, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: ehabkost@redhat.com, kchamart@redhat.com, jsnow@redhat.com, armbru@redhat.com, wainersm@redhat.com, G S Niteesh Babu , stefanha@redhat.com, crosa@redhat.com, eblake@redhat.com Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: "Qemu-devel" Add an entry point for aqmp-tui. This will allow it to be run from the command line using "aqmp-tui localhost:1234" More options available in the TUI can be found using "aqmp-tui -h" Signed-off-by: G S Niteesh Babu Reviewed-by: John Snow --- python/setup.cfg | 1 + 1 file changed, 1 insertion(+) diff --git a/python/setup.cfg b/python/setup.cfg index 50f9894468..8cd9ac0d81 100644 --- a/python/setup.cfg +++ b/python/setup.cfg @@ -66,6 +66,7 @@ console_scripts = qom-fuse = qemu.qmp.qom_fuse:QOMFuse.entry_point [fuse] qemu-ga-client = qemu.qmp.qemu_ga_client:main qmp-shell = qemu.qmp.qmp_shell:main + aqmp-tui = qemu.aqmp.aqmp_tui:main [tui] [flake8] extend-ignore = E722 # Prefer pylint's bare-except checks to flake8's From patchwork Fri Jul 30 20:18:39 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Niteesh G. S." X-Patchwork-Id: 12411833 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-13.5 required=3.0 tests=BAYES_00, DKIM_ADSP_CUSTOM_MED,DKIM_INVALID,DKIM_SIGNED,FREEMAIL_FORGED_FROMDOMAIN, FREEMAIL_FROM,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER, INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED, USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 66F9AC4338F for ; Fri, 30 Jul 2021 20:20:57 +0000 (UTC) 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 mail.kernel.org (Postfix) with ESMTPS id EDD2F60720 for ; Fri, 30 Jul 2021 20:20:56 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.4.1 mail.kernel.org EDD2F60720 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=gmail.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=nongnu.org Received: from localhost ([::1]:58466 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1m9Z04-0007j6-3s for qemu-devel@archiver.kernel.org; Fri, 30 Jul 2021 16:20:56 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:50852) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1m9YyY-0004tK-9W for qemu-devel@nongnu.org; Fri, 30 Jul 2021 16:19:22 -0400 Received: from mail-pl1-x62a.google.com ([2607:f8b0:4864:20::62a]:34674) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1m9YyW-0000wx-7k for qemu-devel@nongnu.org; Fri, 30 Jul 2021 16:19:22 -0400 Received: by mail-pl1-x62a.google.com with SMTP id d1so12459432pll.1 for ; Fri, 30 Jul 2021 13:19:19 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=FHZOs2ShdJMMVObpalGIARKR5uUDpYP03WxnR2dRxps=; b=gd/GJrrr35IiKS7tXeWmFxVWGeK+1zgNBct1FyEZaccxk58paXn3bjsbEkLukj38sN CjsCGlkxAiSQutbbe8ZLVH+0oRaDLBTT8Sm2A0oF/zpiw9iC1z65Wse1USnt/cnBLcE/ pZ4cKHSyQ3reMdXqIEHBZA3VuK7fC2ZaRB7aisZwuf5nFeZZrSnm6SSi4E3wGJId2pI/ t2r7iFm7VespT3yglsrZvv4X6T7k6MwRz42fNn6esJhnhsNg5T07/0OwGsdh5bZvCuc5 r9da97LE3BhftGFljDmnKDRfTuQMhpl6KOA33CBIQzUy+Jrq7g0800BqgPROlmVoBYt7 QjoQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=FHZOs2ShdJMMVObpalGIARKR5uUDpYP03WxnR2dRxps=; b=Ls8qldjvDW/gFwH66MLp3MDKuhys02BRqhXRinAr6WhxZYkPjRyEbI2zN3jCkTNgds 74y50MwHGC/cKBeRgYxd9Pu0LgwnFg/xgx/tsNEgNfdOxwhmE8//rfkawwbyc+MeAKDB kfaQbyzIjpFAE5Nh6Nm72t5ZiqYS1yR3eR9cvFnGMBQtovaJm9Cuk4goEmXobPjPRusl FG4dZiWS7QRhD0B2eWQ7T5e0t2P50VYY/FXK1VEIWuv/qEYZIq7NYyBufz5t+qF9iF93 v8peUnFZrJX6xaOu0K8P6k6bMeYKiofK0+/wgx/wfhdllgWuzxeIKPrNGSiUc4Kx4cC6 hxQQ== X-Gm-Message-State: AOAM530F3eBsbGDrwZx4ikVm1Zzms3jQz7EYC6z9LDrB6igsk+A6cgZy N6QondOUux7z0fJglYSoCmuV7ATmqq1hUA== X-Google-Smtp-Source: ABdhPJwAgG0sAn2VJwJhAzgS14sj4zHYcv+Nn6Lhb+vqeYCXAERrsQh8zl2Gmo5AIOp7z7zZZlxRLQ== X-Received: by 2002:a17:90b:1d84:: with SMTP id pf4mr4801767pjb.166.1627676358799; Fri, 30 Jul 2021 13:19:18 -0700 (PDT) Received: from localhost.localdomain ([120.138.12.243]) by smtp.gmail.com with ESMTPSA id s50sm3256842pfw.212.2021.07.30.13.19.15 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 30 Jul 2021 13:19:18 -0700 (PDT) From: G S Niteesh Babu To: qemu-devel@nongnu.org Subject: [PATCH v3 06/13] python/aqmp-tui: Added type annotations for aqmp-tui Date: Sat, 31 Jul 2021 01:48:39 +0530 Message-Id: <20210730201846.5147-7-niteesh.gs@gmail.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20210730201846.5147-1-niteesh.gs@gmail.com> References: <20210730201846.5147-1-niteesh.gs@gmail.com> Received-SPF: pass client-ip=2607:f8b0:4864:20::62a; envelope-from=niteesh.gs@gmail.com; helo=mail-pl1-x62a.google.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, FREEMAIL_FROM=0.001, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: ehabkost@redhat.com, kchamart@redhat.com, jsnow@redhat.com, armbru@redhat.com, wainersm@redhat.com, G S Niteesh Babu , stefanha@redhat.com, crosa@redhat.com, eblake@redhat.com Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: "Qemu-devel" This patch adds type annotations for aqmp-tui using the mypy library. Signed-off-by: G S Niteesh Babu --- python/qemu/aqmp/aqmp_tui.py | 79 ++++++++++++++++++++---------------- python/setup.cfg | 3 -- 2 files changed, 43 insertions(+), 39 deletions(-) diff --git a/python/qemu/aqmp/aqmp_tui.py b/python/qemu/aqmp/aqmp_tui.py index ec9eba0aa7..ab9ada793a 100644 --- a/python/qemu/aqmp/aqmp_tui.py +++ b/python/qemu/aqmp/aqmp_tui.py @@ -9,8 +9,15 @@ import argparse import asyncio import logging -from logging import Handler +from logging import Handler, LogRecord import signal +from typing import ( + Any, + List, + Optional, + Tuple, + Union, +) import urwid import urwid_readline @@ -22,13 +29,13 @@ from .util import create_task, pretty_traceback -UPDATE_MSG = 'UPDATE_MSG' +UPDATE_MSG: str = 'UPDATE_MSG' # Using root logger to enable all loggers under qemu and asyncio LOGGER = logging.getLogger() -def format_json(msg): +def format_json(msg: str) -> str: """ Formats given multiline JSON message into a single line message. Converting into single line is more asthetically pleasing when looking @@ -43,17 +50,17 @@ def format_json(msg): class App(QMPClient): - def __init__(self, address): + def __init__(self, address: Union[str, Tuple[str, int]]) -> None: urwid.register_signal(type(self), UPDATE_MSG) self.window = Window(self) self.address = address - self.aloop = None + self.aloop: Optional[Any] = None # FIXME: Use more concrete type. super().__init__() - def add_to_history(self, msg): + def add_to_history(self, msg: str) -> None: urwid.emit_signal(self, UPDATE_MSG, msg) - def _cb_outbound(self, msg): + def _cb_outbound(self, msg: Message) -> Message: # FIXME: I think the ideal way to omit these messages during in-TUI # logging will be to add a filter to the logger. We can use regex to # filter out messages starting with 'Request:' or 'Response:' but I @@ -67,25 +74,25 @@ def _cb_outbound(self, msg): self.add_to_history('<-- ' + str(msg)) return msg - def _cb_inbound(self, msg): + def _cb_inbound(self, msg: Message) -> Message: handler = LOGGER.handlers[0] if not isinstance(handler, TUILogHandler): LOGGER.debug('Response: %s', str(msg)) self.add_to_history('--> ' + str(msg)) return msg - async def wait_for_events(self): + async def wait_for_events(self) -> None: async for event in self.events: self.handle_event(event) - async def _send_to_server(self, raw_msg): + async def _send_to_server(self, raw_msg: str) -> None: # FIXME: Format the raw_msg in history view to one line. It is not # pleasing to see multiple lines JSON object with an error statement. try: msg = Message(bytes(raw_msg, encoding='utf-8')) # Format multiline json into a single line JSON, since it is more # pleasing to look along with err message in TUI. - raw_msg = self.format_json(raw_msg) + raw_msg = format_json(raw_msg) await self._raw(msg, assign_id='id' not in msg) except (ValueError, TypeError) as err: LOGGER.info('Invalid message: %s', str(err)) @@ -102,18 +109,18 @@ def _cb_inbound(self, msg): LOGGER.error('Exception from _send_to_server: %s', str(err)) raise err - def cb_send_to_server(self, msg): + def cb_send_to_server(self, msg: str) -> None: create_task(self._send_to_server(msg)) - def unhandled_input(self, key): + def unhandled_input(self, key: str) -> None: if key == 'esc': self.kill_app() - def kill_app(self): + def kill_app(self) -> None: # TODO: Work on the disconnect logic create_task(self._kill_app()) - async def _kill_app(self): + async def _kill_app(self) -> None: # It is ok to call disconnect even in disconnect state try: await self.disconnect() @@ -124,7 +131,7 @@ def kill_app(self): raise err raise urwid.ExitMainLoop() - def handle_event(self, event): + def handle_event(self, event: Message) -> None: # FIXME: Consider all states present in qapi/run-state.json if event['event'] == 'SHUTDOWN': self._set_status('Server shutdown') @@ -139,7 +146,7 @@ def _get_formatted_address(self) -> str: addr = f'{host}:{port}' return addr - async def connect_server(self): + async def connect_server(self) -> None: try: await self.connect(self.address) addr = self._get_formatted_address() @@ -148,7 +155,7 @@ def _get_formatted_address(self) -> str: LOGGER.info('connect_server: ConnectError %s', str(err)) self._set_status('Server shutdown') - def run(self, debug=False): + def run(self, debug: bool = False) -> None: self.aloop = asyncio.get_event_loop() self.aloop.set_debug(debug) @@ -176,7 +183,7 @@ class StatusBar(urwid.Text): """ A simple Text widget that currently only shows connection status. """ - def __init__(self, text=''): + def __init__(self, text: str = ''): super().__init__(text, align='right') @@ -185,14 +192,14 @@ class Editor(urwid_readline.ReadlineEdit): Support urwid_readline features along with history support which lacks in urwid_readline """ - def __init__(self, master): + def __init__(self, master: App) -> None: super().__init__(caption='> ', multiline=True) self.master = master - self.history = [] - self.last_index = -1 - self.show_history = False + self.history: List[str] = [] + self.last_index: int = -1 + self.show_history: bool = False - def keypress(self, size, key): + def keypress(self, size: Tuple[int, int], key: str) -> Optional[str]: # TODO: Add some logic for down key and clean up logic if possible. # Returning None means the key has been handled by this widget # which otherwise is propogated to the parent widget to be @@ -223,7 +230,7 @@ def keypress(self, size, key): else: self.show_history = False self.last_index = 0 - return super().keypress(size, key) + return super().keypress(size, key) # type: ignore return None @@ -231,7 +238,7 @@ class EditorWidget(urwid.Filler): """ Wraps CustomEdit """ - def __init__(self, master): + def __init__(self, master: App) -> None: super().__init__(Editor(master), valign='top') @@ -239,12 +246,12 @@ class HistoryBox(urwid.ListBox): """ Shows all the QMP message transmitted/received """ - def __init__(self, master): + def __init__(self, master: App) -> None: self.master = master self.history = urwid.SimpleFocusListWalker([]) super().__init__(self.history) - def add_to_history(self, history): + def add_to_history(self, history: str) -> None: self.history.append(urwid.Text(history)) if self.history: self.history.set_focus(len(self.history) - 1) @@ -254,7 +261,7 @@ class HistoryWindow(urwid.Frame): """ Composes the HistoryBox and EditorWidget """ - def __init__(self, master): + def __init__(self, master: App) -> None: self.master = master self.editor_widget = EditorWidget(master) self.editor = urwid.LineBox(self.editor_widget) @@ -264,7 +271,7 @@ def __init__(self, master): super().__init__(self.body) urwid.connect_signal(self.master, UPDATE_MSG, self.cb_add_to_history) - def cb_add_to_history(self, msg): + def cb_add_to_history(self, msg: str) -> None: self.history.add_to_history(msg) @@ -275,7 +282,7 @@ class Window(urwid.Frame): future when we will have multiple windows and want to the switch between them and display overlays """ - def __init__(self, master): + def __init__(self, master: App) -> None: self.master = master footer = StatusBar() body = HistoryWindow(master) @@ -283,18 +290,18 @@ def __init__(self, master): class TUILogHandler(Handler): - def __init__(self, tui): + def __init__(self, tui: App) -> None: super().__init__() self.tui = tui - def emit(self, record): + def emit(self, record: LogRecord) -> None: level = record.levelname msg = record.getMessage() msg = f'[{level}]: {msg}' self.tui.add_to_history(msg) -def main(): +def main() -> None: parser = argparse.ArgumentParser(description='AQMP TUI') parser.add_argument('qmp_server', help='Address of the QMP server' '< UNIX socket path | TCP addr:port >') @@ -311,7 +318,7 @@ def main(): try: address = QEMUMonitorProtocol.parse_address(args.qmp_server) except QMPBadPortError as err: - parser.error(err) + parser.error(str(err)) app = App(address) @@ -330,4 +337,4 @@ def main(): if __name__ == '__main__': - main() # type: ignore + main() diff --git a/python/setup.cfg b/python/setup.cfg index 8cd9ac0d81..11c6240aba 100644 --- a/python/setup.cfg +++ b/python/setup.cfg @@ -83,9 +83,6 @@ namespace_packages = True allow_subclassing_any = True [mypy-qemu.aqmp.aqmp_tui] -disallow_untyped_defs = False -disallow_incomplete_defs = False -check_untyped_defs = False # urwid and urwid_readline have no type stubs: allow_subclassing_any = True From patchwork Fri Jul 30 20:18:40 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Niteesh G. S." X-Patchwork-Id: 12411913 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-13.6 required=3.0 tests=BAYES_00, DKIM_ADSP_CUSTOM_MED,DKIM_INVALID,DKIM_SIGNED,FREEMAIL_FORGED_FROMDOMAIN, FREEMAIL_FROM,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER, INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id BC079C4338F for ; Fri, 30 Jul 2021 20:26:38 +0000 (UTC) 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 mail.kernel.org (Postfix) with ESMTPS id 7781260EE6 for ; Fri, 30 Jul 2021 20:26:38 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.4.1 mail.kernel.org 7781260EE6 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=gmail.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=nongnu.org Received: from localhost ([::1]:53164 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1m9Z5Z-0006mc-J4 for qemu-devel@archiver.kernel.org; Fri, 30 Jul 2021 16:26:37 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:50882) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1m9Yyc-00055J-8N for qemu-devel@nongnu.org; Fri, 30 Jul 2021 16:19:26 -0400 Received: from mail-pj1-x1033.google.com ([2607:f8b0:4864:20::1033]:52198) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1m9Yya-0000zq-Kp for qemu-devel@nongnu.org; Fri, 30 Jul 2021 16:19:26 -0400 Received: by mail-pj1-x1033.google.com with SMTP id mt6so16895349pjb.1 for ; Fri, 30 Jul 2021 13:19:24 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=x8nI1gjkdCEj7MHHw+ygQfpgEXfIOirnsZ0+rfOXPbk=; b=V+F35C8DInqs/g2pmgBlLLXaq9onEpa1xnFXp+7ZhO2VviZEVG9xf3mkBzlueDaC1J 8KgkANyCEQpibeOZEA6poGgioSqhsEUTEGOeSqdgVMo4esL7nAl2BZik3Vy0Ly5n52ty 6DYms6tcFLyoUlsj7upeFfl9m6kRswla6Dn88N0jOShqlAY4RBdilyS5PZF11SyQwnKN nqeDPVmKVO/quNPrbmTBaPQIMghyPv0ape8hJ/zzLcGJx4FuXSh/LdR77CbPC6m27I21 GicpH/GqNBvHlSoibjf2J1TcANN49xsyBOzw4lcvkbJOv3j8GGzZU6R/JOH6BwP3gUF3 WWwg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=x8nI1gjkdCEj7MHHw+ygQfpgEXfIOirnsZ0+rfOXPbk=; b=jsvpFEVDXRIl3WPyi3wM1ce7vdFPAbA+n2GYrWP4GyIPBBrXZKEVrNPw5apXB8WNfu gOJl0T22mqEzvW1DwWs7VI7M15BocOKYoDXWP/UMDG8O6XeRVFwRPLwuhcmU20SNpJfO bJa3qBudnIY7JDvJendrt1IZOKyC8HkvuajPCDAibQ7taOkN1e+FJMLZVAPEo9JO1fg7 IiRSZolj0ffKGbumbBAUqfqvBTeib0kvDHGWqUa7E1S/zQ8YgpcJjPUUAAF8LCPozi0T vIMw8uCrxxPUehsB5KpSpmyFbGekAEKHSDOGHrhPA0NxQrBnoiJlGyV9glVoeQHaVa7t hqYA== X-Gm-Message-State: AOAM532GNln3lSqTyp/GEfzXxWSA9tUtP+dSGCOoUcwbWg8rzbvxCawa iNas4Nu7Uxw+PsfUn+9Nb+E+7jBDfquCAg== X-Google-Smtp-Source: ABdhPJyF+r/NBTGNm7qZ0hYbNxBgywI1hm1kPEtt4tgR/XfwfMisJXlkd358DOSXzrzgd1bD7xOFOA== X-Received: by 2002:a62:79c9:0:b029:3aa:ef64:1569 with SMTP id u192-20020a6279c90000b02903aaef641569mr4586005pfc.8.1627676362226; Fri, 30 Jul 2021 13:19:22 -0700 (PDT) Received: from localhost.localdomain ([120.138.12.243]) by smtp.gmail.com with ESMTPSA id s50sm3256842pfw.212.2021.07.30.13.19.19 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 30 Jul 2021 13:19:21 -0700 (PDT) From: G S Niteesh Babu To: qemu-devel@nongnu.org Subject: [PATCH v3 07/13] python: add optional pygments dependency Date: Sat, 31 Jul 2021 01:48:40 +0530 Message-Id: <20210730201846.5147-8-niteesh.gs@gmail.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20210730201846.5147-1-niteesh.gs@gmail.com> References: <20210730201846.5147-1-niteesh.gs@gmail.com> Received-SPF: pass client-ip=2607:f8b0:4864:20::1033; envelope-from=niteesh.gs@gmail.com; helo=mail-pj1-x1033.google.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, FREEMAIL_FROM=0.001, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: ehabkost@redhat.com, kchamart@redhat.com, jsnow@redhat.com, armbru@redhat.com, wainersm@redhat.com, G S Niteesh Babu , stefanha@redhat.com, crosa@redhat.com, eblake@redhat.com Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: "Qemu-devel" Added pygments as optional dependency for AQMP TUI. This is required for the upcoming syntax highlighting feature in AQMP TUI. The dependency has also been added in the devel optional group. Added mypy 'ignore_missing_imports' for pygments since it does not have any type stubs. Signed-off-by: G S Niteesh Babu Reviewed-by: John Snow --- python/Pipfile.lock | 8 ++++++++ python/setup.cfg | 5 +++++ 2 files changed, 13 insertions(+) diff --git a/python/Pipfile.lock b/python/Pipfile.lock index 76cf1e4930..2c6d779348 100644 --- a/python/Pipfile.lock +++ b/python/Pipfile.lock @@ -200,6 +200,14 @@ ], "version": "==2.0.0" }, + "pygments": { + "hashes": [ + "sha256:a18f47b506a429f6f4b9df81bb02beab9ca21d0a5fee38ed15aef65f0545519f", + "sha256:d66e804411278594d764fc69ec36ec13d9ae9147193a1740cd34d272ca383b8e" + ], + "markers": "python_version >= '3.5'", + "version": "==2.9.0" + }, "pylint": { "hashes": [ "sha256:082a6d461b54f90eea49ca90fff4ee8b6e45e8029e5dbd72f6107ef84f3779c0", diff --git a/python/setup.cfg b/python/setup.cfg index 11c6240aba..bbb7306c3d 100644 --- a/python/setup.cfg +++ b/python/setup.cfg @@ -46,6 +46,7 @@ devel = tox >= 3.18.0 urwid >= 2.1.2 urwid-readline >= 0.13 + Pygments >= 2.9.0 # Provides qom-fuse functionality fuse = @@ -55,6 +56,7 @@ fuse = tui = urwid >= 2.1.2 urwid-readline >= 0.13 + Pygments >= 2.9.0 [options.entry_points] console_scripts = @@ -97,6 +99,9 @@ ignore_missing_imports = True [mypy-urwid_readline] ignore_missing_imports = True +[mypy-pygments] +ignore_missing_imports = True + [pylint.messages control] # Disable the message, report, category or checker with the given id(s). You # can either give multiple identifiers separated by comma (,) or put this From patchwork Fri Jul 30 20:18:41 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Niteesh G. S." X-Patchwork-Id: 12411911 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-13.5 required=3.0 tests=BAYES_00, DKIM_ADSP_CUSTOM_MED,DKIM_INVALID,DKIM_SIGNED,FREEMAIL_FORGED_FROMDOMAIN, FREEMAIL_FROM,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER, INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED, USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 9ECBEC4338F for ; Fri, 30 Jul 2021 20:25:11 +0000 (UTC) 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 mail.kernel.org (Postfix) with ESMTPS id 2001B60E09 for ; Fri, 30 Jul 2021 20:25:11 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.4.1 mail.kernel.org 2001B60E09 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=gmail.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=nongnu.org Received: from localhost ([::1]:47984 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1m9Z4A-0003Al-9H for qemu-devel@archiver.kernel.org; Fri, 30 Jul 2021 16:25:10 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:50894) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1m9Yye-0005B2-TW for qemu-devel@nongnu.org; Fri, 30 Jul 2021 16:19:28 -0400 Received: from mail-pj1-x1035.google.com ([2607:f8b0:4864:20::1035]:45924) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1m9Yyd-000121-0u for qemu-devel@nongnu.org; Fri, 30 Jul 2021 16:19:28 -0400 Received: by mail-pj1-x1035.google.com with SMTP id m10-20020a17090a34cab0290176b52c60ddso15972588pjf.4 for ; Fri, 30 Jul 2021 13:19:26 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=7JX3P4ngjaa3qz3zAmkSBrtNTj8wTbnHCG7iT7l/iY0=; b=K5zyY4OuZVT4kvWoeFIqV73wW8IXlknaTVgxBQlrTZEINjdOMd3IamNsTpTtBY/dpi nMSUTIqs7icQ7tihaNnKwmBZD7b4I+bApQAJb38qwmHTEqe5tvF6QGuDl7lxZCnexo4o jw6sIia6Gq/Cak8GQmvcq/U8n4+m74GFEbEUHawSo/ZxzXV2zHUDCS2EiSngd+lZD120 TRrTWasE+f50rkCrfTkJIPKL0kQqcORCz1d2fRQeTJUfZCJk7QrYHDoNQEl38lGMb0S0 vJ82SZTlhoh4Ysmgm9c6WnTj3ErciackPW59kdgSVoUh2TmgLZFKni9cRBnuztZtMg32 G0pQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=7JX3P4ngjaa3qz3zAmkSBrtNTj8wTbnHCG7iT7l/iY0=; b=kX8CMvtQjzxQhB04KhfUwkn/nWUzlqd7Ur9szbFNcDxqbMWFQ5zXCTL07YALQgNx1J V4YnGNX00uXW8q+lTa2B3EZY5FZZtI5kirQKqBjlFH9duGlVtAaWMbOCjjgATA6T78lc OjPRwpLoFv+qNvgG9CLYj7fgMpipOiSmfO2T9DM61C9A6mxpjZHuizJI+ySVW2CK3vur ftUjrxS+uZXffBBmZd0JobU/X0N4wuMyRHP4N04vPLRbrg1IDzndJlT77jkVX9JVYqFj EEUBQm2Jo/oefOBn6k+RGXAgb/AYftmIeqCAfimcWUJXddvLXRYc3IOvp8I2uwSnIirS kQyw== X-Gm-Message-State: AOAM533HzS8KBwBMfM1idjuRDtSxDlNh8lgGt9o94nJg/3173A+RjT/1 k8pQVBZ1nEkA8vOQixxKpSV7Z6iwOOm1UA== X-Google-Smtp-Source: ABdhPJwEGvbX1TFEEAPFnzapFgjx+9D/hrnCIz7f05RdWj8ofgEsfSrz5RSaZ612880t0HOAqJzYHQ== X-Received: by 2002:a62:8fd4:0:b029:3af:3fa7:c993 with SMTP id n203-20020a628fd40000b02903af3fa7c993mr3579812pfd.77.1627676365620; Fri, 30 Jul 2021 13:19:25 -0700 (PDT) Received: from localhost.localdomain ([120.138.12.243]) by smtp.gmail.com with ESMTPSA id s50sm3256842pfw.212.2021.07.30.13.19.22 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 30 Jul 2021 13:19:25 -0700 (PDT) From: G S Niteesh Babu To: qemu-devel@nongnu.org Subject: [PATCH v3 08/13] python/aqmp-tui: add syntax highlighting Date: Sat, 31 Jul 2021 01:48:41 +0530 Message-Id: <20210730201846.5147-9-niteesh.gs@gmail.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20210730201846.5147-1-niteesh.gs@gmail.com> References: <20210730201846.5147-1-niteesh.gs@gmail.com> Received-SPF: pass client-ip=2607:f8b0:4864:20::1035; envelope-from=niteesh.gs@gmail.com; helo=mail-pj1-x1035.google.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, FREEMAIL_FROM=0.001, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: ehabkost@redhat.com, kchamart@redhat.com, jsnow@redhat.com, armbru@redhat.com, wainersm@redhat.com, G S Niteesh Babu , stefanha@redhat.com, crosa@redhat.com, eblake@redhat.com Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: "Qemu-devel" Add syntax highlighting for the incoming and outgoing QMP messages. This is achieved using the pygments module which was added in a previous commit. The current implementation is a really simple one which doesn't allow for any configuration. In future this has to be improved to allow for easier theme config using an external config of some sort. Signed-off-by: G S Niteesh Babu --- python/qemu/aqmp/aqmp_tui.py | 52 +++++++++++++++++++++++++++--------- 1 file changed, 40 insertions(+), 12 deletions(-) diff --git a/python/qemu/aqmp/aqmp_tui.py b/python/qemu/aqmp/aqmp_tui.py index ab9ada793a..0d5ec62cb7 100644 --- a/python/qemu/aqmp/aqmp_tui.py +++ b/python/qemu/aqmp/aqmp_tui.py @@ -19,6 +19,8 @@ Union, ) +from pygments import lexers +from pygments import token as Token import urwid import urwid_readline @@ -35,6 +37,22 @@ LOGGER = logging.getLogger() +palette = [ + (Token.Punctuation, '', '', '', 'h15,bold', 'g7'), + (Token.Text, '', '', '', '', 'g7'), + (Token.Name.Tag, '', '', '', 'bold,#f88', 'g7'), + (Token.Literal.Number.Integer, '', '', '', '#fa0', 'g7'), + (Token.Literal.String.Double, '', '', '', '#6f6', 'g7'), + (Token.Keyword.Constant, '', '', '', '#6af', 'g7'), + ('DEBUG', '', '', '', '#ddf', 'g7'), + ('INFO', '', '', '', 'g100', 'g7'), + ('WARNING', '', '', '', '#ff6', 'g7'), + ('ERROR', '', '', '', '#a00', 'g7'), + ('CRITICAL', '', '', '', '#a00', 'g7'), + ('background', '', 'black', '', '', 'g7'), +] + + def format_json(msg: str) -> str: """ Formats given multiline JSON message into a single line message. @@ -57,17 +75,14 @@ def __init__(self, address: Union[str, Tuple[str, int]]) -> None: self.aloop: Optional[Any] = None # FIXME: Use more concrete type. super().__init__() - def add_to_history(self, msg: str) -> None: - urwid.emit_signal(self, UPDATE_MSG, msg) + def add_to_history(self, msg: str, level: Optional[str] = None) -> None: + urwid.emit_signal(self, UPDATE_MSG, msg, level) def _cb_outbound(self, msg: Message) -> Message: # FIXME: I think the ideal way to omit these messages during in-TUI - # logging will be to add a filter to the logger. We can use regex to - # filter out messages starting with 'Request:' or 'Response:' but I - # think a better approach will be encapsulate the message in an object - # and filter based on the object. Encapsulation of the message will - # also be necessary when we want different formatting of messages - # inside TUI. + # logging will be to add a filter to the logger. We can use + # regex/startswith to filter out messages starting with 'Request:' or + # 'Response:'. If possible please suggest other ideas. handler = LOGGER.handlers[0] if not isinstance(handler, TUILogHandler): LOGGER.debug('Request: %s', str(msg)) @@ -156,6 +171,9 @@ def _get_formatted_address(self) -> str: self._set_status('Server shutdown') def run(self, debug: bool = False) -> None: + screen = urwid.raw_display.Screen() + screen.set_terminal_properties(256) + self.aloop = asyncio.get_event_loop() self.aloop.set_debug(debug) @@ -167,6 +185,8 @@ def run(self, debug: bool = False) -> None: event_loop = urwid.AsyncioEventLoop(loop=self.aloop) main_loop = urwid.MainLoop(urwid.AttrMap(self.window, 'background'), unhandled_input=self.unhandled_input, + screen=screen, + palette=palette, handle_mouse=True, event_loop=event_loop) @@ -251,7 +271,8 @@ def __init__(self, master: App) -> None: self.history = urwid.SimpleFocusListWalker([]) super().__init__(self.history) - def add_to_history(self, history: str) -> None: + def add_to_history(self, + history: Union[str, List[Tuple[str, str]]]) -> None: self.history.append(urwid.Text(history)) if self.history: self.history.set_focus(len(self.history) - 1) @@ -271,8 +292,15 @@ def __init__(self, master: App) -> None: super().__init__(self.body) urwid.connect_signal(self.master, UPDATE_MSG, self.cb_add_to_history) - def cb_add_to_history(self, msg: str) -> None: - self.history.add_to_history(msg) + def cb_add_to_history(self, msg: str, level: Optional[str] = None) -> None: + formatted = [] + if level: + formatted.append((level, msg)) + else: + lexer = lexers.JsonLexer() # pylint: disable=no-member + for token in lexer.get_tokens(msg): + formatted.append(token) + self.history.add_to_history(formatted) class Window(urwid.Frame): @@ -298,7 +326,7 @@ def emit(self, record: LogRecord) -> None: level = record.levelname msg = record.getMessage() msg = f'[{level}]: {msg}' - self.tui.add_to_history(msg) + self.tui.add_to_history(msg, level) def main() -> None: From patchwork Fri Jul 30 20:18:42 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Niteesh G. S." X-Patchwork-Id: 12411837 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-13.5 required=3.0 tests=BAYES_00, DKIM_ADSP_CUSTOM_MED,DKIM_INVALID,DKIM_SIGNED,FREEMAIL_FORGED_FROMDOMAIN, FREEMAIL_FROM,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER, INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED, USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 1E668C4338F for ; Fri, 30 Jul 2021 20:22:39 +0000 (UTC) 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 mail.kernel.org (Postfix) with ESMTPS id B03AE60F36 for ; Fri, 30 Jul 2021 20:22:38 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.4.1 mail.kernel.org B03AE60F36 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=gmail.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=nongnu.org Received: from localhost ([::1]:36720 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1m9Z1h-0003nx-I1 for qemu-devel@archiver.kernel.org; Fri, 30 Jul 2021 16:22:37 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:50906) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1m9Yyi-0005Qx-Je for qemu-devel@nongnu.org; Fri, 30 Jul 2021 16:19:32 -0400 Received: from mail-pl1-x62e.google.com ([2607:f8b0:4864:20::62e]:42571) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1m9Yyg-00013w-Gn for qemu-devel@nongnu.org; Fri, 30 Jul 2021 16:19:32 -0400 Received: by mail-pl1-x62e.google.com with SMTP id t3so10319107plg.9 for ; Fri, 30 Jul 2021 13:19:30 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=JkZwuzQkkxI2CGB1gC7hFR0u0qV4Z/y/4b8e7xW4IJ0=; b=UuxIfdlYBD8LSP65f0xZCVb68Mpqw/y2yshbkDGQ7SEEW+1xVFxCU2yTxyTWo85EoS ue7LNZj6fx39TA73O/KJDecYaXgIhqs+bnRrPUzVHuzwkLbf1HNLw1jhvTucrI/yx8HP 0pfbez4z+EAUn1Jbj3vY599j4qsYUp7Sb3gLXCTWODKki0OHzHE706MGOCTFpy4NgxpL IJOwMBpKOC8GWQ6vCfzgnD4+fnbA9KDPP3L4u+Wy7rw6OftmS6xvZnQVSD+f9Bkg+5T8 KlZPCQBMB5d7RJcOtaCt2ZsSu9g0wnYtjoQmUt5Q+sJGnS86+6DNWegAAVLqc8hoThQf or/A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=JkZwuzQkkxI2CGB1gC7hFR0u0qV4Z/y/4b8e7xW4IJ0=; b=Ii4Aafuz0DkOP6WcqOqcyOuScjPw5SDEqQPkdjkw6j+KOQt4S6RNMCveYqpBtKVAvN IGgov9KTw/1mWpGf/Rm/DosqlA4cPzCSs4+y3LSp5lxf1cVe5EG8a2dmYY7J/p4MJSk+ HMWyAkfsW0gi3/gd7Dn33T7K5ev30OYKTUGbVrvNsUT+gc2qkFGRu6Qsk+RpsVmJUeoL BiNMHJdKJ21c2zzXT1C5ndLl0N7Wydxd9gTx0xDKWRZIS/pPv2J8MZmmF/dhGL9AJd8V wp9F03fUov2H7bvZ8SBPRqQ/eu8KLkgUogAUDc+TSCT2rB7Anyp3fNO2/s95PJY1cS4c bjXg== X-Gm-Message-State: AOAM533tzP5F2acEu0zEiT947+uAJKiS8Eum6qlYIM+ZKGog+SvTaOLf H0BRqhRiMvTW+gHvyAcks91ch9TnWT8ydA== X-Google-Smtp-Source: ABdhPJwFmiSofFANrO20vdJAICMB3f6Muxjtr58mYgJxqMV8LhSl9pGarJZGZ8I7KFQT1Nm+sgLGHw== X-Received: by 2002:a62:1ac3:0:b029:3ae:d818:dfd with SMTP id a186-20020a621ac30000b02903aed8180dfdmr3932827pfa.43.1627676369021; Fri, 30 Jul 2021 13:19:29 -0700 (PDT) Received: from localhost.localdomain ([120.138.12.243]) by smtp.gmail.com with ESMTPSA id s50sm3256842pfw.212.2021.07.30.13.19.26 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 30 Jul 2021 13:19:28 -0700 (PDT) From: G S Niteesh Babu To: qemu-devel@nongnu.org Subject: [PATCH v3 09/13] python/aqmp-tui: Add QMP connection manager Date: Sat, 31 Jul 2021 01:48:42 +0530 Message-Id: <20210730201846.5147-10-niteesh.gs@gmail.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20210730201846.5147-1-niteesh.gs@gmail.com> References: <20210730201846.5147-1-niteesh.gs@gmail.com> Received-SPF: pass client-ip=2607:f8b0:4864:20::62e; envelope-from=niteesh.gs@gmail.com; helo=mail-pl1-x62e.google.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, FREEMAIL_FROM=0.001, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: ehabkost@redhat.com, kchamart@redhat.com, jsnow@redhat.com, armbru@redhat.com, wainersm@redhat.com, G S Niteesh Babu , stefanha@redhat.com, crosa@redhat.com, eblake@redhat.com Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: "Qemu-devel" Instead of manually connecting and disconnecting from the server. We now rely on the runstate to manage the QMP connection. Along with this the ability to reconnect on certain exceptions has also been added. Signed-off-by: G S Niteesh Babu --- python/qemu/aqmp/aqmp_tui.py | 109 ++++++++++++++++++++++++++++++----- 1 file changed, 94 insertions(+), 15 deletions(-) diff --git a/python/qemu/aqmp/aqmp_tui.py b/python/qemu/aqmp/aqmp_tui.py index 0d5ec62cb7..ef91883fa5 100644 --- a/python/qemu/aqmp/aqmp_tui.py +++ b/python/qemu/aqmp/aqmp_tui.py @@ -25,8 +25,9 @@ import urwid_readline from ..qmp import QEMUMonitorProtocol, QMPBadPortError +from .error import ProtocolError from .message import DeserializationError, Message, UnexpectedTypeError -from .protocol import ConnectError +from .protocol import ConnectError, Runstate from .qmp_client import ExecInterruptedError, QMPClient from .util import create_task, pretty_traceback @@ -67,12 +68,24 @@ def format_json(msg: str) -> str: return ' '.join(words) +def type_name(mtype: Any) -> str: + """ + Returns the type name + """ + return type(mtype).__name__ + + class App(QMPClient): - def __init__(self, address: Union[str, Tuple[str, int]]) -> None: + def __init__(self, address: Union[str, Tuple[str, int]], num_retries: int, + retry_delay: Optional[int]) -> None: urwid.register_signal(type(self), UPDATE_MSG) self.window = Window(self) self.address = address self.aloop: Optional[Any] = None # FIXME: Use more concrete type. + self.num_retries = num_retries + self.retry_delay = retry_delay + self.retry: bool = False + self.disconnecting: bool = False super().__init__() def add_to_history(self, msg: str, level: Optional[str] = None) -> None: @@ -119,7 +132,7 @@ def _cb_inbound(self, msg: Message) -> Message: LOGGER.info('Error server disconnected before reply') urwid.emit_signal(self, UPDATE_MSG, '{"error": "Server disconnected before reply"}') - self._set_status("Server disconnected") + await self.disconnect() except Exception as err: LOGGER.error('Exception from _send_to_server: %s', str(err)) raise err @@ -136,15 +149,29 @@ def kill_app(self) -> None: create_task(self._kill_app()) async def _kill_app(self) -> None: - # It is ok to call disconnect even in disconnect state + await self.disconnect() + LOGGER.debug('Disconnect finished. Exiting app') + raise urwid.ExitMainLoop() + + async def disconnect(self) -> None: + if self.disconnecting: + return try: - await self.disconnect() - LOGGER.debug('Disconnect finished. Exiting app') + self.disconnecting = True + await super().disconnect() + self.retry = True + except EOFError as err: + LOGGER.info('disconnect: %s', type_name(err)) + self.retry = True + except ProtocolError as err: + LOGGER.info('disconnect: %s', type_name(err)) + self.retry = False except Exception as err: - LOGGER.info('_kill_app: %s', str(err)) - # Let the app crash after providing a proper stack trace + LOGGER.error('disconnect: Unhandled exception %s', str(err)) + self.retry = False raise err - raise urwid.ExitMainLoop() + finally: + self.disconnecting = False def handle_event(self, event: Message) -> None: # FIXME: Consider all states present in qapi/run-state.json @@ -161,14 +188,61 @@ def _get_formatted_address(self) -> str: addr = f'{host}:{port}' return addr - async def connect_server(self) -> None: + async def _retry_connection(self) -> Optional[str]: + current_retries = 0 + err = None + # Increase in power sequence of 2 if no delay is provided + cur_delay = 1 + inc_delay = 2 + if self.retry_delay: + inc_delay = 1 + cur_delay = self.retry_delay + # initial try + await self.connect_server() + while self.retry and current_retries < self.num_retries: + LOGGER.info('Connection Failed, retrying in %d', cur_delay) + status = f'[Retry #{current_retries} ({cur_delay}s)]' + self._set_status(status) + + await asyncio.sleep(cur_delay) + + err = await self.connect_server() + cur_delay *= inc_delay + # Cap delay to 5mins + cur_delay = min(cur_delay, 5 * 60) + current_retries += 1 + # If all retries failed report the last error + LOGGER.info('All retries failed: %s', str(err)) + return type_name(err) + + async def manage_connection(self) -> None: + while True: + if self.runstate == Runstate.IDLE: + LOGGER.info('Trying to reconnect') + err = await self._retry_connection() + # If retry is still true then, we have exhausted all our tries. + if self.retry: + self._set_status(f'Error: {err}') + else: + addr = self._get_formatted_address() + self._set_status(f'[Connected {addr}]') + elif self.runstate == Runstate.DISCONNECTING: + self._set_status('[Disconnected]') + await self.disconnect() + # check if a retry is needed + if self.runstate == Runstate.IDLE: + continue + await self.runstate_changed() + + async def connect_server(self) -> Optional[str]: try: await self.connect(self.address) - addr = self._get_formatted_address() - self._set_status(f'Connected to {addr}') + self.retry = False except ConnectError as err: LOGGER.info('connect_server: ConnectError %s', str(err)) - self._set_status('Server shutdown') + self.retry = True + return type_name(err) + return None def run(self, debug: bool = False) -> None: screen = urwid.raw_display.Screen() @@ -191,7 +265,7 @@ def run(self, debug: bool = False) -> None: event_loop=event_loop) create_task(self.wait_for_events(), self.aloop) - create_task(self.connect_server(), self.aloop) + create_task(self.manage_connection(), self.aloop) try: main_loop.run() except Exception as err: @@ -333,6 +407,11 @@ def main() -> None: parser = argparse.ArgumentParser(description='AQMP TUI') parser.add_argument('qmp_server', help='Address of the QMP server' '< UNIX socket path | TCP addr:port >') + parser.add_argument('--num-retries', type=int, default=10, + help='Number of times to reconnect before giving up') + parser.add_argument('--retry-delay', type=int, + help='Time(s) to wait before next retry.' + 'Default action is to increase delay in powers of 2') parser.add_argument('--log-file', help='The Log file name') parser.add_argument('--log-level', default='WARNING', help='Log level ') @@ -348,7 +427,7 @@ def main() -> None: except QMPBadPortError as err: parser.error(str(err)) - app = App(address) + app = App(address, args.num_retries, args.retry_delay) if args.log_file: LOGGER.addHandler(logging.FileHandler(args.log_file)) From patchwork Fri Jul 30 20:18:43 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Niteesh G. S." X-Patchwork-Id: 12411841 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-13.5 required=3.0 tests=BAYES_00, DKIM_ADSP_CUSTOM_MED,DKIM_INVALID,DKIM_SIGNED,FREEMAIL_FORGED_FROMDOMAIN, FREEMAIL_FROM,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER, INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED, USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 656C4C4338F for ; Fri, 30 Jul 2021 20:23:03 +0000 (UTC) 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 mail.kernel.org (Postfix) with ESMTPS id 2DEDA60F48 for ; Fri, 30 Jul 2021 20:23:03 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.4.1 mail.kernel.org 2DEDA60F48 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=gmail.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=nongnu.org Received: from localhost ([::1]:38670 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1m9Z26-00057T-7N for qemu-devel@archiver.kernel.org; Fri, 30 Jul 2021 16:23:02 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:50918) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1m9Yyl-0005ao-4w for qemu-devel@nongnu.org; Fri, 30 Jul 2021 16:19:35 -0400 Received: from mail-pj1-x1031.google.com ([2607:f8b0:4864:20::1031]:55819) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1m9Yyj-00015p-GB for qemu-devel@nongnu.org; Fri, 30 Jul 2021 16:19:34 -0400 Received: by mail-pj1-x1031.google.com with SMTP id ca5so16808836pjb.5 for ; Fri, 30 Jul 2021 13:19:33 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=NKoC2j7+7O40T4y64pzeDDCdbYzeyUyxg5Gk/jXeOWA=; b=oyj3tzRDZYPHep0dcQVTWdgREFg89D922Q1g4yvPPtMjhBU9SMIRHvOoabHpopfoC/ +qZEceoSCISN8tMxER6+tCPFNCSNsUK2F2tBdhD9MsLn8MtU83cc2G2yNG2+eYYbAHq6 Ha8uEKD0xvRTVg9ZMnaLKuWfzeSru0gzg+dIFJO0leh1CELan7/Jp72SisMdkkNjLoae iiEZq2aqTEmjVEDUd/37doa7XP5veuqxfk5D2V2f/Z51ZI0zEHYh0CNy6Oafk2UIrC+/ aAirwFCditJpjsmjfhzSLvIskOAMOq3GTL++f1JPP2T8s86d0bAThM85S3wfHPKuAni/ ewlg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=NKoC2j7+7O40T4y64pzeDDCdbYzeyUyxg5Gk/jXeOWA=; b=qp8/GJnnqXO7ucjJKpUD+60jZoVIWwlOCH1QN5pQA5YHbi8c7/CMzZyqj/JLyZyljD xFIFySpGFnuST63RL5flc0Hlph69yQrA67OX/+kBfHTdzuGfNzS8RmnWjqEFs5dI9u7w BhoYMbM6lM7abAlY6+YI1R6+gehDlsqIt81DQoQu3cUxYJlwzu1GdUAu15LH//sludqc zfMeBmOR03dlqyb+95hm/jVf+U+EMS5XblwOm6EiWg91DBW5EZs35kG5X4q+yvF/50WJ Y/ujq21VSHyw3D0UN6wIQHdP0hj2szQ0lD51l7kqJYS8RqvB1ZHSIogRQc8EYuSDwWAH LQLA== X-Gm-Message-State: AOAM530dTKCS5pcqSgbU2Ss7PVj48oY6eB1JZeiJGh//5Fw3i3htACME j1u7+cKB06wzAJbqA5YiG0HzSovnKSLPhA== X-Google-Smtp-Source: ABdhPJzyFVmiPew3gXJqkYYENgJ1EAfSh2mn3NVHgJNGcR61rx6FP76qLyNW8ZljJEZkJWktZiW+Rw== X-Received: by 2002:a05:6a00:2303:b029:329:308f:9ef6 with SMTP id h3-20020a056a002303b0290329308f9ef6mr4172178pfh.24.1627676372116; Fri, 30 Jul 2021 13:19:32 -0700 (PDT) Received: from localhost.localdomain ([120.138.12.243]) by smtp.gmail.com with ESMTPSA id s50sm3256842pfw.212.2021.07.30.13.19.29 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 30 Jul 2021 13:19:31 -0700 (PDT) From: G S Niteesh Babu To: qemu-devel@nongnu.org Subject: [PATCH v3 10/13] python/aqmp-tui: Add scrolling to history box Date: Sat, 31 Jul 2021 01:48:43 +0530 Message-Id: <20210730201846.5147-11-niteesh.gs@gmail.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20210730201846.5147-1-niteesh.gs@gmail.com> References: <20210730201846.5147-1-niteesh.gs@gmail.com> Received-SPF: pass client-ip=2607:f8b0:4864:20::1031; envelope-from=niteesh.gs@gmail.com; helo=mail-pj1-x1031.google.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, FREEMAIL_FROM=0.001, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: ehabkost@redhat.com, kchamart@redhat.com, jsnow@redhat.com, armbru@redhat.com, wainersm@redhat.com, G S Niteesh Babu , stefanha@redhat.com, crosa@redhat.com, eblake@redhat.com Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: "Qemu-devel" Adds scroll support to history box. The list can now be scrolled using arrow keys, page up/down and the mouse. The current implementation requires the widget to be in focus to enable scrolling. Therefore the user has to click on the widget before scrolling. Signed-off-by: G S Niteesh Babu --- python/qemu/aqmp/aqmp_tui.py | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/python/qemu/aqmp/aqmp_tui.py b/python/qemu/aqmp/aqmp_tui.py index ef91883fa5..fb828b1a27 100644 --- a/python/qemu/aqmp/aqmp_tui.py +++ b/python/qemu/aqmp/aqmp_tui.py @@ -351,6 +351,19 @@ def add_to_history(self, if self.history: self.history.set_focus(len(self.history) - 1) + def mouse_event(self, size: Tuple[int, int], _event: str, button: float, + _x: int, _y: int, focus: bool) -> None: + # Scroll only on focus. Therefore it is required to + # click on the widget to enable scrolling. + if not focus: + return + # button == 4 represents scroll up event + if button == 4.0: + super().keypress(size, 'up') + # button == 5 represents scroll down event + elif button == 5.0: + super().keypress(size, 'down') + class HistoryWindow(urwid.Frame): """ From patchwork Fri Jul 30 20:18:44 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Niteesh G. S." X-Patchwork-Id: 12411847 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-13.5 required=3.0 tests=BAYES_00, DKIM_ADSP_CUSTOM_MED,DKIM_INVALID,DKIM_SIGNED,FREEMAIL_FORGED_FROMDOMAIN, FREEMAIL_FROM,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER, INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED, USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 03F4AC4338F for ; Fri, 30 Jul 2021 20:25:01 +0000 (UTC) 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 mail.kernel.org (Postfix) with ESMTPS id BE84560E09 for ; Fri, 30 Jul 2021 20:25:00 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.4.1 mail.kernel.org BE84560E09 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=gmail.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=nongnu.org Received: from localhost ([::1]:47134 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1m9Z3z-0002Zu-Q3 for qemu-devel@archiver.kernel.org; Fri, 30 Jul 2021 16:24:59 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:50932) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1m9Yyo-0005oO-OB for qemu-devel@nongnu.org; Fri, 30 Jul 2021 16:19:39 -0400 Received: from mail-pj1-x102f.google.com ([2607:f8b0:4864:20::102f]:43629) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1m9Yyn-00017l-3j for qemu-devel@nongnu.org; Fri, 30 Jul 2021 16:19:38 -0400 Received: by mail-pj1-x102f.google.com with SMTP id pj14-20020a17090b4f4eb029017786cf98f9so5386831pjb.2 for ; Fri, 30 Jul 2021 13:19:36 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=4KZ0HzG+B9+mKhjGsq5d786iXcrEj0YCq/8pG6bXXhM=; b=LSvJoPc3F/6GdhImMoPMULwzxA9ZjJktB6VK/VwTTMa+MMQY1w5PpeLa3u8reoT0F1 NmH22XETOaYY1A5+b9upKawuR84JMLsI0fvgHxcbARNIA8FFBIK0Z3W/+MiLNzxtA3s+ v9Id5epyO9+ceWw/gUsHIQZKOe6Nct3YIvOOYJMZRV43FnHdK+4F2Qq1Y7vhID6HhiMN EG1sTgwzonBNOKYzBufPggO4vVMdwP55yJChTdnCqGLwzWrcE4AvZ+GfuTvY+hPL4JsF PVarvTiYQsrQZrfb0NX1H1NISJS6KXolj4S6IPpKQ9DfeHkaPbjQd5aClvqkVQOpj0+5 Rc3Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=4KZ0HzG+B9+mKhjGsq5d786iXcrEj0YCq/8pG6bXXhM=; b=caS6eSjl8XyCkQBcuhDVnVfwAzQnDgyqudUIE/wk20ZLhZLlkM/WW7705Su6MDXUmt ZGsSgPXe+qeT1K+gYbnH7Dye+DLcRX8q7gE+G3V03l2ZUtkwFoeRO7bDZhp3pkPXbPeI CVWomg5Av/Doa4G0pwU2jVO5EziT72MNuSAtP6ceQkRQBMQ6JAkL+92pYg/L0Z4lRIXk 0n7RAHINO7JRey8BTTI8angJDy0ByKNpD3T8anu6LAQRUXNfUxFTxY+GomQt9uhhO0J8 cLbVbp/wA+b/vZLee8S2Z1scYvfjQSprPMvUWYrTQB30nkgXTYHWEBgdHhp+qeUit0XE Na3g== X-Gm-Message-State: AOAM531Kxx6wtuUncJ2TEwynpC8XqZEsBCmAF1vwwrVNeAnooA3B/cfP 5rvwJEGMaFfH90B+1KdYojuZgVpNZZIHPw== X-Google-Smtp-Source: ABdhPJyTfLpfinEvXIJ7cwLyBEEDRCKzuOeafixbUN3CnmGEQ1RIBRdvd5F90ecA8ORfjmc+kvftbg== X-Received: by 2002:a05:6a00:1756:b029:340:d051:518b with SMTP id j22-20020a056a001756b0290340d051518bmr4236316pfc.25.1627676375683; Fri, 30 Jul 2021 13:19:35 -0700 (PDT) Received: from localhost.localdomain ([120.138.12.243]) by smtp.gmail.com with ESMTPSA id s50sm3256842pfw.212.2021.07.30.13.19.32 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 30 Jul 2021 13:19:35 -0700 (PDT) From: G S Niteesh Babu To: qemu-devel@nongnu.org Subject: [PATCH v3 11/13] python/aqmp-tui: Add ability to highlight messages Date: Sat, 31 Jul 2021 01:48:44 +0530 Message-Id: <20210730201846.5147-12-niteesh.gs@gmail.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20210730201846.5147-1-niteesh.gs@gmail.com> References: <20210730201846.5147-1-niteesh.gs@gmail.com> Received-SPF: pass client-ip=2607:f8b0:4864:20::102f; envelope-from=niteesh.gs@gmail.com; helo=mail-pj1-x102f.google.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, FREEMAIL_FROM=0.001, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: ehabkost@redhat.com, kchamart@redhat.com, jsnow@redhat.com, armbru@redhat.com, wainersm@redhat.com, G S Niteesh Babu , stefanha@redhat.com, crosa@redhat.com, eblake@redhat.com Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: "Qemu-devel" Adds ability to highlight messages in the history box. The messages can be selected using up/down arrow keys. This can be enhanced in the future to apply specific settings to a particular message. Signed-off-by: G S Niteesh Babu --- python/qemu/aqmp/aqmp_tui.py | 50 ++++++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) diff --git a/python/qemu/aqmp/aqmp_tui.py b/python/qemu/aqmp/aqmp_tui.py index fb828b1a27..4bae0d4e89 100644 --- a/python/qemu/aqmp/aqmp_tui.py +++ b/python/qemu/aqmp/aqmp_tui.py @@ -344,6 +344,7 @@ def __init__(self, master: App) -> None: self.master = master self.history = urwid.SimpleFocusListWalker([]) super().__init__(self.history) + self.highlighting = -1 def add_to_history(self, history: Union[str, List[Tuple[str, str]]]) -> None: @@ -351,8 +352,57 @@ def add_to_history(self, if self.history: self.history.set_focus(len(self.history) - 1) + def _remove_highlighting(self) -> None: + assert self.highlighting != -1 + pos = self.highlighting + widget = self.history[pos] + widget = widget.original_widget + self.history[pos] = widget + + def _update_highlighting(self) -> None: + assert self.highlighting != -1 + pos = self.highlighting + widget = self.history[pos] + self.history[pos] = urwid.LineBox(widget) + + def keypress(self, size: Tuple[int, int], key: str) -> Optional[str]: + if key == 'up': + if self.highlighting != -1: + pos = self.highlighting + self._remove_highlighting() + pos = max(pos - 1, 0) + self.highlighting = pos + else: + self.highlighting = len(self.history) - 1 + self._update_highlighting() + self.change_focus(size, self.highlighting) + return None + if key == 'down': + pos = self.highlighting + if pos == -1: + return None + + self._remove_highlighting() + if pos == len(self.history) - 1: + self.highlighting = -1 + else: + self.highlighting = pos + 1 + self._update_highlighting() + self.change_focus(size, self.highlighting) + return None + + # Remove highlighting if someother key is pressed + if self.highlighting != -1: + self._remove_highlighting() + self.highlighting = -1 + return super().keypress(size, key) # type: ignore + def mouse_event(self, size: Tuple[int, int], _event: str, button: float, _x: int, _y: int, focus: bool) -> None: + if self.highlighting != -1: + self._remove_highlighting() + self.highlighting = -1 + # Scroll only on focus. Therefore it is required to # click on the widget to enable scrolling. if not focus: From patchwork Fri Jul 30 20:18:45 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Niteesh G. S." X-Patchwork-Id: 12411915 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-13.6 required=3.0 tests=BAYES_00, DKIM_ADSP_CUSTOM_MED,DKIM_INVALID,DKIM_SIGNED,FREEMAIL_FORGED_FROMDOMAIN, FREEMAIL_FROM,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER, INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id D8B30C4338F for ; Fri, 30 Jul 2021 20:26:54 +0000 (UTC) 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 mail.kernel.org (Postfix) with ESMTPS id 901B760E09 for ; Fri, 30 Jul 2021 20:26:54 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.4.1 mail.kernel.org 901B760E09 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=gmail.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=nongnu.org Received: from localhost ([::1]:54318 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1m9Z5p-0007Yf-LU for qemu-devel@archiver.kernel.org; Fri, 30 Jul 2021 16:26:53 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:50948) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1m9Yys-00060g-9h for qemu-devel@nongnu.org; Fri, 30 Jul 2021 16:19:42 -0400 Received: from mail-pj1-x1029.google.com ([2607:f8b0:4864:20::1029]:35331) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1m9Yyq-00019y-JE for qemu-devel@nongnu.org; Fri, 30 Jul 2021 16:19:42 -0400 Received: by mail-pj1-x1029.google.com with SMTP id pf12-20020a17090b1d8cb0290175c085e7a5so22461407pjb.0 for ; Fri, 30 Jul 2021 13:19:40 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=Dsu/4D9anWF9gnF2alt4V4p0NibEInA/6NoWQOcZZeQ=; b=l5ZtYm571GU8Dkwhkk1MsPyhAqnZnQv3aN5bYzO/KINiECVnewgalqNsAgZSKwmci5 qq4k3ZEMd1aYj6YDN6ZOSh8wdY5kiJiV+EGd9+eKM0oFyl6La6rzjET2gkko9aNVS78/ OrEc5D4IZV2hKCWcTroJfQNI3ZifRkXpZbx7/tcJnMj53/ZZM2CQ4qed8qf8DVnf/9iG GoMCvbN+jVncwDHZdXQ1VHoCnhmb/K4mRSQUg/5w5xste3moHOOATL5o+rTAWIBZTNjc 8SvYT6LW4hKV1p5xsl/otWVNMXxKsIJ5AJD6DnfWRGNuPv9dhUCLvJrKwFwsHQrEtAyd acQA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=Dsu/4D9anWF9gnF2alt4V4p0NibEInA/6NoWQOcZZeQ=; b=aV4StURAwVwmbq2MK82h5P0di/0bey4TFi2mmXxrQeWLmggnoG52uOjJBlH9i88My6 X7Rc7Yl9aTX5etOybpSyWvR1yDstwq4Pk2KrkUv48L2IOweZmqUtGOFx3fxl6Wx+SU1S 31KxtyR7Tlg/8KsjpcCUT7V9/ia+etANL7SxAzHKhnp5zFHLzvPAaqp9EuF90+dPP6Ji ZA74bOk3tCOhLbzSaeCRsz6mN13oT3RHjdLHC/XrfhLexzObgxGgJ1WB5sr/h7T34pee N/nujKNpAFEk+92KoA2NbBMiOw/EWbGbnhD1XMFoU240cZEL2fRHuagZbCvdKeHhQgRC mBvQ== X-Gm-Message-State: AOAM530RUQ/a4o0Gua63pXwlj1h92Y6Q24BE7Wh4QPLY0SqCsiTc++Ie oNhX0QJDo9DNGWjfNaPecYVqlVgcOxl8Xw== X-Google-Smtp-Source: ABdhPJw5CA1Xt8Y3ugo1Gmgtnl0n9O/+3tXowogP8KTILx62qJW9ilHv8M5rq+PETRtcRFgPOPXTSQ== X-Received: by 2002:a17:902:ce8b:b029:12b:2b93:fbdc with SMTP id f11-20020a170902ce8bb029012b2b93fbdcmr3779261plg.46.1627676379194; Fri, 30 Jul 2021 13:19:39 -0700 (PDT) Received: from localhost.localdomain ([120.138.12.243]) by smtp.gmail.com with ESMTPSA id s50sm3256842pfw.212.2021.07.30.13.19.36 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 30 Jul 2021 13:19:38 -0700 (PDT) From: G S Niteesh Babu To: qemu-devel@nongnu.org Subject: [PATCH v3 12/13] python/aqmp-tui: Add pyperclip dependency Date: Sat, 31 Jul 2021 01:48:45 +0530 Message-Id: <20210730201846.5147-13-niteesh.gs@gmail.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20210730201846.5147-1-niteesh.gs@gmail.com> References: <20210730201846.5147-1-niteesh.gs@gmail.com> Received-SPF: pass client-ip=2607:f8b0:4864:20::1029; envelope-from=niteesh.gs@gmail.com; helo=mail-pj1-x1029.google.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, FREEMAIL_FROM=0.001, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: ehabkost@redhat.com, kchamart@redhat.com, jsnow@redhat.com, armbru@redhat.com, wainersm@redhat.com, G S Niteesh Babu , stefanha@redhat.com, crosa@redhat.com, eblake@redhat.com Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: "Qemu-devel" This dependency is required to enable copying from the TUI using special keys to the system clipboard. pyperclip works out of the box on windows and macos but requires xsel/xclip to be installed on linux machines. Signed-off-by: G S Niteesh Babu --- python/Pipfile.lock | 22 ++++++++++++++++++++++ python/setup.cfg | 5 +++++ 2 files changed, 27 insertions(+) diff --git a/python/Pipfile.lock b/python/Pipfile.lock index 2c6d779348..3544c8703d 100644 --- a/python/Pipfile.lock +++ b/python/Pipfile.lock @@ -45,6 +45,14 @@ "index": "pypi", "version": "==87.0" }, + "backports.entry-points-selectable": { + "hashes": [ + "sha256:988468260ec1c196dab6ae1149260e2f5472c9110334e5d51adcb77867361f6a", + "sha256:a6d9a871cde5e15b4c4a53e3d43ba890cc6861ec1332c9c2428c92f977192acc" + ], + "markers": "python_version >= '2.7'", + "version": "==1.1.0" + }, "distlib": { "hashes": [ "sha256:106fef6dc37dd8c0e2c0a60d3fca3e77460a48907f335fa28420463a6f799736", @@ -169,6 +177,14 @@ "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", "version": "==20.9" }, + "platformdirs": { + "hashes": [ + "sha256:4666d822218db6a262bdfdc9c39d21f23b4cfdb08af331a81e92751daf6c866c", + "sha256:632daad3ab546bd8e6af0537d09805cec458dce201bccfe23012df73332e181e" + ], + "markers": "python_version >= '3.6'", + "version": "==2.2.0" + }, "pluggy": { "hashes": [ "sha256:15b2acde666561e1298d71b523007ed7364de07029219b604cf808bfa1c765b0", @@ -224,6 +240,12 @@ "markers": "python_version >= '2.6' and python_version not in '3.0, 3.1, 3.2, 3.3'", "version": "==2.4.7" }, + "pyperclip": { + "hashes": [ + "sha256:105254a8b04934f0bc84e9c24eb360a591aaf6535c9def5f29d92af107a9bf57" + ], + "version": "==1.8.2" + }, "qemu": { "editable": true, "path": "." diff --git a/python/setup.cfg b/python/setup.cfg index bbb7306c3d..683c0b1d00 100644 --- a/python/setup.cfg +++ b/python/setup.cfg @@ -47,6 +47,7 @@ devel = urwid >= 2.1.2 urwid-readline >= 0.13 Pygments >= 2.9.0 + pyperclip >= 1.8.2 # Provides qom-fuse functionality fuse = @@ -57,6 +58,7 @@ tui = urwid >= 2.1.2 urwid-readline >= 0.13 Pygments >= 2.9.0 + pyperclip >= 1.8.2 [options.entry_points] console_scripts = @@ -102,6 +104,9 @@ ignore_missing_imports = True [mypy-pygments] ignore_missing_imports = True +[mypy-pyperclip] +ignore_missing_imports = True + [pylint.messages control] # Disable the message, report, category or checker with the given id(s). You # can either give multiple identifiers separated by comma (,) or put this From patchwork Fri Jul 30 20:18:46 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Niteesh G. S." X-Patchwork-Id: 12411917 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-13.5 required=3.0 tests=BAYES_00, DKIM_ADSP_CUSTOM_MED,DKIM_INVALID,DKIM_SIGNED,FREEMAIL_FORGED_FROMDOMAIN, FREEMAIL_FROM,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER, INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED, USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 7ACC1C4338F for ; Fri, 30 Jul 2021 20:27:02 +0000 (UTC) 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 mail.kernel.org (Postfix) with ESMTPS id 3F4B560E09 for ; Fri, 30 Jul 2021 20:27:02 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.4.1 mail.kernel.org 3F4B560E09 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=gmail.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=nongnu.org Received: from localhost ([::1]:54900 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1m9Z5x-00080f-En for qemu-devel@archiver.kernel.org; Fri, 30 Jul 2021 16:27:01 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:50978) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1m9Yyv-0006D6-TV for qemu-devel@nongnu.org; Fri, 30 Jul 2021 16:19:45 -0400 Received: from mail-pj1-x102b.google.com ([2607:f8b0:4864:20::102b]:54225) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1m9Yyu-0001Bx-0S for qemu-devel@nongnu.org; Fri, 30 Jul 2021 16:19:45 -0400 Received: by mail-pj1-x102b.google.com with SMTP id j1so16842958pjv.3 for ; Fri, 30 Jul 2021 13:19:43 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=RvQdQFOqZAua2VjIGleNmluh7reCfzFuoJQXI/+8inM=; b=M5wPVGYldyGNSDhCr+5PcVN5FZwNNbm3ZwUNJNNbB6R51ZshMfmeqWFdTsRxmwOj9l wGQhDmBTnviMqVUgLIGbKfdCxuROIJJ9FY+JQsfZ+3olLa6tt81wlpXDafdDPGAxjx2S cFbjHdVMdaGU8TchSUtM3N0aHWBl/PgQOaO+OeQqRFL2l19xW4LpFDU1+a4gmAA7QZGt UQd1NBwjnntWSrMyHCDV/M4uPRm/d6m4HhWr9c3TsphePw3bjGf6+RLcdiNwKVwK3CON ZsPpYQFYeAcoMjjCYyHybo4j9Q/3z77QoJErMDRBkz+GrsYUM1YATbI2TVRrnAdh1dgn /8lQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=RvQdQFOqZAua2VjIGleNmluh7reCfzFuoJQXI/+8inM=; b=XN5a5MQg0Ibz0Gkl1CFbCHfoJky7gyKBRRF24nt8rso/ou8nHq/3i7H1m3MSYZOqMj skaogMWM8W0TvuLP9QAhWSVC8PIaHxXaYTOcqjLX7yX+/b6N5t85GcWTdGmBUlwK3QCq oxTQniWJEwvgxoCjWc/qLCZ8Q0dkRK15uWxvcYNTkAqTAuCk4AnNNSuUouIm0IrYrV8X g2yxFx/FwOeIla/QKSMTiy/rKWR42Y/6fjDXKhoHPCpm9hVMiXETc9nu0mHFPq+7V/PM 4quOkmlWE98r5xi1jG4seo6uEHRtN/SILoTJc7ZamJUxTa1a6KpLsM5jMG30ZeKs88pI FNuw== X-Gm-Message-State: AOAM531dMuyMcNj0pbVW3j8Olc5zHlBTnCDf3Muh1hcDBxdxa8G8A3WA ydqm6um+xn9J/rweHfEofKMJjFB3GDvpAw== X-Google-Smtp-Source: ABdhPJydPh1tv6IMmEt04TE2fvViBfEEN8uuT6nEwJeGVzDaepXHtXY+SgRNtjQwM8LocPjXJu3G7g== X-Received: by 2002:a17:90a:9483:: with SMTP id s3mr4944312pjo.22.1627676382648; Fri, 30 Jul 2021 13:19:42 -0700 (PDT) Received: from localhost.localdomain ([120.138.12.243]) by smtp.gmail.com with ESMTPSA id s50sm3256842pfw.212.2021.07.30.13.19.39 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 30 Jul 2021 13:19:42 -0700 (PDT) From: G S Niteesh Babu To: qemu-devel@nongnu.org Subject: [PATCH v3 13/13] python/aqmp-tui: Allow copying message from TUI Date: Sat, 31 Jul 2021 01:48:46 +0530 Message-Id: <20210730201846.5147-14-niteesh.gs@gmail.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20210730201846.5147-1-niteesh.gs@gmail.com> References: <20210730201846.5147-1-niteesh.gs@gmail.com> Received-SPF: pass client-ip=2607:f8b0:4864:20::102b; envelope-from=niteesh.gs@gmail.com; helo=mail-pj1-x102b.google.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, FREEMAIL_FROM=0.001, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: ehabkost@redhat.com, kchamart@redhat.com, jsnow@redhat.com, armbru@redhat.com, wainersm@redhat.com, G S Niteesh Babu , stefanha@redhat.com, crosa@redhat.com, eblake@redhat.com Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: "Qemu-devel" This commit adds a feature that enables use to copy messages from the TUI after highlighting the message in the history box using up/down arrow keys and pressing alt-c. Signed-off-by: G S Niteesh Babu --- python/qemu/aqmp/aqmp_tui.py | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/python/qemu/aqmp/aqmp_tui.py b/python/qemu/aqmp/aqmp_tui.py index 4bae0d4e89..434f431a35 100644 --- a/python/qemu/aqmp/aqmp_tui.py +++ b/python/qemu/aqmp/aqmp_tui.py @@ -21,6 +21,7 @@ from pygments import lexers from pygments import token as Token +import pyperclip import urwid import urwid_readline @@ -390,6 +391,14 @@ def keypress(self, size: Tuple[int, int], key: str) -> Optional[str]: self._update_highlighting() self.change_focus(size, self.highlighting) return None + if key == 'meta c': + if self.highlighting == -1: + return None + widget = self.history[self.highlighting].original_widget + text = widget.get_text()[0] + LOGGER.info('Text is %s', text) + pyperclip.copy(text) + return None # Remove highlighting if someother key is pressed if self.highlighting != -1: