diff --git a/bindep.txt b/bindep.txt index b9dfdcfb5..841df7fc4 100644 --- a/bindep.txt +++ b/bindep.txt @@ -10,5 +10,5 @@ python-devel [test platform:rpm !platform:fedora !platform:centos-8 !platform:rh python-dev [test platform:dpkg platform:apk !platform:ubuntu-jammy !platform:ubuntu-noble !platform:debian-bookworm] python2-dev [test platform:ubuntu-jammy] -# Required for sphinx testing on Noble for Pillow wheel builds -libjpeg-dev [doc platform:ubuntu-noble] +# Required for sphinx graphviz image generation +graphviz [test doc] diff --git a/doc/requirements.txt b/doc/requirements.txt index 2861efbd2..2b917912c 100644 --- a/doc/requirements.txt +++ b/doc/requirements.txt @@ -1,9 +1,4 @@ zuul-sphinx>=0.1.1 -sphinxcontrib-blockdiag>=1.1.0 -funcparserlib>=1.0.0a0 # https://github.com/blockdiag/blockdiag/pull/148 -sphinxcontrib-seqdiag sphinx_rtd_theme # NOTE(ianw) 2022-10-17 : until we can figure out circular reference errors sphinx<=5.2.3 -# NOTE(lk) sphinxcontrib-blockdiag uses pillow and is not compatible with 10.0.0 -Pillow<10.0 diff --git a/doc/source/conf.py b/doc/source/conf.py index bafe9287c..307a15402 100755 --- a/doc/source/conf.py +++ b/doc/source/conf.py @@ -20,8 +20,7 @@ sys.path.insert(0, os.path.abspath('../..')) # Add any Sphinx extension module names here, as strings. They can be # extensions coming with Sphinx (named 'sphinx.ext.*') or your custom ones. extensions = [ - 'sphinxcontrib.blockdiag', - 'sphinxcontrib.seqdiag', + 'sphinx.ext.graphviz', 'zuul_sphinx', 'sphinx_rtd_theme', ] diff --git a/doc/source/docker-image.rst b/doc/source/docker-image.rst index 058221b1c..f6418ad16 100644 --- a/doc/source/docker-image.rst +++ b/doc/source/docker-image.rst @@ -253,24 +253,87 @@ another. With these concepts in mind, the jobs described above implement the 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: -.. seqdiag:: +.. graphviz:: :caption: Buildset registry image transfer - seqdiag image_transfer { - Ireg [label="Intermediate\nRegistry"]; - Breg [label="Buildset\nRegistry"]; - Bjob [label="Image Build Job"]; - Djob [label="Deployment Test Job"]; + digraph image_transfer { + splines=false + nodesep=1 - Ireg -> Breg [label='Images from previous changes']; - Breg -> Bjob [label='Images from previous changes']; - Breg <- Bjob [label='Current image']; - Ireg <- Breg [noactivate, label='Current image']; - Breg -> Djob [label='Current and previous images']; - Breg <- Djob [style=none]; - Ireg <- Breg [style=none]; + // Set things up like a spreadsheet grid as I found that simplifies + // remembering which nodes have edges between them. + ir_start [label="Intermediate\nRegistry" shape="box"] + ir_end [style=invis] + ir_0 [label="" shape=point height=.005] + ir_1 [label="" shape=point height=.005] + 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\nRegistry" shape="box"] + 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\nBuild Job" shape="box"] + 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\nTest Job" shape="box"] + 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 + br_4 -> tj_4 [weight=0 xlabel="Current and previous images" ] } The intermediate registry is always running and the buildset registry @@ -293,14 +356,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 we need to construct a job graph with dependencies as follows: -.. blockdiag:: +.. graphviz:: - blockdiag dependencies { - obr [label='yoursite-\nbuildset-registry']; - bi [label='build-image']; - ti [label='test-image']; - - obr <- bi <- ti; + digraph dependencies { + rankdir="LR"; + node [shape=box]; + "yoursite-\nbuildset-registry" -> "build-image" [dir=back]; + "build-image" -> "test-image" [dir=back]; } The :ref:`yoursite-buildset-registry` job will run first and @@ -366,19 +428,57 @@ Keeping in mind that everything described above in :ref:`yoursite-upload-docker-image` job, the following illustrates 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 { - DH [activated, label="Docker Hub"]; - Ujob [label="upload-image"]; - Pjob [label="promote-image"]; +.. graphviz:: - DH -> Ujob [style=none]; - DH <- Ujob [label='Current image with temporary tag']; - DH -> Pjob [label='Current image manifest with temporary tag', - note='Only the manifest - is transferred, - not the actual - image layers.']; - DH <- Pjob [label='Current image manifest with final tag']; + digraph image_transfer { + splines=false + nodesep=1 + + // Set things up like a spreadsheet grid as I found that simplifies + // remembering which nodes have edges between them. + dh_start [label="Docker Hub" shape="box"] + 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" shape="box"] + 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" shape="box"] + 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" xlabel="Only the manifest\nis transferred,\nnot the actual\nimage layers"] + 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\nwith Temporary Tag"] + pi_2 -> ui_2 [weight=0 label="Current Image Manifest\nwith Final Tag" arrowhead="none"] + ui_2 -> dh_2 [weight=0] + dh_end -> pi_end [weight=0 style=invis] }