On 11/6/2026 12:36 PM, Alex Bennée wrote:
> Pierrick Bouvier <[email protected]> writes:
> 
>> On 11/6/2026 4:21 AM, Alex Bennée wrote:
>>> We've had various versions of this diagram for a while so I thought it
>>> would be worth adding to the developer docs. I chose plantuml as it
>>> has a plugin for sphinx that we can use and supports sequence diagrams
>>> which could be useful for documenting other features in the code base.
>>>
>>> Signed-off-by: Alex Bennée <[email protected]>
>>>
>>> ---
>>> vRFC
>>>   - I've bundled all the plumbing together in this commit but it can
>>>   be split up if we want to go forward.
>>> ---
>>>  docs/conf.py                    | 22 +++++++++++++++
>>>  docs/devel/index-process.rst    | 47 +++++++++++++++++++++++++++++++++
>>>  docs/meson.build                |  3 ++-
>>>  docs/requirements.txt           |  1 +
>>>  configure                       |  6 +++++
>>>  pythondeps.toml                 |  1 +
>>>  tests/lcitool/mappings.yml      |  3 +++
>>>  tests/lcitool/projects/qemu.yml |  1 +
>>>  8 files changed, 83 insertions(+), 1 deletion(-)
>>>
>>> diff --git a/docs/conf.py b/docs/conf.py
>>> index 914bae67d9c..9fc7be362ba 100644
>>> --- a/docs/conf.py
>>> +++ b/docs/conf.py
>>> @@ -66,8 +66,11 @@
>>>      'qapi_domain',
>>>      'qapidoc',
>>>      'qmp_lexer',
>>> +    'sphinxcontrib.plantuml',
>>>  ]
>>>  
>>> +plantuml_output_format = 'svg'
>>> +
>>>  # Add any paths that contain templates here, relative to this directory.
>>>  templates_path = [os.path.join(qemu_docdir, '_templates')]
>>>  
>>> @@ -345,3 +348,22 @@
>>>  qapidoc_srctree = os.path.join(qemu_docdir, '..')
>>>  dbusdoc_srctree = os.path.join(qemu_docdir, '..')
>>>  dbus_index_common_prefix = ["org.qemu."]
>>> +
>>> +
>>> +def setup(app):
>>> +    import docutils.nodes
>>> +    import sphinxcontrib.plantuml
>>> +
>>> +    # We manually setup the plantuml extension so we can skip nodes with
>>> +    # diagrams when generating the text based output.
>>> +
>>> +    def skip_node(self, node):
>>> +        raise docutils.nodes.SkipNode
>>> +
>>> +    app.setup_extension('sphinxcontrib.plantuml')
>>> +    app.add_node(
>>> +        sphinxcontrib.plantuml.plantuml,
>>> +        override=True,
>>> +        man=(skip_node, None),
>>> +        text=(skip_node, None),
>>> +    )
>>> diff --git a/docs/devel/index-process.rst b/docs/devel/index-process.rst
>>> index ce0f4e73197..1c13dd3f7b5 100644
>>> --- a/docs/devel/index-process.rst
>>> +++ b/docs/devel/index-process.rst
>>> @@ -5,6 +5,53 @@ QEMU Community Processes
>>>  
>>>  Notes about how to interact with the community and how and where to submit 
>>> patches.
>>>  
>>> +.. uml::
>>> +   :caption: QEMU Patch Review and Acceptance Flow
>>> +
>>> +   @startuml
>>> +   skinparam roundCorner 8
>>> +   skinparam shadowing false
>>> +   skinparam defaultFontName monospace
>>> +   skinparam sequenceMessageAlign center
>>> +
>>> +   actor "Developer" as dev
>>> +   participant "QEMU Community\n(qemu-devel)" as list
>>> +   actor "Subsystem\nMaintainer" as sub
>>> +   actor "QEMU\nMaintainer" as top
>>> +
>>> +   dev -> dev: Develop & test feature
>>> +
>>> +   loop Needs revision (v1, v2, ... vn)
>>> +       dev -> list: Post patch series to list
>>> +       note over list: Code review on list
>>> +
>>> +       opt Review comments
>>> +           list -> dev: Feedback & change requests
>>> +           dev -> dev: Incorporate feedback
>>> +       end
>>> +       opt Review tags
>>> +           list -> dev: Tags (Reviewed-by, Acked-by, ...)
>>> +           dev -> dev: Apply tags
>>> +       end
>>> +
>>> +       dev -> dev: Prepare n+1
>>> +   end
>>> +
>>> +   group Patch acceptance & release
>>> +       list -> sub: Maintainer accepts some or all patches
>>> +       note over sub: Incorporates patches\nfrom other developers
>>> +       sub -> sub: Add Maintainer Sign-off
>>> +       sub -> sub: GIT branch foo/next
>>> +       sub -> list: Sign & Submit Pull Request
>>> +       list -> top: Pull Request delivered to list
>>> +       note over top: Pull Requests from\nother maintainers
>>> +       top -> top: Test and Merge Pull Reqs
>>> +       top -> top: qemu.git master
>>> +       top -> top: Tag Release
>>> +       top -> list: QEMU Release
>>> +   end
>>> +   @enduml
>>> +
>>>  .. toctree::
>>>     :maxdepth: 2
>>>  
>>> diff --git a/docs/meson.build b/docs/meson.build
>>> index 4d8cc545fcc..600d3283299 100644
>>> --- a/docs/meson.build
>>> +++ b/docs/meson.build
>>> @@ -1,9 +1,10 @@
>>>  sphinx_build = find_program(fs.parent(python.full_path()) / 'sphinx-build',
>>>                              required: get_option('docs'))
>>> +plantuml = find_program('plantuml', required: get_option('docs'))
>>>  
>>>  # Check if tools are available to build documentation.
>>>  build_docs = false
>>> -if sphinx_build.found()
>>> +if sphinx_build.found() and plantuml.found()
>>>    SPHINX_ARGS = ['env', 'CONFDIR=' + qemu_confdir, sphinx_build, '-q']
>>>    # If we're making warnings fatal, apply this to Sphinx runs as well
>>>    if get_option('werror')
>>> diff --git a/docs/requirements.txt b/docs/requirements.txt
>>> index 509d56bd1e8..1cafcbaa38f 100644
>>> --- a/docs/requirements.txt
>>> +++ b/docs/requirements.txt
>>> @@ -3,3 +3,4 @@
>>>  
>>>  sphinx==7.2.6
>>>  sphinx_rtd_theme==2.0.0
>>> +sphinxcontrib-plantuml==0.30
>>> diff --git a/configure b/configure
>>> index 42dffed28f0..b0dedde65dd 100755
>>> --- a/configure
>>> +++ b/configure
>>> @@ -1020,6 +1020,12 @@ if test "$docs" != "disabled" ; then
>>>          fi
>>>          echo "Sphinx not found/usable, disabling docs."
>>>          docs=disabled
>>> +    elif ! has plantuml; then
>>> +        if test "$docs" = "enabled" ; then
>>> +            error_exit "plantuml not found"
>>> +        fi
>>> +        echo "plantuml not found, disabling docs."
>>> +        docs=disabled
>>>      else
>>>          docs=enabled
>>>      fi
>>> diff --git a/pythondeps.toml b/pythondeps.toml
>>> index c9a697046c6..c21d127ec93 100644
>>> --- a/pythondeps.toml
>>> +++ b/pythondeps.toml
>>> @@ -30,6 +30,7 @@ meson = { accepted = ">=1.12.0", installed = "1.12.0", 
>>> canary = "meson" }
>>>  # Please keep the installed versions in sync with docs/requirements.txt
>>>  sphinx = { accepted = ">=7.2.6", installed = "7.2.6", canary = 
>>> "sphinx-build" }
>>>  sphinx_rtd_theme = { accepted = ">=1.2.2", installed = "2.0.0" }
>>> +sphinxcontrib-plantuml = { accepted = ">=0.5", installed = "0.30" }
>>>  
>>>  # This test group is for dependencies required to run various tooling
>>>  # and tests that should always be installed at configure time. It should
>>> diff --git a/tests/lcitool/mappings.yml b/tests/lcitool/mappings.yml
>>> index c99f007798e..eca6748ac09 100644
>>> --- a/tests/lcitool/mappings.yml
>>> +++ b/tests/lcitool/mappings.yml
>>> @@ -3,6 +3,9 @@ mappings:
>>>    bindgen:
>>>      Ubuntu2204:
>>>  
>>> +  plantuml:
>>> +    default: plantuml
>>> +
>>>    python3:
>>>      CentOSStream9: python3.12
>>>  
>>> diff --git a/tests/lcitool/projects/qemu.yml 
>>> b/tests/lcitool/projects/qemu.yml
>>> index abbd3e3f0b8..de4395cd3c7 100644
>>> --- a/tests/lcitool/projects/qemu.yml
>>> +++ b/tests/lcitool/projects/qemu.yml
>>> @@ -89,6 +89,7 @@ packages:
>>>   - pcre-static
>>>   - pixman
>>>   - pkg-config
>>> + - plantuml
>>>   - pulseaudio
>>>   - python3
>>>   - python3-numpy
>>
>> It will silently disable doc by default for most of the people
>> unfortunately, not sure it's the best move we can do.
> 
> plantuml seems to be pretty widely packaged so in this sense its just
> another dependency.
> 
>> Maybe a simpler solution could be to generate diagrams out of sphinx,
>> add them as a dependency, and generate a blank image (or an image with
>> diagram source and a message - please install plantuml) if not
>> available. What does plantuml brings compares to graphviz builtin
>> extension?
> 
> Ohh I didn't realize there was graphviz - I'll see if I can recreate
> with that.
>

