diff --git a/doc/Makefile b/doc/Makefile index 4a9592d165337467663c8564507d30b15d9e6c5d..d79bcfd1337a2143cfef24f0aa7b9096be2ae4e3 100644 --- a/doc/Makefile +++ b/doc/Makefile @@ -20,10 +20,10 @@ rapport.md: rapport.gpp.md logbook.gpp.md markdown.gpp gitlab-markdown.gpp csv2b $(GPP) -DGITLAB_MARKDOWN $< | ./trimstart.py > $@ rapport.tex: rapport.gpp.md diagrams markdown.gpp pandoc-pdf-markdown.gpp logbook.gpp.md csv2barchart.py templates/default.latex $(PLANTUML_DIAGRAMS_SVG) $(PLANTUML_DIAGRAMS_PNG) - $(GPP) -DPANDOC_PDF $< | ./trimstart.py | pandoc --standalone --pdf-engine=xelatex --template=templates/default.latex -o $@ + $(GPP) -DPANDOC_PDF $< | ./trimstart.py | pandoc --filter=pandoc-citeproc --standalone --pdf-engine=xelatex --template=templates/default.latex -o $@ rapport.pdf: rapport.gpp.md markdown.gpp pandoc-pdf-markdown.gpp logbook.gpp.md csv2barchart.py templates/default.latex abstract.pdf statement.pdf $(PLANTUML_DIAGRAMS_SVG) $(PLANTUML_DIAGRAMS_PNG) - $(GPP) -DPANDOC_PDF $< | ./trimstart.py | pandoc --pdf-engine=xelatex --template=templates/default.latex -o $@ + $(GPP) -DPANDOC_PDF $< | ./trimstart.py | pandoc --filter=pandoc-citeproc --pdf-engine=xelatex --template=templates/default.latex -o $@ diagrams: $(PLANTUML_DIAGRAMS_SVG) $(PLANTUML_DIAGRAMS_PNG) diff --git a/doc/charts/chart_deploy_time_debian.png b/doc/charts/chart_deploy_time_debian.png index c4081ae3a6c844425bf728256649f20b266961b2..5226182d0c30499dd0277b76b90ce0e9d17b2953 100644 --- a/doc/charts/chart_deploy_time_debian.png +++ b/doc/charts/chart_deploy_time_debian.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:9a0bb3b1af44613e5674989b57e19b91f0bfcc3bcfb32cfc7647dbb60ce88a39 -size 18644 +oid sha256:45cfc1486e1a2ce929d279e728e26a08d00a29696cf6373894247253b72729aa +size 18578 diff --git a/doc/charts/chart_deploy_time_debian.svg b/doc/charts/chart_deploy_time_debian.svg index 1aaaff343712f9251357cfb1865cdc2f18851e93..0393b336468f7416b8b35f2222f3f345066dcc3c 100644 --- a/doc/charts/chart_deploy_time_debian.svg +++ b/doc/charts/chart_deploy_time_debian.svg @@ -3,10 +3,22 @@ "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"> <!-- Created with matplotlib (https://matplotlib.org/) --> <svg height="345.6pt" version="1.1" viewBox="0 0 460.8 345.6" width="460.8pt" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> + <metadata> + <rdf:RDF xmlns:cc="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"> + <cc:Work> + <dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage"/> + <dc:date>2020-08-16T19:18:09.724445</dc:date> + <dc:format>image/svg+xml</dc:format> + <dc:creator> + <cc:Agent> + <dc:title>Matplotlib v3.3.0, https://matplotlib.org/</dc:title> + </cc:Agent> + </dc:creator> + </cc:Work> + </rdf:RDF> + </metadata> <defs> - <style type="text/css"> -*{stroke-linecap:butt;stroke-linejoin:round;} - </style> + <style type="text/css">*{stroke-linecap:butt;stroke-linejoin:round;}</style> </defs> <g id="figure_1"> <g id="patch_1"> @@ -72,8 +84,9 @@ L 0 3.5 </g> <g id="text_1"> <!-- Gzip --> - <defs> - <path d="M 59.515625 10.40625 + <g transform="translate(96.945171 308.358437)scale(0.1 -0.1)"> + <defs> + <path d="M 59.515625 10.40625 L 59.515625 29.984375 L 43.40625 29.984375 L 43.40625 38.09375 @@ -98,7 +111,7 @@ Q 48.046875 6.6875 52.140625 7.59375 Q 56.25 8.5 59.515625 10.40625 z " id="DejaVuSans-71"/> - <path d="M 5.515625 54.6875 + <path d="M 5.515625 54.6875 L 48.1875 54.6875 L 48.1875 46.484375 L 14.40625 7.171875 @@ -110,7 +123,7 @@ L 38.09375 47.515625 L 5.515625 47.515625 z " id="DejaVuSans-122"/> - <path d="M 9.421875 54.6875 + <path d="M 9.421875 54.6875 L 18.40625 54.6875 L 18.40625 0 L 9.421875 0 @@ -121,7 +134,7 @@ L 18.40625 64.59375 L 9.421875 64.59375 z " id="DejaVuSans-105"/> - <path d="M 18.109375 8.203125 + <path d="M 18.109375 8.203125 L 18.109375 -20.796875 L 9.078125 -20.796875 L 9.078125 54.6875 @@ -147,16 +160,16 @@ Q 40.53125 6.109375 44.609375 11.75 Q 48.6875 17.390625 48.6875 27.296875 z " id="DejaVuSans-112"/> - </defs> - <g transform="translate(96.945171 308.358437)scale(0.1 -0.1)"> + </defs> <use xlink:href="#DejaVuSans-71"/> <use x="77.490234" xlink:href="#DejaVuSans-122"/> <use x="129.980469" xlink:href="#DejaVuSans-105"/> <use x="157.763672" xlink:href="#DejaVuSans-112"/> </g> <!-- (sans cache) --> - <defs> - <path d="M 31 75.875 + <g transform="translate(76.266265 319.55625)scale(0.1 -0.1)"> + <defs> + <path d="M 31 75.875 Q 24.46875 64.65625 21.28125 53.65625 Q 18.109375 42.671875 18.109375 31.390625 Q 18.109375 20.125 21.3125 9.0625 @@ -168,7 +181,7 @@ Q 8.59375 42.28125 12.203125 53.3125 Q 15.828125 64.359375 23.1875 75.875 z " id="DejaVuSans-40"/> - <path d="M 44.28125 53.078125 + <path d="M 44.28125 53.078125 L 44.28125 44.578125 Q 40.484375 46.53125 36.375 47.5 Q 32.28125 48.484375 27.875 48.484375 @@ -199,7 +212,7 @@ Q 31.78125 56 36.171875 55.265625 Q 40.578125 54.546875 44.28125 53.078125 z " id="DejaVuSans-115"/> - <path d="M 34.28125 27.484375 + <path d="M 34.28125 27.484375 Q 23.390625 27.484375 19.1875 25 Q 14.984375 22.515625 14.984375 16.5 Q 14.984375 11.71875 18.140625 8.90625 @@ -231,7 +244,7 @@ Q 40.484375 56 46.34375 49.84375 Q 52.203125 43.703125 52.203125 31.203125 z " id="DejaVuSans-97"/> - <path d="M 54.890625 33.015625 + <path d="M 54.890625 33.015625 L 54.890625 0 L 45.90625 0 L 45.90625 32.71875 @@ -250,8 +263,8 @@ Q 45.21875 56 50.046875 50.171875 Q 54.890625 44.34375 54.890625 33.015625 z " id="DejaVuSans-110"/> - <path id="DejaVuSans-32"/> - <path d="M 48.78125 52.59375 + <path id="DejaVuSans-32"/> + <path d="M 48.78125 52.59375 L 48.78125 44.1875 Q 44.96875 46.296875 41.140625 47.34375 Q 37.3125 48.390625 33.40625 48.390625 @@ -272,7 +285,7 @@ Q 37.15625 56 41.109375 55.140625 Q 45.0625 54.296875 48.78125 52.59375 z " id="DejaVuSans-99"/> - <path d="M 54.890625 33.015625 + <path d="M 54.890625 33.015625 L 54.890625 0 L 45.90625 0 L 45.90625 32.71875 @@ -291,7 +304,7 @@ Q 45.21875 56 50.046875 50.171875 Q 54.890625 44.34375 54.890625 33.015625 z " id="DejaVuSans-104"/> - <path d="M 56.203125 29.59375 + <path d="M 56.203125 29.59375 L 56.203125 25.203125 L 14.890625 25.203125 Q 15.484375 15.921875 20.484375 11.0625 @@ -315,7 +328,7 @@ Q 24.90625 48.390625 20.390625 44.140625 Q 15.875 39.890625 15.1875 32.171875 z " id="DejaVuSans-101"/> - <path d="M 8.015625 75.875 + <path d="M 8.015625 75.875 L 15.828125 75.875 Q 23.140625 64.359375 26.78125 53.3125 Q 30.421875 42.28125 30.421875 31.390625 @@ -328,8 +341,7 @@ Q 20.90625 42.671875 17.703125 53.65625 Q 14.5 64.65625 8.015625 75.875 z " id="DejaVuSans-41"/> - </defs> - <g transform="translate(76.266265 319.55625)scale(0.1 -0.1)"> + </defs> <use xlink:href="#DejaVuSans-40"/> <use x="39.013672" xlink:href="#DejaVuSans-115"/> <use x="91.113281" xlink:href="#DejaVuSans-97"/> @@ -360,8 +372,9 @@ z <use x="157.763672" xlink:href="#DejaVuSans-112"/> </g> <!-- (avec cache) --> - <defs> - <path d="M 2.984375 54.6875 + <g transform="translate(161.29464 319.55625)scale(0.1 -0.1)"> + <defs> + <path d="M 2.984375 54.6875 L 12.5 54.6875 L 29.59375 8.796875 L 46.6875 54.6875 @@ -370,8 +383,7 @@ L 35.6875 0 L 23.484375 0 z " id="DejaVuSans-118"/> - </defs> - <g transform="translate(161.29464 319.55625)scale(0.1 -0.1)"> + </defs> <use xlink:href="#DejaVuSans-40"/> <use x="39.013672" xlink:href="#DejaVuSans-97"/> <use x="100.292969" xlink:href="#DejaVuSans-118"/> @@ -395,8 +407,9 @@ z </g> <g id="text_3"> <!-- Clonezilla --> - <defs> - <path d="M 64.40625 67.28125 + <g transform="translate(254.837078 308.358437)scale(0.1 -0.1)"> + <defs> + <path d="M 64.40625 67.28125 L 64.40625 56.890625 Q 59.421875 61.53125 53.78125 63.8125 Q 48.140625 66.109375 41.796875 66.109375 @@ -417,13 +430,13 @@ Q 47.75 74.21875 53.53125 72.484375 Q 59.328125 70.75 64.40625 67.28125 z " id="DejaVuSans-67"/> - <path d="M 9.421875 75.984375 + <path d="M 9.421875 75.984375 L 18.40625 75.984375 L 18.40625 0 L 9.421875 0 z " id="DejaVuSans-108"/> - <path d="M 30.609375 48.390625 + <path d="M 30.609375 48.390625 Q 23.390625 48.390625 19.1875 42.75 Q 14.984375 37.109375 14.984375 27.296875 Q 14.984375 17.484375 19.15625 11.84375 @@ -444,8 +457,7 @@ Q 5.515625 40.765625 12.171875 48.375 Q 18.84375 56 30.609375 56 z " id="DejaVuSans-111"/> - </defs> - <g transform="translate(254.837078 308.358437)scale(0.1 -0.1)"> + </defs> <use xlink:href="#DejaVuSans-67"/> <use x="69.824219" xlink:href="#DejaVuSans-108"/> <use x="97.607422" xlink:href="#DejaVuSans-111"/> @@ -513,8 +525,9 @@ z </g> <g id="text_5"> <!-- Type --> - <defs> - <path d="M -0.296875 72.90625 + <g transform="translate(224.677188 333.234375)scale(0.1 -0.1)"> + <defs> + <path d="M -0.296875 72.90625 L 61.375 72.90625 L 61.375 64.59375 L 35.5 64.59375 @@ -524,7 +537,7 @@ L 25.59375 64.59375 L -0.296875 64.59375 z " id="DejaVuSans-84"/> - <path d="M 32.171875 -5.078125 + <path d="M 32.171875 -5.078125 Q 28.375 -14.84375 24.75 -17.8125 Q 21.140625 -20.796875 15.09375 -20.796875 L 7.90625 -20.796875 @@ -540,8 +553,7 @@ L 46.6875 54.6875 L 56.203125 54.6875 z " id="DejaVuSans-121"/> - </defs> - <g transform="translate(224.677188 333.234375)scale(0.1 -0.1)"> + </defs> <use xlink:href="#DejaVuSans-84"/> <use x="45.458984" xlink:href="#DejaVuSans-121"/> <use x="104.638672" xlink:href="#DejaVuSans-112"/> @@ -563,8 +575,9 @@ L -3.5 0 </g> <g id="text_6"> <!-- 0 --> - <defs> - <path d="M 31.78125 66.40625 + <g transform="translate(44.2375 297.559219)scale(0.1 -0.1)"> + <defs> + <path d="M 31.78125 66.40625 Q 24.171875 66.40625 20.328125 58.90625 Q 16.5 51.421875 16.5 36.375 Q 16.5 21.390625 20.328125 13.890625 @@ -585,8 +598,7 @@ Q 6.59375 54.828125 13.0625 64.515625 Q 19.53125 74.21875 31.78125 74.21875 z " id="DejaVuSans-48"/> - </defs> - <g transform="translate(44.2375 297.559219)scale(0.1 -0.1)"> + </defs> <use xlink:href="#DejaVuSans-48"/> </g> </g> @@ -599,8 +611,9 @@ z </g> <g id="text_7"> <!-- 5 --> - <defs> - <path d="M 10.796875 72.90625 + <g transform="translate(44.2375 266.754823)scale(0.1 -0.1)"> + <defs> + <path d="M 10.796875 72.90625 L 49.515625 72.90625 L 49.515625 64.59375 L 19.828125 64.59375 @@ -624,8 +637,7 @@ Q 22.75 39.890625 18.8125 39.015625 Q 14.890625 38.140625 10.796875 36.28125 z " id="DejaVuSans-53"/> - </defs> - <g transform="translate(44.2375 266.754823)scale(0.1 -0.1)"> + </defs> <use xlink:href="#DejaVuSans-53"/> </g> </g> @@ -638,8 +650,9 @@ z </g> <g id="text_8"> <!-- 10 --> - <defs> - <path d="M 12.40625 8.296875 + <g transform="translate(37.875 235.950428)scale(0.1 -0.1)"> + <defs> + <path d="M 12.40625 8.296875 L 28.515625 8.296875 L 28.515625 63.921875 L 10.984375 60.40625 @@ -652,8 +665,7 @@ L 54.390625 0 L 12.40625 0 z " id="DejaVuSans-49"/> - </defs> - <g transform="translate(37.875 235.950428)scale(0.1 -0.1)"> + </defs> <use xlink:href="#DejaVuSans-49"/> <use x="63.623047" xlink:href="#DejaVuSans-48"/> </g> @@ -681,8 +693,9 @@ z </g> <g id="text_10"> <!-- 20 --> - <defs> - <path d="M 19.1875 8.296875 + <g transform="translate(37.875 174.341636)scale(0.1 -0.1)"> + <defs> + <path d="M 19.1875 8.296875 L 53.609375 8.296875 L 53.609375 0 L 7.328125 0 @@ -706,8 +719,7 @@ Q 44.1875 33.984375 37.640625 27.21875 Q 31.109375 20.453125 19.1875 8.296875 z " id="DejaVuSans-50"/> - </defs> - <g transform="translate(37.875 174.341636)scale(0.1 -0.1)"> + </defs> <use xlink:href="#DejaVuSans-50"/> <use x="63.623047" xlink:href="#DejaVuSans-48"/> </g> @@ -735,8 +747,9 @@ z </g> <g id="text_12"> <!-- 30 --> - <defs> - <path d="M 40.578125 39.3125 + <g transform="translate(37.875 112.732845)scale(0.1 -0.1)"> + <defs> + <path d="M 40.578125 39.3125 Q 47.65625 37.796875 51.625 33 Q 55.609375 28.21875 55.609375 21.1875 Q 55.609375 10.40625 48.1875 4.484375 @@ -768,8 +781,7 @@ Q 53.90625 49.265625 50.4375 45.09375 Q 46.96875 40.921875 40.578125 39.3125 z " id="DejaVuSans-51"/> - </defs> - <g transform="translate(37.875 112.732845)scale(0.1 -0.1)"> + </defs> <use xlink:href="#DejaVuSans-51"/> <use x="63.623047" xlink:href="#DejaVuSans-48"/> </g> @@ -797,8 +809,9 @@ z </g> <g id="text_14"> <!-- 40 --> - <defs> - <path d="M 37.796875 64.3125 + <g transform="translate(37.875 51.124054)scale(0.1 -0.1)"> + <defs> + <path d="M 37.796875 64.3125 L 12.890625 25.390625 L 37.796875 25.390625 z @@ -815,8 +828,7 @@ L 4.890625 17.1875 L 4.890625 26.703125 z " id="DejaVuSans-52"/> - </defs> - <g transform="translate(37.875 51.124054)scale(0.1 -0.1)"> + </defs> <use xlink:href="#DejaVuSans-52"/> <use x="63.623047" xlink:href="#DejaVuSans-48"/> </g> @@ -824,8 +836,9 @@ z </g> <g id="text_15"> <!-- Temps de déploiement (secondes) --> - <defs> - <path d="M 52 44.1875 + <g transform="translate(31.795312 253.394125)rotate(-90)scale(0.1 -0.1)"> + <defs> + <path d="M 52 44.1875 Q 55.375 50.25 60.0625 53.125 Q 64.75 56 71.09375 56 Q 79.640625 56 84.28125 50.015625 @@ -855,7 +868,7 @@ Q 41.65625 56 45.828125 52.96875 Q 50 49.953125 52 44.1875 z " id="DejaVuSans-109"/> - <path d="M 45.40625 46.390625 + <path d="M 45.40625 46.390625 L 45.40625 75.984375 L 54.390625 75.984375 L 54.390625 0 @@ -881,7 +894,7 @@ Q 22.953125 48.484375 18.875 42.84375 Q 14.796875 37.203125 14.796875 27.296875 z " id="DejaVuSans-100"/> - <path d="M 56.203125 29.59375 + <path d="M 56.203125 29.59375 L 56.203125 25.203125 L 14.890625 25.203125 Q 15.484375 15.921875 20.484375 11.0625 @@ -910,7 +923,7 @@ L 32.375 61.625 L 24.90625 61.625 z " id="DejaVuSans-233"/> - <path d="M 18.3125 70.21875 + <path d="M 18.3125 70.21875 L 18.3125 54.6875 L 36.8125 54.6875 L 36.8125 47.703125 @@ -930,8 +943,7 @@ L 9.28125 54.6875 L 9.28125 70.21875 z " id="DejaVuSans-116"/> - </defs> - <g transform="translate(31.795312 253.394125)rotate(-90)scale(0.1 -0.1)"> + </defs> <use xlink:href="#DejaVuSans-84"/> <use x="44.083984" xlink:href="#DejaVuSans-101"/> <use x="105.607422" xlink:href="#DejaVuSans-109"/> diff --git a/doc/charts/chart_deploy_time_win10.png b/doc/charts/chart_deploy_time_win10.png index ee8a4bfff1cce07cfc96377d1f5f1bcc815bd4d9..9ffbe7210ebe6e62abee869f64b4e57db7352a17 100644 --- a/doc/charts/chart_deploy_time_win10.png +++ b/doc/charts/chart_deploy_time_win10.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:ccdd7f2f8a9352cc44a5d2d1d8fa6312b882072dbddeeafd8ddaabaf069c251f -size 19588 +oid sha256:ececbb3c526023b31d619469bef208357e4b9328d7191ace787f138945793566 +size 19594 diff --git a/doc/charts/chart_deploy_time_win10.svg b/doc/charts/chart_deploy_time_win10.svg index 3c64f1f776f54ffbf2c71150c23807deb5fe1d41..08df1320643661d45efee65c7d0cd24bd86da8d4 100644 --- a/doc/charts/chart_deploy_time_win10.svg +++ b/doc/charts/chart_deploy_time_win10.svg @@ -3,10 +3,22 @@ "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"> <!-- Created with matplotlib (https://matplotlib.org/) --> <svg height="345.6pt" version="1.1" viewBox="0 0 460.8 345.6" width="460.8pt" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> + <metadata> + <rdf:RDF xmlns:cc="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"> + <cc:Work> + <dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage"/> + <dc:date>2020-08-16T19:18:10.751033</dc:date> + <dc:format>image/svg+xml</dc:format> + <dc:creator> + <cc:Agent> + <dc:title>Matplotlib v3.3.0, https://matplotlib.org/</dc:title> + </cc:Agent> + </dc:creator> + </cc:Work> + </rdf:RDF> + </metadata> <defs> - <style type="text/css"> -*{stroke-linecap:butt;stroke-linejoin:round;} - </style> + <style type="text/css">*{stroke-linecap:butt;stroke-linejoin:round;}</style> </defs> <g id="figure_1"> <g id="patch_1"> @@ -56,8 +68,9 @@ L 0 3.5 </g> <g id="text_1"> <!-- Gzip --> - <defs> - <path d="M 59.515625 10.40625 + <g transform="translate(134.916463 308.358437)scale(0.1 -0.1)"> + <defs> + <path d="M 59.515625 10.40625 L 59.515625 29.984375 L 43.40625 29.984375 L 43.40625 38.09375 @@ -82,7 +95,7 @@ Q 48.046875 6.6875 52.140625 7.59375 Q 56.25 8.5 59.515625 10.40625 z " id="DejaVuSans-71"/> - <path d="M 5.515625 54.6875 + <path d="M 5.515625 54.6875 L 48.1875 54.6875 L 48.1875 46.484375 L 14.40625 7.171875 @@ -94,7 +107,7 @@ L 38.09375 47.515625 L 5.515625 47.515625 z " id="DejaVuSans-122"/> - <path d="M 9.421875 54.6875 + <path d="M 9.421875 54.6875 L 18.40625 54.6875 L 18.40625 0 L 9.421875 0 @@ -105,7 +118,7 @@ L 18.40625 64.59375 L 9.421875 64.59375 z " id="DejaVuSans-105"/> - <path d="M 18.109375 8.203125 + <path d="M 18.109375 8.203125 L 18.109375 -20.796875 L 9.078125 -20.796875 L 9.078125 54.6875 @@ -131,16 +144,16 @@ Q 40.53125 6.109375 44.609375 11.75 Q 48.6875 17.390625 48.6875 27.296875 z " id="DejaVuSans-112"/> - </defs> - <g transform="translate(134.916463 308.358437)scale(0.1 -0.1)"> + </defs> <use xlink:href="#DejaVuSans-71"/> <use x="77.490234" xlink:href="#DejaVuSans-122"/> <use x="129.980469" xlink:href="#DejaVuSans-105"/> <use x="157.763672" xlink:href="#DejaVuSans-112"/> </g> <!-- (sans cache) --> - <defs> - <path d="M 31 75.875 + <g transform="translate(114.237557 319.55625)scale(0.1 -0.1)"> + <defs> + <path d="M 31 75.875 Q 24.46875 64.65625 21.28125 53.65625 Q 18.109375 42.671875 18.109375 31.390625 Q 18.109375 20.125 21.3125 9.0625 @@ -152,7 +165,7 @@ Q 8.59375 42.28125 12.203125 53.3125 Q 15.828125 64.359375 23.1875 75.875 z " id="DejaVuSans-40"/> - <path d="M 44.28125 53.078125 + <path d="M 44.28125 53.078125 L 44.28125 44.578125 Q 40.484375 46.53125 36.375 47.5 Q 32.28125 48.484375 27.875 48.484375 @@ -183,7 +196,7 @@ Q 31.78125 56 36.171875 55.265625 Q 40.578125 54.546875 44.28125 53.078125 z " id="DejaVuSans-115"/> - <path d="M 34.28125 27.484375 + <path d="M 34.28125 27.484375 Q 23.390625 27.484375 19.1875 25 Q 14.984375 22.515625 14.984375 16.5 Q 14.984375 11.71875 18.140625 8.90625 @@ -215,7 +228,7 @@ Q 40.484375 56 46.34375 49.84375 Q 52.203125 43.703125 52.203125 31.203125 z " id="DejaVuSans-97"/> - <path d="M 54.890625 33.015625 + <path d="M 54.890625 33.015625 L 54.890625 0 L 45.90625 0 L 45.90625 32.71875 @@ -234,8 +247,8 @@ Q 45.21875 56 50.046875 50.171875 Q 54.890625 44.34375 54.890625 33.015625 z " id="DejaVuSans-110"/> - <path id="DejaVuSans-32"/> - <path d="M 48.78125 52.59375 + <path id="DejaVuSans-32"/> + <path d="M 48.78125 52.59375 L 48.78125 44.1875 Q 44.96875 46.296875 41.140625 47.34375 Q 37.3125 48.390625 33.40625 48.390625 @@ -256,7 +269,7 @@ Q 37.15625 56 41.109375 55.140625 Q 45.0625 54.296875 48.78125 52.59375 z " id="DejaVuSans-99"/> - <path d="M 54.890625 33.015625 + <path d="M 54.890625 33.015625 L 54.890625 0 L 45.90625 0 L 45.90625 32.71875 @@ -275,7 +288,7 @@ Q 45.21875 56 50.046875 50.171875 Q 54.890625 44.34375 54.890625 33.015625 z " id="DejaVuSans-104"/> - <path d="M 56.203125 29.59375 + <path d="M 56.203125 29.59375 L 56.203125 25.203125 L 14.890625 25.203125 Q 15.484375 15.921875 20.484375 11.0625 @@ -299,7 +312,7 @@ Q 24.90625 48.390625 20.390625 44.140625 Q 15.875 39.890625 15.1875 32.171875 z " id="DejaVuSans-101"/> - <path d="M 8.015625 75.875 + <path d="M 8.015625 75.875 L 15.828125 75.875 Q 23.140625 64.359375 26.78125 53.3125 Q 30.421875 42.28125 30.421875 31.390625 @@ -312,8 +325,7 @@ Q 20.90625 42.671875 17.703125 53.65625 Q 14.5 64.65625 8.015625 75.875 z " id="DejaVuSans-41"/> - </defs> - <g transform="translate(114.237557 319.55625)scale(0.1 -0.1)"> + </defs> <use xlink:href="#DejaVuSans-40"/> <use x="39.013672" xlink:href="#DejaVuSans-115"/> <use x="91.113281" xlink:href="#DejaVuSans-97"/> @@ -337,8 +349,9 @@ z </g> <g id="text_2"> <!-- Clonezilla --> - <defs> - <path d="M 64.40625 67.28125 + <g transform="translate(302.301193 308.358437)scale(0.1 -0.1)"> + <defs> + <path d="M 64.40625 67.28125 L 64.40625 56.890625 Q 59.421875 61.53125 53.78125 63.8125 Q 48.140625 66.109375 41.796875 66.109375 @@ -359,13 +372,13 @@ Q 47.75 74.21875 53.53125 72.484375 Q 59.328125 70.75 64.40625 67.28125 z " id="DejaVuSans-67"/> - <path d="M 9.421875 75.984375 + <path d="M 9.421875 75.984375 L 18.40625 75.984375 L 18.40625 0 L 9.421875 0 z " id="DejaVuSans-108"/> - <path d="M 30.609375 48.390625 + <path d="M 30.609375 48.390625 Q 23.390625 48.390625 19.1875 42.75 Q 14.984375 37.109375 14.984375 27.296875 Q 14.984375 17.484375 19.15625 11.84375 @@ -386,8 +399,7 @@ Q 5.515625 40.765625 12.171875 48.375 Q 18.84375 56 30.609375 56 z " id="DejaVuSans-111"/> - </defs> - <g transform="translate(302.301193 308.358437)scale(0.1 -0.1)"> + </defs> <use xlink:href="#DejaVuSans-67"/> <use x="69.824219" xlink:href="#DejaVuSans-108"/> <use x="97.607422" xlink:href="#DejaVuSans-111"/> @@ -418,8 +430,9 @@ z </g> <g id="text_3"> <!-- Type --> - <defs> - <path d="M -0.296875 72.90625 + <g transform="translate(224.677188 333.234375)scale(0.1 -0.1)"> + <defs> + <path d="M -0.296875 72.90625 L 61.375 72.90625 L 61.375 64.59375 L 35.5 64.59375 @@ -429,7 +442,7 @@ L 25.59375 64.59375 L -0.296875 64.59375 z " id="DejaVuSans-84"/> - <path d="M 32.171875 -5.078125 + <path d="M 32.171875 -5.078125 Q 28.375 -14.84375 24.75 -17.8125 Q 21.140625 -20.796875 15.09375 -20.796875 L 7.90625 -20.796875 @@ -445,8 +458,7 @@ L 46.6875 54.6875 L 56.203125 54.6875 z " id="DejaVuSans-121"/> - </defs> - <g transform="translate(224.677188 333.234375)scale(0.1 -0.1)"> + </defs> <use xlink:href="#DejaVuSans-84"/> <use x="45.458984" xlink:href="#DejaVuSans-121"/> <use x="104.638672" xlink:href="#DejaVuSans-112"/> @@ -468,8 +480,9 @@ L -3.5 0 </g> <g id="text_4"> <!-- 0 --> - <defs> - <path d="M 31.78125 66.40625 + <g transform="translate(44.2375 297.559219)scale(0.1 -0.1)"> + <defs> + <path d="M 31.78125 66.40625 Q 24.171875 66.40625 20.328125 58.90625 Q 16.5 51.421875 16.5 36.375 Q 16.5 21.390625 20.328125 13.890625 @@ -490,8 +503,7 @@ Q 6.59375 54.828125 13.0625 64.515625 Q 19.53125 74.21875 31.78125 74.21875 z " id="DejaVuSans-48"/> - </defs> - <g transform="translate(44.2375 297.559219)scale(0.1 -0.1)"> + </defs> <use xlink:href="#DejaVuSans-48"/> </g> </g> @@ -504,8 +516,9 @@ z </g> <g id="text_5"> <!-- 500 --> - <defs> - <path d="M 10.796875 72.90625 + <g transform="translate(31.5125 262.56442)scale(0.1 -0.1)"> + <defs> + <path d="M 10.796875 72.90625 L 49.515625 72.90625 L 49.515625 64.59375 L 19.828125 64.59375 @@ -529,8 +542,7 @@ Q 22.75 39.890625 18.8125 39.015625 Q 14.890625 38.140625 10.796875 36.28125 z " id="DejaVuSans-53"/> - </defs> - <g transform="translate(31.5125 262.56442)scale(0.1 -0.1)"> + </defs> <use xlink:href="#DejaVuSans-53"/> <use x="63.623047" xlink:href="#DejaVuSans-48"/> <use x="127.246094" xlink:href="#DejaVuSans-48"/> @@ -545,8 +557,9 @@ z </g> <g id="text_6"> <!-- 1000 --> - <defs> - <path d="M 12.40625 8.296875 + <g transform="translate(25.15 227.569622)scale(0.1 -0.1)"> + <defs> + <path d="M 12.40625 8.296875 L 28.515625 8.296875 L 28.515625 63.921875 L 10.984375 60.40625 @@ -559,8 +572,7 @@ L 54.390625 0 L 12.40625 0 z " id="DejaVuSans-49"/> - </defs> - <g transform="translate(25.15 227.569622)scale(0.1 -0.1)"> + </defs> <use xlink:href="#DejaVuSans-49"/> <use x="63.623047" xlink:href="#DejaVuSans-48"/> <use x="127.246094" xlink:href="#DejaVuSans-48"/> @@ -592,8 +604,9 @@ z </g> <g id="text_8"> <!-- 2000 --> - <defs> - <path d="M 19.1875 8.296875 + <g transform="translate(25.15 157.580025)scale(0.1 -0.1)"> + <defs> + <path d="M 19.1875 8.296875 L 53.609375 8.296875 L 53.609375 0 L 7.328125 0 @@ -617,8 +630,7 @@ Q 44.1875 33.984375 37.640625 27.21875 Q 31.109375 20.453125 19.1875 8.296875 z " id="DejaVuSans-50"/> - </defs> - <g transform="translate(25.15 157.580025)scale(0.1 -0.1)"> + </defs> <use xlink:href="#DejaVuSans-50"/> <use x="63.623047" xlink:href="#DejaVuSans-48"/> <use x="127.246094" xlink:href="#DejaVuSans-48"/> @@ -650,8 +662,9 @@ z </g> <g id="text_10"> <!-- 3000 --> - <defs> - <path d="M 40.578125 39.3125 + <g transform="translate(25.15 87.590428)scale(0.1 -0.1)"> + <defs> + <path d="M 40.578125 39.3125 Q 47.65625 37.796875 51.625 33 Q 55.609375 28.21875 55.609375 21.1875 Q 55.609375 10.40625 48.1875 4.484375 @@ -683,8 +696,7 @@ Q 53.90625 49.265625 50.4375 45.09375 Q 46.96875 40.921875 40.578125 39.3125 z " id="DejaVuSans-51"/> - </defs> - <g transform="translate(25.15 87.590428)scale(0.1 -0.1)"> + </defs> <use xlink:href="#DejaVuSans-51"/> <use x="63.623047" xlink:href="#DejaVuSans-48"/> <use x="127.246094" xlink:href="#DejaVuSans-48"/> @@ -710,8 +722,9 @@ z </g> <g id="text_12"> <!-- Temps de déploiement (secondes) --> - <defs> - <path d="M 52 44.1875 + <g transform="translate(19.070312 253.394125)rotate(-90)scale(0.1 -0.1)"> + <defs> + <path d="M 52 44.1875 Q 55.375 50.25 60.0625 53.125 Q 64.75 56 71.09375 56 Q 79.640625 56 84.28125 50.015625 @@ -741,7 +754,7 @@ Q 41.65625 56 45.828125 52.96875 Q 50 49.953125 52 44.1875 z " id="DejaVuSans-109"/> - <path d="M 45.40625 46.390625 + <path d="M 45.40625 46.390625 L 45.40625 75.984375 L 54.390625 75.984375 L 54.390625 0 @@ -767,7 +780,7 @@ Q 22.953125 48.484375 18.875 42.84375 Q 14.796875 37.203125 14.796875 27.296875 z " id="DejaVuSans-100"/> - <path d="M 56.203125 29.59375 + <path d="M 56.203125 29.59375 L 56.203125 25.203125 L 14.890625 25.203125 Q 15.484375 15.921875 20.484375 11.0625 @@ -796,7 +809,7 @@ L 32.375 61.625 L 24.90625 61.625 z " id="DejaVuSans-233"/> - <path d="M 18.3125 70.21875 + <path d="M 18.3125 70.21875 L 18.3125 54.6875 L 36.8125 54.6875 L 36.8125 47.703125 @@ -816,8 +829,7 @@ L 9.28125 54.6875 L 9.28125 70.21875 z " id="DejaVuSans-116"/> - </defs> - <g transform="translate(19.070312 253.394125)rotate(-90)scale(0.1 -0.1)"> + </defs> <use xlink:href="#DejaVuSans-84"/> <use x="44.083984" xlink:href="#DejaVuSans-101"/> <use x="105.607422" xlink:href="#DejaVuSans-109"/> diff --git a/doc/charts/chart_deploy_time_xubuntu.png b/doc/charts/chart_deploy_time_xubuntu.png index 4d1fbeb0488edc8e9cb19c601fe18420830ec27f..b0502c25f4442bd4c0211dc51d6d298fdedc2e2c 100644 --- a/doc/charts/chart_deploy_time_xubuntu.png +++ b/doc/charts/chart_deploy_time_xubuntu.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:1f360c0e3544b5c6f67f9088263b6ce7f2c2261a4c4c46d288772646f9a37c81 -size 19288 +oid sha256:730faa3b5d5b5c1a31a1f9455154f66e7ebedff0b912f66255fa16222edbfa5a +size 19266 diff --git a/doc/charts/chart_deploy_time_xubuntu.svg b/doc/charts/chart_deploy_time_xubuntu.svg index b2746b124196dbc938670eea8312695d41c0f8fa..e46174394ed60267f8172defbda27b7d5b921608 100644 --- a/doc/charts/chart_deploy_time_xubuntu.svg +++ b/doc/charts/chart_deploy_time_xubuntu.svg @@ -3,10 +3,22 @@ "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"> <!-- Created with matplotlib (https://matplotlib.org/) --> <svg height="345.6pt" version="1.1" viewBox="0 0 460.8 345.6" width="460.8pt" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> + <metadata> + <rdf:RDF xmlns:cc="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"> + <cc:Work> + <dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage"/> + <dc:date>2020-08-16T19:18:10.244037</dc:date> + <dc:format>image/svg+xml</dc:format> + <dc:creator> + <cc:Agent> + <dc:title>Matplotlib v3.3.0, https://matplotlib.org/</dc:title> + </cc:Agent> + </dc:creator> + </cc:Work> + </rdf:RDF> + </metadata> <defs> - <style type="text/css"> -*{stroke-linecap:butt;stroke-linejoin:round;} - </style> + <style type="text/css">*{stroke-linecap:butt;stroke-linejoin:round;}</style> </defs> <g id="figure_1"> <g id="patch_1"> @@ -72,8 +84,9 @@ L 0 3.5 </g> <g id="text_1"> <!-- Gzip --> - <defs> - <path d="M 59.515625 10.40625 + <g transform="translate(96.945171 308.358437)scale(0.1 -0.1)"> + <defs> + <path d="M 59.515625 10.40625 L 59.515625 29.984375 L 43.40625 29.984375 L 43.40625 38.09375 @@ -98,7 +111,7 @@ Q 48.046875 6.6875 52.140625 7.59375 Q 56.25 8.5 59.515625 10.40625 z " id="DejaVuSans-71"/> - <path d="M 5.515625 54.6875 + <path d="M 5.515625 54.6875 L 48.1875 54.6875 L 48.1875 46.484375 L 14.40625 7.171875 @@ -110,7 +123,7 @@ L 38.09375 47.515625 L 5.515625 47.515625 z " id="DejaVuSans-122"/> - <path d="M 9.421875 54.6875 + <path d="M 9.421875 54.6875 L 18.40625 54.6875 L 18.40625 0 L 9.421875 0 @@ -121,7 +134,7 @@ L 18.40625 64.59375 L 9.421875 64.59375 z " id="DejaVuSans-105"/> - <path d="M 18.109375 8.203125 + <path d="M 18.109375 8.203125 L 18.109375 -20.796875 L 9.078125 -20.796875 L 9.078125 54.6875 @@ -147,16 +160,16 @@ Q 40.53125 6.109375 44.609375 11.75 Q 48.6875 17.390625 48.6875 27.296875 z " id="DejaVuSans-112"/> - </defs> - <g transform="translate(96.945171 308.358437)scale(0.1 -0.1)"> + </defs> <use xlink:href="#DejaVuSans-71"/> <use x="77.490234" xlink:href="#DejaVuSans-122"/> <use x="129.980469" xlink:href="#DejaVuSans-105"/> <use x="157.763672" xlink:href="#DejaVuSans-112"/> </g> <!-- (sans cache) --> - <defs> - <path d="M 31 75.875 + <g transform="translate(76.266265 319.55625)scale(0.1 -0.1)"> + <defs> + <path d="M 31 75.875 Q 24.46875 64.65625 21.28125 53.65625 Q 18.109375 42.671875 18.109375 31.390625 Q 18.109375 20.125 21.3125 9.0625 @@ -168,7 +181,7 @@ Q 8.59375 42.28125 12.203125 53.3125 Q 15.828125 64.359375 23.1875 75.875 z " id="DejaVuSans-40"/> - <path d="M 44.28125 53.078125 + <path d="M 44.28125 53.078125 L 44.28125 44.578125 Q 40.484375 46.53125 36.375 47.5 Q 32.28125 48.484375 27.875 48.484375 @@ -199,7 +212,7 @@ Q 31.78125 56 36.171875 55.265625 Q 40.578125 54.546875 44.28125 53.078125 z " id="DejaVuSans-115"/> - <path d="M 34.28125 27.484375 + <path d="M 34.28125 27.484375 Q 23.390625 27.484375 19.1875 25 Q 14.984375 22.515625 14.984375 16.5 Q 14.984375 11.71875 18.140625 8.90625 @@ -231,7 +244,7 @@ Q 40.484375 56 46.34375 49.84375 Q 52.203125 43.703125 52.203125 31.203125 z " id="DejaVuSans-97"/> - <path d="M 54.890625 33.015625 + <path d="M 54.890625 33.015625 L 54.890625 0 L 45.90625 0 L 45.90625 32.71875 @@ -250,8 +263,8 @@ Q 45.21875 56 50.046875 50.171875 Q 54.890625 44.34375 54.890625 33.015625 z " id="DejaVuSans-110"/> - <path id="DejaVuSans-32"/> - <path d="M 48.78125 52.59375 + <path id="DejaVuSans-32"/> + <path d="M 48.78125 52.59375 L 48.78125 44.1875 Q 44.96875 46.296875 41.140625 47.34375 Q 37.3125 48.390625 33.40625 48.390625 @@ -272,7 +285,7 @@ Q 37.15625 56 41.109375 55.140625 Q 45.0625 54.296875 48.78125 52.59375 z " id="DejaVuSans-99"/> - <path d="M 54.890625 33.015625 + <path d="M 54.890625 33.015625 L 54.890625 0 L 45.90625 0 L 45.90625 32.71875 @@ -291,7 +304,7 @@ Q 45.21875 56 50.046875 50.171875 Q 54.890625 44.34375 54.890625 33.015625 z " id="DejaVuSans-104"/> - <path d="M 56.203125 29.59375 + <path d="M 56.203125 29.59375 L 56.203125 25.203125 L 14.890625 25.203125 Q 15.484375 15.921875 20.484375 11.0625 @@ -315,7 +328,7 @@ Q 24.90625 48.390625 20.390625 44.140625 Q 15.875 39.890625 15.1875 32.171875 z " id="DejaVuSans-101"/> - <path d="M 8.015625 75.875 + <path d="M 8.015625 75.875 L 15.828125 75.875 Q 23.140625 64.359375 26.78125 53.3125 Q 30.421875 42.28125 30.421875 31.390625 @@ -328,8 +341,7 @@ Q 20.90625 42.671875 17.703125 53.65625 Q 14.5 64.65625 8.015625 75.875 z " id="DejaVuSans-41"/> - </defs> - <g transform="translate(76.266265 319.55625)scale(0.1 -0.1)"> + </defs> <use xlink:href="#DejaVuSans-40"/> <use x="39.013672" xlink:href="#DejaVuSans-115"/> <use x="91.113281" xlink:href="#DejaVuSans-97"/> @@ -360,8 +372,9 @@ z <use x="157.763672" xlink:href="#DejaVuSans-112"/> </g> <!-- (avec cache) --> - <defs> - <path d="M 2.984375 54.6875 + <g transform="translate(161.29464 319.55625)scale(0.1 -0.1)"> + <defs> + <path d="M 2.984375 54.6875 L 12.5 54.6875 L 29.59375 8.796875 L 46.6875 54.6875 @@ -370,8 +383,7 @@ L 35.6875 0 L 23.484375 0 z " id="DejaVuSans-118"/> - </defs> - <g transform="translate(161.29464 319.55625)scale(0.1 -0.1)"> + </defs> <use xlink:href="#DejaVuSans-40"/> <use x="39.013672" xlink:href="#DejaVuSans-97"/> <use x="100.292969" xlink:href="#DejaVuSans-118"/> @@ -395,8 +407,9 @@ z </g> <g id="text_3"> <!-- Clonezilla --> - <defs> - <path d="M 64.40625 67.28125 + <g transform="translate(254.837078 308.358437)scale(0.1 -0.1)"> + <defs> + <path d="M 64.40625 67.28125 L 64.40625 56.890625 Q 59.421875 61.53125 53.78125 63.8125 Q 48.140625 66.109375 41.796875 66.109375 @@ -417,13 +430,13 @@ Q 47.75 74.21875 53.53125 72.484375 Q 59.328125 70.75 64.40625 67.28125 z " id="DejaVuSans-67"/> - <path d="M 9.421875 75.984375 + <path d="M 9.421875 75.984375 L 18.40625 75.984375 L 18.40625 0 L 9.421875 0 z " id="DejaVuSans-108"/> - <path d="M 30.609375 48.390625 + <path d="M 30.609375 48.390625 Q 23.390625 48.390625 19.1875 42.75 Q 14.984375 37.109375 14.984375 27.296875 Q 14.984375 17.484375 19.15625 11.84375 @@ -444,8 +457,7 @@ Q 5.515625 40.765625 12.171875 48.375 Q 18.84375 56 30.609375 56 z " id="DejaVuSans-111"/> - </defs> - <g transform="translate(254.837078 308.358437)scale(0.1 -0.1)"> + </defs> <use xlink:href="#DejaVuSans-67"/> <use x="69.824219" xlink:href="#DejaVuSans-108"/> <use x="97.607422" xlink:href="#DejaVuSans-111"/> @@ -513,8 +525,9 @@ z </g> <g id="text_5"> <!-- Type --> - <defs> - <path d="M -0.296875 72.90625 + <g transform="translate(224.677188 333.234375)scale(0.1 -0.1)"> + <defs> + <path d="M -0.296875 72.90625 L 61.375 72.90625 L 61.375 64.59375 L 35.5 64.59375 @@ -524,7 +537,7 @@ L 25.59375 64.59375 L -0.296875 64.59375 z " id="DejaVuSans-84"/> - <path d="M 32.171875 -5.078125 + <path d="M 32.171875 -5.078125 Q 28.375 -14.84375 24.75 -17.8125 Q 21.140625 -20.796875 15.09375 -20.796875 L 7.90625 -20.796875 @@ -540,8 +553,7 @@ L 46.6875 54.6875 L 56.203125 54.6875 z " id="DejaVuSans-121"/> - </defs> - <g transform="translate(224.677188 333.234375)scale(0.1 -0.1)"> + </defs> <use xlink:href="#DejaVuSans-84"/> <use x="45.458984" xlink:href="#DejaVuSans-121"/> <use x="104.638672" xlink:href="#DejaVuSans-112"/> @@ -563,8 +575,9 @@ L -3.5 0 </g> <g id="text_6"> <!-- 0 --> - <defs> - <path d="M 31.78125 66.40625 + <g transform="translate(44.2375 297.559219)scale(0.1 -0.1)"> + <defs> + <path d="M 31.78125 66.40625 Q 24.171875 66.40625 20.328125 58.90625 Q 16.5 51.421875 16.5 36.375 Q 16.5 21.390625 20.328125 13.890625 @@ -585,8 +598,7 @@ Q 6.59375 54.828125 13.0625 64.515625 Q 19.53125 74.21875 31.78125 74.21875 z " id="DejaVuSans-48"/> - </defs> - <g transform="translate(44.2375 297.559219)scale(0.1 -0.1)"> + </defs> <use xlink:href="#DejaVuSans-48"/> </g> </g> @@ -599,8 +611,9 @@ z </g> <g id="text_7"> <!-- 100 --> - <defs> - <path d="M 12.40625 8.296875 + <g transform="translate(31.5125 259.420443)scale(0.1 -0.1)"> + <defs> + <path d="M 12.40625 8.296875 L 28.515625 8.296875 L 28.515625 63.921875 L 10.984375 60.40625 @@ -613,8 +626,7 @@ L 54.390625 0 L 12.40625 0 z " id="DejaVuSans-49"/> - </defs> - <g transform="translate(31.5125 259.420443)scale(0.1 -0.1)"> + </defs> <use xlink:href="#DejaVuSans-49"/> <use x="63.623047" xlink:href="#DejaVuSans-48"/> <use x="127.246094" xlink:href="#DejaVuSans-48"/> @@ -629,8 +641,9 @@ z </g> <g id="text_8"> <!-- 200 --> - <defs> - <path d="M 19.1875 8.296875 + <g transform="translate(31.5125 221.281668)scale(0.1 -0.1)"> + <defs> + <path d="M 19.1875 8.296875 L 53.609375 8.296875 L 53.609375 0 L 7.328125 0 @@ -654,8 +667,7 @@ Q 44.1875 33.984375 37.640625 27.21875 Q 31.109375 20.453125 19.1875 8.296875 z " id="DejaVuSans-50"/> - </defs> - <g transform="translate(31.5125 221.281668)scale(0.1 -0.1)"> + </defs> <use xlink:href="#DejaVuSans-50"/> <use x="63.623047" xlink:href="#DejaVuSans-48"/> <use x="127.246094" xlink:href="#DejaVuSans-48"/> @@ -670,8 +682,9 @@ z </g> <g id="text_9"> <!-- 300 --> - <defs> - <path d="M 40.578125 39.3125 + <g transform="translate(31.5125 183.142892)scale(0.1 -0.1)"> + <defs> + <path d="M 40.578125 39.3125 Q 47.65625 37.796875 51.625 33 Q 55.609375 28.21875 55.609375 21.1875 Q 55.609375 10.40625 48.1875 4.484375 @@ -703,8 +716,7 @@ Q 53.90625 49.265625 50.4375 45.09375 Q 46.96875 40.921875 40.578125 39.3125 z " id="DejaVuSans-51"/> - </defs> - <g transform="translate(31.5125 183.142892)scale(0.1 -0.1)"> + </defs> <use xlink:href="#DejaVuSans-51"/> <use x="63.623047" xlink:href="#DejaVuSans-48"/> <use x="127.246094" xlink:href="#DejaVuSans-48"/> @@ -719,8 +731,9 @@ z </g> <g id="text_10"> <!-- 400 --> - <defs> - <path d="M 37.796875 64.3125 + <g transform="translate(31.5125 145.004117)scale(0.1 -0.1)"> + <defs> + <path d="M 37.796875 64.3125 L 12.890625 25.390625 L 37.796875 25.390625 z @@ -737,8 +750,7 @@ L 4.890625 17.1875 L 4.890625 26.703125 z " id="DejaVuSans-52"/> - </defs> - <g transform="translate(31.5125 145.004117)scale(0.1 -0.1)"> + </defs> <use xlink:href="#DejaVuSans-52"/> <use x="63.623047" xlink:href="#DejaVuSans-48"/> <use x="127.246094" xlink:href="#DejaVuSans-48"/> @@ -753,8 +765,9 @@ z </g> <g id="text_11"> <!-- 500 --> - <defs> - <path d="M 10.796875 72.90625 + <g transform="translate(31.5125 106.865341)scale(0.1 -0.1)"> + <defs> + <path d="M 10.796875 72.90625 L 49.515625 72.90625 L 49.515625 64.59375 L 19.828125 64.59375 @@ -778,8 +791,7 @@ Q 22.75 39.890625 18.8125 39.015625 Q 14.890625 38.140625 10.796875 36.28125 z " id="DejaVuSans-53"/> - </defs> - <g transform="translate(31.5125 106.865341)scale(0.1 -0.1)"> + </defs> <use xlink:href="#DejaVuSans-53"/> <use x="63.623047" xlink:href="#DejaVuSans-48"/> <use x="127.246094" xlink:href="#DejaVuSans-48"/> @@ -794,8 +806,9 @@ z </g> <g id="text_12"> <!-- 600 --> - <defs> - <path d="M 33.015625 40.375 + <g transform="translate(31.5125 68.726566)scale(0.1 -0.1)"> + <defs> + <path d="M 33.015625 40.375 Q 26.375 40.375 22.484375 35.828125 Q 18.609375 31.296875 18.609375 23.390625 Q 18.609375 15.53125 22.484375 10.953125 @@ -825,8 +838,7 @@ Q 40.921875 74.21875 44.703125 73.484375 Q 48.484375 72.75 52.59375 71.296875 z " id="DejaVuSans-54"/> - </defs> - <g transform="translate(31.5125 68.726566)scale(0.1 -0.1)"> + </defs> <use xlink:href="#DejaVuSans-54"/> <use x="63.623047" xlink:href="#DejaVuSans-48"/> <use x="127.246094" xlink:href="#DejaVuSans-48"/> @@ -835,8 +847,9 @@ z </g> <g id="text_13"> <!-- Temps de déploiement (secondes) --> - <defs> - <path d="M 52 44.1875 + <g transform="translate(25.432812 253.394125)rotate(-90)scale(0.1 -0.1)"> + <defs> + <path d="M 52 44.1875 Q 55.375 50.25 60.0625 53.125 Q 64.75 56 71.09375 56 Q 79.640625 56 84.28125 50.015625 @@ -866,7 +879,7 @@ Q 41.65625 56 45.828125 52.96875 Q 50 49.953125 52 44.1875 z " id="DejaVuSans-109"/> - <path d="M 45.40625 46.390625 + <path d="M 45.40625 46.390625 L 45.40625 75.984375 L 54.390625 75.984375 L 54.390625 0 @@ -892,7 +905,7 @@ Q 22.953125 48.484375 18.875 42.84375 Q 14.796875 37.203125 14.796875 27.296875 z " id="DejaVuSans-100"/> - <path d="M 56.203125 29.59375 + <path d="M 56.203125 29.59375 L 56.203125 25.203125 L 14.890625 25.203125 Q 15.484375 15.921875 20.484375 11.0625 @@ -921,7 +934,7 @@ L 32.375 61.625 L 24.90625 61.625 z " id="DejaVuSans-233"/> - <path d="M 18.3125 70.21875 + <path d="M 18.3125 70.21875 L 18.3125 54.6875 L 36.8125 54.6875 L 36.8125 47.703125 @@ -941,8 +954,7 @@ L 9.28125 54.6875 L 9.28125 70.21875 z " id="DejaVuSans-116"/> - </defs> - <g transform="translate(25.432812 253.394125)rotate(-90)scale(0.1 -0.1)"> + </defs> <use xlink:href="#DejaVuSans-84"/> <use x="44.083984" xlink:href="#DejaVuSans-101"/> <use x="105.607422" xlink:href="#DejaVuSans-109"/> diff --git a/doc/charts/chart_image_sizes_debian.png b/doc/charts/chart_image_sizes_debian.png index 33e7fa83cdaee91ed85f43db518e94ccd8d8adfd..7eb8eba5be7a8d0879cd96682621ea8a046356eb 100644 --- a/doc/charts/chart_image_sizes_debian.png +++ b/doc/charts/chart_image_sizes_debian.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:70cac82311df35270ca7e3df975b44c89250c29a2e92f16d5017f0c6d8c9ae4c -size 12262 +oid sha256:1c83eab1894f44baf8d346a345a9e98da1d2385f7b92abcc3bf363adc7416a24 +size 12235 diff --git a/doc/charts/chart_image_sizes_debian.svg b/doc/charts/chart_image_sizes_debian.svg index 601d6def8ff526c65589cc9d6db9dbac24748bb5..9d5b6677119f1b17b0f73d75fd283647e6411e21 100644 --- a/doc/charts/chart_image_sizes_debian.svg +++ b/doc/charts/chart_image_sizes_debian.svg @@ -3,10 +3,22 @@ "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"> <!-- Created with matplotlib (https://matplotlib.org/) --> <svg height="345.6pt" version="1.1" viewBox="0 0 460.8 345.6" width="460.8pt" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> + <metadata> + <rdf:RDF xmlns:cc="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"> + <cc:Work> + <dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage"/> + <dc:date>2020-08-16T19:18:08.204014</dc:date> + <dc:format>image/svg+xml</dc:format> + <dc:creator> + <cc:Agent> + <dc:title>Matplotlib v3.3.0, https://matplotlib.org/</dc:title> + </cc:Agent> + </dc:creator> + </cc:Work> + </rdf:RDF> + </metadata> <defs> - <style type="text/css"> -*{stroke-linecap:butt;stroke-linejoin:round;} - </style> + <style type="text/css">*{stroke-linecap:butt;stroke-linejoin:round;}</style> </defs> <g id="figure_1"> <g id="patch_1"> @@ -64,8 +76,9 @@ L 0 3.5 </g> <g id="text_1"> <!-- Déployé --> - <defs> - <path d="M 19.671875 64.796875 + <g transform="translate(99.626792 308.758437)scale(0.1 -0.1)"> + <defs> + <path d="M 19.671875 64.796875 L 19.671875 8.109375 L 31.59375 8.109375 Q 46.6875 8.109375 53.6875 14.9375 @@ -82,7 +95,7 @@ Q 51.171875 0 30.078125 0 L 9.8125 0 z " id="DejaVuSans-68"/> - <path d="M 56.203125 29.59375 + <path d="M 56.203125 29.59375 L 56.203125 25.203125 L 14.890625 25.203125 Q 15.484375 15.921875 20.484375 11.0625 @@ -111,7 +124,7 @@ L 32.375 61.625 L 24.90625 61.625 z " id="DejaVuSans-233"/> - <path d="M 18.109375 8.203125 + <path d="M 18.109375 8.203125 L 18.109375 -20.796875 L 9.078125 -20.796875 L 9.078125 54.6875 @@ -137,13 +150,13 @@ Q 40.53125 6.109375 44.609375 11.75 Q 48.6875 17.390625 48.6875 27.296875 z " id="DejaVuSans-112"/> - <path d="M 9.421875 75.984375 + <path d="M 9.421875 75.984375 L 18.40625 75.984375 L 18.40625 0 L 9.421875 0 z " id="DejaVuSans-108"/> - <path d="M 30.609375 48.390625 + <path d="M 30.609375 48.390625 Q 23.390625 48.390625 19.1875 42.75 Q 14.984375 37.109375 14.984375 27.296875 Q 14.984375 17.484375 19.15625 11.84375 @@ -164,7 +177,7 @@ Q 5.515625 40.765625 12.171875 48.375 Q 18.84375 56 30.609375 56 z " id="DejaVuSans-111"/> - <path d="M 32.171875 -5.078125 + <path d="M 32.171875 -5.078125 Q 28.375 -14.84375 24.75 -17.8125 Q 21.140625 -20.796875 15.09375 -20.796875 L 7.90625 -20.796875 @@ -180,8 +193,7 @@ L 46.6875 54.6875 L 56.203125 54.6875 z " id="DejaVuSans-121"/> - </defs> - <g transform="translate(99.626792 308.758437)scale(0.1 -0.1)"> + </defs> <use xlink:href="#DejaVuSans-68"/> <use x="77.001953" xlink:href="#DejaVuSans-233"/> <use x="138.525391" xlink:href="#DejaVuSans-112"/> @@ -200,8 +212,9 @@ z </g> <g id="text_2"> <!-- Gzip --> - <defs> - <path d="M 59.515625 10.40625 + <g transform="translate(225.098281 308.358437)scale(0.1 -0.1)"> + <defs> + <path d="M 59.515625 10.40625 L 59.515625 29.984375 L 43.40625 29.984375 L 43.40625 38.09375 @@ -226,7 +239,7 @@ Q 48.046875 6.6875 52.140625 7.59375 Q 56.25 8.5 59.515625 10.40625 z " id="DejaVuSans-71"/> - <path d="M 5.515625 54.6875 + <path d="M 5.515625 54.6875 L 48.1875 54.6875 L 48.1875 46.484375 L 14.40625 7.171875 @@ -238,7 +251,7 @@ L 38.09375 47.515625 L 5.515625 47.515625 z " id="DejaVuSans-122"/> - <path d="M 9.421875 54.6875 + <path d="M 9.421875 54.6875 L 18.40625 54.6875 L 18.40625 0 L 9.421875 0 @@ -249,8 +262,7 @@ L 18.40625 64.59375 L 9.421875 64.59375 z " id="DejaVuSans-105"/> - </defs> - <g transform="translate(225.098281 308.358437)scale(0.1 -0.1)"> + </defs> <use xlink:href="#DejaVuSans-71"/> <use x="77.490234" xlink:href="#DejaVuSans-122"/> <use x="129.980469" xlink:href="#DejaVuSans-105"/> @@ -266,8 +278,9 @@ z </g> <g id="text_3"> <!-- Clonezilla --> - <defs> - <path d="M 64.40625 67.28125 + <g transform="translate(328.067427 308.358437)scale(0.1 -0.1)"> + <defs> + <path d="M 64.40625 67.28125 L 64.40625 56.890625 Q 59.421875 61.53125 53.78125 63.8125 Q 48.140625 66.109375 41.796875 66.109375 @@ -288,7 +301,7 @@ Q 47.75 74.21875 53.53125 72.484375 Q 59.328125 70.75 64.40625 67.28125 z " id="DejaVuSans-67"/> - <path d="M 54.890625 33.015625 + <path d="M 54.890625 33.015625 L 54.890625 0 L 45.90625 0 L 45.90625 32.71875 @@ -307,7 +320,7 @@ Q 45.21875 56 50.046875 50.171875 Q 54.890625 44.34375 54.890625 33.015625 z " id="DejaVuSans-110"/> - <path d="M 56.203125 29.59375 + <path d="M 56.203125 29.59375 L 56.203125 25.203125 L 14.890625 25.203125 Q 15.484375 15.921875 20.484375 11.0625 @@ -331,7 +344,7 @@ Q 24.90625 48.390625 20.390625 44.140625 Q 15.875 39.890625 15.1875 32.171875 z " id="DejaVuSans-101"/> - <path d="M 34.28125 27.484375 + <path d="M 34.28125 27.484375 Q 23.390625 27.484375 19.1875 25 Q 14.984375 22.515625 14.984375 16.5 Q 14.984375 11.71875 18.140625 8.90625 @@ -363,8 +376,7 @@ Q 40.484375 56 46.34375 49.84375 Q 52.203125 43.703125 52.203125 31.203125 z " id="DejaVuSans-97"/> - </defs> - <g transform="translate(328.067427 308.358437)scale(0.1 -0.1)"> + </defs> <use xlink:href="#DejaVuSans-67"/> <use x="69.824219" xlink:href="#DejaVuSans-108"/> <use x="97.607422" xlink:href="#DejaVuSans-111"/> @@ -380,8 +392,9 @@ z </g> <g id="text_4"> <!-- Type --> - <defs> - <path d="M -0.296875 72.90625 + <g transform="translate(224.677188 322.436562)scale(0.1 -0.1)"> + <defs> + <path d="M -0.296875 72.90625 L 61.375 72.90625 L 61.375 64.59375 L 35.5 64.59375 @@ -391,8 +404,7 @@ L 25.59375 64.59375 L -0.296875 64.59375 z " id="DejaVuSans-84"/> - </defs> - <g transform="translate(224.677188 322.436562)scale(0.1 -0.1)"> + </defs> <use xlink:href="#DejaVuSans-84"/> <use x="45.458984" xlink:href="#DejaVuSans-121"/> <use x="104.638672" xlink:href="#DejaVuSans-112"/> @@ -414,8 +426,9 @@ L -3.5 0 </g> <g id="text_5"> <!-- 0.0 --> - <defs> - <path d="M 31.78125 66.40625 + <g transform="translate(34.696875 297.559219)scale(0.1 -0.1)"> + <defs> + <path d="M 31.78125 66.40625 Q 24.171875 66.40625 20.328125 58.90625 Q 16.5 51.421875 16.5 36.375 Q 16.5 21.390625 20.328125 13.890625 @@ -436,14 +449,13 @@ Q 6.59375 54.828125 13.0625 64.515625 Q 19.53125 74.21875 31.78125 74.21875 z " id="DejaVuSans-48"/> - <path d="M 10.6875 12.40625 + <path d="M 10.6875 12.40625 L 21 12.40625 L 21 0 L 10.6875 0 z " id="DejaVuSans-46"/> - </defs> - <g transform="translate(34.696875 297.559219)scale(0.1 -0.1)"> + </defs> <use xlink:href="#DejaVuSans-48"/> <use x="63.623047" xlink:href="#DejaVuSans-46"/> <use x="95.410156" xlink:href="#DejaVuSans-48"/> @@ -458,8 +470,9 @@ z </g> <g id="text_6"> <!-- 0.5 --> - <defs> - <path d="M 10.796875 72.90625 + <g transform="translate(34.696875 260.251591)scale(0.1 -0.1)"> + <defs> + <path d="M 10.796875 72.90625 L 49.515625 72.90625 L 49.515625 64.59375 L 19.828125 64.59375 @@ -483,8 +496,7 @@ Q 22.75 39.890625 18.8125 39.015625 Q 14.890625 38.140625 10.796875 36.28125 z " id="DejaVuSans-53"/> - </defs> - <g transform="translate(34.696875 260.251591)scale(0.1 -0.1)"> + </defs> <use xlink:href="#DejaVuSans-48"/> <use x="63.623047" xlink:href="#DejaVuSans-46"/> <use x="95.410156" xlink:href="#DejaVuSans-53"/> @@ -499,8 +511,9 @@ z </g> <g id="text_7"> <!-- 1.0 --> - <defs> - <path d="M 12.40625 8.296875 + <g transform="translate(34.696875 222.943963)scale(0.1 -0.1)"> + <defs> + <path d="M 12.40625 8.296875 L 28.515625 8.296875 L 28.515625 63.921875 L 10.984375 60.40625 @@ -513,8 +526,7 @@ L 54.390625 0 L 12.40625 0 z " id="DejaVuSans-49"/> - </defs> - <g transform="translate(34.696875 222.943963)scale(0.1 -0.1)"> + </defs> <use xlink:href="#DejaVuSans-49"/> <use x="63.623047" xlink:href="#DejaVuSans-46"/> <use x="95.410156" xlink:href="#DejaVuSans-48"/> @@ -544,8 +556,9 @@ z </g> <g id="text_9"> <!-- 2.0 --> - <defs> - <path d="M 19.1875 8.296875 + <g transform="translate(34.696875 148.328706)scale(0.1 -0.1)"> + <defs> + <path d="M 19.1875 8.296875 L 53.609375 8.296875 L 53.609375 0 L 7.328125 0 @@ -569,8 +582,7 @@ Q 44.1875 33.984375 37.640625 27.21875 Q 31.109375 20.453125 19.1875 8.296875 z " id="DejaVuSans-50"/> - </defs> - <g transform="translate(34.696875 148.328706)scale(0.1 -0.1)"> + </defs> <use xlink:href="#DejaVuSans-50"/> <use x="63.623047" xlink:href="#DejaVuSans-46"/> <use x="95.410156" xlink:href="#DejaVuSans-48"/> @@ -600,8 +612,9 @@ z </g> <g id="text_11"> <!-- 3.0 --> - <defs> - <path d="M 40.578125 39.3125 + <g transform="translate(34.696875 73.71345)scale(0.1 -0.1)"> + <defs> + <path d="M 40.578125 39.3125 Q 47.65625 37.796875 51.625 33 Q 55.609375 28.21875 55.609375 21.1875 Q 55.609375 10.40625 48.1875 4.484375 @@ -633,8 +646,7 @@ Q 53.90625 49.265625 50.4375 45.09375 Q 46.96875 40.921875 40.578125 39.3125 z " id="DejaVuSans-51"/> - </defs> - <g transform="translate(34.696875 73.71345)scale(0.1 -0.1)"> + </defs> <use xlink:href="#DejaVuSans-51"/> <use x="63.623047" xlink:href="#DejaVuSans-46"/> <use x="95.410156" xlink:href="#DejaVuSans-48"/> @@ -643,9 +655,10 @@ z </g> <g id="text_12"> <!-- Taille (GB) --> - <defs> - <path id="DejaVuSans-32"/> - <path d="M 31 75.875 + <g transform="translate(28.617187 192.948031)rotate(-90)scale(0.1 -0.1)"> + <defs> + <path id="DejaVuSans-32"/> + <path d="M 31 75.875 Q 24.46875 64.65625 21.28125 53.65625 Q 18.109375 42.671875 18.109375 31.390625 Q 18.109375 20.125 21.3125 9.0625 @@ -657,7 +670,7 @@ Q 8.59375 42.28125 12.203125 53.3125 Q 15.828125 64.359375 23.1875 75.875 z " id="DejaVuSans-40"/> - <path d="M 19.671875 34.8125 + <path d="M 19.671875 34.8125 L 19.671875 8.109375 L 35.5 8.109375 Q 43.453125 8.109375 47.28125 11.40625 @@ -686,7 +699,7 @@ Q 48.25 0 35.984375 0 L 9.8125 0 z " id="DejaVuSans-66"/> - <path d="M 8.015625 75.875 + <path d="M 8.015625 75.875 L 15.828125 75.875 Q 23.140625 64.359375 26.78125 53.3125 Q 30.421875 42.28125 30.421875 31.390625 @@ -699,8 +712,7 @@ Q 20.90625 42.671875 17.703125 53.65625 Q 14.5 64.65625 8.015625 75.875 z " id="DejaVuSans-41"/> - </defs> - <g transform="translate(28.617187 192.948031)rotate(-90)scale(0.1 -0.1)"> + </defs> <use xlink:href="#DejaVuSans-84"/> <use x="44.583984" xlink:href="#DejaVuSans-97"/> <use x="105.863281" xlink:href="#DejaVuSans-105"/> diff --git a/doc/charts/chart_image_sizes_win10.png b/doc/charts/chart_image_sizes_win10.png index 1f307b4f2156bf5577dbb48de17f74754b0d1388..8358bb8f21ec093f395fa43e4fd5fb9e36a666b5 100644 --- a/doc/charts/chart_image_sizes_win10.png +++ b/doc/charts/chart_image_sizes_win10.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:0399fa84632fda7b3c7e26e7f75125abb7343df1f9f19a34a6eb802bec6b0516 -size 12569 +oid sha256:1d7e8bc591131e9a18bbc29ef29294100fa01f9a8904c88004abeec831dd519a +size 12543 diff --git a/doc/charts/chart_image_sizes_win10.svg b/doc/charts/chart_image_sizes_win10.svg index 1dbdf6bc5eed909b4668716b828ea6d0cae6be13..4f089ffb291b0ff47326aa1947e211b48e48221e 100644 --- a/doc/charts/chart_image_sizes_win10.svg +++ b/doc/charts/chart_image_sizes_win10.svg @@ -3,10 +3,22 @@ "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"> <!-- Created with matplotlib (https://matplotlib.org/) --> <svg height="345.6pt" version="1.1" viewBox="0 0 460.8 345.6" width="460.8pt" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> + <metadata> + <rdf:RDF xmlns:cc="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"> + <cc:Work> + <dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage"/> + <dc:date>2020-08-16T19:18:09.215542</dc:date> + <dc:format>image/svg+xml</dc:format> + <dc:creator> + <cc:Agent> + <dc:title>Matplotlib v3.3.0, https://matplotlib.org/</dc:title> + </cc:Agent> + </dc:creator> + </cc:Work> + </rdf:RDF> + </metadata> <defs> - <style type="text/css"> -*{stroke-linecap:butt;stroke-linejoin:round;} - </style> + <style type="text/css">*{stroke-linecap:butt;stroke-linejoin:round;}</style> </defs> <g id="figure_1"> <g id="patch_1"> @@ -64,8 +76,9 @@ L 0 3.5 </g> <g id="text_1"> <!-- Déployé --> - <defs> - <path d="M 19.671875 64.796875 + <g transform="translate(99.626792 308.758437)scale(0.1 -0.1)"> + <defs> + <path d="M 19.671875 64.796875 L 19.671875 8.109375 L 31.59375 8.109375 Q 46.6875 8.109375 53.6875 14.9375 @@ -82,7 +95,7 @@ Q 51.171875 0 30.078125 0 L 9.8125 0 z " id="DejaVuSans-68"/> - <path d="M 56.203125 29.59375 + <path d="M 56.203125 29.59375 L 56.203125 25.203125 L 14.890625 25.203125 Q 15.484375 15.921875 20.484375 11.0625 @@ -111,7 +124,7 @@ L 32.375 61.625 L 24.90625 61.625 z " id="DejaVuSans-233"/> - <path d="M 18.109375 8.203125 + <path d="M 18.109375 8.203125 L 18.109375 -20.796875 L 9.078125 -20.796875 L 9.078125 54.6875 @@ -137,13 +150,13 @@ Q 40.53125 6.109375 44.609375 11.75 Q 48.6875 17.390625 48.6875 27.296875 z " id="DejaVuSans-112"/> - <path d="M 9.421875 75.984375 + <path d="M 9.421875 75.984375 L 18.40625 75.984375 L 18.40625 0 L 9.421875 0 z " id="DejaVuSans-108"/> - <path d="M 30.609375 48.390625 + <path d="M 30.609375 48.390625 Q 23.390625 48.390625 19.1875 42.75 Q 14.984375 37.109375 14.984375 27.296875 Q 14.984375 17.484375 19.15625 11.84375 @@ -164,7 +177,7 @@ Q 5.515625 40.765625 12.171875 48.375 Q 18.84375 56 30.609375 56 z " id="DejaVuSans-111"/> - <path d="M 32.171875 -5.078125 + <path d="M 32.171875 -5.078125 Q 28.375 -14.84375 24.75 -17.8125 Q 21.140625 -20.796875 15.09375 -20.796875 L 7.90625 -20.796875 @@ -180,8 +193,7 @@ L 46.6875 54.6875 L 56.203125 54.6875 z " id="DejaVuSans-121"/> - </defs> - <g transform="translate(99.626792 308.758437)scale(0.1 -0.1)"> + </defs> <use xlink:href="#DejaVuSans-68"/> <use x="77.001953" xlink:href="#DejaVuSans-233"/> <use x="138.525391" xlink:href="#DejaVuSans-112"/> @@ -200,8 +212,9 @@ z </g> <g id="text_2"> <!-- Gzip --> - <defs> - <path d="M 59.515625 10.40625 + <g transform="translate(225.098281 308.358437)scale(0.1 -0.1)"> + <defs> + <path d="M 59.515625 10.40625 L 59.515625 29.984375 L 43.40625 29.984375 L 43.40625 38.09375 @@ -226,7 +239,7 @@ Q 48.046875 6.6875 52.140625 7.59375 Q 56.25 8.5 59.515625 10.40625 z " id="DejaVuSans-71"/> - <path d="M 5.515625 54.6875 + <path d="M 5.515625 54.6875 L 48.1875 54.6875 L 48.1875 46.484375 L 14.40625 7.171875 @@ -238,7 +251,7 @@ L 38.09375 47.515625 L 5.515625 47.515625 z " id="DejaVuSans-122"/> - <path d="M 9.421875 54.6875 + <path d="M 9.421875 54.6875 L 18.40625 54.6875 L 18.40625 0 L 9.421875 0 @@ -249,8 +262,7 @@ L 18.40625 64.59375 L 9.421875 64.59375 z " id="DejaVuSans-105"/> - </defs> - <g transform="translate(225.098281 308.358437)scale(0.1 -0.1)"> + </defs> <use xlink:href="#DejaVuSans-71"/> <use x="77.490234" xlink:href="#DejaVuSans-122"/> <use x="129.980469" xlink:href="#DejaVuSans-105"/> @@ -266,8 +278,9 @@ z </g> <g id="text_3"> <!-- Clonezilla --> - <defs> - <path d="M 64.40625 67.28125 + <g transform="translate(328.067427 308.358437)scale(0.1 -0.1)"> + <defs> + <path d="M 64.40625 67.28125 L 64.40625 56.890625 Q 59.421875 61.53125 53.78125 63.8125 Q 48.140625 66.109375 41.796875 66.109375 @@ -288,7 +301,7 @@ Q 47.75 74.21875 53.53125 72.484375 Q 59.328125 70.75 64.40625 67.28125 z " id="DejaVuSans-67"/> - <path d="M 54.890625 33.015625 + <path d="M 54.890625 33.015625 L 54.890625 0 L 45.90625 0 L 45.90625 32.71875 @@ -307,7 +320,7 @@ Q 45.21875 56 50.046875 50.171875 Q 54.890625 44.34375 54.890625 33.015625 z " id="DejaVuSans-110"/> - <path d="M 56.203125 29.59375 + <path d="M 56.203125 29.59375 L 56.203125 25.203125 L 14.890625 25.203125 Q 15.484375 15.921875 20.484375 11.0625 @@ -331,7 +344,7 @@ Q 24.90625 48.390625 20.390625 44.140625 Q 15.875 39.890625 15.1875 32.171875 z " id="DejaVuSans-101"/> - <path d="M 34.28125 27.484375 + <path d="M 34.28125 27.484375 Q 23.390625 27.484375 19.1875 25 Q 14.984375 22.515625 14.984375 16.5 Q 14.984375 11.71875 18.140625 8.90625 @@ -363,8 +376,7 @@ Q 40.484375 56 46.34375 49.84375 Q 52.203125 43.703125 52.203125 31.203125 z " id="DejaVuSans-97"/> - </defs> - <g transform="translate(328.067427 308.358437)scale(0.1 -0.1)"> + </defs> <use xlink:href="#DejaVuSans-67"/> <use x="69.824219" xlink:href="#DejaVuSans-108"/> <use x="97.607422" xlink:href="#DejaVuSans-111"/> @@ -380,8 +392,9 @@ z </g> <g id="text_4"> <!-- Type --> - <defs> - <path d="M -0.296875 72.90625 + <g transform="translate(224.677188 322.436562)scale(0.1 -0.1)"> + <defs> + <path d="M -0.296875 72.90625 L 61.375 72.90625 L 61.375 64.59375 L 35.5 64.59375 @@ -391,8 +404,7 @@ L 25.59375 64.59375 L -0.296875 64.59375 z " id="DejaVuSans-84"/> - </defs> - <g transform="translate(224.677188 322.436562)scale(0.1 -0.1)"> + </defs> <use xlink:href="#DejaVuSans-84"/> <use x="45.458984" xlink:href="#DejaVuSans-121"/> <use x="104.638672" xlink:href="#DejaVuSans-112"/> @@ -414,8 +426,9 @@ L -3.5 0 </g> <g id="text_5"> <!-- 0 --> - <defs> - <path d="M 31.78125 66.40625 + <g transform="translate(44.2375 297.559219)scale(0.1 -0.1)"> + <defs> + <path d="M 31.78125 66.40625 Q 24.171875 66.40625 20.328125 58.90625 Q 16.5 51.421875 16.5 36.375 Q 16.5 21.390625 20.328125 13.890625 @@ -436,8 +449,7 @@ Q 6.59375 54.828125 13.0625 64.515625 Q 19.53125 74.21875 31.78125 74.21875 z " id="DejaVuSans-48"/> - </defs> - <g transform="translate(44.2375 297.559219)scale(0.1 -0.1)"> + </defs> <use xlink:href="#DejaVuSans-48"/> </g> </g> @@ -450,8 +462,9 @@ z </g> <g id="text_6"> <!-- 100 --> - <defs> - <path d="M 12.40625 8.296875 + <g transform="translate(31.5125 250.639368)scale(0.1 -0.1)"> + <defs> + <path d="M 12.40625 8.296875 L 28.515625 8.296875 L 28.515625 63.921875 L 10.984375 60.40625 @@ -464,8 +477,7 @@ L 54.390625 0 L 12.40625 0 z " id="DejaVuSans-49"/> - </defs> - <g transform="translate(31.5125 250.639368)scale(0.1 -0.1)"> + </defs> <use xlink:href="#DejaVuSans-49"/> <use x="63.623047" xlink:href="#DejaVuSans-48"/> <use x="127.246094" xlink:href="#DejaVuSans-48"/> @@ -480,8 +492,9 @@ z </g> <g id="text_7"> <!-- 200 --> - <defs> - <path d="M 19.1875 8.296875 + <g transform="translate(31.5125 203.719516)scale(0.1 -0.1)"> + <defs> + <path d="M 19.1875 8.296875 L 53.609375 8.296875 L 53.609375 0 L 7.328125 0 @@ -505,8 +518,7 @@ Q 44.1875 33.984375 37.640625 27.21875 Q 31.109375 20.453125 19.1875 8.296875 z " id="DejaVuSans-50"/> - </defs> - <g transform="translate(31.5125 203.719516)scale(0.1 -0.1)"> + </defs> <use xlink:href="#DejaVuSans-50"/> <use x="63.623047" xlink:href="#DejaVuSans-48"/> <use x="127.246094" xlink:href="#DejaVuSans-48"/> @@ -521,8 +533,9 @@ z </g> <g id="text_8"> <!-- 300 --> - <defs> - <path d="M 40.578125 39.3125 + <g transform="translate(31.5125 156.799665)scale(0.1 -0.1)"> + <defs> + <path d="M 40.578125 39.3125 Q 47.65625 37.796875 51.625 33 Q 55.609375 28.21875 55.609375 21.1875 Q 55.609375 10.40625 48.1875 4.484375 @@ -554,8 +567,7 @@ Q 53.90625 49.265625 50.4375 45.09375 Q 46.96875 40.921875 40.578125 39.3125 z " id="DejaVuSans-51"/> - </defs> - <g transform="translate(31.5125 156.799665)scale(0.1 -0.1)"> + </defs> <use xlink:href="#DejaVuSans-51"/> <use x="63.623047" xlink:href="#DejaVuSans-48"/> <use x="127.246094" xlink:href="#DejaVuSans-48"/> @@ -570,8 +582,9 @@ z </g> <g id="text_9"> <!-- 400 --> - <defs> - <path d="M 37.796875 64.3125 + <g transform="translate(31.5125 109.879814)scale(0.1 -0.1)"> + <defs> + <path d="M 37.796875 64.3125 L 12.890625 25.390625 L 37.796875 25.390625 z @@ -588,8 +601,7 @@ L 4.890625 17.1875 L 4.890625 26.703125 z " id="DejaVuSans-52"/> - </defs> - <g transform="translate(31.5125 109.879814)scale(0.1 -0.1)"> + </defs> <use xlink:href="#DejaVuSans-52"/> <use x="63.623047" xlink:href="#DejaVuSans-48"/> <use x="127.246094" xlink:href="#DejaVuSans-48"/> @@ -604,8 +616,9 @@ z </g> <g id="text_10"> <!-- 500 --> - <defs> - <path d="M 10.796875 72.90625 + <g transform="translate(31.5125 62.959963)scale(0.1 -0.1)"> + <defs> + <path d="M 10.796875 72.90625 L 49.515625 72.90625 L 49.515625 64.59375 L 19.828125 64.59375 @@ -629,8 +642,7 @@ Q 22.75 39.890625 18.8125 39.015625 Q 14.890625 38.140625 10.796875 36.28125 z " id="DejaVuSans-53"/> - </defs> - <g transform="translate(31.5125 62.959963)scale(0.1 -0.1)"> + </defs> <use xlink:href="#DejaVuSans-53"/> <use x="63.623047" xlink:href="#DejaVuSans-48"/> <use x="127.246094" xlink:href="#DejaVuSans-48"/> @@ -639,9 +651,10 @@ z </g> <g id="text_11"> <!-- Taille (GB) --> - <defs> - <path id="DejaVuSans-32"/> - <path d="M 31 75.875 + <g transform="translate(25.432812 192.948031)rotate(-90)scale(0.1 -0.1)"> + <defs> + <path id="DejaVuSans-32"/> + <path d="M 31 75.875 Q 24.46875 64.65625 21.28125 53.65625 Q 18.109375 42.671875 18.109375 31.390625 Q 18.109375 20.125 21.3125 9.0625 @@ -653,7 +666,7 @@ Q 8.59375 42.28125 12.203125 53.3125 Q 15.828125 64.359375 23.1875 75.875 z " id="DejaVuSans-40"/> - <path d="M 19.671875 34.8125 + <path d="M 19.671875 34.8125 L 19.671875 8.109375 L 35.5 8.109375 Q 43.453125 8.109375 47.28125 11.40625 @@ -682,7 +695,7 @@ Q 48.25 0 35.984375 0 L 9.8125 0 z " id="DejaVuSans-66"/> - <path d="M 8.015625 75.875 + <path d="M 8.015625 75.875 L 15.828125 75.875 Q 23.140625 64.359375 26.78125 53.3125 Q 30.421875 42.28125 30.421875 31.390625 @@ -695,8 +708,7 @@ Q 20.90625 42.671875 17.703125 53.65625 Q 14.5 64.65625 8.015625 75.875 z " id="DejaVuSans-41"/> - </defs> - <g transform="translate(25.432812 192.948031)rotate(-90)scale(0.1 -0.1)"> + </defs> <use xlink:href="#DejaVuSans-84"/> <use x="44.583984" xlink:href="#DejaVuSans-97"/> <use x="105.863281" xlink:href="#DejaVuSans-105"/> diff --git a/doc/charts/chart_image_sizes_xubuntu.png b/doc/charts/chart_image_sizes_xubuntu.png index 79d30c80377e364d98aab3abe94f30a9bf68daa7..e6a8d8f15fda2cc5b3b8bd9e69aa9b473387eeb9 100644 --- a/doc/charts/chart_image_sizes_xubuntu.png +++ b/doc/charts/chart_image_sizes_xubuntu.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:b2121f09a33bf4f6d93b02aefec24ebad4b3dbff972809d400bcb5c185db608a -size 13652 +oid sha256:32c51829ae50fd667e8fe755f9c9558dc4c382abc64b8ef76064107262e3bc35 +size 13627 diff --git a/doc/charts/chart_image_sizes_xubuntu.svg b/doc/charts/chart_image_sizes_xubuntu.svg index a67f2f85e3d3867ee92ccb81b0849ebd36b690b8..c7418b637170226a95211771d2d0c7e4e6c860c9 100644 --- a/doc/charts/chart_image_sizes_xubuntu.svg +++ b/doc/charts/chart_image_sizes_xubuntu.svg @@ -3,10 +3,22 @@ "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"> <!-- Created with matplotlib (https://matplotlib.org/) --> <svg height="345.6pt" version="1.1" viewBox="0 0 460.8 345.6" width="460.8pt" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> + <metadata> + <rdf:RDF xmlns:cc="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"> + <cc:Work> + <dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage"/> + <dc:date>2020-08-16T19:18:08.711073</dc:date> + <dc:format>image/svg+xml</dc:format> + <dc:creator> + <cc:Agent> + <dc:title>Matplotlib v3.3.0, https://matplotlib.org/</dc:title> + </cc:Agent> + </dc:creator> + </cc:Work> + </rdf:RDF> + </metadata> <defs> - <style type="text/css"> -*{stroke-linecap:butt;stroke-linejoin:round;} - </style> + <style type="text/css">*{stroke-linecap:butt;stroke-linejoin:round;}</style> </defs> <g id="figure_1"> <g id="patch_1"> @@ -64,8 +76,9 @@ L 0 3.5 </g> <g id="text_1"> <!-- Déployé --> - <defs> - <path d="M 19.671875 64.796875 + <g transform="translate(99.626792 308.758437)scale(0.1 -0.1)"> + <defs> + <path d="M 19.671875 64.796875 L 19.671875 8.109375 L 31.59375 8.109375 Q 46.6875 8.109375 53.6875 14.9375 @@ -82,7 +95,7 @@ Q 51.171875 0 30.078125 0 L 9.8125 0 z " id="DejaVuSans-68"/> - <path d="M 56.203125 29.59375 + <path d="M 56.203125 29.59375 L 56.203125 25.203125 L 14.890625 25.203125 Q 15.484375 15.921875 20.484375 11.0625 @@ -111,7 +124,7 @@ L 32.375 61.625 L 24.90625 61.625 z " id="DejaVuSans-233"/> - <path d="M 18.109375 8.203125 + <path d="M 18.109375 8.203125 L 18.109375 -20.796875 L 9.078125 -20.796875 L 9.078125 54.6875 @@ -137,13 +150,13 @@ Q 40.53125 6.109375 44.609375 11.75 Q 48.6875 17.390625 48.6875 27.296875 z " id="DejaVuSans-112"/> - <path d="M 9.421875 75.984375 + <path d="M 9.421875 75.984375 L 18.40625 75.984375 L 18.40625 0 L 9.421875 0 z " id="DejaVuSans-108"/> - <path d="M 30.609375 48.390625 + <path d="M 30.609375 48.390625 Q 23.390625 48.390625 19.1875 42.75 Q 14.984375 37.109375 14.984375 27.296875 Q 14.984375 17.484375 19.15625 11.84375 @@ -164,7 +177,7 @@ Q 5.515625 40.765625 12.171875 48.375 Q 18.84375 56 30.609375 56 z " id="DejaVuSans-111"/> - <path d="M 32.171875 -5.078125 + <path d="M 32.171875 -5.078125 Q 28.375 -14.84375 24.75 -17.8125 Q 21.140625 -20.796875 15.09375 -20.796875 L 7.90625 -20.796875 @@ -180,8 +193,7 @@ L 46.6875 54.6875 L 56.203125 54.6875 z " id="DejaVuSans-121"/> - </defs> - <g transform="translate(99.626792 308.758437)scale(0.1 -0.1)"> + </defs> <use xlink:href="#DejaVuSans-68"/> <use x="77.001953" xlink:href="#DejaVuSans-233"/> <use x="138.525391" xlink:href="#DejaVuSans-112"/> @@ -200,8 +212,9 @@ z </g> <g id="text_2"> <!-- Gzip --> - <defs> - <path d="M 59.515625 10.40625 + <g transform="translate(225.098281 308.358437)scale(0.1 -0.1)"> + <defs> + <path d="M 59.515625 10.40625 L 59.515625 29.984375 L 43.40625 29.984375 L 43.40625 38.09375 @@ -226,7 +239,7 @@ Q 48.046875 6.6875 52.140625 7.59375 Q 56.25 8.5 59.515625 10.40625 z " id="DejaVuSans-71"/> - <path d="M 5.515625 54.6875 + <path d="M 5.515625 54.6875 L 48.1875 54.6875 L 48.1875 46.484375 L 14.40625 7.171875 @@ -238,7 +251,7 @@ L 38.09375 47.515625 L 5.515625 47.515625 z " id="DejaVuSans-122"/> - <path d="M 9.421875 54.6875 + <path d="M 9.421875 54.6875 L 18.40625 54.6875 L 18.40625 0 L 9.421875 0 @@ -249,8 +262,7 @@ L 18.40625 64.59375 L 9.421875 64.59375 z " id="DejaVuSans-105"/> - </defs> - <g transform="translate(225.098281 308.358437)scale(0.1 -0.1)"> + </defs> <use xlink:href="#DejaVuSans-71"/> <use x="77.490234" xlink:href="#DejaVuSans-122"/> <use x="129.980469" xlink:href="#DejaVuSans-105"/> @@ -266,8 +278,9 @@ z </g> <g id="text_3"> <!-- Clonezilla --> - <defs> - <path d="M 64.40625 67.28125 + <g transform="translate(328.067427 308.358437)scale(0.1 -0.1)"> + <defs> + <path d="M 64.40625 67.28125 L 64.40625 56.890625 Q 59.421875 61.53125 53.78125 63.8125 Q 48.140625 66.109375 41.796875 66.109375 @@ -288,7 +301,7 @@ Q 47.75 74.21875 53.53125 72.484375 Q 59.328125 70.75 64.40625 67.28125 z " id="DejaVuSans-67"/> - <path d="M 54.890625 33.015625 + <path d="M 54.890625 33.015625 L 54.890625 0 L 45.90625 0 L 45.90625 32.71875 @@ -307,7 +320,7 @@ Q 45.21875 56 50.046875 50.171875 Q 54.890625 44.34375 54.890625 33.015625 z " id="DejaVuSans-110"/> - <path d="M 56.203125 29.59375 + <path d="M 56.203125 29.59375 L 56.203125 25.203125 L 14.890625 25.203125 Q 15.484375 15.921875 20.484375 11.0625 @@ -331,7 +344,7 @@ Q 24.90625 48.390625 20.390625 44.140625 Q 15.875 39.890625 15.1875 32.171875 z " id="DejaVuSans-101"/> - <path d="M 34.28125 27.484375 + <path d="M 34.28125 27.484375 Q 23.390625 27.484375 19.1875 25 Q 14.984375 22.515625 14.984375 16.5 Q 14.984375 11.71875 18.140625 8.90625 @@ -363,8 +376,7 @@ Q 40.484375 56 46.34375 49.84375 Q 52.203125 43.703125 52.203125 31.203125 z " id="DejaVuSans-97"/> - </defs> - <g transform="translate(328.067427 308.358437)scale(0.1 -0.1)"> + </defs> <use xlink:href="#DejaVuSans-67"/> <use x="69.824219" xlink:href="#DejaVuSans-108"/> <use x="97.607422" xlink:href="#DejaVuSans-111"/> @@ -380,8 +392,9 @@ z </g> <g id="text_4"> <!-- Type --> - <defs> - <path d="M -0.296875 72.90625 + <g transform="translate(224.677188 322.436562)scale(0.1 -0.1)"> + <defs> + <path d="M -0.296875 72.90625 L 61.375 72.90625 L 61.375 64.59375 L 35.5 64.59375 @@ -391,8 +404,7 @@ L 25.59375 64.59375 L -0.296875 64.59375 z " id="DejaVuSans-84"/> - </defs> - <g transform="translate(224.677188 322.436562)scale(0.1 -0.1)"> + </defs> <use xlink:href="#DejaVuSans-84"/> <use x="45.458984" xlink:href="#DejaVuSans-121"/> <use x="104.638672" xlink:href="#DejaVuSans-112"/> @@ -414,8 +426,9 @@ L -3.5 0 </g> <g id="text_5"> <!-- 0 --> - <defs> - <path d="M 31.78125 66.40625 + <g transform="translate(44.2375 297.559219)scale(0.1 -0.1)"> + <defs> + <path d="M 31.78125 66.40625 Q 24.171875 66.40625 20.328125 58.90625 Q 16.5 51.421875 16.5 36.375 Q 16.5 21.390625 20.328125 13.890625 @@ -436,8 +449,7 @@ Q 6.59375 54.828125 13.0625 64.515625 Q 19.53125 74.21875 31.78125 74.21875 z " id="DejaVuSans-48"/> - </defs> - <g transform="translate(44.2375 297.559219)scale(0.1 -0.1)"> + </defs> <use xlink:href="#DejaVuSans-48"/> </g> </g> @@ -450,8 +462,9 @@ z </g> <g id="text_6"> <!-- 25 --> - <defs> - <path d="M 19.1875 8.296875 + <g transform="translate(37.875 267.601602)scale(0.1 -0.1)"> + <defs> + <path d="M 19.1875 8.296875 L 53.609375 8.296875 L 53.609375 0 L 7.328125 0 @@ -475,7 +488,7 @@ Q 44.1875 33.984375 37.640625 27.21875 Q 31.109375 20.453125 19.1875 8.296875 z " id="DejaVuSans-50"/> - <path d="M 10.796875 72.90625 + <path d="M 10.796875 72.90625 L 49.515625 72.90625 L 49.515625 64.59375 L 19.828125 64.59375 @@ -499,8 +512,7 @@ Q 22.75 39.890625 18.8125 39.015625 Q 14.890625 38.140625 10.796875 36.28125 z " id="DejaVuSans-53"/> - </defs> - <g transform="translate(37.875 267.601602)scale(0.1 -0.1)"> + </defs> <use xlink:href="#DejaVuSans-50"/> <use x="63.623047" xlink:href="#DejaVuSans-53"/> </g> @@ -528,8 +540,9 @@ z </g> <g id="text_8"> <!-- 75 --> - <defs> - <path d="M 8.203125 72.90625 + <g transform="translate(37.875 207.686368)scale(0.1 -0.1)"> + <defs> + <path d="M 8.203125 72.90625 L 55.078125 72.90625 L 55.078125 68.703125 L 28.609375 0 @@ -538,8 +551,7 @@ L 43.21875 64.59375 L 8.203125 64.59375 z " id="DejaVuSans-55"/> - </defs> - <g transform="translate(37.875 207.686368)scale(0.1 -0.1)"> + </defs> <use xlink:href="#DejaVuSans-55"/> <use x="63.623047" xlink:href="#DejaVuSans-53"/> </g> @@ -553,8 +565,9 @@ z </g> <g id="text_9"> <!-- 100 --> - <defs> - <path d="M 12.40625 8.296875 + <g transform="translate(31.5125 177.728751)scale(0.1 -0.1)"> + <defs> + <path d="M 12.40625 8.296875 L 28.515625 8.296875 L 28.515625 63.921875 L 10.984375 60.40625 @@ -567,8 +580,7 @@ L 54.390625 0 L 12.40625 0 z " id="DejaVuSans-49"/> - </defs> - <g transform="translate(31.5125 177.728751)scale(0.1 -0.1)"> + </defs> <use xlink:href="#DejaVuSans-49"/> <use x="63.623047" xlink:href="#DejaVuSans-48"/> <use x="127.246094" xlink:href="#DejaVuSans-48"/> @@ -637,9 +649,10 @@ z </g> <g id="text_14"> <!-- Taille (GB) --> - <defs> - <path id="DejaVuSans-32"/> - <path d="M 31 75.875 + <g transform="translate(25.432812 192.948031)rotate(-90)scale(0.1 -0.1)"> + <defs> + <path id="DejaVuSans-32"/> + <path d="M 31 75.875 Q 24.46875 64.65625 21.28125 53.65625 Q 18.109375 42.671875 18.109375 31.390625 Q 18.109375 20.125 21.3125 9.0625 @@ -651,7 +664,7 @@ Q 8.59375 42.28125 12.203125 53.3125 Q 15.828125 64.359375 23.1875 75.875 z " id="DejaVuSans-40"/> - <path d="M 19.671875 34.8125 + <path d="M 19.671875 34.8125 L 19.671875 8.109375 L 35.5 8.109375 Q 43.453125 8.109375 47.28125 11.40625 @@ -680,7 +693,7 @@ Q 48.25 0 35.984375 0 L 9.8125 0 z " id="DejaVuSans-66"/> - <path d="M 8.015625 75.875 + <path d="M 8.015625 75.875 L 15.828125 75.875 Q 23.140625 64.359375 26.78125 53.3125 Q 30.421875 42.28125 30.421875 31.390625 @@ -693,8 +706,7 @@ Q 20.90625 42.671875 17.703125 53.65625 Q 14.5 64.65625 8.015625 75.875 z " id="DejaVuSans-41"/> - </defs> - <g transform="translate(25.432812 192.948031)rotate(-90)scale(0.1 -0.1)"> + </defs> <use xlink:href="#DejaVuSans-84"/> <use x="44.583984" xlink:href="#DejaVuSans-97"/> <use x="105.863281" xlink:href="#DejaVuSans-105"/> diff --git a/doc/charts/chart_protocols.png b/doc/charts/chart_protocols.png index 636fa4678526da2a5d03c1e88944976402465e6b..39ca5bac082e22832a5fe02df22082ed85d93630 100644 --- a/doc/charts/chart_protocols.png +++ b/doc/charts/chart_protocols.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:e11e376fd98f104b05bc323d98a563d706e772d3996de381ce0ebf5209f6ea8e -size 13071 +oid sha256:6315daadb53225c7f0e11ad6b9e8ac4267eb5ec25604961aacefa95e65f71285 +size 13041 diff --git a/doc/charts/chart_protocols.svg b/doc/charts/chart_protocols.svg index 19ba40b45a407921c21366cc7eb2547cbc53676a..c9472a56fd286eefc8b394df895dd51f3612a8f0 100644 --- a/doc/charts/chart_protocols.svg +++ b/doc/charts/chart_protocols.svg @@ -3,10 +3,22 @@ "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"> <!-- Created with matplotlib (https://matplotlib.org/) --> <svg height="345.6pt" version="1.1" viewBox="0 0 460.8 345.6" width="460.8pt" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> + <metadata> + <rdf:RDF xmlns:cc="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"> + <cc:Work> + <dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage"/> + <dc:date>2020-08-16T19:18:07.697144</dc:date> + <dc:format>image/svg+xml</dc:format> + <dc:creator> + <cc:Agent> + <dc:title>Matplotlib v3.3.0, https://matplotlib.org/</dc:title> + </cc:Agent> + </dc:creator> + </cc:Work> + </rdf:RDF> + </metadata> <defs> - <style type="text/css"> -*{stroke-linecap:butt;stroke-linejoin:round;} - </style> + <style type="text/css">*{stroke-linecap:butt;stroke-linejoin:round;}</style> </defs> <g id="figure_1"> <g id="patch_1"> @@ -88,8 +100,9 @@ L 0 3.5 </g> <g id="text_1"> <!-- SCP --> - <defs> - <path d="M 53.515625 70.515625 + <g transform="translate(86.542227 308.358437)scale(0.1 -0.1)"> + <defs> + <path d="M 53.515625 70.515625 L 53.515625 60.890625 Q 47.90625 63.578125 42.921875 64.890625 Q 37.9375 66.21875 33.296875 66.21875 @@ -120,7 +133,7 @@ Q 37.3125 74.21875 42.625 73.28125 Q 47.953125 72.359375 53.515625 70.515625 z " id="DejaVuSans-83"/> - <path d="M 64.40625 67.28125 + <path d="M 64.40625 67.28125 L 64.40625 56.890625 Q 59.421875 61.53125 53.78125 63.8125 Q 48.140625 66.109375 41.796875 66.109375 @@ -141,7 +154,7 @@ Q 47.75 74.21875 53.53125 72.484375 Q 59.328125 70.75 64.40625 67.28125 z " id="DejaVuSans-67"/> - <path d="M 19.671875 64.796875 + <path d="M 19.671875 64.796875 L 19.671875 37.40625 L 32.078125 37.40625 Q 38.96875 37.40625 42.71875 40.96875 @@ -160,8 +173,7 @@ L 19.671875 0 L 9.8125 0 z " id="DejaVuSans-80"/> - </defs> - <g transform="translate(86.542227 308.358437)scale(0.1 -0.1)"> + </defs> <use xlink:href="#DejaVuSans-83"/> <use x="63.476562" xlink:href="#DejaVuSans-67"/> <use x="133.300781" xlink:href="#DejaVuSans-80"/> @@ -176,8 +188,9 @@ z </g> <g id="text_2"> <!-- HTTP --> - <defs> - <path d="M 9.8125 72.90625 + <g transform="translate(139.402305 308.358437)scale(0.1 -0.1)"> + <defs> + <path d="M 9.8125 72.90625 L 19.671875 72.90625 L 19.671875 43.015625 L 55.515625 43.015625 @@ -191,7 +204,7 @@ L 19.671875 0 L 9.8125 0 z " id="DejaVuSans-72"/> - <path d="M -0.296875 72.90625 + <path d="M -0.296875 72.90625 L 61.375 72.90625 L 61.375 64.59375 L 35.5 64.59375 @@ -201,8 +214,7 @@ L 25.59375 64.59375 L -0.296875 64.59375 z " id="DejaVuSans-84"/> - </defs> - <g transform="translate(139.402305 308.358437)scale(0.1 -0.1)"> + </defs> <use xlink:href="#DejaVuSans-72"/> <use x="75.195312" xlink:href="#DejaVuSans-84"/> <use x="134.529297" xlink:href="#DejaVuSans-84"/> @@ -218,8 +230,9 @@ z </g> <g id="text_3"> <!-- FTP --> - <defs> - <path d="M 9.8125 72.90625 + <g transform="translate(199.315508 308.358437)scale(0.1 -0.1)"> + <defs> + <path d="M 9.8125 72.90625 L 51.703125 72.90625 L 51.703125 64.59375 L 19.671875 64.59375 @@ -231,8 +244,7 @@ L 19.671875 0 L 9.8125 0 z " id="DejaVuSans-70"/> - </defs> - <g transform="translate(199.315508 308.358437)scale(0.1 -0.1)"> + </defs> <use xlink:href="#DejaVuSans-70"/> <use x="55.769531" xlink:href="#DejaVuSans-84"/> <use x="116.853516" xlink:href="#DejaVuSans-80"/> @@ -247,8 +259,9 @@ z </g> <g id="text_4"> <!-- NFS --> - <defs> - <path d="M 9.8125 72.90625 + <g transform="translate(254.444336 308.358437)scale(0.1 -0.1)"> + <defs> + <path d="M 9.8125 72.90625 L 23.09375 72.90625 L 55.421875 11.921875 L 55.421875 72.90625 @@ -260,8 +273,7 @@ L 19.390625 0 L 9.8125 0 z " id="DejaVuSans-78"/> - </defs> - <g transform="translate(254.444336 308.358437)scale(0.1 -0.1)"> + </defs> <use xlink:href="#DejaVuSans-78"/> <use x="74.804688" xlink:href="#DejaVuSans-70"/> <use x="130.574219" xlink:href="#DejaVuSans-83"/> @@ -276,8 +288,9 @@ z </g> <g id="text_5"> <!-- SMB --> - <defs> - <path d="M 9.8125 72.90625 + <g transform="translate(309.203632 308.358437)scale(0.1 -0.1)"> + <defs> + <path d="M 9.8125 72.90625 L 24.515625 72.90625 L 43.109375 23.296875 L 61.8125 72.90625 @@ -292,7 +305,7 @@ L 19.390625 0 L 9.8125 0 z " id="DejaVuSans-77"/> - <path d="M 19.671875 34.8125 + <path d="M 19.671875 34.8125 L 19.671875 8.109375 L 35.5 8.109375 Q 43.453125 8.109375 47.28125 11.40625 @@ -321,8 +334,7 @@ Q 48.25 0 35.984375 0 L 9.8125 0 z " id="DejaVuSans-66"/> - </defs> - <g transform="translate(309.203632 308.358437)scale(0.1 -0.1)"> + </defs> <use xlink:href="#DejaVuSans-83"/> <use x="63.476562" xlink:href="#DejaVuSans-77"/> <use x="149.755859" xlink:href="#DejaVuSans-66"/> @@ -337,15 +349,15 @@ z </g> <g id="text_6"> <!-- IPFS --> - <defs> - <path d="M 9.8125 72.90625 + <g transform="translate(365.64496 308.358437)scale(0.1 -0.1)"> + <defs> + <path d="M 9.8125 72.90625 L 19.671875 72.90625 L 19.671875 0 L 9.8125 0 z " id="DejaVuSans-73"/> - </defs> - <g transform="translate(365.64496 308.358437)scale(0.1 -0.1)"> + </defs> <use xlink:href="#DejaVuSans-73"/> <use x="29.492188" xlink:href="#DejaVuSans-80"/> <use x="89.794922" xlink:href="#DejaVuSans-70"/> @@ -355,8 +367,9 @@ z </g> <g id="text_7"> <!-- Protocole --> - <defs> - <path d="M 41.109375 46.296875 + <g transform="translate(212.936562 322.036562)scale(0.1 -0.1)"> + <defs> + <path d="M 41.109375 46.296875 Q 39.59375 47.171875 37.8125 47.578125 Q 36.03125 48 33.890625 48 Q 26.265625 48 22.1875 43.046875 @@ -372,7 +385,7 @@ Q 37.453125 56 38.578125 55.875 Q 39.703125 55.765625 41.0625 55.515625 z " id="DejaVuSans-114"/> - <path d="M 30.609375 48.390625 + <path d="M 30.609375 48.390625 Q 23.390625 48.390625 19.1875 42.75 Q 14.984375 37.109375 14.984375 27.296875 Q 14.984375 17.484375 19.15625 11.84375 @@ -393,7 +406,7 @@ Q 5.515625 40.765625 12.171875 48.375 Q 18.84375 56 30.609375 56 z " id="DejaVuSans-111"/> - <path d="M 18.3125 70.21875 + <path d="M 18.3125 70.21875 L 18.3125 54.6875 L 36.8125 54.6875 L 36.8125 47.703125 @@ -413,7 +426,7 @@ L 9.28125 54.6875 L 9.28125 70.21875 z " id="DejaVuSans-116"/> - <path d="M 48.78125 52.59375 + <path d="M 48.78125 52.59375 L 48.78125 44.1875 Q 44.96875 46.296875 41.140625 47.34375 Q 37.3125 48.390625 33.40625 48.390625 @@ -434,13 +447,13 @@ Q 37.15625 56 41.109375 55.140625 Q 45.0625 54.296875 48.78125 52.59375 z " id="DejaVuSans-99"/> - <path d="M 9.421875 75.984375 + <path d="M 9.421875 75.984375 L 18.40625 75.984375 L 18.40625 0 L 9.421875 0 z " id="DejaVuSans-108"/> - <path d="M 56.203125 29.59375 + <path d="M 56.203125 29.59375 L 56.203125 25.203125 L 14.890625 25.203125 Q 15.484375 15.921875 20.484375 11.0625 @@ -464,8 +477,7 @@ Q 24.90625 48.390625 20.390625 44.140625 Q 15.875 39.890625 15.1875 32.171875 z " id="DejaVuSans-101"/> - </defs> - <g transform="translate(212.936562 322.036562)scale(0.1 -0.1)"> + </defs> <use xlink:href="#DejaVuSans-80"/> <use x="58.552734" xlink:href="#DejaVuSans-114"/> <use x="97.416016" xlink:href="#DejaVuSans-111"/> @@ -492,8 +504,9 @@ L -3.5 0 </g> <g id="text_8"> <!-- 0 --> - <defs> - <path d="M 31.78125 66.40625 + <g transform="translate(44.2375 297.559219)scale(0.1 -0.1)"> + <defs> + <path d="M 31.78125 66.40625 Q 24.171875 66.40625 20.328125 58.90625 Q 16.5 51.421875 16.5 36.375 Q 16.5 21.390625 20.328125 13.890625 @@ -514,8 +527,7 @@ Q 6.59375 54.828125 13.0625 64.515625 Q 19.53125 74.21875 31.78125 74.21875 z " id="DejaVuSans-48"/> - </defs> - <g transform="translate(44.2375 297.559219)scale(0.1 -0.1)"> + </defs> <use xlink:href="#DejaVuSans-48"/> </g> </g> @@ -528,8 +540,9 @@ z </g> <g id="text_9"> <!-- 100 --> - <defs> - <path d="M 12.40625 8.296875 + <g transform="translate(31.5125 243.806582)scale(0.1 -0.1)"> + <defs> + <path d="M 12.40625 8.296875 L 28.515625 8.296875 L 28.515625 63.921875 L 10.984375 60.40625 @@ -542,8 +555,7 @@ L 54.390625 0 L 12.40625 0 z " id="DejaVuSans-49"/> - </defs> - <g transform="translate(31.5125 243.806582)scale(0.1 -0.1)"> + </defs> <use xlink:href="#DejaVuSans-49"/> <use x="63.623047" xlink:href="#DejaVuSans-48"/> <use x="127.246094" xlink:href="#DejaVuSans-48"/> @@ -558,8 +570,9 @@ z </g> <g id="text_10"> <!-- 200 --> - <defs> - <path d="M 19.1875 8.296875 + <g transform="translate(31.5125 190.053945)scale(0.1 -0.1)"> + <defs> + <path d="M 19.1875 8.296875 L 53.609375 8.296875 L 53.609375 0 L 7.328125 0 @@ -583,8 +596,7 @@ Q 44.1875 33.984375 37.640625 27.21875 Q 31.109375 20.453125 19.1875 8.296875 z " id="DejaVuSans-50"/> - </defs> - <g transform="translate(31.5125 190.053945)scale(0.1 -0.1)"> + </defs> <use xlink:href="#DejaVuSans-50"/> <use x="63.623047" xlink:href="#DejaVuSans-48"/> <use x="127.246094" xlink:href="#DejaVuSans-48"/> @@ -599,8 +611,9 @@ z </g> <g id="text_11"> <!-- 300 --> - <defs> - <path d="M 40.578125 39.3125 + <g transform="translate(31.5125 136.301309)scale(0.1 -0.1)"> + <defs> + <path d="M 40.578125 39.3125 Q 47.65625 37.796875 51.625 33 Q 55.609375 28.21875 55.609375 21.1875 Q 55.609375 10.40625 48.1875 4.484375 @@ -632,8 +645,7 @@ Q 53.90625 49.265625 50.4375 45.09375 Q 46.96875 40.921875 40.578125 39.3125 z " id="DejaVuSans-51"/> - </defs> - <g transform="translate(31.5125 136.301309)scale(0.1 -0.1)"> + </defs> <use xlink:href="#DejaVuSans-51"/> <use x="63.623047" xlink:href="#DejaVuSans-48"/> <use x="127.246094" xlink:href="#DejaVuSans-48"/> @@ -648,8 +660,9 @@ z </g> <g id="text_12"> <!-- 400 --> - <defs> - <path d="M 37.796875 64.3125 + <g transform="translate(31.5125 82.548672)scale(0.1 -0.1)"> + <defs> + <path d="M 37.796875 64.3125 L 12.890625 25.390625 L 37.796875 25.390625 z @@ -666,8 +679,7 @@ L 4.890625 17.1875 L 4.890625 26.703125 z " id="DejaVuSans-52"/> - </defs> - <g transform="translate(31.5125 82.548672)scale(0.1 -0.1)"> + </defs> <use xlink:href="#DejaVuSans-52"/> <use x="63.623047" xlink:href="#DejaVuSans-48"/> <use x="127.246094" xlink:href="#DejaVuSans-48"/> @@ -676,8 +688,9 @@ z </g> <g id="text_13"> <!-- Durée (secondes) --> - <defs> - <path d="M 19.671875 64.796875 + <g transform="translate(25.432812 211.735531)rotate(-90)scale(0.1 -0.1)"> + <defs> + <path d="M 19.671875 64.796875 L 19.671875 8.109375 L 31.59375 8.109375 Q 46.6875 8.109375 53.6875 14.9375 @@ -694,7 +707,7 @@ Q 51.171875 0 30.078125 0 L 9.8125 0 z " id="DejaVuSans-68"/> - <path d="M 8.5 21.578125 + <path d="M 8.5 21.578125 L 8.5 54.6875 L 17.484375 54.6875 L 17.484375 21.921875 @@ -715,7 +728,7 @@ z M 31.109375 56 z " id="DejaVuSans-117"/> - <path d="M 56.203125 29.59375 + <path d="M 56.203125 29.59375 L 56.203125 25.203125 L 14.890625 25.203125 Q 15.484375 15.921875 20.484375 11.0625 @@ -744,8 +757,8 @@ L 32.375 61.625 L 24.90625 61.625 z " id="DejaVuSans-233"/> - <path id="DejaVuSans-32"/> - <path d="M 31 75.875 + <path id="DejaVuSans-32"/> + <path d="M 31 75.875 Q 24.46875 64.65625 21.28125 53.65625 Q 18.109375 42.671875 18.109375 31.390625 Q 18.109375 20.125 21.3125 9.0625 @@ -757,7 +770,7 @@ Q 8.59375 42.28125 12.203125 53.3125 Q 15.828125 64.359375 23.1875 75.875 z " id="DejaVuSans-40"/> - <path d="M 44.28125 53.078125 + <path d="M 44.28125 53.078125 L 44.28125 44.578125 Q 40.484375 46.53125 36.375 47.5 Q 32.28125 48.484375 27.875 48.484375 @@ -788,7 +801,7 @@ Q 31.78125 56 36.171875 55.265625 Q 40.578125 54.546875 44.28125 53.078125 z " id="DejaVuSans-115"/> - <path d="M 54.890625 33.015625 + <path d="M 54.890625 33.015625 L 54.890625 0 L 45.90625 0 L 45.90625 32.71875 @@ -807,7 +820,7 @@ Q 45.21875 56 50.046875 50.171875 Q 54.890625 44.34375 54.890625 33.015625 z " id="DejaVuSans-110"/> - <path d="M 45.40625 46.390625 + <path d="M 45.40625 46.390625 L 45.40625 75.984375 L 54.390625 75.984375 L 54.390625 0 @@ -833,7 +846,7 @@ Q 22.953125 48.484375 18.875 42.84375 Q 14.796875 37.203125 14.796875 27.296875 z " id="DejaVuSans-100"/> - <path d="M 8.015625 75.875 + <path d="M 8.015625 75.875 L 15.828125 75.875 Q 23.140625 64.359375 26.78125 53.3125 Q 30.421875 42.28125 30.421875 31.390625 @@ -846,8 +859,7 @@ Q 20.90625 42.671875 17.703125 53.65625 Q 14.5 64.65625 8.015625 75.875 z " id="DejaVuSans-41"/> - </defs> - <g transform="translate(25.432812 211.735531)rotate(-90)scale(0.1 -0.1)"> + </defs> <use xlink:href="#DejaVuSans-68"/> <use x="77.001953" xlink:href="#DejaVuSans-117"/> <use x="140.380859" xlink:href="#DejaVuSans-114"/> diff --git a/doc/gitlab-markdown.gpp b/doc/gitlab-markdown.gpp index fd14f13cb767b7523a9b750c04663c1f38553056..69b76fe1decd933a904180427967c40a2023290c 100644 --- a/doc/gitlab-markdown.gpp +++ b/doc/gitlab-markdown.gpp @@ -62,4 +62,8 @@ !!define{!!label{ref_id}}{} -!!define{!!ref{ref_id}}{} \ No newline at end of file +!!define{!!ref{ref_id}}{} + +!!define{!!cite{citation_id}}{} + +!!define{!!citelong{citation_content}}{} \ No newline at end of file diff --git a/doc/iso690.csl b/doc/iso690.csl new file mode 100644 index 0000000000000000000000000000000000000000..93cca47ed37c6963ddc6ecb0966e8393d2b9e870 --- /dev/null +++ b/doc/iso690.csl @@ -0,0 +1,493 @@ +<?xml version="1.0" encoding="utf-8"?> +<style xmlns="http://purl.org/net/xbiblio/csl" class="in-text" version="1.0" demote-non-dropping-particle="never" default-locale="fr-FR"> + <info> + <title>ISO-690 (numeric, French)</title> + <id>http://www.zotero.org/styles/iso690-numeric-fr</id> + <link href="http://www.zotero.org/styles/iso690-numeric-fr" rel="self"/> + <link href="https://forums.zotero.org/discussion/23511" rel="documentation"/> + <author> + <name>Laure Mellifluo</name> + <email>laure.melli@gmail.com</email> + </author> + <author> + <name>Raphael Grolimund</name> + <email>raphael.grolimund@epfl.ch</email> + </author> + <author> + <name>Michel Hardegger</name> + <email>hardegger@gmail.com</email> + </author> + <category citation-format="numeric"/> + <category field="generic-base"/> + <summary>Style based on ISO 690:2010(F), V1.1</summary> + <updated>2015-01-22T16:03:28+00:00</updated> + <rights license="http://creativecommons.org/licenses/by-sa/3.0/">This work is licensed under a Creative Commons Attribution-ShareAlike 3.0 License</rights> + </info> + <locale> + <terms> + <term name="no date">[sans date]</term> + <term name="in">in</term> + <term name="online">en ligne</term> + <term name="accessed">consulté le</term> + <term name="retrieved">disponible</term> + <term name="from">à l'adresse</term> + </terms> + </locale> + <macro name="author"> + <names variable="author"> + <name and="text" name-as-sort-order="all" sort-separator=", " delimiter=", " delimiter-precedes-last="never"> + <name-part name="family" text-case="uppercase"/> + <name-part name="given"/> + </name> + </names> + </macro> + <macro name="editor"> + <names variable="editor"> + <name and="text" name-as-sort-order="all" sort-separator=", " delimiter=", " delimiter-precedes-last="never"> + <name-part name="family" text-case="uppercase"/> + <name-part name="given"/> + </name> + <label prefix=" (" form="short" suffix=".)"/> + </names> + </macro> + <macro name="translator"> + <names variable="translator"> + <name and="text" name-as-sort-order="all" sort-separator=", " delimiter=", " delimiter-precedes-last="never"> + <name-part name="family" text-case="uppercase"/> + <name-part name="given"/> + </name> + <label prefix=" (" form="short" suffix=".)"/> + </names> + </macro> + <macro name="responsability"> + <choose> + <if variable="author editor translator" match="any"> + <choose> + <if variable="author"> + <text macro="author"/> + </if> + <else-if variable="editor"> + <text macro="editor"/> + </else-if> + <else> + <text macro="translator"/> + </else> + </choose> + </if> + </choose> + </macro> + <macro name="container-author"> + <names variable="container-author"> + <name and="text" name-as-sort-order="all" sort-separator=", " delimiter=", " delimiter-precedes-last="never"> + <name-part name="family" text-case="uppercase"/> + <name-part name="given"/> + </name> + </names> + </macro> + <macro name="container-responsability"> + <choose> + <if variable="container-author editor translator" match="any"> + <choose> + <if variable="container-author"> + <text macro="container-author"/> + </if> + <else-if variable="editor"> + <text macro="editor"/> + </else-if> + <else> + <text macro="translator"/> + </else> + </choose> + </if> + </choose> + </macro> + <macro name="year-date"> + <choose> + <if variable="issued"> + <date variable="issued"> + <date-part name="year" form="long"/> + </date> + </if> + <else> + <text term="no date"/> + </else> + </choose> + </macro> + <macro name="title"> + <choose> + <if type="book thesis map motion_picture song manuscript" match="any"> + <text variable="title" font-style="italic"/> + </if> + <else-if type="paper-conference speech chapter article-journal article-magazine article-newspaper entry entry-dictionary entry-encyclopedia post-weblog post webpage broadcast" match="any"> + <text variable="title" suffix=". "/> + <choose> + <if type="chapter paper-conference" match="any"> + <text term="in" text-case="capitalize-first" suffix=" : "/> + </if> + </choose> + <choose> + <if variable="container-author editor translator" match="any"> + <text macro="container-responsability"/> + <choose> + <if variable="container-title event" match="any"> + <text value=", "/> + </if> + </choose> + </if> + </choose> + <choose> + <if variable="container-title"> + <text variable="container-title" font-style="italic"/> + </if> + <else> + <text variable="event" font-style="italic"/> + </else> + </choose> + </else-if> + <else-if type="report"> + <text variable="number" suffix=": "/> + <text variable="title" font-style="italic"/> + </else-if> + <else-if type="patent"> + <text variable="title"/> + </else-if> + <else> + <text variable="title" font-style="italic"/> + </else> + </choose> + <choose> + <if variable="URL"> + <text term="online" prefix=" [" suffix="]"/> + </if> + </choose> + </macro> + <macro name="number"> + <text variable="number"/> + </macro> + <macro name="medium"> + <text variable="medium" prefix=" [" suffix="]"/> + </macro> + <macro name="genre"> + <choose> + <if type="map"> + <choose> + <if variable="genre"> + <text variable="genre" prefix="[" suffix="]"/> + </if> + <else> + <text value="carte" prefix="[" suffix="]"/> + </else> + </choose> + </if> + <else> + <text variable="genre"/> + </else> + </choose> + </macro> + <macro name="date"> + <choose> + <if variable="issued"> + <date variable="issued"> + <date-part name="day" suffix=" "/> + <date-part name="month" suffix=" "/> + <date-part name="year"/> + </date> + </if> + </choose> + </macro> + <macro name="edition"> + <text variable="edition" form="long"/> + </macro> + <macro name="publisher-group"> + <group delimiter=" : "> + <text variable="publisher-place"/> + <text variable="publisher"/> + </group> + </macro> + <macro name="issue"> + <group delimiter=", "> + <text variable="volume" prefix="Vol. "/> + <choose> + <if variable="volume"> + <text variable="issue" prefix="n° "/> + <text variable="page" prefix="pp. "/> + </if> + <else-if variable="issue"> + <text variable="issue" prefix="N° "/> + <text variable="page" prefix="pp. "/> + </else-if> + <else> + <text variable="page" prefix="pp. "/> + </else> + </choose> + </group> + </macro> + <macro name="accessed"> + <choose> + <if variable="URL"> + <group prefix=" [" suffix="]"> + <text term="accessed" text-case="capitalize-first"/> + <date variable="accessed"> + <date-part name="day" prefix=" "/> + <date-part name="month" prefix=" "/> + <date-part name="year" prefix=" "/> + </date> + </group> + </if> + </choose> + </macro> + <macro name="collection"> + <group delimiter=", "> + <text variable="collection-title"/> + <text variable="collection-number"/> + </group> + </macro> + <macro name="page"> + <choose> + <if type="book thesis manuscript" match="any"> + <text variable="number-of-pages" suffix=" p"/> + </if> + <else-if type="chapter paper-conference article-newspaper" match="any"> + <text variable="page" prefix="pp. "/> + </else-if> + <else-if type="report patent" match="any"> + <text variable="page" suffix=" p"/> + </else-if> + </choose> + </macro> + <macro name="isbn"> + <text variable="ISBN" prefix="ISBN "/> + </macro> + <macro name="doi"> + <text variable="DOI" prefix="DOI "/> + </macro> + <macro name="url"> + <choose> + <if variable="URL"> + <group> + <text term="retrieved" suffix=" " text-case="capitalize-first"/> + <text term="from" suffix=" : "/> + <text variable="URL"/> + </group> + </if> + </choose> + </macro> + <macro name="archive"> + <group delimiter=": "> + <text variable="archive"/> + <text macro="archive_location"/> + </group> + </macro> + <macro name="archive_location"> + <choose> + <if variable="archive_location"> + <text variable="archive_location"/> + </if> + <else> + <text variable="call-number"/> + </else> + </choose> + </macro> + <macro name="abstract"> + <text variable="abstract"/> + </macro> + <macro name="note"> + <text variable="note"/> + </macro> + <citation collapse="citation-number" after-collapse-delimiter="; "> + <sort> + <key variable="citation-number"/> + </sort> + <layout prefix="(" suffix=")" delimiter=", "> + <group delimiter=", "> + <text variable="citation-number"/> + <group> + <label variable="locator" suffix=". " form="short" strip-periods="true"/> + <text variable="locator"/> + </group> + </group> + </layout> + </citation> + <bibliography> + <sort> + <key variable="citation-number"/> + </sort> + <layout> + <text variable="citation-number" display="left-margin" font-weight="bold" suffix=". "/> + <choose> + <if type="book map" match="any"> + <group display="right-inline"> + <text macro="responsability" suffix=". "/> + <text macro="title" suffix=". "/> + <text macro="genre" suffix=". "/> + <text macro="edition" suffix=". "/> + <text macro="publisher-group" suffix=", "/> + <text macro="year-date" suffix=". "/> + <text macro="accessed" suffix=". "/> + <text macro="collection" suffix=". "/> + <text macro="isbn" suffix=". "/> + <text macro="url"/> + </group> + </if> + <else-if type="article-journal article-magazine" match="any"> + <group display="right-inline"> + <text macro="responsability" suffix=". "/> + <text macro="title" suffix=". "/> + <text macro="edition" suffix=". "/> + <text macro="date" suffix=". "/> + <text macro="issue" suffix=". "/> + <text macro="accessed" suffix=". "/> + <text macro="doi" suffix=". "/> + <text macro="url"/> + </group> + </else-if> + <else-if type="article-newspaper"> + <group display="right-inline"> + <text macro="responsability" suffix=". "/> + <text macro="title" suffix=". "/> + <text macro="edition" suffix=". "/> + <text macro="publisher-group" suffix=", "/> + <text macro="date" suffix=". "/> + <text macro="page" suffix=". "/> + <text macro="accessed" suffix=". "/> + <text macro="url"/> + </group> + </else-if> + <else-if type="chapter entry entry-dictionary entry-encyclopedia" match="any"> + <group display="right-inline"> + <text macro="responsability" suffix=". "/> + <text macro="title" font-style="normal" suffix=". "/> + <text macro="edition" suffix=". "/> + <text macro="publisher-group" suffix=", "/> + <text macro="year-date" suffix=". "/> + <text macro="page" suffix=". "/> + <text macro="collection" suffix=". "/> + <text macro="accessed" suffix=". "/> + <text macro="isbn" suffix=". "/> + <text macro="url"/> + </group> + </else-if> + <else-if type="speech"> + <group display="right-inline"> + <text macro="responsability" suffix=". "/> + <text macro="title" suffix=". "/> + <text macro="genre" suffix=". "/> + <text macro="publisher-group" suffix=". "/> + <text macro="date" suffix=". "/> + <text macro="accessed" suffix=". "/> + <text macro="page" suffix=". "/> + <text macro="url"/> + </group> + </else-if> + <else-if type="paper-conference"> + <group display="right-inline"> + <text macro="responsability" suffix=". "/> + <text macro="title" suffix=". "/> + <text macro="genre" suffix=". "/> + <text macro="publisher-group" suffix=", "/> + <text macro="date" suffix=". "/> + <text macro="page" suffix=". "/> + <text macro="accessed" suffix=". "/> + <text macro="collection" suffix=". "/> + <text macro="isbn" suffix=". "/> + <text macro="url"/> + </group> + </else-if> + <else-if type="thesis"> + <group display="right-inline"> + <text macro="responsability" suffix=". "/> + <text macro="title" suffix=". "/> + <text macro="genre" suffix=". "/> + <text macro="publisher-group" suffix=", "/> + <text macro="year-date" suffix=". "/> + <text macro="accessed" suffix=". "/> + <text macro="url"/> + </group> + </else-if> + <else-if type="post-weblog post webpage" match="any"> + <group display="right-inline"> + <text macro="responsability" suffix=". "/> + <text macro="title" suffix=". "/> + <text macro="date" suffix=". "/> + <text macro="accessed" suffix=". "/> + <text macro="url"/> + </group> + </else-if> + <else-if type="broadcast motion_picture song" match="any"> + <group display="right-inline"> + <text macro="responsability" suffix=". "/> + <text macro="title" suffix=". "/> + <text macro="medium" suffix=". "/> + <text macro="publisher-group" suffix=", "/> + <text macro="date" suffix=". "/> + <text macro="accessed" suffix=". "/> + <text macro="collection" suffix=". "/> + <text macro="isbn" suffix=". "/> + <text macro="url"/> + </group> + </else-if> + <else-if type="report" match="any"> + <group display="right-inline"> + <text macro="responsability" suffix=". "/> + <text macro="title" suffix=". "/> + <text macro="genre" suffix=". "/> + <text macro="edition" suffix=". "/> + <text macro="publisher-group" suffix=", "/> + <text macro="year-date" suffix=". "/> + <text macro="accessed" suffix=". "/> + <text macro="collection" suffix=". "/> + <text macro="url"/> + </group> + </else-if> + <else-if type="manuscript" match="any"> + <group display="right-inline"> + <text macro="responsability" suffix=". "/> + <text macro="title" suffix=". "/> + <text macro="genre" suffix=". "/> + <text macro="edition" suffix=". "/> + <text macro="publisher-group" suffix=", "/> + <text macro="year-date" suffix=". "/> + <text macro="accessed" suffix=". "/> + <text macro="collection" suffix=". "/> + <text macro="url"/> + </group> + </else-if> + <else-if type="patent"> + <group display="right-inline"> + <text macro="responsability" suffix=". "/> + <text macro="title" suffix=". "/> + <text macro="number" suffix=". "/> + <text macro="date" suffix=". "/> + <text macro="publisher-group" suffix=". "/> + <text macro="accessed" suffix=". "/> + <text macro="collection" suffix=". "/> + <text macro="url"/> + </group> + </else-if> + <else> + <group display="right-inline"> + <text macro="responsability" suffix=". "/> + <text macro="title" suffix=". "/> + <text macro="medium" suffix=". "/> + <text macro="genre" suffix=". "/> + <text macro="date" suffix=". "/> + <text macro="edition" suffix=". "/> + <text macro="publisher-group" suffix=". "/> + <text macro="number" suffix=". "/> + <text macro="accessed" suffix=". "/> + <text macro="collection" suffix=". "/> + <text macro="page" suffix=". "/> + <text macro="isbn" suffix=". "/> + <text macro="url"/> + </group> + </else> + </choose> + <group display="right-inline"> + <text macro="archive"/> + </group> + <group display="right-inline"> + <text macro="note"/> + </group> + </layout> + </bibliography> +</style> diff --git a/doc/pandoc-pdf-markdown.gpp b/doc/pandoc-pdf-markdown.gpp index f2b2e18fc05e3862e5d5af8651a78b5630c37290..dd5fc5b3af75d37011b8dc750b135ed271ca4002 100644 --- a/doc/pandoc-pdf-markdown.gpp +++ b/doc/pandoc-pdf-markdown.gpp @@ -41,3 +41,7 @@ !!define{!!tableheader{ref_id}{description}}{ Table: !!description \label{!!ref_id} } + +!!define{!!cite{citation_id}}{[@@!!citation_id]} + +!!define{!!citelong{citation_content}}{[!!citation_content]} \ No newline at end of file diff --git a/doc/rapport.gpp.md b/doc/rapport.gpp.md index 179a3f45093272650f679aa860649be34e4cdcea..3192f4005699d24dd5f42eda9b6385d3640e3279 100644 --- a/doc/rapport.gpp.md +++ b/doc/rapport.gpp.md @@ -18,6 +18,11 @@ numbersections: true fontsize: 12pt monofont: JetBrains Mono output: pdf_document +filters: +- pandoc-citeproc +bibliography: references.bib +csl: iso690.csl +link-citations: true header-includes: | \usepackage{pdfpages} \usepackage{fancyhdr} @@ -44,7 +49,7 @@ header-includes: | \setlength{\parindent}{0pt} \setlength{\parskip}{9pt} - \setlength{\beforechapskip}{0pt} + \setlength{\beforechapskip}{-10pt} \OnehalfSpacing --- @@ -62,7 +67,8 @@ header-includes: | !!defacronym{FTP}{_File Transfer Protocol_: protocole de transfert de fichier} !!defacronym{GPT}{_GUID Partition Table_: table de partitionnement GUID} !!defacronym{GRUB}{_GRand Unified Bootloader_} -!!defacronym{HEPIA}{Haute école du paysage, d'ingénierie et d'architecture de Genève} +!!defacronym{HEPIA}{Haute École du Paysage, d'Ingénierie et d'Architecture de Genève} +!!defacronym{HES}{Haute École Spécialisée} !!defacronym{HTTPS}{_HyperText Transfer Protocol Secure_: protocole de transfert hypertexte sécurisé} !!defacronym{HTTP}{_HyperText Transfer Protocol_: protocole de transfert hypertexte} !!defacronym{IBM}{_International Business Machines corporation_} @@ -78,6 +84,7 @@ header-includes: | !!defacronym{PC}{_Personal Computer_: ordinateur personnel} !!defacronym{PXE}{_Pre-boot eXecution Environment_: environnement d'exécution pré-démarrage} !!defacronym{SCP}{_Secure CoPy_: protocole de copie sécurisée sur le réseau} +!!defacronym{SI}{Système d'Information} !!defacronym{SMB}{_Server Message Block_} !!defacronym{SSH}{_Secure SHell_: protocole de terminal à distance securisé} !!defacronym{TFTP}{_Trivial File Transfer Protocol_: protocole simplifié de transfert de fichiers} @@ -89,7 +96,20 @@ header-includes: | !!chapterwithoutnumber{Remerciements} -**TODO: remerciements** +Je souhaite remercier **Florent Glück**, professeur !!acronym{HES} +associé à !!acronym{HEPIA}, ainsi que **Sébastien Chassot**, assistant +!!acronym{HES} à !!acronym{HEPIA} pour leur implication et leur aide +précieuse apportée lors des rendez-vous hebdomadaire de suivi de ce +projet. + +Je souhaite également remercier ma compagne, **Nathalie Sieber**, pour +son soutien, sa patience et sa confiance, tout au long de mon cursus à +!!acronym{HEPIA}. + +Enfin, je souhaite remercier mes parents, Cristina Lizzi et Enzo Zonca +pour m'avoir fait découvrir le monde de l'informatique quand j'étais +petit et m'avoir toujours encouragé et aidé à poursuivre mes études dans +ce domaine. !!ifdef{PANDOC_PDF} \addcontentsline{toc}{chapter}{Résumé} @@ -111,6 +131,9 @@ header-includes: | ## Contexte +Le contexte du projet, tiré de l´énoncé de ce dernier +!!cite{gluck_enonce_2020}, est le suivant: + Aujourd’hui les machines des salles de cours à !!acronym{HEPIA} sont installées avec une image spécifique d’un système d’exploitation. Dans le cadre de certains cours, on désirerait pouvoir utiliser un autre @@ -131,6 +154,9 @@ d’un travail déjà existant. ## Objectifs +Les objectifs du projet, tirés de l´énoncé de ce dernier +!!cite{gluck_enonce_2020}, sont les suivants: + - Etude du travail existant. - Mise en place d’un déploiement automatisé et reproductible du travail existant. @@ -221,16 +247,19 @@ projet _Bootiful_. Il permet aux postes clients de lancer un mini système d'exploitation via !!acronym{PXE} au démarrage de la machine. Ce mini-système permet de télécharger et déployer des images de système d'exploitation sur la machine, tout en créant une copie en cache à la -fin du disque pour éviter de la télécharger plusieurs fois. +fin du disque pour éviter de la télécharger plusieurs fois +!!cite{bpbatch_homepage}. La première version, nommée _BpBatch_ fut distribuée gratuitement sur internet. Une entreprise nommée _Rembo Technology Sàrl_ a ensuite été -fondée en 1999 pour continuer un développement commercial de ce projet -sous le nom de _Rembo_. En 2006, la société a été rachetée par IBM et le -projet a été intégré à leur solution _Tivoli Provisionning Manager_. - -Ce système réponde aux besoins de !!acronym{HEPIA}, et il a même déjà -été utilisé au sein de l'institution par le passé. Il a cependant été +fondée en 1999 !!cite{registre_commerce_rembo} pour continuer un +développement commercial de ce projet sous le nom de _Rembo_. En 2006, +la société a été rachetée par IBM !!cite{registre_commerce_rembo} et le +projet a été intégré à leur solution _Tivoli Provisionning Manager_ +!!cite{ibm_rembo}. + +Ce système répond aux besoins de !!acronym{HEPIA}, et il a même déjà été +utilisé au sein de l'institution par le passé. Il a cependant été abandonné à cause de sa licence devenue très couteuse et de sa complexité devenue trop grande pour les besoins simple de l'école. @@ -242,6 +271,7 @@ intéressante. !!acronym{FOG} est une solution open-source gratuite permettant de déployer des images de systèmes d'exploitation sur des postes clients. +!!cite{fog_wiki_intro} Elle fonctionne avec une architecture client-serveur. Le serveur est accédé par une interface web, où un administrateur peut gérer ses images @@ -267,7 +297,7 @@ nouveau depuis le serveur, ce qui peut prendre beaucoup de temps et doit ### Clonezilla _Clonezilla_ est une solution open-source et gratuite de création et de -restauration d'images. +restauration d'images. !!cite{clonezilla_home} Cet outil peut être utilisé de deux manières: @@ -302,10 +332,11 @@ déploiement. Cette possibilité sera étudiée plus tard dans ce document. # Architecture initiale du projet Le projet _Bootiful_ n'a pas été initié dans le cadre de ce travail de -bachelor: une implémentation basique avait déjà été réalisée afin de -prouver que l'idée fonctionne. Cette version initiale a été créée par -Abhilash Venkatesh, un étudiant indien qui est venu à !!acronym{HEPIA} -effectuer un stage pendant la période de mai à juillet 2019. +bachelor: une implémentation basique !!cite{venkatesh_remote_imaging} +avait déjà été réalisée afin de prouver que l'idée fonctionne. Cette +version initiale a été créée par Abhilash Venkatesh, un étudiant indien +qui est venu à !!acronym{HEPIA} effectuer un stage pendant la période de +mai à juillet 2019. Les premières étapes de ce travail diplôme ont été de reproduire le système réalisé dans le projet initial afin de valider son @@ -2027,9 +2058,11 @@ avancés (_sIT_384_), programmation avancée des systèmes (_sIT_632_) et virtualisation des !!acronym{SI} (_sIT_632_). !!ifdef{PANDOC_PDF} -# Références -**TODO: add references** +!!chapterwithoutnumber{Références} + +::: {#refs} +::: \appendix !!endif diff --git a/doc/rapport.md b/doc/rapport.md index 163744a52ec5a1aad9d711d7caaf579da4f86a9c..2d8209a59b7c2b3723f521f367b36ab62e469922 100644 --- a/doc/rapport.md +++ b/doc/rapport.md @@ -61,6 +61,8 @@ - **SCP**: _Secure CoPy_: protocole de copie sécurisée sur le réseau +- **SI**: Système d'Information + - **SMB**: _Server Message Block_ - **SSH**: _Secure SHell_: protocole de terminal à distance securisé @@ -84,6 +86,9 @@ ## Contexte +Le contexte du projet, tiré de l´énoncé de ce dernier +, est le suivant: + Aujourd’hui les machines des salles de cours à <abbr title="Haute école du paysage, d’ingénierie et d’architecture de Genève ">HEPIA</abbr> sont installées avec une image spécifique d’un système d’exploitation. Dans le cadre de certains cours, on désirerait pouvoir utiliser un autre @@ -104,6 +109,9 @@ d’un travail déjà existant. ## Objectifs +Les objectifs du projet, tirés de l´énoncé de ce dernier +, sont les suivants: + - Etude du travail existant. - Mise en place d’un déploiement automatisé et reproductible du travail existant. @@ -208,16 +216,19 @@ projet _Bootiful_. Il permet aux postes clients de lancer un mini système d'exploitation via <abbr title="Pre-boot eXecution Environment: environnement d’exécution pré-démarrage ">PXE</abbr> au démarrage de la machine. Ce mini-système permet de télécharger et déployer des images de système d'exploitation sur la machine, tout en créant une copie en cache à la -fin du disque pour éviter de la télécharger plusieurs fois. +fin du disque pour éviter de la télécharger plusieurs fois +. La première version, nommée _BpBatch_ fut distribuée gratuitement sur internet. Une entreprise nommée _Rembo Technology Sàrl_ a ensuite été -fondée en 1999 pour continuer un développement commercial de ce projet -sous le nom de _Rembo_. En 2006, la société a été rachetée par IBM et le -projet a été intégré à leur solution _Tivoli Provisionning Manager_. +fondée en 1999 pour continuer un +développement commercial de ce projet sous le nom de _Rembo_. En 2006, +la société a été rachetée par IBM et le +projet a été intégré à leur solution _Tivoli Provisionning Manager_ +. -Ce système réponde aux besoins de <abbr title="Haute école du paysage, d’ingénierie et d’architecture de Genève ">HEPIA</abbr>, et il a même déjà -été utilisé au sein de l'institution par le passé. Il a cependant été +Ce système répond aux besoins de <abbr title="Haute école du paysage, d’ingénierie et d’architecture de Genève ">HEPIA</abbr>, et il a même déjà été +utilisé au sein de l'institution par le passé. Il a cependant été abandonné à cause de sa licence devenue très couteuse et de sa complexité devenue trop grande pour les besoins simple de l'école. @@ -230,6 +241,7 @@ intéressante. <abbr title="Free Open-source Ghost ">FOG</abbr> est une solution open-source gratuite permettant de déployer des images de systèmes d'exploitation sur des postes clients. + Elle fonctionne avec une architecture client-serveur. Le serveur est accédé par une interface web, où un administrateur peut gérer ses images et les déployer sur des clients qui démarrent un logiciel de déploiement @@ -254,7 +266,7 @@ nouveau depuis le serveur, ce qui peut prendre beaucoup de temps et doit ### Clonezilla _Clonezilla_ est une solution open-source et gratuite de création et de -restauration d'images. +restauration d'images. Cet outil peut être utilisé de deux manières: @@ -289,10 +301,11 @@ déploiement. Cette possibilité sera étudiée plus tard dans ce document. # Architecture initiale du projet Le projet _Bootiful_ n'a pas été initié dans le cadre de ce travail de -bachelor: une implémentation basique avait déjà été réalisée afin de -prouver que l'idée fonctionne. Cette version initiale a été créée par -Abhilash Venkatesh, un étudiant indien qui est venu à <abbr title="Haute école du paysage, d’ingénierie et d’architecture de Genève ">HEPIA</abbr> -effectuer un stage pendant la période de mai à juillet 2019. +bachelor: une implémentation basique +avait déjà été réalisée afin de prouver que l'idée fonctionne. Cette +version initiale a été créée par Abhilash Venkatesh, un étudiant indien +qui est venu à <abbr title="Haute école du paysage, d’ingénierie et d’architecture de Genève ">HEPIA</abbr> effectuer un stage pendant la période de +mai à juillet 2019. Les premières étapes de ce travail diplôme ont été de reproduire le système réalisé dans le projet initial afin de valider son @@ -2137,7 +2150,7 @@ suivis les quatre années précédentes, dont en particulier les cours de programmation des systèmes (_sIT_242_), systèmes d'exploitation (_sIT_244_), réseaux et protocoles informatiques (sIT_362), réseaux avancés (_sIT_384_), programmation avancée des systèmes (_sIT_632_) et -virtualisation des <abbr title=" ">SI</abbr> (_sIT_632_). +virtualisation des <abbr title="Système d’Information ">SI</abbr> (_sIT_632_). diff --git a/doc/rapport.pdf b/doc/rapport.pdf index 63c0b86d133ed20c40fba24a10b7ec7ee8ca9fbb..3c14f1fd62f75188d65774567252da9bc0efde8b 100644 Binary files a/doc/rapport.pdf and b/doc/rapport.pdf differ diff --git a/doc/rapport.tex b/doc/rapport.tex index e51283ea6342d5309da407edae4c7927a84d46c8..19a3c6b53d30a3eafeb71e8cb9fa21b62bac2e9c 100644 --- a/doc/rapport.tex +++ b/doc/rapport.tex @@ -18,6 +18,7 @@ \usepackage{unicode-math} \defaultfontfeatures{Scale=MatchLowercase} \defaultfontfeatures[\rmfamily]{Ligatures=TeX,Scale=1} + \setmonofont[]{JetBrains Mono} \fi % Use upquote if available, for straight quotes in verbatim environments \IfFileExists{upquote.sty}{\usepackage{upquote}}{} @@ -39,14 +40,14 @@ \IfFileExists{xurl.sty}{\usepackage{xurl}}{} % add URL line breaks if available \IfFileExists{bookmark.sty}{\usepackage{bookmark}}{\usepackage{hyperref}} \hypersetup{ - pdftitle={Bootiful Déploiement d'OS à choix durant le processus de boot}, + pdftitle={Bootiful}, pdfauthor={Dimitri Lizzi}, pdflang={fr-CH}, pdfkeywords={Bachelor, HEPIA, HESSO, Bootiful}, hidelinks, pdfcreator={LaTeX via pandoc}} \urlstyle{same} % disable monospaced font for URLs -\usepackage[margin=2.5cm,includefoot,includehead]{geometry} +\usepackage[includeheadfoot,margin=2.5cm]{geometry} \usepackage{color} \usepackage{fancyvrb} \newcommand{\VerbBar}{|} @@ -117,7 +118,7 @@ \usepackage{float} \usepackage{lastpage} \usepackage{fvextra} -\DefineVerbatimEnvironment{Highlighting}{Verbatim}{frame=single,breaklines,commandchars=\\\{\}} +\DefineVerbatimEnvironment{Highlighting}{Verbatim}{frame=single,breaklines,commandchars=\\\{\},fontsize=\footnotesize} \pagestyle{fancy} \setlength{\headheight}{14pt} @@ -129,7 +130,6 @@ \fancyhead[CO,CE]{Déploiement d'OS à choix durant le processus de boot} \fancyhead[RO,RE]{Dimitri Lizzi} \fancyfoot[LO,LE]{août 2020} - \fancyfoot[CO,CE]{} \fancyfoot[RE,RO]{\thepage /\pageref{LastPage}} @@ -137,6 +137,7 @@ \setlength{\parindent}{0pt} \setlength{\parskip}{9pt} +\setlength{\beforechapskip}{-10pt} \OnehalfSpacing \ifxetex @@ -146,9 +147,20 @@ \else \usepackage[shorthands=off,main=french]{babel} \fi +\newlength{\cslhangindent} +\setlength{\cslhangindent}{1.5em} +\newenvironment{cslreferences}% + {}% + {\par} -\title{Bootiful\\ -Déploiement d'OS à choix durant le processus de boot} +\title{Bootiful} +\usepackage{etoolbox} +\makeatletter +\providecommand{\subtitle}[1]{% add subtitle to \maketitle + \apptocmd{\@title}{\par {\large #1 \par}}{}{} +} +\makeatother +\subtitle{Déploiement d'OS à choix durant le processus de boot} \author{Dimitri Lizzi} \date{Août 2020} @@ -158,37 +170,36 @@ Déploiement d'OS à choix durant le processus de boot} \renewcommand*\listtablename{Liste des tableaux} % Sets the page numbering style to roman %\pagestyle{headings} -\setcounter{page}{1} -\pagenumbering{roman} +%\setcounter{page}{1} +%\pagenumbering{roman} % Hides the page number for the cover page \thispagestyle{empty} +\addtolength{\voffset}{-5pt} % Hides the header for the cover page % Cover page \begin{figure} + \vspace*{-5cm} \begin{sffamily} \begin{minipage}{.4\textwidth} \centering - \hspace*{-3cm}\includegraphics[height=2cm,bb=0 0 278.9 70.92]{images/logo_hepia.svg} + \hspace*{-3cm}\includegraphics[height=1.25cm]{images/logo_hepia.pdf} \end{minipage}\qquad \begin{minipage}{.4\textwidth} \centering - \hspace*{5cm}\includegraphics[scale=1]{images/hes.png} + \hspace*{5cm}\includegraphics[height=1.25cm]{images/logo-hesso-geneve.pdf} \end{minipage} \end{sffamily} \end{figure} \begin{center} - \huge{Bootiful\\ -Déploiement d'OS à choix durant le processus de boot}\\ - \vspace{.5cm} - \IfFileExists{images/front-logo.png}{ - \includegraphics[width=8cm,height=5cm]{images/front-logo.png}\\ - }{ - \vspace{5cm} - } - + \vspace{1.5cm} + \includegraphics[height=5cm]{images/bootiful_logo_final.pdf}\\ \vspace{5mm} + + \huge{Déploiement d'OS à choix durant le processus de boot}\\ + \vspace{2cm} + \large{Thèse de Bachelor présentée par}\\ \vspace{5mm} \textbf{\Large{Dimitri Lizzi}}\\ @@ -196,12 +207,12 @@ Déploiement d'OS à choix durant le processus de boot}\\ \large{pour l’obtention du titre Bachelor of Science HES-SO en}\\ \vspace{5mm} - \textbf{\Large{Ingénierie des technologies de l’information avec orientation en \\logiciels + \textbf{\Large{Ingénierie des technologies de l’information \\avec orientation en \\logiciels et systèmes complexes}} \vspace{5mm} \textbf{Août 2020\\} - \vspace{5mm} + \vspace{8mm} \begin{tabular}{ p{6cm} } \multicolumn{1}{c}{Professeur-e HES responsable}\\ \multicolumn{1}{c}{\textbf{Florent Glück}}\\ @@ -213,123 +224,96 @@ et systèmes complexes}} \tableofcontents \newpage +\chapter*{Remerciements} +\addcontentsline{toc}{chapter}{Remerciements} + +\textbf{TODO: remerciements} + +\addcontentsline{toc}{chapter}{Résumé} +\includepdf{abstract.pdf} + +\addcontentsline{toc}{chapter}{Énoncé} +\includepdf{statement.pdf} + \chapter*{Liste des acronymes} \addcontentsline{toc}{chapter}{Liste des acronymes} \begin{description} -\item[EFI \protect\hypertarget{acronym__EFI}{}{}] -\emph{Extensible Firmware Interface}: interface micrologicielle -extensible unifiée +\tightlist \item[BIOS \protect\hypertarget{acronym__BIOS}{}{}] \emph{Basic Input Output System}: système de base d'entrée sortie -\item[FTP \protect\hypertarget{acronym__FTP}{}{}] -\emph{File Transfer Protocol}: protocole de transfert de fichier \item[DHCP \protect\hypertarget{acronym__DHCP}{}{}] \emph{Dynamic Host Configuration Protocol}: protocole de configuration dynamique des hôtes -\item[GPT \protect\hypertarget{acronym__GPT}{}{}] -\emph{GUID Partition Table}: table de partitionnement GUID -\item[GRUB \protect\hypertarget{acronym__GRUB}{}{}] -\emph{GRand Unified Bootloader} EFI -\protect\hypertarget{acronym__EFI}{}{} - +\item[EFI \protect\hypertarget{acronym__EFI}{}{}] \emph{Extensible Firmware Interface}: interface micrologicielle extensible unifiée -\end{description} - -FTP \protect\hypertarget{acronym__FTP}{}{} HEPIA -\protect\hypertarget{acronym__HEPIA}{}{} \textasciitilde{} \emph{File -Transfer Protocol}: protocole de transfert de fichier \textasciitilde{} -Haute école du paysage, d'ingénierie et d'architecture de Genève - -\begin{description} -\tightlist +\item[ESP \protect\hypertarget{acronym__ESP}{}{}] +\emph{EFI System Partition}: partition système EFI +\item[FOG \protect\hypertarget{acronym__FOG}{}{}] +\emph{Free Open-source Ghost} +\item[FTP \protect\hypertarget{acronym__FTP}{}{}] +\emph{File Transfer Protocol}: protocole de transfert de fichier \item[GPT \protect\hypertarget{acronym__GPT}{}{}] \emph{GUID Partition Table}: table de partitionnement GUID -\item[HTTPS \protect\hypertarget{acronym__HTTPS}{}{}] -\emph{HyperText Transfer Protocol Secure}: protocole de transfert -hypertexte sécurisé \item[GRUB \protect\hypertarget{acronym__GRUB}{}{}] \emph{GRand Unified Bootloader} -\item[HTTP \protect\hypertarget{acronym__HTTP}{}{}] -\emph{HyperText Transfer Protocol}: protocole de transfert hypertexte \item[HEPIA \protect\hypertarget{acronym__HEPIA}{}{}] Haute école du paysage, d'ingénierie et d'architecture de Genève -\item[IPFS \protect\hypertarget{acronym__IPFS}{}{}] -\emph{InterPlanetary File System}: système de fichier inter-planétaire \item[HTTPS \protect\hypertarget{acronym__HTTPS}{}{}] \emph{HyperText Transfer Protocol Secure}: protocole de transfert hypertexte sécurisé -\item[IP \protect\hypertarget{acronym__IP}{}{}] -\emph{Internet Protocol}: protocole internet \item[HTTP \protect\hypertarget{acronym__HTTP}{}{}] \emph{HyperText Transfer Protocol}: protocole de transfert hypertexte -\item[LDAP \protect\hypertarget{acronym__LDAP}{}{}] -\emph{Lightweight Directory Access Protocol}: protocole léger d'accès à -un annuaire +\item[IBM \protect\hypertarget{acronym__IBM}{}{}] +\emph{International Business Machines corporation} \item[IPFS \protect\hypertarget{acronym__IPFS}{}{}] \emph{InterPlanetary File System}: système de fichier inter-planétaire -\item[MBR \protect\hypertarget{acronym__MBR}{}{}] -\emph{Master Boot Record}: enregistrement d'amorcage maître \item[IP \protect\hypertarget{acronym__IP}{}{}] \emph{Internet Protocol}: protocole internet -\item[NAT \protect\hypertarget{acronym__NAT}{}{}] -\emph{Network Address Translation}: traduction d'adresse réseau \item[LDAP \protect\hypertarget{acronym__LDAP}{}{}] \emph{Lightweight Directory Access Protocol}: protocole léger d'accès à un annuaire -\item[NFS \protect\hypertarget{acronym__NFS}{}{}] -\emph{Network File System}: système de fichiers en réseau +\item[MAC \protect\hypertarget{acronym__MAC}{}{}] +\emph{Media Access Control (address)}: adresse physique \item[MBR \protect\hypertarget{acronym__MBR}{}{}] \emph{Master Boot Record}: enregistrement d'amorcage maître -\item[OS \protect\hypertarget{acronym__OS}{}{}] -\emph{Operating System}: système d'exploitation \item[NAT \protect\hypertarget{acronym__NAT}{}{}] \emph{Network Address Translation}: traduction d'adresse réseau -\item[PC \protect\hypertarget{acronym__PC}{}{}] -\emph{Personal Computer}: ordinateur personnel \item[NFS \protect\hypertarget{acronym__NFS}{}{}] \emph{Network File System}: système de fichiers en réseau +\item[NVRAM \protect\hypertarget{acronym__NVRAM}{}{}] +\emph{Non-Volatile Random Access Memory}: mémoire vive non volatile +\item[OS \protect\hypertarget{acronym__OS}{}{}] +\emph{Operating System}: système d'exploitation +\item[PC \protect\hypertarget{acronym__PC}{}{}] +\emph{Personal Computer}: ordinateur personnel \item[PXE \protect\hypertarget{acronym__PXE}{}{}] \emph{Pre-boot eXecution Environment}: environnement d'exécution pré-démarrage -\item[OS \protect\hypertarget{acronym__OS}{}{}] -\emph{Operating System}: système d'exploitation \item[SCP \protect\hypertarget{acronym__SCP}{}{}] \emph{Secure CoPy}: protocole de copie sécurisée sur le réseau -\item[PC \protect\hypertarget{acronym__PC}{}{}] -\emph{Personal Computer}: ordinateur personnel +\item[SI \protect\hypertarget{acronym__SI}{}{}] +Système d'Information \item[SMB \protect\hypertarget{acronym__SMB}{}{}] \emph{Server Message Block} \item[SSH \protect\hypertarget{acronym__SSH}{}{}] \emph{Secure SHell}: protocole de terminal à distance securisé -\item[PXE \protect\hypertarget{acronym__PXE}{}{}] -\emph{Pre-boot eXecution Environment}: environnement d'exécution -pré-démarrage -\end{description} - -SCP \protect\hypertarget{acronym__SCP}{}{} TFTP -\protect\hypertarget{acronym__TFTP}{}{} \textasciitilde{} \emph{Secure -CoPy}: protocole de copie sécurisée sur le réseau \textasciitilde{} +\item[TFTP \protect\hypertarget{acronym__TFTP}{}{}] \emph{Trivial File Transfer Protocol}: protocole simplifié de transfert de fichiers - -\begin{description} \item[UEFI \protect\hypertarget{acronym__UEFI}{}{}] \emph{Unified Extensible Firmware Interface}: interface micrologicielle -extensible unifiée SMB \protect\hypertarget{acronym__SMB}{}{} - -\emph{Server Message Block} +extensible unifiée +\item[WWW \protect\hypertarget{acronym__WWW}{}{}] +\emph{World Wide Web}: toile mondiale / réseau mondial \end{description} -WWW \protect\hypertarget{acronym__WWW}{}{} SSH -\protect\hypertarget{acronym__SSH}{}{} \textasciitilde{} \emph{World -Wide Web}: toile mondiale / réseau mondial \textasciitilde{} -\emph{Secure SHell}: protocole de terminal à distance securisé - \newpage + \listoffigures \newpage + \listoftables \hypertarget{introduction}{% @@ -402,22 +386,99 @@ ce base sur une ébauche d'un travail déjà existant. dans le cas de nombreux téléchargements effectués en parallèle. \end{itemize} -\hypertarget{muxe9thodologie-de-travail}{% -\section{Méthodologie de travail}\label{muxe9thodologie-de-travail}} +\hypertarget{duxe9roulement}{% +\section{Déroulement}\label{duxe9roulement}} -\textbf{TODO: Expliquer comment le travail a été planifié, les meetings -hebdomadaires, les outils à disposition, le fait de travailler à -distance dans un contexte ``cours du soir''} +Ce projet n'a pas n'a pas été réalisé dans les locaux +d'\protect\hyperlink{acronym__HEPIA}{HEPIA} mais à distance, depuis la +maison, en partie à cause de la situation sanitaire due au COVID-19 mais +aussi parce qu'il est effectué dans le cadre d'un bachelor en cours du +soir, en parallèle à une activité professionnelle à 80\%. -\hypertarget{cas-dutilisation}{% -\chapter{Cas d'utilisation}\label{cas-dutilisation}} +Des rendez-vous hebdomadaires avec le professeur responsable Florent +Glück ainsi que l'assistant Sébastien Chassot ont été organisés tous les +mercredis, afin d'assurer un suivi du projet. + +\hypertarget{matuxe9riel-uxe0-disposition}{% +\section{Matériel à disposition}\label{matuxe9riel-uxe0-disposition}} + +Deux mini-ordinateurs ont étés prêtés par +\protect\hyperlink{acronym__HEPIA}{HEPIA} pour la durée du projet, afin +d'effectuer des tests sur du matériel réel. Les spécifications de ces +ordinateurs sont définies dans la table \ref{mini_pc_specs}. + +\begin{longtable}[]{@{}ll@{}} +\caption{Spécifications techniques des ordinateurs mis à disposition +\label{mini_pc_specs}}\tabularnewline +\toprule +\begin{minipage}[b]{0.19\columnwidth}\raggedright +Caractéristique\strut +\end{minipage} & \begin{minipage}[b]{0.75\columnwidth}\raggedright +Description\strut +\end{minipage}\tabularnewline +\midrule +\endfirsthead +\toprule +\begin{minipage}[b]{0.19\columnwidth}\raggedright +Caractéristique\strut +\end{minipage} & \begin{minipage}[b]{0.75\columnwidth}\raggedright +Description\strut +\end{minipage}\tabularnewline +\midrule +\endhead +\begin{minipage}[t]{0.19\columnwidth}\raggedright +Constructeur\strut +\end{minipage} & \begin{minipage}[t]{0.75\columnwidth}\raggedright +\emph{DELL}\strut +\end{minipage}\tabularnewline +\begin{minipage}[t]{0.19\columnwidth}\raggedright +Modèle\strut +\end{minipage} & \begin{minipage}[t]{0.75\columnwidth}\raggedright +\emph{Optiplex 7060 micro}\strut +\end{minipage}\tabularnewline +\begin{minipage}[t]{0.19\columnwidth}\raggedright +Processeur\strut +\end{minipage} & \begin{minipage}[t]{0.75\columnwidth}\raggedright +\emph{Intel® Core™ i7-8700 3.20GHz}\strut +\end{minipage}\tabularnewline +\begin{minipage}[t]{0.19\columnwidth}\raggedright +Mémoire vive\strut +\end{minipage} & \begin{minipage}[t]{0.75\columnwidth}\raggedright +8 GiB (2 barettes 4GiB \emph{SODIMM DDR4 Synchronous} 2666 MHz (0.4 +ns))\strut +\end{minipage}\tabularnewline +\begin{minipage}[t]{0.19\columnwidth}\raggedright +Disque\strut +\end{minipage} & \begin{minipage}[t]{0.75\columnwidth}\raggedright +\emph{TOSHIBA KSG60ZMV} SSD 476GiB (512GB)\strut +\end{minipage}\tabularnewline +\begin{minipage}[t]{0.19\columnwidth}\raggedright +Réseau\strut +\end{minipage} & \begin{minipage}[t]{0.75\columnwidth}\raggedright +\emph{Intel e1000e Gigabit Ethernet}\strut +\end{minipage}\tabularnewline +\bottomrule +\end{longtable} + +\hypertarget{muxe9thodologie}{% +\section{Méthodologie}\label{muxe9thodologie}} + +Le travail a été découpé en plusieurs parties, dont la durée a été +estimée en semaines de travail. Un planning a été effectué sous la forme +d'un diagramme de Gantt. Ce diagramme est visible dans la figure +\ref{planning_gantt}. + +\begin{figure} +\centering +\includegraphics{images/planning.pdf} +\caption{Diagramme de Gantt du planning\label{planning_gantt}} +\end{figure} -\textbf{TODO: décrire les cas d'utilisation du projet à l'aide d'un -diagramme de use cases qui montre les inter-actions possibles entre les -différentes entités du sytème que sont les utilsateurs, administrateurs, -les postes clients, le serveur, les images, les configurations. Le -diagramme doit décrire les aspects fonctionnels du système (quoi) sans -détailler les aspects techniques (comment).} +\hypertarget{analyse}{% +\section{Analyse}\label{analyse}} + +\hypertarget{cas-dutilisation}{% +\section{Cas d'utilisation}\label{cas-dutilisation}} L'aspect fonctionnel du système à réaliser est décrit avec un diagramme de cas d'utilisations dans la figure \ref{diagram_usecases}. @@ -429,8 +490,9 @@ de cas d'utilisations dans la figure \ref{diagram_usecases}. système.\label{diagram_usecases}} \end{figure} -\hypertarget{uxe9tat-de-lart}{% -\chapter{État de l'art}\label{uxe9tat-de-lart}} +\hypertarget{uxe9tude-des-solutions-existantes}{% +\section{Étude des solutions +existantes}\label{uxe9tude-des-solutions-existantes}} De nombreux systèmes de déploiement d'\protect\hyperlink{acronym__OS}{OS} existent, mais aucun d'entre eux @@ -441,53 +503,120 @@ Les sous-sections qui suivent décrivent quelques-uns de ces systèmes, leurs points forts et points faibles et pourquoi ils ne sont pas adaptés tels-quel pour ce projet. -\hypertarget{ibm-tivoli-rembo}{% -\section{IBM Tivoli / Rembo}\label{ibm-tivoli-rembo}} - -\textbf{TODO: expliquer que ce projet se rapproche le plus des objectifs -du projet, qu'il a été développé initialement à l'université de Genève -et a été utilisé à HEPIA par le passé avec succès. Expliquer le rachat -par IBM et la problématique de la licence couteuse. Introduire l'intérêt -d'une solution open source pour ne pas retomber dans le meme schéma.} - -\hypertarget{fog}{% -\section{Fog}\label{fog}} - -\textbf{TODO: expliquer le fonctionnement et les cas d'utilisation de -fog, l'utilisation actuelle de ce système dans l'école, de ses -limitations et pourquoi il ne permet pas de répondre aux objectifs de ce -projet.} +\hypertarget{bpbatch-rembo-ibm-tivoli}{% +\subsection{\texorpdfstring{BpBatch / Rembo / +\protect\hyperlink{acronym__IBM}{IBM} +Tivoli}{BpBatch / Rembo / IBM Tivoli}}\label{bpbatch-rembo-ibm-tivoli}} + +Ce système est l'inspiration directe de ce projet. Son développement a +commencé en 1996 au département informatique de l'université de Genève +par Marc Vuilleumier Stückelberg et David Clerc. + +Les fonctionnalités de ce projet sont similaires à celles visée par le +projet \emph{Bootiful}. Il permet aux postes clients de lancer un mini +système d'exploitation via \protect\hyperlink{acronym__PXE}{PXE} au +démarrage de la machine. Ce mini-système permet de télécharger et +déployer des images de système d'exploitation sur la machine, tout en +créant une copie en cache à la fin du disque pour éviter de la +télécharger plusieurs fois. + +La première version, nommée \emph{BpBatch} fut distribuée gratuitement +sur internet. Une entreprise nommée \emph{Rembo Technology Sàrl} a +ensuite été fondée en 1999 pour continuer un développement commercial de +ce projet sous le nom de \emph{Rembo}. En 2006, la société a été +rachetée par IBM et le projet a été intégré à leur solution \emph{Tivoli +Provisionning Manager}. + +Ce système réponde aux besoins de +\protect\hyperlink{acronym__HEPIA}{HEPIA}, et il a même déjà été utilisé +au sein de l'institution par le passé. Il a cependant été abandonné à +cause de sa licence devenue très couteuse et de sa complexité devenue +trop grande pour les besoins simple de l'école. + +Le développement d'une solution alternative \emph{open-source} plus +simple et se basant sur des briques logicielles existantes serait donc +très intéressante. + +\hypertarget{fog-project}{% +\subsection{\texorpdfstring{\protect\hyperlink{acronym__FOG}{FOG} +project}{FOG project}}\label{fog-project}} + +\protect\hyperlink{acronym__FOG}{FOG} est une solution open-source +gratuite permettant de déployer des images de systèmes d'exploitation +sur des postes clients. + +Elle fonctionne avec une architecture client-serveur. Le serveur est +accédé par une interface web, où un administrateur peut gérer ses images +et les déployer sur des clients qui démarrent un logiciel de déploiement +avec \protect\hyperlink{acronym__PXE}{PXE}. + +Cette solution est utilisées dans certaines classes à +\protect\hyperlink{acronym__HEPIA}{HEPIA} pour déployer des images sur +certains postes, notemment pour les travaux de laboratoire de réseau. + +Malheureusement, ce système ne répond pas exactement au cahier des +charges de ce projet: il est plutôt conçu pour ``pousser'' des images +sur des clients, depuis le serveur, après une initiation du déploiement +par un administrateur. Nous souhaitons plutôt un système ne nécessitant +pas d'intervention d'un administrateur pour initier un déploiement. + +De plus,\protect\hyperlink{acronym__FOG}{FOG} ne dispose pas de +mécanisme de cache sur les clients permettant de ne pas télécharger les +images plusieurs fois. À chaque fois qu'un image doit être déployée, +elle doit être téléchargée à nouveau depuis le serveur, ce qui peut +prendre beaucoup de temps et doit être planifié à l'avance. \hypertarget{clonezilla}{% -\section{Clonezilla}\label{clonezilla}} - -\textbf{TODO: expliquer le fonctionnement, les cas d'utilisation le -contexte. Parler de l'outil partclone et de ses avantages. Expliquer -pourquoi il n'est pas adapté tel quel, mais aussi pourquoi il est -intéressant de réutiliser certaines parties.} +\subsection{Clonezilla}\label{clonezilla}} -\hypertarget{ghost}{% -\section{Ghost}\label{ghost}} +\emph{Clonezilla} est une solution open-source et gratuite de création +et de restauration d'images. -\textbf{TODO: expliquer le fonctionnement et mettre en parallèle à fog -et clonezilla et souligner les problématiques d'une solution commerciale -au lieu d'une solution open-source. } +Cet outil peut être utilisé de deux manières: -\hypertarget{acronis-trueimage}{% -\section{Acronis TrueImage}\label{acronis-trueimage}} +\begin{itemize} +\tightlist +\item + En faisant démarrer les clients sur le réseau. Ils chargent un petit + système d'exploitation de déploiement depuis un un serveur + \protect\hyperlink{acronym__PXE}{PXE}. Ils peuvent ensuite initier le + déploiement ou la restauration d'une image depuis/vers ce serveur. +\item + En faisant démarrer les clients sur un CD ou une clé USB. Ils peuvent + ensuite initier le déploiement ou la restauration d'une image + d'\protect\hyperlink{acronym__OS}{OS} depuis/vers sur un autre disque + ou un serveur distant. +\end{itemize} -\textbf{TODO: expliquer le fonctionnement et mettre en parallèle à fog -et clonezilla et souligner les problématiques d'une solution commerciale -au lieu d'une solution open-source. } +Un avantage de \emph{Clonezilla} est le format utilisé pour la +sauvegarde des images. L'outil \emph{Partclone}, développé par la même +équipe, est utilisé. Il permet de créer des images de partitions en ne +copiant que les blocs utilisés dans le système de fichiers. Les parties +non utilisées de la partition ne sont pas comprises dans l'image créée, +ce qui permet de réduire sa taille et d'accélérer le processus de +sauvegarde et de restauration. + +Malheureusement, comme pour \protect\hyperlink{acronym__FOG}{FOG}, +\emph{Clonezilla} ne dispose pas de mécanisme de cache sur les clients +permettant de ne pas télécharger les images depuis un serveur distant +plusieurs fois. À chaque fois qu'un image doit être déployée, elle doit +être téléchargée à nouveau depuis le serveur, ce qui peut prendre +beaucoup de temps et doit être planifié à l'avance. + +\emph{Clonezilla} ne peut donc pas être utilisé tel-quel. Cependant, il +est possible de l'utiliser uniquement pour la création d'images et +d'intégrer son mécanisme de restauration à un autre système de +déploiement. Cette possibilité sera étudiée plus tard dans ce document. \hypertarget{architecture-initiale-du-projet}{% \chapter{Architecture initiale du projet}\label{architecture-initiale-du-projet}} Le projet \emph{Bootiful} n'a pas été initié dans le cadre de ce travail -de bachelor: une implémentation basique avait déjà été réalisée afin de -prouver que l'idée fonctionne. Cette version initiale a été créée par -Abhilash Venkatesh, un étudiant indien qui est venu à +de bachelor: une implémentation basique +(\protect\hyperlink{ref-venkatesh_remote_imaging}{1}) avait déjà été +réalisée afin de prouver que l'idée fonctionne. Cette version initiale a +été créée par Abhilash Venkatesh, un étudiant indien qui est venu à \protect\hyperlink{acronym__HEPIA}{HEPIA} effectuer un stage pendant la période de mai à juillet 2019. @@ -1759,16 +1888,17 @@ des images déployées et à la taille des images juste compressées avec \def\labelenumi{\arabic{enumi}.} \tightlist \item - Une petite image du système \emph{Debian}, comparée dans le tableau - \ref{table_image_sizes_debian} et la figure - \ref{chart_image_sizes_debian} + Une petite image (environ 3.2 GB) du système \emph{Debian}, dont les + tailles sont comparées dans le tableau \ref{table_image_sizes_debian} + et la figure \ref{chart_image_sizes_debian} \item - Une image moyenne du système \emph{Xubuntu}, comparée dans le tableau - \ref{table_image_sizes_xubuntu} et la figure - \ref{chart_image_sizes_xubuntu} + Une image moyenne (environ 200GB) du système \emph{Xubuntu}, dont les + tailles sont comparées dans le tableau \ref{table_image_sizes_xubuntu} + et la figure \ref{chart_image_sizes_xubuntu} \item - Une grande image du système \emph{Windows 10}, comparée dans le - tableau \ref{table_image_sizes_win10} et la figure + Une grande image (environ 512GB) du système \emph{Windows 10}, dont + les tailles sont comparées dans le tableau + \ref{table_image_sizes_win10} et la figure \ref{chart_image_sizes_win10} \end{enumerate} @@ -2042,10 +2172,11 @@ possible depuis d'autres distributions Linux, un conteneur \emph{Docker} a été créé. Le processus de création du système décrit dans la section précédente a -été automatisé et est décrit dans un fichier \texttt{Dockerfile}. La -nouvelle fonctionnalité de Docker de construction en plusieurs -``étages'' (\emph{multi-stage build}) a été utilisée. Trois ``étages'' -sont définis: +été automatisé et est décrit dans un fichier \texttt{Dockerfile} (le +code-souce de ce fichier peut être consulté dans la section +\ref{deployer_dockerfile}). La fonctionnalité de Docker de construction +en plusieurs ``étages'' (\emph{multi-stage build}) a été utilisée. Trois +``étages'' sont définis: \begin{itemize} \tightlist @@ -2101,41 +2232,493 @@ des deux derniers étages dans leurs dossiers respectifs: \protect\hyperlink{acronym__TFTP}{TFTP}. \end{itemize} +\hypertarget{duxe9ploiement-dimage-windows}{% +\section{Déploiement d'image +Windows}\label{duxe9ploiement-dimage-windows}} + +Une image \emph{Windows 10} a été créée avec \emph{Clonezilla}, à partir +du système présent par défaut sur les mini-pc DELL que l'école avait mis +à disposition. Les PC étant neufs il s'agit du système d'exploitation +par défaut installé pour le constructeur. L'image qui a été créée a déjà +été mentionnée dans la section \emph{Réduction de la taille des images}. +Elle a la particularité d'être très grande car elle prend l'espace +entier du disque. + +Un problème a été rencontré lors du premier déploiement de l'image: le +script de déploiement ne gérait pas une image qui est tellement grande +qu'elle écrase la partition de cache et plantait. Une vérification a +donc été rajoutée sur la taille de l'image. Quand une image va écraser +la partition de cache, un message d'avertissement est affiché et +l'utilisateur doit confirmer qu'il souhaite continuer. Si l'utilisateur +accepte, le déploiment se fait sans mise en cache de l'image et la +partition cachée de cache est détruite. + +Une fois ce système mis en place, le déploiement de l'image s'est +déroulé sans problème particulier, et a confirmé que le déploiement +d'une image \emph{Windows} est faisable avec ce système. + \hypertarget{ruxe9duction-du-temps-de-duxe9ploiement-total}{% \section{Réduction du temps de déploiement total}\label{ruxe9duction-du-temps-de-duxe9ploiement-total}} -\textbf{TODO: expliquer, détailler et comparer (tableaux, diagrammes) -les différentes mesures qui ont montré que clonezilla est intéressant -les images larges mais que dd est parfois plus performant pour de -petites images.} +Théoriquement, le déploiement d'images avec clonezilla devrait être plus +court que le déploiement d'images \emph{raw}. Des mesures ont été +effectuées avec les trois images dont les différences de taille ont déjà +étudiées précédemment dans la section \emph{Réduction de la taille des +images}: -\hypertarget{duxe9ploiement-dimage-windows}{% -\section{Déploiement d'image -Windows}\label{duxe9ploiement-dimage-windows}} +\begin{enumerate} +\def\labelenumi{\arabic{enumi}.} +\tightlist +\item + Une petite image (environ 3.2 GB) du système \emph{Debian}, dont les + temps de déploiement sont comparés dans le tableau + \ref{table_deploy_time_debian} et la figure + \ref{chart_deploy_time_debian} +\item + Une image moyenne (environ 200GB) du système \emph{Xubuntu}, dont les + temps de déploiement sont comparés dans le tableau + \ref{table_deploy_time_xubuntu} et la figure + \ref{chart_deploy_time_xubuntu} +\item + Une grande image (environ 512GB) du système \emph{Windows 10}, dont + les temps de déploiement sont comparés dans le tableau + \ref{table_deploy_time_win10} et la figure + \ref{chart_deploy_time_win10} +\end{enumerate} + +\clearpage + +\begin{longtable}[]{@{}ll@{}} +\caption{Table des temps de déploiement d'une petite image \emph{Debian} +dans plusieurs formats \label{table_deploy_time_debian}}\tabularnewline +\toprule +Type & Temps de déploiement (secondes)\tabularnewline +\midrule +\endfirsthead +\toprule +Type & Temps de déploiement (secondes)\tabularnewline +\midrule +\endhead +Gzip (sans cache) & 14\tabularnewline +Gzip (avec cache) & 13\tabularnewline +Clonezilla (sans cache) & 39\tabularnewline +Clonezilla (avec cache) & 39\tabularnewline +\bottomrule +\end{longtable} + +\begin{figure} +\centering +\includegraphics{charts/chart_deploy_time_debian.svg} +\caption{Graphique des temps de déploiement d'une petite image +\emph{Debian} dans plusieurs formats\label{chart_deploy_time_debian}} +\end{figure} + +\clearpage + +\begin{longtable}[]{@{}ll@{}} +\caption{Table des temps de déploiement d'une image \emph{Xubuntu} +moyenne dans plusieurs formats +\label{table_deploy_time_xubuntu}}\tabularnewline +\toprule +Type & Temps de déploiement (secondes)\tabularnewline +\midrule +\endfirsthead +\toprule +Type & Temps de déploiement (secondes)\tabularnewline +\midrule +\endhead +Gzip (sans cache) & 623\tabularnewline +Gzip (avec cache) & 630\tabularnewline +Clonezilla (sans cache) & 109\tabularnewline +Clonezilla (avec cache) & 85\tabularnewline +\bottomrule +\end{longtable} + +\begin{figure} +\centering +\includegraphics{charts/chart_deploy_time_xubuntu.svg} +\caption{Graphique des temps de déploiement d'une image \emph{Xubuntu} +moyenne dans plusieurs formats\label{chart_deploy_time_xubuntu}} +\end{figure} + +\clearpage + +\begin{longtable}[]{@{}ll@{}} +\caption{Table des temps de déploiement d'une grande image \emph{Windows +10} dans plusieurs formats +\label{table_deploy_time_win10}}\tabularnewline +\toprule +Type & Temps de déploiement (secondes)\tabularnewline +\midrule +\endfirsthead +\toprule +Type & Temps de déploiement (secondes)\tabularnewline +\midrule +\endhead +Gzip (sans cache) & 3433\tabularnewline +Clonezilla (sans cache) & 371\tabularnewline +\bottomrule +\end{longtable} + +\begin{figure} +\centering +\includegraphics{charts/chart_deploy_time_win10.svg} +\caption{Graphique des temps de déploiement d'une grande image +\emph{Windows 10} dans plusieurs formats\label{chart_deploy_time_win10}} +\end{figure} + +\clearpage + +Ces mesures permettent de se rendre contre de plusieurs faits +remarquables, qui ne sont pas forcément intuitifs. + +Sur des très petites images le déploiement au format \emph{raw} +compressé avec \emph{gzip} est plus rapide que le déploiement avec +\emph{Clonezilla}. Ceci peut s'expliquer par le fait que +\emph{Clonezilla} prend du temps pour créer une table des partitions, un +système de fichiers pour chacune de ces partitions et copie ensuite les +blocs un à un sur chaque système de fichiers. Sur une grande image, ce +mode de fonctionnement est ``rentable'' car il y a beaucoup de blocs qui +n'auront pas à être copiés, alors qu'une image \emph{raw} devra passer +du temps à copier les données de chacun de ces blocs. Sur une très +petite image comme l'image \emph{Debian} mesurée ici, presque tous les +blocs du système de fichiers sont déjà utilisés, donc la copie brute des +données des partitions est plus rapide car tout le temps est passé à +copier les données. + +Sur les plus grosses images, cependant, \emph{Clonezilla} a clairement +l'avantage, car de nombreux blocs vides n'ont pas besoin d'être copiés. +Ainsi, avec les images plus larges utilisées dans les mesures, le temps +de déploiement des images plus larges au format \emph{raw} prend environ +5 à 9 fois plus de temps que le temps de déploiement avec +\emph{Clonezilla}. + +Un autre fait remarquable est que le déploiement d'une image \emph{raw} +déjà mise en cache prend plus de temps que le déploiement avec une copie +simultanée dans le cache. Cela s'explique peut être par le fait que dans +le premier cas, des données doivent être lues depuis le disque et +écrites sur le même disque, tandis que dans le second cas, seule de +l'écriture est effectuée. + +Par contre, dans le cas des images \emph{Clonezilla}, le déploiement +d'une image déjà présente en cache s'effectue plus rapidement que le +déploiement d'une image présente en cache. C'est l'inverse de ce qui se +passe avec les images \emph{raw}. Cela s'explique par le fait que les +images \emph{Clonezilla} sont copiées avant d'être déployées, alors que +les images \emph{raw} sont copiées et déployées simultanément. + +Il est important de se rappeller que les mesures montrées ici sont +effectuées dans des circonstances idéales: il n'y a qu'un seul client +qui télécharge l'image, seul un switch réseau sépare le client du +serveur et le client et le serveur sont les appareils connectés à ce +réseau local. Dans des conditions réelles, plusieurs machines seront +fréquemment en train de télécharger des images depuis le serveur en même +temps. Dans ce cas, le temps de déploiement d'une image non présente en +cache risque de prendre beaucoup plus de temps. Au contraire, le +déploiement d'une image déjà mise en cache devrait théoriquement prendre +le même temps que dans ces circonstances idéales. \hypertarget{amuxe9lioration-des-scripts-de-duxe9ploiement}{% \section{Amélioration des scripts de déploiement}\label{amuxe9lioration-des-scripts-de-duxe9ploiement}} -\textbf{TODO: Expliquer les problèmes rencontrés avec les scripts de -déploiement initiaux et les nombreuses améliorations apportées par leur -ré-écriture\\ -quasi-complète (gestion des erreurs, stack traces, amélioration des -logs, gestion des images plus grandes que le cache, mesure des timings, -scripts utilitaires de maintenance, possibilité d'utiliser clonezilla, -détection du point d'entrée EFI).} +De très nombreuses améliorations ont été apportées aux scripts de +déploiement, au point qu'ils sont presque complètement différents des +scripts initiaux. + +\hypertarget{gestion-des-erreurs}{% +\subsection{Gestion des erreurs}\label{gestion-des-erreurs}} + +Premièrement, la gestion des erreurs, inexistante dans le script initial +a été rajoutée. Les codes de retour des commandes sont vérifiés et les +données récupérées depuis la sortie de ces commandes sont validées avant +utilisation. Si un code de retour ou une donnée récupérée n'est pas au +format attendu, une fonction spéciale \texttt{fatal\_error} est appelée +avec comme argument un message d'erreur adapté à la situation. Cette +fonction va afficher le message d'erreur, ainsi qu'une trace de la pile +des appels (\emph{stack trace} en anglais). Cette trace permet +d'identifier précisément à quelle ligne de quel fonction et dans quel +fichier une erreur a eu lieu. + +Finalement, le script de déploiement \texttt{bootiful-deploy} sera +quitté avec un code d'erreur, ce qui permet au script parent, +\texttt{bootiful-init}, de détecter qu'une erreur a eu lieu et de +proposer à l'utilisateur quelle action il souhaite effectuer parmi les +choix suivants: + +\begin{itemize} +\tightlist +\item + Recommencer le déploiement +\item + Redémarrer la machine +\item + Éteindre la machine +\item + Ouvrir un \emph{shell} interactif (\texttt{/bin/bash}) pour étudier la + cause de l'erreur. Une fois le \emph{shell} terminé, l'utilisateur + peut à nouveau choisir ce qu'il souhaite faire. +\end{itemize} + +Le mécanisme de gestion d'erreurs a été très utile lors du développement +et du test des scripts de déploiement pour comprendre pourquoi certaines +erreurs arrivaient et adapter les scripts pour les éviter. Ce mécanisme +sera aussi utile pour aider un futur administrateur du système à +comprendre ce qu'il se passe si un déploiement ne se déroule pas comme +prévu. + +\hypertarget{mesure-du-temps-uxe9couluxe9}{% +\subsection{Mesure du temps écoulé}\label{mesure-du-temps-uxe9couluxe9}} + +Un système permettant de mesurer et d'afficher le temps passé dans +chaque section du script de déploiement a été créé. Il permet de mesurer +chacune des parties et d'afficher le temps passé dans chaque partie à la +fin du script. Les parties mesurées sont classées en deux catégories: +\emph{batch} et \emph{interactive}. Les parties \emph{batch} sont celles +qui sont exécutées automatiquement, sans intervention de l'utilisateur, +tandis que les parties \emph{interactive} sont celles où le système +attend un choix de l'utilisateur, comme par exemple le choix de l'image +à déployer. Cette catégorisation des parties permet d'afficher à la fin +du script combien de temps a été passé dans les parties \emph{batch} +sans prendre en compte le temps passé à attendre un choix de +l'utilisateur. + +\hypertarget{amuxe9lioration-des-logs}{% +\subsection{Amélioration des logs}\label{amuxe9lioration-des-logs}} + +Plusieurs améliorations ont été apportées au mécanisme de logging. Dans +le système initial, les flux \texttt{stdin} et \texttt{stdout} du script +de déploiement étaient redirigés vers un fichier de log sur le serveur. +Cela permet d'étudier à \emph{posteriori} comment le déploiement s'est +effectué, et de vérifier la durée d'exécution. Cela permet aussi de +comprendre ce qui s'est mal passé en cas d'erreur. + +Dans le système initial, étant donné que les flux sont redirigés vers un +fichier, un écran noir est affiché sur l'écran du poste client. Cela a +l'inconvénient de ne pas permettre à l'utilisateur du poste client de +savoir ce qu'il est en train de se passer. Il n'est pas possible pour +l'utilisateur de savoir si le déploiement est en cours ou s'il est +bloqué sur une étape. La première modification apportée au système de +logging a été d'utiliser la commande \texttt{tee} pour écrire dans les +fichiers de log, au lieu d'une simple redirection. Cela permet aux +sorties d'être simultanément affichées sur l'écran du client et +sauvegardée dans les logs. + +De nombreux textes informatifs ont aussi été rajoutés dans la sortie du +script pour expliquer ce qu'il est en train de se passer petit à petit. +Cela permet de mieux contextualiser chaque ligne de log. Une barre de +progression a aussi été rajoutée lors du déploiement d'une image au +format \emph{raw} pour que l'utilisateur puisse suivre la progression du +déploiement et qu'il puisse voir le temps écoulé ainsi qu'une estimation +du temps restant. + +Le mécanisme initial de logging créait un fichier de log par poste +client, en le nommant avec l'adresse +\protect\hyperlink{acronym__MAC}{MAC} du poste. Chaque déploiement +successif était loggué dans ce même fichier. Pour bien différencier le +début et la fin d'un log, une ligne facilement reconnaissable contenant +la date et l'heure était affichée. Il y a plusieurs problèmes avec ce +système: + +\begin{itemize} +\tightlist +\item + Les fichiers de log peuvent devenir très gros après de nombreux + déploiements. +\item + Le nettoyage du dossier de logs pour ne garder que les plus récents + est compliqué, car chaque fichier contient les logs de plusieurs + déploiements. +\item + La manipulation avec des commandes standard telles que \texttt{grep}, + \texttt{awk}, \texttt{tail} du log d'un déploiement précis est + compliqué. +\item + La comparaison de deux logs de déploiement sur la même machine est + difficile car il faut trouver où les déploiements commencent et se + terminent dans le même fichier. +\end{itemize} + +Le système de log a donc été modifié pour qu'un fichier par déploiement +soit créé par déploiement. Chaque fichier de log est nommé selon +l'adresse mac de la machine ainsi que la date et l'heure du début du +déploiement. + +\hypertarget{intuxe9gration-de-clonezilla-comme-type-dimage}{% +\subsection{\texorpdfstring{Intégration de \emph{Clonezilla} comme type +d'image}{Intégration de Clonezilla comme type d'image}}\label{intuxe9gration-de-clonezilla-comme-type-dimage}} + +Le script de déploiement a été modifié pour pouvoir détecter si une +image est au format \emph{raw} ou s'il s'agit d'une image +\emph{Clonezilla}. Selon le type d'image, des stratégies différentes +sont utilisées pour différentes étapes du déploiement: + +\begin{itemize} +\tightlist +\item + Détermination de la place nécessaire sur le disque pour déployer + l'image +\item + Commandes utilisées pour le déploiement +\item + Détermination du point d'entrée EFI. +\end{itemize} + +\hypertarget{duxe9tection-automatique-du-point-dentruxe9e-efi}{% +\subsection{\texorpdfstring{Détection automatique du point d'entrée +\protect\hyperlink{acronym__EFI}{EFI}}{Détection automatique du point d'entrée EFI}}\label{duxe9tection-automatique-du-point-dentruxe9e-efi}} + +Si l'image est au format \emph{Clonezilla}, le script de déploiement est +capable de déterminer automatiquement quel sera le programme +\protect\hyperlink{acronym__EFI}{EFI} qui sera exécuté au prochain +démarrage pour démarrer l'\protect\hyperlink{acronym__OS}{OS} déployé. + +En effet, les images \emph{Clonezilla} de systèmes +\protect\hyperlink{acronym__EFI}{EFI} contiennent un fichier spécial, +\texttt{efi-nvram.dat}, qui contient les variables contenues dans la +\protect\hyperlink{acronym__NVRAM}{NVRAM} du système +\protect\hyperlink{acronym__EFI}{EFI} au moment de la création de +l'image. Cette mémoire contient notemment l'ordre des entrées de boot et +les programmes \protect\hyperlink{acronym__EFI}{EFI} à exécuter pour +chacune de ces entrées, si applicable. + +Par exemple, voici le contenu du fichier \texttt{nvram.dat} de l'image +\emph{Windows 10} mentionnée dans les sections précédentes: + +\begin{Shaded} +\begin{Highlighting}[] +\NormalTok{BootCurrent: 0001} +\NormalTok{Timeout: 0 seconds} +\NormalTok{BootOrder: 0000,0001} +\NormalTok{Boot0000* Windows Boot Manager HD(1,GPT,0cccfd69{-}e584{-}4e2d{-}8a5d{-}6afa7130fcab,0x800,0x15e000) /File(\textbackslash{}EFI\textbackslash{}Microsoft\textbackslash{}Boot\textbackslash{}bootmgfw.efi) WINDOWS.........x...B.C.D.O.B.J.E.C.T.=.\{.9.d.e.a.8.6.2.c.{-}.5.c.d.d.{-}.4.e.7.0.{-}.a.c.c.1.{-}.f.3.2.b.3.4.4.d.4.7.9.5.\}....................} +\NormalTok{Boot0001* UEFI: USB DISK 3.0 PMAP PciRoot(0x0)/Pci(0x14,0x0)/USB(16,0)/CDROM(1,0x344,0x5e00)..BO} +\end{Highlighting} +\end{Shaded} + +Le script de déploiement est capable de lire ce fichier, de trouver la +première entrée contenant un chemin vers un exécutable +\protect\hyperlink{acronym__EFI}{EFI}, et transformer ce chemin en un +chemin \emph{Unix}, c'est à dire avec le caractère \texttt{/} au lieu de +\texttt{\textbackslash{}} et des noms de dossiers et fichiers sensibles +à la casse, qui correspondent à des dossiers et fichiers présents sur la +partition \protect\hyperlink{acronym__ESP}{ESP} qui vient d'être +déployée. Cette conversion est importante car ce chemin devra être passé +à \protect\hyperlink{acronym__GRUB}{GRUB}, qui ne sait lire que des +chemins au format \emph{Unix}. + +Une fois le point d'entrée déterminé un fichier \texttt{efi\_entrypoint} +est écrit à la racine de la partition +\protect\hyperlink{acronym__ESP}{ESP}. Il sera ensuite lu par +\protect\hyperlink{acronym__GRUB}{GRUB} au prochain démarrage pour +trouver le point d'entrée à exécuter. Le contenu de ce fichier +ressemblera à ceci: + +\begin{Shaded} +\begin{Highlighting}[] +\KeywordTok{set} \VariableTok{efi\_entrypoint=}\NormalTok{/efi/Microsoft/Boot/bootmgfw.efi} +\end{Highlighting} +\end{Shaded} + +Si l'image est au format \emph{raw}, ou alors qu'il est souhaité +d'outrepasser la lecture automatique du point d'entrée d'une image +\emph{Clonezilla}, il suffit de rajouter un fichier +\texttt{efi\_entrypoint} dans le dossier de l'image. Ce fichier sera +directement copié dans l'\protect\hyperlink{acronym__ESP}{ESP}, sans +qu'une tentative de détermination automatique du point d'entrée à partir +du fichier \texttt{nvram.dat} soit effectuée. \hypertarget{personnalisation-dimages-post-duxe9ploiement}{% \section{Personnalisation d'images post-déploiement}\label{personnalisation-dimages-post-duxe9ploiement}} -\textbf{TODO: expliquer pourquoi Ansible a été choisi pour cette tache, -et des avantages que cela apporte de pouvoir customiser une image -post-déploiement plutôt que d'avoir une multitude d'images pour chaque -personnalisation (simplicité de création de playbook plutot que la -création d'une image complète, possiblité de réutiliser les mêmes -playbooks sur plusieurs images similaires, réutilisation d'images).} +Un système a été conçu pour que l'utilisateur puisse choisir des +personnalisations post-déploiement pour une image parmi un ensemble +prédéfini. Ces personnalisations peuvent être implémentées de plusieurs +manières: il ne s'agit que de fichiers qui seront copiés dans un dossier +présent dans un répertoire de la machine déployée. + +Une image supportant les personnalisation post-déploiement peut par +exemple être configurée pour exécuter des scripts qui auront été copiés +dans un répertoire. Par exemple, sur une image dont +l'\protect\hyperlink{acronym__OS}{OS} est une distribution \emph{Linux} +utilisant \emph{Systemd}, une unité peut être configurée pour être +exécutée au démarrage. Cette unité peut lancer au démarrage un script +servant à exécuter séquentiellement des scripts présents dans un dossier +prédéfini, ou alors exécuter des \emph{playbooks} \emph{Ansible}. + +Des personnalisations peuvent aussi être ``passives'' et ne pas +nécessiter de configuration particulière du côté du client. Par exemple, +si elle consiste uniquement à copier/remplacer un fichier de +configuration à un endroit précis. + +Après le choix d'une image, le script de déploiement va chercher si un +sous dossier \texttt{customizations} existe. Ce dossier contient un +sous-dossier par personnalisation que l'utilisateur peut choisir. Chaque +sous dossier personnalisation doit contenir une arborescence de dossiers +et de fichiers dont le premier niveau contient uniquement des dossier +correspondant à des noms de partitions existant dans l'image déployée. À +l'intérieur de ce dossier, une arborescence des fichiers copiés sur la +machine depuis laS + +Étudions une arborescence fictive de personnalisations pour mieux +comprendre ce système. Voici l'arborescence du dossier +\texttt{customizations} d'une image: + +\begin{Shaded} +\begin{Highlighting}[] +\NormalTok{customizations} +\NormalTok{├── C language development environment} +\NormalTok{│ └── sda2} +\NormalTok{│ └── etc} +\NormalTok{│ └── bootiful} +\NormalTok{│ └── postdeploy{-}playbooks} +\NormalTok{│ └── 002{-}install{-}c{-}dev.yml} +\NormalTok{├── Custom bashrc} +\NormalTok{│ └── sda2} +\NormalTok{│ └── etc} +\NormalTok{│ └── bash.bashrc} +\NormalTok{└── Join LDAP domain} +\NormalTok{ └── sda2} +\NormalTok{ └── etc} +\NormalTok{ └── bootiful} +\NormalTok{ └── postdeploy{-}playbooks} +\NormalTok{ └── 001{-}join{-}ldap.yml} +\end{Highlighting} +\end{Shaded} + +Cette arborescence définit les personnalisations suivantes, qui peuvent +être choisies par l'utilisateur: + +\begin{enumerate} +\def\labelenumi{\arabic{enumi}.} +\tightlist +\item + \texttt{C\ language\ development\ environment}: copie un + \emph{playbook} \emph{Ansible} servant à installer un environnement de + développement C dans le dossier + \texttt{/etc/bootiful/postdeploy-playbooks} de la partition + \texttt{sda2} +\item + \texttt{Custom\ bashrc}: remplace le ficher \texttt{/etc/bash.bashrc} + de la partition \texttt{sda2} par un fichier personnalisé. +\item + \texttt{Join\ LDAP\ domain}: copie un \emph{playbook} \emph{Ansible} + servant à rejoindre un domaine \protect\hyperlink{acronym__LDAP}{LDAP} + dans le dossier \texttt{/etc/bootiful/postdeploy-playbooks} de la + partition \texttt{sda2} +\end{enumerate} + +Les personnalisations \textbf{1} et \textbf{3} nécessitent que l'image +soit équipée d'un mécanisme qui va exécuter les \emph{playbooks Ansible} +présents dans \texttt{/etc/bootiful/postdeploy-playbooks} au démarrage. +Des exemples d'un tel script et de l'unité \emph{systemd} servant à le +lancer au démarrage sont consultables dans les sections +\ref{source_ansible_run} et \ref{source_ansible_init}.'w'\,'\,'\,' + +La personnalisation \textbf{2} est passive: elle remplace juste un +fichier mais ne nécessite pas de mécanisme spécial sur la machine de +déploiement pour l'exécuter. \hypertarget{architecture-finale-du-projet}{% \chapter{Architecture finale du @@ -2184,14 +2767,6 @@ cette configuration à un environnement de production.} \textbf{TODO: expliquer exactement comment sont structurées les données des images (raw et clonezilla).} -\hypertarget{systuxe8me-de-personnalisation-des-images}{% -\section{Système de personnalisation des -images}\label{systuxe8me-de-personnalisation-des-images}} - -\textbf{TODO: expliquer en détails comment fonctionne le système de -personnalisation des images, ce qui est nécéssaire sur le client et ce -qui est nécessaire sur le serveur} - \hypertarget{utilisation-du-systuxe8me-duxe9ployuxe9}{% \chapter{Utilisation du système déployé}\label{utilisation-du-systuxe8me-duxe9ployuxe9}} @@ -2200,6 +2775,18 @@ déployé}\label{utilisation-du-systuxe8me-duxe9ployuxe9}} \section{Déployer une image sur un poste}\label{duxe9ployer-une-image-sur-un-poste}} +Cette section contient une marche à suivre qui décrit les étapes pour +déployer une image sur un poste client quand un serveur est déjà +installé et configuré, que la machine est configurée pour démarrer sur +le réseau. + +\begin{enumerate} +\def\labelenumi{\arabic{enumi}.} +\tightlist +\item + Démarrer la machine et attendre qu'elle +\end{enumerate} + \textbf{TODO: expliquer pas à pas comment utiliser l'interface pour déployer une image sur un client et les différentes inter-actions de l'utilisateur, avec des captures d'écran, etc.} @@ -2229,15 +2816,2270 @@ scripts de personnalisation, avec un exemple type simple.} \chapter{Conclusion}\label{conclusion}} \hypertarget{synthuxe8se-du-travail-effectuuxe9}{% -\subsection{Synthèse du travail +\section{Synthèse du travail effectué}\label{synthuxe8se-du-travail-effectuuxe9}} +Le travail initial a été récupéré, analysé, documenté et remis en +fonctionnement en corrigeant quelques problèmes dans les fichiers de +configuration et les scripts de déploiement. L'outil \emph{Vagrant} a +été utilisé pour automatiser la création d'un serveur virtuel qui +exécute les différents services du système. + +Le système a été ensuite modifié pour le rendre compatible avec les +ordinateurs modernes utilisant le standard +\protect\hyperlink{acronym__UEFI}{UEFI} au lieu d'un +\protect\hyperlink{acronym__BIOS}{BIOS}. + +Des mesures ont été effectuées pour déterminer si le choix du protocole +\protect\hyperlink{acronym__NFS}{NFS}, le protocole réseau utilisé pour +transférer les images, était pertinent. Il été comparé aux protocoles +\protect\hyperlink{acronym__SCP}{SCP}, +\protect\hyperlink{acronym__HTTP}{HTTP}, +\protect\hyperlink{acronym__FTP}{FTP}, +\protect\hyperlink{acronym__NFS}{NFS}, +\protect\hyperlink{acronym__SMB}{SMB} et +\protect\hyperlink{acronym__IPFS}{IPFS} en mesurant le temps de +transfert d'une image. Ces mesures ont montré que les temps de +déploiement avec ces différents protocoles étaient similaires, à +l'exception d'\protect\hyperlink{acronym__IPFS}{IPFS} qui prenait +beaucoup plus de temps. Le protocole +\protect\hyperlink{acronym__NFS}{NFS} a donc été gardé car les mesures +ont prouvé que ses performances étaient similaires à ses alternatives. + +Un format d'images alternatif aux images brutes compressées a été +recherché. Une solution produisant des images plus petites et +déployables plus rapidement a été trouvée: utiliser des images produites +avec l'outil \emph{Clonezilla}. Cet outil permet aussi de faciliter la +création d'images en utilisant sa version \emph{live}. Des mesures +prouvant que ce système de déploiement d'images offre un réel avantage +en espace utilisé et en temps de déploiement par rapport aux images +brutes compressées. + +Le système d'exploitation utilisé pour effectuer le déploiement a été +complètement remplacé. Initialement construit avec \emph{Buildroot}, +avec un système de fichiers racine chargé entièrement en mémoire, il a +été remplacé par un système \emph{Debian} dont le système de fichiers +racine est monté depuis un partage \protect\hyperlink{acronym__NFS}{NFS} +en lecture seule. Ce système permet une installation aisée de tous les +paquets \emph{Debian}, notamment \emph{Clonezilla} qui était compliqué à +installer sur un système construit avec \emph{Buildroot}. La création de +ce système d'exploitation a été automatisée et encapsulée dans un +conteneur \emph{Docker} pour rendre sa modification et reconstruction +très simple, indépendamment du système d'exploitation utilisé. + +Les scripts de déploiement du système initial ont été réécrits. Une +gestion avancée des erreurs a été implémentée. Un système de mesure et +d'affichage du temps d'exécution de chaque partie du déploiement a été +développé. La génération de fichiers de log a été améliorée pour qu'ils +fournissent plus d'informations utiles et qu'ils soient structurés de +manière à rendre leur gestion et leur consultation plus aisée. Le +déploiement d'images avec \emph{Clonezilla} a été implémenté, tout en +gardant la possibilité d'utiliser des images brutes compressées pour +offrir plus de flexibilité et permettre de comparer les deux systèmes. +Le support des images de systèmes d'exploitations compatibles +\protect\hyperlink{acronym__UEFI}{UEFI} a aussi été implémenté, +notamment en permettant de déterminer automatiquement l'exécutable +\protect\hyperlink{acronym__EFI}{EFI} qui devra être lancé pour démarrer +le système déployé. + +Enfin, un système de personnalisation d'un système après son déploiement +a été conçu, permettant de définir des configurations que l'utilisateur +peut choisir de copier ou non sur le système déployé. Une image de +système d'exploitation peut être conçue pour exécuter les fichiers +copiés par ces personnalisations dans un dossier spécifique, pour +permettre des configurations complexes exécutées lors du démarrage avec +un outil choisi, par exemple \emph{Ansible}. Ce système offre beaucoup +de flexibilité et permet de définir des configurations avancées tout en +gardant le système de déploiement indépendant de ce qui est utilisé pour +les exécuter, car le seul mécanisme présent dans le système de +déploiement est la copie de fichiers sur une partition donnée. + \hypertarget{points-damuxe9lioration}{% -\subsection{Points d'amélioration}\label{points-damuxe9lioration}} +\section{Points d'amélioration}\label{points-damuxe9lioration}} + +Bien que le système à la fin de ce projet soit parfaitement fonctionnel, +il existe des points qui devraient ou pourraient être étudiés, améliorés +ou implémentés pour que le système soit prêt à une utilisation dans un +cadre réel. + +\hypertarget{amuxe9lioration-des-performances-de-tuxe9luxe9chargement-des-images-sur-un-ruxe9seau-ruxe9el-avec-de-nombreux-clients-simultanuxe9s}{% +\subsection{Amélioration des performances de téléchargement des images +sur un réseau réel avec de nombreux clients +simultanés}\label{amuxe9lioration-des-performances-de-tuxe9luxe9chargement-des-images-sur-un-ruxe9seau-ruxe9el-avec-de-nombreux-clients-simultanuxe9s}} + +Le protocole réseau utilisé pour le téléchargement des images a été +testé avec un client unique, sur un réseau minimal ne comprenant que le +client et le serveur. Il est très probable que le temps de +téléchargement des images soit beaucoup plus long que celui mesuré dans +le cadre de ce travail si de nombreux clients téléchargent des images en +même temps, dans un réseau plus complexe tel que celui de l'école. + +L'étude et la mitigation de cette problématique a volontairement été +mise de côté dans le cadre de ce travail car il était difficile de +simuler les conditions réelles du système déployé dans une école alors +que tout le travail a été effectué hors de l'école, dans un petit réseau +local domestique avec une quantité limitée d'ordinateurs à disposition +pour faire des tests. + +Différentes approches pourraient être utilisées pour améliorer ces +performances, telles que la copie en \emph{multicast} des images, la +redondance des serveurs mettant à disposition les images ou encore +l'utilisation d'un protocole \emph{pair à pair} tel que +\emph{Bittorrent} ou \emph{IPFS} pour permettre de distribuer le +transfert des images sur tous les clients connectés plutôt que +d'utiliser uniquement le serveur central comme source du fichiers. + +\hypertarget{amuxe9lioration-du-systuxe8me-de-personnalisation-des-images}{% +\subsection{Amélioration du système de personnalisation des +images}\label{amuxe9lioration-du-systuxe8me-de-personnalisation-des-images}} + +Le système de personnalisation des images a été implémenté tardivement +dans le travail. Bien qu'il soit fonctionnel, il n'a pas été testé +extensivement. Il faudrait passer un peu de temps à créer des +configurations post-déploiement complexes qui sont exécutées au +démarrage par le système déployé et de valider leur fonctionnement. + +Par exemple, il était prévu de tester l'exécution de \emph{playbooks} +\emph{Ansible} au démarrage du système, copiés selon les choix de +personnalisation de l'utilisateur. Ces \emph{playbooks} pourraient étre +utilisés pour effectuer de nombreuses actions, telles que l'installation +de groupes de paquets choisis, la génération d'un nom d'hôte unique pour +la machine et la connexion à un domaine \emph{Active Directory} pour +permettre aux élèves de se connecter avec le même nom d'utilisateur et +d'avoir accès à leur dossier \emph{home} depuis un partage +\protect\hyperlink{acronym__NFS}{NFS}, comme sur les postes de travail +standards présents de l'école. + +\hypertarget{amuxe9lioration-de-la-suxe9curituxe9}{% +\subsection{Amélioration de la +sécurité}\label{amuxe9lioration-de-la-suxe9curituxe9}} + +Sur le système actuel, un utilisateur mal intentionné peut détruire ou +modifier les images présentes sur le serveur distant, car elles sont +récupérées sur un partage \protect\hyperlink{acronym__NFS}{NFS} avec des +droits de lecture-écriture. La raison de ce partage en lecture et +écriture est que les logs sont écrits sur le même partage. Une manière +simple de résoudre ce problème serait de séparer ce partage en deux: le +premier en lecture seule contiendrait les images et le second +contiendrait les logs uniquement. + +Il faudrait ensuite trouver une solution pour empêcher une machine +d'aller modifier ou supprimer les logs d'une autre machine, ce qui est +compliqué à mettre en oeuvre avec un partage +\protect\hyperlink{acronym__NFS}{NFS}. Peut être que les logs pourraient +être transmis au serveur en utilisant un autre canal de communication et +de déléguer la création et le nommage du fichier au serveur, pour que +les clients ne soient plus capables d'accéder directement aux fichiers +des logs, mais que ce soit le serveur qui ait la responsabilité de les +créer et de les gérer. + +\hypertarget{ruxe9trospection-sur-le-duxe9roulement-du-travail}{% +\section{Rétrospection sur le déroulement du +travail}\label{ruxe9trospection-sur-le-duxe9roulement-du-travail}} + +J'ai eu beaucoup d'intérêt à travailler sur ce sujet. Cela m'a permis de +mettre en pratique de nombreuses compétences acquises lors des cours +suivis les quatre années précédentes, dont en particulier les cours de +programmation des systèmes (\emph{sIT\_242}), systèmes d'exploitation +(\emph{sIT\_244}), réseaux et protocoles informatiques (sIT\_362), +réseaux avancés (\emph{sIT\_384}), programmation avancée des systèmes +(\emph{sIT\_632}) et virtualisation des +\protect\hyperlink{acronym__SI}{SI} (\emph{sIT\_632}). + +\hypertarget{ruxe9fuxe9rences}{% +\chapter{Références}\label{ruxe9fuxe9rences}} + +\appendix + +\hypertarget{appendix_source}{% +\chapter{Codes sources notables}\label{appendix_source}} + +Cette annexe contient les listings des codes sources les plus importants +du projet. + +\hypertarget{makefile-configuration-gnu-make-du-projet}{% +\section{\texorpdfstring{\texttt{Makefile}: configuration \emph{GNU +Make} du +projet}{Makefile: configuration GNU Make du projet}}\label{makefile-configuration-gnu-make-du-projet}} + +\begin{Shaded} +\begin{Highlighting}[] +\DataTypeTok{SHELL }\CharTok{:=}\StringTok{ /bin/bash} +\DataTypeTok{MAKEFLAGS }\CharTok{+=}\StringTok{ "{-}j 4"} + +\DataTypeTok{DOCKER\_BUILDKIT\_BUILD }\CharTok{=}\StringTok{ DOCKER\_BUILDKIT=1 docker build {-}{-}progress=plain} + +\DataTypeTok{GRUB\_SRC }\CharTok{:=}\StringTok{ }\CharTok{$(}\KeywordTok{shell}\StringTok{ find grub/bootiful{-}grub/ {-}type f {-}regex ".*\textbackslash{}.[c|h|sh|py|cfg|conf]"}\CharTok{)} +\DataTypeTok{GRUB\_I386\_PC\_BIN }\CharTok{=}\StringTok{ tftp/tftpboot/boot/grub/i386{-}pc/core.0} +\DataTypeTok{GRUB\_I386\_EFI\_BIN }\CharTok{=}\StringTok{ tftp/tftpboot/boot/grub/i386{-}efi/core.efi} +\DataTypeTok{GRUB\_X86\_64\_EFI\_BIN }\CharTok{=}\StringTok{ tftp/tftpboot/boot/grub/x86\_64{-}efi/core.efi} +\DataTypeTok{DEPLOYER\_SRC }\CharTok{:=}\StringTok{ }\CharTok{$(}\KeywordTok{wildcard}\StringTok{ deployer/*}\CharTok{)} +\DataTypeTok{TFTP\_DEPLOYER\_DIR }\CharTok{=}\StringTok{ tftp/tftpboot/boot/deployer} +\DataTypeTok{TFTP\_DEPLOYER\_VMLINUZ }\CharTok{:=}\StringTok{ }\CharTok{$(}\DataTypeTok{TFTP\_DEPLOYER\_DIR}\CharTok{)}\StringTok{/vmlinuz} +\DataTypeTok{TFTP\_DEPLOYER\_INITRD }\CharTok{:=}\StringTok{ }\CharTok{$(}\DataTypeTok{TFTP\_DEPLOYER\_DIR}\CharTok{)}\StringTok{/initrd.img} +\DataTypeTok{NFS\_DEPLOYER\_ROOT }\CharTok{:=}\StringTok{ nfs/nfsroot.tar.gz} +\DataTypeTok{LATEST\_LOG }\CharTok{:=}\StringTok{ }\CharTok{$(}\KeywordTok{shell}\StringTok{ ls {-}1 nfs/nfsshared/log/*.log | tail {-}n 1}\CharTok{)} + +\OtherTok{.PHONY:}\DataTypeTok{ doc grub deployer start{-}server reprovision{-}server clean print\_last\_log help} + +\CommentTok{\# Builds everything} +\DecValTok{all:}\DataTypeTok{ doc grub deployer} + +\CommentTok{\# Builds PDF and markdown documents} +\DecValTok{doc:} + \CharTok{$(}\DataTypeTok{MAKE}\CharTok{)}\NormalTok{ {-}C doc} + +\DecValTok{grub/bootiful{-}grub/bootstrap partclone/bootiful{-}partclone/Makefile.am:}\DataTypeTok{ .gitmodules} +\NormalTok{ git submodule init \&\& git submodule update} + +\CommentTok{\# Bootstraps GRUB dependencies and configuration script} +\DecValTok{grub/bootiful{-}grub/configure:}\DataTypeTok{ grub/bootiful{-}grub/bootstrap} +\NormalTok{ (pushd grub/bootiful{-}grub \&\& ./bootstrap; popd)} + +\CommentTok{\# Builds GRUB for i386{-}pc} +\DecValTok{$(GRUB\_I386\_PC\_BIN):}\DataTypeTok{ grub/Dockerfile grub/bootiful{-}grub/configure }\CharTok{$(}\DataTypeTok{GRUB\_SRC}\CharTok{)} + \CharTok{$(}\DataTypeTok{DOCKER\_BUILDKIT\_BUILD}\CharTok{)}\NormalTok{ ./grub }\CharTok{\textbackslash{}} +\NormalTok{ {-}{-}output ./tftp/tftpboot }\CharTok{\textbackslash{}} +\NormalTok{ {-}{-}build{-}arg PLATFORM=pc }\CharTok{\textbackslash{}} +\NormalTok{ {-}{-}build{-}arg TARGET=i386} + +\CommentTok{\# Builds GRUB for i386{-}efi} +\DecValTok{$(GRUB\_I386\_EFI\_BIN):}\DataTypeTok{ grub/Dockerfile grub/bootiful{-}grub/configure }\CharTok{$(}\DataTypeTok{GRUB\_SRC}\CharTok{)} + \CharTok{$(}\DataTypeTok{DOCKER\_BUILDKIT\_BUILD}\CharTok{)}\NormalTok{ ./grub }\CharTok{\textbackslash{}} +\NormalTok{ {-}{-}output ./tftp/tftpboot }\CharTok{\textbackslash{}} +\NormalTok{ {-}{-}build{-}arg PLATFORM=efi }\CharTok{\textbackslash{}} +\NormalTok{ {-}{-}build{-}arg TARGET=i386} + +\CommentTok{\# Builds GRUB for x86\_64{-}efi} +\DecValTok{$(GRUB\_X86\_64\_EFI\_BIN):}\DataTypeTok{ grub/Dockerfile grub/bootiful{-}grub/configure }\CharTok{$(}\DataTypeTok{GRUB\_SRC}\CharTok{)} + \CharTok{$(}\DataTypeTok{DOCKER\_BUILDKIT\_BUILD}\CharTok{)}\NormalTok{ ./grub }\CharTok{\textbackslash{}} +\NormalTok{ {-}{-}output ./tftp/tftpboot }\CharTok{\textbackslash{}} +\NormalTok{ {-}{-}build{-}arg PLATFORM=efi }\CharTok{\textbackslash{}} +\NormalTok{ {-}{-}build{-}arg TARGET=x86\_64} + +\CommentTok{\# Builds GRUB for all platforms} +\DecValTok{grub:}\DataTypeTok{ }\CharTok{$(}\DataTypeTok{GRUB\_I386\_PC\_BIN}\CharTok{)}\DataTypeTok{ }\CharTok{$(}\DataTypeTok{GRUB\_I386\_EFI\_BIN}\CharTok{)}\DataTypeTok{ }\CharTok{$(}\DataTypeTok{GRUB\_X86\_64\_EFI\_BIN}\CharTok{)} + +\CommentTok{\# Builds the deployer OS} +\DecValTok{deployer:}\DataTypeTok{ }\CharTok{$(}\DataTypeTok{TFTP\_DEPLOYER\_VMLINUZ}\CharTok{)}\DataTypeTok{ }\CharTok{$(}\DataTypeTok{TFTP\_DEPLOYER\_INITRD}\CharTok{)}\DataTypeTok{ }\CharTok{$(}\DataTypeTok{NFS\_DEPLOYER\_ROOT}\CharTok{)} + +\DecValTok{$(TFTP\_DEPLOYER\_VMLINUZ) $(TFTP\_DEPLOYER\_INITRD) \&:}\DataTypeTok{ }\CharTok{$(}\DataTypeTok{DEPLOYER\_SRC}\CharTok{)} + \CharTok{$(}\DataTypeTok{DOCKER\_BUILDKIT\_BUILD}\CharTok{)}\NormalTok{ ./deployer {-}{-}target tftp{-}export{-}stage {-}{-}output }\CharTok{$(}\DataTypeTok{TFTP\_DEPLOYER\_DIR}\CharTok{)}\NormalTok{ \&\& }\CharTok{\textbackslash{}} +\NormalTok{ touch {-}c }\CharTok{$(}\DataTypeTok{TFTP\_DEPLOYER\_VMLINUZ}\CharTok{)} \CharTok{$(}\DataTypeTok{TFTP\_DEPLOYER\_INITRD}\CharTok{)} + +\DecValTok{$(NFS\_DEPLOYER\_ROOT):}\DataTypeTok{ }\CharTok{$(}\DataTypeTok{DEPLOYER\_SRC}\CharTok{)} + \CharTok{$(}\DataTypeTok{DOCKER\_BUILDKIT\_BUILD}\CharTok{)}\NormalTok{ ./deployer {-}{-}target nfs{-}export{-}stage {-}{-}output nfs/ \&\& }\CharTok{\textbackslash{}} +\NormalTok{ touch {-}c }\CharTok{$(}\DataTypeTok{NFS\_DEPLOYER\_ROOT}\CharTok{)} + +\CommentTok{\# Starts bootiful services in docker containers} +\DecValTok{start{-}server:}\DataTypeTok{ grub deployer} +\NormalTok{ docker{-}compose up {-}{-}build {-}{-}remove{-}orphans {-}{-}abort{-}on{-}container{-}exit} + +\CommentTok{\# Removes all generated files} +\DecValTok{clean:} +\NormalTok{ rm {-}rf deployer/rootfs} + \CharTok{$(}\DataTypeTok{MAKE}\CharTok{)}\NormalTok{ {-}C doc clean} + +\CommentTok{\# Prints the latest deployment log file} +\DecValTok{print{-}latest{-}log:} +\NormalTok{ cat }\CharTok{$(}\DataTypeTok{LATEST\_LOG}\CharTok{)} + +\CommentTok{\# Show this help.} +\DecValTok{help:} +\NormalTok{ printf }\StringTok{"Usage: make \textless{}target\textgreater{}\textbackslash{}n\textbackslash{}nTargets:\textbackslash{}n"} +\NormalTok{ awk }\StringTok{\textquotesingle{}/\^{}\#/\{c=substr(}\CharTok{$$}\StringTok{0,3);next\}c\&\&/\^{}[[:alpha:]][[:alnum:]\_{-}]+:/\{print " " substr(}\CharTok{$$}\StringTok{1,1,index(}\CharTok{$$}\StringTok{1,":")),c\}1\{c=0\}\textquotesingle{}} \CharTok{$(}\DataTypeTok{MAKEFILE\_LIST}\CharTok{)}\NormalTok{ | column {-}s: {-}t} +\end{Highlighting} +\end{Shaded} + +\hypertarget{docker-compose.yml-configuration-docker-compose-du-serveur-de-duxe9ploiement}{% +\section{\texorpdfstring{\texttt{docker-compose.yml}: configuration +\emph{docker-compose} du serveur de +déploiement}{docker-compose.yml: configuration docker-compose du serveur de déploiement}}\label{docker-compose.yml-configuration-docker-compose-du-serveur-de-duxe9ploiement}} + +\begin{Shaded} +\begin{Highlighting}[] +\FunctionTok{version}\KeywordTok{:}\AttributeTok{ }\StringTok{"3.8"} + +\FunctionTok{services}\KeywordTok{:} +\AttributeTok{ }\FunctionTok{bootiful{-}dhcp}\KeywordTok{:} +\AttributeTok{ }\FunctionTok{build}\KeywordTok{:}\AttributeTok{ ./dhcp} +\AttributeTok{ }\FunctionTok{network\_mode}\KeywordTok{:}\AttributeTok{ host} +\AttributeTok{ }\FunctionTok{bootiful{-}tftp}\KeywordTok{:} +\AttributeTok{ }\FunctionTok{build}\KeywordTok{:}\AttributeTok{ ./tftp} +\AttributeTok{ }\FunctionTok{network\_mode}\KeywordTok{:}\AttributeTok{ host} +\AttributeTok{ }\FunctionTok{volumes}\KeywordTok{:} +\AttributeTok{ }\KeywordTok{{-}}\AttributeTok{ }\FunctionTok{type}\KeywordTok{:}\AttributeTok{ bind} +\AttributeTok{ }\FunctionTok{source}\KeywordTok{:}\AttributeTok{ ./tftp/tftpboot} +\AttributeTok{ }\FunctionTok{target}\KeywordTok{:}\AttributeTok{ /tftpboot} +\AttributeTok{ }\FunctionTok{read\_only}\KeywordTok{:}\AttributeTok{ }\CharTok{yes} +\AttributeTok{ }\FunctionTok{bootiful{-}nfs}\KeywordTok{:} +\AttributeTok{ }\FunctionTok{build}\KeywordTok{:}\AttributeTok{ ./nfs} +\AttributeTok{ }\FunctionTok{network\_mode}\KeywordTok{:}\AttributeTok{ host} +\AttributeTok{ }\FunctionTok{privileged}\KeywordTok{:}\AttributeTok{ }\CharTok{yes} +\AttributeTok{ }\FunctionTok{volumes}\KeywordTok{:} +\AttributeTok{ }\KeywordTok{{-}}\AttributeTok{ }\FunctionTok{type}\KeywordTok{:}\AttributeTok{ tmpfs} +\AttributeTok{ }\FunctionTok{target}\KeywordTok{:}\AttributeTok{ /nfsroot} +\AttributeTok{ }\KeywordTok{{-}}\AttributeTok{ }\FunctionTok{type}\KeywordTok{:}\AttributeTok{ bind} +\AttributeTok{ }\FunctionTok{source}\KeywordTok{:}\AttributeTok{ /run/media/araxor/bigdata/nfsshared} +\AttributeTok{ }\FunctionTok{target}\KeywordTok{:}\AttributeTok{ /nfsshared} +\AttributeTok{ }\KeywordTok{{-}}\AttributeTok{ }\FunctionTok{type}\KeywordTok{:}\AttributeTok{ bind} +\AttributeTok{ }\FunctionTok{source}\KeywordTok{:}\AttributeTok{ /lib/modules} +\AttributeTok{ }\FunctionTok{target}\KeywordTok{:}\AttributeTok{ /lib/modules} +\AttributeTok{ }\FunctionTok{read\_only}\KeywordTok{:}\AttributeTok{ }\CharTok{yes} +\AttributeTok{ }\FunctionTok{environment}\KeywordTok{:} +\AttributeTok{ }\FunctionTok{NFS\_LOG\_LEVEL}\KeywordTok{:}\AttributeTok{ DEBUG} +\end{Highlighting} +\end{Shaded} + +\hypertarget{deployer_dockerfile}{% +\section{\texorpdfstring{\texttt{deployer/Dockerfile}: configuration +\emph{Docker} pour la construction de l'OS de +déploiement}{deployer/Dockerfile: configuration Docker pour la construction de l'OS de déploiement}}\label{deployer_dockerfile}} + +\begin{Shaded} +\begin{Highlighting}[] +\KeywordTok{FROM}\NormalTok{ debian:bullseye as build{-}stage} +\KeywordTok{RUN}\NormalTok{ apt{-}get update \&\& apt{-}get install {-}y multistrap} + +\KeywordTok{WORKDIR}\NormalTok{ /multistrap} + +\KeywordTok{ADD}\NormalTok{ ./multistrap.config ./} +\KeywordTok{RUN}\NormalTok{ multistrap {-}{-}arch amd64 {-}{-}file ./multistrap.config {-}{-}dir ./rootfs {-}{-}tidy{-}up} + +\KeywordTok{ADD}\NormalTok{ ./hostname ./rootfs/etc/hostname} +\KeywordTok{ADD}\NormalTok{ ./hosts ./rootfs/etc/hosts} +\KeywordTok{ADD}\NormalTok{ ./fstab ./rootfs/etc/fstab} +\KeywordTok{ADD}\NormalTok{ ./initramfs.conf ./rootfs/etc/initramfs{-}tools/initramfs.conf} +\KeywordTok{ADD}\NormalTok{ ./bootiful{-}deploy{-}log.service ./rootfs/etc/systemd/system/bootiful{-}deploy{-}log.service} + +\KeywordTok{ADD}\NormalTok{ ./configure.sh ./rootfs/} +\KeywordTok{RUN}\NormalTok{ chroot /multistrap/rootfs ./configure.sh} + +\KeywordTok{RUN}\NormalTok{ mkdir ./boot ./rootfs/bootiful ./rootfs/var/lib/clonezilla ./rootfs/home/partimag} +\KeywordTok{RUN}\NormalTok{ ln {-}s /proc/mounts rootfs/etc/mtab} +\KeywordTok{RUN}\NormalTok{ cp ./rootfs/vmlinuz ./rootfs/initrd.img ./boot/ \&\& \textbackslash{}} +\NormalTok{ rm {-}rf ./rootfs/configure.sh ./rootfs/vmlinuz* ./rootfs/initrd.img* ./rootfs/boot} + +\KeywordTok{ADD}\NormalTok{ ./bootiful{-}deploy{-}init ./rootfs/usr/bin/} +\KeywordTok{ADD}\NormalTok{ ./bootiful{-}common ./rootfs/usr/bin/} +\KeywordTok{ADD}\NormalTok{ ./bootiful{-}deploy ./rootfs/usr/bin/} +\KeywordTok{ADD}\NormalTok{ ./bootiful{-}save{-}image ./rootfs/usr/bin/} +\KeywordTok{ADD}\NormalTok{ ./bootiful{-}reset{-}cache ./rootfs/usr/bin/} +\KeywordTok{RUN}\NormalTok{ tar {-}czf nfsroot.tar.gz rootfs {-}{-}hard{-}dereference \&\& rm {-}rf ./rootfs} + +\KeywordTok{FROM}\NormalTok{ scratch AS nfs{-}export{-}stage} +\KeywordTok{COPY}\NormalTok{ {-}{-}from=build{-}stage /multistrap/nfsroot.tar.gz /} + +\KeywordTok{FROM}\NormalTok{ scratch AS tftp{-}export{-}stage} +\KeywordTok{COPY}\NormalTok{ {-}{-}from=build{-}stage /multistrap/boot /} + +\end{Highlighting} +\end{Shaded} + +\hypertarget{deployerbootiful-deploy-log.service-configuration-de-lunituxe9-systemd-des-script-de-duxe9ploiement}{% +\section{\texorpdfstring{\texttt{deployer/bootiful-deploy-log.service}: +configuration de l'unité \emph{Systemd} des script de +déploiement}{deployer/bootiful-deploy-log.service: configuration de l'unité Systemd des script de déploiement}}\label{deployerbootiful-deploy-log.service-configuration-de-lunituxe9-systemd-des-script-de-duxe9ploiement}} + +\begin{Shaded} +\begin{Highlighting}[] +\KeywordTok{[Unit]} +\DataTypeTok{Description}\OtherTok{=}\StringTok{Bootiful interactive remote image deployment} +\DataTypeTok{Conflicts}\OtherTok{=}\StringTok{gettytty1.service} +\DataTypeTok{Before}\OtherTok{=}\StringTok{getty.target} + +\KeywordTok{[Service]} +\DataTypeTok{Type}\OtherTok{=}\StringTok{oneshot} +\DataTypeTok{RemainAfterExit}\OtherTok{=}\KeywordTok{yes} +\DataTypeTok{ExecStartPre}\OtherTok{=}\StringTok{/bin/sleep }\DecValTok{2} +\DataTypeTok{ExecStart}\OtherTok{=}\StringTok{/usr/bin/bootiful{-}deploy{-}init} +\DataTypeTok{StandardInput}\OtherTok{=}\StringTok{tty} +\DataTypeTok{StandardOutput}\OtherTok{=}\StringTok{tty} +\DataTypeTok{StandardError}\OtherTok{=}\StringTok{tty} +\DataTypeTok{ } +\KeywordTok{[Install]} +\DataTypeTok{WantedBy}\OtherTok{=}\StringTok{multi{-}user.target} +\end{Highlighting} +\end{Shaded} + +\hypertarget{deployerinitramfs.conf-configuration-pour-cruxe9ation-dun-initramfs-pour-duxe9marrer-avec-nfs}{% +\section{\texorpdfstring{\texttt{deployer/initramfs.conf}: configuration +pour création d'un \emph{initramfs} pour démarrer avec +\protect\hyperlink{acronym__NFS}{NFS}}{deployer/initramfs.conf: configuration pour création d'un initramfs pour démarrer avec NFS}}\label{deployerinitramfs.conf-configuration-pour-cruxe9ation-dun-initramfs-pour-duxe9marrer-avec-nfs}} + +\begin{Shaded} +\begin{Highlighting}[] +\CommentTok{\#} +\CommentTok{\# initramfs.conf} +\CommentTok{\# Configuration file for mkinitramfs(8). See initramfs.conf(5).} +\CommentTok{\#} +\CommentTok{\# Note that configuration options from this file can be overridden} +\CommentTok{\# by config files in the /etc/initramfs{-}tools/conf.d directory.} + +\CommentTok{\#} +\CommentTok{\# MODULES: [ most | netboot | dep | list ]} +\CommentTok{\#} +\CommentTok{\# most {-} Add most filesystem and all harddrive drivers.} +\CommentTok{\#} +\CommentTok{\# dep {-} Try and guess which modules to load.} +\CommentTok{\#} +\CommentTok{\# netboot {-} Add the base modules, network modules, but skip block devices.} +\CommentTok{\#} +\CommentTok{\# list {-} Only include modules from the \textquotesingle{}additional modules\textquotesingle{} list} +\CommentTok{\#} + +\VariableTok{MODULES=}\NormalTok{netboot} + +\CommentTok{\#} +\CommentTok{\# BUSYBOX: [ y | n | auto ]} +\CommentTok{\#} +\CommentTok{\# Use busybox shell and utilities. If set to n, klibc utilities will be used.} +\CommentTok{\# If set to auto (or unset), busybox will be used if installed and klibc will} +\CommentTok{\# be used otherwise.} +\CommentTok{\#} + +\VariableTok{BUSYBOX=}\NormalTok{auto} + +\CommentTok{\#} +\CommentTok{\# KEYMAP: [ y | n ]} +\CommentTok{\#} +\CommentTok{\# Load a keymap during the initramfs stage.} +\CommentTok{\#} + +\VariableTok{KEYMAP=}\NormalTok{n} + +\CommentTok{\#} +\CommentTok{\# COMPRESS: [ gzip | bzip2 | lz4 | lzma | lzop | xz ]} +\CommentTok{\#} + +\VariableTok{COMPRESS=}\NormalTok{xz} + +\CommentTok{\#} +\CommentTok{\# NFS Section of the config.} +\CommentTok{\#} + +\CommentTok{\#} +\CommentTok{\# DEVICE: ...} +\CommentTok{\#} +\CommentTok{\# Specify a specific network interface, like eth0} +\CommentTok{\# Overridden by optional ip= or BOOTIF= bootarg} +\CommentTok{\#} + +\VariableTok{DEVICE=} + +\CommentTok{\#} +\CommentTok{\# NFSROOT: [ auto | HOST:MOUNT ]} +\CommentTok{\#} + +\VariableTok{NFSROOT=}\NormalTok{auto} + +\CommentTok{\#} +\CommentTok{\# RUNSIZE: ...} +\CommentTok{\#} +\CommentTok{\# The size of the /run tmpfs mount point, like 256M or 10\%} +\CommentTok{\# Overridden by optional initramfs.runsize= bootarg} +\CommentTok{\#} + +\VariableTok{RUNSIZE=}\NormalTok{10}\ExtensionTok{\%} +\end{Highlighting} +\end{Shaded} + +\hypertarget{deployermultistrap.config-configuration-multistrap-pour-la-cruxe9ation-du-systuxe8me-de-fichiers-racine}{% +\section{\texorpdfstring{\texttt{deployer/multistrap.config}: +configuration \emph{multistrap} pour la création du système de fichiers +racine}{deployer/multistrap.config: configuration multistrap pour la création du système de fichiers racine}}\label{deployermultistrap.config-configuration-multistrap-pour-la-cruxe9ation-du-systuxe8me-de-fichiers-racine}} + +\begin{Shaded} +\begin{Highlighting}[] +\KeywordTok{[General]} +\DataTypeTok{unpack}\OtherTok{=}\KeywordTok{true} +\DataTypeTok{bootstrap}\OtherTok{=}\StringTok{DRBL Debian} +\DataTypeTok{aptsources}\OtherTok{=}\StringTok{Debian} +\DataTypeTok{addimportant}\OtherTok{=}\KeywordTok{true} + +\KeywordTok{[Debian]} +\DataTypeTok{packages}\OtherTok{=}\StringTok{nfs{-}common linux{-}image{-}amd64 parted systemd udev strace zstd dialog lolcat gdisk gawk pigz pv clonezilla partclone partimage cifs{-}utils} +\DataTypeTok{source}\OtherTok{=}\StringTok{http://http.debian.net/debian} +\DataTypeTok{keyring}\OtherTok{=}\StringTok{debian{-}archive{-}keyring} +\DataTypeTok{suite}\OtherTok{=}\StringTok{bullseye} +\DataTypeTok{components}\OtherTok{=}\StringTok{main contrib non{-}free} +\end{Highlighting} +\end{Shaded} + +\hypertarget{deployerconfigure.sh-script-de-configuration-du-systuxe8me-de-fichier-racine-uxe0-exuxe9cuter-en-chroot}{% +\section{\texorpdfstring{\texttt{deployer/configure.sh}: script de +configuration du système de fichier racine à exécuter en +\texttt{chroot}}{deployer/configure.sh: script de configuration du système de fichier racine à exécuter en chroot}}\label{deployerconfigure.sh-script-de-configuration-du-systuxe8me-de-fichier-racine-uxe0-exuxe9cuter-en-chroot}} + +\begin{Shaded} +\begin{Highlighting}[] +\CommentTok{\#!/bin/bash} + +\KeywordTok{set} \ExtensionTok{{-}e} + +\BuiltInTok{export} \VariableTok{DEBIAN\_FRONTEND=}\NormalTok{noninteractive }\VariableTok{DEBCONF\_NONINTERACTIVE\_SEEN=}\NormalTok{true} +\BuiltInTok{export} \VariableTok{LC\_ALL=}\NormalTok{C }\VariableTok{LANGUAGE=}\NormalTok{C }\VariableTok{LANG=}\NormalTok{C} + +\ExtensionTok{dpkg}\NormalTok{ {-}{-}configure {-}a} + +\ExtensionTok{apt{-}get}\NormalTok{ autoremove {-}{-}purge} +\ExtensionTok{apt{-}get}\NormalTok{ clean} + +\ExtensionTok{update{-}initramfs}\NormalTok{ {-}u} + +\ExtensionTok{systemctl}\NormalTok{ enable bootiful{-}deploy{-}log.service} + +\BuiltInTok{echo} \StringTok{"root:bootiful"} \KeywordTok{|} \ExtensionTok{chpasswd} +\end{Highlighting} +\end{Shaded} + +\hypertarget{deployerbootiful-deploy-init-script-dinitialisation-du-duxe9ploiement}{% +\section{\texorpdfstring{\texttt{deployer/bootiful-deploy-init}: script +d'initialisation du +déploiement}{deployer/bootiful-deploy-init: script d'initialisation du déploiement}}\label{deployerbootiful-deploy-init-script-dinitialisation-du-duxe9ploiement}} + +\begin{Shaded} +\begin{Highlighting}[] +\CommentTok{\#!/bin/bash} + +\BuiltInTok{umask}\NormalTok{ {-}S 0000 }\OperatorTok{\&\textgreater{}}\NormalTok{/dev/null} +\FunctionTok{clear} +\ExtensionTok{/usr/games/lolcat}\NormalTok{ {-}a {-}d 6 {-}s 20 {-}F 0.5 }\OperatorTok{\textless{}\textless{}\textquotesingle{}EOF\textquotesingle{}} +\NormalTok{ .o8 . o8o .o88o. oooo} +\NormalTok{"888 .o8 \textasciigrave{}"\textquotesingle{} 888 \textasciigrave{}" \textasciigrave{}888} +\NormalTok{ 888oooo. .ooooo. .ooooo. .o888oo oooo o888oo oooo oooo 888} +\NormalTok{ d88\textquotesingle{} \textasciigrave{}88b d88\textquotesingle{} \textasciigrave{}88b d88\textquotesingle{} \textasciigrave{}88b 888 \textasciigrave{}888 888 \textasciigrave{}888 \textasciigrave{}888 888} +\NormalTok{ 888 888 888 888 888 888 888 888 888 888 888 888} +\NormalTok{ 888 888 888 888 888 888 888 . 888 888 888 888 888} +\NormalTok{ \textasciigrave{}Y8bod8P\textquotesingle{} \textasciigrave{}Y8bod8P\textquotesingle{} \textasciigrave{}Y8bod8P\textquotesingle{} "888" o888o o888o \textasciigrave{}V88V"V8P\textquotesingle{} o888o} +\OperatorTok{EOF} +\BuiltInTok{declare} \VariableTok{logo\_pressed\_key} +\BuiltInTok{read}\NormalTok{ {-}t 0.001 {-}n 1 {-}s {-}r }\VariableTok{logo\_pressed\_key} +\BuiltInTok{readonly} \VariableTok{logo\_pressed\_key} + +\FunctionTok{select\_next\_action()} \KeywordTok{\{} + \BuiltInTok{local} \VariableTok{next\_action\_pressed\_key} + \KeywordTok{while} \FunctionTok{true}\KeywordTok{;} \KeywordTok{do} + \BuiltInTok{echo} + \BuiltInTok{echo} \StringTok{"Press \textquotesingle{}d\textquotesingle{} to restart deployment"} + \BuiltInTok{echo} \StringTok{"Press \textquotesingle{}s\textquotesingle{} to start an interactive command{-}line shell"} + \BuiltInTok{echo} \StringTok{"Press \textquotesingle{}r\textquotesingle{} to reboot"} + \BuiltInTok{echo} \StringTok{"Press \textquotesingle{}p\textquotesingle{} to power off"} + + \BuiltInTok{read}\NormalTok{ {-}n 1 {-}s {-}r }\VariableTok{next\_action\_pressed\_key} + \KeywordTok{case} \StringTok{"}\VariableTok{$next\_action\_pressed\_key}\StringTok{"}\KeywordTok{ in} +\NormalTok{ [dD]}\KeywordTok{)} + \BuiltInTok{echo} \StringTok{"Restarting deployment..."} + \BuiltInTok{break} + \KeywordTok{;;} +\NormalTok{ [sS]}\KeywordTok{)} + \BuiltInTok{echo} \StringTok{"Starting an interactive command{-}line shell..."} + \ExtensionTok{/bin/bash}\NormalTok{ {-}i} + \KeywordTok{;;} +\NormalTok{ [rR]}\KeywordTok{)} + \BuiltInTok{echo} \StringTok{"Rebooting..."} + \ExtensionTok{reboot} + \KeywordTok{;;} +\NormalTok{ [pP]}\KeywordTok{)} + \BuiltInTok{echo} \StringTok{"Powering off..."} + \ExtensionTok{poweroff} + \KeywordTok{;;} +\NormalTok{ *}\KeywordTok{)} + \BuiltInTok{echo} \StringTok{"Error: No action defined for key \textquotesingle{}}\VariableTok{$next\_action\_pressed\_key}\StringTok{\textquotesingle{}"} + \KeywordTok{;;} + \KeywordTok{esac} + \KeywordTok{done} +\KeywordTok{\}} + +\KeywordTok{if [[} \StringTok{"}\VariableTok{$logo\_pressed\_key}\StringTok{"}\NormalTok{ =\textasciitilde{} \^{}[sS]$}\KeywordTok{ ]]}\NormalTok{; }\KeywordTok{then} + \BuiltInTok{echo} \StringTok{"Skipping deployment...."} + \ExtensionTok{/bin/bash}\NormalTok{ {-}i} + \ExtensionTok{select\_next\_action} +\KeywordTok{fi} + +\KeywordTok{while}\NormalTok{ ! }\ExtensionTok{bootiful{-}deploy}\KeywordTok{;} \KeywordTok{do} + \BuiltInTok{echo} \StringTok{"Error in deployment."} + \ExtensionTok{select\_next\_action} +\KeywordTok{done} + +\BuiltInTok{echo} \StringTok{"Deployment successful. Rebooting..."} +\ExtensionTok{reboot} + +\end{Highlighting} +\end{Shaded} + +\hypertarget{deployerbootiful-common-script-de-duxe9finition-des-fonctions-communes-aux-scripts-bootiful-}{% +\section{\texorpdfstring{\texttt{deployer/bootiful-common}: script de +définition des fonctions communes aux scripts +\texttt{bootiful-*}}{deployer/bootiful-common: script de définition des fonctions communes aux scripts bootiful-*}}\label{deployerbootiful-common-script-de-duxe9finition-des-fonctions-communes-aux-scripts-bootiful-}} + +\begin{Shaded} +\begin{Highlighting}[] +\CommentTok{\#!/bin/bash} + +\KeywordTok{if [[} \StringTok{"}\VariableTok{$\{BASH\_SOURCE[0]\}}\StringTok{"} \OtherTok{==} \StringTok{"}\VariableTok{$0}\StringTok{"}\KeywordTok{ ]]}\NormalTok{; }\KeywordTok{then} + \BuiltInTok{echo} \OperatorTok{\textgreater{}\&2} \StringTok{"Error: script \textquotesingle{}}\VariableTok{$0}\StringTok{\textquotesingle{} must be sourced, not executed."} + \BuiltInTok{return}\NormalTok{ 1} +\KeywordTok{fi} + +\KeywordTok{if [[} \OtherTok{{-}n} \StringTok{"}\VariableTok{$BOOTIFUL\_COMMON\_SOURCED}\StringTok{"}\KeywordTok{ ]]}\NormalTok{; }\KeywordTok{then} + \BuiltInTok{echo} \OperatorTok{\textgreater{}\&2} \StringTok{"Warning: script \textquotesingle{}}\VariableTok{$0}\StringTok{\textquotesingle{} sourced more than once."} + \BuiltInTok{return}\NormalTok{ 0} +\KeywordTok{fi} + +\BuiltInTok{readonly} \VariableTok{BOOTIFUL\_COMMON\_SOURCED=}\NormalTok{true} + +\FunctionTok{echo\_err()} \KeywordTok{\{} + \BuiltInTok{echo} \OperatorTok{\textgreater{}\&2} \StringTok{"$"} +\KeywordTok{\}} + +\CommentTok{\# Writes an error message and a stack trace to stderr, then exits the current} +\CommentTok{\# shell with the error status code 1.} +\CommentTok{\#} +\CommentTok{\# Warning: if called in a sub{-}shell, the error messages are written to stderr} +\CommentTok{\# but only the sub{-}shell is exited. The parent shell should always} +\CommentTok{\# check the sub{-}shells exit status codes and call \textasciigrave{}fatal\_error\textasciigrave{} if a} +\CommentTok{\# non{-}0 exit status is returned.} +\FunctionTok{fatal\_error()} \KeywordTok{\{} + \BuiltInTok{local}\NormalTok{ {-}r }\VariableTok{message=}\StringTok{"}\VariableTok{$\{1:{-}}\NormalTok{unknown reason}\VariableTok{\}}\StringTok{"} + + \ExtensionTok{echo\_err} \StringTok{"Fatal error: }\VariableTok{$message}\StringTok{"} + + \ExtensionTok{echo\_err} \StringTok{"Stack trace:"} + \BuiltInTok{local} \VariableTok{frame=}\NormalTok{0} + \KeywordTok{while} \OperatorTok{\textgreater{}\&2} \BuiltInTok{caller} \VariableTok{$frame}\KeywordTok{;} \KeywordTok{do} + \KeywordTok{((}\NormalTok{frame++}\KeywordTok{))} + \KeywordTok{done} + + \BuiltInTok{exit}\NormalTok{ 1} +\KeywordTok{\}} + +\CommentTok{\# If the INT signal (ctrl+c) is received, a fatal error is thrown} +\FunctionTok{fatal\_error\_on\_sigint()} \KeywordTok{\{} + \ExtensionTok{fatal\_error} \StringTok{"SIGINT received"} +\KeywordTok{\}} +\BuiltInTok{trap}\NormalTok{ fatal\_error\_on\_sigint INT} + +\BuiltInTok{declare}\NormalTok{ {-}a }\VariableTok{exit\_callbacks=()} +\FunctionTok{execute\_exit\_callbacks()} \KeywordTok{\{} + \KeywordTok{for} \ExtensionTok{exit\_callback}\NormalTok{ in }\StringTok{"}\VariableTok{$\{exit\_callbacks[]\}}\StringTok{"}\KeywordTok{;} \KeywordTok{do} + \StringTok{"}\VariableTok{$exit\_callback}\StringTok{"} + \KeywordTok{done} +\KeywordTok{\}} +\BuiltInTok{trap} \StringTok{\textquotesingle{}execute\_exit\_callbacks\textquotesingle{}}\NormalTok{ EXIT} + +\FunctionTok{add\_exit\_callback()} \KeywordTok{\{} + \BuiltInTok{local}\NormalTok{ {-}r }\VariableTok{exit\_callback\_function=}\StringTok{"}\VariableTok{$1}\StringTok{"} + \VariableTok{exit\_callbacks+=(}\StringTok{"}\VariableTok{$exit\_callback\_function}\StringTok{"}\VariableTok{)} +\KeywordTok{\}} + +\BuiltInTok{declare}\NormalTok{ {-}a }\VariableTok{step\_names=()} +\BuiltInTok{declare}\NormalTok{ {-}a }\VariableTok{step\_timestamps=()} +\BuiltInTok{declare}\NormalTok{ {-}a }\VariableTok{step\_durations=()} +\BuiltInTok{declare}\NormalTok{ {-}a }\VariableTok{step\_types=()} + +\BuiltInTok{readonly} \VariableTok{STEP\_TYPE\_BATCH=}\StringTok{"batch"} +\BuiltInTok{readonly} \VariableTok{STEP\_TYPE\_INTERACTIVE=}\StringTok{"interactive"} + +\FunctionTok{timestamp\_now()} \KeywordTok{\{} + \FunctionTok{date}\NormalTok{ +\%s} +\KeywordTok{\}} + +\FunctionTok{finish\_step()} \KeywordTok{\{} + \BuiltInTok{local}\NormalTok{ {-}r }\VariableTok{step\_name=}\StringTok{"}\VariableTok{$1}\StringTok{"} + \BuiltInTok{local}\NormalTok{ {-}r }\VariableTok{step\_start\_timestamp=}\StringTok{"}\VariableTok{$2}\StringTok{"} + \BuiltInTok{local}\NormalTok{ {-}r }\VariableTok{step\_finish\_timestamp=}\StringTok{"}\VariableTok{$3}\StringTok{"} + + \VariableTok{step\_durations+=($((}\StringTok{"}\VariableTok{$step\_finish\_timestamp}\StringTok{"}\NormalTok{ {-} }\StringTok{"}\VariableTok{$\{step\_start\_timestamp\}}\StringTok{"}\VariableTok{)))} + \ExtensionTok{echo\_err} \StringTok{"Finished }\VariableTok{$step\_name}\StringTok{ (duration: }\VariableTok{$\{step\_durations[{-}1]\}}\StringTok{s)"} +\KeywordTok{\}} + +\FunctionTok{print\_step\_durations()} \KeywordTok{\{} + + \KeywordTok{if [[} \StringTok{"$\{\#step\_timestamps[]\}"} \OtherTok{{-}gt}\NormalTok{ 1}\KeywordTok{ ]]}\NormalTok{; }\KeywordTok{then} + \ExtensionTok{finish\_step} \StringTok{"}\VariableTok{$\{step\_names[{-}1]\}}\StringTok{"} \KeywordTok{\textbackslash{}} + \StringTok{"}\VariableTok{$\{step\_timestamps[{-}1]\}}\StringTok{"} \KeywordTok{\textbackslash{}} + \StringTok{"}\VariableTok{$(}\ExtensionTok{timestamp\_now}\VariableTok{)}\StringTok{"} + \KeywordTok{fi} + + \BuiltInTok{local} \VariableTok{total\_batch\_duration=}\NormalTok{0} + \BuiltInTok{local} \VariableTok{total\_interactive\_duration=}\NormalTok{0} + \BuiltInTok{local} \VariableTok{total\_duration=}\NormalTok{0} + \BuiltInTok{local} \VariableTok{step\_name} + \BuiltInTok{local} \VariableTok{step\_type} + \BuiltInTok{local} \VariableTok{step\_duration} + \BuiltInTok{local} \VariableTok{step\_number} + + \ExtensionTok{echo\_err} + \ExtensionTok{echo\_err} \StringTok{"Steps duration summary:"} + + \KeywordTok{for} \ExtensionTok{i}\NormalTok{ in }\StringTok{"$\{!step\_durations[]\}"}\KeywordTok{;} \KeywordTok{do} + \VariableTok{step\_name=}\StringTok{"}\VariableTok{$\{step\_names[$i]\}}\StringTok{"} + \VariableTok{step\_duration=}\StringTok{"}\VariableTok{$\{step\_durations[$i]\}}\StringTok{"} + \VariableTok{step\_type=}\StringTok{"}\VariableTok{$\{step\_types[$i]\}}\StringTok{"} + \VariableTok{step\_number=$((}\NormalTok{i + 1}\VariableTok{))} + + \ExtensionTok{echo\_err} \StringTok{"}\VariableTok{$step\_number}\StringTok{ {-} }\VariableTok{$step\_name}\StringTok{ took }\VariableTok{$\{step\_duration\}}\StringTok{ seconds (}\VariableTok{$step\_type}\StringTok{)"} + + \KeywordTok{case} \StringTok{"}\VariableTok{$step\_type}\StringTok{"}\KeywordTok{ in} + \StringTok{"}\VariableTok{$STEP\_TYPE\_BATCH}\StringTok{"}\KeywordTok{)} + \KeywordTok{((}\NormalTok{total\_batch\_duration += }\StringTok{"}\VariableTok{$step\_duration}\StringTok{"}\KeywordTok{))} + \KeywordTok{;;} + \StringTok{"}\VariableTok{$STEP\_TYPE\_INTERACTIVE}\StringTok{"}\KeywordTok{)} + \KeywordTok{((}\NormalTok{total\_interactive\_duration += }\StringTok{"}\VariableTok{$step\_duration}\StringTok{"}\KeywordTok{))} + \KeywordTok{;;} + \KeywordTok{esac} + + \KeywordTok{((}\NormalTok{total\_duration += }\StringTok{"}\VariableTok{$step\_duration}\StringTok{"}\KeywordTok{))} + \KeywordTok{done} + + \ExtensionTok{echo\_err} + \ExtensionTok{echo\_err} \StringTok{"Total batch duration: }\VariableTok{$\{total\_batch\_duration\}}\StringTok{s"} + \ExtensionTok{echo\_err} \StringTok{"Total interactive duration: }\VariableTok{$\{total\_interactive\_duration\}}\StringTok{s"} + \ExtensionTok{echo\_err} \StringTok{"Total duration: }\VariableTok{$\{total\_duration\}}\StringTok{s"} +\KeywordTok{\}} + +\FunctionTok{start\_step()} \KeywordTok{\{} + \VariableTok{step\_timestamps+=(}\StringTok{"}\VariableTok{$(}\ExtensionTok{timestamp\_now}\VariableTok{)}\StringTok{"}\VariableTok{)} + \VariableTok{step\_names+=(}\StringTok{"}\VariableTok{$1}\StringTok{"}\VariableTok{)} + \VariableTok{step\_types+=(}\StringTok{"}\VariableTok{$2}\StringTok{"}\VariableTok{)} + + \BuiltInTok{local}\NormalTok{ {-}r }\VariableTok{steps\_count=}\StringTok{"$\{\#step\_timestamps[]\}"} + + \KeywordTok{if [[} \VariableTok{$steps\_count} \OtherTok{{-}eq}\NormalTok{ 1}\KeywordTok{ ]]}\NormalTok{; }\KeywordTok{then} + \ExtensionTok{add\_exit\_callback} \StringTok{"print\_step\_durations"} + \KeywordTok{elif [[} \StringTok{"$\{\#step\_timestamps[]\}"} \OtherTok{{-}gt}\NormalTok{ 1}\KeywordTok{ ]]}\NormalTok{; }\KeywordTok{then} + \ExtensionTok{finish\_step} \StringTok{"}\VariableTok{$\{step\_names[{-}2]\}}\StringTok{"} \KeywordTok{\textbackslash{}} + \StringTok{"}\VariableTok{$\{step\_timestamps[{-}2]\}}\StringTok{"} \KeywordTok{\textbackslash{}} + \StringTok{"}\VariableTok{$\{step\_timestamps[{-}1]\}}\StringTok{"} + \KeywordTok{fi} + + \ExtensionTok{echo\_err} \StringTok{"Started }\VariableTok{$\{step\_names[{-}1]\}}\StringTok{"} +\KeywordTok{\}} + +\FunctionTok{start\_step\_batch()} \KeywordTok{\{} + \BuiltInTok{local}\NormalTok{ {-}r }\VariableTok{step\_name=}\StringTok{"}\VariableTok{$1}\StringTok{"} + \ExtensionTok{start\_step} \StringTok{"}\VariableTok{$step\_name}\StringTok{"} \StringTok{"}\VariableTok{$STEP\_TYPE\_BATCH}\StringTok{"} +\KeywordTok{\}} + +\FunctionTok{start\_step\_interactive()} \KeywordTok{\{} + \BuiltInTok{local}\NormalTok{ {-}r }\VariableTok{step\_name=}\StringTok{"}\VariableTok{$1}\StringTok{"} + \ExtensionTok{start\_step} \StringTok{"}\VariableTok{$step\_name}\StringTok{"} \StringTok{"}\VariableTok{$STEP\_TYPE\_INTERACTIVE}\StringTok{"} +\KeywordTok{\}} + +\FunctionTok{warning()} \KeywordTok{\{} + \BuiltInTok{local}\NormalTok{ {-}r }\VariableTok{message=}\StringTok{"}\VariableTok{$1}\StringTok{"} + + \ExtensionTok{echo\_err} + \ExtensionTok{echo\_err} \StringTok{"Warning: }\VariableTok{$message}\StringTok{"} + + \BuiltInTok{local} \VariableTok{pressed\_key} + \KeywordTok{while} \FunctionTok{true}\KeywordTok{;} \KeywordTok{do} + \ExtensionTok{echo\_err} + \ExtensionTok{echo\_err} \StringTok{"Continue? (y/n) "} + + \BuiltInTok{read}\NormalTok{ {-}n 1 {-}s {-}r }\VariableTok{pressed\_key} + \KeywordTok{case} \StringTok{"}\VariableTok{$pressed\_key}\StringTok{"}\KeywordTok{ in} +\NormalTok{ [yY]}\KeywordTok{)} + \ExtensionTok{echo\_err} \StringTok{"Continuing..."} + \BuiltInTok{return}\NormalTok{ 0} + \KeywordTok{;;} +\NormalTok{ [nN]}\KeywordTok{)} + \ExtensionTok{echo\_err} \StringTok{"Aborting..."} + \BuiltInTok{exit}\NormalTok{ 1} + \KeywordTok{;;} +\NormalTok{ *}\KeywordTok{)} + \ExtensionTok{echo\_err} \StringTok{"Invalid key \textquotesingle{}}\VariableTok{$pressed\_key}\StringTok{\textquotesingle{}"} + \KeywordTok{;;} + \KeywordTok{esac} + \KeywordTok{done} +\KeywordTok{\}} + +\FunctionTok{validation\_error()} \KeywordTok{\{} + \BuiltInTok{local}\NormalTok{ {-}r }\VariableTok{value=}\StringTok{"}\VariableTok{$1}\StringTok{"} + \BuiltInTok{local}\NormalTok{ {-}r }\VariableTok{validation\_error\_message=}\StringTok{"}\VariableTok{$2}\StringTok{"} + \BuiltInTok{local}\NormalTok{ {-}r }\VariableTok{fatal\_error\_message=}\StringTok{"}\VariableTok{$3}\StringTok{"} + \ExtensionTok{echo\_err} \StringTok{"Validation error: value \textquotesingle{}}\VariableTok{$value}\StringTok{\textquotesingle{} }\VariableTok{$validation\_error\_message}\StringTok{."} + \ExtensionTok{fatal\_error} \StringTok{"}\VariableTok{$fatal\_error\_message}\StringTok{"} +\KeywordTok{\}} + +\FunctionTok{validate\_not\_empty()} \KeywordTok{\{} + \BuiltInTok{local}\NormalTok{ {-}r }\VariableTok{value=}\StringTok{"}\VariableTok{$1}\StringTok{"} + \BuiltInTok{local}\NormalTok{ {-}r }\VariableTok{error\_message=}\StringTok{"}\VariableTok{$2}\StringTok{"} + + \KeywordTok{if [[} \OtherTok{{-}z} \StringTok{"}\VariableTok{$value}\StringTok{"}\KeywordTok{ ]]}\NormalTok{; }\KeywordTok{then} + \ExtensionTok{validation\_error} \StringTok{"}\VariableTok{$value}\StringTok{"} \StringTok{"is empty"} \StringTok{"}\VariableTok{$error\_message}\StringTok{"} + \KeywordTok{fi} +\KeywordTok{\}} + +\FunctionTok{validate\_with\_regex()} \KeywordTok{\{} + \BuiltInTok{local}\NormalTok{ {-}r }\VariableTok{value=}\StringTok{"}\VariableTok{$1}\StringTok{"} + \BuiltInTok{local}\NormalTok{ {-}r }\VariableTok{regex\_pattern=}\StringTok{"}\VariableTok{$2}\StringTok{"} + \BuiltInTok{local}\NormalTok{ {-}r }\VariableTok{fatal\_error\_message=}\StringTok{"}\VariableTok{$3}\StringTok{"} + \BuiltInTok{local}\NormalTok{ {-}r }\VariableTok{validation\_error\_message=}\StringTok{"}\VariableTok{$\{4:{-}}\StringTok{"does not match regex pattern \textquotesingle{}}\VariableTok{$regex\_pattern}\StringTok{\textquotesingle{}"}\VariableTok{\}}\StringTok{"} + + \KeywordTok{if [[} \OtherTok{!} \StringTok{"}\VariableTok{$value}\StringTok{"}\NormalTok{ =\textasciitilde{} }\VariableTok{$regex\_pattern}\KeywordTok{ ]]}\NormalTok{; }\KeywordTok{then} + \ExtensionTok{validation\_error} \StringTok{"}\VariableTok{$value}\StringTok{"} \StringTok{"}\VariableTok{$validation\_error\_message}\StringTok{"} \StringTok{"}\VariableTok{$fatal\_error\_message}\StringTok{"} + \KeywordTok{fi} +\KeywordTok{\}} + +\FunctionTok{validate\_uint()} \KeywordTok{\{} + \BuiltInTok{local}\NormalTok{ {-}r }\VariableTok{value=}\StringTok{"}\VariableTok{$1}\StringTok{"} + \BuiltInTok{local}\NormalTok{ {-}r }\VariableTok{error\_message=}\StringTok{"}\VariableTok{$2}\StringTok{"} + \BuiltInTok{local}\NormalTok{ {-}r }\VariableTok{regex\_pattern=}\StringTok{\textquotesingle{}\^{}[0{-}9]+$\textquotesingle{}} + + \ExtensionTok{validate\_with\_regex} \StringTok{"}\VariableTok{$value}\StringTok{"} \StringTok{"}\VariableTok{$regex\_pattern}\StringTok{"} \StringTok{"}\VariableTok{$error\_message}\StringTok{"} \StringTok{"is not a positive integer"} +\KeywordTok{\}} + +\FunctionTok{validate\_nonzero\_uint()} \KeywordTok{\{} + \BuiltInTok{local}\NormalTok{ {-}r }\VariableTok{value=}\StringTok{"}\VariableTok{$1}\StringTok{"} + \BuiltInTok{local}\NormalTok{ {-}r }\VariableTok{error\_message=}\StringTok{"}\VariableTok{$2}\StringTok{"} + + \ExtensionTok{validate\_uint} \StringTok{"}\VariableTok{$value}\StringTok{"} \StringTok{"}\VariableTok{$error\_message}\StringTok{"} + + \KeywordTok{if [[} \StringTok{"}\VariableTok{$value}\StringTok{"} \OtherTok{{-}le}\NormalTok{ 0}\KeywordTok{ ]]}\NormalTok{; }\KeywordTok{then} + \ExtensionTok{validation\_error} \StringTok{"}\VariableTok{$value}\StringTok{"} \StringTok{"is not bigger than zero"} \StringTok{"}\VariableTok{$error\_message}\StringTok{"} + \KeywordTok{fi} +\KeywordTok{\}} + +\FunctionTok{validate\_file\_exists()} \KeywordTok{\{} + \BuiltInTok{local}\NormalTok{ {-}r }\VariableTok{value=}\StringTok{"}\VariableTok{$1}\StringTok{"} + \BuiltInTok{local}\NormalTok{ {-}r }\VariableTok{error\_message=}\StringTok{"}\VariableTok{$\{2:{-}}\NormalTok{File does not exist}\VariableTok{\}}\StringTok{"} + + \KeywordTok{if [[} \OtherTok{!} \OtherTok{{-}f} \StringTok{"}\VariableTok{$value}\StringTok{"}\KeywordTok{ ]]}\NormalTok{; }\KeywordTok{then} + \ExtensionTok{validation\_error} \StringTok{"}\VariableTok{$value}\StringTok{"} \StringTok{"is not the path of an existing regular file"} \StringTok{"}\VariableTok{$error\_message}\StringTok{"} + \KeywordTok{fi} +\KeywordTok{\}} + +\CommentTok{\# Validates that the given file exists but do not test if it\textquotesingle{}s a regular file} +\CommentTok{\# like \textasciigrave{}validate\_file\_exists\textasciigrave{}.} +\FunctionTok{validate\_exists()} \KeywordTok{\{} + \BuiltInTok{local}\NormalTok{ {-}r }\VariableTok{value=}\StringTok{"}\VariableTok{$1}\StringTok{"} + \BuiltInTok{local}\NormalTok{ {-}r }\VariableTok{error\_message=}\StringTok{"}\VariableTok{$2}\StringTok{"} + + \KeywordTok{if [[} \OtherTok{!} \OtherTok{{-}e} \StringTok{"}\VariableTok{$value}\StringTok{"}\KeywordTok{ ]]}\NormalTok{; }\KeywordTok{then} + \ExtensionTok{validation\_error} \StringTok{"}\VariableTok{$value}\StringTok{"} \StringTok{"is not an existing path"} \StringTok{"}\VariableTok{$error\_message}\StringTok{"} + \KeywordTok{fi} +\KeywordTok{\}} + +\CommentTok{\# Usage:} +\CommentTok{\# ensure\_variable VARIABLE\_NAME COMPUTATION\_FUNCTION VALIDATION\_FUNCTION} +\CommentTok{\#} +\CommentTok{\# Description:} +\CommentTok{\# Ensures that a readonly global variable named VARIABLE\_NAME is declared,} +\CommentTok{\# that it\textquotesingle{}s value is initialized using COMPUTATION\_FUNCTION and validated} +\CommentTok{\# using VALIDATION\_FUNCTION.} +\CommentTok{\#} +\CommentTok{\# The value is computed, validated and set to a readonly global variable} +\CommentTok{\# during the first call to this function. Nothing more is done on} +\CommentTok{\# subsequent calls if the variable is already set.} +\CommentTok{\#} +\CommentTok{\# If this function returns, the variable VARIABLE\_NAME should be safe to} +\CommentTok{\# use without any further validation. The variable can be accessed from} +\CommentTok{\# it\textquotesingle{}s name, or using an expression like \textasciigrave{}$\{!VARIABLE\_NAME\}\textasciigrave{}.} +\CommentTok{\#} +\CommentTok{\# Arguments:} +\CommentTok{\# VARIABLE\_NAME} +\CommentTok{\# The name of the variable to ensure.} +\CommentTok{\#} +\CommentTok{\# COMPUTATION\_FUNCTION} +\CommentTok{\# A function that takes 0 arguments, writes the computed value to} +\CommentTok{\# standard output and returns 0 if the computation is successful.} +\CommentTok{\#} +\CommentTok{\# VALIDATION\_FUNCTION} +\CommentTok{\# A function that takes the computed value and returns 0 if the value} +\CommentTok{\# is valid.} +\CommentTok{\#} +\CommentTok{\# Exit status code:} +\CommentTok{\# 0 when no error is encountered. If any error is encountered during} +\CommentTok{\# declaration, computation, validation or assignation, the current shell} +\CommentTok{\# will be exited by a call to \textasciigrave{}fatal\_error\textasciigrave{} so the function will never} +\CommentTok{\# return.} +\FunctionTok{ensure\_variable()} \KeywordTok{\{} + \BuiltInTok{local}\NormalTok{ {-}r }\VariableTok{variable\_name=}\StringTok{"}\VariableTok{$1}\StringTok{"} + \BuiltInTok{local}\NormalTok{ {-}r }\VariableTok{computation\_function=}\StringTok{"}\VariableTok{$2}\StringTok{"} + \BuiltInTok{local}\NormalTok{ {-}r }\VariableTok{validation\_function=}\StringTok{"}\VariableTok{$3}\StringTok{"} + + \KeywordTok{if [[}\NormalTok{ {-}v }\StringTok{"}\VariableTok{$variable\_name}\StringTok{"}\KeywordTok{ ]]}\NormalTok{; }\KeywordTok{then} + \BuiltInTok{return}\NormalTok{ 0} + \KeywordTok{fi} + + \BuiltInTok{local} \VariableTok{computed\_value} \KeywordTok{||} + \ExtensionTok{fatal\_error} \StringTok{"cannot declare local variable \textquotesingle{}computed\_value\textquotesingle{}"} + + \VariableTok{computed\_value=}\StringTok{"}\VariableTok{$(}\StringTok{"}\VariableTok{$computation\_function}\StringTok{"}\VariableTok{)}\StringTok{"} \KeywordTok{||} + \ExtensionTok{fatal\_error} \StringTok{"cannot compute value of \textquotesingle{}}\VariableTok{$variable\_name}\StringTok{\textquotesingle{} with \textquotesingle{}}\VariableTok{$computation\_function}\StringTok{\textquotesingle{}"} + + \StringTok{"}\VariableTok{$validation\_function}\StringTok{"} \StringTok{"}\VariableTok{$computed\_value}\StringTok{"} \KeywordTok{||} + \ExtensionTok{fatal\_error} \StringTok{"cannot validate value of \textquotesingle{}}\VariableTok{$variable\_name}\StringTok{\textquotesingle{} with \textquotesingle{}}\VariableTok{$validation\_function}\StringTok{\textquotesingle{}"} + + \BuiltInTok{declare}\NormalTok{ {-}g {-}r }\StringTok{"}\VariableTok{$variable\_name}\StringTok{"}\VariableTok{=}\StringTok{"}\VariableTok{$computed\_value}\StringTok{"} \KeywordTok{||} + \ExtensionTok{fatal\_error} \StringTok{"cannot initialize global readonly variable \textquotesingle{}}\VariableTok{$variable\_name}\StringTok{\textquotesingle{} with value \textquotesingle{}}\VariableTok{$computed\_value}\StringTok{\textquotesingle{}"} + + \BuiltInTok{local}\NormalTok{ {-}r }\VariableTok{log\_variable\_name=}\StringTok{"}\VariableTok{$(}\BuiltInTok{echo} \StringTok{"}\VariableTok{$\{variable\_name\^{}\}}\StringTok{"} \KeywordTok{|} \FunctionTok{tr} \StringTok{\textquotesingle{}\_\textquotesingle{}} \StringTok{\textquotesingle{} \textquotesingle{}}\VariableTok{)}\StringTok{"} + \ExtensionTok{echo\_err} \StringTok{"}\VariableTok{$log\_variable\_name}\StringTok{: }\VariableTok{$\{!variable\_name\}}\StringTok{"} + + \BuiltInTok{return}\NormalTok{ 0} +\KeywordTok{\}} + +\CommentTok{\# Ensures $remote\_address is declared, initialized and valid.} +\FunctionTok{ensure\_remote\_address()} \KeywordTok{\{} + \BuiltInTok{declare}\NormalTok{ {-}g }\VariableTok{remote\_address} + + \FunctionTok{get\_remote\_address()} \KeywordTok{\{} + \FunctionTok{mount}\NormalTok{ {-}t nfs }\KeywordTok{|} \FunctionTok{cut}\NormalTok{ {-}d}\StringTok{\textquotesingle{}:\textquotesingle{}}\NormalTok{ {-}f1 }\KeywordTok{|} \FunctionTok{head}\NormalTok{ {-}1 }\KeywordTok{||} + \ExtensionTok{fatal\_error} \StringTok{"cannot retrieve remote server address."} + \KeywordTok{\}} + + \FunctionTok{validate\_remote\_address()} \KeywordTok{\{} + \ExtensionTok{validate\_not\_empty} \StringTok{"}\VariableTok{$1}\StringTok{"} \StringTok{"no valid remote server address has not been found."} + \KeywordTok{\}} + + \ExtensionTok{ensure\_variable} \StringTok{"remote\_address"} \StringTok{"get\_remote\_address"} \StringTok{"validate\_remote\_address"} +\KeywordTok{\}} + +\CommentTok{\# Ensures $net\_interface is declared, initialized and valid.} +\FunctionTok{ensure\_net\_interface()} \KeywordTok{\{} + \BuiltInTok{declare}\NormalTok{ {-}g }\VariableTok{net\_interface} + + \ExtensionTok{ensure\_remote\_address} + + \FunctionTok{get\_net\_interface()} \KeywordTok{\{} + \ExtensionTok{ip}\NormalTok{ route get }\StringTok{"}\VariableTok{$remote\_address}\StringTok{"} \KeywordTok{|} \FunctionTok{head}\NormalTok{ {-}1 }\KeywordTok{|} \FunctionTok{sed}\NormalTok{ {-}n }\StringTok{\textquotesingle{}s/.* dev \textbackslash{}([\^{} ]*\textbackslash{}).*/\textbackslash{}1/p\textquotesingle{}} \KeywordTok{||} + \ExtensionTok{fatal\_error} \StringTok{"cannot retrieve network interface with route to \textquotesingle{}}\VariableTok{$remote\_address}\StringTok{\textquotesingle{}."} + \KeywordTok{\}} + + \FunctionTok{validate\_net\_interface()} \KeywordTok{\{} + \ExtensionTok{validate\_not\_empty} \StringTok{"}\VariableTok{$1}\StringTok{"} \StringTok{"no valid network interface has been found."} + \KeywordTok{\}} + + \ExtensionTok{ensure\_variable} \StringTok{"net\_interface"} \StringTok{"get\_net\_interface"} \StringTok{"validate\_net\_interface"} +\KeywordTok{\}} + +\CommentTok{\# Ensures $mac\_address is declared, initialized and valid.} +\FunctionTok{ensure\_mac\_address()} \KeywordTok{\{} + \CommentTok{\# shellcheck disable=SC2034 \# the variable is declared for parent scripts that source this one} + \BuiltInTok{declare}\NormalTok{ {-}g }\VariableTok{mac\_address} + + \ExtensionTok{ensure\_net\_interface} + + \FunctionTok{get\_mac\_address()} \KeywordTok{\{} + \FunctionTok{tr} \StringTok{"[:upper:]:"} \StringTok{"[:lower:]{-}"} \OperatorTok{\textless{}} \StringTok{"/sys/class/net/}\VariableTok{$net\_interface}\StringTok{/address"} \KeywordTok{||} + \ExtensionTok{fatal\_error} \StringTok{"failed to retrieve and convert mac address of network interface \textquotesingle{}}\VariableTok{$net\_interface}\StringTok{\textquotesingle{}"} + \KeywordTok{\}} + + \FunctionTok{validate\_mac\_address()} \KeywordTok{\{} + \BuiltInTok{local}\NormalTok{ {-}r }\VariableTok{value=}\StringTok{"}\VariableTok{$1}\StringTok{"} + \BuiltInTok{local}\NormalTok{ {-}r }\VariableTok{regex\_pattern=}\StringTok{\textquotesingle{}\^{}([0{-}9a{-}f]\{2\}{-})\{5\}[0{-}9a{-}f]\{2\}$\textquotesingle{}} + + \ExtensionTok{validate\_with\_regex} \KeywordTok{\textbackslash{}} + \StringTok{"}\VariableTok{$value}\StringTok{"} \StringTok{"}\VariableTok{$regex\_pattern}\StringTok{"} \KeywordTok{\textbackslash{}} + \StringTok{"mac address does not match required format."} \KeywordTok{\textbackslash{}} + \StringTok{"is not a mac address formatted as lower{-}case hexadecimal bytes separated by hyphens."} + \KeywordTok{\}} + + \ExtensionTok{ensure\_variable} \StringTok{"mac\_address"} \StringTok{"get\_mac\_address"} \StringTok{"validate\_mac\_address"} +\KeywordTok{\}} + +\BuiltInTok{readonly} \VariableTok{mounting\_point\_remote=}\StringTok{"/bootiful/shared"} +\BuiltInTok{readonly} \VariableTok{deployment\_disk=}\StringTok{"/dev/sda"} + +\CommentTok{\# Ensures the kernel is informed of the latest partition table changes} +\FunctionTok{refresh\_partition\_table()} \KeywordTok{\{} + \ExtensionTok{echo\_err} \StringTok{"Refreshing partition table on disk \textquotesingle{}}\VariableTok{$deployment\_disk}\StringTok{\textquotesingle{}..."} + \ExtensionTok{partprobe} \StringTok{"}\VariableTok{$deployment\_disk}\StringTok{"} +\KeywordTok{\}} + +\CommentTok{\# Checks if something is currently mounted on the given mount point} +\FunctionTok{is\_mounted()} \KeywordTok{\{} + \BuiltInTok{local}\NormalTok{ {-}r }\VariableTok{mount\_point=}\StringTok{"}\VariableTok{$1}\StringTok{"} + + \ExtensionTok{refresh\_partition\_table} + \ExtensionTok{findmnt}\NormalTok{ {-}{-}mountpoint }\StringTok{"}\VariableTok{$mount\_point}\StringTok{"} +\KeywordTok{\}} + +\CommentTok{\# Ensures that the given directory exists or create it. If the directory does} +\CommentTok{\# not exist and cannot be created, \textasciigrave{}fatal\_error\textasciigrave{} is called.} +\FunctionTok{ensure\_directory()} \KeywordTok{\{} + \BuiltInTok{local}\NormalTok{ {-}r }\VariableTok{directory=}\StringTok{"}\VariableTok{$1}\StringTok{"} + + \ExtensionTok{echo\_err} \StringTok{"Ensuring directory \textquotesingle{}}\VariableTok{$directory}\StringTok{\textquotesingle{} exists..."} + \KeywordTok{if [[} \OtherTok{{-}d} \StringTok{"}\VariableTok{$directory}\StringTok{"}\KeywordTok{ ]]}\NormalTok{; }\KeywordTok{then} + \ExtensionTok{echo\_err} \StringTok{"Directory \textquotesingle{}}\VariableTok{$directory}\StringTok{\textquotesingle{} already exists."} + \BuiltInTok{return}\NormalTok{ 0} + \KeywordTok{fi} + + \ExtensionTok{echo\_err} \StringTok{"Directory \textquotesingle{}}\VariableTok{$directory}\StringTok{\textquotesingle{} does not exist. Attempting to create it..."} + \FunctionTok{mkdir}\NormalTok{ {-}p }\StringTok{"}\VariableTok{$directory}\StringTok{"} \KeywordTok{||} + \ExtensionTok{fatal\_error} \StringTok{"Cannot create directory }\VariableTok{$directory}\StringTok{."} + \ExtensionTok{echo\_err} \StringTok{"Directory \textquotesingle{}}\VariableTok{$directory}\StringTok{\textquotesingle{} created."} +\KeywordTok{\}} + +\CommentTok{\# Mounts a device to a mount point if it\textquotesingle{}s not already mounted} +\FunctionTok{ensure\_mounted()} \KeywordTok{\{} + \BuiltInTok{local}\NormalTok{ {-}r }\VariableTok{source\_device=}\StringTok{"}\VariableTok{$1}\StringTok{"} + \BuiltInTok{local}\NormalTok{ {-}r }\VariableTok{mount\_point=}\StringTok{"}\VariableTok{$2}\StringTok{"} + \BuiltInTok{local}\NormalTok{ {-}r }\VariableTok{mount\_fstype=}\StringTok{"}\VariableTok{$3}\StringTok{"} + \BuiltInTok{local}\NormalTok{ {-}r }\VariableTok{mount\_options=}\StringTok{"}\VariableTok{$4}\StringTok{"} + + \ExtensionTok{echo\_err} \StringTok{"Ensuring device \textquotesingle{}}\VariableTok{$source\_device}\StringTok{\textquotesingle{} is mounted on \textquotesingle{}}\VariableTok{$mount\_point}\StringTok{\textquotesingle{}..."} + + \KeywordTok{if} \ExtensionTok{is\_mounted} \StringTok{"}\VariableTok{$mount\_point}\StringTok{"}\KeywordTok{;} \KeywordTok{then} + \ExtensionTok{echo\_err} \StringTok{"Mount point \textquotesingle{}}\VariableTok{$mount\_point}\StringTok{\textquotesingle{} is already mounted."} + \BuiltInTok{return}\NormalTok{ 0} + \KeywordTok{fi} + + \ExtensionTok{echo\_err} \StringTok{"Nothing is mounted on mount point \textquotesingle{}}\VariableTok{$mount\_point}\StringTok{\textquotesingle{}."} + + \ExtensionTok{ensure\_directory} \StringTok{"}\VariableTok{$mount\_point}\StringTok{"} + + \ExtensionTok{echo\_err} \StringTok{"Attempting to mount \textquotesingle{}}\VariableTok{$source\_device}\StringTok{\textquotesingle{} on \textquotesingle{}}\VariableTok{$mount\_point}\StringTok{\textquotesingle{} as \textquotesingle{}}\VariableTok{$mount\_fstype}\StringTok{\textquotesingle{} with options \textquotesingle{}}\VariableTok{$mount\_options}\StringTok{\textquotesingle{}."} + + \FunctionTok{mount}\NormalTok{ {-}t }\StringTok{"}\VariableTok{$mount\_fstype}\StringTok{"}\NormalTok{ {-}o }\StringTok{"}\VariableTok{$mount\_options}\StringTok{"} \StringTok{"}\VariableTok{$source\_device}\StringTok{"} \StringTok{"}\VariableTok{$mount\_point}\StringTok{"} \KeywordTok{||} + \ExtensionTok{fatal\_error} \StringTok{"Failed to mount device \textquotesingle{}}\VariableTok{$source\_device}\StringTok{\textquotesingle{} on \textquotesingle{}}\VariableTok{$mount\_point}\StringTok{\textquotesingle{}"}\NormalTok{.} + + \ExtensionTok{echo\_err} \StringTok{"Mount successful."} +\KeywordTok{\}} + +\CommentTok{\# Mounts the remote shared data if it\textquotesingle{}s not already mounted} +\FunctionTok{ensure\_remote\_shared\_mounted()} \KeywordTok{\{} + \ExtensionTok{ensure\_remote\_address} + \BuiltInTok{local}\NormalTok{ {-}r }\VariableTok{remote\_nfs\_share=}\StringTok{"}\VariableTok{$remote\_address}\StringTok{:/nfsshared"} + \ExtensionTok{ensure\_mounted} \StringTok{"}\VariableTok{$remote\_nfs\_share}\StringTok{"} \StringTok{"}\VariableTok{$mounting\_point\_remote}\StringTok{"} \StringTok{"nfs"} \StringTok{"nolock"} +\KeywordTok{\}} + +\CommentTok{\# Ensures $total\_disk\_size is declared, initialized and valid.} +\FunctionTok{ensure\_total\_disk\_size()} \KeywordTok{\{} + \BuiltInTok{declare}\NormalTok{ {-}g }\VariableTok{total\_disk\_size} + + \FunctionTok{get\_total\_disk\_size()} \KeywordTok{\{} + \ExtensionTok{parted}\NormalTok{ {-}{-}script }\StringTok{"}\VariableTok{$deployment\_disk}\StringTok{"}\NormalTok{ unit B print }\KeywordTok{|} + \FunctionTok{sed}\NormalTok{ {-}En }\StringTok{\textquotesingle{}s\#\^{}Disk\textbackslash{}s*\textquotesingle{}"}\VariableTok{$deployment\_disk}\StringTok{"\textquotesingle{}:\textbackslash{}s*([0{-}9]+)B$\#\textbackslash{}1\#p\textquotesingle{}} \KeywordTok{||} + \ExtensionTok{fatal\_error} \StringTok{"cannot retrieve total disk size"} + \KeywordTok{\}} + + \FunctionTok{validate\_total\_disk\_size()} \KeywordTok{\{} + \ExtensionTok{validate\_nonzero\_uint} \StringTok{"}\VariableTok{$1}\StringTok{"} \StringTok{"retrieved disk size format is invalid."} + \KeywordTok{\}} + + \ExtensionTok{ensure\_variable} \StringTok{"total\_disk\_size"} \StringTok{"get\_total\_disk\_size"} \StringTok{"validate\_total\_disk\_size"} +\KeywordTok{\}} + +\CommentTok{\# Ensures $sector\_sizes is declared, initialized and valid} +\FunctionTok{ensure\_sector\_sizes()} \KeywordTok{\{} + \BuiltInTok{declare}\NormalTok{ {-}g }\VariableTok{sector\_sizes} + + \FunctionTok{get\_sector\_sizes()} \KeywordTok{\{} + \ExtensionTok{parted}\NormalTok{ {-}{-}script }\StringTok{"}\VariableTok{$deployment\_disk}\StringTok{"}\NormalTok{ print }\KeywordTok{|} + \FunctionTok{sed}\NormalTok{ {-}En }\StringTok{\textquotesingle{}s\#\^{}Sector size \textbackslash{}(logical/physical\textbackslash{}):\textbackslash{}s*([0{-}9]+)B/([0{-}9]+)B$\#\textbackslash{}1\textbackslash{}t\textbackslash{}2\#p\textquotesingle{}} \KeywordTok{||} + \ExtensionTok{fatal\_error} \StringTok{"cannot retrieve sector size"} + \KeywordTok{\}} + + \FunctionTok{validate\_sector\_sizes()} \KeywordTok{\{} + \ExtensionTok{validate\_with\_regex} \KeywordTok{\textbackslash{}} + \StringTok{"}\VariableTok{$1}\StringTok{"} \KeywordTok{\textbackslash{}} + \StringTok{\textquotesingle{}\^{}[0{-}9]+\textbackslash{}s+[0{-}9]+$\textquotesingle{}} \KeywordTok{\textbackslash{}} + \StringTok{\textquotesingle{}retrieved sector sizes are invalid\textquotesingle{}} \KeywordTok{\textbackslash{}} + \StringTok{\textquotesingle{}does not contain two unsigned integers separated by spaces\textquotesingle{}} + \KeywordTok{\}} + + \ExtensionTok{ensure\_variable} \StringTok{"sector\_sizes"} \StringTok{"get\_sector\_sizes"} \StringTok{"validate\_sector\_sizes"} +\KeywordTok{\}} + +\CommentTok{\# Ensures $logical\_sector\_size is declared, initialized and valid} +\FunctionTok{ensure\_logical\_sector\_size()} \KeywordTok{\{} + \CommentTok{\# shellcheck disable=SC2034 \# the variable is declared for parent scripts that source this one} + \BuiltInTok{declare}\NormalTok{ {-}g }\VariableTok{logical\_sector\_size} + + \ExtensionTok{ensure\_sector\_sizes} + + \FunctionTok{extract\_logical\_sector\_size()} \KeywordTok{\{} + \BuiltInTok{echo} \StringTok{"}\VariableTok{$sector\_sizes}\StringTok{"} \KeywordTok{|} \FunctionTok{cut}\NormalTok{ {-}f 1 }\KeywordTok{||} + \ExtensionTok{fatal\_error} \StringTok{"cannot extract logical sector size from sector sizes"} + \KeywordTok{\}} + + \FunctionTok{validate\_logical\_sector\_size()} \KeywordTok{\{} + \ExtensionTok{validate\_nonzero\_uint} \StringTok{"}\VariableTok{$1}\StringTok{"} \StringTok{"retrieved logical sector size is invalid"} + \KeywordTok{\}} + + \ExtensionTok{ensure\_variable} \StringTok{"logical\_sector\_size"} \StringTok{"extract\_logical\_sector\_size"} \StringTok{"validate\_logical\_sector\_size"} +\KeywordTok{\}} + +\CommentTok{\# Ensures $physical\_sector\_size is declared, initialized and valid} +\FunctionTok{ensure\_physical\_sector\_size()} \KeywordTok{\{} + \BuiltInTok{declare}\NormalTok{ {-}g }\VariableTok{physical\_sector\_size} + + \ExtensionTok{ensure\_sector\_sizes} + + \FunctionTok{extract\_physical\_sector\_size()} \KeywordTok{\{} + \BuiltInTok{echo} \StringTok{"}\VariableTok{$sector\_sizes}\StringTok{"} \KeywordTok{|} \FunctionTok{cut}\NormalTok{ {-}f 2 }\KeywordTok{||} + \ExtensionTok{fatal\_error} \StringTok{"cannot extract physical sector size from sector sizes"} + \KeywordTok{\}} + + \FunctionTok{validate\_physical\_sector\_size()} \KeywordTok{\{} + \ExtensionTok{validate\_nonzero\_uint} \StringTok{"}\VariableTok{$1}\StringTok{"} \StringTok{"retrieved physical sector size is invalid"} + \KeywordTok{\}} + + \ExtensionTok{ensure\_variable} \StringTok{"physical\_sector\_size"} \StringTok{"extract\_physical\_sector\_size"} \StringTok{"validate\_physical\_sector\_size"} +\KeywordTok{\}} + +\CommentTok{\# Ensures $image\_cache\_partition\_size is declared, initialized and valid} +\FunctionTok{ensure\_image\_cache\_partition\_size()} \KeywordTok{\{} + \BuiltInTok{declare}\NormalTok{ {-}g }\VariableTok{image\_cache\_partition\_size} + + \ExtensionTok{ensure\_total\_disk\_size} + \ExtensionTok{ensure\_physical\_sector\_size} + + \FunctionTok{calculate\_image\_cache\_partition\_size()} \KeywordTok{\{} + \BuiltInTok{echo} \StringTok{"}\VariableTok{$((}\NormalTok{(20 * total\_disk\_size / 100) / physical\_sector\_size * physical\_sector\_size}\VariableTok{))}\StringTok{"} \KeywordTok{||} + \ExtensionTok{fatal\_error} \StringTok{"cannot calculate image partition size"} + \KeywordTok{\}} + + \FunctionTok{validate\_image\_cache\_partition\_size()} \KeywordTok{\{} + \ExtensionTok{validate\_nonzero\_uint} \StringTok{"}\VariableTok{$1}\StringTok{"} \StringTok{"calculated image cache partition size is invalid"} + \KeywordTok{\}} + + \ExtensionTok{ensure\_variable} \StringTok{"image\_cache\_partition\_size"} \KeywordTok{\textbackslash{}} + \StringTok{"calculate\_image\_cache\_partition\_size"} \KeywordTok{\textbackslash{}} + \StringTok{"validate\_image\_cache\_partition\_size"} +\KeywordTok{\}} + +\CommentTok{\# Ensures $image\_cache\_partition\_start is declared, initialized and valid} +\FunctionTok{ensure\_image\_cache\_partition\_start()} \KeywordTok{\{} + \BuiltInTok{declare}\NormalTok{ {-}g }\VariableTok{image\_cache\_partition\_start} + + \ExtensionTok{ensure\_total\_disk\_size} + \ExtensionTok{ensure\_physical\_sector\_size} + \ExtensionTok{ensure\_image\_cache\_partition\_size} + + \FunctionTok{calculate\_image\_cache\_partition\_start()} \KeywordTok{\{} + \BuiltInTok{echo} \StringTok{"}\VariableTok{$((}\NormalTok{(total\_disk\_size {-} image\_cache\_partition\_size) / physical\_sector\_size * physical\_sector\_size {-} 4096}\VariableTok{))}\StringTok{"} \KeywordTok{||} + \ExtensionTok{fatal\_error} \StringTok{"cannot calculate image cache partition start"} + \KeywordTok{\}} + + \FunctionTok{validate\_image\_cache\_partition\_start()} \KeywordTok{\{} + \ExtensionTok{validate\_nonzero\_uint} \StringTok{"}\VariableTok{$1}\StringTok{"} \StringTok{"calculated image cache partition start is invalid"} + \KeywordTok{\}} + + \ExtensionTok{ensure\_variable} \StringTok{"image\_cache\_partition\_start"} \KeywordTok{\textbackslash{}} + \StringTok{"calculate\_image\_cache\_partition\_start"} \KeywordTok{\textbackslash{}} + \StringTok{"validate\_image\_cache\_partition\_start"} +\KeywordTok{\}} + +\CommentTok{\# Ensures $image\_cache\_partition\_end is declared, initialized and valid} +\FunctionTok{ensure\_image\_cache\_partition\_end()} \KeywordTok{\{} + \CommentTok{\# shellcheck disable=SC2034 \# the variable is declared for parent scripts that source this one} + \BuiltInTok{declare}\NormalTok{ {-}g }\VariableTok{image\_cache\_partition\_end} + + \ExtensionTok{ensure\_image\_cache\_partition\_size} + \ExtensionTok{ensure\_image\_cache\_partition\_start} + + \FunctionTok{calculate\_image\_cache\_partition\_end()} \KeywordTok{\{} + \BuiltInTok{echo} \StringTok{"}\VariableTok{$((}\NormalTok{image\_cache\_partition\_start + image\_cache\_partition\_size}\VariableTok{))}\StringTok{"} \KeywordTok{||} + \ExtensionTok{fatal\_error} \StringTok{"cannot calculate image cache partition end"} + \KeywordTok{\}} + + \FunctionTok{validate\_image\_cache\_partition\_end()} \KeywordTok{\{} + \ExtensionTok{validate\_nonzero\_uint} \StringTok{"}\VariableTok{$1}\StringTok{"} \StringTok{"calculated image cache partition start is invalid"} + \KeywordTok{\}} + + \ExtensionTok{ensure\_variable} \StringTok{"image\_cache\_partition\_end"} \KeywordTok{\textbackslash{}} + \StringTok{"calculate\_image\_cache\_partition\_end"} \KeywordTok{\textbackslash{}} + \StringTok{"validate\_image\_cache\_partition\_end"} +\KeywordTok{\}} + +\FunctionTok{parse\_last\_partition\_end()} \KeywordTok{\{} + \BuiltInTok{local}\NormalTok{ {-}r }\VariableTok{gawk\_input\_data=}\StringTok{"}\VariableTok{$1}\StringTok{"} + \BuiltInTok{local}\NormalTok{ {-}r }\VariableTok{input\_size\_unit=}\StringTok{"}\VariableTok{$2}\StringTok{"} + \BuiltInTok{local}\NormalTok{ {-}r }\VariableTok{start\_parse\_token=}\StringTok{"}\VariableTok{$3}\StringTok{"} + + \BuiltInTok{local} \VariableTok{gawk\_program} + \BuiltInTok{read}\NormalTok{ {-}r {-}d }\StringTok{\textquotesingle{}\textquotesingle{}} \VariableTok{gawk\_program} \OperatorTok{\textless{}\textless{} \textquotesingle{}EOF\textquotesingle{}} +\NormalTok{ $0 \textasciitilde{} start\_parse\_regex\_pattern \{} +\NormalTok{ parsing=1;} +\NormalTok{ max\_part\_end=0;} +\NormalTok{ next;} +\NormalTok{ \}} +\NormalTok{ parsing \&\& $3 \textasciitilde{} disk\_end\_regex\_pattern \{} +\NormalTok{ part\_end=substr($3, 1, length($3){-}length(size\_unit)) + 0;} +\NormalTok{ if(part\_end\textgreater{}max\_part\_end) \{} +\NormalTok{ max\_part\_end=part\_end;} +\NormalTok{ \}} +\NormalTok{ \}} +\NormalTok{ END \{} +\NormalTok{ printf "\%d", max\_part\_end;} +\NormalTok{ \}} +\OperatorTok{EOF} + + \BuiltInTok{echo} \StringTok{"}\VariableTok{$gawk\_input\_data}\StringTok{"} \KeywordTok{|} \FunctionTok{gawk} \KeywordTok{\textbackslash{}} + \ExtensionTok{{-}v}\NormalTok{ start\_parse\_regex\_pattern=}\StringTok{"\^{}}\VariableTok{$start\_parse\_token}\StringTok{"} \KeywordTok{\textbackslash{}} + \ExtensionTok{{-}v}\NormalTok{ disk\_end\_regex\_pattern=}\StringTok{"\^{}[0{-}9]+}\VariableTok{$input\_size\_unit}\StringTok{$"} \KeywordTok{\textbackslash{}} + \ExtensionTok{{-}v}\NormalTok{ size\_unit=}\StringTok{"}\VariableTok{$input\_size\_unit}\StringTok{"} \KeywordTok{\textbackslash{}} + \ExtensionTok{{-}M} \StringTok{"}\VariableTok{$gawk\_program}\StringTok{"} \KeywordTok{\textbackslash{}} + \KeywordTok{||} \ExtensionTok{fatal\_error} \StringTok{"cannot extract image size"} +\KeywordTok{\}} + +\CommentTok{\# Print the end offset of the last partition of a parted output} +\FunctionTok{parse\_parted\_last\_partition\_end()} \KeywordTok{\{} + \BuiltInTok{local}\NormalTok{ {-}r }\VariableTok{parted\_output=}\StringTok{"}\VariableTok{$1}\StringTok{"} + \BuiltInTok{local}\NormalTok{ {-}r }\VariableTok{parted\_unit=}\StringTok{"}\VariableTok{$2}\StringTok{"} + + \ExtensionTok{parse\_last\_partition\_end} \StringTok{"}\VariableTok{$parted\_output}\StringTok{"} \StringTok{"}\VariableTok{$parted\_unit}\StringTok{"} \StringTok{\textquotesingle{}Number\textquotesingle{}} +\KeywordTok{\}} + +\FunctionTok{parse\_parted\_last\_partition\_end\_sector()} \KeywordTok{\{} + \ExtensionTok{parse\_parted\_last\_partition\_end} \StringTok{"}\VariableTok{$1}\StringTok{"} \StringTok{"s"} +\KeywordTok{\}} + +\FunctionTok{parse\_fdisk\_last\_partition\_end\_sector()} \KeywordTok{\{} + \BuiltInTok{local}\NormalTok{ {-}r }\VariableTok{fdisk\_output=}\StringTok{"}\VariableTok{$1}\StringTok{"} + + \ExtensionTok{parse\_last\_partition\_end} \StringTok{"}\VariableTok{$fdisk\_output}\StringTok{"} \StringTok{\textquotesingle{}\textquotesingle{}} \StringTok{\textquotesingle{}Device\textquotesingle{}} +\KeywordTok{\}} + +\FunctionTok{create\_hidden\_partition()} \KeywordTok{\{} + \BuiltInTok{echo} \StringTok{"Erasing MBR..."} + \FunctionTok{dd}\NormalTok{ if=/dev/zero bs=512 count=1 of=}\StringTok{"}\VariableTok{$deployment\_disk}\StringTok{"} + \BuiltInTok{echo} \StringTok{"MBR erased."} + + \BuiltInTok{echo} \StringTok{"Creating new partition table with hidden partition..."} + \ExtensionTok{ensure\_image\_cache\_partition\_start} + \ExtensionTok{ensure\_image\_cache\_partition\_end} + \ExtensionTok{parted}\NormalTok{ {-}s {-}a opt }\StringTok{"}\VariableTok{$deployment\_disk}\StringTok{"}\NormalTok{ mklabel msdos mkpart primary ext2 }\StringTok{"}\VariableTok{$\{image\_cache\_partition\_start\}}\StringTok{B"} \StringTok{"}\VariableTok{$\{image\_cache\_partition\_end\}}\StringTok{B"} \KeywordTok{||} + \ExtensionTok{fatal\_error} \StringTok{"parted exited with error code }\VariableTok{$?}\StringTok{"} + \BuiltInTok{echo} \StringTok{"New partition table with hidden partition created."} + + \ExtensionTok{refresh\_partition\_table} + + \BuiltInTok{echo} \StringTok{"Creating file system in hidden partition..."} + \ExtensionTok{mke2fs}\NormalTok{ {-}t ext2 }\StringTok{"}\VariableTok{$\{deployment\_disk\}}\StringTok{1"} \KeywordTok{||} + \ExtensionTok{fatal\_error} \StringTok{"mke2fs exited with error code }\VariableTok{$?}\StringTok{"} + \BuiltInTok{echo} \StringTok{"File system in hidden partition created."} + + \ExtensionTok{refresh\_partition\_table} +\KeywordTok{\}} +\end{Highlighting} +\end{Shaded} + +\hypertarget{deployerbootiful-deploy-script-de-duxe9ploiement-dimages}{% +\section{\texorpdfstring{\texttt{deployer/bootiful-deploy}: script de +déploiement +d'images}{deployer/bootiful-deploy: script de déploiement d'images}}\label{deployerbootiful-deploy-script-de-duxe9ploiement-dimages}} + +\begin{Shaded} +\begin{Highlighting}[] +\CommentTok{\#!/bin/bash} + +\BuiltInTok{shopt}\NormalTok{ {-}s nullglob} + +\BuiltInTok{readonly} \VariableTok{SCRIPT\_NAME=}\StringTok{"}\VariableTok{$(}\FunctionTok{basename} \StringTok{"}\VariableTok{$0}\StringTok{"}\VariableTok{)}\StringTok{"} +\BuiltInTok{readonly} \VariableTok{SCRIPT\_DIR=}\StringTok{"}\VariableTok{$(}\FunctionTok{readlink}\NormalTok{ {-}m }\StringTok{"}\VariableTok{$(}\FunctionTok{dirname} \StringTok{"}\VariableTok{$0}\StringTok{"}\VariableTok{)}\StringTok{"}\VariableTok{)}\StringTok{"} + +\FunctionTok{usage()} \KeywordTok{\{} + \FunctionTok{cat} \OperatorTok{\textless{}\textless{} EOF} +\NormalTok{Usage:} + \VariableTok{$SCRIPT\_DIR}\NormalTok{ [{-}h | {-}{-}help]} + +\NormalTok{Description:} +\NormalTok{ Deploys an operating system image on the disk.} + +\NormalTok{ The image is retrieved from the NFS server that already provides the root file} +\NormalTok{ system. The NFS shared directory /nfsshared is mounted on /bootiful/shared and} +\NormalTok{ contains multiple images that can be deployed.} + +\NormalTok{ The available images from the server are scanned from /bootiful/shared/images} +\NormalTok{ and displayed in an interactive menu that allows to choose which particular} +\NormalTok{ image will be deployed.} + +\NormalTok{ All the data written in the standard input and standard error during the} +\NormalTok{ deployment is also written in a log file in /bootiful/shared/logs.} + +\NormalTok{ If there is enough disk space available, the image is cached in a hidden} +\NormalTok{ partition to avoid downloading it again over the network during a future} +\NormalTok{ deployment. This hidden partition takes 20\% of the disk.} + +\NormalTok{ If the image to deploy overlaps the image cache partition (i.e. the image} +\NormalTok{ takes more than 80\% of the disk size), a warning message is shown and an} +\NormalTok{ interactive menu allows to choose whether to abort or continue the deployment} +\NormalTok{ without using the cache.} + +\NormalTok{Options:} +\NormalTok{ {-}h, {-}{-}help Shows this help} + +\NormalTok{Exit status:} +\NormalTok{ 0 if an image has been deployed successfully} +\NormalTok{ 1 if some error has occured during deployment} + +\NormalTok{Example:} + \VariableTok{$SCRIPT\_NAME} +\OperatorTok{EOF} +\KeywordTok{\}} + +\KeywordTok{if [[} \StringTok{"}\VariableTok{$1}\StringTok{"} \OtherTok{==} \StringTok{"{-}h"}\NormalTok{ || }\StringTok{"}\VariableTok{$1}\StringTok{"} \OtherTok{==} \StringTok{"{-}{-}help"}\KeywordTok{ ]]}\NormalTok{; }\KeywordTok{then} + \ExtensionTok{usage} + \BuiltInTok{exit}\NormalTok{ 0} +\KeywordTok{fi} + +\CommentTok{\# Loads declarations from the \textquotesingle{}bootiful{-}common\textquotesingle{} script, which is a "library"} +\CommentTok{\# of functions and constants shared by multiple bootiful{-}* scripts.} +\BuiltInTok{readonly} \VariableTok{bootiful\_common\_script\_file=}\StringTok{"}\VariableTok{$SCRIPT\_DIR}\StringTok{/bootiful{-}common"} +\KeywordTok{if [[} \OtherTok{!} \OtherTok{{-}f} \StringTok{"}\VariableTok{$bootiful\_common\_script\_file}\StringTok{"}\KeywordTok{ ]]}\NormalTok{; }\KeywordTok{then} + \BuiltInTok{echo} \OperatorTok{\textgreater{}\&2} \StringTok{"Fatal error: cannot find required script file \textquotesingle{}}\VariableTok{$bootiful\_common\_script\_file}\StringTok{\textquotesingle{}."} + \BuiltInTok{exit}\NormalTok{ 1} +\KeywordTok{fi} +\CommentTok{\# shellcheck source=./bootiful{-}common} +\BuiltInTok{.} \StringTok{"}\VariableTok{$SCRIPT\_DIR}\StringTok{/bootiful{-}common"} + +\ExtensionTok{start\_step\_batch} \StringTok{"remote shared data mount initialization"} +\VariableTok{start\_timestamp=}\StringTok{"}\VariableTok{$\{step\_timestamps[0]\}}\StringTok{"} + +\ExtensionTok{ensure\_remote\_shared\_mounted} + +\ExtensionTok{start\_step\_batch} \StringTok{"log file initialization"} +\BuiltInTok{readonly} \VariableTok{log\_dir=}\StringTok{"}\VariableTok{$mounting\_point\_remote}\StringTok{/log"} + +\ExtensionTok{ensure\_mac\_address} +\ExtensionTok{ensure\_directory} \StringTok{"}\VariableTok{$log\_dir}\StringTok{"} +\BuiltInTok{readonly} \VariableTok{logfile\_date=$(}\FunctionTok{date}\NormalTok{ {-}{-}date }\StringTok{"}\VariableTok{$start\_timestamp}\StringTok{"}\NormalTok{ {-}{-}universal +\%Y{-}\%m{-}\%d\_\%H{-}\%M{-}\%S}\VariableTok{)} +\BuiltInTok{readonly} \VariableTok{log\_file\_prefix=}\StringTok{"}\VariableTok{$log\_dir}\StringTok{/}\VariableTok{$\{mac\_address\}}\StringTok{\_}\VariableTok{$logfile\_date}\StringTok{"} + +\BuiltInTok{readonly} \VariableTok{log\_file=}\StringTok{"}\VariableTok{$log\_file\_prefix}\StringTok{.log"} +\BuiltInTok{echo} \StringTok{"Starting logging stdout and stderr to }\VariableTok{$log\_file}\StringTok{..."} + +\KeywordTok{\{} + \ExtensionTok{start\_step\_batch} \StringTok{"hardware log files creation"} + + \FunctionTok{log\_command\_to\_file()} \KeywordTok{\{} + \BuiltInTok{local}\NormalTok{ {-}r }\VariableTok{prefix=}\StringTok{"}\VariableTok{$1}\StringTok{"} + \BuiltInTok{local}\NormalTok{ {-}r }\VariableTok{extension=}\StringTok{"}\VariableTok{$2}\StringTok{"} + \BuiltInTok{local}\NormalTok{ {-}r }\VariableTok{command=}\StringTok{"}\VariableTok{$3}\StringTok{"} + + \BuiltInTok{local}\NormalTok{ {-}r }\VariableTok{hardware\_log\_file=}\StringTok{"}\VariableTok{$prefix}\StringTok{.}\VariableTok{$extension}\StringTok{"} + + \BuiltInTok{echo} \StringTok{"Writing }\VariableTok{$extension}\StringTok{ log file }\VariableTok{$hardware\_log\_file}\StringTok{..."} + + \CommentTok{\# shellcheck disable=SC2086 \# we need to expand args} + \FunctionTok{bash}\NormalTok{ {-}c }\StringTok{"}\VariableTok{$command}\StringTok{"} \OperatorTok{\textgreater{}} \StringTok{"}\VariableTok{$hardware\_log\_file}\StringTok{"} \KeywordTok{||} + \ExtensionTok{fatal\_error} \StringTok{"Cannot write }\VariableTok{$extension}\StringTok{ log file }\VariableTok{$hardware\_log\_file}\StringTok{."} + + \BuiltInTok{echo} \StringTok{"Wrote }\VariableTok{$extension}\StringTok{ log file }\VariableTok{$hardware\_log\_file}\StringTok{."} + \KeywordTok{\}} + + \ExtensionTok{log\_command\_to\_file} \StringTok{"}\VariableTok{$log\_file\_prefix}\StringTok{"}\NormalTok{ cpuinfo }\StringTok{\textquotesingle{}cat /proc/cpuinfo\textquotesingle{}} + \ExtensionTok{log\_command\_to\_file} \StringTok{"}\VariableTok{$log\_file\_prefix}\StringTok{"}\NormalTok{ meminfo }\StringTok{\textquotesingle{}cat /proc/meminfo\textquotesingle{}} + \ExtensionTok{log\_command\_to\_file} \StringTok{"}\VariableTok{$log\_file\_prefix}\StringTok{"}\NormalTok{ parted }\StringTok{\textquotesingle{}parted {-}{-}script {-}{-}list\textquotesingle{}} + + \ExtensionTok{start\_step\_batch} \StringTok{"remote images search"} + + \VariableTok{remote\_images\_dir=}\StringTok{"}\VariableTok{$mounting\_point\_remote}\StringTok{/images"} + + \BuiltInTok{echo} \StringTok{"Finding remote images..."} + \BuiltInTok{declare} \VariableTok{count=}\NormalTok{0} + \BuiltInTok{declare}\NormalTok{ {-}A }\VariableTok{images} + \BuiltInTok{declare} \VariableTok{found\_image\_name} + \KeywordTok{for} \ExtensionTok{image\_folder}\NormalTok{ in }\StringTok{"}\VariableTok{$remote\_images\_dir}\StringTok{"}\NormalTok{/*}\KeywordTok{;} \KeywordTok{do} + \VariableTok{found\_image\_name=$(}\FunctionTok{basename} \StringTok{"}\VariableTok{$image\_folder}\StringTok{"}\VariableTok{)} + \BuiltInTok{echo} \StringTok{"Image \textquotesingle{}}\VariableTok{$found\_image\_name}\StringTok{\textquotesingle{} found"} + \VariableTok{options=(}\StringTok{"}\VariableTok{$\{options[]\}}\StringTok{"} \StringTok{"}\VariableTok{$((}\NormalTok{++count}\VariableTok{))}\StringTok{"} \StringTok{"}\VariableTok{$found\_image\_name}\StringTok{"}\VariableTok{)} + \VariableTok{images[$count]=}\StringTok{"}\VariableTok{$found\_image\_name}\StringTok{"} + \KeywordTok{done} + \BuiltInTok{echo} \StringTok{"}\VariableTok{$count}\StringTok{ remote images found."} + + \KeywordTok{if [[} \VariableTok{$count} \OtherTok{{-}eq}\NormalTok{ 0}\KeywordTok{ ]]}\NormalTok{; }\KeywordTok{then} + \ExtensionTok{fatal\_error} \StringTok{"No image found in remote images directory }\VariableTok{$remote\_images\_dir}\StringTok{"} + \KeywordTok{fi} + + \ExtensionTok{start\_step\_interactive} \StringTok{"image selection"} + + \BuiltInTok{declare} \VariableTok{tty} + \VariableTok{tty=$(}\ExtensionTok{tty}\VariableTok{)} + \BuiltInTok{readonly} \VariableTok{tty} + + \BuiltInTok{declare} \VariableTok{choice} + \VariableTok{choice=$(}\ExtensionTok{dialog} \KeywordTok{\textbackslash{}} + \ExtensionTok{{-}{-}clear} \KeywordTok{\textbackslash{}} + \ExtensionTok{{-}{-}title} \StringTok{"Image selection"} \KeywordTok{\textbackslash{}} + \ExtensionTok{{-}{-}menu} \StringTok{"Select an image to deploy"} \KeywordTok{\textbackslash{}} + \ExtensionTok{0}\NormalTok{ 0 0 }\KeywordTok{\textbackslash{}} + \StringTok{"}\VariableTok{$\{options[]\}}\StringTok{"} \KeywordTok{\textbackslash{}} + \OperatorTok{2\textgreater{}\&1} \OperatorTok{\textgreater{}} \StringTok{"}\VariableTok{$tty}\StringTok{"}\VariableTok{)} + \BuiltInTok{readonly} \VariableTok{choice} + + \ExtensionTok{validate\_not\_empty} \StringTok{"}\VariableTok{$choice}\StringTok{"} \StringTok{"No image has been chosen"} + + \BuiltInTok{readonly} \VariableTok{image\_name=$\{images[$choice]\}} + + \BuiltInTok{echo} \StringTok{"Chosen image is }\VariableTok{$image\_name}\StringTok{"} + + \BuiltInTok{readonly} \VariableTok{remote\_image\_dir=}\StringTok{"}\VariableTok{$remote\_images\_dir}\StringTok{/}\VariableTok{$image\_name}\StringTok{"} + \BuiltInTok{readonly} \VariableTok{remote\_image\_gzip\_file=}\StringTok{"}\VariableTok{$remote\_image\_dir}\StringTok{/}\VariableTok{$image\_name}\StringTok{.img.gz"} + \BuiltInTok{readonly} \VariableTok{remote\_image\_clonezilla\_id\_file=}\StringTok{"}\VariableTok{$remote\_image\_dir}\StringTok{/Info{-}img{-}id.txt"} + + \BuiltInTok{readonly} \VariableTok{IMAGE\_TYPE\_RAW=}\StringTok{"raw"} + \BuiltInTok{readonly} \VariableTok{IMAGE\_TYPE\_CLONEZILLA=}\StringTok{"clonezilla"} + + \KeywordTok{if [[} \OtherTok{{-}f} \StringTok{"}\VariableTok{$remote\_image\_gzip\_file}\StringTok{"}\KeywordTok{ ]]}\NormalTok{; }\KeywordTok{then} + \BuiltInTok{readonly} \VariableTok{image\_type=}\StringTok{"}\VariableTok{$IMAGE\_TYPE\_RAW}\StringTok{"} + \BuiltInTok{readonly} \VariableTok{remote\_image\_md5\_file=}\StringTok{"}\VariableTok{$remote\_image\_dir}\StringTok{/}\VariableTok{$image\_name}\StringTok{.md5"} + \BuiltInTok{readonly} \VariableTok{remote\_image\_size\_file=}\StringTok{"}\VariableTok{$remote\_image\_dir}\StringTok{/}\VariableTok{$image\_name}\StringTok{.partition"} + \BuiltInTok{readonly} \VariableTok{parse\_end\_sector\_function=}\NormalTok{parse\_fdisk\_last\_partition\_end\_sector} + \KeywordTok{elif [[} \OtherTok{{-}f} \StringTok{"}\VariableTok{$remote\_image\_clonezilla\_id\_file}\StringTok{"}\KeywordTok{ ]]}\NormalTok{; }\KeywordTok{then} + \BuiltInTok{readonly} \VariableTok{image\_type=}\StringTok{"}\VariableTok{$IMAGE\_TYPE\_CLONEZILLA}\StringTok{"} + \BuiltInTok{readonly} \VariableTok{remote\_image\_size\_file=}\StringTok{"}\VariableTok{$remote\_image\_dir}\StringTok{/sda{-}pt.parted"} + \BuiltInTok{readonly} \VariableTok{parse\_end\_sector\_function=}\NormalTok{parse\_parted\_last\_partition\_end\_sector} + \KeywordTok{else} + \ExtensionTok{fatal\_error} \StringTok{"Cannot find type of image \textquotesingle{}}\VariableTok{$image\_name}\StringTok{\textquotesingle{} in \textquotesingle{}}\VariableTok{$remote\_image\_dir}\StringTok{\textquotesingle{}"} + \KeywordTok{fi} + + \ExtensionTok{start\_step\_batch} \StringTok{"image size verification"} + + \ExtensionTok{validate\_file\_exists} \KeywordTok{\textbackslash{}} + \StringTok{"}\VariableTok{$remote\_image\_size\_file}\StringTok{"} \KeywordTok{\textbackslash{}} + \StringTok{"cannot retrieve size of image because parted/fdisk dump file does not exist."} + + \BuiltInTok{readonly} \VariableTok{remote\_image\_size\_file\_content=}\StringTok{"}\OperatorTok{$(\textless{}} \StringTok{"}\VariableTok{$remote\_image\_size\_file}\StringTok{"}\OperatorTok{)}\StringTok{"} \KeywordTok{||} + \ExtensionTok{fatal\_error} \StringTok{"Cannot read parted/fdisk dump file \textquotesingle{}}\VariableTok{$remote\_image\_size\_file}\StringTok{\textquotesingle{}"} + + \BuiltInTok{declare} \VariableTok{image\_end\_sector} + \VariableTok{image\_end\_sector=$(}\StringTok{"}\VariableTok{$parse\_end\_sector\_function}\StringTok{"} \StringTok{"}\VariableTok{$remote\_image\_size\_file\_content}\StringTok{"}\VariableTok{)} + \BuiltInTok{readonly} \VariableTok{image\_end\_sector} + \ExtensionTok{validate\_nonzero\_uint} \StringTok{"}\VariableTok{$image\_end\_sector}\StringTok{"} \StringTok{"Invalid image end sector"} + + \ExtensionTok{ensure\_logical\_sector\_size} + \KeywordTok{((}\NormalTok{image\_size = image\_end\_sector * logical\_sector\_size}\KeywordTok{))} + \ExtensionTok{validate\_nonzero\_uint} \StringTok{"}\VariableTok{$image\_size}\StringTok{"} \StringTok{"Retrieved image size is invalid"} + + \BuiltInTok{echo} \StringTok{"Image type: }\VariableTok{$image\_type}\StringTok{"} + \BuiltInTok{echo} \StringTok{"Image size: }\VariableTok{$image\_size}\StringTok{ B"} + + \ExtensionTok{ensure\_total\_disk\_size} + \BuiltInTok{echo} \StringTok{"Available space in disk without image cache partition: }\VariableTok{$total\_disk\_size}\StringTok{ B"} + \ExtensionTok{ensure\_image\_cache\_partition\_size} + \BuiltInTok{echo} \StringTok{"Available space before image cache partition partition: }\VariableTok{$image\_cache\_partition\_size}\StringTok{ B"} + + \KeywordTok{if [[} \StringTok{"}\VariableTok{$image\_size}\StringTok{"} \OtherTok{{-}gt} \StringTok{"}\VariableTok{$total\_disk\_size}\StringTok{"}\KeywordTok{ ]]}\NormalTok{; }\KeywordTok{then} + \ExtensionTok{fatal\_error} \StringTok{"Insufficient disk space for imaging. Image size: }\VariableTok{$image\_size}\StringTok{ B Disk size: }\VariableTok{$total\_disk\_size}\StringTok{ B"} + \KeywordTok{fi} + + \VariableTok{mounting\_point\_hidden=}\StringTok{"/mnt"} + \VariableTok{DEPLOY\_MODE\_ALREADY\_CACHED=}\StringTok{\textquotesingle{}cached\textquotesingle{}} + \VariableTok{DEPLOY\_MODE\_CACHED\_NOW=}\StringTok{\textquotesingle{}cached\_now\textquotesingle{}} + \VariableTok{DEPLOY\_MODE\_NOT\_CACHED=}\StringTok{\textquotesingle{}not\_cached\textquotesingle{}} + + \ExtensionTok{ensure\_image\_cache\_partition\_start} + \KeywordTok{if [[} \StringTok{"}\VariableTok{$image\_size}\StringTok{"} \OtherTok{{-}gt} \StringTok{"}\VariableTok{$image\_cache\_partition\_start}\StringTok{"}\KeywordTok{ ]]}\NormalTok{; }\KeywordTok{then} + \ExtensionTok{start\_step\_interactive} \StringTok{"hidden partition destruction confirmation"} + + \ExtensionTok{warning} \StringTok{"Image overlaps with local image cache."} \KeywordTok{\textbackslash{}} + \StringTok{"It can be deployed from network but the image cache will be destroyed."} \KeywordTok{\textbackslash{}} + \StringTok{"Continue?"} + + \BuiltInTok{echo} \StringTok{"Sufficient disk space for imaging, but image cache partition will be destroyed if it exists."} + \VariableTok{deploy\_mode=}\StringTok{"}\VariableTok{$DEPLOY\_MODE\_NOT\_CACHED}\StringTok{"} + \KeywordTok{else} + \BuiltInTok{echo} \StringTok{"Sufficient disk space for imaging with cache. Image cache partition will be restored or created."} + + \BuiltInTok{readonly} \VariableTok{hidden\_partition\_dev=}\StringTok{"/dev/loop0"} + + \BuiltInTok{readonly} \VariableTok{HIDDEN\_PARTITION\_STATUS\_UNKNOWN=}\StringTok{\textquotesingle{}unknown\textquotesingle{}} + \BuiltInTok{readonly} \VariableTok{HIDDEN\_PARTITION\_STATUS\_CREATED=}\StringTok{\textquotesingle{}created\textquotesingle{}} + \BuiltInTok{readonly} \VariableTok{HIDDEN\_PARTITION\_STATUS\_RESTORED=}\StringTok{\textquotesingle{}restored\textquotesingle{}} + \BuiltInTok{declare} \VariableTok{hidden\_partition\_status=}\StringTok{"}\VariableTok{$HIDDEN\_PARTITION\_STATUS\_UNKNOWN}\StringTok{"} + + \CommentTok{\# Mounts the hidden partition.} + \CommentTok{\# If there is a mount error and the partition was restored, the partition will be} + \CommentTok{\# recreated and there will be another tentative to mount it.} + \FunctionTok{mount\_hidden\_partition()} \KeywordTok{\{} + \ExtensionTok{start\_step\_batch} \StringTok{"image cache partition mount tentative"} + + \BuiltInTok{echo} \StringTok{"Creating loopback node for }\VariableTok{$deployment\_disk}\StringTok{ (offset=}\VariableTok{$image\_cache\_partition\_start}\StringTok{) on }\VariableTok{$hidden\_partition\_dev}\StringTok{"} + + \ExtensionTok{losetup}\NormalTok{ {-}o }\StringTok{"}\VariableTok{$image\_cache\_partition\_start}\StringTok{"} \StringTok{"}\VariableTok{$hidden\_partition\_dev}\StringTok{"} \StringTok{"}\VariableTok{$deployment\_disk}\StringTok{"} \KeywordTok{||} + \ExtensionTok{fatal\_error} \StringTok{"Failed to create loopback node for }\VariableTok{$deployment\_disk}\StringTok{ on }\VariableTok{$hidden\_partition\_dev}\StringTok{"} + \BuiltInTok{echo} \StringTok{"Created loopback node for }\VariableTok{$deployment\_disk}\StringTok{ on }\VariableTok{$hidden\_partition\_dev}\StringTok{"} + + \BuiltInTok{echo} \StringTok{"Mounting hidden partition from }\VariableTok{$hidden\_partition\_dev}\StringTok{ on }\VariableTok{$mounting\_point\_hidden}\StringTok{..."} + \KeywordTok{if}\NormalTok{ ! }\FunctionTok{mount}\NormalTok{ {-}t ext2 }\StringTok{"}\VariableTok{$hidden\_partition\_dev}\StringTok{"} \StringTok{"}\VariableTok{$mounting\_point\_hidden}\StringTok{"}\KeywordTok{;} \KeywordTok{then} + \BuiltInTok{local}\NormalTok{ {-}r }\VariableTok{error\_message=}\StringTok{"Cannot mount }\VariableTok{$hidden\_partition\_status}\StringTok{ hidden partition from }\VariableTok{$hidden\_partition\_dev}\StringTok{ on }\VariableTok{$mounting\_point\_hidden}\StringTok{"} + + \KeywordTok{if [[} \StringTok{"}\VariableTok{$hidden\_partition\_status}\StringTok{"} \OtherTok{!=} \StringTok{"}\VariableTok{$HIDDEN\_PARTITION\_STATUS\_CREATED}\StringTok{"}\KeywordTok{ ]]}\NormalTok{; }\KeywordTok{then} + \BuiltInTok{echo} \StringTok{"}\VariableTok{$error\_message}\StringTok{"} + + \ExtensionTok{losetup}\NormalTok{ {-}d }\StringTok{"}\VariableTok{$hidden\_partition\_dev}\StringTok{"} \KeywordTok{||} + \ExtensionTok{fatal\_error} \StringTok{"Cannot detach loopback device }\VariableTok{$hidden\_partition\_dev}\StringTok{"} + + \ExtensionTok{start\_step\_batch} \StringTok{"image cache partition creation"} + \ExtensionTok{create\_hidden\_partition} + \ExtensionTok{mount\_hidden\_partition} + \VariableTok{hidden\_partition\_status=}\StringTok{"}\VariableTok{$HIDDEN\_PARTITION\_STATUS\_CREATED}\StringTok{"} + \KeywordTok{else} + \ExtensionTok{fatal\_error} \StringTok{"}\VariableTok{$error\_message}\StringTok{"} + \KeywordTok{fi} + \KeywordTok{fi} + + \KeywordTok{if [[} \StringTok{"}\VariableTok{$hidden\_partition\_status}\StringTok{"} \OtherTok{!=} \StringTok{"}\VariableTok{$HIDDEN\_PARTITION\_STATUS\_CREATED}\StringTok{"}\KeywordTok{ ]]}\NormalTok{; }\KeywordTok{then} + \VariableTok{hidden\_partition\_status=}\StringTok{"}\VariableTok{$HIDDEN\_PARTITION\_STATUS\_RESTORED}\StringTok{"} + \KeywordTok{fi} + + \BuiltInTok{echo} \StringTok{"Hidden partition mounted on }\VariableTok{$mounting\_point\_hidden}\StringTok{"} + \KeywordTok{\}} + + \ExtensionTok{mount\_hidden\_partition} + + \FunctionTok{read\_raw\_image\_id\_file()} \KeywordTok{\{} + \BuiltInTok{local}\NormalTok{ {-}r }\VariableTok{image\_id\_file=}\StringTok{"}\VariableTok{$1}\StringTok{"} + \FunctionTok{head}\NormalTok{ {-}n 1 }\StringTok{"}\VariableTok{$image\_id\_file}\StringTok{"} \KeywordTok{|} \FunctionTok{cut}\NormalTok{ {-}d }\StringTok{" "}\NormalTok{ {-}f 1} + \KeywordTok{\}} + + \FunctionTok{read\_clonezilla\_image\_id\_file()} \KeywordTok{\{} + \BuiltInTok{local}\NormalTok{ {-}r }\VariableTok{image\_id\_file=}\StringTok{"}\VariableTok{$1}\StringTok{"} + \FunctionTok{awk}\NormalTok{ {-}F }\StringTok{\textquotesingle{}=\textquotesingle{}} \StringTok{\textquotesingle{}/IMG\_ID/ \{print $2\}\textquotesingle{}} \StringTok{"}\VariableTok{$image\_id\_file}\StringTok{"} + \KeywordTok{\}} + + \CommentTok{\# Check if the selected image exists in cache by comparing its id file to the one stored in cache.} + \CommentTok{\# Return value: 0 if the image is cached, 1 if it\textquotesingle{}s not} + \FunctionTok{is\_image\_cached()} \KeywordTok{\{} + \KeywordTok{if [[}\NormalTok{ hidden\_partition\_status }\OtherTok{==} \StringTok{"}\VariableTok{$HIDDEN\_PARTITION\_STATUS\_CREATED}\StringTok{"}\KeywordTok{ ]]}\NormalTok{; }\KeywordTok{then} + \BuiltInTok{return}\NormalTok{ 1} + \KeywordTok{fi} + + \KeywordTok{if [[} \StringTok{"}\VariableTok{$image\_type}\StringTok{"} \OtherTok{==} \StringTok{"}\VariableTok{$IMAGE\_TYPE\_RAW}\StringTok{"}\KeywordTok{ ]]}\NormalTok{; }\KeywordTok{then} + \BuiltInTok{local}\NormalTok{ {-}r }\VariableTok{remote\_image\_id\_file=}\StringTok{"}\VariableTok{$remote\_image\_dir}\StringTok{/}\VariableTok{$image\_name}\StringTok{.md5"} + \BuiltInTok{local}\NormalTok{ {-}r }\VariableTok{cached\_image\_id\_file=}\StringTok{"}\VariableTok{$mounting\_point\_hidden}\StringTok{/}\VariableTok{$image\_name}\StringTok{.md5"} + \BuiltInTok{local}\NormalTok{ {-}r }\VariableTok{read\_image\_id\_file=}\NormalTok{read\_raw\_image\_id\_file} + \KeywordTok{elif [[} \StringTok{"}\VariableTok{$image\_type}\StringTok{"} \OtherTok{==} \StringTok{"}\VariableTok{$IMAGE\_TYPE\_CLONEZILLA}\StringTok{"}\KeywordTok{ ]]}\NormalTok{; }\KeywordTok{then} + \BuiltInTok{local}\NormalTok{ {-}r }\VariableTok{remote\_image\_id\_file=}\StringTok{"}\VariableTok{$remote\_image\_dir}\StringTok{/Info{-}img{-}id.txt"} + \BuiltInTok{local}\NormalTok{ {-}r }\VariableTok{cached\_image\_id\_file=}\StringTok{"}\VariableTok{$mounting\_point\_hidden}\StringTok{/}\VariableTok{$image\_name}\StringTok{/Info{-}img{-}id.txt"} + \BuiltInTok{local}\NormalTok{ {-}r }\VariableTok{read\_image\_id\_file=}\NormalTok{read\_clonezilla\_image\_id\_file} + \KeywordTok{else} + \ExtensionTok{fatal\_error} \StringTok{"Unhandled image type: }\VariableTok{$image\_type}\StringTok{"} + \KeywordTok{fi} + + \KeywordTok{if [[} \OtherTok{{-}f} \StringTok{"}\VariableTok{$cached\_image\_id\_file}\StringTok{"}\KeywordTok{ ]]}\NormalTok{; }\KeywordTok{then} + \BuiltInTok{local}\NormalTok{ {-}r }\VariableTok{cached\_image\_id=$($read\_image\_id\_file} \StringTok{"}\VariableTok{$cached\_image\_id\_file}\StringTok{"}\VariableTok{)} + \KeywordTok{if [[} \OtherTok{{-}z} \StringTok{"}\VariableTok{$cached\_image\_id}\StringTok{"}\KeywordTok{ ]]}\NormalTok{; }\KeywordTok{then} + \BuiltInTok{return}\NormalTok{ 1} + \KeywordTok{fi} + + \BuiltInTok{local}\NormalTok{ {-}r }\VariableTok{remote\_image\_id=$($read\_image\_id\_file} \StringTok{"}\VariableTok{$remote\_image\_id\_file}\StringTok{"}\VariableTok{)} + \KeywordTok{if [[} \StringTok{"}\VariableTok{$cached\_image\_id}\StringTok{"} \OtherTok{==} \StringTok{"}\VariableTok{$remote\_image\_id}\StringTok{"}\KeywordTok{ ]]}\NormalTok{; }\KeywordTok{then} + \BuiltInTok{return}\NormalTok{ 0} + \KeywordTok{fi} + \KeywordTok{fi} + \BuiltInTok{return}\NormalTok{ 1} + \KeywordTok{\}} + + \ExtensionTok{start\_step\_batch} \StringTok{"cached image search"} + \BuiltInTok{echo} \StringTok{"Checking if image is cached..."} + \KeywordTok{if} \ExtensionTok{is\_image\_cached}\KeywordTok{;} \KeywordTok{then} + \BuiltInTok{echo} \StringTok{"Image found in cache."} + \VariableTok{deploy\_mode=}\StringTok{"}\VariableTok{$DEPLOY\_MODE\_ALREADY\_CACHED}\StringTok{"} + \KeywordTok{else} + \BuiltInTok{echo} \StringTok{"Image not found in cache."} + + \ExtensionTok{start\_step\_batch} \StringTok{"image cache space availability check"} + + \VariableTok{cache\_available\_size\_bytes=$(}\FunctionTok{df}\NormalTok{ {-}{-}block{-}size=1 {-}{-}output=avail }\StringTok{"}\VariableTok{$mounting\_point\_hidden}\StringTok{"} \KeywordTok{|} \FunctionTok{tail}\NormalTok{ {-}n 1}\VariableTok{)} + + \KeywordTok{if [[} \OtherTok{{-}z} \StringTok{"}\VariableTok{$cache\_available\_size\_bytes}\StringTok{"}\KeywordTok{ ]]}\NormalTok{; }\KeywordTok{then} + \ExtensionTok{fatal\_error} \StringTok{"Cannot retrieve available size in cache."} + \KeywordTok{fi} + + \KeywordTok{((}\NormalTok{cache\_available\_size\_bytes = cache\_available\_size\_bytes {-} 4096}\KeywordTok{))} + + \BuiltInTok{echo} \StringTok{"Available size in cache: }\VariableTok{$cache\_available\_size\_bytes}\StringTok{ B"} + + \KeywordTok{if [[} \StringTok{"}\VariableTok{$image\_type}\StringTok{"} \OtherTok{==} \StringTok{"}\VariableTok{$IMAGE\_TYPE\_RAW}\StringTok{"}\KeywordTok{ ]]}\NormalTok{; }\KeywordTok{then} + \VariableTok{image\_size\_bytes=$(}\FunctionTok{stat}\NormalTok{ {-}c \%s }\StringTok{"}\VariableTok{$remote\_image\_gzip\_file}\StringTok{"}\VariableTok{)} + \KeywordTok{elif [[} \StringTok{"}\VariableTok{$image\_type}\StringTok{"} \OtherTok{==} \StringTok{"}\VariableTok{$IMAGE\_TYPE\_CLONEZILLA}\StringTok{"}\KeywordTok{ ]]}\NormalTok{; }\KeywordTok{then} + \VariableTok{image\_size\_bytes=$(}\FunctionTok{du}\NormalTok{ {-}b {-}c }\StringTok{"}\VariableTok{$remote\_image\_dir}\StringTok{"} \KeywordTok{|} \FunctionTok{tail}\NormalTok{ {-}n1 }\KeywordTok{|} \FunctionTok{cut}\NormalTok{ {-}f1}\VariableTok{)} + \KeywordTok{else} + \ExtensionTok{fatal\_error} \StringTok{"Unhandled image type: }\VariableTok{$image\_type}\StringTok{"} + \KeywordTok{fi} + + \BuiltInTok{echo} \StringTok{"Size of image to download: }\VariableTok{$image\_size\_bytes}\StringTok{ B"} + + \CommentTok{\# Check enough space available in hidden partition for caching} + \KeywordTok{if [[} \StringTok{"}\VariableTok{$image\_size\_bytes}\StringTok{"} \OtherTok{{-}lt} \StringTok{"}\VariableTok{$cache\_available\_size\_bytes}\StringTok{"}\KeywordTok{ ]]}\NormalTok{; }\KeywordTok{then} + \BuiltInTok{echo} \StringTok{"Enough space for caching. Image will be cached and deployed simultaneously."} + \VariableTok{deploy\_mode=}\StringTok{"}\VariableTok{$DEPLOY\_MODE\_CACHED\_NOW}\StringTok{"} + \KeywordTok{else} + \BuiltInTok{echo} \StringTok{"Not enough space for caching. Image will be deployed without caching."} + \VariableTok{deploy\_mode=}\StringTok{"}\VariableTok{$DEPLOY\_MODE\_NOT\_CACHED}\StringTok{"} + \KeywordTok{fi} + \KeywordTok{fi} + \KeywordTok{fi} + + \FunctionTok{deploy\_image\_with\_clonezilla()} \KeywordTok{\{} + \BuiltInTok{local}\NormalTok{ {-}r }\VariableTok{clonezilla\_images\_dir=}\StringTok{"}\VariableTok{$1}\StringTok{"} + \BuiltInTok{echo} \StringTok{"Starting deployment of image }\VariableTok{$image\_name}\StringTok{ from }\VariableTok{$clonezilla\_images\_dir}\StringTok{ with clonezilla..."} + \CommentTok{\# yes \textquotesingle{}\textquotesingle{} 2\textgreater{}/dev/null |} + \ExtensionTok{ocs{-}sr} \KeywordTok{\textbackslash{}} + \ExtensionTok{{-}{-}ignore{-}update{-}efi{-}nvram} \KeywordTok{\textbackslash{}} + \ExtensionTok{{-}{-}ocsroot} \StringTok{"}\VariableTok{$clonezilla\_images\_dir}\StringTok{"} \KeywordTok{\textbackslash{}} + \ExtensionTok{{-}{-}skip{-}check{-}restorable{-}r} \KeywordTok{\textbackslash{}} + \ExtensionTok{{-}{-}nogui} \KeywordTok{\textbackslash{}} + \ExtensionTok{{-}{-}batch} \KeywordTok{\textbackslash{}} + \ExtensionTok{restoredisk} \StringTok{"}\VariableTok{$image\_name}\StringTok{"}\NormalTok{ sda} + + \BuiltInTok{echo} \StringTok{"Checking for error during clonezilla deployment..."} + + \KeywordTok{if} \FunctionTok{grep} \StringTok{"Failed to restore partition image file"}\NormalTok{ /var/log/clonezilla.log}\KeywordTok{;} \KeywordTok{then} + \ExtensionTok{fatal\_error} \StringTok{"Error while deploying image with clonezilla."} + \KeywordTok{fi} + + \BuiltInTok{echo} \StringTok{"Image deployed with clonezilla."} + \KeywordTok{\}} + + \FunctionTok{print\_progress()} \KeywordTok{\{} + \ExtensionTok{pv}\NormalTok{ {-}ptebar {-}{-}size }\StringTok{"}\VariableTok{$image\_size}\StringTok{"} \OperatorTok{2\textgreater{}}\StringTok{"}\VariableTok{$tty}\StringTok{"} + \KeywordTok{\}} + + \ExtensionTok{start\_step\_batch} \StringTok{"image deployment"} + \KeywordTok{if [[} \StringTok{"}\VariableTok{$deploy\_mode}\StringTok{"} \OtherTok{==} \StringTok{"}\VariableTok{$DEPLOY\_MODE\_CACHED\_NOW}\StringTok{"}\KeywordTok{ ]]}\NormalTok{; }\KeywordTok{then} + \BuiltInTok{echo} \StringTok{"Saving image to cache and deploying it..."} + \KeywordTok{if [[} \StringTok{"}\VariableTok{$image\_type}\StringTok{"} \OtherTok{==} \StringTok{"}\VariableTok{$IMAGE\_TYPE\_RAW}\StringTok{"}\KeywordTok{ ]]}\NormalTok{; }\KeywordTok{then} + \FunctionTok{cp} \StringTok{"}\VariableTok{$remote\_image\_md5\_file}\StringTok{"} \StringTok{"}\VariableTok{$mounting\_point\_hidden}\StringTok{/"} \KeywordTok{||} + \ExtensionTok{fatal\_error} \StringTok{"Cannot copy hash of image to }\VariableTok{$mounting\_point\_hidden}\StringTok{"} + + \FunctionTok{tee} \StringTok{"}\VariableTok{$mounting\_point\_hidden}\StringTok{/}\VariableTok{$image\_name}\StringTok{.img.gz"} \OperatorTok{\textless{}} \StringTok{"}\VariableTok{$remote\_image\_gzip\_file}\StringTok{"} \KeywordTok{|} + \FunctionTok{gunzip}\NormalTok{ {-}c }\KeywordTok{|} + \ExtensionTok{print\_progress} \KeywordTok{|} + \FunctionTok{dd}\NormalTok{ bs=128k of=}\StringTok{"}\VariableTok{$deployment\_disk}\StringTok{"} \KeywordTok{||} + \ExtensionTok{fatal\_error} \StringTok{"Cannot copy image to cache and disk."} + \KeywordTok{elif [[} \StringTok{"}\VariableTok{$image\_type}\StringTok{"} \OtherTok{==} \StringTok{"}\VariableTok{$IMAGE\_TYPE\_CLONEZILLA}\StringTok{"}\KeywordTok{ ]]}\NormalTok{; }\KeywordTok{then} + \BuiltInTok{echo} \StringTok{"Starting copy of clonezilla image to cache..."} + \FunctionTok{rm}\NormalTok{ {-}rf }\StringTok{"}\VariableTok{$\{mounting\_point\_hidden:?\}}\StringTok{/}\VariableTok{$image\_name}\StringTok{"} + \FunctionTok{cp}\NormalTok{ {-}r }\StringTok{"}\VariableTok{$remote\_image\_dir}\StringTok{"} \StringTok{"}\VariableTok{$\{mounting\_point\_hidden:?\}}\StringTok{/"} \KeywordTok{||} + \ExtensionTok{fatal\_error} \StringTok{"Error while copying remote image to cache."} + \BuiltInTok{echo} \StringTok{"Clonezilla image copied to cache."} + \BuiltInTok{echo} \StringTok{"Content of cache:"} + \FunctionTok{ls}\NormalTok{ {-}als }\StringTok{"}\VariableTok{$mounting\_point\_hidden}\StringTok{"} + + \ExtensionTok{deploy\_image\_with\_clonezilla} \StringTok{"}\VariableTok{$mounting\_point\_hidden}\StringTok{"} + \KeywordTok{else} + \ExtensionTok{fatal\_error} \StringTok{"Unhandled image type: }\VariableTok{$image\_type}\StringTok{"} + \KeywordTok{fi} + + \BuiltInTok{echo} \StringTok{"Image deployed and cached."} + \KeywordTok{elif [[} \StringTok{"}\VariableTok{$deploy\_mode}\StringTok{"} \OtherTok{==} \StringTok{"}\VariableTok{$DEPLOY\_MODE\_ALREADY\_CACHED}\StringTok{"}\KeywordTok{ ]]}\NormalTok{; }\KeywordTok{then} + \BuiltInTok{echo} \StringTok{"Deploying image from cache..."} + + \KeywordTok{if [[} \StringTok{"}\VariableTok{$image\_type}\StringTok{"} \OtherTok{==} \StringTok{"}\VariableTok{$IMAGE\_TYPE\_RAW}\StringTok{"}\KeywordTok{ ]]}\NormalTok{; }\KeywordTok{then} + \FunctionTok{gunzip}\NormalTok{ {-}c }\StringTok{"}\VariableTok{$mounting\_point\_hidden}\StringTok{/}\VariableTok{$image\_name}\StringTok{.img.gz"} \KeywordTok{|} + \ExtensionTok{print\_progress} \KeywordTok{|} + \FunctionTok{dd}\NormalTok{ bs=1M of=}\StringTok{"}\VariableTok{$deployment\_disk}\StringTok{"} \KeywordTok{||} + \ExtensionTok{fatal\_error} \StringTok{"Cannot copy image from cache to disk."} + \KeywordTok{elif [[} \StringTok{"}\VariableTok{$image\_type}\StringTok{"} \OtherTok{==} \StringTok{"}\VariableTok{$IMAGE\_TYPE\_CLONEZILLA}\StringTok{"}\KeywordTok{ ]]}\NormalTok{; }\KeywordTok{then} + \ExtensionTok{deploy\_image\_with\_clonezilla} \StringTok{"}\VariableTok{$mounting\_point\_hidden}\StringTok{"} + \KeywordTok{else} + \ExtensionTok{fatal\_error} \StringTok{"Unhandled image type: }\VariableTok{$image\_type}\StringTok{"} + \KeywordTok{fi} + + \BuiltInTok{echo} \StringTok{"Image deployed from cache."} + \KeywordTok{elif [[} \StringTok{"}\VariableTok{$deploy\_mode}\StringTok{"} \OtherTok{==} \StringTok{"}\VariableTok{$DEPLOY\_MODE\_NOT\_CACHED}\StringTok{"}\KeywordTok{ ]]}\NormalTok{; }\KeywordTok{then} + \BuiltInTok{echo} \StringTok{"Deploying image without caching..."} + + \KeywordTok{if [[} \StringTok{"}\VariableTok{$image\_type}\StringTok{"} \OtherTok{==} \StringTok{"}\VariableTok{$IMAGE\_TYPE\_RAW}\StringTok{"}\KeywordTok{ ]]}\NormalTok{; }\KeywordTok{then} + \FunctionTok{gunzip}\NormalTok{ {-}c }\StringTok{"}\VariableTok{$remote\_image\_gzip\_file}\StringTok{"} \KeywordTok{|} + \ExtensionTok{print\_progress} \KeywordTok{|} + \FunctionTok{dd}\NormalTok{ of=}\StringTok{"}\VariableTok{$deployment\_disk}\StringTok{"}\NormalTok{ bs=128k }\KeywordTok{||} + \ExtensionTok{fatal\_error} \StringTok{"Cannot copy image without caching."} + \KeywordTok{elif [[} \StringTok{"}\VariableTok{$image\_type}\StringTok{"} \OtherTok{==} \StringTok{"}\VariableTok{$IMAGE\_TYPE\_CLONEZILLA}\StringTok{"}\KeywordTok{ ]]}\NormalTok{; }\KeywordTok{then} + \ExtensionTok{deploy\_image\_with\_clonezilla} \StringTok{"}\VariableTok{$remote\_images\_dir}\StringTok{"} + \KeywordTok{else} + \ExtensionTok{fatal\_error} \StringTok{"Unhandled image type: }\VariableTok{$image\_type}\StringTok{"} + \KeywordTok{fi} + + \BuiltInTok{echo} \StringTok{"Image deployed without caching."} + \KeywordTok{else} + \ExtensionTok{fatal\_error} \StringTok{"Unhandled deploy mode: }\VariableTok{$deploy\_mode}\StringTok{"} + \KeywordTok{fi} + + \BuiltInTok{echo} \StringTok{"Deployment of image }\VariableTok{$image\_name}\StringTok{ (}\VariableTok{$image\_size}\StringTok{ B) done."} + + \KeywordTok{if} \ExtensionTok{findmnt}\NormalTok{ {-}{-}mountpoint }\StringTok{"}\VariableTok{$mounting\_point\_hidden}\StringTok{"}\KeywordTok{;} \KeywordTok{then} + \ExtensionTok{start\_step\_batch} \StringTok{"image cache partition unmount"} + \BuiltInTok{echo} \StringTok{"Unmounting hidden partition from }\VariableTok{$mounting\_point\_hidden}\StringTok{"} + \FunctionTok{umount} \StringTok{"}\VariableTok{$mounting\_point\_hidden}\StringTok{"} \KeywordTok{||} + \ExtensionTok{fatal\_error} \StringTok{"Cannot unmount hidden partition from }\VariableTok{$mounting\_point\_hidden}\StringTok{"} + \BuiltInTok{echo} \StringTok{"Unmounted hidden partition from }\VariableTok{$mounting\_point\_hidden}\StringTok{"} + + \ExtensionTok{start\_step\_batch} \StringTok{"image cache partition check"} + \ExtensionTok{fsck}\NormalTok{ {-}y }\StringTok{"}\VariableTok{$hidden\_partition\_dev}\StringTok{"} + \KeywordTok{fi} + + \ExtensionTok{start\_step\_batch} \StringTok{"EFI entrypoint file creation"} + + \BuiltInTok{readonly} \VariableTok{remote\_image\_efi\_entrypoint\_file=}\StringTok{"}\VariableTok{$remote\_image\_dir}\StringTok{/efi\_entrypoint"} + \BuiltInTok{readonly} \VariableTok{remote\_image\_efi\_nvram\_file=}\StringTok{"}\VariableTok{$remote\_image\_dir}\StringTok{/efi{-}nvram.dat"} + \BuiltInTok{readonly} \VariableTok{mounting\_point\_esp=}\StringTok{"/bootiful/esp"} + \BuiltInTok{readonly} \VariableTok{esp\_partition=}\StringTok{"}\VariableTok{$\{deployment\_disk\}}\StringTok{1"} + + \FunctionTok{mount\_esp()} \KeywordTok{\{} + \BuiltInTok{echo} \StringTok{"Mounting ESP partition..."} + \ExtensionTok{ensure\_directory} \StringTok{"}\VariableTok{$mounting\_point\_esp}\StringTok{"} + \ExtensionTok{refresh\_partition\_table} + \FunctionTok{mount} \StringTok{"}\VariableTok{$esp\_partition}\StringTok{"} \StringTok{"}\VariableTok{$mounting\_point\_esp}\StringTok{"} \KeywordTok{||} + \ExtensionTok{fatal\_error} \StringTok{"Cannot mount }\VariableTok{$esp\_partition}\StringTok{ on }\VariableTok{$mounting\_point\_esp}\StringTok{"} + \BuiltInTok{echo} \StringTok{"ESP partition mounted."} + \KeywordTok{\}} + + \FunctionTok{write\_efi\_entrypoint\_file()} \KeywordTok{\{} + \BuiltInTok{local}\NormalTok{ {-}r }\VariableTok{efi\_entrypoint\_file\_content=}\StringTok{"}\VariableTok{$1}\StringTok{"} + \BuiltInTok{local}\NormalTok{ {-}r }\VariableTok{target\_efi\_entrypoint\_file=}\StringTok{"}\VariableTok{$mounting\_point\_esp}\StringTok{/efi\_entrypoint"} + + \BuiltInTok{echo} \StringTok{"Writing efi entrypoint file \textquotesingle{}}\VariableTok{$target\_efi\_entrypoint\_file}\StringTok{\textquotesingle{}"} + + \BuiltInTok{echo} \StringTok{"}\VariableTok{$efi\_entrypoint\_file\_content}\StringTok{"} \OperatorTok{\textgreater{}} \StringTok{"}\VariableTok{$target\_efi\_entrypoint\_file}\StringTok{"} \KeywordTok{||} + \ExtensionTok{fatal\_error} \StringTok{"Cannot write EFI entrypoint file \textquotesingle{}}\VariableTok{$target\_efi\_entrypoint\_file}\StringTok{\textquotesingle{}."} + + \BuiltInTok{echo} \StringTok{"EFI entrypoint file \textquotesingle{}}\VariableTok{$target\_efi\_entrypoint\_file}\StringTok{\textquotesingle{} written."} + + \FunctionTok{umount} \StringTok{"}\VariableTok{$mounting\_point\_esp}\StringTok{"} + \KeywordTok{\}} + + \KeywordTok{if [[} \OtherTok{{-}e} \StringTok{"}\VariableTok{$remote\_image\_efi\_entrypoint\_file}\StringTok{"}\KeywordTok{ ]]}\NormalTok{; }\KeywordTok{then} + \BuiltInTok{echo} \StringTok{"EFI entrypoint file detected. Copying it to ESP root..."} + \ExtensionTok{mount\_esp} + \ExtensionTok{write\_efi\_entrypoint\_file} \StringTok{"}\VariableTok{$(}\FunctionTok{cat} \StringTok{"}\VariableTok{$remote\_image\_efi\_entrypoint\_file}\StringTok{"}\VariableTok{)}\StringTok{"} + \KeywordTok{elif [[} \OtherTok{{-}e} \StringTok{"}\VariableTok{$remote\_image\_efi\_nvram\_file}\StringTok{"}\KeywordTok{ ]]}\NormalTok{; }\KeywordTok{then} + \BuiltInTok{echo} \StringTok{"Trying to find boot entry from efi nvram file }\VariableTok{$remote\_image\_efi\_nvram\_file}\StringTok{..."} + + \VariableTok{boot\_order\_entries=}\StringTok{"}\VariableTok{$(}\FunctionTok{sed}\NormalTok{ {-}nr }\StringTok{\textquotesingle{}s/\^{}BootOrder: ([0{-}9]+(,[0{-}9]+)*)$/\textbackslash{}1/p\textquotesingle{}} \StringTok{"}\VariableTok{$remote\_image\_efi\_nvram\_file}\StringTok{"} \KeywordTok{|} + \FunctionTok{head}\NormalTok{ {-}n 1 }\KeywordTok{|} + \FunctionTok{tr} \StringTok{\textquotesingle{},\textquotesingle{}} \StringTok{\textquotesingle{} \textquotesingle{}}\VariableTok{)}\StringTok{"} + + \KeywordTok{if [[} \OtherTok{{-}n} \StringTok{"}\VariableTok{$boot\_order\_entries}\StringTok{"}\KeywordTok{ ]]}\NormalTok{; }\KeywordTok{then} + \BuiltInTok{echo} \StringTok{"Boot order entries found: }\VariableTok{$boot\_order\_entries}\StringTok{"} + \VariableTok{written\_boot\_order\_entry=}\StringTok{""} + \KeywordTok{for} \ExtensionTok{boot\_order\_entry}\NormalTok{ in }\VariableTok{$boot\_order\_entries}\KeywordTok{;} \KeywordTok{do} + \BuiltInTok{echo} \StringTok{"Trying to find boot file path for boot order entry }\VariableTok{$boot\_order\_entry}\StringTok{..."} + \VariableTok{boot\_file\_path=}\StringTok{"}\VariableTok{$(}\FunctionTok{sed}\NormalTok{ {-}nr }\StringTok{"s|\^{}Boot}\VariableTok{$boot\_order\_entry}\StringTok{.*\textbackslash{}tHD\textbackslash{}(1.*\textbackslash{})/File\textbackslash{}((.*)\textbackslash{}).*$|\textbackslash{}1|p"} \StringTok{"}\VariableTok{$remote\_image\_efi\_nvram\_file}\StringTok{"}\VariableTok{)}\StringTok{"} + + \KeywordTok{if [[} \OtherTok{{-}z} \StringTok{"}\VariableTok{$boot\_file\_path}\StringTok{"}\KeywordTok{ ]]}\NormalTok{; }\KeywordTok{then} + \BuiltInTok{echo} \StringTok{"Boot file path not found for boot entry }\VariableTok{$boot\_order\_entry}\StringTok{"} + \BuiltInTok{continue} + \KeywordTok{fi} + + \BuiltInTok{echo} \StringTok{"Boot file path found for boot entry }\VariableTok{$boot\_order\_entry}\StringTok{: }\VariableTok{$boot\_file\_path}\StringTok{"} + + \ExtensionTok{mount\_esp} + + \KeywordTok{if [[} \StringTok{"}\VariableTok{$boot\_file\_path}\StringTok{"}\NormalTok{ =\textasciitilde{} \^{}}\DataTypeTok{\textbackslash{}\textbackslash{}}\KeywordTok{ ]]}\NormalTok{; }\KeywordTok{then} + \BuiltInTok{echo} \StringTok{"Boot file path looks like a windows{-}like path. Converting it to a unix{-}like path..."} + \VariableTok{unix\_boot\_file\_path=}\StringTok{"}\VariableTok{$(}\BuiltInTok{echo} \StringTok{"}\VariableTok{$boot\_file\_path}\StringTok{"} \KeywordTok{|} \FunctionTok{tr} \DataTypeTok{\textbackslash{}\textbackslash{}\textbackslash{}\textbackslash{}}\NormalTok{ /}\VariableTok{)}\StringTok{"} + \BuiltInTok{echo} \StringTok{"Windows{-}like path \textquotesingle{}}\VariableTok{$boot\_file\_path}\StringTok{\textquotesingle{} converted to unix{-}like path \textquotesingle{}}\VariableTok{$unix\_boot\_file\_path}\StringTok{\textquotesingle{}"} + + \BuiltInTok{echo} \StringTok{"Trying to find the case sensitive path for \textquotesingle{}}\VariableTok{$unix\_boot\_file\_path}\StringTok{\textquotesingle{} in EFI..."} + \VariableTok{boot\_file\_path=}\StringTok{"}\VariableTok{$(} + \FunctionTok{find} \StringTok{"}\VariableTok{$mounting\_point\_esp}\StringTok{"} \KeywordTok{\textbackslash{}} + \ExtensionTok{{-}type}\NormalTok{ f }\KeywordTok{\textbackslash{}} + \ExtensionTok{{-}ipath} \StringTok{"}\VariableTok{$mounting\_point\_esp$unix\_boot\_file\_path}\StringTok{"} \KeywordTok{\textbackslash{}} + \ExtensionTok{{-}printf} \StringTok{\textquotesingle{}/\%P\textbackslash{}n\textquotesingle{}} \KeywordTok{|} + \FunctionTok{head}\NormalTok{ {-}n 1} + \VariableTok{)}\StringTok{"} + + \KeywordTok{if [[} \OtherTok{{-}z} \StringTok{"}\VariableTok{$boot\_file\_path}\StringTok{"}\KeywordTok{ ]]}\NormalTok{; }\KeywordTok{then} + \ExtensionTok{fatal\_error} \StringTok{"Cannot find a case insensitive match for efi boot file \textquotesingle{}}\VariableTok{$unix\_boot\_file\_path}\StringTok{\textquotesingle{}"} + \KeywordTok{fi} + + \BuiltInTok{echo} \StringTok{"Case insensitive EFI boot file path found: \textquotesingle{}}\VariableTok{$boot\_file\_path}\StringTok{\textquotesingle{}."} + \KeywordTok{fi} + + \ExtensionTok{write\_efi\_entrypoint\_file} \StringTok{"set efi\_entrypoint=}\VariableTok{$boot\_file\_path}\StringTok{"} + \VariableTok{written\_boot\_order\_entry=}\StringTok{"}\VariableTok{$boot\_order\_entry}\StringTok{"} + \BuiltInTok{break} + \KeywordTok{done} + + \KeywordTok{if [[} \OtherTok{{-}z} \StringTok{"}\VariableTok{$written\_boot\_order\_entry}\StringTok{"}\KeywordTok{ ]]}\NormalTok{; }\KeywordTok{then} + \ExtensionTok{fatal\_error} \StringTok{"No bootfile found in \textquotesingle{}}\VariableTok{$remote\_image\_efi\_nvram\_file}\StringTok{\textquotesingle{}."} + \KeywordTok{fi} + \KeywordTok{else} + \ExtensionTok{fatal\_error} \StringTok{"Boot order entries not found in \textquotesingle{}}\VariableTok{$remote\_image\_efi\_nvram\_file}\StringTok{\textquotesingle{}."} + \KeywordTok{fi} + \KeywordTok{else} + \BuiltInTok{echo} \StringTok{"No EFI entrypoint file or EFI nvram file found."} + \KeywordTok{fi} + + \ExtensionTok{start\_step\_batch} \StringTok{"signature creation"} + + \KeywordTok{((}\NormalTok{signature\_offset = total\_disk\_size {-} 200}\KeywordTok{))} + \VariableTok{signature=}\StringTok{"hepia2015"} + + \BuiltInTok{echo} \StringTok{"Writing signature \textquotesingle{}}\VariableTok{$signature}\StringTok{\textquotesingle{} on offset }\VariableTok{$signature\_offset}\StringTok{ B..."} + \BuiltInTok{echo}\NormalTok{ {-}ne }\StringTok{"}\VariableTok{$signature}\StringTok{"} \KeywordTok{|} \FunctionTok{dd}\NormalTok{ of=}\StringTok{"}\VariableTok{$deployment\_disk}\StringTok{"}\NormalTok{ seek=}\StringTok{"}\VariableTok{$signature\_offset}\StringTok{"}\NormalTok{ bs=1 iflag=skip\_bytes }\KeywordTok{||} + \ExtensionTok{fatal\_error} \StringTok{"Cannot write signature at the end of the disk"} + \BuiltInTok{echo} \StringTok{"Signature written."} + + \BuiltInTok{echo} \StringTok{"Image deployment process successful."} + + \ExtensionTok{print\_step\_durations} + +\KeywordTok{\}} \OperatorTok{2\textgreater{}\&1} \KeywordTok{|} \FunctionTok{tee} \StringTok{"}\VariableTok{$log\_file}\StringTok{"} + +\BuiltInTok{exit} \StringTok{"}\VariableTok{$\{PIPESTATUS[0]\}}\StringTok{"} +\end{Highlighting} +\end{Shaded} + +\hypertarget{deployerbootiful-save-image-script-utilitaire-de-cruxe9ation-dimage-raw}{% +\section{\texorpdfstring{\texttt{deployer/bootiful-save-image}: script +utilitaire de création d'image +raw}{deployer/bootiful-save-image: script utilitaire de création d'image raw}}\label{deployerbootiful-save-image-script-utilitaire-de-cruxe9ation-dimage-raw}} + +\begin{Shaded} +\begin{Highlighting}[] +\CommentTok{\#!/bin/bash} +\BuiltInTok{readonly} \VariableTok{SCRIPT\_NAME=}\StringTok{"}\VariableTok{$(}\FunctionTok{basename} \StringTok{"}\VariableTok{$0}\StringTok{"}\VariableTok{)}\StringTok{"} +\BuiltInTok{readonly} \VariableTok{SCRIPT\_DIR=}\StringTok{"}\VariableTok{$(}\FunctionTok{readlink}\NormalTok{ {-}m }\StringTok{"}\VariableTok{$(}\FunctionTok{dirname} \StringTok{"}\VariableTok{$0}\StringTok{"}\VariableTok{)}\StringTok{"}\VariableTok{)}\StringTok{"} + +\FunctionTok{usage()} \KeywordTok{\{} + \FunctionTok{cat} \OperatorTok{\textless{}\textless{} EOF} +\NormalTok{Usage:} + \VariableTok{$SCRIPT\_DIR}\NormalTok{ IMAGE\_NAME} + \VariableTok{$SCRIPT\_DIR}\NormalTok{ [{-}h | {-}{-}help]} + +\NormalTok{Description:} +\NormalTok{ Saves a raw dd image of the /dev/sda device to the remote server shared images} +\NormalTok{ folder.} + +\NormalTok{Parameters:} +\NormalTok{ IMAGE\_NAME Name of the image to create} + +\NormalTok{Options:} +\NormalTok{ {-}h {-}{-}help Shows this help} + +\NormalTok{Example:} +\NormalTok{ ./}\VariableTok{$SCRIPT\_NAME}\NormalTok{ debian{-}buster{-}x86\_64{-}efi} +\OperatorTok{EOF} +\KeywordTok{\}} + +\KeywordTok{if [[} \StringTok{"}\VariableTok{$1}\StringTok{"} \OtherTok{==} \StringTok{"{-}h"}\NormalTok{ || }\StringTok{"}\VariableTok{$1}\StringTok{"} \OtherTok{==} \StringTok{"{-}{-}help"}\KeywordTok{ ]]}\NormalTok{; }\KeywordTok{then} + \ExtensionTok{usage} + \BuiltInTok{exit}\NormalTok{ 0} +\KeywordTok{fi} + +\BuiltInTok{readonly} \VariableTok{image\_name=}\StringTok{"}\VariableTok{$1}\StringTok{"} +\KeywordTok{if [[} \OtherTok{{-}z} \StringTok{"}\VariableTok{$image\_name}\StringTok{"}\KeywordTok{ ]]}\NormalTok{; }\KeywordTok{then} + \ExtensionTok{usage} + \BuiltInTok{exit}\NormalTok{ 1} +\KeywordTok{fi} + +\CommentTok{\# Loads declarations from the \textquotesingle{}bootiful{-}common\textquotesingle{} script, which is a "library"} +\CommentTok{\# of functions and constants shared by multiple bootiful{-}* scripts.} +\BuiltInTok{readonly} \VariableTok{bootiful\_common\_script\_file=}\StringTok{"}\VariableTok{$SCRIPT\_DIR}\StringTok{/bootiful{-}common"} +\KeywordTok{if [[} \OtherTok{!} \OtherTok{{-}f} \StringTok{"}\VariableTok{$bootiful\_common\_script\_file}\StringTok{"}\KeywordTok{ ]]}\NormalTok{; }\KeywordTok{then} + \OperatorTok{\textgreater{}\&2} \BuiltInTok{echo} \StringTok{"Fatal error: cannot find required script file \textquotesingle{}}\VariableTok{$bootiful\_common\_script\_file}\StringTok{\textquotesingle{}."} + \BuiltInTok{exit}\NormalTok{ 1} +\KeywordTok{fi} +\CommentTok{\# shellcheck source=./bootiful{-}common} +\BuiltInTok{.} \StringTok{"}\VariableTok{$bootiful\_common\_script\_file}\StringTok{"} + +\ExtensionTok{ensure\_remote\_shared\_mounted} + +\BuiltInTok{echo} \StringTok{"Finding size of the image to create..."} +\BuiltInTok{readonly} \VariableTok{parted\_unit=}\StringTok{"B"} + +\BuiltInTok{declare} \VariableTok{parted\_output} +\VariableTok{parted\_output=$(}\ExtensionTok{parted}\NormalTok{ {-}{-}script }\StringTok{"}\VariableTok{$deployment\_disk}\StringTok{"}\NormalTok{ unit }\StringTok{"}\VariableTok{$parted\_unit}\StringTok{"}\NormalTok{ print}\VariableTok{)} \KeywordTok{||} + \ExtensionTok{fatal\_error} \StringTok{"failed to save parted output"} +\BuiltInTok{readonly} \VariableTok{parted\_output} + +\BuiltInTok{declare} \VariableTok{image\_size} +\VariableTok{image\_size=$(}\ExtensionTok{parse\_parted\_last\_partition\_end} \StringTok{"}\VariableTok{$parted\_output}\StringTok{"} \StringTok{"}\VariableTok{$parted\_unit}\StringTok{"}\VariableTok{)} +\BuiltInTok{readonly} \VariableTok{image\_size} + +\BuiltInTok{echo} \StringTok{"Image size: }\VariableTok{$image\_size}\StringTok{"} + +\BuiltInTok{readonly} \VariableTok{image\_folder=}\StringTok{"}\VariableTok{$mounting\_point\_hidden}\StringTok{/images/}\VariableTok{$image\_name}\StringTok{"} + +\KeywordTok{if [[} \OtherTok{{-}d} \StringTok{"}\VariableTok{$image\_folder}\StringTok{"}\KeywordTok{ ]]}\NormalTok{; }\KeywordTok{then} + \BuiltInTok{echo} \StringTok{"Image folder \textquotesingle{}}\VariableTok{$image\_folder}\StringTok{\textquotesingle{} already exists."} + \BuiltInTok{exit}\NormalTok{ 1} +\KeywordTok{fi} + +\KeywordTok{if}\NormalTok{ ! }\FunctionTok{mkdir} \StringTok{"}\VariableTok{$image\_folder}\StringTok{"}\KeywordTok{;} \KeywordTok{then} + \BuiltInTok{echo} \StringTok{"Cannot create image folder \textquotesingle{}}\VariableTok{$image\_folder}\StringTok{\textquotesingle{}"} + \BuiltInTok{exit}\NormalTok{ 1} +\KeywordTok{fi} + +\BuiltInTok{readonly} \VariableTok{image\_file=}\StringTok{"}\VariableTok{$image\_folder}\StringTok{/}\VariableTok{$image\_name}\StringTok{.img.gz"} +\KeywordTok{if}\NormalTok{ ! }\ExtensionTok{pv}\NormalTok{ {-}{-}size }\StringTok{"}\VariableTok{$image\_size}\StringTok{"}\NormalTok{ {-}{-}stop{-}at{-}size /dev/sda }\KeywordTok{|} + \ExtensionTok{pigz}\NormalTok{ {-}c }\OperatorTok{\textgreater{}} \StringTok{"}\VariableTok{$image\_file}\StringTok{"} +\KeywordTok{then} + \BuiltInTok{echo} \StringTok{"Cannot create image file \textquotesingle{}}\VariableTok{$image\_file}\StringTok{\textquotesingle{}"} + \BuiltInTok{exit}\NormalTok{ 1} +\KeywordTok{fi} + +\CommentTok{\# }\AlertTok{TODO}\CommentTok{: Rename md5 files to uuid because creating md5 hashes takes too much time} +\BuiltInTok{readonly} \VariableTok{md5\_file=}\StringTok{"}\VariableTok{$image\_folder}\StringTok{/}\VariableTok{$image\_name}\StringTok{.md5"} +\KeywordTok{if}\NormalTok{ ! }\FunctionTok{cat}\NormalTok{ /proc/sys/kernel/random/uuid }\OperatorTok{\textgreater{}} \StringTok{"}\VariableTok{$md5\_file}\StringTok{"}\KeywordTok{;} \KeywordTok{then} + \BuiltInTok{echo} \StringTok{"Cannot create md5 file \textquotesingle{}}\VariableTok{$md5\_file}\StringTok{\textquotesingle{}"} + \BuiltInTok{exit}\NormalTok{ 1} +\KeywordTok{fi} + +\BuiltInTok{readonly} \VariableTok{partition\_file=}\StringTok{"}\VariableTok{$image\_folder}\StringTok{/}\VariableTok{$image\_name}\StringTok{.partition"} +\KeywordTok{if}\NormalTok{ ! }\ExtensionTok{fdisk}\NormalTok{ {-}l /dev/sda }\OperatorTok{\textgreater{}} \StringTok{"}\VariableTok{$partition\_file}\StringTok{"}\KeywordTok{;} \KeywordTok{then} + \BuiltInTok{echo} \StringTok{"Cannot create partition file }\VariableTok{$partition\_file}\StringTok{"} + \BuiltInTok{exit}\NormalTok{ 1} +\KeywordTok{fi} + +\BuiltInTok{readonly} \VariableTok{size\_file=}\StringTok{"}\VariableTok{$image\_folder}\StringTok{/}\VariableTok{$image\_name}\StringTok{.size"} +\KeywordTok{if}\NormalTok{ ! }\FunctionTok{du} \StringTok{"}\VariableTok{$image\_file}\StringTok{"} \OperatorTok{\textgreater{}} \StringTok{"}\VariableTok{$size\_file}\StringTok{"}\KeywordTok{;} \KeywordTok{then} + \BuiltInTok{echo} \StringTok{"Cannot create size file }\VariableTok{$size\_file}\StringTok{"} + \BuiltInTok{exit}\NormalTok{ 1} +\KeywordTok{fi} + +\BuiltInTok{echo} \StringTok{"Image creation successful."} +\BuiltInTok{exit}\NormalTok{ 0} + +\end{Highlighting} +\end{Shaded} + +\hypertarget{deployerbootiful-reset-cache-script-utilitaire-de-ruxe9initialisation-du-cache}{% +\section{\texorpdfstring{\texttt{deployer/bootiful-reset-cache}: script +utilitaire de réinitialisation du +cache}{deployer/bootiful-reset-cache: script utilitaire de réinitialisation du cache}}\label{deployerbootiful-reset-cache-script-utilitaire-de-ruxe9initialisation-du-cache}} + +\begin{Shaded} +\begin{Highlighting}[] +\CommentTok{\#!/bin/bash} + +\BuiltInTok{readonly} \VariableTok{SCRIPT\_NAME=}\StringTok{"}\VariableTok{$(}\FunctionTok{basename} \StringTok{"}\VariableTok{$0}\StringTok{"}\VariableTok{)}\StringTok{"} +\BuiltInTok{readonly} \VariableTok{SCRIPT\_DIR=}\StringTok{"}\VariableTok{$(}\FunctionTok{readlink}\NormalTok{ {-}m }\StringTok{"}\VariableTok{$(}\FunctionTok{dirname} \StringTok{"}\VariableTok{$0}\StringTok{"}\VariableTok{)}\StringTok{"}\VariableTok{)}\StringTok{"} + +\FunctionTok{usage()} \KeywordTok{\{} + \FunctionTok{cat} \OperatorTok{\textless{}\textless{} EOF} +\NormalTok{Usage:} + \VariableTok{$SCRIPT\_DIR}\NormalTok{ [{-}h | {-}{-}help]} + +\NormalTok{Description:} +\NormalTok{ Clears the bootiful image cache by re{-}creating the hidden partition} + +\NormalTok{Options:} +\NormalTok{ {-}h {-}{-}help Shows this help} + +\NormalTok{Example:} +\NormalTok{ ./}\VariableTok{$SCRIPT\_NAME} +\OperatorTok{EOF} +\KeywordTok{\}} + +\KeywordTok{if [[} \StringTok{"}\VariableTok{$1}\StringTok{"} \OtherTok{==} \StringTok{"{-}h"}\NormalTok{ || }\StringTok{"}\VariableTok{$1}\StringTok{"} \OtherTok{==} \StringTok{"{-}{-}help"}\KeywordTok{ ]]}\NormalTok{; }\KeywordTok{then} + \ExtensionTok{usage} + \BuiltInTok{exit}\NormalTok{ 0} +\KeywordTok{fi} + +\CommentTok{\# Loads declarations from the \textquotesingle{}bootiful{-}common\textquotesingle{} script, which is a "library"} +\CommentTok{\# of functions and constants shared by multiple bootiful{-}* scripts.} +\BuiltInTok{readonly} \VariableTok{bootiful\_common\_script\_file=}\StringTok{"}\VariableTok{$SCRIPT\_DIR}\StringTok{/bootiful{-}common"} +\KeywordTok{if [[} \OtherTok{!} \OtherTok{{-}f} \StringTok{"}\VariableTok{$bootiful\_common\_script\_file}\StringTok{"}\KeywordTok{ ]]}\NormalTok{; }\KeywordTok{then} + \OperatorTok{\textgreater{}\&2} \BuiltInTok{echo} \StringTok{"Fatal error: cannot find required script file \textquotesingle{}}\VariableTok{$bootiful\_common\_script\_file}\StringTok{\textquotesingle{}."} + \BuiltInTok{exit}\NormalTok{ 1} +\KeywordTok{fi} +\CommentTok{\# shellcheck source=./bootiful{-}common} +\BuiltInTok{.} \StringTok{"}\VariableTok{$bootiful\_common\_script\_file}\StringTok{"} + +\ExtensionTok{validate\_exists} \StringTok{"}\VariableTok{$deployment\_disk}\StringTok{"} +\ExtensionTok{create\_hidden\_partition} +\end{Highlighting} +\end{Shaded} + +\hypertarget{dhcpdockerfile-configuration-docker-du-serveur-dhcp}{% +\section{\texorpdfstring{\texttt{dhcp/Dockerfile}: configuration +\emph{Docker} du serveur +\protect\hyperlink{acronym__DHCP}{DHCP}}{dhcp/Dockerfile: configuration Docker du serveur DHCP}}\label{dhcpdockerfile-configuration-docker-du-serveur-dhcp}} + +\begin{Shaded} +\begin{Highlighting}[] +\KeywordTok{FROM}\NormalTok{ alpine:3.12} +\KeywordTok{RUN}\NormalTok{ apk add dhcp{-}server{-}vanilla \&\& touch /var/lib/dhcp/dhcpd.leases} +\KeywordTok{COPY}\NormalTok{ dhcpd.conf /etc/dhcp/dhcpd.conf} +\KeywordTok{EXPOSE}\NormalTok{ 67} +\KeywordTok{ENTRYPOINT}\NormalTok{ [}\StringTok{"dhcpd"}\NormalTok{, }\StringTok{"{-}f"}\NormalTok{]} +\end{Highlighting} +\end{Shaded} + +\hypertarget{dhcpdhcpd.conf-configuration-du-serveur-dhcp}{% +\section{\texorpdfstring{\texttt{dhcp/dhcpd.conf}: configuration du +serveur +\protect\hyperlink{acronym__DHCP}{DHCP}}{dhcp/dhcpd.conf: configuration du serveur DHCP}}\label{dhcpdhcpd.conf-configuration-du-serveur-dhcp}} + +\begin{Shaded} +\begin{Highlighting}[] +\ExtensionTok{allow}\NormalTok{ bootp}\KeywordTok{;} + +\ExtensionTok{subnet}\NormalTok{ 192.168.56.0 netmask 255.255.255.0 \{} + \ExtensionTok{range}\NormalTok{ 192.168.56.10 192.168.56.80}\KeywordTok{;} + \ExtensionTok{default{-}lease{-}time}\NormalTok{ 600}\KeywordTok{;} + \ExtensionTok{max{-}lease{-}time}\NormalTok{ 7200}\KeywordTok{;} + +\CommentTok{\# option domain{-}name{-}servers 10.136.132.100;} +\CommentTok{\# option routers 192.168.56.100;} + + \ExtensionTok{class} \StringTok{"pxeclient"}\NormalTok{ \{} + \ExtensionTok{match}\NormalTok{ if substring (option vendor{-}class{-}identifier, 0, 9) = }\StringTok{"PXEClient"}\NormalTok{;} + \ExtensionTok{next{-}server}\NormalTok{ 192.168.56.100}\KeywordTok{;} + \ExtensionTok{option}\NormalTok{ tftp{-}server{-}name }\StringTok{"192.168.56.100"}\KeywordTok{;} + + \KeywordTok{if} \ExtensionTok{substring}\NormalTok{ (option vendor{-}class{-}identifier, 15, 5) = }\StringTok{"00000"} \KeywordTok{\{} + \ExtensionTok{option}\NormalTok{ bootfile{-}name }\StringTok{"/boot/grub/i386{-}pc/core.0"}\KeywordTok{;} + \KeywordTok{\}} + \ExtensionTok{elsif}\NormalTok{ substring (option vendor{-}class{-}identifier, 15, 5) = }\StringTok{"00006"} \KeywordTok{\{} + \ExtensionTok{option}\NormalTok{ bootfile{-}name }\StringTok{"/boot/grub/i386{-}efi/core.efi"}\KeywordTok{;} + \KeywordTok{\}} + \KeywordTok{else} \KeywordTok{\{} + \ExtensionTok{option}\NormalTok{ bootfile{-}name }\StringTok{"/boot/grub/x86\_64{-}efi/core.efi"}\KeywordTok{;} + \KeywordTok{\}} +\NormalTok{ \}} + + \ExtensionTok{class} \StringTok{"normalclient"}\NormalTok{ \{} + \ExtensionTok{match}\NormalTok{ if substring (option vendor{-}class{-}identifier, 0, 9) != }\StringTok{"PXEClient"}\NormalTok{;} +\NormalTok{ \}} +\NormalTok{\}} + +\end{Highlighting} +\end{Shaded} + +\hypertarget{grubdockerfile-configuration-docker-pour-la-compilation-de-grub}{% +\section{\texorpdfstring{\texttt{grub/Dockerfile}: configuration +\emph{Docker} pour la compilation de +\protect\hyperlink{acronym__GRUB}{GRUB}}{grub/Dockerfile: configuration Docker pour la compilation de GRUB}}\label{grubdockerfile-configuration-docker-pour-la-compilation-de-grub}} + +\begin{Shaded} +\begin{Highlighting}[] +\KeywordTok{FROM}\NormalTok{ debian:buster AS build{-}stage} +\KeywordTok{RUN}\NormalTok{ apt{-}get update \&\& apt{-}get install {-}y {-}{-}no{-}install{-}recommends \textbackslash{}} +\NormalTok{ gcc \textbackslash{}} +\NormalTok{ make \textbackslash{}} +\NormalTok{ bison \textbackslash{}} +\NormalTok{ gettext \textbackslash{}} +\NormalTok{ binutils \textbackslash{}} +\NormalTok{ flex \textbackslash{}} +\NormalTok{ pkg{-}config \textbackslash{}} +\NormalTok{ libdevmapper{-}dev \textbackslash{}} +\NormalTok{ libfreetype6{-}dev \textbackslash{}} +\NormalTok{ unifont \textbackslash{}} +\NormalTok{ python \textbackslash{}} +\NormalTok{ automake \textbackslash{}} +\NormalTok{ autoconf} + +\KeywordTok{WORKDIR}\NormalTok{ /bootiful{-}grub} +\KeywordTok{ADD}\NormalTok{ ./bootiful{-}grub ./} + +\KeywordTok{ARG}\NormalTok{ PLATFORM} +\KeywordTok{ARG}\NormalTok{ TARGET} +\KeywordTok{RUN}\NormalTok{ ./configure {-}{-}with{-}platform=$\{PLATFORM\} {-}{-}target=$\{TARGET\}} +\KeywordTok{RUN}\NormalTok{ make} +\KeywordTok{RUN}\NormalTok{ make install} + +\KeywordTok{RUN}\NormalTok{ grub{-}mknetdir {-}{-}net{-}directory=./netdir {-}{-}subdir=./boot/grub} + +\KeywordTok{FROM}\NormalTok{ scratch AS export{-}stage} +\KeywordTok{COPY}\NormalTok{ {-}{-}from=build{-}stage ./bootiful{-}grub/netdir /} +\end{Highlighting} +\end{Shaded} + +\hypertarget{nfsdockerfile-configuration-docker-du-serveur-nfs}{% +\section{\texorpdfstring{\texttt{nfs/Dockerfile}: configuration +\emph{Docker} du serveur +\protect\hyperlink{acronym__NFS}{NFS}}{nfs/Dockerfile: configuration Docker du serveur NFS}}\label{nfsdockerfile-configuration-docker-du-serveur-nfs}} + +\begin{Shaded} +\begin{Highlighting}[] +\KeywordTok{FROM}\NormalTok{ erichough/nfs{-}server} +\KeywordTok{ADD}\NormalTok{ nfsroot.tar.gz /nfsrootsrc/} +\KeywordTok{COPY}\NormalTok{ exports /etc/exports} +\KeywordTok{VOLUME}\NormalTok{ /nfsroot} +\KeywordTok{VOLUME}\NormalTok{ /nfsshared} +\KeywordTok{ENTRYPOINT}\NormalTok{ cp {-}a nfsrootsrc/rootfs/. /nfsroot/ \&\& entrypoint.sh} +\end{Highlighting} +\end{Shaded} + +\hypertarget{nfsexports-configuration-des-partages-du-serveur-nfs}{% +\section{\texorpdfstring{\texttt{nfs/exports}: configuration des +partages du serveur +\protect\hyperlink{acronym__NFS}{NFS}}{nfs/exports: configuration des partages du serveur NFS}}\label{nfsexports-configuration-des-partages-du-serveur-nfs}} + +\begin{Shaded} +\begin{Highlighting}[] +\CommentTok{\# /etc/exports: the access control list for filesystems which may be exported} +\CommentTok{\# to NFS clients. See exports(5).} +\CommentTok{\#} +\CommentTok{\# Example for NFSv2 and NFSv3:} +\CommentTok{\# /srv/homes hostname1(rw,sync,no\_subtree\_check) hostname2(ro,sync,no\_subtree\_check)} +\CommentTok{\#} +\CommentTok{\# Example for NFSv4:} +\CommentTok{\# /srv/nfs4 gss/krb5i(rw,sync,fsid=0,crossmnt,no\_subtree\_check)} +\CommentTok{\# /srv/nfs4/homes gss/krb5i(rw,sync,no\_subtree\_check)} +\CommentTok{\#} +\ExtensionTok{/nfsroot}\NormalTok{ *(ro,fsid=0,no\_root\_squash,no\_subtree\_check,async,insecure)} +\ExtensionTok{/nfsshared}\NormalTok{ *(rw,fsid=1,no\_root\_squash,no\_subtree\_check,async,insecure)} +\end{Highlighting} +\end{Shaded} + +\hypertarget{tftpdockerfile-configuration-docker-du-serveur-tftp}{% +\section{\texorpdfstring{\texttt{tftp/Dockerfile}: configuration +\emph{Docker} du serveur +\protect\hyperlink{acronym__TFTP}{TFTP}}{tftp/Dockerfile: configuration Docker du serveur TFTP}}\label{tftpdockerfile-configuration-docker-du-serveur-tftp}} + +\begin{Shaded} +\begin{Highlighting}[] +\KeywordTok{FROM}\NormalTok{ alpine:3.12} +\KeywordTok{RUN}\NormalTok{ apk add tftp{-}hpa} +\KeywordTok{VOLUME}\NormalTok{ /tftpboot} +\KeywordTok{EXPOSE}\NormalTok{ 69/udp} +\KeywordTok{ENTRYPOINT}\NormalTok{ [}\StringTok{"in.tftpd"}\NormalTok{, }\StringTok{"{-}{-}foreground"}\NormalTok{, }\StringTok{"{-}{-}address"}\NormalTok{, }\StringTok{":69"}\NormalTok{, }\StringTok{"{-}{-}secure"}\NormalTok{, }\StringTok{"{-}{-}verbose"}\NormalTok{, }\StringTok{"/tftpboot"}\NormalTok{]} +\end{Highlighting} +\end{Shaded} + +\hypertarget{tftptftpd-hpa-configuration-du-serveur-tftp}{% +\section{\texorpdfstring{\texttt{tftp/tftpd-hpa}: configuration du +serveur +\protect\hyperlink{acronym__TFTP}{TFTP}}{tftp/tftpd-hpa: configuration du serveur TFTP}}\label{tftptftpd-hpa-configuration-du-serveur-tftp}} + +\begin{Shaded} +\begin{Highlighting}[] +\VariableTok{TFTP\_USERNAME=}\StringTok{"tftp"} +\VariableTok{TFTP\_DIRECTORY=}\StringTok{"/tftpboot"} +\VariableTok{TFTP\_ADDRESS=}\StringTok{":69"} +\VariableTok{TFTP\_OPTIONS=}\StringTok{"{-}s {-}c"} +\VariableTok{RUN\_DAEMON=}\StringTok{"yes"} +\end{Highlighting} +\end{Shaded} + +\hypertarget{tftptftpbootbootgrubgrub.cfg-configuration-de-grub-servie-par-tftp}{% +\section{\texorpdfstring{\texttt{tftp/tftpboot/boot/grub/grub.cfg}: +configuration de \protect\hyperlink{acronym__GRUB}{GRUB} servie par +\protect\hyperlink{acronym__TFTP}{TFTP}}{tftp/tftpboot/boot/grub/grub.cfg: configuration de GRUB servie par TFTP}}\label{tftptftpbootbootgrubgrub.cfg-configuration-de-grub-servie-par-tftp}} + +\begin{Shaded} +\begin{Highlighting}[] +\KeywordTok{set} \VariableTok{timeout=}\NormalTok{3} + +\ExtensionTok{insmod}\NormalTok{ part\_msdos} +\ExtensionTok{insmod}\NormalTok{ part\_gpt} +\ExtensionTok{insmod}\NormalTok{ isign} +\ExtensionTok{insmod}\NormalTok{ all\_video} + +\ExtensionTok{isign}\NormalTok{ {-}c hepia2015 (hd0)} +\KeywordTok{set} \VariableTok{check1=$?} +\KeywordTok{if}\BuiltInTok{ [} \VariableTok{$check1} \OtherTok{==}\NormalTok{ 101}\BuiltInTok{ ]}\NormalTok{; }\KeywordTok{then} + \ExtensionTok{isign}\NormalTok{ {-}w 000000000 (hd0)} + + \ExtensionTok{menuentry} \StringTok{"Local HDD"}\NormalTok{ \{} + \KeywordTok{set} \VariableTok{root=(}\NormalTok{hd0,1}\VariableTok{)} + + \KeywordTok{if}\BuiltInTok{ [} \OtherTok{{-}e}\NormalTok{ /efi\_entrypoint}\BuiltInTok{ ]}\NormalTok{; }\KeywordTok{then} + \BuiltInTok{echo} \StringTok{"Reading EFI entry point from (hd0,1)/efi\_entrypoint file..."} + \BuiltInTok{source}\NormalTok{ /efi\_entrypoint} + + \BuiltInTok{echo} \StringTok{"Chainloading to }\VariableTok{$efi\_entrypoint}\StringTok{"} + \ExtensionTok{chainloader} \VariableTok{$efi\_entrypoint} + \KeywordTok{else} + \BuiltInTok{echo} \StringTok{"Legacy chainloading to (hd0,1)+1..."} + \ExtensionTok{chainloader}\NormalTok{ +1} + \KeywordTok{fi} +\NormalTok{ \}} +\KeywordTok{fi} + +\ExtensionTok{menuentry} \StringTok{"Bootiful deployer"}\NormalTok{ \{} + \BuiltInTok{echo} \StringTok{"Loading vmlinuz..."} + \ExtensionTok{linux}\NormalTok{ boot/deployer/vmlinuz root=/dev/nfs nfsroot=}\VariableTok{$net\_default\_server}\NormalTok{:/nfsroot ro} + \ExtensionTok{initrd}\NormalTok{ boot/deployer/initrd.img} +\NormalTok{\}} + +\end{Highlighting} +\end{Shaded} + +\hypertarget{source_ansible_run}{% +\section{\texorpdfstring{\texttt{postdeploy/bootiful-postdeploy}: script +de post-déploiement qui exécute les playbooks \emph{Ansible} présents +dans un +dossier}{postdeploy/bootiful-postdeploy: script de post-déploiement qui exécute les playbooks Ansible présents dans un dossier}}\label{source_ansible_run}} + +\begin{Shaded} +\begin{Highlighting}[] +\CommentTok{\#!/bin/bash} + +\KeywordTok{function}\FunctionTok{ log()} \KeywordTok{\{} + \BuiltInTok{local}\NormalTok{ {-}r }\VariableTok{log\_message=}\StringTok{"}\VariableTok{$0}\StringTok{"} + \OperatorTok{\textgreater{}\&2} \BuiltInTok{echo} \StringTok{"}\VariableTok{$log\_message}\StringTok{"} +\KeywordTok{\}} + +\KeywordTok{function}\FunctionTok{ fatal\_error()} \KeywordTok{\{} + \BuiltInTok{local}\NormalTok{ {-}r }\VariableTok{error\_message=}\StringTok{"}\VariableTok{$0}\StringTok{"} + \ExtensionTok{log} \StringTok{"Fatal error: }\VariableTok{$error\_message}\StringTok{"} + + \ExtensionTok{log} \StringTok{"Stack trace:"} + \BuiltInTok{local} \VariableTok{frame=}\NormalTok{0} + \KeywordTok{while} \OperatorTok{\textgreater{}\&2} \BuiltInTok{caller} \VariableTok{$frame}\KeywordTok{;} \KeywordTok{do} + \KeywordTok{((}\NormalTok{frame++}\KeywordTok{))} + \KeywordTok{done} + + \BuiltInTok{exit}\NormalTok{ 1} +\KeywordTok{\}} + +\ExtensionTok{log} \StringTok{"Starting bootiful post{-}deployment script..."} +\BuiltInTok{readonly} \VariableTok{playbooks\_dir=}\StringTok{"/etc/bootiful/postdeploy{-}playbooks"} +\KeywordTok{[[} \OtherTok{{-}d} \StringTok{"}\VariableTok{$playbooks\_dir}\StringTok{"}\KeywordTok{ ]]} \KeywordTok{||} \ExtensionTok{fatal\_error} \StringTok{"playbooks directory \textquotesingle{}}\VariableTok{$playbooks\_dir}\StringTok{\textquotesingle{} not found."} + +\BuiltInTok{readonly} \VariableTok{playbook\_files=}\StringTok{"}\VariableTok{$()}\StringTok{"} + +\KeywordTok{if [[} \OtherTok{{-}z} \StringTok{"}\VariableTok{$playbook\_files}\StringTok{"}\KeywordTok{ ]]}\NormalTok{; }\KeywordTok{then} + \ExtensionTok{log} \StringTok{"no story found in directory \textquotesingle{}}\VariableTok{$playbooks\_dir}\StringTok{\textquotesingle{}. Exiting."} + \BuiltInTok{exit}\NormalTok{ 0} +\KeywordTok{fi} + +\FunctionTok{run\_playbook()} \KeywordTok{\{} + \BuiltInTok{local}\NormalTok{ {-}r }\VariableTok{playbook\_file=}\StringTok{"}\VariableTok{$0}\StringTok{"} + \ExtensionTok{log} \StringTok{"Executing playbook file \textquotesingle{}}\VariableTok{$playbook\_file}\StringTok{\textquotesingle{}..."} +\NormalTok{ [[ }\ExtensionTok{{-}f} \StringTok{"}\VariableTok{$playbook\_file}\StringTok{"}\NormalTok{ ]] }\KeywordTok{||} \ExtensionTok{fatal\_error} \StringTok{"playbook file }\VariableTok{$playbook\_file}\StringTok{ not found."} + + \ExtensionTok{ansible{-}playbook} \KeywordTok{\textbackslash{}} + \ExtensionTok{{-}{-}connection}\NormalTok{=local }\KeywordTok{\textbackslash{}} + \ExtensionTok{{-}{-}inventory}\NormalTok{=127.0.0.1, }\KeywordTok{\textbackslash{}} + \StringTok{"}\VariableTok{$playbook\_file}\StringTok{"} \KeywordTok{\textbackslash{}} + \KeywordTok{||} \ExtensionTok{fatal\_error} \StringTok{"error while executing playbook file "} + + \ExtensionTok{log} \StringTok{"Execution of playbook file \textquotesingle{}}\VariableTok{$playbook\_file}\StringTok{\textquotesingle{} successful."} +\KeywordTok{\}} +\BuiltInTok{export}\NormalTok{ {-}f }\VariableTok{run\_playbook} + +\CommentTok{\# shellcheck disable=SC2016 \# we do not want to expand $1 in bash command} +\FunctionTok{find} \StringTok{"}\VariableTok{$playbooks\_dir}\StringTok{"}\NormalTok{ {-}maxdepth 1 {-}type f {-}name }\StringTok{\textquotesingle{}*.yml\textquotesingle{}}\NormalTok{ {-}print0 }\KeywordTok{|} + \FunctionTok{sort}\NormalTok{ {-}z }\KeywordTok{|} + \FunctionTok{xargs}\NormalTok{ {-}n1 {-}0 bash {-}c }\StringTok{$\textquotesingle{}trap }\DataTypeTok{\textbackslash{}\textquotesingle{}}\StringTok{[[ $? == 0 ]] || exit 255}\DataTypeTok{\textbackslash{}\textquotesingle{}}\StringTok{ EXIT; run\_playbook "$1"\textquotesingle{}}\NormalTok{ {-}{-}} +\end{Highlighting} +\end{Shaded} + +\hypertarget{source_ansible_init}{% +\section{\texorpdfstring{\texttt{postdeploy/bootiful-postdeploy.service}: +configuration de l'unité \emph{Systemd} pour exécuter des scripts de +post-déploiement sur un +client}{postdeploy/bootiful-postdeploy.service: configuration de l'unité Systemd pour exécuter des scripts de post-déploiement sur un client}}\label{source_ansible_init}} + +\begin{Shaded} +\begin{Highlighting}[] +\KeywordTok{[Unit]} +\DataTypeTok{Description}\OtherTok{=}\StringTok{Runs bootiful post{-}deployment script }\KeywordTok{on}\StringTok{ boot} +\DataTypeTok{After}\OtherTok{=}\StringTok{network.target} + +\KeywordTok{[Service]} +\DataTypeTok{ExecStart}\OtherTok{=}\StringTok{/usr/local/bin/bootiful{-}postdeploy} +\DataTypeTok{Type}\OtherTok{=}\StringTok{oneshot} + +\KeywordTok{[Install]} +\DataTypeTok{WantedBy}\OtherTok{=}\StringTok{multi{-}user.target} +\end{Highlighting} +\end{Shaded} -\hypertarget{retour-personnel-sur-la-maniuxe8re-dont-le-travail-sest-effectuuxe9}{% -\subsection{Retour personnel sur la manière dont le travail s'est -effectué}\label{retour-personnel-sur-la-maniuxe8re-dont-le-travail-sest-effectuuxe9}} +\hypertarget{refs}{} +\begin{cslreferences} +\leavevmode\hypertarget{ref-venkatesh_remote_imaging}{}% +\textbf{1}. VENKATESH, Abhilash. Remote imaging. GitLab. {[}en~ligne{]}. +{[}Consulté~le~16~août~2020{]}. Disponible à l'adresse~: +\url{https://githepia.hesge.ch/abhilash.venkates/remote-imaging} +\end{cslreferences} \backmatter \end{document} diff --git a/doc/references.bib b/doc/references.bib new file mode 100644 index 0000000000000000000000000000000000000000..87842cf037a06f497700dbc7846b503b1421c57a --- /dev/null +++ b/doc/references.bib @@ -0,0 +1,123 @@ + +@online{venkatesh_remote_imaging, + title = {Remote imaging}, + url = {https://githepia.hesge.ch/abhilash.venkates/remote-imaging}, + abstract = {On fly remote imaging}, + titleaddon = {{GitLab}}, + author = {Venkatesh, Abhilash}, + urldate = {2020-08-16}, + langid = {english}, +} + +@online{noauthor_linux_nodate, + title = {Linux Remote-Boot mini-{HOWTO}: Configuring Remote-Boot Workstations with Linux, {DOS}, Windows 95/98 and Windows {NT}}, + url = {https://www.tldp.org/HOWTO/Remote-Boot.html#toc3}, + urldate = {2020-08-16} +} + +@online{noauthor_diskless_nodate, + title = {Diskless system - {ArchWiki}}, + url = {https://wiki.archlinux.org/index.php/Diskless_system}, + urldate = {2020-08-16} +} + +@article{blanchet_read-only_2016, + title = {Read-only {NFS} Root with Debian 8}, + pages = {20}, + author = {Blanchet, Sébastien}, + date = {2016}, + langid = {english}, +} + +@online{noauthor_multistrap1_nodate, + title = {multistrap(1) — multistrap — Debian buster — Debian Manpages}, + url = {https://manpages.debian.org/buster/multistrap/multistrap.1.en.html}, + urldate = {2020-08-16} +} + +@online{noauthor_execute_nodate, + title = {Execute an interactive script at boot with systemd}, + url = {https://alan-mushi.github.io/2014/10/26/execute-an-interactive-script-at-boot-with-systemd.html}, + urldate = {2020-08-16} +} + +@online{noauthor_lancer_nodate, + title = {Lancer un script sur une console virtuelle - systemd / Wiki / Debian-facile}, + url = {https://debian-facile.org/doc:programmation:bash:script:systemd:script-sur-un-vt}, + urldate = {2020-08-16} +} + +@online{noauthor_rethinking_nodate, + title = {Rethinking {PID} 1}, + url = {http://0pointer.de/blog/projects/systemd.html}, + urldate = {2020-08-16} +} + +@online{ludwar_ansible-pull_2016, + title = {Ansible-pull and kickstart, for one-touch server provisioning}, + url = {https://calgaryrhce.ca/blog/2016/02/03/ansible-pull-and-kickstart-for-one-touch-server-provisioning/}, + abstract = {Recently I’ve been learning and using Ansible as my configuration management tool. It came recommended by several colleagues, recently had an O’Reilly book published, and went through an aquisition. Safe to say its momentum and adoption is on a high… and so far, I’m loving using it. I find it vastly easier to setup and use than Puppet, Chef, {CFengine}, or {SaltStack}.}, + titleaddon = {Calgary {RHCE}}, + author = {Ludwar, Andrew}, + urldate = {2020-08-16}, + date = {2016-02-03}, + langid = {english}, +} + +@online{admin_how_2019, + title = {How to Run Ansible Playbook Locally {\textbar} {DevOps} Junction}, + url = {https://www.middlewareinventory.com/blog/run-ansible-playbook-locally/}, + abstract = {How to Run Ansible Playbook Locally on a Control machine. {HOw} to run Ansible Playbook on Localhost. In this post we are going to discuss about how to run your playbook on the local control machine before you execute it with the remote server or host. How to limit the playbook to run on localhost with example}, + titleaddon = {Middleware Inventory}, + author = {{admin}}, + urldate = {2020-08-16}, + date = {2019-07-17}, + langid = {american}, + note = {Section: Ansible}, +} + +@online{noauthor_gpp_nodate, + title = {{GPP} 2.26 — Generic Preprocessor}, + url = {https://files.nothingisreal.com/software/gpp/gpp.html}, + urldate = {2020-08-16} +} + +@online{bpbatch_homepage, + title = {BPBatch home page}, + url = {http://www.bpbatch.org}, + urldate = {2020-08-16}, +} + +@online{registre_commerce_rembo, + title = {Registre du Commerce du Canton de Genève}, + url = {http://ge.ch/hrcintapp/externalCompanyReport.action?companyOfsUid=CHE-105.105.486&lang=FR}, + urldate = {2020-08-16}, +} + +@online{clonezilla_home, + title = {Clonezilla}, + url = {https://clonezilla.org/}, + urldate = {2020-08-16} +} + +@online{ibm_rembo, + title = {{IBM} met la main sur Rembo Technology}, + url = {https://www.journaldunet.com/solutions/cloud-computing/1060590-ibm-met-la-main-sur-rembo-technology/}, + urldate = {2020-08-16}, + langid = {french}, + file = {Snapshot:/home/araxor/Zotero/storage/BU5TCN6Y/1060590-ibm-met-la-main-sur-rembo-technology.html:text/html} +} + +@online{fog_wiki_intro, + title = {{FOG} Project wiki (introduction)}, + url = {https://wiki.fogproject.org/wiki/index.php?title=Introduction}, + urldate = {2020-08-16} +} + +@online{gluck_enonce_2020, + title = {Énoncé du projet Bootiful}, + url = {https://gradechelor2.hesge.ch/studentFiles/1660/ITI_IN_enonce_diplome_Lizzi_Gluck_2020.pdf}, + author = {Glück, Florent}, + urldate = {2020-08-16}, + date = {2020-05-06} +} \ No newline at end of file