On Tue, Mar 18, 2025 at 05:36:03PM +0100, Peter Krempa wrote:
> From: Peter Krempa <pkre...@redhat.com>
> 
> As no argument parsing is employed the script is hard to use and when
> running without arguments it blurbs:
> 
>  $ ./scripts/render_block_graph.py
>  Traceback (most recent call last):
>    File "/home/pipo/git/qemu.git/./scripts/render_block_graph.py", line 135, 
> in <module>
>      obj = sys.argv[1]
>           ~~~~~~~~^^^
>  IndexError: list index out of range
> 
> instead of an actionable error. The user then usually needs to read the
> script to understand arguments.
> 
> Implement proper argument parsing via 'argparse'. The following
> arguments will be supported:
> 
>  $ ./scripts/render_block_graph.py --help
>  usage: render_block_graph.py [-h] [--socket SOCKET] [--vm VM] [--uri URI] 
> [--output OUTPUT]
> 
>  Tool that renders the qemu block graph into a image.
> 
>  options:
>    -h, --help       show this help message and exit
>    --socket SOCKET  direct mode - path to qemu monitor socket
>    --vm VM          libvirt mode - name of libvirt VM
>    --uri URI        libvirt URI to connect to
>    --output OUTPUT  path to output image; .png suffix will be added; in 
> libvirt mode default is the name of the VM
> 
> Usage then requires one of '--vm' or '--socket'. In libvirt mode the
> output file is by default populated from the VM name and the '--uri'
> parameter allows overriding the libvirt connection uri.
> 
> Signed-off-by: Peter Krempa <pkre...@redhat.com>
> ---
>  scripts/render_block_graph.py | 53 ++++++++++++++++++++++++++++-------
>  1 file changed, 43 insertions(+), 10 deletions(-)
> 
> diff --git a/scripts/render_block_graph.py b/scripts/render_block_graph.py
> index 14b2d02ec2..7a6738410c 100755
> --- a/scripts/render_block_graph.py
> +++ b/scripts/render_block_graph.py
> @@ -23,6 +23,7 @@
>  import subprocess
>  import json
>  from graphviz import Digraph
> +import argparse
> 
>  sys.path.append(os.path.join(os.path.dirname(__file__), '..', 'python'))
>  from qemu.qmp import QMPError
> @@ -91,13 +92,19 @@ def render_block_graph(qmp, filename, format='png'):
> 
> 
>  class LibvirtGuest():
> -    def __init__(self, name):
> +    def __init__(self, name, uri=None):
>          self.name = name
> +        self.uri = uri
> 
>      def cmd(self, cmd):
>          # only supports qmp commands without parameters
>          m = {'execute': cmd}
> -        ar = ['virsh', 'qemu-monitor-command', self.name, json.dumps(m)]
> +        ar = ['virsh']
> +
> +        if self.uri:
> +            ar += ['-c', self.uri]
> +
> +        ar += ['qemu-monitor-command', self.name, json.dumps(m)]
> 
>          reply = json.loads(subprocess.check_output(ar))
> 
> @@ -108,15 +115,41 @@ def cmd(self, cmd):
> 
> 
>  if __name__ == '__main__':
> -    obj = sys.argv[1]
> -    out = sys.argv[2]
> +    parser = argparse.ArgumentParser(
> +            description='Tool that renders the qemu block graph into a 
> image.')
> +
> +    parser.add_argument('--socket',
> +                        help='direct mode - path to qemu monitor socket')
> +
> +    parser.add_argument('--vm', help='libvirt mode - name of libvirt VM')
> +    parser.add_argument('--uri', help='libvirt URI to connect to')
> +
> +    parser.add_argument('--output',
> +                        help='path to output image (.png suffix added);'
> +                             'in libvirt mode default is the name of the VM')
> +
> +    args = parser.parse_args()
> 
> -    if os.path.exists(obj):
> -        # assume unix socket
> -        qmp = QEMUMonitorProtocol(obj)
> +    if (args.socket and args.vm) or (not args.socket and not args.vm):
> +        print("One of --socket or --vm is required.", file=sys.stderr)
> +        parser.print_help()
> +        sys.exit(1)

It's possible to do with argparse as well:

modegroup = parser.add_mutually_exclusive_group(required=True)
modegroup.add_argument('--socket',
                       help='direct mode - path to qemu monitor socket')
modegroup.add_argument('--vm', help='libvirt mode - name of libvirt VM')

The only difference is that it will print usage `parser.print_usage()`.

> +
> +    if args.socket:
> +        qmp = QEMUMonitorProtocol(args.socket)
>          qmp.connect()
> -    else:
> -        # assume libvirt guest name
> -        qmp = LibvirtGuest(obj)
> +
> +    if args.vm:
> +        qmp = LibvirtGuest(args.vm, args.uri)
> +
> +        if args.output:
> +            out = args.output
> +        else:
> +            out = args.vm
> +
> +    if not out:

This needs to use args.output otherwise python will complain that it
doesn't know `out` variable.

> +        print("--output required", file=sys.stderr)
> +        parser.print_help()

Probably use `parser.print_usage()` if you decide to use the
add_mutually_exclusive_group().

Pavel

> +        sys.exit(1)
> 
>      render_block_graph(qmp, out)
> -- 
> 2.48.1
> 
> 

Attachment: signature.asc
Description: PGP signature

Reply via email to