If graphviz is not installed, a warning is emitted, which stops the
build since we turn warnings into error.

The warning emitted has no type, so it can't be filtered with
suppress_warning setting from sphinx-build.

However, since sphinx uses standard logging framework, you can silence
it this way: https://github.com/sphinx-doc/sphinx/issues/10219

```
--- a/docs/conf.py
+++ b/docs/conf.py
@@ -24,6 +24,7 @@
+import logging
 import os
 import sys
 import sphinx
@@ -66,8 +67,20 @@
     'qapi_domain',
     'qapidoc',
     'qmp_lexer',
+    'sphinx.ext.graphviz',
 ]

+# Render graphviz diagrams as SVG so they scale cleanly in HTML output.
+graphviz_output_format = 'svg'
+
+# Silence the warning emitted by sphinx.ext.graphviz when 'dot' is not
+# installed. Diagrams are then rendered as their raw source instead.
+class _NoDotWarning(logging.Filter):
+    def filter(self, record):
+        return 'cannot be run (needed for graphviz output)' not in
record.getMessage()
+
+logging.getLogger('sphinx.sphinx.ext.graphviz').addFilter(_NoDotWarning())
```

The advantage is that graphviz is not a required dependency, so doc is
still built for anyone having sphinx installed. That's a nice end result
I think.

