Replace blockdiag and seqdiag with graphviz in docs

blockdiag, seqdiag and their associated sphinx extension are no longer
maintained. This wasn't an issue until the version of Pillow we need for
blockdiag/seqdiag stopped having wheels built for python3.12 and we
moved our default build env to python3.12. The good news is that sphinx
has a built in graphviz extension which should be well maintained that
we can switch to.

To make that switch we do need to install graphviz for the `dot` command
instead of libjpeg-dev since graphviz isn't a native python tool. But
this tradeoff seems reasonable since this software is maintained.

Change-Id: I60ba6235fcfc28508ce10bb60854c0dc62705e0c
This commit is contained in:
Clark Boylan 2024-09-20 11:41:29 -07:00
parent 7bd42d37c4
commit eb8826b605
4 changed files with 138 additions and 41 deletions

View File

@ -1,10 +1,10 @@
# This is a cross-platform list tracking distribution packages needed by tests; # This is a cross-platform list tracking distribution packages needed by tests;
# see http://docs.openstack.org/infra/bindep/ for additional information. # see http://docs.openstack.org/infra/bindep/ for additional information.
graphviz [test doc]
libffi-devel [test platform:rpm] libffi-devel [test platform:rpm]
libffi-dev [test platform:dpkg] libffi-dev [test platform:dpkg]
# For Building Pillow wheels # For Building Pillow wheels
libjpeg-dev [test doc platform:dpkg]
libssl-dev [platform:dpkg] libssl-dev [platform:dpkg]
openssl-devel [platform:rpm] openssl-devel [platform:rpm]
python3-dev [compile test platform:dpkg platform:apk] python3-dev [compile test platform:dpkg platform:apk]

View File

@ -19,8 +19,7 @@
extensions = [ extensions = [
# 'sphinx.ext.autodoc', # 'sphinx.ext.autodoc',
# 'sphinx.ext.intersphinx', # 'sphinx.ext.intersphinx',
'sphinxcontrib.blockdiag', 'sphinx.ext.graphviz',
'sphinxcontrib.seqdiag',
'zuul_sphinx', 'zuul_sphinx',
] ]

View File

