From mboxrd@z Thu Jan 1 00:00:00 1970 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=-10.6 required=3.0 tests=BAYES_00,DKIM_INVALID, DKIM_SIGNED,HEADER_FROM_DIFFERENT_DOMAINS,HTML_MESSAGE,INCLUDES_CR_TRAILER, INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED 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 E5F04C47082 for ; Tue, 8 Jun 2021 23:56:22 +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 30EF261278 for ; Tue, 8 Jun 2021 23:56:22 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 30EF261278 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=redhat.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Received: from localhost ([::1]:60270 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1lqla1-0003hg-5k for qemu-devel@archiver.kernel.org; Tue, 08 Jun 2021 19:56:21 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:60310) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1lqlZL-0002tT-0A for qemu-devel@nongnu.org; Tue, 08 Jun 2021 19:55:39 -0400 Received: from us-smtp-delivery-124.mimecast.com ([170.10.133.124]:21104) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1lqlZF-0004BO-L9 for qemu-devel@nongnu.org; Tue, 08 Jun 2021 19:55:37 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1623196531; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: in-reply-to:in-reply-to:references:references; bh=//NQZd4qrXW1T55TH8lQFj6a+hKQCPq/RN+AnIi9cew=; b=T1rVqzT2bMcZWkYORY7q5FiW7hmIjoYYW/s8EOl8IjolXbMsZvkq3/5Ix28Pb1Wvqq5GPQ +cWOwsBQ0oWOOB1LH9T4ISpY+ok+e4ULLF1gzf56HusoyPlrk0OlmsLvdtip6h5eHnzpSC HcQqK8Gt6ToBS/2v/2f+ytbYZZs2Gck= Received: from mail-ej1-f70.google.com (mail-ej1-f70.google.com [209.85.218.70]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-252-KNEbN-IRMHS8uVqkhn_JHw-1; Tue, 08 Jun 2021 19:55:29 -0400 X-MC-Unique: KNEbN-IRMHS8uVqkhn_JHw-1 Received: by mail-ej1-f70.google.com with SMTP id jy19-20020a1709077633b02903eb7acdb38cso7337809ejc.14 for ; Tue, 08 Jun 2021 16:55:29 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:mime-version:references:in-reply-to:from:date :message-id:subject:to:cc; bh=//NQZd4qrXW1T55TH8lQFj6a+hKQCPq/RN+AnIi9cew=; b=MaGwho22Nhp0L2h4zbHZK4ZYVw9PJijJWW/OGukH44hSJXydmrEWxsoCk0Z1BHUeFY NJEwQJJyfDqUj4cCnXxk3PfnnliDFh7OwE1IfXH/zWUCY3eEVagAouNYVolrCW3NUlMa o9vSr6KmxyXlfw8rx5GNaxjTrqu2NOFv7gXrrunm+Z778npPF2jWwvPRnESANeVZqdQs 1HOMoTangf71KOTkK1WXyjttgB4nZvqcXyEthHYzb5Hh4myL/XCZEAHjLdiNjiknIwZR vqhNE1FbEfd0J3I3WLd4A/YpKL2m/WSZPA8tWZ9OY9M965t1TSDz4szbV7pUSwaFZnzk IJFw== X-Gm-Message-State: AOAM533VnZKaARMl+gj4oFuc+b9dIubp3ECsmAqnjq8hk/wcLR/fp2R9 wT3FEx9vWxVh7BR+4kO5R2vdN9hMXvkg0Pul04mzsuVZJj6MwBgawMl5mOpSjCAJIGYfM3+TsuE E8CiNdYzh5pc2rIOKGOh7GbPQzq5d65k= X-Received: by 2002:a05:6402:1713:: with SMTP id y19mr28103577edu.346.1623196528607; Tue, 08 Jun 2021 16:55:28 -0700 (PDT) X-Google-Smtp-Source: ABdhPJxeO+Bj9Pcd8IHQqjei5OEnokLX63w0Df8uS5PDYJqoURZZFryflmEUdCXoOiPqF9g4Q3urCrQnOuaBL0c6emA= X-Received: by 2002:a05:6402:1713:: with SMTP id y19mr28103544edu.346.1623196528336; Tue, 08 Jun 2021 16:55:28 -0700 (PDT) MIME-Version: 1.0 References: <20210608140938.863580-1-crosa@redhat.com> <20210608140938.863580-3-crosa@redhat.com> In-Reply-To: From: Cleber Rosa Junior Date: Tue, 8 Jun 2021 19:55:17 -0400 Message-ID: Subject: Re: [PATCH 2/4] Python QEMU utils: introduce a generic feature list To: Wainer dos Santos Moschetta Authentication-Results: relay.mimecast.com; auth=pass smtp.auth=CUSA124A263 smtp.mailfrom=crosa@redhat.com X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Content-Type: multipart/alternative; boundary="00000000000078f20505c449e424" Received-SPF: pass client-ip=170.10.133.124; envelope-from=crosa@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -29 X-Spam_score: -3.0 X-Spam_bar: --- X-Spam_report: (-3.0 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.197, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, HTML_MESSAGE=0.001, RCVD_IN_DNSWL_LOW=-0.7, RCVD_IN_MSPIKE_H4=0.001, RCVD_IN_MSPIKE_WL=0.001, 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: Kevin Wolf , Fam Zheng , Thomas Huth , Eduardo Habkost , qemu-block@nongnu.org, Erik Skultety , =?UTF-8?Q?Philippe_Mathieu=2DDaud=C3=A9?= , =?UTF-8?Q?Philippe_Mathieu=2DDaud=C3=A9?= , qemu-devel , Willian Rampazzo , Max Reitz , Willian Rampazzo , Stefan Hajnoczi , Andrea Bolognani , =?UTF-8?B?QWxleCBCZW5uw6ll?= , John Snow , Beraldo Leal Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: "Qemu-devel" --00000000000078f20505c449e424 Content-Type: text/plain; charset="UTF-8" On Tue, Jun 8, 2021 at 5:42 PM Wainer dos Santos Moschetta < wainersm@redhat.com> wrote: > Hi, > > On 6/8/21 11:09 AM, Cleber Rosa wrote: > > Which can be used to check for any "feature" that is available as a > > QEMU command line option, and that will return its list of available > > options. > > > > This is a generalization of the list_accel() utility function, which > > is itself re-implemented in terms of the more generic feature. > > > > Signed-off-by: Cleber Rosa > > --- > > python/qemu/utils/__init__.py | 2 ++ > > python/qemu/utils/accel.py | 15 ++---------- > > python/qemu/utils/feature.py | 44 +++++++++++++++++++++++++++++++++++ > > 3 files changed, 48 insertions(+), 13 deletions(-) > > create mode 100644 python/qemu/utils/feature.py > > > > diff --git a/python/qemu/utils/__init__.py > b/python/qemu/utils/__init__.py > > index 7f1a5138c4..1d0789eaa2 100644 > > --- a/python/qemu/utils/__init__.py > > +++ b/python/qemu/utils/__init__.py > > @@ -20,12 +20,14 @@ > > > > # pylint: disable=import-error > > from .accel import kvm_available, list_accel, tcg_available > > +from .feature import list_feature > > > > > > __all__ = ( > > 'get_info_usernet_hostfwd_port', > > 'kvm_available', > > 'list_accel', > > + 'list_feature', > > 'tcg_available', > > ) > > > > diff --git a/python/qemu/utils/accel.py b/python/qemu/utils/accel.py > > index 297933df2a..b5bb80c6d3 100644 > > --- a/python/qemu/utils/accel.py > > +++ b/python/qemu/utils/accel.py > > @@ -14,13 +14,11 @@ > > # the COPYING file in the top-level directory. > > # > > > > -import logging > > import os > > -import subprocess > > from typing import List, Optional > > > > +from qemu.utils.feature import list_feature > > > > -LOG = logging.getLogger(__name__) > > > > # Mapping host architecture to any additional architectures it can > > # support which often includes its 32 bit cousin. > > @@ -39,16 +37,7 @@ def list_accel(qemu_bin: str) -> List[str]: > > @raise Exception: if failed to run `qemu -accel help` > > @return a list of accelerator names. > > """ > > - if not qemu_bin: > > - return [] > > - try: > > - out = subprocess.check_output([qemu_bin, '-accel', 'help'], > > - universal_newlines=True) > > - except: > > - LOG.debug("Failed to get the list of accelerators in %s", > qemu_bin) > > - raise > > - # Skip the first line which is the header. > > - return [acc.strip() for acc in out.splitlines()[1:]] > > + return list_feature(qemu_bin, 'accel') > > > > > > def kvm_available(target_arch: Optional[str] = None, > > diff --git a/python/qemu/utils/feature.py b/python/qemu/utils/feature.py > > new file mode 100644 > > index 0000000000..b4a5f929ab > > --- /dev/null > > +++ b/python/qemu/utils/feature.py > > @@ -0,0 +1,44 @@ > > +""" > > +QEMU feature module: > > + > > +This module provides a utility for discovering the availability of > > +generic features. > > +""" > > +# Copyright (C) 2022 Red Hat Inc. > Cleber, please, tell me how is the future like! :) > I grabbed a sports almanac. That's all I can say. :) Now seriously, thanks for spotting the typo. > > +# > > +# Authors: > > +# Cleber Rosa > > +# > > +# This work is licensed under the terms of the GNU GPL, version 2. See > > +# the COPYING file in the top-level directory. > > +# > > + > > +import logging > > +import subprocess > > +from typing import List > > + > > + > > +LOG = logging.getLogger(__name__) > > + > > + > > +def list_feature(qemu_bin: str, feature: str) -> List[str]: > > + """ > > + List available options the QEMU binary for a given feature type. > > + > > + By calling a "qemu $feature -help" and parsing its output. > > I understand we need a mean to easily cancel the test if given feature > is not present. However, I'm unsure this generic list_feature() is what > we need. > > The `-accel help` returns a simple list of strings (besides the header, > which is dismissed). Whereas `-machine help` returns what could be > parsed as a tuple of (name, description). > > Another example is `-cpu help` which will print a similar list as > `-machine`, plus a section with CPUID flags. > > I made sure it worked with both "accel" and "machine", but you're right about many other "-$feature help" that won't conform to the mapping ("-chardev help" is probably the only other one that should work). What I thought about was to keep the same list_feature(), but make its parsing of items flexible. Then it could be reused for other list_$feature() like methods. At the same time, it could be an opportunity to standardize a bit more of the "help" outputs. For instance, I think it would make sense for "cpu" to keep showing the amount of information it shows, but: 1) The first item could be the name of the relevant "option" (the cpu model) for that feature (cpu), instead of, say, "x86". Basically reversing the order of first and second, or first and third fields. 2) Everything *after* an empty line would be extra information, not necessarily an option available for that feature. But, this is most probably not going to be achieved in the short term. What I can do here, is to hide list_feature(), say call it _list_feature() so that we don't duplicate code, and expose a list_machine(). Let me know what you think. Thanks, - Cleber. > If confess I still don't have a better idea, although I feel it will > require a OO design. > > Thanks! > > - Wainer > > > + > > + @param qemu_bin (str): path to the QEMU binary. > > + @param feature (str): feature name, matching the command line > option. > > + @raise Exception: if failed to run `qemu -feature help` > > + @return a list of available options for the given feature. > > + """ > > + if not qemu_bin: > > + return [] > > + try: > > + out = subprocess.check_output([qemu_bin, '-%s' % feature, > 'help'], > > + universal_newlines=True) > > + except: > > + LOG.debug("Failed to get the list of %s(s) in %s", feature, > qemu_bin) > > + raise > > + # Skip the first line which is the header. > > + return [item.split(' ', 1)[0] for item in out.splitlines()[1:]] > > --00000000000078f20505c449e424 Content-Type: text/html; charset="UTF-8" Content-Transfer-Encoding: quoted-printable