>> Also, text diagrams (https://asciidraw.github.io/) with raw formatting
>> have the advantage to not require any external tool.
> 
> I have the ascii original although ditaa seemed more of a stretch:
> 
> --8<---------------cut here---------------start------------->8---
> #+name: QEMU Development Process
> #+begin_src ditaa :cmdline -T -o :file images/qemu-dev-process.png
>            Developer                                   QEMU Community         
>                   Subsystem Maintainer
>   +-=--------------------------+   
> +-=---------------------------------------------------+   
> +-=----------------------+
>   |                            |   |                                          
>            |   |                        |
>   |    +-------------------+   |   |  
> +-----------------------------------------------+  |   |   +----------------+ 
>   |
>   |    |{io}               |   |   |  |{io}                                   
>         |  |   |   |{io}            |   |
>   |    |  Develop and      |   | +--->|              Code Review on List      
>         |  | +---->| Add Maintainer |   |
>   |    |   Test feature    |   | | |  |                                       
>         |  | | |   |    Sign-off    |   |
>   |    |                   |   | | |  
> +------+----------------+----------------+------+  | | |   |                | 
>   |
>   |    +--------+----------+   | | |         |                |               
>  |         | | |   +-------+--------+   |
>   |             |              | | |         V                V               
>  V         | | |           |            |
>   |             V              | | :  +-------------+  +-------------+  
> +-------------+  | | |           v            |
>   |    +-------------------+   | | |  |{d}          |  |{d}          |  |{io} 
>         |  | | |   +----------------+   |
>   |    |{io}               |   | | |  |  Review     |  |  Review     |  | 
> Maintainer  |  | | |   |{s}             |   |
>   | +->|  Post to List     +-----+ |  |    Comments |  |    Tags     |  |  
> accepts    |  | | |   |   GIT Branch   |   |
>   | |  |                   |   |   |  |             |  |             |  | 
> some or all |  | | |   |    foo/next    |   |
>   | |  +-------------------+   |   |  |             |  |             |  |  
> patches    |  | | |   |                |   |
>   | |                          :   |  +------+------+  +------+------+  
> +------+------+  | | :   |                |   |
>   | |  +-------------------+   |   |         |                |               
>  |         | | |   |                |   |
>   | |  |{io}               |<----------------+                |               
>  +-----------+ |   |                |   |
>   | |  |    Incorporate    |                                  |               
>            |   |   |                |   |
>   | |  |     Feedback      |<---------------------------------+               
>            |   |   |                |   |
>   | |  +--------+----------+   |   |                                          
>            :   |   +-------+--------+   |
>   | |           |              :   
> +-----------------------------------------------------+   |           |       
>      |
>   | |           v              |                                              
>                |           V            |
>   | |  +-------------------+   |                       QEMU Maintainer        
>                |   +----------------+   |
>   | |  |{io}               |   |  
> +-=-----------------------------------------------------+  |   |{io}          
>   |   |
>   | |  |    Prepare n+1    |   |  | +-------------+  +--------------+  
> +----------------+ |  |   |  Sign & Submit |   |
>   | |  |                   |   |  | |{io}         |  |{s}           |  |{io}  
>           | |  |   |      Pull      |   |
>   | |  +--------+----------+   |  | | Tag Release |<-+   qemu.git   |<-+ Test 
> and Merge |<-------+     Request    |   |
>   | |           |              |  | |             |  |    master    |  |    
> Pull Reqs   |<-+ |   |                |   |
>   | +-----------+              |  | |             |  |              |  |      
>           | || |   +----------------+   |
>   |                            |  | +------+------+  +--------------+  
> +----------------+ || |                        |
>   +----------------------------+  
> +--------+----------------------------------------------+| 
> +------------------------+
>                                            +----------------+                 
>              |
>                                                             |                 
>              |
>                                                             V                 
>              |       Pull Requests
>                                                      +--------------+         
>              +----       from
>                                                      |{d}           |         
>                    Other Maintainers
>                                                      |     QEMU     |
>                                                      |    Release   |
>                                                      |              |
>                                                      |              |
>                                                      +--------------+
> 
> #+end_src
> --8<---------------cut here---------------end--------------->8---
>

Nice diagram!
Better in picture indeed.

> 
>>
>> What do you think?
>>
>> Regards,
>> Pierrick
> 


Reply via email to