@ -26,24 +26,90 @@ another. OpenDev maintains such a registry.
With these concepts in mind, the jobs described below implement the With these concepts in mind, the jobs described below implement the
following workflow for a single change: following workflow for a single change:
..
The below diagram was adapted from the TCP flow example here
https://stackoverflow.com/questions/32436856/using-graphviz-to-create-tcp-flow-diagrams
.. _buildset_image_transfer: .. _buildset_image_transfer:
.. seqdiag:: .. graphviz::
:caption: Buildset registry image transfer :caption: Buildset registry image transfer
seqdiag image_transfer { digraph image_transfer {
Ireg [label="Intermediate\nRegistry"]; splines=false
Breg [label="Buildset\nRegistry"]; nodesep=1
Bjob [label="Image Build Job"];
Djob [label="Deployment Test Job"];
Ireg -> Breg [label='Images from previous changes']; // Set things up like a spreadsheet grid as I found that simplifies
Breg -> Bjob [label='Images from previous changes']; // remembering which nodes have edges between them.
Breg <- Bjob [label='Current image']; ir_start [label="Intermediate Registry"]
Ireg <- Breg [noactivate, label='Current image']; ir_end [style=invis]
Breg -> Djob [label='Current and previous images']; ir_0 [label="" shape=point height=.005]
Breg <- Djob [style=none]; ir_1 [label="" shape=point height=.005]
Ireg <- Breg [style=none]; ir_2 [label="" shape=point height=.005]
ir_3 [label="" shape=point height=.005]
ir_4 [label="" shape=point height=.005]
ir_5 [label="" shape=point height=.005]
ir_start -> ir_0 -> ir_1 -> ir_2 -> ir_3 -> ir_4 -> ir_5 -> ir_end [arrowhead="none" style="bold"]
br_start [label="Buildset Registry"]
br_end [style=invis]
br_0 [label="" shape=point height=.005]
br_1 [label="" shape=point height=.005]
br_2 [label="" shape=point height=.005]
br_3 [label="" shape=point height=.005]
br_4 [label="" shape=point height=.005]
br_5 [label="" shape=point height=.005]
br_start -> br_0 -> br_1 -> br_2 -> br_3 -> br_4 -> br_5 [arrowhead="none" style="bold"]
br_5 -> br_end [arrowhead="none" style="dashed"]
ij_start [label="Image Build Job"]
ij_end [style=invis]
ij_0 [label="" shape=point height=.005]
ij_1 [label="" shape=point height=.005]
ij_2 [label="" shape=point height=.005]
ij_3 [label="" shape=point height=.005]
ij_4 [label="" shape=point height=.005]
ij_5 [label="" shape=point height=.005]
ij_start -> ij_0 -> ij_1 [arrowhead="none" style="dashed"]
ij_1 -> ij_2 [arrowhead="none" style="bold"]
ij_2 -> ij_3 -> ij_4 -> ij_5 -> ij_end [arrowhead="none" style="dashed"]
tj_start [label="Deployment Test Job"]
tj_end [style=invis]
tj_0 [label="" shape=point height=.005]
tj_1 [label="" shape=point height=.005]
tj_2 [label="" shape=point height=.005]
tj_3 [label="" shape=point height=.005]
tj_4 [label="" shape=point height=.005]
tj_5 [label="" shape=point height=.005]
tj_start -> tj_0 -> tj_1 -> tj_2 -> tj_3 -> tj_4 [arrowhead="none" style="dashed"]
tj_4 -> tj_5 [arrowhead="none" style="bold"]
tj_5 -> tj_end [arrowhead="none" style="dashed"]
{rank=same;ir_start;br_start;ij_start;tj_start}
{rank=same;ir_0;br_0;ij_0;tj_0}
{rank=same;ir_1;br_1;ij_1;tj_1}
{rank=same;ir_2;br_2;ij_2;tj_2}
{rank=same;ir_3;br_3;ij_3;tj_3}
{rank=same;ir_4;br_4;ij_4;tj_4}
{rank=same;ir_5;br_5;ij_5;tj_5}
{rank=same;ir_end;br_end;ij_end;tj_end}
// Flows between first and second column
ir_0 -> br_0 [weight=0 label="Images from previous changes"]
br_3 -> ir_3 [weight=0 label="Current image"]
ir_end -> br_end [weight=0 style=invis]
// Flows between second and third column
br_1 -> ij_1 [weight=0 label="Images from previous changes"]
ij_2 -> br_2 [weight=0 label="Current image"]
br_end -> ij_end [weight=0 style=invis]
// Flows between second and fourth column
ij_0 -> tj_0 [style=invis]
ij_4 -> tj_4 [weight=0 label="Current and previous images"]
br_4 -> ij_4 [weight=0 arrowhead="none"]
ij_end -> tj_end [weight=0 style=invis]
} }
The intermediate registry is always running and the buildset registry The intermediate registry is always running and the buildset registry
@ -63,14 +129,13 @@ image build job, and at least one job which uses that image (for
example, by performing a test deployment of the image). In this case example, by performing a test deployment of the image). In this case
we need to construct a job graph with dependencies as follows: we need to construct a job graph with dependencies as follows:
.. blockdiag:: .. graphviz::
blockdiag dependencies { digraph inheritance {
obr [label='opendev-\nbuildset-registry']; rankdir="LR";
bi [label='build-image']; node [shape=box];
ti [label='test-image']; "opendev-buildset-registry" -> "build-image" [dir=back];
"build-image" -> "test-image" [dir=back];
obr <- bi <- ti;
} }
The :zuul:job:`opendev-buildset-registry` job will run first and The :zuul:job:`opendev-buildset-registry` job will run first and
@ -136,21 +201,59 @@ Keeping in mind that everything described above in
:zuul:job:`opendev-upload-docker-image` job, the following illustrates :zuul:job:`opendev-upload-docker-image` job, the following illustrates
the additional tasks performed by the "upload" and "promote" jobs: the additional tasks performed by the "upload" and "promote" jobs:
.. seqdiag:: ..
The below diagram was adapted from the TCP flow example here
https://stackoverflow.com/questions/32436856/using-graphviz-to-create-tcp-flow-diagrams
seqdiag image_transfer { .. graphviz::
DH [activated, label="Docker Hub"];
Ujob [label="upload-image"];
Pjob [label="promote-image"];
DH -> Ujob [style=none]; digraph image_transfer {
DH <- Ujob [label='Current image with temporary tag']; splines=false
DH -> Pjob [label='Current image manifest with temporary tag', nodesep=1
note='Only the manifest
is transferred, // Set things up like a spreadsheet grid as I found that simplifies
not the actual // remembering which nodes have edges between them.
image layers.']; dh_start [label="Docker Hub"]
DH <- Pjob [label='Current image manifest with final tag']; dh_end [style=invis]
dh_0 [label="" shape=point height=.005]
dh_1 [label="" shape=point height=.005]
dh_2 [label="" shape=point height=.005]
dh_start -> dh_0 -> dh_1 -> dh_2 -> dh_end [arrowhead="none" style="bold"]
ui_start [label="upload-image"]
ui_end [style=invis]
ui_0 [label="" shape=point height=.005]
ui_1 [label="" shape=point height=.005]
ui_2 [label="" shape=point height=.005]
ui_start -> ui_0 [arrowhead="none" style="bold"]
ui_0 -> ui_1 -> ui_2 -> ui_end [arrowhead="none" style="dashed"]
pi_start [label="promote-image"]
pi_end [style=invis]
pi_0 [label="" shape=point height=.005]
pi_1 [label="" shape=point height=.005]
pi_2 [label="" shape=point height=.005]
pi_start -> pi_0 -> pi_1 [arrowhead="none" style="dashed"]
pi_1 -> pi_2 [arrowhead="none" style="bold"]
pi_2 -> pi_end [arrowhead="none" style="dashed"]
{rank=same;dh_start;ui_start;pi_start}
{rank=same;dh_0;ui_0;pi_0}
{rank=same;dh_1;ui_1;pi_1}
{rank=same;dh_2;ui_2;pi_2}
{rank=same;dh_end;ui_end;pi_end}
// Flows between first and second column
ui_0 -> dh_0 [weight=0 label="Current Image with Temporary Tag"]
dh_end -> ui_end [weight=0 style=invis]
// Flows between first and third column
dh_1 -> ui_1 [weight=0 arrowhead="none"]
ui_1 -> pi_1 [weight=0 label="Current Image Manifest with Temporary Tag"]
pi_1 [xlabel="Only the manifest is transferred,\nnot the actual image layers"]
pi_2 -> ui_2 [weight=0 label="Current Image Manifest with Final Tag" arrowhead="none"]
ui_2 -> dh_2 [weight=0 label=""]
dh_end -> pi_end [weight=0 style=invis]
} }
Jobs Jobs

View File

@ -14,8 +14,3 @@ ansible-lint<25.0.0
bashate>=0.2 bashate>=0.2
zuul-sphinx>=0.1.1 zuul-sphinx>=0.1.1
stestr>=1.0.0 # Apache-2.0 stestr>=1.0.0 # Apache-2.0
sphinxcontrib-blockdiag>=1.1.0
sphinxcontrib-seqdiag
# Latest blockdiag (3.0.0) relies on functions deprecated in Pillow 10.x
# https://github.com/blockdiag/blockdiag/pull/171
Pillow<10