=
On Tue, Jun 8, 2021 at 5:42 PM Wainer= dos Santos Moschetta <wainersm@r= edhat.com> wrote:
Hi,

On 6/8/21 11:09 AM, Cleber Rosa wrote:
> Which can be used to check for any "feature" that is availab= le as a
> QEMU command line option, and that will return its list of available > options.
>
> This is a generalization of the list_accel() utility function, which > is itself re-implemented in terms of the more generic feature.
>
> Signed-off-by: Cleber Rosa <crosa@redhat.com>
> ---
>=C2=A0 =C2=A0python/qemu/utils/__init__.py |=C2=A0 2 ++
>=C2=A0 =C2=A0python/qemu/utils/accel.py=C2=A0 =C2=A0 | 15 ++----------<= br> >=C2=A0 =C2=A0python/qemu/utils/feature.py=C2=A0 | 44 ++++++++++++++++++= +++++++++++++++++
>=C2=A0 =C2=A03 files changed, 48 insertions(+), 13 deletions(-)
>=C2=A0 =C2=A0create mode 100644 python/qemu/utils/feature.py
>
> diff --git a/python/qemu/utils/__init__.py b/python/qemu/utils/__init_= _.py
> index 7f1a5138c4..1d0789eaa2 100644
> --- a/python/qemu/utils/__init__.py
> +++ b/python/qemu/utils/__init__.py
> @@ -20,12 +20,14 @@
>=C2=A0 =C2=A0
>=C2=A0 =C2=A0# pylint: disable=3Dimport-error
>=C2=A0 =C2=A0from .accel import kvm_available, list_accel, tcg_availabl= e
> +from .feature import list_feature
>=C2=A0 =C2=A0
>=C2=A0 =C2=A0
>=C2=A0 =C2=A0__all__ =3D (
>=C2=A0 =C2=A0 =C2=A0 =C2=A0'get_info_usernet_hostfwd_port',
>=C2=A0 =C2=A0 =C2=A0 =C2=A0'kvm_available',
>=C2=A0 =C2=A0 =C2=A0 =C2=A0'list_accel',
> +=C2=A0 =C2=A0 'list_feature',
>=C2=A0 =C2=A0 =C2=A0 =C2=A0'tcg_available',
>=C2=A0 =C2=A0)
>=C2=A0 =C2=A0
> diff --git a/python/qemu/utils/accel.py b/python/qemu/utils/accel.py > index 297933df2a..b5bb80c6d3 100644
> --- a/python/qemu/utils/accel.py
> +++ b/python/qemu/utils/accel.py
> @@ -14,13 +14,11 @@
>=C2=A0 =C2=A0# the COPYING file in the top-level directory.
>=C2=A0 =C2=A0#
>=C2=A0 =C2=A0
> -import logging
>=C2=A0 =C2=A0import os
> -import subprocess
>=C2=A0 =C2=A0from typing import List, Optional
>=C2=A0 =C2=A0
> +from qemu.utils.feature import list_feature
>=C2=A0 =C2=A0
> -LOG =3D logging.getLogger(__name__)
>=C2=A0 =C2=A0
>=C2=A0 =C2=A0# Mapping host architecture to any additional architecture= s it can
>=C2=A0 =C2=A0# support which often includes its 32 bit cousin.
> @@ -39,16 +37,7 @@ def list_accel(qemu_bin: str) -> List[str]:
>=C2=A0 =C2=A0 =C2=A0 =C2=A0@raise Exception: if failed to run `qemu -ac= cel help`
>=C2=A0 =C2=A0 =C2=A0 =C2=A0@return a list of accelerator names.
>=C2=A0 =C2=A0 =C2=A0 =C2=A0"""
> -=C2=A0 =C2=A0 if not qemu_bin:
> -=C2=A0 =C2=A0 =C2=A0 =C2=A0 return []
> -=C2=A0 =C2=A0 try:
> -=C2=A0 =C2=A0 =C2=A0 =C2=A0 out =3D subprocess.check_output([qemu_bin= , '-accel', 'help'],
> -=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 universal_n= ewlines=3DTrue)
> -=C2=A0 =C2=A0 except:
> -=C2=A0 =C2=A0 =C2=A0 =C2=A0 LOG.debug("Failed to get the list of= accelerators in %s", qemu_bin)
> -=C2=A0 =C2=A0 =C2=A0 =C2=A0 raise
> -=C2=A0 =C2=A0 # Skip the first line which is the header.
> -=C2=A0 =C2=A0 return [acc.strip() for acc in out.splitlines()[1:]] > +=C2=A0 =C2=A0 return list_feature(qemu_bin, 'accel')
>=C2=A0 =C2=A0
>=C2=A0 =C2=A0
>=C2=A0 =C2=A0def kvm_available(target_arch: Optional[str] =3D None,
> diff --git a/python/qemu/utils/feature.py b/python/qemu/utils/feature.= py
> new file mode 100644
> index 0000000000..b4a5f929ab
> --- /dev/null
> +++ b/python/qemu/utils/feature.py
> @@ -0,0 +1,44 @@
> +"""
> +QEMU feature module:
> +
> +This module provides a utility for discovering the availability of > +generic features.
> +"""
> +# Copyright (C) 2022 Red Hat Inc.
Cleber, please, tell me how is the future like! :)
I grabbed a sports almanac.=C2=A0 That's all I can say. :)<= /div>

Now seriously, thanks for spotting the typo.
=
=C2=A0
> +#
> +# Authors:
> +#=C2=A0 Cleber Rosa <crosa@redhat.com>
> +#
> +# This work is licensed under the terms of the GNU GPL, version 2.=C2= =A0 See
> +# the COPYING file in the top-level directory.
> +#
> +
> +import logging
> +import subprocess
> +from typing import List
> +
> +
> +LOG =3D logging.getLogger(__name__)
> +
> +
> +def list_feature(qemu_bin: str, feature: str) -> List[str]:
> +=C2=A0 =C2=A0 """
> +=C2=A0 =C2=A0 List available options the QEMU binary for a given feat= ure type.
> +
> +=C2=A0 =C2=A0 By calling a "qemu $feature -help" and parsin= g its output.

