* [PATCH 0/3] scripts: render_block_graph: Fix with new python and improve argument parsing
@ 2025-03-18 16:36 Peter Krempa
2025-03-18 16:36 ` [PATCH 1/3] scripts: render_block_graph: Fix invalid escape sequence warning with python 3.12 Peter Krempa
` (2 more replies)
0 siblings, 3 replies; 5+ messages in thread
From: Peter Krempa @ 2025-03-18 16:36 UTC (permalink / raw)
To: qemu-devel; +Cc: John Snow, Cleber Rosa, qemu-block
New python doesn't like '\l' escapes from the 'dot' language.
While at it improve usability of the script by employing proper argument
parsing.
Peter Krempa (3):
scripts: render_block_graph: Fix invalid escape sequence warning with
python 3.12
scripts: render_block_graph: Implement proper argument parser
scripts: render_block_graph: Avoid backtrace on error from virsh
scripts/render_block_graph.py | 82 +++++++++++++++++++++++++----------
1 file changed, 59 insertions(+), 23 deletions(-)
--
2.48.1
^ permalink raw reply [flat|nested] 5+ messages in thread
* [PATCH 1/3] scripts: render_block_graph: Fix invalid escape sequence warning with python 3.12
2025-03-18 16:36 [PATCH 0/3] scripts: render_block_graph: Fix with new python and improve argument parsing Peter Krempa
@ 2025-03-18 16:36 ` Peter Krempa
2025-03-18 16:36 ` [PATCH 2/3] scripts: render_block_graph: Implement proper argument parser Peter Krempa
2025-03-18 16:36 ` [PATCH 3/3] scripts: render_block_graph: Avoid backtrace on error from virsh Peter Krempa
2 siblings, 0 replies; 5+ messages in thread
From: Peter Krempa @ 2025-03-18 16:36 UTC (permalink / raw)
To: qemu-devel; +Cc: John Snow, Cleber Rosa, qemu-block
From: Peter Krempa <pkrempa@redhat.com>
Trying to run 'render_block_graph' produces following warnings on
machine with python 3.12:
$ ./scripts/render_block_graph.py cd-throttle ble.png
./scripts/render_block_graph.py:57: SyntaxWarning: invalid escape sequence '\l'
' w - Write\l'
./scripts/render_block_graph.py:58: SyntaxWarning: invalid escape sequence '\l'
' r - consistent-Read\l'
./scripts/render_block_graph.py:59: SyntaxWarning: invalid escape sequence '\l'
' u - write - Unchanged\l'
./scripts/render_block_graph.py:60: SyntaxWarning: invalid escape sequence '\l'
[...]
The graphviz '\l' escape sequence is used to left-justify the line and
new python started enforcing of strings to contain only known escape
sequences. Convert the strings containing the dot language to raw.
Signed-off-by: Peter Krempa <pkrempa@redhat.com>
---
scripts/render_block_graph.py | 24 ++++++++++++------------
1 file changed, 12 insertions(+), 12 deletions(-)
diff --git a/scripts/render_block_graph.py b/scripts/render_block_graph.py
index 3e1a2e3fa7..14b2d02ec2 100755
--- a/scripts/render_block_graph.py
+++ b/scripts/render_block_graph.py
@@ -53,16 +53,16 @@ def render_block_graph(qmp, filename, format='png'):
graph = Digraph(comment='Block Nodes Graph')
graph.format = format
- graph.node('permission symbols:\l'
- ' w - Write\l'
- ' r - consistent-Read\l'
- ' u - write - Unchanged\l'
- ' g - Graph-mod\l'
- ' s - reSize\l'
- 'edge label scheme:\l'
- ' <child type>\l'
- ' <perm>\l'
- ' <shared_perm>\l', shape='none')
+ graph.node(r'permission symbols:\l'
+ r' w - Write\l'
+ r' r - consistent-Read\l'
+ r' u - write - Unchanged\l'
+ r' g - Graph-mod\l'
+ r' s - reSize\l'
+ r'edge label scheme:\l'
+ r' <child type>\l'
+ r' <perm>\l'
+ r' <shared_perm>\l', shape='none')
for n in block_graph['nodes']:
if n['type'] == 'block-driver':
@@ -83,8 +83,8 @@ def render_block_graph(qmp, filename, format='png'):
graph.node(str(n['id']), label, shape=shape)
for e in block_graph['edges']:
- label = '%s\l%s\l%s\l' % (e['name'], perm(e['perm']),
- perm(e['shared-perm']))
+ label = r'%s\l%s\l%s\l' % (e['name'], perm(e['perm']),
+ perm(e['shared-perm']))
graph.edge(str(e['parent']), str(e['child']), label=label)
graph.render(filename)
--
2.48.1
^ permalink raw reply related [flat|nested] 5+ messages in thread
* [PATCH 2/3] scripts: render_block_graph: Implement proper argument parser
2025-03-18 16:36 [PATCH 0/3] scripts: render_block_graph: Fix with new python and improve argument parsing Peter Krempa
2025-03-18 16:36 ` [PATCH 1/3] scripts: render_block_graph: Fix invalid escape sequence warning with python 3.12 Peter Krempa
@ 2025-03-18 16:36 ` Peter Krempa
2025-03-18 20:46 ` Pavel Hrdina
2025-03-18 16:36 ` [PATCH 3/3] scripts: render_block_graph: Avoid backtrace on error from virsh Peter Krempa
2 siblings, 1 reply; 5+ messages in thread
From: Peter Krempa @ 2025-03-18 16:36 UTC (permalink / raw)
To: qemu-devel; +Cc: John Snow, Cleber Rosa, qemu-block
From: Peter Krempa <pkrempa@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 <pkrempa@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)
+
+ 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:
+ print("--output required", file=sys.stderr)
+ parser.print_help()
+ sys.exit(1)
render_block_graph(qmp, out)
--
2.48.1
^ permalink raw reply related [flat|nested] 5+ messages in thread
* [PATCH 3/3] scripts: render_block_graph: Avoid backtrace on error from virsh
2025-03-18 16:36 [PATCH 0/3] scripts: render_block_graph: Fix with new python and improve argument parsing Peter Krempa
2025-03-18 16:36 ` [PATCH 1/3] scripts: render_block_graph: Fix invalid escape sequence warning with python 3.12 Peter Krempa
2025-03-18 16:36 ` [PATCH 2/3] scripts: render_block_graph: Implement proper argument parser Peter Krempa
@ 2025-03-18 16:36 ` Peter Krempa
2 siblings, 0 replies; 5+ messages in thread
From: Peter Krempa @ 2025-03-18 16:36 UTC (permalink / raw)
To: qemu-devel; +Cc: John Snow, Cleber Rosa, qemu-block
From: Peter Krempa <pkrempa@redhat.com>
An error from virsh spews also backtrace:
$ ./scripts/render_block_graph.py --vm doesnotexist
error: failed to get domain 'doesnotexist'
Traceback (most recent call last):
File "/home/pipo/git/qemu.git/./scripts/render_block_graph.py", line 152, in <module>
render_block_graph(qmp, out)
~~~~~~~~~~~~~~~~~~^^^^^^^^^^
File "/home/pipo/git/qemu.git/./scripts/render_block_graph.py", line 47, in render_block_graph
[snipped]
instead of just the important bits:
$ ./scripts/render_block_graph.py --vm doesnotexist
error: failed to get domain 'doesnotexist'
Catch the exception and exit. 'virsh' already printed the error.
Signed-off-by: Peter Krempa <pkrempa@redhat.com>
---
scripts/render_block_graph.py | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/scripts/render_block_graph.py b/scripts/render_block_graph.py
index 7a6738410c..e2bb83b60e 100755
--- a/scripts/render_block_graph.py
+++ b/scripts/render_block_graph.py
@@ -106,7 +106,10 @@ def cmd(self, cmd):
ar += ['qemu-monitor-command', self.name, json.dumps(m)]
- reply = json.loads(subprocess.check_output(ar))
+ try:
+ reply = json.loads(subprocess.check_output(ar))
+ except subprocess.CalledProcessError:
+ sys.exit(1)
if 'error' in reply:
raise QMPError(reply)
--
2.48.1
^ permalink raw reply related [flat|nested] 5+ messages in thread
* Re: [PATCH 2/3] scripts: render_block_graph: Implement proper argument parser
2025-03-18 16:36 ` [PATCH 2/3] scripts: render_block_graph: Implement proper argument parser Peter Krempa
@ 2025-03-18 20:46 ` Pavel Hrdina
0 siblings, 0 replies; 5+ messages in thread
From: Pavel Hrdina @ 2025-03-18 20:46 UTC (permalink / raw)
To: Peter Krempa; +Cc: qemu-devel, John Snow, Cleber Rosa, qemu-block
[-- Attachment #1: Type: text/plain, Size: 5055 bytes --]
On Tue, Mar 18, 2025 at 05:36:03PM +0100, Peter Krempa wrote:
> From: Peter Krempa <pkrempa@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 <pkrempa@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 #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]
^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2025-03-18 20:49 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-03-18 16:36 [PATCH 0/3] scripts: render_block_graph: Fix with new python and improve argument parsing Peter Krempa
2025-03-18 16:36 ` [PATCH 1/3] scripts: render_block_graph: Fix invalid escape sequence warning with python 3.12 Peter Krempa
2025-03-18 16:36 ` [PATCH 2/3] scripts: render_block_graph: Implement proper argument parser Peter Krempa
2025-03-18 20:46 ` Pavel Hrdina
2025-03-18 16:36 ` [PATCH 3/3] scripts: render_block_graph: Avoid backtrace on error from virsh Peter Krempa
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).