I understand we need a mean to easily cancel the test if given feature
is not present. However, I'm unsure this generic list_feature() is what=
we need.

The `-accel help` returns a simple list of strings (besides the header, which is dismissed). Whereas `-machine help` returns what could be
parsed as a tuple of (name, description).

Another example is `-cpu help` which will print a similar list as
`-machine`, plus a section with CPUID flags.


I made sure it worked with both "= accel" and "machine", but you're right about many other = "-$feature help" that won't conform to the mapping ("-ch= ardev help" is probably the only other one that should work).=C2=A0 Wh= at I thought about was to keep the same list_feature(), but make its parsin= g of items flexible.=C2=A0 Then it could be reused for other list_$feature(= ) like methods.=C2=A0 At the same time, it could be an opportunity to stand= ardize a bit more of the "help" outputs.

For instance, I think it would make sense for "cpu" to keep show= ing the amount of information it shows, but:

1) Th= e first item could be the name of the relevant "option" (the cpu = model) for that feature (cpu), instead of, say, "x86". Basically = reversing the order of first and second, or first and third fields.
2) Everything *after* an empty line would be extra information, not nece= ssarily an option available for that feature.

But,= this is most probably not going to be achieved in the short term.

What I can do here, is to hide list_feature(), say call it= _list_feature() so that we don't duplicate code, and expose a list_mac= hine().

Let me know what you think.

=
Thanks,
- Cleber.
=C2=A0
If confess I still don't have a better idea, although I feel it will require a OO design.

Thanks!

- Wainer

> +
> +=C2=A0 =C2=A0 @param qemu_bin (str): path to the QEMU binary.
> +=C2=A0 =C2=A0 @param feature (str): feature name, matching the comman= d line option.
> +=C2=A0 =C2=A0 @raise Exception: if failed to run `qemu -feature help`=
> +=C2=A0 =C2=A0 @return a list of available options for the given featu= re.
> +=C2=A0 =C2=A0 """
> +=C2=A0 =C2=A0 if not qemu_bin:
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 return []
> +=C2=A0 =C2=A0 try:
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 out =3D subprocess.check_output([qemu_bin= , '-%s' % feature, 'help'],
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 universal_n= ewlines=3DTrue)
> +=C2=A0 =C2=A0 except:
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 LOG.debug("Failed to get the list of= %s(s) in %s", feature, qemu_bin)
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 raise
> +=C2=A0 =C2=A0 # Skip the first line which is the header.
> +=C2=A0 =C2=A0 return [item.split(' ', 1)[0] for item in out.s= plitlines()[1:]]

--00000000000078f20505c449e424--