From d1d15e08f0aca02852dd20ac64b1871b22ab4b48 Mon Sep 17 00:00:00 2001 From: "Brian C. Lane" Date: Thu, 19 Dec 2019 14:07:51 -0800 Subject: [PATCH] Add lorax 28.14.33 documentation --- rhel8-branch/.buildinfo | 4 + rhel8-branch/.doctrees/composer-cli.doctree | Bin 0 -> 43171 bytes rhel8-branch/.doctrees/environment.pickle | Bin 0 -> 2226096 bytes rhel8-branch/.doctrees/index.doctree | Bin 0 -> 6475 bytes rhel8-branch/.doctrees/intro.doctree | Bin 0 -> 9230 bytes .../.doctrees/livemedia-creator.doctree | Bin 0 -> 167828 bytes rhel8-branch/.doctrees/lorax-composer.doctree | Bin 0 -> 112884 bytes rhel8-branch/.doctrees/lorax.doctree | Bin 0 -> 70370 bytes rhel8-branch/.doctrees/modules.doctree | Bin 0 -> 2535 bytes rhel8-branch/.doctrees/product-images.doctree | Bin 0 -> 7127 bytes rhel8-branch/.doctrees/pylorax.api.doctree | Bin 0 -> 700855 bytes rhel8-branch/.doctrees/pylorax.doctree | Bin 0 -> 533262 bytes rhel8-branch/.doctrees/source/index.doctree | Bin 0 -> 4918 bytes rhel8-branch/_modules/index.html | 223 + rhel8-branch/_modules/pylorax.html | 652 + .../_modules/pylorax/api/cmdline.html | 263 + .../_modules/pylorax/api/compose.html | 1405 +++ rhel8-branch/_modules/pylorax/api/config.html | 313 + .../_modules/pylorax/api/crossdomain.html | 264 + .../_modules/pylorax/api/projects.html | 805 ++ rhel8-branch/_modules/pylorax/api/queue.html | 875 ++ .../_modules/pylorax/api/recipes.html | 1478 +++ rhel8-branch/_modules/pylorax/api/server.html | 282 + rhel8-branch/_modules/pylorax/api/v0.html | 2277 ++++ .../_modules/pylorax/api/workspace.html | 299 + rhel8-branch/_modules/pylorax/base.html | 267 + rhel8-branch/_modules/pylorax/buildstamp.html | 261 + rhel8-branch/_modules/pylorax/cmdline.html | 511 + rhel8-branch/_modules/pylorax/creator.html | 977 ++ rhel8-branch/_modules/pylorax/decorators.html | 230 + rhel8-branch/_modules/pylorax/discinfo.html | 239 + rhel8-branch/_modules/pylorax/dnfhelper.html | 310 + rhel8-branch/_modules/pylorax/executils.html | 547 + rhel8-branch/_modules/pylorax/imgutils.html | 720 ++ rhel8-branch/_modules/pylorax/installer.html | 860 ++ rhel8-branch/_modules/pylorax/ltmpl.html | 1085 ++ rhel8-branch/_modules/pylorax/monitor.html | 395 + rhel8-branch/_modules/pylorax/mount.html | 302 + rhel8-branch/_modules/pylorax/sysutils.html | 332 + .../_modules/pylorax/treebuilder.html | 602 + rhel8-branch/_modules/pylorax/treeinfo.html | 257 + rhel8-branch/_sources/composer-cli.rst.txt | 62 + rhel8-branch/_sources/index.rst.txt | 34 + rhel8-branch/_sources/index.txt | 27 + rhel8-branch/_sources/intro.rst.txt | 67 + rhel8-branch/_sources/intro.txt | 67 + .../_sources/livemedia-creator.rst.txt | 641 + rhel8-branch/_sources/livemedia-creator.txt | 638 + rhel8-branch/_sources/lorax-composer.rst.txt | 490 + rhel8-branch/_sources/lorax.rst.txt | 162 + rhel8-branch/_sources/lorax.txt | 144 + rhel8-branch/_sources/modules.rst.txt | 7 + rhel8-branch/_sources/modules.txt | 7 + rhel8-branch/_sources/product-images.rst.txt | 27 + rhel8-branch/_sources/product-images.txt | 27 + rhel8-branch/_sources/pylorax.api.rst.txt | 102 + rhel8-branch/_sources/pylorax.rst.txt | 157 + rhel8-branch/_sources/pylorax.txt | 134 + rhel8-branch/_sources/source/index.txt | 22 + rhel8-branch/_static/ajax-loader.gif | Bin 0 -> 673 bytes rhel8-branch/_static/basic.css | 676 + rhel8-branch/_static/comment-bright.png | Bin 0 -> 756 bytes rhel8-branch/_static/comment-close.png | Bin 0 -> 829 bytes rhel8-branch/_static/comment.png | Bin 0 -> 641 bytes rhel8-branch/_static/css/badge_only.css | 1 + rhel8-branch/_static/css/theme.css | 6 + rhel8-branch/_static/doctools.js | 315 + rhel8-branch/_static/documentation_options.js | 10 + rhel8-branch/_static/down-pressed.png | Bin 0 -> 222 bytes rhel8-branch/_static/down.png | Bin 0 -> 202 bytes rhel8-branch/_static/file.png | Bin 0 -> 286 bytes .../_static/fonts/Inconsolata-Bold.ttf | Bin 0 -> 108360 bytes .../_static/fonts/Inconsolata-Regular.ttf | Bin 0 -> 95960 bytes rhel8-branch/_static/fonts/Inconsolata.ttf | Bin 0 -> 63184 bytes rhel8-branch/_static/fonts/Lato-Bold.ttf | Bin 0 -> 657188 bytes .../_static/fonts/Lato-BoldItalic.ttf | Bin 0 -> 699008 bytes rhel8-branch/_static/fonts/Lato-Italic.ttf | Bin 0 -> 723544 bytes rhel8-branch/_static/fonts/Lato-Regular.ttf | Bin 0 -> 657212 bytes rhel8-branch/_static/fonts/Lato/lato-bold.eot | Bin 0 -> 256056 bytes rhel8-branch/_static/fonts/Lato/lato-bold.ttf | Bin 0 -> 657188 bytes .../_static/fonts/Lato/lato-bold.woff | Bin 0 -> 309728 bytes .../_static/fonts/Lato/lato-bold.woff2 | Bin 0 -> 184912 bytes .../_static/fonts/Lato/lato-bolditalic.eot | Bin 0 -> 266158 bytes .../_static/fonts/Lato/lato-bolditalic.ttf | Bin 0 -> 699008 bytes .../_static/fonts/Lato/lato-bolditalic.woff | Bin 0 -> 323344 bytes .../_static/fonts/Lato/lato-bolditalic.woff2 | Bin 0 -> 193308 bytes .../_static/fonts/Lato/lato-italic.eot | Bin 0 -> 268604 bytes .../_static/fonts/Lato/lato-italic.ttf | Bin 0 -> 723544 bytes .../_static/fonts/Lato/lato-italic.woff | Bin 0 -> 328412 bytes .../_static/fonts/Lato/lato-italic.woff2 | Bin 0 -> 195704 bytes .../_static/fonts/Lato/lato-regular.eot | Bin 0 -> 253461 bytes .../_static/fonts/Lato/lato-regular.ttf | Bin 0 -> 657212 bytes .../_static/fonts/Lato/lato-regular.woff | Bin 0 -> 309192 bytes .../_static/fonts/Lato/lato-regular.woff2 | Bin 0 -> 182708 bytes .../_static/fonts/RobotoSlab-Bold.ttf | Bin 0 -> 170616 bytes .../_static/fonts/RobotoSlab-Regular.ttf | Bin 0 -> 169064 bytes .../fonts/RobotoSlab/roboto-slab-v7-bold.eot | Bin 0 -> 79520 bytes .../fonts/RobotoSlab/roboto-slab-v7-bold.ttf | Bin 0 -> 170616 bytes .../fonts/RobotoSlab/roboto-slab-v7-bold.woff | Bin 0 -> 87624 bytes .../RobotoSlab/roboto-slab-v7-bold.woff2 | Bin 0 -> 67312 bytes .../RobotoSlab/roboto-slab-v7-regular.eot | Bin 0 -> 78331 bytes .../RobotoSlab/roboto-slab-v7-regular.ttf | Bin 0 -> 169064 bytes .../RobotoSlab/roboto-slab-v7-regular.woff | Bin 0 -> 86288 bytes .../RobotoSlab/roboto-slab-v7-regular.woff2 | Bin 0 -> 66444 bytes .../_static/fonts/fontawesome-webfont.eot | Bin 0 -> 165742 bytes .../_static/fonts/fontawesome-webfont.svg | 2671 ++++ .../_static/fonts/fontawesome-webfont.ttf | Bin 0 -> 165548 bytes .../_static/fonts/fontawesome-webfont.woff | Bin 0 -> 98024 bytes .../_static/fonts/fontawesome-webfont.woff2 | Bin 0 -> 77160 bytes rhel8-branch/_static/jquery-1.11.1.js | 10308 ++++++++++++++++ rhel8-branch/_static/jquery-3.1.0.js | 10074 +++++++++++++++ rhel8-branch/_static/jquery-3.2.1.js | 10253 +++++++++++++++ rhel8-branch/_static/jquery.js | 4 + rhel8-branch/_static/js/modernizr.min.js | 4 + rhel8-branch/_static/js/theme.js | 3 + rhel8-branch/_static/language_data.js | 297 + rhel8-branch/_static/minus.png | Bin 0 -> 90 bytes rhel8-branch/_static/plus.png | Bin 0 -> 90 bytes rhel8-branch/_static/pygments.css | 69 + rhel8-branch/_static/searchtools.js | 481 + rhel8-branch/_static/underscore-1.3.1.js | 999 ++ rhel8-branch/_static/underscore.js | 31 + rhel8-branch/_static/up-pressed.png | Bin 0 -> 214 bytes rhel8-branch/_static/up.png | Bin 0 -> 203 bytes rhel8-branch/_static/websupport.js | 808 ++ rhel8-branch/composer-cli.html | 404 + rhel8-branch/genindex.html | 1139 ++ rhel8-branch/index.html | 238 + rhel8-branch/intro.html | 261 + rhel8-branch/livemedia-creator.html | 1183 ++ rhel8-branch/lorax-composer.html | 767 ++ rhel8-branch/lorax.html | 583 + rhel8-branch/modules.html | 261 + rhel8-branch/objects.inv | Bin 0 -> 3089 bytes rhel8-branch/product-images.html | 233 + rhel8-branch/py-modindex.html | 356 + rhel8-branch/pylorax.api.html | 4130 +++++++ rhel8-branch/pylorax.html | 2356 ++++ rhel8-branch/search.html | 217 + rhel8-branch/searchindex.js | 1 + rhel8-branch/source/index.html | 213 + 141 files changed, 69202 insertions(+) create mode 100644 rhel8-branch/.buildinfo create mode 100644 rhel8-branch/.doctrees/composer-cli.doctree create mode 100644 rhel8-branch/.doctrees/environment.pickle create mode 100644 rhel8-branch/.doctrees/index.doctree create mode 100644 rhel8-branch/.doctrees/intro.doctree create mode 100644 rhel8-branch/.doctrees/livemedia-creator.doctree create mode 100644 rhel8-branch/.doctrees/lorax-composer.doctree create mode 100644 rhel8-branch/.doctrees/lorax.doctree create mode 100644 rhel8-branch/.doctrees/modules.doctree create mode 100644 rhel8-branch/.doctrees/product-images.doctree create mode 100644 rhel8-branch/.doctrees/pylorax.api.doctree create mode 100644 rhel8-branch/.doctrees/pylorax.doctree create mode 100644 rhel8-branch/.doctrees/source/index.doctree create mode 100644 rhel8-branch/_modules/index.html create mode 100644 rhel8-branch/_modules/pylorax.html create mode 100644 rhel8-branch/_modules/pylorax/api/cmdline.html create mode 100644 rhel8-branch/_modules/pylorax/api/compose.html create mode 100644 rhel8-branch/_modules/pylorax/api/config.html create mode 100644 rhel8-branch/_modules/pylorax/api/crossdomain.html create mode 100644 rhel8-branch/_modules/pylorax/api/projects.html create mode 100644 rhel8-branch/_modules/pylorax/api/queue.html create mode 100644 rhel8-branch/_modules/pylorax/api/recipes.html create mode 100644 rhel8-branch/_modules/pylorax/api/server.html create mode 100644 rhel8-branch/_modules/pylorax/api/v0.html create mode 100644 rhel8-branch/_modules/pylorax/api/workspace.html create mode 100644 rhel8-branch/_modules/pylorax/base.html create mode 100644 rhel8-branch/_modules/pylorax/buildstamp.html create mode 100644 rhel8-branch/_modules/pylorax/cmdline.html create mode 100644 rhel8-branch/_modules/pylorax/creator.html create mode 100644 rhel8-branch/_modules/pylorax/decorators.html create mode 100644 rhel8-branch/_modules/pylorax/discinfo.html create mode 100644 rhel8-branch/_modules/pylorax/dnfhelper.html create mode 100644 rhel8-branch/_modules/pylorax/executils.html create mode 100644 rhel8-branch/_modules/pylorax/imgutils.html create mode 100644 rhel8-branch/_modules/pylorax/installer.html create mode 100644 rhel8-branch/_modules/pylorax/ltmpl.html create mode 100644 rhel8-branch/_modules/pylorax/monitor.html create mode 100644 rhel8-branch/_modules/pylorax/mount.html create mode 100644 rhel8-branch/_modules/pylorax/sysutils.html create mode 100644 rhel8-branch/_modules/pylorax/treebuilder.html create mode 100644 rhel8-branch/_modules/pylorax/treeinfo.html create mode 100644 rhel8-branch/_sources/composer-cli.rst.txt create mode 100644 rhel8-branch/_sources/index.rst.txt create mode 100644 rhel8-branch/_sources/index.txt create mode 100644 rhel8-branch/_sources/intro.rst.txt create mode 100644 rhel8-branch/_sources/intro.txt create mode 100644 rhel8-branch/_sources/livemedia-creator.rst.txt create mode 100644 rhel8-branch/_sources/livemedia-creator.txt create mode 100644 rhel8-branch/_sources/lorax-composer.rst.txt create mode 100644 rhel8-branch/_sources/lorax.rst.txt create mode 100644 rhel8-branch/_sources/lorax.txt create mode 100644 rhel8-branch/_sources/modules.rst.txt create mode 100644 rhel8-branch/_sources/modules.txt create mode 100644 rhel8-branch/_sources/product-images.rst.txt create mode 100644 rhel8-branch/_sources/product-images.txt create mode 100644 rhel8-branch/_sources/pylorax.api.rst.txt create mode 100644 rhel8-branch/_sources/pylorax.rst.txt create mode 100644 rhel8-branch/_sources/pylorax.txt create mode 100644 rhel8-branch/_sources/source/index.txt create mode 100644 rhel8-branch/_static/ajax-loader.gif create mode 100644 rhel8-branch/_static/basic.css create mode 100644 rhel8-branch/_static/comment-bright.png create mode 100644 rhel8-branch/_static/comment-close.png create mode 100644 rhel8-branch/_static/comment.png create mode 100644 rhel8-branch/_static/css/badge_only.css create mode 100644 rhel8-branch/_static/css/theme.css create mode 100644 rhel8-branch/_static/doctools.js create mode 100644 rhel8-branch/_static/documentation_options.js create mode 100644 rhel8-branch/_static/down-pressed.png create mode 100644 rhel8-branch/_static/down.png create mode 100644 rhel8-branch/_static/file.png create mode 100644 rhel8-branch/_static/fonts/Inconsolata-Bold.ttf create mode 100644 rhel8-branch/_static/fonts/Inconsolata-Regular.ttf create mode 100644 rhel8-branch/_static/fonts/Inconsolata.ttf create mode 100644 rhel8-branch/_static/fonts/Lato-Bold.ttf create mode 100644 rhel8-branch/_static/fonts/Lato-BoldItalic.ttf create mode 100644 rhel8-branch/_static/fonts/Lato-Italic.ttf create mode 100644 rhel8-branch/_static/fonts/Lato-Regular.ttf create mode 100644 rhel8-branch/_static/fonts/Lato/lato-bold.eot create mode 100644 rhel8-branch/_static/fonts/Lato/lato-bold.ttf create mode 100644 rhel8-branch/_static/fonts/Lato/lato-bold.woff create mode 100644 rhel8-branch/_static/fonts/Lato/lato-bold.woff2 create mode 100644 rhel8-branch/_static/fonts/Lato/lato-bolditalic.eot create mode 100644 rhel8-branch/_static/fonts/Lato/lato-bolditalic.ttf create mode 100644 rhel8-branch/_static/fonts/Lato/lato-bolditalic.woff create mode 100644 rhel8-branch/_static/fonts/Lato/lato-bolditalic.woff2 create mode 100644 rhel8-branch/_static/fonts/Lato/lato-italic.eot create mode 100644 rhel8-branch/_static/fonts/Lato/lato-italic.ttf create mode 100644 rhel8-branch/_static/fonts/Lato/lato-italic.woff create mode 100644 rhel8-branch/_static/fonts/Lato/lato-italic.woff2 create mode 100644 rhel8-branch/_static/fonts/Lato/lato-regular.eot create mode 100644 rhel8-branch/_static/fonts/Lato/lato-regular.ttf create mode 100644 rhel8-branch/_static/fonts/Lato/lato-regular.woff create mode 100644 rhel8-branch/_static/fonts/Lato/lato-regular.woff2 create mode 100644 rhel8-branch/_static/fonts/RobotoSlab-Bold.ttf create mode 100644 rhel8-branch/_static/fonts/RobotoSlab-Regular.ttf create mode 100644 rhel8-branch/_static/fonts/RobotoSlab/roboto-slab-v7-bold.eot create mode 100644 rhel8-branch/_static/fonts/RobotoSlab/roboto-slab-v7-bold.ttf create mode 100644 rhel8-branch/_static/fonts/RobotoSlab/roboto-slab-v7-bold.woff create mode 100644 rhel8-branch/_static/fonts/RobotoSlab/roboto-slab-v7-bold.woff2 create mode 100644 rhel8-branch/_static/fonts/RobotoSlab/roboto-slab-v7-regular.eot create mode 100644 rhel8-branch/_static/fonts/RobotoSlab/roboto-slab-v7-regular.ttf create mode 100644 rhel8-branch/_static/fonts/RobotoSlab/roboto-slab-v7-regular.woff create mode 100644 rhel8-branch/_static/fonts/RobotoSlab/roboto-slab-v7-regular.woff2 create mode 100644 rhel8-branch/_static/fonts/fontawesome-webfont.eot create mode 100644 rhel8-branch/_static/fonts/fontawesome-webfont.svg create mode 100644 rhel8-branch/_static/fonts/fontawesome-webfont.ttf create mode 100644 rhel8-branch/_static/fonts/fontawesome-webfont.woff create mode 100644 rhel8-branch/_static/fonts/fontawesome-webfont.woff2 create mode 100644 rhel8-branch/_static/jquery-1.11.1.js create mode 100644 rhel8-branch/_static/jquery-3.1.0.js create mode 100644 rhel8-branch/_static/jquery-3.2.1.js create mode 100644 rhel8-branch/_static/jquery.js create mode 100644 rhel8-branch/_static/js/modernizr.min.js create mode 100644 rhel8-branch/_static/js/theme.js create mode 100644 rhel8-branch/_static/language_data.js create mode 100644 rhel8-branch/_static/minus.png create mode 100644 rhel8-branch/_static/plus.png create mode 100644 rhel8-branch/_static/pygments.css create mode 100644 rhel8-branch/_static/searchtools.js create mode 100644 rhel8-branch/_static/underscore-1.3.1.js create mode 100644 rhel8-branch/_static/underscore.js create mode 100644 rhel8-branch/_static/up-pressed.png create mode 100644 rhel8-branch/_static/up.png create mode 100644 rhel8-branch/_static/websupport.js create mode 100644 rhel8-branch/composer-cli.html create mode 100644 rhel8-branch/genindex.html create mode 100644 rhel8-branch/index.html create mode 100644 rhel8-branch/intro.html create mode 100644 rhel8-branch/livemedia-creator.html create mode 100644 rhel8-branch/lorax-composer.html create mode 100644 rhel8-branch/lorax.html create mode 100644 rhel8-branch/modules.html create mode 100644 rhel8-branch/objects.inv create mode 100644 rhel8-branch/product-images.html create mode 100644 rhel8-branch/py-modindex.html create mode 100644 rhel8-branch/pylorax.api.html create mode 100644 rhel8-branch/pylorax.html create mode 100644 rhel8-branch/search.html create mode 100644 rhel8-branch/searchindex.js create mode 100644 rhel8-branch/source/index.html diff --git a/rhel8-branch/.buildinfo b/rhel8-branch/.buildinfo new file mode 100644 index 00000000..fb04fc50 --- /dev/null +++ b/rhel8-branch/.buildinfo @@ -0,0 +1,4 @@ +# Sphinx build info version 1 +# This file hashes the configuration used when building these files. When it is not found, a full rebuild will be done. +config: 3bd21c088305773bcf2949c400b7d8c0 +tags: 645f666f9bcd5a90fca523b33c5a78b7 diff --git a/rhel8-branch/.doctrees/composer-cli.doctree b/rhel8-branch/.doctrees/composer-cli.doctree new file mode 100644 index 0000000000000000000000000000000000000000..c11a78d0e0a0f916991aab27cf36b058e21a458a GIT binary patch literal 43171 zcmdUY4U8Svb>5QV-#(H{iqgs!Nr_|85-DllE+tEfL{m&Caw*Xymo&Me^<(Po?7rEZ zH++A3GmpzvEQe_#RC2}%5IO;LA~ot7vEw$a5x2G6I!4ko zNShQ!1Ec-UxpU^;c{@8ZZ~oG zTB{k;yBpn2?&izAgLt_ys0DS$colA&Yc<*}-|3X+>a`xxfo#LHbB!|Wd;3a{1pvcc z;ik5YEQ6lA(_QD@6mE(HnhH16YfYy&)t$A&k{tw{+H5y~A|&`twW<#x!_9Mb+xPJh ze{XEs4fWTSYPYR#X6?Bv9cP|sy5Z))UZ7V!cf{T8ZlxUEJ>h#M+*ZSxn4POnTyUzD zr|e*&-D!FLM7`CquT8*k{)DOBc*lpldrzEA<*4ifP4EWGQ~V>id}YK@eXq^-7^MFZSjN2r=5Y7H*6+gq{rG=3{vUvC+NOXAI8xXNDW*lpKL zeP?!RPJGZE4R`d>^j>1&H+9EQNuzbNeRVJ{g2}efZN^fGg?9OI$JQQ)< z0OB%XIgji8AdEoIsMr7-pHYQ@yD|L4%#4ZhnHj6*TV3C&T0zUIH3O$(&jr?EEpV;C zb*z~g4v(^=0sXP_r!15JSDnt7)v%lPLan)A&DOh4yMy%pnB`n+BN08dufojsY~8Wi z2vB>$!CSjowPw30gNUH%ELyb&y%>)mgd(Y4BPr@87IyYaEoev+PKfP6b7>nBEb*rdL3cW zYEmGS>a97uZuv`o;4~D7DLfE39jnuAHVMqN0C;w)e#FAI8ct&t?_2XxC@rE2>CDWO z7CNnNd)%6Koh7TVScad)%6qTFcAk`M+7_k-$i2Yi9AL%35FH`epWVzIr0(9hlN-9s1dhp1LTcAFmE7H@x?f*Wx=%(^Yy zcZT{b*72w_Wt5sLt(v7}i^rQKFwPJ^rVvpjI1y=Gc>S<_A?)4rjL~d#y zwW5Z??NPI^GK;GCirF~)>8_6!bO3b#d6+(=tSfo!%%1U^P9nhOR+xB&%4 zTt=vyq+-|e74tr=Q z8#huB4DbHS7_RRYU<55^Ddt+9)?D-gU;{mkM#G|C7{}w58idO;5zbQZ(0p?#b zsrPY1EWy97GY+5Y25odgsGEZ!MC*MQ&rP8><+suCQ2isvM(;@VZJMo41JT~%Bym}| z78bD`y#EFD+$7ZdT)c@V6}1E8FikiRY*LH~}%NGs9U zD8IsxYV=f%lZIP-CkRmNV66A%c<^_=)55?_v)T(cU9vF{Lof>x)8 zo2pHfn%!vQW~<5y1!nUKZcEW^w^PU6_MkOap>b7ui|jT+w$4&7+%=E>DY~qV@$&S# za66i{L9^SaT$=|L(BBD1sDNx&sBMCzK3MKiPn^2LPbxIZRFTnLI9X#bJeN$POlG3u3e9BH-?scY-BFI@Q%JWeJs3v>xYKI5ye-_u<_~XljTQ|fAU3N;&3PF;KNWZOjPH3dwbn( zE_Bflg2k(-$Jb+sKfDEl1+7lCQgzzE2ePRF98=+@xmI%?YQiG5Y6TVkeC=A#-4u>s zV4+pfkHYmefNFcS+h|u};K8u`fCmdv#}mUH`~=o*`s9B7sO>x5YO8|w1*mpnWDt`F z6*DEHWG<*&t)b1p5ZzI!)_fW?gd&lYnM>u z0agyUb>y_mcOQBPW*OUej0HC@>;O+F6nt^?-;?@@2I{pKu z8|p1W_%^>`Bc5LDB7A+MyoK-8ZG}g;lm+jYb1?}phhbP1R`3{=KNY0D(rx!%NG`!!u7k0e*TT`cddt32acEG!VplOc z#q&L{hBrCQt28+jZc!xxLJugaHLDoW17_6V4o?i-jEsPafCt8a5KINVjIt{6l*W_z zF}TggH#8?eGfg1hOb?^Khw1NNsm&?eeR#XwbPm&RpR1wlp(ZDIs3#OaLZ<{XpC~%a zW5Gp@*;YOFHu;oq!78(SBaho1t(E!aF7#!DJ7j0(PM; zlwuf1apLjT_%S=7RHcF?ia~cB*PCdBOJxY36|Og_Uzn&jJ*tbd8=+BqRW)R?Nu&1a z?}KM|c2zC5ZDmYbl*>N4oq%i9ph!N9n-ge9?e=~FMSG3`q}BFw1xTY-Tgaq2t+scc zw`u04#mzP)u|)+3J)+4=r-=b=(V-Y|tef{6kO1oaI$cs)V*FgU#H_d_cGm=k$R~Il zaKdia#+6)m#bU&SZ(jeERMI!Ee@c&#d0$Xsyv|~Hze$$?TWnvXG^)k+ST(U2DQ}5>5wT=9j#y=kLJ_M- zc_b%cH;;Ug9fncFDiCLru03Km@-UC!E4qtu%rW}ctbS%8B{BL}1xTY9{hv&l5~Icp zY#enMiQ>>aIG$X1famv$?8S&<)x7ODafoiE%d!yl=<&)b$GwuM`(vQ|4kY}cMENZc zoKa316ztC_Qbzd}O0~{YTvoOmEG0uI3IT65z=z8=RY@pJ1t`Xo7!3^cr`Q77vPWZ1 zlLbg4pg+N+DL_AHAbl4t6}aSdd^C}$0>W&mh@18*mfN$*?7O`RU6!Hvpn9$=nr(6Y zao3@^QrQ_lM5S^lS%K6QdymlH2*5?Y4Mv?UyCe4Yg z3+J&U&f@8b273DxT+!^uxb?u}XVFrXd$p8j9zCmZ>%p`)wPp?duxdPL_g1iu?dJVU zXb0#29$iu*o1g2*F2zB7NL*n)(rmw?*nXMWdS9Z;fD!$5N~0qBcQlt`5lv~0h^E^g z%7`YraYQR)6pHA`ZWPf8yLse`>@bZYS^++rbnOwnzI;g_M1RK6;Yi-LffO$k$-@Om zqe$Mwq&bm%kMFh?F-zXUlFP;c-@>vwt}Zc@N^6H`wH%FditGnX@;9%4a^(cEhTh$f z1Mb;Rmz0>}=Q`&4N6K>t&<`p0pDqK&-XoMo#h#_P6pKAdYs4Pi{!qpq*^OgQ z8KY3_MRuduOW4gLUt|YV6nhGy*`$fs%O;H`{Ak|H^q%(xJSaZl7i006H%dc8QN3pI zn3Z+pi8D`6p1*KvYWk>kWcu0jlSfOXi!|tE*>R26^)Z~U20$>?fKf~=IF;q898hXx z-lEaH@lr`L;K9C9=?q3mRN`)%W*=w?U^Ej(qk%>ONQ8+8GX+1OIWbzfC(8mUgy*AL zR%A5U(6Eg4{GyF1^X9^bqEsJ}6d$6h+o@iTvcc$bZ4RpwX^@pi-z<9;;-&J%LWd(y zKYi-NQS1357f(Gmc@#`8QfWg|dYC&1EP85Pc|vCK#1iO$8fwnjSeRXpSd~i0)vX=t zC#gu!DhwWA!Ax^WttH0nYz^b)G;fGGIaBM1k_8;Y`U&{)gi6fP(NI-Yv`R@%7KlY+ zrK(QAmP!~$E#4G9hEf>YwJ{ZD$2?B77MmD_#xiIaCw_|_3%9K>e*`V)m1v6=*O6|w zRy|r4;&H%GqX{*j(Y`kpeas?;YNaZ#uqHi}#K~OL zO9d48z%)aIdqsgs#)fHuaqA?2Nu%WOI?XQm(NbB7t2pL-9(gq4gvZ_mbb5`rP5?*g z8;h$v9r%KlnvXe|B^D_rhV!lIb7#+3Dn62YFsaeRAh%J5q_7eqFt8kZ&ecUnl3BGj zKW}hCX>{_!xwGZt=gyuz#bwhu`5Q(xM5T1@c%5m|6%# zTAIuST?31aT}=O35OZqs16ZO|nwA``RLZf4Zj6$A;M|4N7tbF%KAAMMeH9;u#3gKG zos0C8ps%eADA_!$JZ6v|9S>TKdV-+@dCXErxuK;MLrZ;D(8r?fx9VwfnO2q03wQxG z3JwSut>8{dp7de63j=C>A>4U-Vv44~6b+!05tN8YKJy*Nc`3zmri9S(CAd1aA)0#V zxpgrK##NFikjgke0Q$LS#z7>mpY82sEKR4!YLqFKkB%#120&5+e2SH{@H8H95!*uj zgIPQ*4bVoR(v^^H!zg%JcQ9p}qr!FrP9;%O2U_gjit0^m%t89YpP-i z9LkeX<3MGa%xAIHxxzEAW@ZsSlCi)DiCEG+F=oX&OO{UWV^$k;YhW+_rV8IE4Rrw+ z5rCAwOrzP;{*qJE3WZ6mD#h~`&b@E)__RbXRrsoIgi*PzK=SikP?h=}oDaCD#UB|t zMg*EtWq0x1(-)3UmZy%Los{B~Yhp7umDI=tlf2dum2#X6h|oKRN49(?WT_O|RrI-$ zkzTpEpT%)5;1N&MWui3#3lSeJvy@1N)Ml9!g<+IzT($621(dQvlpk^9Lw^%R?Nqc1 z)o==Z|F@%x`Q;|BhfH6YNJO{x5%n)m3~3n+t({o88N9YuF!wJ>k`0*jHy1{Raf=6v zp_!eCJ#K(Y*EF9{cS-*~IwZ z{rH;9BC4&Ci`M&>l-{4n*IQOilhPm0C-*+4I4k>P_tIV_(%7OeF>~+3xX9AFQ0Ak! zDd*>Ri4=OgpEh}H7sRSX6wxq3-&1Xwe?~&>_P)T<6h#D0w*MBV@Onnx7}KFue{nxD zwDLN2;^=%rE%BF>#D9=4vG|h2{a5+q;!CAjQC|}CG+$1NA5_6)ICGHRYMO^flAOhc z{g1W9{#04)zZWopj(S=X{4GwA?c;~Fj|WgpgkEK8t=spMZvQ7=H$ej__P_JV1r5pu zMbSXa)6j59d`1m`0;3LW)ciq*GVI%St>kXfo}B+ct6$aw{%*gSi@B+hC}j zoFW@u_Y|{)Xi=10OMgH~e|Nt00w5Cou6%Lu4zKfXYA0DYBt(Z(%h>>H$({9WE&yrt@_WK#&6O&nFi^ zC|!#Jf|#cPVp_bG94B1cFku=zMpH8q6R+@An=?@6>=dw%hQux?-Q*P6ka&De>WU6) z7O#`Y|0JJWysoq> z>UCnC=JliEBXbO&i_}6x_-SsxC55HfF!h}_+SioP{;+@*w5#6<)xOLrvR$pp{UU0K zv;(BjI(%E{@U46u#POuSf6gZt$17cnI-Z!PIX)i4kQo!1*+@(}#4iV)dr3paI|Laq zTQ$=m_FnP5w(h!3+^qb61*do=p z=aUPzl$DBNizMf2oOesuHbH>#+GzGJo_0$^Ph55wT*cI>@3h?xDZ7mqFoZ_U zozU(+PLYk8u|YHwfd@;ZH94j<`O$n$1OcSRk$iGNfYP`q0*HAU0;=NRzG>6gR5xPQ zGz}!TrDrT=U+J|ra77vTasi8JsJshic$QOSL*>kk)L(SEu}rlk+R75md`k$_$P8EV z$pvc4Vnv}w%+sJ2S7eE~^VrbT0bbM8c^b-Y6_lBIia*j{YPR%{R{qq94Yq%VMLT_-2Y`EM%fI=ecKxwodUr~B|IbRQPIVtg_ zd~$KQ(zmF~iFumKPZ}QbX}VU=u|=I>WBo`>yKIU-&H4LcazAw$jTktKuCH(WKa^4b ztbmm?IPQb$-{BP5;JDjdG7-z(uc}C0kXi%c`%3n|&6iyOL4toTpIiW;bSw%8Vx9(w z)3N4$yr3Zq6SC+bZOu{|D(=eXFDA|*?Zd{N&D>SG9haQWf~T=jh80FRMK(4LnApfr zSwt^PukkUa}UyX z8anRC|ici^Im+(dm3=| z7{KXgEoRQ7(Z<}gg*y)$a4Ft-I0}`AI7K#4?k%jQNIgIbt;0K%4x{-x2p~v-UHRk! z2&HRLKoIjZKzzXP+6o^pn1R**DZq-~E~FvkUAcLQ#j`2NS2jYqN)^C!FVApm_bC*}6I{v_EusdPJ$ubZHV6g!qrE+|qqD2gIto`$07 z<(|zQzUqfk|Im&)hUQ>$De*nUG7<+AAnyZHRT+G?fCV*}PQWZLaEfd&jb-7XUw_eI zutd55>MBkAd`$#8q((cRT%e;gE(#rDo(3H+#iJ?xl~UY4ScV(^z=yU^!Y61kv$U^~ z*rEjhm6E+UBMne}$0{pq^N}RYbEJ!AgVgGfL}E=W8wC zBb9$GpIpGFtWy+x#5@grQ!!q!g-YM|X{-1=Ee&A1SI$CApGBfg`uobHzgxgY8c6Sh z;$P$x*+6=5aBW5U)g;wg{gKk@tNB_9P)Mb(<{L}i&2Qx?NU?*3q)d109(j%aBW;9Ze)BK3T#2TytMZSPDSxAYZM4&$ zg~FfX6xmKcP*6#cxiGzk!tW^gznCw-K!Jq+?R;{9g3_}n6o`2m6b>f#S4fEk*o{E0HiHwtK|9r{6t{U10*wnKNXEV;;)MWUtr3nk^B=SwMWBN4xw zPcCj#+7xvgF;8>bV`6y~XU4V>@|_axI%USMN{}A5cV=@F3uch@1@BgDkOs+zami`d z8ZE5~Qf%ZD*}lI0#7Y}^h@cr1+S7ZLjJxw?6i<_Y@5m&G!jqzF#b05A9+XO8x?;$ae8N<8>l^+Zu_KD-&o5e_cuVxqJ!5!6e>i z^2x=)N|T}vCg#e)*(t86?KlG7U&Gi5=Dlhcl+|zPgtO$<#6w&5OUkl;kZ&rntOwe7a?7PZl-=WJu$LW4MPQkL>hOKtv?SY=DV0+q&yt@@`rHZ}cs1GK4 z$m+3%c*xDiNe1+KW+wV5r^Cku>-QyMFf%h|wQJak9Y+cB9)CW~8A0c0tWKRMua2^6 zVaqt$qb@p0KFK(-7bfwbbH&PPq1VjJxOIxpVC>L2#rR4D$JdKR(JZ}+)~Sti!mOoM zm$rq(Zny0vmMA*8(Yc1R0BIM(nRp2qZ!7P2aYAb8h#X)_`rdbL)V% zd+J6-ffgjZaXiy3tIw0a{FX+ZxZ;+S@Yc$*)%WLET@Id4WrcI+Puz&YLe8g`xX?$` zKY4>nBW000UhW-q_u(i$)~1a41U~J%%;lbOl6|VOalIGP>4Du&t>?XmjE7qAYw93- z5q~sXXRPd@n-nnUy1DIV*e;lA zovJzo#I|^cR_u<6bKvNdfqS`LiuyfBjZGEf1EjHabYe$N>>8|Q0(f)XVBEThJ)fyM zqoYWrPE(ZW-Ko2Lz)?SS%GwEdD&1~ui?nzJZ1 zw2~j6=v(ELOY-8P6D!+OMT4JgB#JffU&)#&skAa| zOLtIPngyRXN!VBpkzyquZTX-}KAi>!3ZoBEw##v2()Ir7Mopw&-we^mf#V@Uvtu9ZfhU8k=*gqa%3kp3PaCk3Lt>$Pgf4BLjcuE&ZSq->*kW!*M5!L^08VxtyRp$+p zDUP_P@h!wNf}9S!Ktm2~pClIIZMQiYnlz>3-A)JF>es31gtRzC-N$eQoh@+~2h-GM z?O7ZiX*X(P)DV2AOf5!#30?Tcn6=PqEzpwMdhM!HuKBI8QVU0W0A+Jm&^razcpr18 zTBcHGOcfMkSVY+wv#z>T{4}ap7<$yC8Xrt8jlO|X!mwXixmdU}+h7tZyUkEZT2+h2 zf$_%$1A}DZ0^}!u@J`Xu@-`4A#b3oj=)Ob<=``U8*EeOmSyuJ49>Y{`bj_XF3ZU9H zqZRPZvn}l8kDidO!VnwS?q4vpGC^#A@B4&Q><-rl*vvi8-4UetUYvqk1`}o(^2|PT z0!2D>mQn{OjT#>^&tQCV(XHW#8}2IdryHb~(g>wRiFVA2HI0w=QDud$+NmqXWYiyw zYJarJlbY5TNN3&%)NKMq9_PU#`OGcy;So|-x}^(2}xl&h01HudnR1u`>J zT6A%Sj%tp89r5C(NyiDgou(=!BUMm6LhS}Vwb5;io0l0%2Y8tB61E@SmTboveVctN z6feq-Gc$q>*}7N_7AJk7^XCF)7ji4oLLsTRfVuvIcBNJz{K3nT?XRr{?8G;lBOq!u z*bjFP>WA$K9BXc2--~Ps-?ajwbO4Clccj)?LZ|a*Z5|y|n@3g|XK`5_gX zHTz=;Q);o)Kb376J*o#i1TfTC&VU_t) zQa)i_^(d@z!+PM*gAZ9{7tPx7iGI^X=NqkoLtKuq@qaJJ_}&L0xOW*p7{vC@;EEHJ z>3e_Cjb@F^LwLhoQk!v!s){vTl*VtlK#;c?g(wOsZSZiL89c@)Z2$8%5!R4-HMN^`z&6-k-qC-haZ6`%U*7-mPTQo9XAjV)owqCjGpE zUYGax=;v|zIZQu)LqGqEey&maF8zF+e!hyIuJ;0D!}KCEpK`zXD)W7nc}_9EDdzPm z^O<5EQ=ERP>+Yk3EYMc>8}8SYG+Rj|mS#Ww#nRA#xRU0fSQ;8#QqoWxh^1jXbUm9z z^5)dV!R2z#TTqvpx?EA0hPt%WB&({mc#C5v(P}GNBem=VV=C2Ex4WvkHrFDlotPvH zb|R)22dAAwwX9Evy6Yf4=R0+pW8(OM`!j zy8GVm{LlH$Ip6vAbKiQyyRX0I+H2^)!NzX8Qf*$!2h9uBPOI4nn!Vv*{lR{Ne6_NLmMR;@c# zZ*_{7rcksyRp~YAQ+Ywv9S)XuJ0(VZXFM@Vms-u)>fCU!Mu;o_UV4bXQ1Y#4T?jgz zYB}ga+`*D=(CagKgG;@j*{!yk-QhE+hN||ZUcT7xwIJAVuu19y4=+@Mi=|dM7!I~* zPpi#d(BXd%2kW#KgkS=cNRZ+j0EEoN&RiZ+41>YiUeIXQi@l&*Xcv1G2sBt(P|t=% zP_+7;Qc&pjXJ@OIhJ#h5R=pmSdQAMms?(iv&q~dd&5)R!OBLl z3lR&fK1-_2ascvWWDSr*A1BBn!@-JDtG&>v&Qsh`X2^da7FnGt z++LU?&*~Psy@fhdvQ+ADC6y@jDnSEJ*Yl@^POq#UvG?6xu~#iAWi0~?J%FY*(ECbI zZx?1DQnN@f%ULCv2G)|6FBKp#V^1!zjz7ZdK7R&xsN6kR!HDuG4KuReCk~4uU_~le z`BYFZcP6HTVgnUu6r25Geb|ExEATsHn}f>%YsX+oohi9;#1BN))}V^VukFDhH`J>a zAY{2(%#}JpvDfMhE3X|)oWRqGlk|Av5Pxim^~|vHgn(Gf_~uHjM!VGwK!0j*3$Mu` z@hF;hwWP|G>eXT8?BE_nbEr|SSDV4a`CheN?JY!M1cMDwUbQ*fBIna}Te;V-2ty4h zG;tbS7%Q~iQm5J`y-&1eCxrXLA=jL&c1uCMUTg-fewS%~Wzg==6nfPj{0bne*q><9 z71H1ngSG5$6scFc6;g_P6t;lM&cQ}jN;>mwwa#ogSk(=Rol+&w+_*T{q&5FS1A(yG zoFkXoUg`DP-AATaq|3J#z`L1mb>^n_Q48C|K{Ehu@`utzoR39p`6sM&8IRu*Pkokp?8g7&g54<7KmbNsi7yD0{v zSigf7v+QVfF3%n<=@npX|{}3WK?sdaE=K`V-Y|57nkO{lU@;#d;sALdQ_K z2g<)5y~yy?+kq?$Fj&@a&No{Zo5RYR@w~F5va_;>e%V#Ik3ZQheisOF;Op!cBYcU$F74z*51)N8!Nv;u zfI9U9N=ZjoYWwDgb<-U+Q?Lc zFoZ6)SD39A!CR(H1h1r(S;_g<{mCG`gOJa`s*l1*MV4@rS$AgjN!SML_kt5;_i zaOKEPS_N-83{yH37|LkFeU1qu)_4gu_vd}PCAsZQM zrPtMp=rotJAp*4%8jf8LZDP294g}+)KCk)y%Kbc6%vCDVTh(Bppt&M<3?5}!Hz2z` zIcAxV9TM-!IoNtefY#CJiQXd-86U9lVazFxw1OeQ{aR2T6J|AgGF!Y*#W+}{o9Y4Bejs65Ea^DY9F?-XSh!C!3V&=}Jd`t35tGKdu{AoAA5tAN4o3}Oxi9QK$K zA#7Bs11;9Y*hIeG#HhIY7tq$KC1ztr%HL7MX$R;%&>7F8pSbRqKPI4gpVaRLM2Ml% zJ2*$7%QnUb;>BhC1$DIr9vvmcja+n!P5cG1k}tRLmuw77&(%2ihI|hW!lAjSBucA| zkv;3Ehm{v}zSM6@T45P3sSYY$a5xq$!;yhmJtiy<4&nv3Gi=NpS1Op-t<~?f`-oMl z!&t&P3?cnSRz(_gp(PbCHbL7Hpxk^s7*Jc6lYr~;6M|SMk5xI0+h#@hOS_eDwp>|- zZV537Bcc~rtP)D64z*lBh@1-`R%nykn83j$_(he*&2TGv@<8EY2jiBG>G?Dkr?4o^ z!P&BKgf5CEFGRqi#-=WMhI+s)EJH`YG3}L`~y>LuGP!ey07N*#>b|E*XItLJeNCp@5~{G z<2RvQ7HEm1t-Q5Tlxh>2p=iEiaNRfWK>PUSox^~OtBA|hE~a=3qR`V+=owi^0dZ-h z?lxmY2~DucOutzc{XGq8SEx5^bhSzSiHQ~~SS=4v)y_g`)HU50zAgtBFff>7^Oq$- zGlwy=Dz+^wCQ#ID@7ld#v9)0_9?cYh#%F#89W}-%G{;=a<{UX0d_$!5Ari{7ZqtX= z2^ut>G2d?uY5DM=*eoG*V@RPOwueO;)h6cCokpP^H0RKnhPu&I*X_017h9b&1-PK; z6_bxAhqW3stN5%7`S4i>2E{btn|K123t?^!i_riYSe^;7 zwuD%$_J|5>;b5?i%_C;2&8bSYkNH_hqA5(_a+(c_M!pECCPGGVV44CHXz0_SUZmG* z)uC?|EY`63lA3Z??&V`5_EdV&{r)YLC*=Q(G2LV@D$Pnu3R5Xo zW_W2{&0eb{28Y-4$6Q!?j72Unz*R*N-rE?P{eaF7Lunq{)mZ#SR<8!a9gq1Jt7RH} zUc;%l^sHAzd!#9&h<#E-F~8PE1nSLthOABHbv5&s)N^*KGgyB!Y_Ne*QpbY6f#yD# zkgh~)uRe$JSab`JGy40gt1og1PcMO(^N6Zh`%lFj6+49aiY9AM# zxLUsJleI6a=Nsj7Or~05g-huCCiN;DboH>_7obwDK4$wUU?OgG%;fJ%54*iXN1W*~Dz(X8wXqz<+CCj)_oR?>CyFxr#L} zDuNZ7vYei5=j9Ox>%oPfUJ$DUG`;1spBs4rd#uRh5ty29T-U?^nA-9tPR3r*90^ks z5jZN3R9?x7Y~e+;L8@#8?6p|8!??XvFLr5Y%O0<%5eb@RY2KPqVf9SD=mc;njA)Nv z%Sg00Jq%nhDid|nUZ5A4r%QfVVUdbe4pk1b;%jJK zFw_r^oa>%NjMJAZg~zTJ&)F28P2lBRLc9=bq)VC@(qE7RLH(T;HrZID@?_;HCdWp2 z7h9KeeP_LVrLB-Mnl18$*Y;|qFRa~Qxm=0hrrIn4nph7Edc|rTqsG4QN22dZcPmwB z@-kSq>#^Lo-g(~}#cXm7E7A-u(ohSpZ|FC%48Wt(CiaeIDQc9gW~s!NL5rEPF?wbr z&Xt$2;*4d59{OR?ez%s|Z9Z{vmmL_*23DY4z$!P3SCB}w>%oomimluD-fo~^!F(9V zm?qHf$`bC=ye>CV0r+{L5wMv(1|;Z^1}ls8cBMEI&?+}CxLFpIt4MN`z+Z2*Uu&aR zR)w2Y0c^*h7Kp4gCMou41yJZA6b6fZ=n&eN9EUaCA`!%@O%=;r9Yk&!1m){$6AP`F z38Ge+K%IhOF*po0bsm-)*H^>P-wAeb<6xiCxNDkF44sgx^$ z(1pHEi%Iu-T&G>+wD|w8Q4%-tCp~xUvQR--`cl!~gdkf2a?i=6h$<(4Yan7&E*) z*l0Y*=mgF0GS*yq^ls$1{?q9 zt3hv;?QPJEo#?5wLBF=zG!{N8?;fm$Z?L&i;S%jikQQjH(e2NePghooSRQAC5wz98 z7Pf!`r@+!Arm$E`q2N$PJvZrVjdIl=I{<70qH_HpZf$(9Mot-E8w@Ym3~#WSp%&z_ zXMeDQHE3#*wB~*lUY;W$pbFdtXz+4(~6O;4f2Y#p1d~Zj9Ce6ar{$G_!22K>i&@*n?>{~$5Qj5p=;Q#gx&jW}k*scK`6X3|}>m!b2ryU-0^ z-eOU*6>aQHH`u$;$c0Vp~+Fu`_>7~$=b@WK1F?LnHnV`+<(*lKaE_i&!T zD==p9B^vv&m)k9}65rWn@9fHy1FR0xHZ)hntrjVr{SYhojC_mro??(!paS{`bd&|Z zKzxgvy}Q{$MDJA!b#GgZbvNwGSX<*FKDYDC7^;U>5;nQtX9ZEG~4ZOJ*L7jwRF8*W4f4rOjcn|;aUjBo+Fc46ufgjXqJx}K!*zkpo z(`p3C20A=QHEGQk-8d^jr?mL-xfPw_MKMCIyf9c^s^FXywnQ+Sto;cA+%S#lEA?|` zfBwRdk=Op5%9yVPOWEYJH>~{`UiN2-m^+5ER2mvwU&R_X9ghen4ud89C;^@>$J$}| z#|+M&u;rR(P`zcnA|{A*q)JqyKf_d3`%`e@6=D)qUZ{N?Pf&-yBKan9x(R+BO!Qh4 zY-Rk5Z+(B)+=IOXy|z}PJ8X)3o$|H62Xt-u^{k4uf50E8TJ4`W+kfUiuEARfaUK70 z1N+ghEyd5;GW-MS$Z$3ujBihQqkW*E`lsBRbmvIYYRm?0SxnYcqp2K2>K0WWb zYfF2lYnlz|#%j12Z**$~El$)$SD6-q^MB1Wp4&Tzk)C^pLz z=h=3Ccj6fBw02GR8dZ=>d+G|MrEnG_t(w#r%2Q9d9N%opkvY`xM*3Aqg+@w2Hb%I0 zVzfSil~Ot{XX?*+%Y|*3!qx)(jc_r?e^mL8dH$opeu&^9m18uMpz zGd6pxk)gR^NQ?a=As2{G-Qzy_H(Cai0F5LcL2;+Mg2ES4DDKB-Ha6Vm2F zX+>1{aY(>r`Nh<-2#B9m5T9TW8EjI^Xp$Sxv@q?(5T{t5IN&t|Ms>{R|9k4%CG`2h z=1H#*j(-0rwFHiSe?KDx&MvA5#nth9+)`0(B&$8vox(u79Ak=QH;l{a*H7B~9V^_B znz>_zYqLUJ143Q>f$AjVBQTd@VDw2Gi#NLTShY}`kB`S2)*r!s!9;Q5Adc7Lz%q6X zjS%U+<`sGzh-S8=|PdIhq!4mITJ`h04m`TdU8ma!Dejwu^cyjnPM_}$dJ93T5_uHh)<*4~eb zVIh~_){dG0CtpqtSDRV=mf=7XJ8k#OaK|aRwfrJB%f%g7`qi@-NssMiIC^Hz!C5J5 zU!0z)jrSLEwRpAI9+1Zechs(50#h!bf0ofdE9jq9^v@dlXC3|tutiY3B=1>aUA)Nd zwE_Buxq1r+j|NLC)iO4r@!J}KuO2Mt2g`5_;W+HeS6ldLAa0vb*|_D*uCNRTyW{V; zPqBmD>>Bsr20HULJidxMiWk}w2tC%K{!@LSx^7JJ%r&td(N^#o3bOtjEvcKF7@ z#K8_VAbWi@DG}G-9$0)aRtlU3J-8Pg3BT#g&JgDyeU3?=V@C;cGg5k|bIGNa$!Ykz zvOnoeD*gu!>PX%Y>Lj!k3GT+Rup9J{)v#Ndd!2kg#;E~dt`IxVG)B0%YiX_zgV9n$VlY~b-cP{#o)SMkFd^jtF zZH4TOifxxfHL6JC?#OCg|0Q1__@^&6>m<2Ni-Fs?y;E;TR5l%Hh~8CJS8t8&sw ztrE8dk%)pft3OYzk%ZbG+~rDEevz96uifee}qVrR;UB0v#u`egLgZ8JcMpB30HW?*{&}BGr-jiAg z#~it=5Mwt7yQ5si#3zU`#gnP4kkk}6PSQnSTL#Ar=TZycnBh!Th_Rbt?Xy9nA7g=q z)Y2!lz`99`y`%gKsd+of?`DM| zCsTalkpUufg#W?kE{nZRz4CQ^c~#3?YSCZtO5C5?8cEyYs>x?VDI71@o0_lV1^KKH zW7q$dCt4RLj-5L_!IGoW$$WNG#>uN+h+#s!4UH5*bSQx$QN>;)`=zeI#{-liKR`$)b>$A7jc1iE~0=*M1*P zEsJBn4`hWHyZu%kIC;!_A4Gq_ZSv{Vl}KunRg=X=Ro+5(+Rvv_^L6z9$*d4#*Z;-? zYR!Y?+D05VTa2#&x5rmfS1PGJHiauOs&{eQ#g|j_ckJ@TtPo?j%l4y`AZ-D8?Hjy# z@KorIc}A4uR$7gObc=Bkz+FMUX_B2kVKRzXCI>36u~wuO!!g#2)`sZ=XD7&D z5k~U7=f>HSx=Kl#(8ft*SjdrqMzo+@YW9v%c4dVayHU2X&j_%qhU|#Vnb#kgIEcjI zW_XJ%#SJu_x_U_sw2kd_iFQMWXt3&&n<4pxj>7@m>rxBhnCVnjh_RdLwgbIZqgvu0 zeTcJGTw!jsOQ|cH)MyyIF==zOLYT;Q{nWBJw(Det7`yFuou@>`6DN^4jh%b?;#=P( zMzM5}@8E8yMVOPLUzd)X^h2q2kkq6*Ci_&0TmzM0$D~9Jay>D#6?XPatlpnm zD95(%$qF%c+umiFi0#abwrVmGZqQ#!UGby_z1ub@NuI!(zmQrY$C^Kv6=Lkx+;$on zrq19lpUiAajTt4UAd%I z+d6rH@6W~B=wxac92>nhE5z7sG|5{RhM(t;96dHcr>OW6aChQjwO2s`-HtWYOGLq~ z*GpaPq}ID@lCP0q#M#G3o^m8NH)J6;-?7WfSs})5mt{|2GzP1f z#!yeW1wN5l{G=9GK3Ng`9kqWvHB(3JAIl11t3AWceRxTY9}Ld`5lZoytY@Fa#Tk|e z>FS;F_oPazy+WPq|C`iS@p}_hD(+nWU#8~eIMJUoh^u+7e=ECX7k8FFvJ`K#H?CZq z$$_Kg0ai6BDRh!E`x{aV;i!KtgUF!%tcS*vClGodb?p*5a^eI+`%+8b=yxhBL>QfR za}zE0(WFF|Ctjag{G>KWaCzc~hgkz>( z%nC7fGp)wWAa!raw2k?S8{~hcu1HdYteMpBD7jYnAE`MzR`~B(A#5vTnAe0;BR<~9 z01-+trm4~TLw$UAzA-T!U_gRTDOtOF?rZK7+gFckIKE-B#3ahekBxZ__iahd-SLY} zSs`qTWH4&z7krN*14JmrpJv@D5nD{`3maE&i^)##redxW9(bVbQ65Kf|+%9V!AbPs@1bTJQH1vH{)khS3RMc2iqt4SCJth zk{XkQbj-6!5(@2wbBktbDI5dLXN3qGQia=avF8@6kMS=bvW%QoXKTFT7I}B-iX^oN zI$K>5#|kf}=ImJErK}KRw}QUVr-z(@{(@WJYd06&(RucQB;%nC7f{oin+ zh0jMDn&*$W&VN6(;7N791e@OA?0Ea{rRL~p`**TJj9uHy&*9Uw_~QM7sqyeJ*ZQ?< z7H1IWbh3jLllYuAm%!2dKW9~2_;I3t%nFfM^O;vsC&U>G{#n&d++mRT;@nhskIhtf z$WtLg;v~mI?o2I>(|B%Y5La=;l>B(e(bTm|8jO;DU+Pe52^{^tCM!hPL>}WNTI>N) zqOI|2YVniWAi?pF+0@J(^_Q|j*y_(PHw>qjypd&q2&EX;s90<^Jw>0FHhU?#*~DM* z@b|vd>P+emahpx=PR-fzg_pBJjNJ2_>8Hh)dArX%!|p>r{d5B#)kYqVXPzB-p z+z9`e6(Vc}f5+{(*h7SsPd`1^Y4zKVZS)u15_gZy63ZsJ46g3)OwH420Jmp_NUZzJ z5oj&n5vV@LR;;WjWWVG_IF`CLNh8rZu^XVI5tOk)^oOYpE-qROwqRrRTVKZbO($ErO%_a#o12Ar!g!7CQ)Sf7-TEw_BMH z7VQ3FL^*D#f0w$7nGMAybPe@yQ;Xmj>K$1j#%`#sj-mS9pktdUvJ^McPo%D1QX}1H zw5&NvC?m3 zg&4b)w%Y-Z&ILZ#Y6e!vG@=~0(?6uHVp2P8v+X2BbWQcQsfBP%_19S;#%?NSY*25N zignvik)^nqZd*65S&TD+;NrPPx;eE7j*+%yg&4b$oOUvcYgreIb$g&Uq8vBW!PHgE z+@7R}uBl#~S_sEfk7k9q`ldo3eSyBt7#I4&a@R%lYkSc&VFkR%65TvvEk zYPOCmyfZ6=ZG;SV3|)aQ8D@Y8rHI+f$h=~*=|H(mYv`x@y*54(G`-Nak5PI{aKHG~ z)Y?tz7x-otlPlL^a^-qVE@9qq0p(Xx3*dOjFENP71(Zd<&v*BcOGO-44IY_*<|o?4 z4!(Mg?8~_F%u)??`|Wni&M=gah8yLNQ|lzDQSP1$xa>I?C#Q+dvkghn9V>k)wM34U zzK|6nY(amJ6(VfM+*kfpw&QhYkkh6(7fhUEpGmitKApGRRkp4l*C2Ym+zQC?&$fHE zVs1>$-0_MH4C3mw-7SZoJj_0vVk+C*gNZ7{RsL}5S|@FtTPMpG%Iw1_Vi!iJ-tAW( zNG*e-`F&X-!uB|o6(Vep-2RKu9y36MQt$)R86ZMk9LstrjHKw#)ZUAu;#aR3+;pac z?Z*;6VbDdlprF|s)>xgE;nz+T zgXd?4rv^%!FAj@?)zxOH-Y+97BX;cZy7oB;R~#&F6fc#7cCRu#e#2l{so17rAZTxx ztG8x`mj_EL)p9v#;^Eitq{$f`hcYpM1aPZaUl?8%iufB;uXZyMxDE1C zl~yB|nkm(%&IaYe6UE*XvJTd|Q_R{^r*p! zRJ(>jM5?y7sKJW4ixI3=35U%W+tr~rU_Al>^?>!-f5CtMdt;WAIgDA$xFg(`)gEEY z;`X?rn6;9dG%C1c%@ep1O+p^4GA^X(FSs6FpIQ$|8^kJV5K;=KJ)BR?*J%%DvqFS@ z#+dZKNxI!ku^S){5FNrZ;`_i`f?MRxsjHRLA~#NQQF6L?a^4q)s)f`7IHtLf6=LkB z*{;6tPBHPDE1+)N)yUB#qky2&w<64f=*$Kjm$#aMqf!?x$HLL z{9PM;IkgOqjlP%_V(d0j!K@sVkRKUV>UzyIq8zu>>W$+XK084#6xB7>iqv8_##)*c zV(iA+DuW(2dP>#iY|Cq^$Wq);ds0^~X_MM!hdn8#Yo=UkAsjR9$_g=dGi_65YR*=I zdK({1@(uK&i*Z9ur>q<72@hyD!7Cj+r4VtAN-W1oMPNk zmr_?Sv!#>-uBG~^rEo0O$qF%cOR1n%ZOla*DzX%}(}z-5FR7iJ&?m)o&Gi1%LO5o6 zPgaPrn@P14k!>X|^f|@2p?)cK1(O=e34KZe*HXWbS_;QfKbI9^?3TJwc2adpBI)g* z{6)BhzLdIRNiDS5?wpu_u64eUS^~#9e~=Yo?AB2;*G3CpzKfeWS%tWTmTwx@fZUnh z3jVH*mZX-!vC(x|A;xYa)jS$4BoQ9nf{Y^EKD$#_EOQHD++FMJOf7+9oqMuEjNLk$ zWqjl3|GegjD8ub@CUw=4+GmR$;kbydflj6t!7U9Eqb`UG$5o5Yh1-Y@_m%5Tkjdio#qBLP$ zd%Zig9FDzS&I&Phd#PqcDu`brvP*GGeIj-Bl3L1XR#E`hOdn4zgkz?UWrY~Knbw_T zTYnSuiDR7mv5qG=Z@F3iD0Ov`nq{5UfLv?*ern#1HGVHEgl&xs8|&fTJU@n#0V0&* zt62}jkQ6vi^c`3CJdxT_#_>*QKUpC{ml>0>Zjm#cI=QvADwAY=4uwvPsQ$yEV=gl=wy@JGm;99fs#E zspW9&wJ9sa*zI+*-qz?6Oi=3iPYjGK$u0I+>S`u!Ww-cRnH1M;VvnR2#4*`JSs})5 zGPNO1k>=Tc(D$DdjV{KGRZLyMq{ebKq?MqqrM@M#6pp2y&I&PhOBpe)6O^jRBjN4D zMiu1NdLeZslUmC=vlGI)_WHKeaya&SOIC=n+shdJQ8u24eSs0>xV3&Lbrq9Z%R5Ts zqPoWV{?uYP#`tdAX=`Y zL=)-?M{{3I&E3)XSF%EcZQ{$^Xi-avncKw5180s+oWFta^G7gzTRCDRyuD6o=cN8ZK$8+se#+ zVNWise2yybnto4e864B+vOoG@a#Fr@>b=Un0sfBdh@0+tiTut{o=yShPrP!Pcx;_tV&CYg%-eY_2saG4--eddr z*bev_j{~N{^Sa>6S#{}m!Ix6QC3V3^JuWD!?|32CWo{25Aat4Ax5stEL25xAH@ut` zVvKIMqsIEUC1*~bo1QQXJ`m4%NAw9Md(DoS+k8%oy%Q@IZt=JxN*VlQ5Blk>TJk#> z7d*}GMp6gEdSt8HV~deyH%c`V#t%oZAJ1B?FcZ+nvO|tdi`q$<62CSic7=| zzkl&cjKja~h>B%l{hWw)Yu3tz9(7Yzi1B-rid{x>8ugS%w6lJ%ni}aX9`HA+-=n_ z#QTzOrVvf+^`;|Pwd4;~2UEi(^``qg-X!Z9?@zBzEtlg@k7k9qn*Ma3icIpD9ox}- z`qi&bRKa|w0;>ZxUNe5jfg;%fTPy{-@O zeM_M+u?K36rS5k8$4BJ#o$tx26~FI%C^cMC-)bcof^Pa2_ zSJQ7iu}22zsYgfpjvITT2)+LE>shtq_n%)&4VTn^+}I=QnTzqEUrjBO<3qoa72<08 zP`Dm16w;mIUtRJY%u(y{zOr6V`TMLo@O#QPQo|+nlv|ug!_^RRMCY$k3*xxP*Rw)g zP4@^VUbe}3XCsuv59wGPl$v-YAoV)WJ=+&`;x(BXE~)dViI=RY_h)Rmvg*C$f{Mp z)A34&=m|gcFw|iTaS{lb=mS=?+qsJs2v%iwb z?sSG5lz(9(7zaD-(|qfsFNxP)zd4juFaFrWMIFa5=|*F0E~_N$9G*gcIBR{vk7ad?3dv?gouoY6+a6 zF_#tMf3GL7!tW`($#o^X>B6K1Q; zYPS-UEoazfhXq;A>kpsJT6e!cd?qzqQhz{hGhFb+RTUW-RJ9zJ_;hL^9GCc1R*0+V z65;hFp_8fEB0gKL%_G3Loy*~2O zSvBDIk)KEnm$XaVZg+`nt&nu!dd82Ymcr@IemE<{)%1)zoEXvwdc|_FSM+yJx7$I) zD(>}=FJ{$*-$VW|HC$2;xz+X%S-Xh7>GP>2alGVrvqD@=FL8Ss=tWd6!bMi37Q}IprCA}ari-{;OuaQ1;U7*HqZRc! z$D>&_;13|LNDY_NIh-zrY8K%c52lvF@r?ahA+DxpglAOMh@w%P!)+a3=ul@=ePzAA zQO&9Yzi-T@hD+)jH`$#_mDCX79HrD^IL`6LtPoezIl?12(%@(@!Zn_Lb+`Il@Ywv! z0#Yp6*}BvboH#nK)4V6EZv0O3uGDZzo#rmvX`mkFGC9&sj_bx9zP>ZHK#u!-XI2Q? zebP+#gcRY&Hh2=u3=p9dJPT4$pC%zG`ZImx+HI8z&3>bRZ%B5k$RPaua7XRCkP-Lz z^4iPvYNCy1z$Oin;AFQ9nwqUn_OcEXb?O9eo0(}YK#N?d}J^YK z&>{$lJ-D{Sek^Ovu zuvP-XVCgyjmrAruIgw8dR#eMyi_@Lc?cphyE@-st#a?ix*eN!;c(PhPInbG-zgLxm zQXMaQ)m9UKE-SZ6bfX8quB&#>2Kw8}gB68R1>XWjg6H8g!@-(DvDs=K3ZLL3m)F2W zwJKg$Sj(wT= z^=0PPmzh^zX12S`Y<8Ks^yR){bX|KvW3ywhTK0bQ0iGeF87$=j4qqG&)W=-tb^aj! zInnAAFCD5EyIoOw2{ea4Q21^g%PO32mpav6wN!-R$eF+-=v7)}qPue>T^a5_mzF5# zbXpyk=#G(`Xfe~JxoafN#bT#fZF=NWA0uX(JB*g_M2kKkEf|DaQ-cbtV7}CXtsG@- zRO0mEgxFndw0WUg8}0>d-s%>}AEdJ9!m@*qz5K*co_*k&;c3P57h$!~FO`6mQ1t`sz_}l!^ z;(T!U)KS4Yth&;aRWOhBD1;+N^-5K;JiNKor@&GuSG)5Cnos!Zce_%S5U5lMO7n&J zYH1$&?nq9CPL!uAUPK!d+Lr>P7NYOc`8ZA3oN(Z#TtLoP>ZK@n`iRsAfF!HApjRk% zN)=yWheNenV6*T-qt(avoXb8U_3bsup#h5&itTp2O8dAzlF)^O&KL>fi5uqdW9CgH4|yc9X7QXI$(fO?RCoC0&<@hsD3_S9c`du1)&*Vd8cx+Uho}ssvdQy z(1rdKEgTJ36q7AiDL5>U?;^S)F)#XM58`@RVYI(e7``Q*`u>i5oj;6n$HFil#sbww zouW}8aD(FAoUH`)wv26(`Mu8jJnK6Tw=Op8tz!95v0k4kmgYshLQ(EZNSF_r(oMC_ zbWc)hTx**{pp%x;AaY3|^ysD0tNt8c%;TEjH9y;KL{?h4ZZu6kqEnC3m&Pt1U0G$u z;8IZP_o{WvCzYG4_xU3zd8UJ}0G4Dt4UMN#%7~)p(DKA+aBZ#T)AtXa&Kv$ixHoR~FUwLWw zlQKZ}8~D|wx{^>D=7q4w90vD3nN*OdHs(AA-XgtSzRn*$c{q@^3N5Sjpvs+Swc5Ut zF5*e*8=Z!(Os^0zLBSVfFbVM!sCcFbXz5mK#D?K~rP~WM6!2+D4Q>>6IhZYChf;L! zY(C@(!K$MU=^BM%uUGVsAH2oO*f39Ayj6gqXL~Yk8C6!^p@a##=$vWb6g4<=Noe>} zhiTd6L!YWt8&_Od@#soN5JXp71s#*a#bULGF5D-R>b(_3V}7RBneF0lUwJi1*2{4SZfk9Y= zRBmH$%s*RdUEJrB$*22ggGL`M$E$nS9UAjAIFFRZX8@#&$9yWOIC5;}EANJ@#yqAa z35#lx&Cs_Rkt;*tLtmJTU_oo9-onhshwpl2pACS0WmU&rZK4OL*X{9F*s$gM{4xI9 z5p8i`MR2JUwB<}RY=ooe8y|IO48@Vn3@JHgq22ONLDh0j$gcV$1n5Cfe?s&$6HtbO}@~PzHY#qSWdUAyMpwkRIYq-g) z;Pw9p6IY?%Mz|{nd_}{pi3(cLX2AZxOP9c7G3cqvUQyG20*`HA)y8F+pnY`$KWPGO zb5a@-xttS|&wJab9qRO8CE6(G?lpCShSCYJU8B|oHC;at?C7#i6sb6G`S0x!Sp>AHRj~)!VIaxL&6@$ z>i*2qd8pX+DK(Dg3}!koU?I5FE~@^)7z3#fF7x7@;1co%dB=pCOq+LT3sSH*5Y-5P zBX+U4jAd*Ls-lHZ`v{E|0;8N*$uWSck$8*FXzrw5Q0x8G?Aa}w?^gP~G8X+@ovBV) zqdJRCKTKMmfaGdOt1(iZ8%dJqmuy{b2}tqnM{spXmD5LatzvV>yXU4NYcwsEd(=o- zYierRqfwq?Ut1Rvh7Rk~KQEd`xHm?s8UvsH1r;snW64S|T7kKJr#gcV71MsD8aQfm z6X`T+AjjV2k9AvYDW~14HYHdnwWe0A51EDYv2&Q6~L$f+hvv02dQ~wORYp6Jt;XM+q#tmS|Cup zK{QR?oP%n9uvhxQC}K8RE+E*G7;a2Zo!JNsb>H9VfgegB!CZie7EJ*8d4vKxPU0XX zQAFg(JD)%d`b1MCfNH`cw16$U>a1rgUrkv?(6aq^jAtmVo@{5DA=5z6q{joHRwHyN zrs1klo~MS`5d{1sf$K0{r_&g*0}q8V1`hpRq0(xpB_gf9u^2izc1&@ohC7TI!PO2| zR28apUCP{6Z%++KoirCtOfmgoHPotc7 zL)Y+9LQ+NZSOK8JeQeRs2`7fsCSAl?m}Me{@cKwmRZR}yBn2J+5!DTQe^nV-B0p2A z=?5=Nw^3`8s(8IR^WgoAK(%X=L=9Bf#Pp#bG(S345^f%9%}yzWm!!#efzBtw z_;YjK<4AMy=>_8t*hiDUFxGT#23R3uor02Gl5oEqBV&vRxXkr)DHH z@M7I`)EO8h0}U;^0s8*_C6<1}>(UCBjdHEp8xp920wq&Wa;eZ2O9dC5QdCErC2@(AfBA?gzXojVQknV_^^#;x0=ScXdI@#pL!X=1mu>CBM9CU}zI#L#Q<9r1nj6I4s+pXEFJT6i7exUL@a4wB$*ntu*!8>-7ddt;A5dyg{-pq(rCIH<*bnC zaCD4cT3~gMW-+9fMe;a>#L9{tW>#r)huKdDK3JndI0!JL@YO^O{&b13{Z?f$%SU0v zVkIC?=7QLPSilq5`)K{#@a3RFaG`^NtZPgo;%MA(h$f0e&D)JCk;lkL#YUL)hmWIQ zk=Ah^S5TvKQ-V_P*L33bSHqbMO0LKPGPd~yH5#y@<4YPiJIxNGx^j-DqSb)pyx4XK zj$P0t03VeR#+8JE3Rd^g__ZNu1cr~!7!KLI#NUxhiC~IGM;#kisgJ2KtPPop#)^>` z|N5nmR4uR=UMevZY2hNyUWzkjt}*?-sz9QAAcic;3H(};jVij;`{{&pvwLX%mZ+v} zq#~a2)d-bFY+&#C3X#ZI=+nA~gx{H9&5NxNUuh2mR;3YoHliV~KOeqv!V%1jE`n21 zG751t$R}PD1@Dr46vjA2;~@?Qx++$iFQLAeP*Dv`ZE0BLlXSwGJWyG$?{&&32JCp9 zE59*8$9e3kn#RguhtVyF5;V4JRC|Y+mrF6i(V!9hOp2K#!Pmv|IoNemTvX^pPd(oh>0PcWy>D7K=G zVr`5lEY?^@lCfAb=Lm{u_Z;B^N8tj|ghnhf2+mE`D`C6VOZfw zGBj0OS>(ddn?jwBquOMo2<@e!i6YkWTODk$xe|NZ4|-h0OTm?`WBW+`l{MBu!FzVr zN9%PMG54b2df!_!Z);)U^s?-JX>je?I zF-B^NI?B{u_o(2;7mYk2r>|;W_rT@b(Ka)t5K=Bs;gm40q(%C#H$?di;Hzq`n7=N@Yzvo;U`avRC%HD!e#2RohL6lPd?y0`Az4^?>JBX z(0TF==gFqqY+Lqq4(G`(=g9%*$+tOAzSDW~G4_PiFLn6y&XeU6 zB#&NZyYu9B=gF+|9j5_4Bv&cQs0ZxgLT+Ue{O+aji9tOcr#ea z>5-O-9|o%r2TP7I4!z;qhPCelUG4knpC6!qeh~k>9cQ3t-aZ^G#{vYG1vOj9slO^O z)IN%0J1pA4YCiRyh(`Z04Si`h;OB2XhKEs*tIn}P6KCkQuutBf2@(5)m6WL~R3_7) zP~(fk+K-^9T@gGc_Uxa^3ojz0pGaHQAFO6ow{y=Se;d#L#xiu_FUmcKAC!9zKPdMc zeo*c?{Gb$T_`&nO?brcRuv{m@fr`YG5^7=xG>avJox{N<{+rt0rPssC3#WQ8@P8ul z?>T5>=$hEUa&t{oo2r*4lAXg^2LVJU+@sQS?btb?7LKT}mB(v>r|kkn--5`sS*EVU z^p_m^fG!Xurhk(~zq?J#yot%b)gqs2i&S2T5#DAY+!-eMidOu$TSWKLZAOQshNSfU zc8gLicC&pwtU)*0nyYNLT_wyGrrUi7JLG$g6T8l$h+yx5#h>TJF+^9zwG3jR!@Ohx zsAK=)sGBDJ7E5|j!tnJSVNx*?0zS@(l&cFOh(5G9@8U=1*i~8PaHELdYY~THW8i^x zr%___5{B4!ifm*a7ZJ&pAn=DQo;z4ZGF{iAtjui|YWaIC(!HJ}WfA(~(t`cJw=i;i zjZY;ki=+QOi+)PX#KYueaR@(XA>`R|k(S6T4&Xmp0Qb;R4s|GTgg;^t=IsP$aR5JV z0qkbGd@9*l9QjXK>i=v}t8OC9sis9NyPF6L89{58%EIPnACe(@{C}1NYHd`eR@3-zwF12?VsO9f zu*llxiJ6iBe1F&CyNk{5NMJdglZ90pxG-#f-Xd1BY?Y5plX{yiwajy7h`o;;QMc2* z`RX9aQHd{Day*Fq3Pu%VS${IQutHz5fL=+H4@wo43GI(9w1?R-flN?;VnOAYnzUqX zF&g?ai+;Z|Y*Z$5($0nI`MQPjU;_2%GOA(OUs*uPaa4k`5sstE7>={!NSI*GqYOm^ zclkSu`>rtA92v(Q*XYFmXc6b=A9yMyJs^EjF;4L{p#F`X2-??zK?v#9Q1ccDkq+-%Y8I%DL-8%=zhMU2@M z&yVL#8V!2q-oI@&e>&24p zu}F6t2XAA^_uJ$&I#)UOV#y!0$T6Qox;~zNFP8WfUgCr*d($EV_GT?!H*cCoIYxDvw_*>2a4-BYnFBDE_M0r)U0OcCSmI|aV$_xA28^YAqeTgk z8)yH@aK5;s&XK~n}B^>m1b~1q#AO=AloI{0h4z5VsF)JxM=hNDg_EU(`3Vc= zApwJ#K}w{bwvZl?NG#=IO0b`e0OL2XQ-b}x1t#n0Z;zu~;gc590Z~UICu2(KK4oF< z!R3pT5TCXnFl5BJpOhe(9lYY{>&~IBn_v7Fc<$6ph&+l3=ufgJto%S&$t`0 z2ANWrFIq4UBGVY|$0ILfN}w-WKo7{wIVo|zV&U8?yJ68?xF-$daNw&J<$chr%iMxf z-Qd?O>K%GwNrG{gI3?r1ut+CGlF89je{E6S!4gi6rukcoX1ASuay0orSmbJlS=_(V z#%lJ)xV)jKFQVRkLglISj8X&z#%cdzu~msGNm}XhqPUj(G8`vehtpa*aJPV!gDkgEcn-^mIz*wYvQX|9=`2&ithHeFv7A3CK{i+*cR{V^ z*csW8>b%h+3lm>P@E4d$lUpr-9HrMlwid552x65N6aI9QMXx3tY&%wSVtc~D-WwB+ zdyKr9-fCmn06cHEc-~J7i7IQRS#eO9DKD~_PQ+oD%VDtMkvt?rwx z$(BgOsW&6Fpf9saYUK8UzAR#B52sT_Vop+k8z3bS^tam*{4SQHGnQ=1BD+WH#Yghn zXA$1blXu24e88oHA`7u}58HI%h-{>sue9jyl?gs$IljuGRF{~k<7G#+j5VX1EPv2S z88*$KpQZN5&TA2Zb688GgkcX^Vmu&nfs*{vr8NpG+i2J_j#@a6iUl5Y;v`O5xMLRF zgFNO3#&|S|Tqi7`gLW!IN*0<{y3-cu1D;7`65-BTIIqxBh^Ce4yoGf??n)q=Xj+)p zTQIL=ha)h4ryEwrnSdk}d^!q^mDXCNb9 z;{aL2=risjk2=N(y}botLWAFK@!g~4N3~5!Br1_=*h{?Kf^d&sNdY~?-(eBU%&A&+ z*P6YgQOlcUK2$eUpmHx+;CIU$tD(y)dcD!TY|-u1ldZ zrfZ(lt9bQ6i)fdVk97p`cU#1}8L^p~bp-kMTI9D_vw2I@|HCSNHx@Bu!q!lWoJd#y z4_I_}vGc!@nDtjqdxo|DgGDw;(*f2YL>~PG)&FTx-HRniGp{Qt#K-T)EXqkX-;+6B zqo{sTQU&Z{(=)>z;`)XfE7Dy(aeQ5C1@>4`D`m8Zhw8LKC9@dGjIds5D21Hl1Wo*` zl*}s-&pH?<5HDp2bU#HDnP!z=bs8ZJ2Y@ucU`eyzNhg~G<(DiJ+n34c2&1@2cU$qb(lDaTb&L%0HbIare*{TB;qKOq_EYLlS+R}19 zU=P3MFH`9zk>Ot~h$#g@X?2qzT!)Li`f6E-Kq+>UAS|&E)C~#N7qXPPS|4ZMkO&JI zUEJ;3=dO?5C=!84swYmluRYuo&$@ox@DP(c(&Q$a1}HR^jU>IYQDDU~5OkrcZuocm<9;6&6pi+VRvv&_MX$oE*}4|}r+CxY5< zLG4L!u$lZ+Q|W^i1RIR7?uO@59nmH;Fdj59SjOT+K&LFA zy(C4Ly*LrZ>nx1>rQ4`<#ED?0Etpq1Fkx2XM1W6OfO`}mEgL0*_@+pR#18k21+iC- z^myY*B*q(U4AJmJ7UV=2B@06x9j0)>I!LVpv5yX`GDh#Qn=NICe7?~_FmUt?6-$EM z{2DiVJtBZe@_CC~O`Lfay?Fjj3xG`#^~rNQ#IqIz|0-fbrY?;K=ve^#HntEVp8TRk zey=zW5l{J?MY)@)HL>lUx5)SN`2q(?EW}$al>4+C&GA+EH(qK!K!~S)(W2hPQ!$h6 z;)yR?#5+|U=XlzIMZ1I1Vofie^d*aw>kFz!e&=}Vmn~|}7`dL~N#AXe8Y_W32U}MQ z7rvE1QOXP$n3W(g*kPU;I$}~H2oW$oU`er&lTTyaAWReeVXIJH&j%e{(~!$YEP%Vu zvh=U9(tXsT+ovapCdT@tNwCWcY_)d&{T9fS%uP6wTwj|0Aq!zQPa2(6fFHKV_i6c~ z6U*?U7RY`+u;b~R6Qlfug|bhgV2e31$WL1!_p9X4#YO<19bpt*t3PYO>{l>pg!y?3 zWf!G#Olp}=TEwfk?}&RkpR(Sr<8O~5^P?#7X{*EzUIJ+gV_o|*7U?cQO39^Ti9c%* z-^YnhvaC_D)St7ccXMiybUK#&H!SkKe2l^KwjzC0l7R4A7RG*=Qd%S&EsdCIbam=k~v&i?djYXkUBs@)m z@fQ}xK8B$s!A=75*A~cq41}`eCZYaYi<(!1yC@~cPJ;0d76v;zDKx={_#?(VVY~ZZ z77W{JK%!bRX?7BUu0aYreQEdJxukA&y+xVRl4&R5ywswfG7@ViL0DlS>@kyUCxKXP zLF{KiR8P2_1ZABUMVOWJnaHRcEtEVD=sXd35-~Pg01tSQawoyrX5nB>K~K<~1mb23 zB8NO@GFf*L`r9n}eHuMW+?@pE4h!Ud1|k}4v028~!;-+-)fU2DD|vVljDr@&ekYN55|kqr3ePtw67wek zc)|iO_W5Z4);Ngm+vnqjj2ZRaA`5xMz?f6O9Zp)zcVRQkoDA`zGOPK7J{dY=5hKe; zX+AOaIh&dmKoe6xX;G`I474P9VUM;5VP9q71q^NF?1bjgcDt|#T6+bdqO0kD)4BR7O&Hl{{Rl{Vja5ta9;E?NvEL3HPhVB0GAtD5@lM zF>6V*SG}YeL^6!3g|RQhp#CQrNZkV2AA+b1d;aLC3ZgnK3q}9Ns;1VBu38Oc-koGO z7pamBx7BDkSkNCVW$Br^!@(+%K)c_=Hv$LikBTnre6#xOVfqfzyM{a8HhgI~Ggwxx zv+>ig_TzUU*YX;f*^el?yx3r4t5cn;Hj8!fF~EMON-4Zo(8Gn#m*X}+tHC1kvx_Km{sC%^7uFCa*}sq-!z|FcN&-nT12edi@w0jf?;4IQ%NeC~tGf z!UU6CR)I@Uue%%`isMiMnTD=FbmUe!$bt+q4OxLm!j;}#U z7Mq9#3tiK#d3A?6mS$!bQ!?D37(Q9_*!%F6uv3VV8B-t=&#hQ&^AI83 zTQLqN*^qCwIxUw+yl;U_w~z#p$Xm}WAbEU1TQ&vy=bKv1pm2WrkkQZ|kJA}?s(_9V zg`E7Lk}K*%ePxFF&_qw;qCg}v0?E;OtLTA_4J5Nf7h-EL5**?1Xs7jD&^(8;HI5^{ zGEPf4p{&81K#~Pw)luY;ppS959AabDtRU6c7+{ji$}_8S1ksUO&ABYdAk&Z)h(umLyh_YqDkR=lNKh+N9j|gh6B7d zE}r!I7*J{4M&L^Js2je*1g#AT7vKQ$DIy^XLjBYdiZ{)DPSI&-QLKTI^@UIe1#39}cD z)a%uDw`z_?W2<9z9U+Q@UJmG^#X3H$rd#6vxL|~O7ClHCvtFNE2ykTg?W(gm=X}{fLq$S|mn| z^rd8%Q_4VP;7I(944+nqFkQRgx^Vn>%5>plG}hFxBp-|o3&?LpA7CsyDvKRqTmE1G zNe;Jx!--(7SXy`r$uwFQyI5XqqFMT4OziN-VmJy{^51UrKi4Z)TTWe%#5Jl>tV2l2 zm0H=U);UBWhf~^Crol*b%!Pq|9=mqL;V`aUmoPqGFrq~4>bg}SAD-m5jPYxlVQ7Dx z#_)kltyhD<0Fa0n3gJNy^Y3~<%{4H`!Lglp4C=$&cdX zlR;+&IS!nLkTy>0I1-=QS#W{2xM&J*G=SLQv^$yBp>z(k)wW0+G$@?|b{hF7*-Tr< zdMN1dIo5D&SI~eYJ`GUlF@4X-&`@k7@}e^siB0W`e~-3NtM`$F@b}->s2hJTjcI-6U+A=uCP6nM3w~nOh z1P0xOW{IzQnIp$o*CjC#0%e6PD9HkKILKN$)@w>8huAte9CRef08w0R;dvAl8%Rd& z;R!s+it0ks6Azo%I6`c+?HwIQ!lR8Gk}GqDv13hvY(-ew>Emm5p*2D%iI1%i^^m?w zc05?XfrPSYlw)zOJd&3IEBUSf-(tIq7-7^ZwreVJBCSdSMFQWbfH4i@a<$CG%-FT@ zC>}bXWQSgsHb6brkFSce18TVzVPl$@2^(~pjzSbEH~L%J1jWc(%(^{XVuzkiJn=$G zmI%r89$i+4x?I!6GK6Fk%;JLGT~Cc-XD6kI?On?21jCuq(+m|+^zoMO64kzot9G7hnWAE5t5^LsB)gUl~ zMW^MlaeTXTc84wNLVVh&&4TUj)LPi+F4!Kc2RydB@a@%l;PHV(U(AT@Fx)}UQ4LBe zp0S6I7JNfllIM zKUik*jWA;agfsrLz@&OG4mcS!4)8H{t8=*3C{~+>y<7!ANYffP7duS8thf?syAW z^HmE=a={qpRG%#1^W9h`j_;aSk_ko^o|YHeJ@~?t)%Gyz<4+EBa0Nv*4#Qbv*T8LO z^&-l;z-7;L0t`Cr!BVWUyo03>OESPzPi|lPY!cfcIX1D;BqP)WorcFSu^p1V#cvq} z=B8evZw`pF4JHMUlo=<5&Y3&$m=l?6EwNG1+F$hHNp^5A>$Q85Aa?dOnjZ(03^AIT zuFxTUx0{U(DP}jT!|3R=DeJL$Y-6-)!FFXWyQ7nx#&U@VJ+=cUrwwNi8j2Jh&Pq?+ zK$vCAmqk+t8Cy(7+{lDXAQBm|HF_=@8!nu=sEH++Krxs`cyyj=^cO-&d~`!kRm-#< zhyf0b&kP;KI=?sQS%8uiEyABabZ)P~AvPE}dg2%s=)Oe&-KQ)oB)xwTK<`(eIB``t zf9jZX+#|N(do&9uTHcSa3aY)C>RNiU{dJO zX)2mv8Q`(O#0-QQio~Yf{$96RFnu|8x8KHP2oiHW*1FZgmc1ClhZojSHg^(x`b~UM`iA$l5BGP(@0VLs9ByVo-@8LDwMQ;(z!+gJZk2zHA~%1}phv2R&_Q(qJU?hE7lqkoYR1EvB8c zyJ(Wpa$M_o8)I7ERv;2~Ri|32lp1ZvsA-$Ij-$ZQM=VN!)o~>FYVq*O1FQiQ!qdmi z;FFGK(zed74kY2%v8NGUA3H^~TB(gCnXIA!;~T7`HLi{$!B=CDj*XTs+|ufRVke+Z zXf&WCgB5+R?6HB@Qcj2>f!AJOhxtkv+&RXLmEA(Opd^bGln=}8iemNdXePuF(EY*6 z(jz1`9k*fUXs{J}pvms+9I6B*^MX}ugoE#gvpfSvRt3k__2)+}VW-^~s>gb3BoB@y z8DT-=KxeLS1{a0ReWut>3$0YEgu;-(SjkYpZ28I%Kejph(K(Q0akI_hK(p*UfD(IM zdIUEeQ!>V)G1cvSlM-mUm5c2^9dV)A6swM}embQnk!368s48aS(hUQvBo z`$XKdHj0^pDw*TxG-qC~(j{nNGCbr{h8ijv?*5!8CRYb_7!fCi&oOndAd)hBY;~#U3(>;$}iho`}1G=i@=oca=5v zm`emd4NmgH?uy`btQ%3g*ahDRZU&&_hlniro#n%4Ly@r^N(3v3CAoxFJ4a{Jq2{Bl zPNQh{URkYXK}w#XCZ}7AtVsh<=ZCYGJjKg_bA@x$XOEqF+)!t1mow^&Xd%RuEO8!z z&UXrythHOwC0?hXkIXD{Ktf7}`WaYHsEl1=9a%pfdL=9D`-OF5uiWuYY&wm2e&)aj z=WH~lttO6A8wQMTdZW|{FC;*34XI6>c8_0QSq(K%$rOEjSVMYGT|{#Z{X8`zqq4C} z*CVy-VoMPWuYLT;bm82wZ#rUdzA~>>kdmQc)w2Oj0u6RoW>oK&V3HAy>6pib@18U&6}w*O)t!ze zSs8Wm#Q5xW5@23NJgys6%FalDNk+J48Y(Zk14%U8ar}Z*XktpXDio;*uRD9TP^6$F z6PgGz$8chI>{Nk$llN#lFeEPd1a4(|dgFMXaPD>r6p2mkh_KP6;DW(XoB}dLj~#p=35s^Q*oKl^ zNaMsMy(L|E-IDB@D91h0X!p$XBeAn2kL&>FKvHrHiKXOpUhhn+d%9Vt9Sw8wJ$7Zo z&&!6CT(Ry?TuX(6*mLUEDHl=DuH(ce`!brz`gq)y4Y4k11F})TQUG@OlLR=-vQHU4 zkw~u&Ljfci2+K(Z=Hc1+ZqQdH&LO<^sp`N|^_YI0tquansRMt$7WAFnC6e2qPQ4lj1`($CTb9mQB`Vo@1OP{|m330%F$ zo2`pY_7;n#hPTJAeS0fw;z@Q`oZ#$EAWdt(%|COfS1^8%>2rJ?O|lYkt5l$&QFQQ# zpM&@qx|otJjn$dIo(<-3p}{&7pQtx+B8P&KOqA8+8&{FptY+eQ*hR(Qtn73=$xbzS zES3bt1|`O|)R?Ww8*mZKSjs^&j$H{e0q0|eJM*5tEHkqZPBOb)dgAL(o;Xw~cFqQ~ z(aj)s@7&wSqmZQt%#u9g|AFoyNvxnGq8|T`H zkk=Y7YIV|DY^+Q!>oneBp7t@M91mbEkASFu{UBdT=TYapA znSE~Tjzy$0iK9f647EBQ!^gZ2ba?^8QL@+3fb_6Le5o%oO9N7}WTP><*;_b-_GcNQNTdBpVzP!|EQfIR+Y;%#lAbG#a}LI*O+UTMEEBUL^qkSdfQ(Y{ZFUZy-zN zw6w%)Pu+%5-`JtWD25D8GGTo@t05+-m69e%MV)?)aD zsFEqIXK^J$9QK-TTNu?$l;tzZWi4FE7#m6E()9>FY4ub7ie?a>A-ttmnqni$nTrhSs#WN+dwZij8;J zZc&t%B$y2|dar}(pps?io4jwMMLFko_!ar4g)15JE}E=}GXZULF)hK!d{iw7PO{-a zU9maT?;yd5X~Ni`KFVL1@Df!rWrJgG$0PV*jz1Di-$qo9<4H!E5|3P}n$@~8B{De4 zhWGSLiFV75?deAg-ptECa2?BZyW5B%BW%;StmP_H;1J}`ZxK&Ks^IDP)CQN!3q zG=iy#Dr<^4wafS9u|sE1pF48s^r^!J`_pm5h9vBDa47}GEj}quou58p2oM`0lL^3Z zNAmVmeo=S}T*(^)rm)^ePD~$QW%Pb4^0?B1lXLW8K*I=EVt*S~^46_jm4OIHTh?co zuEYuv@KO>z{!me>ez#X_v<)3xN&GQUC0`6PmGvp)!S@Z0vHkc6n@c>&3j;rc*U8hT zrk^ml#jXOyaN~%QANB?ees4H(zzpZH1NInp3{Y~@EjWGbmf9m#uOpXjfP9RP=L}WH?zsA$OCZU*VZ0dPyQ84k z;qNFW<_HMGdB#ZwDx)&7N5UfbC@@(c5d+xLvp>dVi~$y+t9ee1+ z%?KU>Ne&dl!NC(EVh@A4@Sgasu-)JgAA>*~?y`kqnz38ez}W}-|A~9gE=h7DTaa_k z?xSd}s&!K|<-B3^u*uk zBpSG&3puo2bO8?Vp^N#wCtV~OxG49l%Edh8^@0B4mb5SStFQ+MMzlsYovgxbTBAk* zHtH`O`XHg()L#VxWJrBjEU)FryN%Qu1=uKW^()6NbjtIWqJ^}nyAlmtl>1cW?RFK( z+-IN-G6ryA`6Ei^3(?zHUV#9aV-ofp6pYZx?4!+0;wWg)hm@pysD;$p$kzbNPArnW!@GBA)E=(HDR<1Bz_gKl7ePW6a9 z8!d32(3HM93r5JF^l`V}N@XvVwJ1YdF%uYpg1f|KG- z=2TM!XVYuqlrAtCcg6?>BG{;oDK;;pO18%+jfksg{KNRWF#6$WJ-%@&MRNQTqw-K4 zt@a8c6Q$K!D-8vF>P1+qz<%W9a=Dl;1`7<-hH3`65jmNqXr_2l`Ffh?Vh-xz$&lU& zJ;@P$jK;!)Hng}(G0|ndbK=tNFH{whOGcukL1^%sHbos>#V)Ev>oz42!AA2ftgZcw z>EKq6IMJW;rg* z&Gw?&x9+=KP;eT(=rP^MEaQsSdI1a^l!NEGM)VQH_n{i*QsgEyGSBfAl1L*NfkJ2;y>?8Hs>gcU*1JR8So76SHzXuAL{b& zuRpZ#P+q1#q93FUCBY_Au+7xJ7OvNT@k-aqMq=T`;=#b*a%~AyF=99i< zaq8qxawL*<@vHk0sjh>R$Fa&P;@XlcH5wd><1tY>pGSD373HF%C2G|K1>~V|wy}dg zZGrybTwajef!1II8xxGQLd0i0+gy%$)<*O!$sGWB%oR2ysJ((37%n#p8GLl{3N<3w zOkYhNgYOm>3byX60R|4rbQ_xnns;(mx511~ORjkW37IZD1`hh5R=%Xf{fh&0vAQr_ z`&ub6!DzLF^svCgt={6%xA+Owk|WPJlR*O)dot$Y z|L}%rL6h{${_V;V3@n^OwOO2Imh_kj9)bfC*FZ3-o1TS2NxL-=X*BSlE-;yT;;59Y z>nSEnCvZ`s>)~cPTf0-ZN$;^Nu4Z)B8Rejz+Gis|Gt>xr<{L0sQcYB03o;MgVZiH0 zL|JvxszQWTmJRutcMel$HiZZ_)OXVD(X705Q|ie%gC;8i5L~G7#KjSUlf6&Y!zL<& z2PW8XpWK*sBQj2HIY4^tvM7qdOuIG3!n z8&mk0VB|4{cp5m>vfY>>gbG%Ug6-$35HIPNDp8Q_qTnztn1zL@`t)w$3KNXN!u+&< z3tOmQ6&9xF_hMmz3uekCaOPXBPTrHPB{}2I{-O?pY#5-^oR9jMd(^3usz|Om3%~;h z_*7a7pHw?u6mt%{AJaKYqFyHZ?EsI92R`c66rUQ`1V)0%emlTrV+DBviILVkPF93^ znY~##TJyp4JI5Cf4|av=(lq?BRRtU@s6&C3p$Q#ylI&%!f-Han3D;!BueWO2squ7G z3o&RMz;n^p@cv5KpJn!*ijK=KyeTu^e?OR$)L1YOv#smeeP4oC8Ur({4AV_={l!Bk!i-JXDeK)|(Z zNzW%9|aPiVjs0tF{~8+Fq)x!1sA_GHnl>}&O0B#>~IAW8hTnjCvK zG0E1-m93(qDeuhrc!JUp6vY7W;F8>Ude$^gJ#4haG{^w8p&JUM{9Io!EDzZdIe3VuexJFg3)dv z^th_cHf5IJb{A*4(jfzC%bdcrzOMQ2#J9L3*7=%v5@aM zznQLd%0el3H{Ts$48Ve&JZZ&ll4gQ3*%l*|zyc2~>w8qp107&;*Ti*UrRr-80CPnE zupcNSL#;5n3=zJoDO@-8o76H458HN5)J$1!*MHb;CK(%q2!h^-N?EVF7;a4_0pFfv zn%*wTr8Q9W&`=zd2yveUhS^DPkm56#U?mR(R@y8&pX^iqa6P&dH96UT#W)2b7^&JB zMm`#IzLCdhq+3ncp1=YNElDygyDy3{hb4i+OGW|_#T-a*QqL9SbY}IEgNrOyYif`D zV30RZeUi(!v$&l)M2qBt{M?{UM(Z11TPmZz)06|q5<}vn6zUqi`(oX5jh2XDqzKUH zPu+$7n=_tFM%590Z9K5mHJhFuj;^QUzyP*w&2}KcDKu1^=c79w93R)P!UJ3Fb6Ffe zo^I=NYcw#`b)|a7Tg-a#ei9LkG-x(;MgJkF(s5DP`57p1(8d+Pp-1TfLncSG(qAR;g+AW5@HiZIuorIBAp?(D9&n z=G<(VoEFPaRHK6V2XW>=As@B$_O{xJ-zj5S{2I{zsC+nc7gZ(4sTmdkE^JWOFpAjA zQ7AZUTf+n(_$bN0KcCRi@P3j%8LQ7#inC6H*+9UjF&hVe!&~KWxz859siE%Du50RN z=_-*gE@@>E|HWpKkYHoaJEv3B=Ho&iE)!5I8F$_meE5k?7C;0eM`w}|DGs4$GCE6; zR-oYJ=uGnR;cI&rN89K7$47!Y8J#7#1u*!z@0R@Ta4Z>}Bxvoy8INN4#M#BNp#PdI zgW6nckI#}NE62tWL};i=*5RbXGe`ho-G&-G{^e*f{USkXAi>Js*VUBzd@p`TkJzZy z*>%{_1eo9rS(x70-x11owXjA6C--iyu8-X__tW04Sy2Vp#CS;O&Il#DGAckYDv#vY z{?08WQHAW560)gxfJIjg#bFl86FC~{gqc^C>Bz9TEG<~rmlnv=;TGnM08xy|LrkXh zoz+5W6kt=1OksQWOCCBAfEG5RUYAcJA8x5!h7dcsNMuGI)?(W*kehP(`sda8hOWyI z@W~mp5WK+wKG|I1`yoTp<^goMDuCjJ8r#nwCdV={0+~Ui-b=HH8GO4hNsb0XL;?-g zqOqCc;%;>ReD_ckM>56=&{RMnhO_-|2K3fdjc= zce;VKpSoEAfdLxOoKY_|2ROj5G(dsdjkrzCAp%_m!9cx$D%-msJrpQhar97yOsRa~ z6_Wi+2$?}3Gh3ycU(*d|fdxoutI(%b4Gl-DS1>@QXw*Wdlev$n z{?jraxf&!Hjm~03HX=B==czSP;@EX5-SfoA6ckt}yWp_cve<;l{K~9}&_)G!T`Ra6 z4rQHdS1Sw<7-$y8Xm_^qDU$1vf*Jt{9F!q392fHy9ST)U_@AN%CYK`xi3A+jXcQP= z^B9w(z$BxB1S`eV5!S=eO0LFD#?)EN3Kr~PojvC6It$ji?mQ`{lasYP!lYf@0TMLh z$d%i8o5-%#W7$Sa&Ok@h0aj3(H66+%Jzr~WG!$5D zZ7$~1vAdqHtv0{{5Bhm7IP)x!>2K4|`-tGA3`tc|!sXk=mCTStic0{3k!H?UM7;vpgl3V?09db%6kWfR$19OP6FkW)R z9;E>qh^U4*M1j@y$pmbQ&RJw{k(yCqxy(LnynH#DCXB|d4^~E5;9=W z#HxK}gdHfN_ElbDg48k}_okxmwKt!F0)=J1C;kzD9bs zP9aL|qJr4c+S+#+pl+|Vj|*}dCJU`~*_@YwLQfvg)U3IK3;}37Nr%f0`6O)TMB8L` z_EsHAYc=s22k5lUnb9dc5$+?I9SlJ;2yiJ|&A5EEhX78_-h_Y^3Xmz@WMm39w%8&g zI{H*Fq+_&zRRkKCjO7n|vb@0oy0N^Q&TnOTJD<-{3EAg#^gK{y(p_G_I5iYxr_8M3 z@CrCNat{?SF^Dp*bqE;0tqzX;x!cxuqVCjdTj}sEY$#y4mI_d`vy=e>zNw>hYOfpJ zwDJxH2k54)QE1g;TN7wtqKqq-20hy>c8bf*H6IBeBkJUMIaIS;K=5hJ=*aFT)8ctx zK$*-3XtHPYweYVJ5o{d#s`{eXxW|6Dxw>+eTBjo>1repRVB@@64B;^Q;5D#uUfsF% z&TC-7t7{R;fG4pZZk_E4)@1%8QLq&#IAz(Y#}|8hyQhM+tBoyK@Nytt*D312_|%i> z^`_j&W|NLenyZyW20M?d)EdS>+ezlp-Bo!42@E`-HwQ#Y(NA*QY zFE^;k=!=5t*l~@DITZR?F}o5PWb~v#cm)LMIUZ08h-okDkk=CnigY}nzP0)Si3Jue zd-a5O<)NC%2AeMXAe96JAA6^Yk5)pGli-!cQn_?qEXrs@f|FK03C_dOcqtEDPp{i; zBGh_BdM<@{H29HO_$qC(YEEGLkPyJEk+l;lgq;!CKc0 ziga9awyhZk3LJIK;0NwLy_S6or$7`ISZcpZPdG2@LFz`_M;L${$?wE|DV-$oFK%e)7PB=iP(ueFTtShkxQOVMeX;7hoiQ*H()FM8K zu*mp?dIrO=GktdJTz;PH86p%0%GW}jO=nl$|NbA}`loO4|Nfo~w<25`5>(VZ7u1A4PwJ8+_rdCBdL_ql$u6mx)*ynB<~$`M-6FZ1zBr`ogr|#{T*{G5G&M6j z$dG`7LPvrScQPnUa03&pwHq_l?f8z9OwD|R1}5snq<$ymb0;yJ?8KVMG$8nB7FY6} z7PquJapG_$)1=LuH7Iz!x_jDt-8G0{^lA>>0JWy0%w>D&SaT{&uu@no?R&o56ainG z42zo$Y@veL^SEC-Gou~7Aj5&H?tImTeBs#J_Es7R40Y$bKc|fuve4Rgz6J^$lu|Th zv;rW7N^BbG+iIs_bbTOAw^O#^kKgX2K$s4F>8k7(mS!ftgS9P9|%2ErAX&vR5< z)48V4K5sDAZ=Tu>^bT_ zvG(qEC2Jen*J#kCZa0BWqHVizdWX7PDi>}m)3$C^V7@Nr<-?J)zp||^1_~Ut=eN2A zTbs6?-+}{IJveo{m$rjbr(Zcf8*W|EMtQnHP3}TUHpbPqrpwKCVmn)VKMQ^sIO;8hR61_Qtp36Vmp`GT)tmoo~<77?*d1qKfC9Lz!XAK%{b z=*$>}!2*LWYhA)z*1CX13A8P14-}lna_c2+VRF=JZ8?B}gZg%|+_TD}wrfv1k%;YT zG@Iq}FLY5JT`aP_zc0*|j37$&rR9EYBrtIKnBQ01H=|`>5ma(GMnsot?Uc`DV}g=~ zyA>r*iSRvp%jv>hG@1;Muf(-EF-Wl5iqeX}N#BZEn4qNbbtRQr%^cuNR{kdA+Mpoi zim40q;mfsiQfk{OqmjVC%}X=zYF1GvlS4GphHA4{PZSXF>yqN1u^>b6B-1YqJQX1L zXb*#>4<6G`TTADDzvN=}3|ioVodQLRU9V3Px+Vj~22ukDE=q)WT#(0hV97*Ck`kz3 zmRf2ddehRtfr}%rx_&wf^poMeUTYYvp#%jEj#>@JO)-8NXxPcbeZ*y|K+NEQjnZZ| zo8@ZkQcGsH%c!4Lq!uiQIX=*8y1NmQQ@U#Xwz~Mlv!%T$fhLY?hOM=;{XfYfN0$5^=>rIBzw(I51x!wpP;h3nEPbOR@z7gM9@*D7Md0Ff<{5K z3dD0l$w0IWJ0ZGP!iH?(^wuAB=M>A3JUwYKMc;Y?GO8!N(6^p|1ZN%Ka6wXbXB6Hf zlMHYoQGkyM=Gxzfs!&^h4=k|M{g`>uV?QPl!Du-ezU$rFA(Ql@g}7+4Wjq_L0RREW?iIk=1T)CS7u2%Npq zmcu!Dqb?u);4vk6g)VJvX2JRT^s#l?w92t_|Iw5FU4R9aIzBN^dW=sbA{d2Uy~U8kC1S|B?tAAKwXOT&^rG4Wk-Nj6w>27=sMXS>J00vjJfkajW`+94-4DN^ zdE}Qj)9af$PZ>c4FP%RVeq(Poa%K#YhYsbEYiLM7p2L?Q(7KWn7CH0=7u?^EbNl)y z&%DYPKw98u2`Pemt-ea#9d$=(DiYX+)@Gk9i|ulLHN93FmiK8>3TZG*wJkR@H2RhZr=YCB-;-Nt>QSMU#wjXZTE17!6+W9;!>sbv3d(osf>qC3@3tkUT zYf=x&QZC6!=7hsKxsYI_J|w{CtJtCsiQktXwZa8rsgT< zbb_J?6_X{?M5N)sM0rP>X-)ggWUe+jbKK0O0l_BhS8kkqS10=^H1LpbsI;OL9%{61 zSM8*4Xiy4x;Ib`9&-{z4x>&FR1e)mD63$M7?jG`^6FY9_HY@3X>Qp##bXlmC`%t`iDLxBe_yN1%Uersq2 z2sXQhdR3-N4OL)Zv1_Q=|4YMJ*HLz$J>i?xgaNzM69opl+4=+us*65O3E3?g8REWLH1MF6-Ji`DuD(GJi zcc!cHXeo;{d62oM0Z;&LWLL*%x;LucUG@qF@TMxdgO$5iMSF~5Ku?@((cM8A0g_T` zkPFdk{r`67RwLRx<$ccR?moINgV4VkJuNniJz0jyIo9IExLB-d-=DRyG=K?3IMU;* zWvTuDWwTmS=STmLBcAl&fB~#ATmTPrTszfc-!mk$s;dx<^bXwTD0mL}0;;5)bBMzN zgC1N^4v~{kO82DAR8}sRov9*o8%DZ8hdAuU!3|nLU(6Toy5;0-=PHD5fM6(&H`X-6 z!~Kgs!AtTr>dayek&;gVO6_NMa?QL?`b6Ip0r;-XhfbO=ECtOzKTY%pOi zfd@7&AY$9BhP%t?LgVl&3IiU8#pBJ2Fb}jk1k-4J|c_>S{^Gqw1I25lT|*!>MV-! zb={}=Yj253M_nsS=t{F#j;?s+OHp%@(-Fzk+j}K@$Yx5r8}mz)o_eRw$VS?7zm10FNquWteK!TL}hnFkv#J4t+>6&jk5!EL-pCFFB z@Ss4$gD_3=)o3|CR&lK0NqU|TkA(#yZWb;PZeg_xFKNbRK0tz&yChBfbwIgvz-6Bn z;{btzoil zOcdJd1-!yk>7j^gsu~9b+*4};Q`B-$m7K9$1t=;ckkATJCZYX^JX}PJkxWT9>oIw7 zpyRNO=*T(H*8gY1WXaM0lzKaBjA+3C-4uyIcZO5Rwh_g*22wRcFNIE$8XTxl8^}8p zC_Pql3!LB;3cyW`Qioau+TY!4l#LW2aa&(|61(xypyvFW{rOcHNDwAH{Del6>*=jE zCKOmugt`*@cmJk_RlgWXutiL`O^rE=Ren=Cdg>$HP z)(EO@iUBlmQH`^ol9Ll{KIw|%Ix!SjCRZ1r_?a)Z(iI@tj!b(XeH zN5uE9m-8_V;zda%!hN=BNz3Y|VA^X{2KGQ@s+@6>$Ffdg$V^}{NKI6-tyVndK z608)E==wOkrt~4{`mIgXiaJ^a$TWlW-R+JhGJavuaXS!C3 za%W@{3B*hRNHEeq zi~u8D+vMGllRT(Dix|k@rv;_VABaMe^(4$^kbuuMzQXq-&}3B8L?Yu)8rdi&E;s&* zs2)jQ5#g!8pbvX@)&~#Bo_nQp8f`M&l^_EqIB7_A>DiAti_DP6E-!0X#eO8s0CX zr0wDyvV^#GX`<)~gJj1T<`Q_&iyeld3ue@lzBb5IK?O;?Wr^)c#9BnI+FFx9nlsr> z!-_b$`Px{awL>lS02GWxi8-x@JLE`a27)@+qYd_B%0wsb9Bwi#6U0_9kh?NYm5H_! zr0tATL4l+yn{uvzzyJ%;@hB5{^;R1TX%t}7VOVB z2-gP+h<2Sz2K%ZH1{(a~lAxFFu_S7AND(dxdhh;9q5_8ubxA0va6djO01f`yN7*mg zKEw{@yZERWJ|qcSqGuoF2~pqjTGvVErJj9M7#&uKO3`!6aHNR(DCfO?TSgEZmI&7e zYCwJZC|d#p4gPRR&`bAN5;Z!csC|?p>iv}j2_bun+7fh}^nAtV@kB$ZF8yX09hQhn z5pWSbN@36;#Sg3A+mV*u3pk3i4#7;6AV-!!CGA%h$79s}h%dHZRlD>fF??7hT2D;- zw)?Xl>xn^!6w!K8H*s5#9?PaCfGp9np;zy^uC`!#|(z4tKWBw?y2X zoD|#8om4cIs}o`YzyRHsebZTh0lMGxO=kguj#3!Vee2A(WO9{H)RI60kyUE+=;CO9 z`*>%!r&6;3K}VCPm0l}#ZI?bFMKC63k>c73OpwxQh?J79KHAt-c z_({*i5*5Uh2dyg^Q-n3`;lu5-0BLd-xq;Mz1m%xx%G1$v z!@o-#U>8MzK6$WU1APP@qEOPV*8XDq>^GuPC$qo}#0m^Fc8gu{lkIXLvuo}B>{bm3 zI?-Y;&i8)x+kjQOv{)N6M*8b7`zNh1K`P7deD8Ptl^=tF#x>~gXwuu8mFj5F3KOKF zWs=2z7qDlSmT5tPlIBIM=Ae6aVbSD_cTLn#j#2}aw9*0_LI_Xv)pSDV8Q=9Ax zfw}#?>&b`u1@x&_Gm= zi-zVA&)mi$&SWw^UWEGaeHR>JSba+1M5gvJfdK;zEo7?dC(Z=1i!r&_tU*6>QVFQ6 z(2~6zH+edem2R6BzP){D>41XPZh_uec^z7yI4O@NreQ{J@S2=8j+#(GK@Y1!=!r{V zw)PdmfPsb2r`BDFh|9h3Ti(Ta1<`@s`r3P!2sp&BqB{Mi9+e53w~y)sWSp`bk7jaxLT5@13CcQ6 zPWNDPe&|3w4_P|7QaDkkB{BrCI%X{Zk3)r#+jq2J+91SH|Va_Od>;okjB53 z2Q~DdF(HC5q%n_*12wG&jV)vd;595V%)g5w?%J>vAn3e?#ZQCkc5PS!81x}+Wsac- zZRsKy4jMXDaQOKPumq3O9R-~nqq=K`3q-DTBW3^iSq|Zpp zMg*Z1Y3axPMp_aRq*l~#UZ8&XWOOY%{`OJ70}5Izz|(K^9pJgBAhsea{YtNqm4J*> z_8D0jN*P&M9!Wp%F|e@!p`jI7=%-%iZ+EioBZ~+)#PC`ydFx;OR(OZ@{jBEJh)smO zb?gewo}x?{6?7V}j2f4dH~?^!~~f%4otqf884 z)3M(VV z$2fYK>Gm113Jz3OprH>n5;dWHpkcs3Q?Hp*8)$R|odnh;CGRAP4uW|1H)x`Ow zfS&C=iUkNd%SG2up9s5lXknECPpax-1sY8FN2)TEU)UL~M}o9{CdoyGrjB6)#o5iU z1~5Vwm_6x6X8=Lx)LH#Bl(^|uXC*Gkol0bKDxy5QRU#mQ&{(xm_L+Lx%a1ic%h&I6o1@5+7arsr%+I!u!h`+TVD^iA8(xwpKKjm$klo6hujV* zXz9oWWS`v)rpbMW(ZIsquWpsj>F!ovrc+SR!I~`O-~TL%r~PE1#sZ1uEBJvbAVJjL zSJZeQvwR>e&h9gut>8dqxh1;PWi}ei98Y_<1T+v?{j+rmyf9(={@F$Zp;ax;7BlCB z)b`avV}Zo#9Myx_bna|FZ{ImufS|K#;o0VLwO+bgPuthR8ZSV0KAO(xDA@6hD6jTp zH6F<7RrW)*E#QjIo~5zx^ma5mFa0EIa=CxhImOT+h-Knxe?nhcW6w=B5V88|iY%1i zZQoaWu+Y&r;p_PaFU5wNYEgWMgtQS(pSak>9V*A95<3Ir04q6 znnz-RgnXEIaI!34+;NFL3|Ko>$*xf!CWJ&KF zC9?oQN3|WAQBWQj+$U>$oUOtGnPoJ!xwpUp$i2Tx_N83wcd5_LrLGf zWuJr%1b~uxh7UK>+2o0LmTB@xk{s;mdWgI;5-Fgz1w5AOE^;3kmq& zA^h!w-K|rBojhrUT>Y3=DNd^1gL}yB zNtfi1G(`tcu+l(5vij!|CDUptP7Mi0%H&DLfa^|XEmD*Q6P(;&c6PT9X`d_;^*sQ&_VN$B*k`latuElQ z8)L!GNOtl%im#epg=?C zG!AKkZ#0|!P2&H1syv)tu>t|IvW`J^uD3`YK^Vc7ms{|4CaQ1byA_0Ol3k30FMuFF zrR|u(^b4}_B^`)QP~iZdJ(R**O6^(!36&9M*5?b{{UbOVxW6kxMY zRoLbAa&)`5naw=&B!?y;5(x)3?k8$C?=0!0pNKLkD6p8ibnXL;7 z4)z$N$rIXJLpQpLBEPH0uwa1B;l}<^U*U#90yvAlPs6UM??~?|x&;Gtb`|x{jx)Wh zs}Mk7;5fH_z|&>4%!kI0q7d4R|H8N+=6c1Q984!q@Vjfhl1Sj-_IOZ?o)vw^H~~;_ za*X2*tCD?cAc9sPK;^bh!{okVLI(;gTqfig>p~H=Aek?khSCoXAgE~0Pd?$QN7rr1 z&2`E3+8LA;FsNx&olmWX!ybP!)t<>;qeBR;ny0(x7pF(V)BWwo+sB6|TcX0lmM4x1ZXOqzQ+tN{XIlqH7l)#fB_k_uTFirsQJp-N$2)bTVmMGyn%)wFavA%F zTL(g~q}y%M3xJ@LM%>wdv@hobI%%fiK*eM8y1Wkdk9Hr@Z2upHZpma;lWsL6D5Z7> z$6xKr3}h$mG#sd8xlvu*B{wc~>r`$41f4YI$?5*l`PRb&*2GRtRfl?RCX0Pr?bX-ZQ3;;=Mr+qeUz=f%LZD;4l z@pg88jAmiy_d2w*8ZfL`uQl=fI9?Oak9)0&fP+>%AM<4Y%<=Wf@#*z=wOK66rQJ_! z7y$G5^vNhPPnFEp$ayM(0|JitzBU#nUwEznPy#-X8)ysfBnRFYp1f3{KVMz! z=2??N+)JLJLx|)eL4()n!Tv255@&O#q6bPcOx1@Lg^d(o*r%AS9|na4h6kjBo+6^G z`fAPd5Z=|O$-z)5)|EsM!T4JJ{LYilBpvN7TvMXTGMo{g!NBpR;CSMk7nNKNk)UBb zFuhwd)oXJ^IVIU**0b=y#+6!M!_=lyi;I|CBv8Cf53KBwH{MG|Iy|^=#(M!s(0z}e zjfZqOh+K`6bdY13I-V6Tta<<#Kz~<5&kLDQOQxEG$c*9uFG{&|q8%`!0N5B~u`Fdq zuAMOyj064GjdK%DJ7@(1Xk+KqMot*CGY6vp`2QSjCizb9rhL9GznIQxb?WA}p!1|` zH=&UL{F=Fg_qLpDoKt0ziCz5-s+|M^{woE|{tN@?Noz}V8wS{KTy5qwFjyL$zFErofrdHiOf~}wy6;?%hrYe$e{{IIr zLl^64fosJiCH#<&ELN>{{3xn zdr1pW{-6K%=YOZEB6aKfVL?-Ylht5!I~+~j)hP|FfBehQV)})bv<_oJ{SfKgy=J}# zQia(>`kZtX)v5 zYuo8I!2o?jU5gZOBQ!*y)2*>kLM>1mjIV}Q`bxVYO^$i0I-rs9Gg0Ub{e!l8AmWv1Aff%=hUAh8c&NH}T4m-g5@~Q| zX+jSf4)+z?7+s%$_(Nxln|su>p(>iH*A zxn!x`+>hIV{YjGqo~Mys3Q;^lb7 zVW{kr8~XpWt%K+gg4`&CPzxF8PD~n<`F2nGu_pb;9yI7_uFud4K8$xxu z>J3eF&YT6fNypzrDNsR5)2bk)mFTp7b6woh$SQEXW<%VbZZ}r}aEMSh8~d&0vUH9+ z?$m62XwcU+SvieW;oQ>NsV3KupsRb@8+S!pr=C`!fuwFOW=yo6I;-b8H5VHcl(YuG zR3yqlENGvd2qKa*B~29Z=Op_}Y7jOZc7qcoQ}RsC(nZXi0+yZtlg$ivy&gP zFhN)+O;(gp9qJBH?Nt@DosuRVGRW)ZqF$j<9u+NZlNHpRYOR9{;<`GmD9=080jFT? zRGn;4P=3E^D66N_#c)+_mg9n|)sl9^dx`yI4zQ`^MDQVqWpqy2ghylDj4p9OTsJ6{ zvltfs7_5^=7N{VtOL|S=bD?9g{z}>g1!bKI+;AFl{%pD|=R9XBXgj3>U0_hx=`ntz z9v#{Xj5?*qBrIs_xPqQ9X}CmfYBF8YD6Mp+P&);)A#jLLj}Iw1eOaz#Qm)hZ5P+bn zs}yG+Ibbd4GJ5LdJZw-<)@}Crl8wt*N8%p&Qa1xq*rXkemP$7UMSyqw&UoQxlv zs5Bh7s2V-lB6ZuzLGn%lal^#N|e9bhDO?JlPR@jyaACa#GiSX(F3Naw;K%mmnJ{ol$omlmrP%igP?I zFUwNq0Fy)Dw3-SNq%;KfNGH>0RQpBkO^!{{v<4N#G*Iw}ugKZSR+9`S)4UoKv@{Y8 z(Uz2hoIax?)r8i`gliUijSV3}x>N4IkOzA7pt}YIEv*Ogbf3=E3Aw|O)0~nMf@#%l z=qwSO=GCVNRx|rqgB7T*)TQ;`zx~!feT)BR4 zr3~rsK4xh`h5$5^6@86%06420k~xTcQ)qCA@#6+DmXvy8S0v4moK(vfr6zzlP3>rT zukFa7Ly)G*N&`^Np~)uQV`Z)IAa(8E}!!fhg_9bh!)?;Hr&19^oDavG<4h2XTYh!hxT$l;$X3$sYY>^*lJezGkFr`toQAf>igKOUC_&-IUK%i?(C>q5X7$&p!73kRbq>J@6W>HKmh9gwMHq6cWb;d02ZQUsLi$uF>d4`wAHXP^u#!CDOnFE8IQR zk;cyxW?3v~7pf?dUWGCE5Qf6ykmPQqOtuKG+mE4wI9wqEt2uh9kj`?BFnPfAy^uR5 zrvU3rT^}%@rFO&Hm0Vt)oQ(~-Tn7+FruY<3=+XjjX;N}T-N*$*kkK9|L&j$oh#H&> zgqw&I8c4`{pHoa~BGff4MB=?6f-I?(S64%bAf#?G@K`#nyANN2kf5aOfb)DsUByes zrpeG~?Ow4K0R=6&0`HB$e*C+;f*2}@XD-$6I>brZOI4;O3?v^ik%gK^nC}C;^2s*FL@>AJ@y0%%32tuz^>G5>z zts&}Ksx>NzJx$ea6H%UBHPwh9^h%OOvT|8Q*OF9#p!4h-%ZduGXjtVt0dKKg5g*Vz16l zrp`oT*E*{JLFe@@{ItBfauw~`yI8QG_A8PTs&uYM)*4qYYM}GD{5wLrMhz7xbo5-p zm3MGWSC^m>LFiQf1;H zFW_O5KY$5R&%c@%WMk~==qgaqdQF6mQ5OEDYZGBSka^<}TC6di(LPEin(R6bv0y>% znYY>|WKZ^WHE#t9T3YEUL+58|>oI2(hJgXt-B*mK&>@J|pm^66pC-K?$>e+224&-d z+%x|3V)S%2UCAi0tMMyP(9+5uX&$^0u>9Ru{xm{E1e*5a_w=SM`|k^Hf*`BX*PBR?+Oryh7^_k-Bf zVZlyIU9|n(*Q#LNHbK_BZ^{G}GGwUgfGdL+dbO$pK~!)@t3)R7r@gG^t~73NQ!@S_)O1=WV8sb9kNU zW4?n|&x{S|520qm+3$MGy7}&AeLMS{eS-}I#b|~YKl7E;&T@d{^_ejWg9R2^QwSE? z08lI`TPRdXPTIzJDzp$&C_T`g320!lN`}fzsMES+7zp@$S-4SqKAFmeJIULRV)jx< zV6ZeOFaOey1`GsztJLW(O}eMS*(KMyEGjfG@m*a;<<-r|Sx1_@@G5334FwKb;81ap z_n}!1VX@?D)hLSr0}qYeE1u1z4xuDf(w|1DYCOZX`TMu&9)!`DatC}30&zdQ*c)yg z{du^3e00A5=;HX|OsIKh?f@P%rE7cnsb&%^$?Mfz4J{m?Q=O=P9iAQwf;-m<2?Y+S z;p#!mT6eDD9vYa8t@e&j54X;RDy?i~aDYx%(J}Mh#leBVPTnyTDhGuEWb!dUcFW+- zUeX2vz9|9JBCo!-Dgl88Ci2HD!2Z$B{^{c7DOy0OvO`RV@7 zt~7ru8vzLT#zyAnUTkDxfkkN1LrH6jv#KVU7Vy>SzJEb)s}@ipSsLhZ#PIR%mMn*4 z|H}80jp+`p`d&%wF417%Adg{jP(q{88gVVlIy<5O07!%L;ltfW`$xmA z1G?&Xc>b7fMR)p~WB|#7WD7rp2R5^O~fdr0Mh=a@jaO+Io@1Bf} zTuW6bfF^%E+}S;$o^$Km>2;EwnhS2>0GWswYy91Hnq;QB6cJ=#6rJ$fSi zO)_?I)i4-<*vaQE=x?&BSwj3Y$&g0RP*h zl~+BJcbf)FT)_aBg6JU!bw`i(_x>!ZXcFA5`!x)}S?KdWpGa#Yaf3oD7~pai>EbBv z=941~$BDUE;GqOQ@$7FO@9Ylu&xVipA3YwPU7VgCKO*lejFmjGz>A_9fI&|ahxS|C zeTLbS6NioL5*Or@-nPlZ#K~6FNL*urlxC?b(mxzi&``Z1Ly}}VKhEpIf|?uf#SsN3 z)F(f5#*<0U>NW)%2n6i4FODwGoNoQj{h`4CEaxECbR6>0?(WW+A0Z~QT251NpbX3A z@2@Ui{=RrIF4V!+Dlz!R7M(hMLnp#c$Gd!JyJ!y$Cj!i-m&?)e4hp`$ zMT-=ce4e&X(-5shX(U?BLW^9dmvm}pKP(arEU!JJy(hbs8SN>^hQVx16$u88Hy+ZK zw5K!`wtwua(xO~kxSD5KJ}u@a(?!5!ZFn3w@VxR+-6rYl(onUd7PFv$|LQ}&H1ey! zoskXQNR+_F0>fL|H`CdK@3}2jD_@U>5qONo2L#uH?Q%Y+z=fL2)@8Y*o4S0$hS}yQ zVHg#xZ`7FsRcz=7(-yTb!T9zLE%7U8 zb37GesAe`Kq+)ylM6i8l_ju3OsUa4Raa1@!esj0J=)z}c823jRTs$y+H|$j#dhRGi z<(`54#va}Cv-^Tp76e*vi`wnNf#)rLa8$1M=(?Lg#ctszd_Zu$y~k$?Q!jB+Qt;xJ zO^X^9Km^-sdmB!}hN^Oleoul`9FK}Q-G)fFi%?O?*t`0BK1?>->7zVpZ8rBBhq$5%K&ev5v&EJw>p zWj8SrXrYA<2(DKS%JS)E;VaUjo!C$n{$X)Tw-fb(Z$kn99ew{o+{ZU;H;Yx_5G44% zdqme8`r5SU6>A`1zfD>+Ro@mpNB|LR@6a>yJF|lC%nF5lEi4y;1mCxh&wRVJ@brKI z?rX=iN}EnNf9|8V=%pkWI6gcnXi?YvIuP>NBhH4LRjjVXfx-R8NwK`0u6TXBuVIT= z$%O;Y+h#arw_;nl7PT*c2)5Tx={9z?Xx~?=MGnG2vskW*C7;sO6N^9t%NsP_Q1=Xm zqJb7A66Vy1ly}d z5}&6c+dQLz8uY0vr#B*-mo|&7GH!x!TGv*3}0Y7mKOfrK?BPx7c|`vqG;h+ zY$)J=?+IT?=9f$h&tf3~{o5hQTg0t^0q(0`(M2WY^FRWuMU4_zV0i1BVp;CcJsaWJ zu|?bW0m1d!aDBr&2KWp_XXYxS81S*$MT386BoI7MC+1Dd!S;y4x!EiY0mM?`% z;K^_>y`8Rkz(g0G`jybU}2X;V*)papQhW*%bUy^$84WzIbP{{(*=RZ&T~gxQYhwSadwIu+Ak({$Ndz%=mvPix z41o>i*G3zfd}~wLd$UT)z_LpVu9nG>aE&yi1Ad0qpu(&kp&30SLxN8;zdB8j9}Y*3z8ZK z=sz6O3D%n>4cXU&D>cKh8a!0f*t;(%VL($6LbHr|9{^PJf!`gXCYc&Kp?+m@h#=FC z1LE(`U5{ZW1R6Z9Z`+fjLG-_L@Kldt>pn*L95|C%17Y>-3WwKN!?ggk< zy$ToSgrxr*kkkZKx@MlM2+Nam(yN>?Mo7sml&+RgHvudMJDbI9O0(+4v0BFDJGqQ_ zNC2Y3B`6@xkHp87G-rCfhA+;OEL+v&4dMt6$n&<4$LG(869j_KuQ9>LexR0C%@-|7 z8az_6m~z$Y8()I2J6j;e0-4wYL}c>C$%qmKoNo{zjSkID#gVUqFNXd*gEP zG7yGm#L4PQqh^Hx-0zN8&jKOkZ!)SBeW+0@1c1IfUQ=RqHP~8SZ+Mc^w^GL11B0O{ zLU>?%mFKgFt?))?8G*6+Rz+^v>ut`#RhxJ@^8g_f4*9CF2q->;ertqz73~X z?H@w;5ajjA#h0Jvd;S!F6) zP_*sCkf8h+FJI7+ zsB|V0uMVh|@YznTVV6W@JVPaTL%1OSh;MM7>5`(cAJ1LT+IGK=XLxvlqy!MZNNn(b zD&En39lOFnGi$gw7U~NyUjz>xQhX>rJfv05qw9bK8D3rh`4R|duzw~#GOt98kl||t zT2urJA9DOee0iuYTpumh+a=#$98PLyj3@D$IqG}Ok zkm9s|kjNna#D0bHYx8o=$#3n8g|Znzyp84Yd*Be^Q~R^}ty8`*$T>(fV@}HkYmfox z5JD8fAa3|lj5F|3lKevUZWr)j?94R?=v(rY+Yl*VR$lTbFo*iNw5a=WO>pJhv zvwT91j4szk^5qZ{h}8_l1N$SBUA;J!2SqjP(adTN7A&-W-=^jEcV3nUeOKWaO>nZgAwn$6sFHe+yFvpi+|X75i&oJ>qh1TbW##t zGUFZDnGw(dC7@gd3H{!tMKkV}V>^D#2dJptIGU(s^%ZhyO zAI^@CVv8*^MmP#XX&giY*Q@#p`9OL$V}xVARV)Gr=&#TIb~_pzd~>+vJC_`M{#v6; z9N@pk>7>gtv|u5l;^Sk*fPZK~LGV%a^9z0G@-|%p5tw+(h~9uC*?d?~zk?6<)Tz?G z0W&-oAOxq42eL{}n)TR>Zw|Ftea^Oe24F$`9)zUuNUinqSu@ra14L*l5kdI*tx5vv zWdhXg54JYz8yc(fRCjP6&Nu1M$c5BmWbi*9 z?z{78XqG8siiAJZ1Qh~6-jyDu^H8eI`ETe6G)$ z5oH3!W3?bbDa?FMiQSUVB=TvynAw2^^>@lpd-yW#lIc68TJ=2;KP+j&h1Z-;if4o4 zv$HM!yRS<|XlVl(t{5`N-(K)^({i9(Nno8tM$<3|iZFmyGfl@&XT{(|{o(7E!=w>3 zlaB_bcNf;P;DUt=4{0zwt_lxq56qhvbM=?%x$TiNyjg(HMFiv9i_)GGQnM>ITaG0) zg4WJQ1Jj3#mqXryKna?`$;)m1H^1mIGG`W$CXE7v`xU)b-d}E?F^g_3v$s(I{XPAo zx3K=-)2-M;7Axt$vn&GB{u$1JzEftYzK5u<)1Xsr_YL4?tm&@4Hs}Hi9Ivj58D%2_ z3>jl0^R2=cI5qmsW=)gqeznO#*WYS%8wcp`uJo^GbW#H65q*}7wr((N7KsP8w^!3^ zy6I-Hzou=P?YyNy&|E$mn7+Td)gjW^;rU5wKyZ|z%??PB3g78xa$0ns==owOH zesN~R836N4>mvsRpaT@93!aW$nFHHIy0wb{K5|3=Jp)pgjNN~B6Tn4=03X6?Tm(D^ zTr5M{XT;|K^2{$$LHrrs*ThR&&Jvx1%9wBjT7cbyh6t~&=uFF^Z4aZr)qFM%(BClV z*Q06St%uCm_G>=32`VUXyoQ&2hW{(W`}!)}XdvLfZt%Hdq5c1&L1d&3Ast@~=OBUM zz13f5bhF;C2kigoD#<`snd5T|h&EOb5rnUS(DyMp8ij~75(plEfLG;T({Z+e5n#r^ z6DUF@2NIMY;$`2{*&ZaP5r_2iQ9=9xh^x7d& zP|&^sZ9_|tGQwVbE{YUbAbEGSnhm!3Y~m}mtH`gW8LR6UL$idyK=lc~c6N5aY)^`% zCJg3wb4+PdMnOUShM}$w_q6M2P6Y0-RX8Ac6$GB^%@|Gz^N}vHfxly*=?E6S_t`I? zoT}i+FR-A4stQE^)o8AkMEFd1tqL9(sNOR=G1XV(vjT27WBl&g%|Qd%14G6~DV!E` zhUeVZEMuC~Wpm*`_Yv(8SkpPHQ(CdXi>mZreaf5wtNPqDulnCEGT2|$HxINN#;Uuf zz{U4Y862R0N>`&V%vR2As*FYaMCgnqG!~fl9*y9T;Unv_v+9d>_N_iQI@kYpk-`3< z#g3_o7YjN7^UlktEFf2V2N>M1tTyw}CXhqONCxRo4N;8(=(i{un$yC}mxCkz?~!w> zdq(r902D{{uL=%KAFM}9K3;*=x6m3yT1?Qk2LO)Yi-3amUA(^gV!a%V13Qy4_Ur>g zPzpfMy@OX{TlX>&GJp_lHXg{R@U-^4kj-xh8J-jXf~rOXQKi+{n%2Ao4lZk}m5m3o zHzCydD3D~z=!)>YP^tn0&Bto1k6A@CI5mmJonk(9nsi1`qM$S#?;nbQg86;HjGaaf zYfi0XE}zu`1mh=qt2u?QW+VQ?(Q-+{MZeBu41sGb&8@b|N1!3VJ8QmfVfwdXaL#}6 zd2`eSgr>#6EI_cmwV^xLl#$P#P8VzsF`~?HY88Ous{U2Mf$4{v<%}246&(JNXQQFm ze2rxSzLptl1q7gGPf|dd2jXM38r%y@Gd7Y56kmiI7rgI@FK8{buX)B?qyX`0D_F38 zXA|lYGo~BpI}MNTf%v`Wqi02+o6XpAtG-mI76x!1JTFF1m&Fx%8F8wqJs8OtsslyS zgdsus=JVq6a!F^N(d?#Q8X4}|`rhz4cwl<)VzT5WK$SnbRV*X5Vo(%U1QCp{n&-Y= z86&y?kH!J|yDx5MgGqTi*f~B7XGk-A6)?0qAwbZ5fLC|QTMFUHkDig6B$0&6%IJfD zBPm@_(0+{9A5%9lT8?jCnmsEnbB4bFlwc0wg1j=ZItxFfZ(9=!K+t^%0r%&0>&ljO zyOFSQM%oHMLQ@|V#8ugv?I2rYbBT`NZCkb;C}^v)HE(R+j5zXD-MwILTecxwkbedn znU`p5gPrgZ{29Rp&>V}aG9vJh*=tc5$HM?7#9d*6w5rp5*!*fSQilZy zZQIsq0SLOPY8{oF(cYTTsqE^UMnT!OYI&fb{Q+!pRNB^$&}XCqfG2Dm1&0{#;4?}Y z@v0+Z1YO3^4gf;G8Vy8MMfz$_}W$^4-~YYuy}gC6s;(Gu^6ofyZm3jPtRIjqY)}qqrjk7Wh&n)yihr#OcyU3 znKdRzm5W%7UJTB*zU~xRFh-@T2MD?!vWd-8s%A7fTwe1KEONp`#_m@Dy4(?T2%?-u zEl5549z5wH(`kfkAR1Ez4lz_1V8l34$4peO*nxOv7!cxjP(l1Q?afx1FWMyiO<<#U z#&{G6%JTS!1s9=WR?&{TQ7Jf3y$dl8M$79Wq*q3V2MnQ?00i9!^eXL|q}BHW;-W3a z^f%vGWDGNF9FT@#LHxbHRRers%8Wsw`ckvh7zS70N;*O?s%|BHTU?4cAiJ&vWyUb7 zK%F-0Z3Bo<>_^T{wZRy1;%fMu=4L3BA=oqaq zQ9=z0&NrRMassJ^6+JvKy(6CJOW}njGm=h?x*5nYAI%id&dFZ+3?%q)3x+Pe73KY9 zqPK;=6c*EnVEf*1I3A5}ipg*&lxj#iQO-}_iS&i(V^n8g;Q;$P!y)?+2f1N-FNSPT zfJ-vdRhg4w=^(d|xxxW9$;>{~L2e_Y7!yyfypVBE@4s^p(vzR$*AfS`fG|aeh zpj$|7P%PXP9pKg-*PsCRU7D#Gy`)%x|4R!dZdVk-i~5)04)xcn@&)07WPAc+8{Zot ztKdNP#)zh`w$9E6RP~G5M20#I6_i3Lbq70tu2phyKtMMaXaYLcVpv{X(e1~=a2bmu zJq`;BG<02trlD1>v|l7hl~YEpIu0D@Dy{hWj5=Z`T56+}1qGVdp;dq)T--7Z#eZOM(s3{SxotPYVyyE!Da_uba8PS0OD@ z$odP&h(80euGSPt$$7c)y~=3_A>+>>8~zN-IF&K?<$a4te2_5HitZBsd$%GJLdN$m z|MunJ;WuCMX)byp8m-(Y$}7>?WQ@WXMzx9<9tgi5dSPA^lhtrKUpTuRGMr^2v5ng( zz=r2SC&LL%9tq963Si?xfFINPWePFqT&>6FhX=HNRR3eVTB&2UhqttD=0-@7;WjHw zRS4C;niwF@FLK@<-ni!xW*m510cQ)PX&_n3QuA^$k|);nZ7IzFc|NZc3fuK%F_I23 zsC}kurkV3Oq|FNd*btPz`=C9P$>dl`~k*$n#Q%PuYu)u zSvnjUqoXi~h62Nzo%gxNGPHjp-qX7I}$WHeN zgsW^u1NSr#U_RBV7%oRNec;AXt*C4;P`%G%6WYCQ-Gv=i_C;m${5)T4m{fGS2I5)Hwj3C5x8(-edthWO>iCi#KtY zF`L(D2?YqgPdz@J7ogk#jXs4#$XFTE$SZ(T{5&IkFZ>1={B-FOZ7&=1*?-jNZbsAj z;b=kmpM~s}GB(lKK&IKnkU{>5{Y^zqnK)_%l0PH4WMjqo0S*y_{(J@Z&XjiJdBe1> z`b*>}`2lTWydUx!8RT@~S6x0VAEnoLTZyOpQAR*-L3y@!u_3_EYyl?4)rd}voG9z- zzYniy6>YhcQo~ zK4R|S@$td#*3t0neCvGoOcY#3re5G0sWO>hDtVizknL=D`+WO!R|u75DNBTeP@sS` ze7oPec(Hy)*3tW>UaX%`g2?M!vl@F11u>%75a55>0@#07`^oe+wZY;3+1dWlBVm|~ zc_Kx*_o-$5u_hKcfParKQQV=KK#EjoKrox$deKqF5^V<2 zBtbNgy)Veh4c$xs*9~2zA&i=lu@2K&cp!XW6Bcy(1T6%h#DL(-n9&aMS#Y5H$fo0Y zVhS|rsFjg>1$oYhCuC6v611WWl|elv+m>OC2C{c-9r>}l%q%B^5K<0UAo|26TG95` zDeZ-&imJAxh!V_L*cL274;0jI3u+49#xjAClS&GyNaGZS0*xv+qS7Ox!9=%0q1s)` z%|`>-2dq>5SglmyK1zlaIU_(@vmhWSRqLzY;MzN!Z{*E)cWr$EIMBhIdK}i5IUTf` z4EMV7a;71Lu-CK}OO#!XE$tj|5DN3l zSkoG?v5N@Ck3B{;fqb%rx#-9p)>V+UtG^y3II9vpDQSX+mSqi@ zv6uSmAcCa>2&VyUJIB9TB zfAW1h93U-JfG1l|&P=nu0bP$m^xvD%A;|+H3C+Ar%IEbS2YVx3PTTd_T|_XxMQOl- z&j;mvApb|E;WGO13P34a{i}kDFj1yWw3&`f3>RZ^R&I4=vKD5&Bh~d6++;*u6-2;( z8W4JYP`#>*%g3n%>nh`%a?0Hauo@?Q0(^%q$u zGrVi{txsp_`pc@eJg8o-{&Gbb8BsYiJYDs1gi>L`q5;kuI*`9_PK621fMwk_*n?&5 zcKB&!lj<+G)A6!g(M<1L8aU&~iV7oQU>mwgXU7}#p|j-?WE)kLjdCs^_)n9yXl+klmU&pMh))a#Elj`;AFP8tXd##L#wF)9aZ6Sj{VC_KV>cQFuwSjm2 zw<)b+5G}X|UV{qWfZy=EaSy&qc;wpqt9s}8#`fO7#{2J&zx7Yw;{QQWhtzY99Z7{_ ztV1B(uzCwjDmZBMVO7QTqlh!i7!+1OvaNWqV0LwMoM8Kq$S~Gx)!(f|!z0)EWdyJl zMo>NFPN7-t0u-O+By9K7zA3t>;C1v2xSfuAIxffI3%Hw(d{I}!7NEHp%AC0ILVH&u zF=5l%y;;wls@e;u)nV5`O3fLmMD2r=AT+eD12cZ@Z{@rgY}RAZle7;~1SA;Wp|u5S z{(^4c4emD17`Djeydglay)PdAbu*fA9@JStoDrHdFj}Bs{n3Qh*zg@uD_%@YbK$pi zZQ_K^kiF!~$N2AZP=6XKX8eQ7b8xsNYyiJ51b%x1sbKT4)U;la#z|46twR_${l0o>sfgz zRn75{O(xceAbj8wn%%gzmN`wgiP1oU@?DqGo1w^PyTAyRrkJGo46p8JlkU--$vjnI zid;CU9QW9usS6E_KZ=NOUCL?DoTw>-o?$`#afF)NvQRx^h6Yd}n?rSl3-b5z#jb9% zWb^Uxc6BX?b9%#&(k>=Qs~U|LC=p4EGzDkd8tp(vDSK>0pmZ9MXWDY17RCxSyP6i5 zQ9bpwiGs7MX$>SOD`x>aJg56X1YuieApk-5Icn_1oR06KB|O%dctMZR(C1={3Lr(Z zX~KsvKgO5gm&de8^hyrbGxpd4Gea6f0C9eRPebB({v=}=H1Lw52&eLS!FR~31H3p4_P#G)TBxr+BE)T?t zSW0b)8S;uI_t=v@EhSkX(hsFlFspf)H@}Fs{UjdIqIF5Y1}oVd5a-A8YluUe!fDq~ z&_o$KeI;gtL=Fvv`jG^1h4PH_RgXr3NQwjk{ZtF2tJ$)+rcufAEND?a57fL**$xVQjO&TQ4VC|go6FsF-Qq1P497| z>R{y;txvpW^I!LAL^109*I*fM^O}6RhK3I$qVorL&8e0HigShQne{Gb6Ep1j>qePr zy^yJ%W+jhWLL|g4?@jCoIVArgQ*!q4-cqZl{{X2gVn{s5l$er@p1^P`pe@l<^Lf&vM zKzk)=#)Vdn@-+nvVrm0zk{;d4NTvT?AVChv!+q`<(dCWxds<3tceQpyo zWHy6M+P1QyV|53+oLf0G{|JSF*@I0WS_3-#6eNK_W|$Oww^&SP<+Zb=F*|7i$dp7C zOO8l%U+L(Uw%v)M>|Laa1tNW_yF;jS*id5sE4L5iL+?iGUw`>apau-(5<#BN!tzw6 zw0o6|P0bqZE&^3d35hC8-n&E<6C^TCZBfpq}tE^2c64*Zsujp7GxgI_{`DGBT z;%el8JSLmGN0Ky4qZ+8)UR^Rrb}`u5-P^i2I3MmmIyydeP6x@D-UW;*B>cn01nGNtVKQAZH!m`Bc4lNO zJ^_fJl!zew2=9u=L;9BtjWgCo04dI@VL|;dK9JP>tK`mD7XhdSZjGBF-^}N7pGZ&S z3K!%bLR_OcUBY>#t{9PeXRPD`P)KhJ6~u07U$IyL=8mOp!-D!9h-!466<4xBXDr4B zL`YkO2eJ?FrbR~H)>&_pv2+YLF-8sANL$WlvPShmt3W~fE~GTtE~nQw(zY23G=LG( zR0D#}t-b20Z{3cy*FtS3_UzjWu`sZ!@rqZTvcY<7uNEpaet=RjB}*w;`kQ3USnUIp zP}u?!lpkG{%Uinnjy4F_e`|NXVEw%&jst`Ivn##}S)DGpXZ}V9_{_`DfioGQV~wT- zXa*&`=1xaH;bLfwo5autLk41s~^t((#6hU*gl z>7U=0aSllZu)dvrUj3s&1JS!Tx1;gk@!{6?;F9l^9C|m+r#wjwDIhs=fp+v_!(H<|qVbYd?=Bc_Re%ov05Y)Z4jbOpot3C+{aX|zLLP@B@T zWX533#?(6IkU-_{+n=*Yr*vsL9r;?2n6&R!Zo17_erdx6rE&2g$mjN#LXb&uxuKlh zvqE0?l##HrA)AGrw1KW_IP(r_n}O%3DS1@PH&RA81U z)o%^~sNpY&=M5I~NfhwY-5{?TG?bsFDr z;%o}ZI91faZ7@%O3)216K{17EzTgF(Q#uJtnk!>6z(GyRRx?4eNcqtMecH+J1q_!QT2CInfIwApII4VN8UL{cI2^)B~+x05}-<<~uOvq9>15*kt zfm(*_*V2sXm;CZ@cpz1zjxMjpU;gS}|3ef`uXPjzki*0Xu61Z9Htl&6Vq|xU6;?wn zHTaO?W5=GRjQoSJGNz&&s0JZ4JY0RiL)dwnwzb3+&6&_Y)3vA-0h z)2G)DaY4FpYcgNZdAsU}Um;nat;ywqR3`MUYM!n?=54O>|MA;@6GCNd%gC-r4h>}b zR|jB6AN?;x+ffVa52lxtuaQB{6@R_@{TE-*rYFj8yrjdY=Yw*2{l%}pz)ltiKUC4v zoRIe49JKhCr+eFM&chL1@g!`Tu`bmixtqv>7;=B%K*r^!6FS{vgfrHEJMedt*ib^& zd>iWzkIJ3WSyg}EHWtK?`*)5JQZ_y+=elBx>M>`Od#uqA9o&%qw;9r#UU4{D4TC-` zW38RTl3P(i%#b|CgRE4ora^$W9q9f%h~$K{zjiDTswL*j`6?vv^xi6nM+=!%>XHV$ z7y&oSOxqu=QP*tdoMXTF2gn}~0lMUPm)Z~v)w50o9E^N>a_XXWTVM)WZz zNcI!9i)CZ^{uRmT4XQI1_c@>;mmML3TqeD#{Ksl=Skew@+G$RkVMBMR+-=mbGII;H z;z0sP^1h`^^&-vXh%Pu|en`N$77@T;{!n~kY~YXFGNvB|P?TGa+I0L!TTaO>4AfRS zH3LBRPp#IE)w%i0fmwvS&3C*Cdt_`nRx%m*TBJMh!A!rhks^ZXd6i*kwf}@a&xoGx zD5}Ecu!Nld`<~2ds34y1o15)P z=dPDa){S>u`s-hB?nlx9D}?^{44dlD%?5y>UPB=aoUtRwrpaw$L0$-+QyKJXZRrl~ zsWN~H;{D84IN}Ms&@4BLa>oWGaemi#iql1sjekY?SH zX0yYs-0}Y%jp|ZDT`Y&w1lTzPMyio zuEm|l2w_EW>+4Vg@WG?631a{h> z-Amq^zz!z_{%lGn<7I&Rhg&DV8JwIRpC4}@9}J)Do}TR=9|>b-j4FYqxP?d4OB(tUdkX84=1(;|2=aE~I0xc4Wu;IyXmhC(kouI%BT&v&zO(!A;?b~Ku#7mOhK>prV}f`;tuboxcE3K~ zJ>nJ`Hd)59tr|5dS%3sW{Y(A1B@`TSQ{B!O_|@2P(PC707SOBt_a~re2%pzl))r*L z?eUqoOIl{{tQ*SMidsWP4d*hzUcq*GSWY&x;*6G;4aU@19Us|GyYx9AQm|cGuhW|I zA+0DMc~?~R(=KC75HDphPTxEG^Lw|L;ebdfi|N;gyh>J%)_S*?V1jtTDsP$D>j(R( z@-73!NfjUk>DSJ&kG&V5;m8$%W7dqMX$>5;SD5E+qIo^%J&7i|^Iz7=xmKgypsOa! zWh^JG!4sAXalv}|B6=3QM-hb;Kdu$!yHy5CW@Q{u#oop?yX>%vtO6zZR{6hx4fzk!mfD7^;#L2Z7!T=e&h=7-nz<@)HPw|;! zgQw5w+GXj}a|$8D3I-Vh#O$z|Ue9Uwkh4;{Cp*;O5aScr;RL7K4My{MNud*EnnY1# z%=80G6h#mi^dI7r`mKpx)GD|ix2%XhDv00riHqCCTIK-vI@4-QkUsE9pVBZ$sG6~z z9VihqD@aiO2rt*B;ODgTW;LdJnY~iZSPc)v26_PxQ3Bd~p>TKY6(lIDQa(egqN6DL zDrFZFq*aruUs#}VNzc-@Nd6WGrD`wX8~n@Hk7{&$IiuYWgB zFIAz4f>0|Qvu)&Kf$4!{3f^;)vGJZzQ0Nv{g$6c9FSTMsw&>P+87we4dd-XH>VP+4 z!`6CLXkhz(WyPuaHlQU=Fnll0m{?9yqb>PZyeM1LVU&}2aIiWy| zUZR5i2h)XF9yi!OdG;G~OfIdtyruIq=|%_HKj(Ci6`rnC)juQf5ahG4AhZW`#_K;t z;pYT|6>ozW6*z?WeprajRPPWj4MBU~dkmr+dsVIpmZ zjJQ}%pSk(hzS@oj4?*GuL~WRt^2+AZV*yq85aq|UIi0GzQNu)kcko3r9V z3M~Wh5X1>B@n#kM*^9HfhL#?9LWp3q>Pv_U96~sqA%vA-pKXq=one>(;y7`O{W1bS zTbQnKO9&sLIDw`0Y9064vUCkBg9H#J(sHcG&laU?U}=ehxD|rL3#bbGY)N`7pb8(N zI9-7yv>o-?(sb<#A`}oP(w1b{XUo%9TapYA#|fe!{5;S{b`7FjY>40l5Y}rP#RPky zt^q`h10qEViH==`IL;dFz6wb)KpZF1gY8oHQ1H_5AfA#V_(1iMO|AGL*L|mPEH(XWva&-;`1d{#HZ|^rr7=ni&GLoy_ zypKrE2Zs={Q>@;bE}s2{HzzEdaeT*4F^CUQq(7-&y^nll03Bk;#%#ZMKl#cC1H_3H z5HBU|KVKDnY-d)#ZP-B#9OfH>0i+b`c!lpCXfKoR@M7}PGTj{S5ck7R&2GJRUT+<*Gig@yn! z#;x9RQ=7I$I>xwB4u}-#1Xj}*>+*`$bc*bD$DpzjrbdStk)okQYB4E=3>`Dul?(ttfTX=Diua;F~D0cMPa4^8_P&nMQWs4#)T%)5viWSV^Xle|z+gNFz6}KrAO} zfmrvGMy}+s;30@J_<$hyGWhVo6G8-=RmU`PWs3?NLO4MIguS;kawUmmfH+RPZ;OL? z-1atI!^sdnL~-JM>(%>-_k#owCem{5Dc-k4NyPisn^io1PX$!r!zS^nYenO>FkRzW zOIeEn;y68%_40ki`w%ZbA~^Ak_1b-9wJUc= zY6=dB6e%Q`bH0y4k_-^X2|Qt;a2V5d0OF%Vj7VL%kN6)#02?Ai3ML-;_T^n91H_5+ zMj|A&t4YVKc2#c$0fhPgh6Mv zzMXKCQa}MgcmF^SCXIgc^tWGqTB|!oKT{V5($3fUk`Gq}2Vpdl-Xu}L1n=!+8oHOB z4U#`?-xk-xsu00>FUhGkItQ5*ytUUtYeB)B&TaT$R{z}kuVke;*DJnVy+5ZybordG z&gdxl+2~99SKaNfS*@$Ha1*G&yui`!gkK_1(Eb=H&duelTYYKk*ZK_G@(ee&sv{75 z9!PLiYlO@c3HYG#rxB7mpAu@Mix8tXHmB{CAi|cb1S51_1s0vv*?nDa)vGstc>Lr5 zHR{2{1RSXD&A(ezqc8vE@h2+wn7#HY_?*|lW@?GUC@7Qb0w|d8q?zm0Da)(iESd%? z@G3~KzL{oS*7bBtcfhar+|q&>!Zvmvx<$o)xu=5;<7u_4m<Wk4tUr;+c+pmHr^91G2&xYkd!Ft0_K$qesI0a>%=WHOs=;!nF82MzNV7=nyGjV^e zpblsAXyL$g&10gqqDAynr{Ll3ESCcWo1d@c$>lECx6&tH77k3Wdih#TXA4#*1cwN- zdD38DdBtN{o&1532o92ENfZ`1{1T$~E2q(G;eATT0fOx{FGt(+YRwNu3J$Dg^JLJ# zbJgde=St`_Gqc{o$4V1;;PRse-2$^ZJ*9^(I9;Ep;X#7&%>})Oyt`c2bU8l#^i2PR z!-(e+CGs6!3;

93l+he+Uf)7*7*YVK$= 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Ƚ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Ƚ$rm7^RNI5u^3CR49l?+tFQ)Zu^t<+ z37fGM+pq&Wu^W4^5BqTthj0W(aU3Ub3a4=v=WqcRaT!-|4cBoKw{Qn{aUT!x2#@g; z&+q~-@fvUN4)5_1pYR1=@f|<#3%?O)bO3=76u}SzArTs35DwuH5s?rDQ4t+65DT#p z7x9n)36U5{kPOL@5~+{|X^|cokO`TQ71@vjIguNA@E7u-0RBcH6h;vgMRAlsDU?Q8 zltTqnL}gS#HB?7U)IuH9MSV0tBQ!=+G(!utL~FD`JG4hf{EN=$f^O)Jp6G=>_z(Ti z9|JK6LogJ>F#@A78e=gI6EG2zF$L2w9WyZtb1)b4u>gy(7)!AXE3gu)u?Fj~9viU< zTd)<|u>-rX8+)-22XGLFaRkS394B!KXK)thaRHZb8CP))H*gcTaR>Ks9}n>ePw*7a z@dB^#8gKCqAMg>M@de-T9Y664e-LO)06`EG!4U$X5E@|-4iOL$kr4&a5FIfQ3vmz^ z@sR+DkQhmk3@MNjsgVZhkRBP430aU8*^vXekQ;gN7xJS33ZfAHK@k)~ag;wbU;URLT7YEH}pVH^hO`_ML!I{ zKn%tZ48w4Y#3+oxSd7O6Ou}SL#Wc*oOw7g{%)@*v3?Sf(xJAZGuoTO&0;{kZYq1U+ zuo0WF1>3M4JFyFUuowGr0EciGM{x`%a1y6+2Ip`d7jX$!a23~a1GjJ+cX1C7@DPvj z1kdmsFYyX*@D}g!0iW<0U-1n;@DsoB2Z6^15Cp*x93c@3VGtJK5do198Bq}pF%T26 z5eM-Q9|@5NNstuDkpiiZ8flRZ8ITc~kpo4b(zy)I~isKtnV}6Es6}v_vbkL0hy(2mFgp=z^~3jvnZR-uMrF z(H{da2!k;c!!QCPF&bkq4&yNqlQ0ESFȽ$rm7^RNI5u^3CR49l?+tFQ)Zu^t<+ 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Ƚ$rm7 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

qBqm9+j;@$H3w_ktH3 zJ9;eP&rP>v_C;K28ekW&L6;|GWeNwXuU>~?!-%`OT=`))K_tz^5N4AXjJ*gA!pK#b&})vX6EU)xHS zFFl+*w7j{wd}-_9HzVy}w~McJbf=WmZ1-ACv=UV9S2}|OppF7IRyNN+fE>%`R@Yaz z9tQr&#nr7#D_5^37cXxn%gL4H&8^k**VdOelPlLYuUx*mQc9AmpbrRv{8MP#klyLn zlUjXHX|_^r^TX)Q6qvPY$!=x8j&7~ioBP14l2pMmj-ZpvMWvNix3eQH1QvmLfY@py z>2$$dDGJodxtg`#oK_Pq8s>OqPeBR==3eEhfoEr9S}m z@9$Tt&AsH_Huw?`Zvp?I8%ot~`#!Mk(MG@9PAc2g1a$582g&le^BZXADZB%hR;q(` z9YxlT+UN8jJ?fs_=t1}N&_m!seL8ydXth;I)8rh+(K-j%dHyVRw;!!n(I}KykpxRt z+1%pM1b=VIRmpd?dLt=gFgFL~axty98kUyd__Jh{FIn9ssqeC2RGd31<+6-kwci{x ztCf}%0vytvQ%M6DEulrFbWlS%a%({plIesgHLH|^;Uug{?b32I^P-+h9?X(z`!{qGB>rDShvZOg;Om@J# z_-4$AQGy>)0nLWIVI3?dV91jD^}(>OAG89Gf4!B~b7?D0i1lTZE)&HHxh%#b9fOB8 zFhXZqTPUT3A)@q#Vbm8VPqH^4EnMQcqcU~=`|Q~E#DD6^pTlr_YVEaa|NZYg_2jSQ zQu$H%)T1B6%)R#dwE|MTGM`EYhb8&-wc|*VudZjjZi!B;6_Mzd^W~6xEyc;TJI2){ z>}W~m*Gfood$y3Lo_wK*s;Aa|O+NoppiOAAHs;Q?-$4FXWfFLHu{!QqTN+8@yVBD9 z=Gt43<`<)KNPYWwZtXli9t|I#di3u}$uoREq*9Y_z@zWK?FBEG))Vr5qz{ZT<3Cyl z$;Sy)mv581O+IIuA#X-o&DX=6rZ#x$$yd0^XM5Oe)zU$w-Gc&m`_G#K=U+}ziyIR(s?RzMBf{h-;d2OW+> z=_<#U>2H`WCe6%P{M3fj@N8Xi3VQv{u-`g`eMv?ep`K(-PAZ}tc_-?9uel>A3=aF}IqO#a2agr;_$V=}&?RfDCq<6hT zCY%dBna}*7G9@z`QEwshx#7;W&2{Eg?!ASqtLa6KG3GVizJ<)!uB~2RPIBaoY|wFa z80z@V5_*IfHpoc~eVkEx+zr>ycfo#X{gJ7iB`ZGQ9v7@EhfWe@^_R|hA(mI#Ubl7v z`qay!1i~ezZOw_gb~Jo7ZR^+gUbL;uH&J26l%+b%IF$vO%rCl8QEk^+%?|BQUs+W( z#@v=QOPp=v39B29Dd?{J4bYRTduC_8JD5rRIQ};v@lTA)o=JzW7 z6xxWGscfV;QkyxzJ`M`-dBdLNJl9Y3K(;;j;DonxxX`P!_It#SoX!#AjKe=&TLv7P;*Tw zWwR7(^%Mpsv9B%_&iCukzr@VB+^JN%u-7Kr-R=May-OvH()AeZ2#*b$FypaIshu-k zA5^LA)RQWUfU#E6`jpV51jACLRx7(~<(+w(uZq`8cW}{i} zPpRp_mCdWGmoLqzi6x*l{d%hod!?_*e#4ZbN*QQ6rK-)9^_AtTD>JG}wW<_0^=ha| ze}Z0^>zdrMNQ&*s0S)9Z=nv4(ZLnao*8*cepG@Zpr@XR7hKT=YS`{L1uE4~-x^;Q; zVN?k#F0fxJRC-XCYIxz;`uZcP#<;G^cQlC7>mt4Oui;tiG-6yuEjyJA4tn(^H{4*z z<*=KKCk?wPhLyA#6+8{RZ7}H81a?F`^U4SRdMfApR6etHp!<*~NE^6 z`a+2olEy^)uie3u+5`OA9#hTm!*NDoX2UE`Vx!&n;DgJXtJsK{LC9^bSe4wFbs?Eh zj~g002^3@zcoe`v26+VVc}ju4fwHmXcd9TxSk^w|3O3L()eXAc){NH7o5GDoX|GQ~ zzzxO}BfVZ8KsH8XzgU4Kn7zQk;R@9;I;jh*N=Zx>jpj~NRAHe$s4mECq!32jPGbsU zin*4fi>+u}p1*wQ;_CeuSJ$10n}iN$g_{Qv9+$eE`ZPhH)lv|!18yE9Fc>UyD+*=! zK7HWw)ma?XR5~;}Fb1|-y}ca@Ti4syADN7T>kuy;eXUoP&#x`tzcQ0%y-IbDbMH>8 zyPXWWm@)(hNN`LY*cu#Ss%qEg?R9B@9ZbGVOS1(1^qwcEXtw&MUPUkP>F3E=(qPh$7Nfp`~N$0zH8C%D*2Kaur)r@D(!_0CA6@d3PLzrZ!BPX zUBEjh_Wr?QrlIp~bEOC9;M!LY3-dA(>HkwNi!ONRx`NBY^Pt(`xsHOBdni zf&v2qrR0LHqv#e>$)Z@AH5P7k`+Lt8ZV#cXfEK)5u$<^)%1@K|c@TRVp5~O3>z5gX zh4>de-%-`3cQ@n2D!@dQUb$&=*ijdl8@uKQ!%+=;A2s{Xq@;cmN~v4FO`M~#3Y;gS z(3eL#ox_z&L-!JM=R|}Y_I|!p43}#)*lfG7KuQO*XwlMa_S5C*lwuu?+?wQ2$WwD2 z+ki4YJdH+Nh5cL<+ik42xTwxx?;G}PHG?zK_>SP0=b|^_IdDGh)vH)T)AtAJ%X8AG zkq*i(HGx`?xF<$B_=33tf78ak~Z;sDqnnk9}$YGXzY! z3*SPOj$XsK`oQw$%7xWUV0&xxR$`Oy1vhcPldS`nH+mz%R}JGDLfuP)F(I~^Sg{c)e3srJVBb`s1k5j5k=fg2JOzL+|7V56=uOcsf7g>}n0%0&km(!u? z{^mJ9L8heNoipcdH*nIlH8OU_u6!pB7KdMUxLm!uo>c3w3P6ZqzTvzlB^*oCew#B2 znNe5Fo-oNyF^T508|C8y@}{AA{WuR(Qq_im^8?Uh)F!u~Qn=FAikU5CyPYEyO23DX~q)d9B9Zk!9Xg(;Zz;KSd23}6 zg&)2kFFlBnjd!ew?P)PN4ohcp+#2gF@xFthtw>YggL}hmcAKBFu)vtkh2{D|FAgLh z3=Z_xK9TwoupO`sLq43csY*>Y?>T{mM$m&A#oE)7{cDJhMFShwaF|uGt-X9%U1;&j zRQ70j3ZLjJ*S01LbgRjH_q0N|Z-9>@alu zCGK&M&$Px{+~QbAd2pRqJIMyiouYnZxS2aaT&d>LuU>|jfWYOrI~6tyXr=2 zN@Pw&x}~PFU)_WwD(UQcAz)kBV3cK+8Q*3b_gY5N$=~`De~>hC+p6< zlKs{seQa1scN^)UyP^wsuljS12m5My&~0PI_5dn8L?3ml&y*i8W6KbSpky6@iE$O0 zLlZ^^iljr1(ESSL*ba@E&wx`O)IyST-J8DRX!aQqy()EYZT({km)m$ZbG=$vxC0Ls zRg)ghEy<+#SiL>8PS8nk92)c8PHS}Kcqp;BsaAC^y;!~5+Q-xejTgjBIj_-6j~bNo z6TqIp#EC`bmjaIdY{St=4<5~Pf|}k_^vEs&pDyC4RU~Jrl=n)Fk zD>e2Z^eP}Wdo0+-;6&!s;ir3m+~Ng0x`7tad^*V;!qZn_E)_jtrme$FAOypva}$Uc zW3I3SUb{l>nd1*fJ?nF}@*2OKn$gI%u7`H*V2n zrHyojksB!}{W2=yq^xpImb|r6v%NF3f2jKHx8aL9e7uxgOQ8uV-^!Ei(#OeyevzszI~c(8lBI3;?9N1oNzyKOqG)w;pB zscT+3(oY|X6L#%@@zd#v>AQHk7Md`g`t=k}VjysySX{t}qZPlGCBd^wzYES}!9gM? zpV{4t4(A0EFXS%{P1qy5rJ4M5LAMLV*u~;#bk6p%?b>d^EmR{(C)88F2@~EtwIWV-@gRZkmi4-%DKpLCrn(iD z>5Y0qezCJ*WS|#VPOFP;`hK#9(;wJuHV1V#$o<}c>lEpHHJfCOD{dlnE~wOL7Tj_x zAYg+pDrQ8(X3lv@aLa>Ev|*h=oD`7lQ{^vb`*5=+1*4xdwv%Pkkld@+dmhOw zQ_NThL^!UYkfdL^5!q!-JCwzV;s#Ts%86;{V2|M0r&!*0^K8&fu$09~UaU_ z)5KX!i>{KxAcQ_|Rkm?ZD@>+^WmE5`Xps>)*O{HYiUZ4B2bjgrm&Zlg30LHaL$IOt zE_bWuE3M`Zjp#CKX7;R3PZrA&Zs*l;z7qAHQ`A^K#1|uv(D}ssQbSji-3lKRU<3PG zhsK(SMx>m+<{g7*M}>zXNxc#ya;GE#N!%~^q)<4CDv}O+bcuvMh0ezb!SpbgN$ExcT_uL=DgVS@r~`Dy~Ihp;t<7K7J}`J>JGrbLa6U)}0jH z+ju$)S&7Al8!b%8VNW4yNE~M1IP9nQluPw&4j@-1R>o7ukc|q&E#eU#u6vzEr7QWc zo8i;~83=fN7;P-%_N7{dzJL)u3}0?}u2bF1P1B*)NTN8E@=*2r#C}d%nkksG`kyNy zR$c;LIP+a`{4<>r)HR~%fhTWtm#TELjVXAVR8oYNT?W4taKG9ca(Oh0(M;wrjOZhwRv@9yeA@0|soQQt>dYq4 zeg`Ksrgiv)N}!3taChJ;DkXL32Pkam%-P>4oyPypEZ*h$T!dVA*1DS0ccHr5#gS?e ziH&9-rrco%W>#3dI@N?a#vv$5eKg|k!;9VTTvgP*CMZ1Co9=Drx0=C$?PL(`Lprp?zbEB zG{{ACE-Vbw{(|_|E!1m!XBU`g;gHOwJ6D$<+_(q<(r+VvQhhcS998o}?0f(Vr$WZs zm77$T)Uo*x^ny7x$si$|KxZ?O>cI_~60WUWTxC4OLm&u~``$hU(6fWx)xBoV_A^jy zP|nr$8i5b6A;VR~KH>ntPB%ePC_|MZs86T=%V024&SREb3vQXIwfMgi4D zC|CwrNyMrE6mxDf#4}(WhUDe*t5`&ux4o$j+GFt0I81M`0N>R{2A_4Lhwx=yeX?iB z7uP^dTzWKxU58ca?_pn^A4Ho~v*PqR?X<)pE49=!YBize96-iX(R@q}LrGUqo|>5= zMks1u;Q~3Ra2YVOiN-nZ6pLucvVIU6M-)9&y}F*5#jVP$zDg_E>QebI8U+GgvGZ`e z%C1+|vH5uu(S>1joaLNpqj-pLvCRQu8mlqqEnBNw>nm^Jc!;(Ql&#dS+>Pb&7{LvI z!D3_WM{t@#cSR)4BZ6=fZ(TXR_4HA(KoIcjjj?&ttz%;0D4sqhV-KMkqlLq!Q}+p- zW82~OgRuGI&UCqqltS)&*@T@b9(IOfPed(QA%q3kL_XFoJWqE{xIC$MFcy631M~Kz z4X(_1`TrYn0?)c;KlPDw$B(>#e-eW{4m)FEr(V1E1cQ7A?`?bkpEiEuh>JTFf0VdW zFUc09F{eg?OJxF1(P-Z7BjD73-q(Or=MiW$4t9R#45MVe>G?2I>gE4@n5mzJFjE#A z3f?F#)Ft+o?bnz%msG+mONcQ=J0Iso_XV>CW}GT4*8a`zaL{bIU%T)IZZ)^vPX>B8 ziU96h&2Ef3j(BUI+BhJ=A}{h(V_DJPq~y(whTxW+$&HezhbQd8^hKt91_r^KgR(^6 z^#?>9F1>?2@3n{p0(MiXLpg{Wwlzg_b>XypYDCGB09ICo_kFw~uSb((B8P8e2Og*{ z$JO%H2XIQ|@L$zH~g}{csyd5*P$VE=Ze8rpmFelYrGD&!E0^p7CC^xRTEepM=)VXZMCX3UacS&W3fac z{aBq5rNX73>QbTCIsi+E(GPE7+@i0o`H$m;#N<{y@U33yw+;}BstUnHW7#7|k8WPO zw6(gi0-Ou7Y)%)fQ|b4Jh;(`_!$pigL}>`|e7Vqdr@5A?Wg&AbVIT)P0hSJ%1KPWU zqO@&t?-K$h*TbUMK{275&Z;@F^UHMXDyKhx2+>= z>t6Twlmj7?V0?v?#H}Dw77iqqk`;8z0e1U=HN(@oi#xFU3`fpxuOvww1+Y<=y>jA| zEQg~wyAuACIDpXnM-6YxhfT}+ARkqq1k>|)&9p52f?H@XHtIE8b&&4i)s7YJP&mI^ zukMjzy#E7cN4DQ3r2*2iYrTuAUZ#r)z1WyMPKpKC0;jeG$)h%h#Xk2!7P&HOWttvh z>K5Wm8dX;d2;p93M;7Ep4f#)`JYw@9FgqyJ?hH!U%4iOvFv&~+L|cg7tLf&F`)~^l zw{i9N^)tAB0pXU7KA~3T{i~#RdswP+RPJ$ZzvZekFEvLFpFH%m z@kc%%80AbzB&?7nQn9er?ZQC=cNLA$M@Yk?#XMP@FIh;&0_}r{8eA-6F+^bpU>6p1 z*$_$eRNx71mN8>gjfM^PiP?XH*4aTXkw4np6sRh=ed}VJe zCCGz-t8514qf=tU{7{6Y%H84uT#`+RtE$pGa)c1Ofrtj09w-$ty(Dso!Mt!>shOe5 z!WSo;XcjpaS3$w!elw%dOA*4c_93Hhg6J*{#$pz&41p!Nym2Is^MRvK1216mJ}&4b z`o>5W5({0yZl=a6L=pdo8n9Yd5=GwCCONH&mrK9i=gzAn12pbKY9Z5hkQ;!8T7I)B-(i~PKIN*pS&H*X6c zhzX5qj}P?$oxM|a;eg|7dugHvfo$61YCptJmO-fU_LFCGpA*!v`x$DR?nV7k&y$E)H>Y!p#D1O2?uDv3K&B*vE^B z^Ne9yUn7K#cSqm{N4k6w?)_r6-i>&1WMlKvdsv zi!dMKCkBn{$s(q;Ib4eetypB7TdKxb!1t3~y_jrP+PF5NlfWx8(_*VOb2N~AkuOA8 zVlg>?t;h+<>&$C)|Bb0A1wd2%rWGj*Q0`KG(ecfavOKC7@DR54oAXI6YdxO1co z<5lPv%Ct|noWReZr-nCnVJc=8dG;P@nPYwv|9;?#XmKniKa6)GHQ9s%jlVi7s3hq9 z4&ri2b=6PN~KXQkAA~v0$nt-0UZ2pOU^X{WU1bE*Dgz{LrZvAGhxr6gUMbqlEfe3&Nd@rC_yP%EI$;W!$M$l}Tk{mSkWv(;P(?-B?%SJaA6~Ap)7RT5Kp)wc=qPt7_RGoEj2DbK7u)j|wFk!=PQBjg-W_PUa z<-QwgHy{#MxKu<>C7j0fiM!@9J?GS3OiH@Qcbc5eiaJ-&so%olWF}Wt@Bqa)8bmy8 zGnq&=LZ3x)m}p*$5Ey!`fW-?kZ7)pO9{0uMf~#7Ol42Hg+KrYPGPzbRCYLpsk4uOh zQJLdq3N=#PA#XC~nYcX8f~3`Aa+RkSFl@=MT8zw!@P&}{PCTo!Eo%!5gE7ktrQETE zwx5I%+|9Hjr8KCV)wVgxoo$F_jiqSFN7k1mPab0=D^auLq%%O$$<3KkKmMSetz zZG^Kj_OWE^@`cM#d+O?J$;*t4`Jo9w2#M;DcH3B+SE}_=N$oZmGrVrVpM$vvC`FB{aP4AA#w|tK zAeQ)I(QW~@E-{V!xs!o$8-k%rOd{YV>hDN_*;V>3TJA)xwQM52On^%p=|M_m%#un8 zPLP@ABV*K}?UC?d0*YR8#Aj^vQc`x=noWLPSFKb%XuU+qTw+YFj0xis?vQ(2%$iw9 zAP3ImH7!lfqG?f6Ju3wLv);2rTzl&yN)m&AyH=^SDSO?E*1rCHB)KETM8_rLBBPQ5 z4RUHc0QsafYIzD&Gh+;S5E;hV`QrWtGAwdIOIbMSjC>>qYKRI8HSn9^lQ)<}>BU$U zS7ijTB*5*uK1%=CBf2OyOvTwxNu6`rt;Rc6RzOXZoW$!(#lj_?Lq`Ne8FR3eV#KQ` z&W&qs9kX4>k_U$AE(9}U7)WRG_Hl+q#omI>SvaLso0o}^x*Q_v;yMXVQokt$$Tf9A zT4h>LaF%wtm%cD}idvV}JE=FZ*`-*(5P%5tViS`~$Q46~b=DtL2Ejoa;^J2eeW@Ia z(LyyKra|&H^Iz&Mtj%w%@mwg424CjLZ;>fL}rOo#7K&m;TRJ;+a|*jT1x=KqEp0 z3=iu7um3LUH>yn{RGi(AwB(;Hry$$h=4AP#vRs|DW!w-#XAW@Yw+XJ@Z&F2n`rL9BB0^^v3#V#Sz3oPw9qVVOIi#d3H%#GF-LdM zZkJP7MKi|`w6bIpiO&&eUFJ5f-5aTfq2h6xp{yLkq6T6W3n1ObjLOI%9BkyGG{^El zt?}#u%P!Vw*S@ebB(o=K!xvq4D$gT4G*oeIkT3x?RC#bkfJFWgvI4rLd{$nf@;6(R z2^3L92J6W%zKA;hrU{xEdXH>h#aIC;Ll25rwl!tiy`f8Dm{V34UDLo&(yXU#aMKEx zq9HbEJtnOcQRq@ff>C)Dt`f2uig{Mh6H<);G=hrwl4}ebsRVwmjc7?UVB=mcTzUIS zSufLqsuyl74%+Gz3mbX7TC+u_x55MiTW+*&(bmIx9$Y+tCqtMjf@&zHdl~~Q&~OzY z{nT6l(}PgfMi1xFMb4%_Bi1%)n;2=tS?R`&ZnuUw;LbW>i*RzIs7~-G+wIn@mrf=K z-)$NcoIVyX6+@$1NAFy|x}Y+MbEPuoNr}}0^7^7}{XCLhOpGp*vmZ&oB?LEsGlQ)> z+yyY0`Y(zeyAC9qgOJLIONIIm zS)`)818cFc09AaU#RxlaW~4Vx(8paXsO^bn0J)@0I3iA?7a{*R%yF%#6hSj+OpE$W zoPpDkqcf|nKDi#j42(6aTzRFR%G|@zh3TbZ-bsTDaOlLL(^M5Lyuq$lj+qJtbbA3o$keHa+`75M3WmU6?kp z1k0pUb4&v}{+1%t6%j03j?PRGm*{0qMOR9+{8PWz@Wq;@?!NHGpvs3f!Y*qVSckyZ zQldZsWofbq0y>rya6vmYz$fN;Q@dKq@q9)+s5#7^D3m}(?CNDLzaD40^10IK%y;M6 zz`gE0YITp-7wC%%TGCEvoi#nS+JUr6z;ic^12Za7P#KEoiaU5^LCiChExh z*kQSpu~XXyo{!|GdjbCE1io)}M1)5DhAC2B`LQ#8z?hwS$!yXA=_QB#gc_anKo>?U z=P67&am?l-0BVDCFSQTDa?Z@s(gC85rN;JPO%5-?LuVsdD};`YUZOkx?HOk&;0D`R z3X5C2Gw*v{cqwXMo@nCbPLhdtB>LBAhT^0!I1dPum{Ww~9P^Hn%~Iy%bsd8;@0(Je zRj3i_ES%HrHkd=|!sKr|N*pEP_D7ou`IABIgloA434?(vOEI~|s2>!KxLcKBav7Zy zSzxn)rO3O#+7igtbTG--0cV!qfLk+3rkkL?c&Lfn^tDpwdWS%ya|&)AZ7D)_XQLAE zC_ewCE3S3YVoB?i6c%Ga37b$kVmHWizY#k)HSxNVW) zElY4~RjgnN^#vk7$0esFS}*wwDZ@KRmI`os=LLc&1hx{%YSuli9`BJ`9AQW=5*_gz zP9tkpq>_{W7 z%gTSJwP|Cid1Jcijj{D)I7e1GkLX49+7)aD;8dBMo=GYQ*q@~mg|4|x zuXno=QjW~Qrbgphd^&92Glx%80LGBk1Wdl+ksGF4h}c4s1CwVECaxpR>JzPCL{X%a zff;g$vp6PzC{L)gX`G)h;8jXQRvcGl*jS{_e3+8h6H!4u_z22{QK$P#gXBtYC&QlCvTv?(_xkU4>ha=-wK{RK~gjpZu;0~jNrQrV`>_k zIJs3yRxLPZ1A%rdq8;4%vHOnz6;dWLNhEUPb|oz<#)uMxBeJ^r;uz0rGCCm7NRT9k z2(d@}AiXJySOZ6$45bQ(oYdQ|LXeMHUrA&pF0woUb*;slKMM1@ox8$k5V8t~4?MbV z#bSwE4Zc9(uU|?|2N6N>APp%NAV_cktDO)(su^(uFc32ieL={@5}3~^p3cy+V+7vI1EJ!lLNIBn=JO?0~?s)?0m5o5u(tHaq$)wf6h&bdsrP_;ffqG ziYWQ>&3pmTEt(fUm^+(?m-yAXRQanejwgM8OdH+!gUul-0g}DHPZ~j6HbJfw3B6Ir(5Q6W0^CA z#YD`Mv3`={E;P$f?vyRqbYueYoC%c9VtW#v5I{=#&!IAceo2muro}mm+qellY*=vS zovZ@*%qlX$!8RZBd;oV7?j0p(aNo*V{&)KHhB!>Z`Yw(ma$id+Sw@<>_ziuFUgyju z)H4c3lr|14;lOAo%pXh_*7YcjGlvw&-m*M7ojNoZ-cCrX{LYg22U8rTYogBqfD(pq z7iU{ovMxU1_YQx2s1IlE_sB9UC_V;ZWIYGroyD2SNARYn{D!buW;jh)7G#f~Z_Tyc+PPm^lA4e4n0_s*0+DzOCp?ghR~7?7hfFVF&RyXUs|Y-gphI#9B~ zY$AvH?;zvJ%?p&+?xHN9Vq!E;bQP!+`BFcerjbu%8^ZX@Jgd$sx*Job_QXL%tmN4+ zgnb5EPRO#2^`(}naY%$!T~V4H3yger;XmP`%y7uyksAwG8fH{QsYtyRXlF63Gc_w8 zBNU;zBkJH_GoDu2A-gL$9bZsnpBXXFu;uh=Nrw$F*@&`8ExhkM!rcuyT1gnWG7yyt zW7KRvOhF_caAlm{G^O9Uf5#odI*d1V50i`lhOzKEOQz?IhiHyv7wb1Hw75JJ3)Nw| zmwk4)-ksh9p`38mD`RzXd|4$iSM4i7VAJMRdL@lzV~AT9ui`x*0;rnTb&TVTP_P?5#r0V(%O|;*-~0 zENd^N#$aJN?$YOW7|iO&oaQp7`>Gfk5K{=yP7P9)-TGN^c+Qu24)6GA7M0m?hYBJ? zp=)GVAM%Z2o)m3$!6x}7OTDK26fAvCQ4k8?33mHwq z^(72AnS?gRf`uoOE0a_;5S;R-?~UcdP$&IR+o-L|6FRHYgsO7Jr0ig9So|KpHXWJJ zpw=;(4CiD$J)s+MSQg7Pt(T;G@!;mg{BaG+A>pkJ8WsGZYv;|(JtB+Aqh~BfrC8J# z&<(P2aInimvPF{+{515&g>V)P4UkD6o7Pl~p>m5YmS(5kfjgH*JSSO1$64l;gjzt80$hAIzF>gJocxUKr9yE8o%Xc70G-)j@r3=GdBwDXpHWYMstGn+7)N^ z$akOat9AFV{~yqt<3tQKOn2R~T?yLwFEaf6udvaX&B2CdbT7Vee^P(F=7Q~v-JEo3 z-M`a#)TQCS(>QJn*4fEAE@%ppNy(v|1_wQ^Ovj8KyI@dV;BxPOBZA=5JzB{nHD5l7tUvhm+2 zYG5(nAV>rCq89;&oj@m0<5QIEVU8{DX+PS9vJ7b*j3+4iU{cqP&p@ng*L6}xMS)bY zUDSvRMd^0GP1yaEZ2<*YHf7U-t$Q{$fx_A>aM6`YRW_X`F%hhDWga51WTFlI|M@HeV)YWmwF`&wGkD~ z$f4s7F(;3RW8vm#Gsq@n3_CSux-v0^j-H?Li5+YEY}xUcb7IP$Q4ae;BL#wRj;Nu? zu|s?0Y|BVl9yzRCGe={DFKmx$q!pxiQbpfO0| z;Ko~?wzkjud?E(t&ALSMT;PLxQkLLm(K04bZC?h3evD4mII2xJSK|hfwa%7nE|cxN zF)~fr?^_l37_1Z)+ORmY*pSfAuvDQ7mrv~6uE@3`Fw8y6mO*Ncl`KBKZyW_eEv8Hr zg%Re)O^Tfyp98uLeoOCV)_UjlJ}mJ_2f{G3$__uhk@{U2EQzoB!f4(o9LEY)QLuAW zq7XAwu$S$I$+$*uv~{tiq@4`Qh^bK4Ug+roZZ1dYDXquMxBi9Ob5jCAbeT+Z8bZ7w z6>V3j|9?sU5$gw3`eFewAh@aDX{6A{-zha>(xSbA29hYhvM@qn46#R**`rZJJR4u; z4j+nzCo{bF)N(=p4aw@PSG-LE#}V)y>%!`=&+R*83-=zX`!Ofb>|f!Egq49M<7RTu z9pZ$e3&N#V!$J~0oMs^?C?_Kx4PJeCx8`js9w0dZs-rdh^85kDGi6xaLQYSs?t#F`1y z6SqxdvusL4rWvtZ>2@$hDGSg6!d+q;x6uZ1tm~1up?{hwL!;=fcx5=~LdNM1w6G

Zo?_u`6eIYq&=}+`$W;>eYgFSH)mhvUNQRx-3 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

B!Z&+5N?UC{5+VKoA`;RLoXU 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 literal 0 HcmV?d00001 diff --git a/rhel8-branch/.doctrees/livemedia-creator.doctree b/rhel8-branch/.doctrees/livemedia-creator.doctree new file mode 100644 index 0000000000000000000000000000000000000000..f6049836f1048e515b33342ccb6785adcef1a7ab GIT binary patch literal 167828 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

-<@VtV$03 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 literal 0 HcmV?d00001 diff --git a/rhel8-branch/.doctrees/lorax-composer.doctree b/rhel8-branch/.doctrees/lorax-composer.doctree new file mode 100644 index 0000000000000000000000000000000000000000..219fcdbe96dd8ebe69b54b11a7b5b647678e33b3 GIT binary patch literal 112884 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 literal 0 HcmV?d00001 diff --git a/rhel8-branch/.doctrees/modules.doctree b/rhel8-branch/.doctrees/modules.doctree new file mode 100644 index 0000000000000000000000000000000000000000..f289caa87231955075cf04f157d5e1452c09b12d GIT binary patch literal 2535 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 XpBUbm4F{8S5=t{oL{jN1hyDKn=}CA` literal 0 HcmV?d00001 diff --git a/rhel8-branch/.doctrees/pylorax.api.doctree b/rhel8-branch/.doctrees/pylorax.api.doctree new file mode 100644 index 0000000000000000000000000000000000000000..276e664880b1e10968c546ce922cebbfcd072609 GIT binary patch literal 700855 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 z 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≪k+%A80J!AYnW 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 + + + + + + + + Overview: module code — Lorax 28.14.33 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

    + + + + + + + + + + + + \ No newline at end of file diff --git a/rhel8-branch/_modules/pylorax.html b/rhel8-branch/_modules/pylorax.html new file mode 100644 index 00000000..3283087b --- /dev/null +++ b/rhel8-branch/_modules/pylorax.html @@ -0,0 +1,652 @@ + + + + + + + + + + + pylorax — Lorax 28.14.33 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + + + +
    + + + + + +
    + +
    + + + + + + + + + + + + + + + + + +
    + + + + +
    +
    +
    +
    + +

    Source code for pylorax

    +#
    +# __init__.py
    +#
    +# Copyright (C) 2010-2015  Red Hat, Inc.
    +#
    +# This program is free software; you can redistribute it and/or modify
    +# it under the terms of the GNU General Public License as published by
    +# the Free Software Foundation; either version 2 of the License, or
    +# (at your option) any later version.
    +#
    +# This program is distributed in the hope that it will be useful,
    +# but WITHOUT ANY WARRANTY; without even the implied warranty of
    +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    +# GNU General Public License for more details.
    +#
    +# You should have received a copy of the GNU General Public License
    +# along with this program.  If not, see <http://www.gnu.org/licenses/>.
    +#
    +# Red Hat Author(s):  Martin Gracik <mgracik@redhat.com>
    +#                     David Cantrell <dcantrell@redhat.com>
    +#                     Will Woods <wwoods@redhat.com>
    +
    +# set up logging
    +import logging
    +logger = logging.getLogger("pylorax")
    +logger.addHandler(logging.NullHandler())
    +
    +program_log = logging.getLogger("program")
    +
    +import sys
    +import os
    +import configparser
    +import tempfile
    +import locale
    +from subprocess import CalledProcessError
    +import selinux
    +from glob import glob
    +
    +from pylorax.base import BaseLoraxClass, DataHolder
    +import pylorax.output as output
    +
    +import dnf
    +
    +from pylorax.sysutils import joinpaths, remove, linktree
    +
    +from pylorax.treebuilder import RuntimeBuilder, TreeBuilder
    +from pylorax.buildstamp import BuildStamp
    +from pylorax.treeinfo import TreeInfo
    +from pylorax.discinfo import DiscInfo
    +from pylorax.executils import runcmd, runcmd_output
    +
    +
    +# get lorax version
    +try:
    +    import pylorax.version
    +except ImportError:
    +    vernum = "devel"
    +else:
    +    vernum = pylorax.version.num
    +
    +DRACUT_DEFAULT = ["--xz", "--install", "/.buildstamp", "--no-early-microcode", "--add", "fips"]
    +
    +# List of drivers to remove on ppc64 arch to keep initrd < 32MiB
    +REMOVE_PPC64_DRIVERS = "floppy scsi_debug nouveau radeon cirrus mgag200"
    +REMOVE_PPC64_MODULES = "drm plymouth"
    +
    +# Used for DNF conf.module_platform_id
    +DEFAULT_PLATFORM_ID = "platform:el8"
    +
    +
    [docs]class ArchData(DataHolder): + lib64_arches = ("x86_64", "ppc64", "ppc64le", "s390x", "ia64", "aarch64") + bcj_arch = dict(i386="x86", x86_64="x86", + ppc="powerpc", ppc64="powerpc", ppc64le="powerpc", + arm="arm", armhfp="arm") + + def __init__(self, buildarch): + super(ArchData, self).__init__() + self.buildarch = buildarch + self.basearch = dnf.rpm.basearch(buildarch) + self.libdir = "lib64" if self.basearch in self.lib64_arches else "lib" + self.bcj = self.bcj_arch.get(self.basearch)
    + +
    [docs]class Lorax(BaseLoraxClass): + + def __init__(self): + BaseLoraxClass.__init__(self) + self._configured = False + self.product = None + self.workdir = None + self.arch = None + self.conf = None + self.inroot = None + self.debug = False + self.outputdir = None + self._templatedir = None + + # set locale to C + locale.setlocale(locale.LC_ALL, 'C') + +
    [docs] def configure(self, conf_file="/etc/lorax/lorax.conf"): + self.conf = configparser.SafeConfigParser() + + # set defaults + self.conf.add_section("lorax") + self.conf.set("lorax", "debug", "1") + self.conf.set("lorax", "sharedir", "/usr/share/lorax") + self.conf.set("lorax", "logdir", "/var/log/lorax") + + self.conf.add_section("output") + self.conf.set("output", "colors", "1") + self.conf.set("output", "encoding", "utf-8") + self.conf.set("output", "ignorelist", "/usr/share/lorax/ignorelist") + + self.conf.add_section("templates") + self.conf.set("templates", "ramdisk", "ramdisk.ltmpl") + + self.conf.add_section("compression") + self.conf.set("compression", "type", "xz") + self.conf.set("compression", "args", "") + self.conf.set("compression", "bcj", "on") + + # read the config file + if os.path.isfile(conf_file): + self.conf.read(conf_file) + + # set up the output + self.debug = self.conf.getboolean("lorax", "debug") + output_level = output.DEBUG if self.debug else output.INFO + + if sys.stdout.isatty(): + colors = self.conf.getboolean("output", "colors") + else: + colors = False + encoding = self.conf.get("output", "encoding") + + self.output.basic_config(output_level=output_level, + colors=colors, encoding=encoding) + + ignorelist = self.conf.get("output", "ignorelist") + if os.path.isfile(ignorelist): + with open(ignorelist, "r") as fobj: + for line in fobj: + line = line.strip() + if line and not line.startswith("#"): + self.output.ignore(line) + + # cron does not have sbin in PATH, + # so we have to add it ourselves + os.environ["PATH"] = "{0}:/sbin:/usr/sbin".format(os.environ["PATH"]) + + # remove some environmental variables that can cause problems with package scripts + env_remove = ('DISPLAY', 'DBUS_SESSION_BUS_ADDRESS') + list(os.environ.pop(k) for k in env_remove if k in os.environ) + + self._configured = True
    + + @property + def templatedir(self): + """Find the template directory. + + Pick the first directory under sharedir/templates.d/ if it exists. + Otherwise use the sharedir + """ + if not self._templatedir: + self._templatedir = find_templates(self.conf.get("lorax", "sharedir")) + logger.info("Using templatedir %s", self._templatedir) + return self._templatedir + +
    [docs] def init_stream_logging(self): + sh = logging.StreamHandler() + sh.setLevel(logging.INFO) + logger.addHandler(sh)
    + +
    [docs] def init_file_logging(self, logdir, logname="pylorax.log"): + fh = logging.FileHandler(filename=joinpaths(logdir, logname), mode="w") + fh.setLevel(logging.DEBUG) + logger.addHandler(fh)
    + +
    [docs] def run(self, dbo, product, version, release, variant="", bugurl="", + isfinal=False, workdir=None, outputdir=None, buildarch=None, volid=None, + domacboot=True, doupgrade=True, remove_temp=False, + installpkgs=None, excludepkgs=None, + size=2, + add_templates=None, + add_template_vars=None, + add_arch_templates=None, + add_arch_template_vars=None, + verify=True, + user_dracut_args=None): + + assert self._configured + + installpkgs = installpkgs or [] + excludepkgs = excludepkgs or [] + + if domacboot: + try: + runcmd(["rpm", "-q", "hfsplus-tools"]) + except CalledProcessError: + logger.critical("you need to install hfsplus-tools to create mac images") + sys.exit(1) + + # set up work directory + self.workdir = workdir or tempfile.mkdtemp(prefix="pylorax.work.") + if not os.path.isdir(self.workdir): + os.makedirs(self.workdir) + + # set up log directory + logdir = self.conf.get("lorax", "logdir") + if not os.path.isdir(logdir): + os.makedirs(logdir) + + self.init_stream_logging() + self.init_file_logging(logdir) + + logger.debug("version is %s", vernum) + log_selinux_state() + + logger.debug("using work directory %s", self.workdir) + logger.debug("using log directory %s", logdir) + + # set up output directory + self.outputdir = outputdir or tempfile.mkdtemp(prefix="pylorax.out.") + if not os.path.isdir(self.outputdir): + os.makedirs(self.outputdir) + logger.debug("using output directory %s", self.outputdir) + + # do we have root privileges? + logger.info("checking for root privileges") + if not os.geteuid() == 0: + logger.critical("no root privileges") + sys.exit(1) + + # do we have a proper dnf base object? + logger.info("checking dnf base object") + if not isinstance(dbo, dnf.Base): + logger.critical("no dnf base object") + sys.exit(1) + self.inroot = dbo.conf.installroot + logger.debug("using install root: %s", self.inroot) + + if not buildarch: + buildarch = get_buildarch(dbo) + + logger.info("setting up build architecture") + self.arch = ArchData(buildarch) + for attr in ('buildarch', 'basearch', 'libdir'): + logger.debug("self.arch.%s = %s", attr, getattr(self.arch,attr)) + + logger.info("setting up build parameters") + self.product = DataHolder(name=product, version=version, release=release, + variant=variant, bugurl=bugurl, isfinal=isfinal) + logger.debug("product data: %s", self.product) + + # NOTE: if you change isolabel, you need to change pungi to match, or + # the pungi images won't boot. + isolabel = volid or "%s-%s-%s" % (self.product.name, self.product.version, self.arch.basearch) + + if len(isolabel) > 32: + logger.fatal("the volume id cannot be longer than 32 characters") + sys.exit(1) + + # NOTE: rb.root = dbo.conf.installroot (== self.inroot) + rb = RuntimeBuilder(product=self.product, arch=self.arch, + dbo=dbo, templatedir=self.templatedir, + installpkgs=installpkgs, + excludepkgs=excludepkgs, + add_templates=add_templates, + add_template_vars=add_template_vars) + + logger.info("installing runtime packages") + rb.install() + + # write .buildstamp + buildstamp = BuildStamp(self.product.name, self.product.version, + self.product.bugurl, self.product.isfinal, + self.arch.buildarch, self.product.variant) + + buildstamp.write(joinpaths(self.inroot, ".buildstamp")) + + if self.debug: + rb.writepkglists(joinpaths(logdir, "pkglists")) + rb.writepkgsizes(joinpaths(logdir, "original-pkgsizes.txt")) + + logger.info("doing post-install configuration") + rb.postinstall() + + # write .discinfo + discinfo = DiscInfo(self.product.release, self.arch.basearch) + discinfo.write(joinpaths(self.outputdir, ".discinfo")) + + logger.info("backing up installroot") + installroot = joinpaths(self.workdir, "installroot") + linktree(self.inroot, installroot) + + logger.info("generating kernel module metadata") + rb.generate_module_data() + + logger.info("cleaning unneeded files") + rb.cleanup() + + if verify: + logger.info("verifying the installroot") + if not rb.verify(): + sys.exit(1) + else: + logger.info("Skipping verify") + + if self.debug: + rb.writepkgsizes(joinpaths(logdir, "final-pkgsizes.txt")) + + logger.info("creating the runtime image") + runtime = "images/install.img" + compression = self.conf.get("compression", "type") + compressargs = self.conf.get("compression", "args").split() # pylint: disable=no-member + if self.conf.getboolean("compression", "bcj"): + if self.arch.bcj: + compressargs += ["-Xbcj", self.arch.bcj] + else: + logger.info("no BCJ filter for arch %s", self.arch.basearch) + rb.create_runtime(joinpaths(installroot,runtime), + compression=compression, compressargs=compressargs, + size=size) + rb.finished() + + logger.info("preparing to build output tree and boot images") + treebuilder = TreeBuilder(product=self.product, arch=self.arch, + inroot=installroot, outroot=self.outputdir, + runtime=runtime, isolabel=isolabel, + domacboot=domacboot, doupgrade=doupgrade, + templatedir=self.templatedir, + add_templates=add_arch_templates, + add_template_vars=add_arch_template_vars, + workdir=self.workdir) + + logger.info("rebuilding initramfs images") + if not user_dracut_args: + dracut_args = DRACUT_DEFAULT + else: + dracut_args = [] + for arg in user_dracut_args: + dracut_args += arg.split(" ", 1) + + anaconda_args = dracut_args + ["--add", "anaconda pollcdrom qemu qemu-net prefixdevname-tools"] + + # ppc64 cannot boot an initrd > 32MiB so remove some drivers + if self.arch.basearch in ("ppc64", "ppc64le"): + dracut_args.extend(["--omit-drivers", REMOVE_PPC64_DRIVERS]) + + # Only omit dracut modules from the initrd so that they're kept for + # upgrade.img + anaconda_args.extend(["--omit", REMOVE_PPC64_MODULES]) + + logger.info("dracut args = %s", dracut_args) + logger.info("anaconda args = %s", anaconda_args) + treebuilder.rebuild_initrds(add_args=anaconda_args) + + logger.info("populating output tree and building boot images") + treebuilder.build() + + # write .treeinfo file and we're done + treeinfo = TreeInfo(self.product.name, self.product.version, + self.product.variant, self.arch.basearch) + for section, data in treebuilder.treeinfo_data.items(): + treeinfo.add_section(section, data) + treeinfo.write(joinpaths(self.outputdir, ".treeinfo")) + + # cleanup + if remove_temp: + remove(self.workdir)
    + + +
    [docs]def get_buildarch(dbo): + # get architecture of the available anaconda package + buildarch = None + q = dbo.sack.query() + a = q.available() + for anaconda in a.filter(name="anaconda-core"): + if anaconda.arch != "src": + buildarch = anaconda.arch + break + if not buildarch: + logger.critical("no anaconda-core package in the repository") + sys.exit(1) + + return buildarch
    + + +
    [docs]def setup_logging(logfile, theLogger): + """ + Setup the various logs + + :param logfile: filename to write the log to + :type logfile: string + :param theLogger: top-level logger + :type theLogger: logging.Logger + """ + if not os.path.isdir(os.path.abspath(os.path.dirname(logfile))): + os.makedirs(os.path.abspath(os.path.dirname(logfile))) + + # Setup logging to console and to logfile + logger.setLevel(logging.DEBUG) + theLogger.setLevel(logging.DEBUG) + + sh = logging.StreamHandler() + sh.setLevel(logging.INFO) + fmt = logging.Formatter("%(asctime)s: %(message)s") + sh.setFormatter(fmt) + logger.addHandler(sh) + theLogger.addHandler(sh) + + fh = logging.FileHandler(filename=logfile, mode="w") + fh.setLevel(logging.DEBUG) + fmt = logging.Formatter("%(asctime)s %(levelname)s %(name)s: %(message)s") + fh.setFormatter(fmt) + logger.addHandler(fh) + theLogger.addHandler(fh) + + # External program output log + program_log.setLevel(logging.DEBUG) + f = os.path.abspath(os.path.dirname(logfile))+"/program.log" + fh = logging.FileHandler(filename=f, mode="w") + fh.setLevel(logging.DEBUG) + program_log.addHandler(fh)
    + + +
    [docs]def find_templates(templatedir="/usr/share/lorax"): + """ Find the templates to use. + + :param str templatedir: Top directory to search for templates + :returns: Path to templates + :rtype: str + + If there is a templates.d directory under templatedir the + lowest numbered directory entry is returned. + + eg. /usr/share/lorax/templates.d/99-generic/ + """ + if os.path.isdir(joinpaths(templatedir, "templates.d")): + try: + templatedir = sorted(glob(joinpaths(templatedir, "templates.d", "*")))[0] + except IndexError: + pass + return templatedir
    + +
    [docs]def log_selinux_state(): + """Log the current state of selinux""" + if selinux.is_selinux_enabled(): + if selinux.security_getenforce(): + logger.info("selinux is enabled and in Enforcing mode") + else: + logger.info("selinux is enabled and in Permissive mode") + else: + logger.info("selinux is Disabled")
    +
    + +
    + +
    +
    + + +
    + +
    +

    + © Copyright 2018-2019, Red Hat, Inc. + +

    +
    + Built with Sphinx using a theme provided by Read the Docs. + +
    + +
    +
    + +
    + +
    + + + + + + + + + + + + \ No newline at end of file diff --git a/rhel8-branch/_modules/pylorax/api/cmdline.html b/rhel8-branch/_modules/pylorax/api/cmdline.html new file mode 100644 index 00000000..71cd21d4 --- /dev/null +++ b/rhel8-branch/_modules/pylorax/api/cmdline.html @@ -0,0 +1,263 @@ + + + + + + + + + + + pylorax.api.cmdline — Lorax 28.14.33 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + + + +
    + + + + + +
    + +
    + + + + + + + + + + + + + + + + + +
    + + + + +
    +
    +
    +
    + +

    Source code for pylorax.api.cmdline

    +#
    +# cmdline.py
    +#
    +# Copyright (C) 2018 Red Hat, Inc.
    +#
    +# This program is free software; you can redistribute it and/or modify
    +# it under the terms of the GNU General Public License as published by
    +# the Free Software Foundation; either version 2 of the License, or
    +# (at your option) any later version.
    +#
    +# This program is distributed in the hope that it will be useful,
    +# but WITHOUT ANY WARRANTY; without even the implied warranty of
    +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    +# GNU General Public License for more details.
    +#
    +# You should have received a copy of the GNU General Public License
    +# along with this program.  If not, see <http://www.gnu.org/licenses/>.
    +#
    +import os
    +import sys
    +import argparse
    +
    +from pylorax import vernum
    +
    +DEFAULT_USER  = "root"
    +DEFAULT_GROUP = "weldr"
    +
    +version = "{0}-{1}".format(os.path.basename(sys.argv[0]), vernum)
    +
    +
    [docs]def lorax_composer_parser(): + """ Return the ArgumentParser for lorax-composer""" + + parser = argparse.ArgumentParser(description="Lorax Composer API Server", + fromfile_prefix_chars="@") + + parser.add_argument("--socket", default="/run/weldr/api.socket", metavar="SOCKET", + help="Path to the socket file to listen on") + parser.add_argument("--user", default=DEFAULT_USER, metavar="USER", + help="User to use for reduced permissions") + parser.add_argument("--group", default=DEFAULT_GROUP, metavar="GROUP", + help="Group to set ownership of the socket to") + parser.add_argument("--log", dest="logfile", default="/var/log/lorax-composer/composer.log", metavar="LOG", + help="Path to logfile (/var/log/lorax-composer/composer.log)") + parser.add_argument("--mockfiles", default="/var/tmp/bdcs-mockfiles/", metavar="MOCKFILES", + help="Path to JSON files used for /api/mock/ paths (/var/tmp/bdcs-mockfiles/)") + parser.add_argument("--sharedir", type=os.path.abspath, metavar="SHAREDIR", + help="Directory containing all the templates. Overrides config file sharedir") + parser.add_argument("-V", action="store_true", dest="showver", + help="show program's version number and exit") + parser.add_argument("-c", "--config", default="/etc/lorax/composer.conf", metavar="CONFIG", + help="Path to lorax-composer configuration file.") + parser.add_argument("--releasever", default=None, metavar="STRING", + help="Release version to use for $releasever in dnf repository urls") + parser.add_argument("--tmp", default="/var/tmp", + help="Top level temporary directory") + parser.add_argument("--proxy", default=None, metavar="PROXY", + help="Set proxy for DNF, overrides configuration file setting.") + parser.add_argument("--no-system-repos", action="store_true", default=False, + help="Do not copy over system repos from /etc/yum.repos.d/ at startup") + parser.add_argument("BLUEPRINTS", metavar="BLUEPRINTS", + help="Path to the blueprints") + + return parser
    +
    + +
    + +
    +
    + + +
    + +
    +

    + © Copyright 2018-2019, Red Hat, Inc. + +

    +
    + Built with Sphinx using a theme provided by Read the Docs. + +
    + +
    +
    + +
    + +
    + + + + + + + + + + + + \ No newline at end of file diff --git a/rhel8-branch/_modules/pylorax/api/compose.html b/rhel8-branch/_modules/pylorax/api/compose.html new file mode 100644 index 00000000..304c7362 --- /dev/null +++ b/rhel8-branch/_modules/pylorax/api/compose.html @@ -0,0 +1,1405 @@ + + + + + + + + + + + pylorax.api.compose — Lorax 28.14.33 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + + + +
    + + + + + +
    + +
    + + + + + + + + + + + + + + + + + +
    + + + + +
    +
    +
    +
    + +

    Source code for pylorax.api.compose

    +# Copyright (C) 2018-2019 Red Hat, Inc.
    +#
    +# This program is free software; you can redistribute it and/or modify
    +# it under the terms of the GNU General Public License as published by
    +# the Free Software Foundation; either version 2 of the License, or
    +# (at your option) any later version.
    +#
    +# This program is distributed in the hope that it will be useful,
    +# but WITHOUT ANY WARRANTY; without even the implied warranty of
    +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    +# GNU General Public License for more details.
    +#
    +# You should have received a copy of the GNU General Public License
    +# along with this program.  If not, see <http://www.gnu.org/licenses/>.
    +#
    +""" Setup for composing an image
    +
    +Adding New Output Types
    +-----------------------
    +
    +The new output type must add a kickstart template to ./share/composer/ where the
    +name of the kickstart (without the trailing .ks) matches the entry in compose_args.
    +
    +The kickstart should not have any url or repo entries, these will be added at build
    +time. The %packages section should be the last thing, and while it can contain mandatory
    +packages required by the output type, it should not have the trailing %end because the
    +package NEVRAs will be appended to it at build time.
    +
    +compose_args should have a name matching the kickstart, and it should set the novirt_install
    +parameters needed to generate the desired output. Other types should be set to False.
    +
    +"""
    +import logging
    +log = logging.getLogger("lorax-composer")
    +
    +import os
    +from glob import glob
    +from io import StringIO
    +from math import ceil
    +import pytoml as toml
    +import shutil
    +from uuid import uuid4
    +
    +# Use pykickstart to calculate disk image size
    +from pykickstart.parser import KickstartParser
    +from pykickstart.version import makeVersion
    +
    +from pylorax import ArchData, find_templates, get_buildarch
    +from pylorax.api.gitrpm import create_gitrpm_repo
    +from pylorax.api.projects import projects_depsolve, projects_depsolve_with_size, dep_nevra
    +from pylorax.api.projects import ProjectsError
    +from pylorax.api.recipes import read_recipe_and_id
    +from pylorax.api.timestamp import TS_CREATED, write_timestamp
    +from pylorax.base import DataHolder
    +from pylorax.imgutils import default_image_name
    +from pylorax.ltmpl import LiveTemplateRunner
    +from pylorax.sysutils import joinpaths, flatconfig
    +
    +
    +
    [docs]def test_templates(dbo, share_dir): + """ Try depsolving each of the the templates and report any errors + + :param dbo: dnf base object + :type dbo: dnf.Base + :returns: List of template types and errors + :rtype: List of errors + + Return a list of templates and errors encountered or an empty list + """ + template_errors = [] + for compose_type, enabled in compose_types(share_dir): + if not enabled: + continue + + # Read the kickstart template for this type + ks_template_path = joinpaths(share_dir, "composer", compose_type) + ".ks" + ks_template = open(ks_template_path, "r").read() + + # How much space will the packages in the default template take? + ks_version = makeVersion() + ks = KickstartParser(ks_version, errorsAreFatal=False, missingIncludeIsFatal=False) + ks.readKickstartFromString(ks_template+"\n%end\n") + pkgs = [(name, "*") for name in ks.handler.packages.packageList] + grps = [grp.name for grp in ks.handler.packages.groupList] + try: + projects_depsolve(dbo, pkgs, grps) + except ProjectsError as e: + template_errors.append("Error depsolving %s: %s" % (compose_type, str(e))) + + return template_errors
    + + +
    [docs]def repo_to_ks(r, url="url"): + """ Return a kickstart line with the correct args. + :param r: DNF repository information + :type r: dnf.Repo + :param url: "url" or "baseurl" to use for the baseurl parameter + :type url: str + :returns: kickstart command arguments for url/repo command + :rtype: str + + Set url to "baseurl" if it is a repo, leave it as "url" for the installation url. + """ + cmd = "" + # url uses --url not --baseurl + if r.baseurl: + cmd += '--%s="%s" ' % (url, r.baseurl[0]) + elif r.metalink: + cmd += '--metalink="%s" ' % r.metalink + elif r.mirrorlist: + cmd += '--mirrorlist="%s" ' % r.mirrorlist + else: + raise RuntimeError("Repo has no baseurl, metalink, or mirrorlist") + + if r.proxy: + cmd += '--proxy="%s" ' % r.proxy + + if not r.sslverify: + cmd += '--noverifyssl' + + if r.sslcacert: + cmd += ' --sslcacert="%s"' % r.sslcacert + if r.sslclientcert: + cmd += ' --sslclientcert="%s"' % r.sslclientcert + if r.sslclientkey: + cmd += ' --sslclientkey="%s"' % r.sslclientkey + + return cmd
    + + +
    [docs]def bootloader_append(line, kernel_append): + """ Insert the kernel_append string into the --append argument + + :param line: The bootloader ... line + :type line: str + :param kernel_append: The arguments to append to the --append section + :type kernel_append: str + + Using pykickstart to process the line is the best way to make sure it + is parsed correctly, and re-assembled for inclusion into the final kickstart + """ + ks_version = makeVersion() + ks = KickstartParser(ks_version, errorsAreFatal=False, missingIncludeIsFatal=False) + ks.readKickstartFromString(line) + + if ks.handler.bootloader.appendLine: + ks.handler.bootloader.appendLine += " %s" % kernel_append + else: + ks.handler.bootloader.appendLine = kernel_append + + # Converting back to a string includes a comment, return just the bootloader line + return str(ks.handler.bootloader).splitlines()[-1]
    + + +
    [docs]def get_kernel_append(recipe): + """Return the customizations.kernel append value + + :param recipe: + :type recipe: Recipe object + :returns: append value or empty string + :rtype: str + """ + if "customizations" not in recipe or \ + "kernel" not in recipe["customizations"] or \ + "append" not in recipe["customizations"]["kernel"]: + return "" + return recipe["customizations"]["kernel"]["append"]
    + + +
    [docs]def timezone_cmd(line, settings): + """ Update the timezone line with the settings + + :param line: The timezone ... line + :type line: str + :param settings: A dict with timezone and/or ntpservers list + :type settings: dict + + Using pykickstart to process the line is the best way to make sure it + is parsed correctly, and re-assembled for inclusion into the final kickstart + """ + ks_version = makeVersion() + ks = KickstartParser(ks_version, errorsAreFatal=False, missingIncludeIsFatal=False) + ks.readKickstartFromString(line) + + if "timezone" in settings: + ks.handler.timezone.timezone = settings["timezone"] + if "ntpservers" in settings: + ks.handler.timezone.ntpservers = settings["ntpservers"] + + # Converting back to a string includes a comment, return just the timezone line + return str(ks.handler.timezone).splitlines()[-1]
    + + +
    [docs]def get_timezone_settings(recipe): + """Return the customizations.timezone dict + + :param recipe: + :type recipe: Recipe object + :returns: append value or empty string + :rtype: dict + """ + if "customizations" not in recipe or \ + "timezone" not in recipe["customizations"]: + return {} + return recipe["customizations"]["timezone"]
    + + +
    [docs]def lang_cmd(line, languages): + """ Update the lang line with the languages + + :param line: The lang ... line + :type line: str + :param settings: The list of languages + :type settings: list + + Using pykickstart to process the line is the best way to make sure it + is parsed correctly, and re-assembled for inclusion into the final kickstart + """ + ks_version = makeVersion() + ks = KickstartParser(ks_version, errorsAreFatal=False, missingIncludeIsFatal=False) + ks.readKickstartFromString(line) + + if languages: + ks.handler.lang.lang = languages[0] + + if len(languages) > 1: + ks.handler.lang.addsupport = languages[1:] + + # Converting back to a string includes a comment, return just the lang line + return str(ks.handler.lang).splitlines()[-1]
    + + +
    [docs]def get_languages(recipe): + """Return the customizations.locale.languages list + + :param recipe: The recipe + :type recipe: Recipe object + :returns: list of language strings + :rtype: list + """ + if "customizations" not in recipe or \ + "locale" not in recipe["customizations"] or \ + "languages" not in recipe["customizations"]["locale"]: + return [] + return recipe["customizations"]["locale"]["languages"]
    + + +
    [docs]def keyboard_cmd(line, layout): + """ Update the keyboard line with the layout + + :param line: The keyboard ... line + :type line: str + :param settings: The keyboard layout + :type settings: str + + Using pykickstart to process the line is the best way to make sure it + is parsed correctly, and re-assembled for inclusion into the final kickstart + """ + ks_version = makeVersion() + ks = KickstartParser(ks_version, errorsAreFatal=False, missingIncludeIsFatal=False) + ks.readKickstartFromString(line) + + if layout: + ks.handler.keyboard.keyboard = layout + ks.handler.keyboard.vc_keymap = "" + ks.handler.keyboard.x_layouts = [] + + # Converting back to a string includes a comment, return just the keyboard line + return str(ks.handler.keyboard).splitlines()[-1]
    + + +
    [docs]def get_keyboard_layout(recipe): + """Return the customizations.locale.keyboard list + + :param recipe: The recipe + :type recipe: Recipe object + :returns: The keyboard layout string + :rtype: str + """ + if "customizations" not in recipe or \ + "locale" not in recipe["customizations"] or \ + "keyboard" not in recipe["customizations"]["locale"]: + return [] + return recipe["customizations"]["locale"]["keyboard"]
    + + +
    [docs]def firewall_cmd(line, settings): + """ Update the firewall line with the new ports and services + + :param line: The firewall ... line + :type line: str + :param settings: A dict with the list of services and ports to enable and disable + :type settings: dict + + Using pykickstart to process the line is the best way to make sure it + is parsed correctly, and re-assembled for inclusion into the final kickstart + """ + ks_version = makeVersion() + ks = KickstartParser(ks_version, errorsAreFatal=False, missingIncludeIsFatal=False) + ks.readKickstartFromString(line) + + # Do not override firewall --disabled + if ks.handler.firewall.enabled != False and settings: + ks.handler.firewall.ports = sorted(set(settings["ports"] + ks.handler.firewall.ports)) + ks.handler.firewall.services = sorted(set(settings["enabled"] + ks.handler.firewall.services)) + ks.handler.firewall.remove_services = sorted(set(settings["disabled"] + ks.handler.firewall.remove_services)) + + # Converting back to a string includes a comment, return just the keyboard line + return str(ks.handler.firewall).splitlines()[-1]
    + + +
    [docs]def get_firewall_settings(recipe): + """Return the customizations.firewall settings + + :param recipe: The recipe + :type recipe: Recipe object + :returns: A dict of settings + :rtype: dict + """ + settings = {"ports": [], "enabled": [], "disabled": []} + + if "customizations" not in recipe or \ + "firewall" not in recipe["customizations"]: + return settings + + settings["ports"] = recipe["customizations"]["firewall"].get("ports", []) + + if "services" in recipe["customizations"]["firewall"]: + settings["enabled"] = recipe["customizations"]["firewall"]["services"].get("enabled", []) + settings["disabled"] = recipe["customizations"]["firewall"]["services"].get("disabled", []) + return settings
    + + +
    [docs]def services_cmd(line, settings): + """ Update the services line with additional services to enable/disable + + :param line: The services ... line + :type line: str + :param settings: A dict with the list of services to enable and disable + :type settings: dict + + Using pykickstart to process the line is the best way to make sure it + is parsed correctly, and re-assembled for inclusion into the final kickstart + """ + # Empty services and no additional settings, return an empty string + if not line and not settings["enabled"] and not settings["disabled"]: + return "" + + ks_version = makeVersion() + ks = KickstartParser(ks_version, errorsAreFatal=False, missingIncludeIsFatal=False) + + # Allow passing in a 'default' so that the enable/disable may be applied to it, without + # parsing it and emitting a kickstart error message + if line != "services": + ks.readKickstartFromString(line) + + # Add to any existing services, removing any duplicates + ks.handler.services.enabled = sorted(set(settings["enabled"] + ks.handler.services.enabled)) + ks.handler.services.disabled = sorted(set(settings["disabled"] + ks.handler.services.disabled)) + + # Converting back to a string includes a comment, return just the keyboard line + return str(ks.handler.services).splitlines()[-1]
    + + +
    [docs]def get_services(recipe): + """Return the customizations.services settings + + :param recipe: The recipe + :type recipe: Recipe object + :returns: A dict of settings + :rtype: dict + """ + settings = {"enabled": [], "disabled": []} + + if "customizations" not in recipe or \ + "services" not in recipe["customizations"]: + return settings + + settings["enabled"] = sorted(recipe["customizations"]["services"].get("enabled", [])) + settings["disabled"] = sorted(recipe["customizations"]["services"].get("disabled", [])) + return settings
    + + +
    [docs]def get_default_services(recipe): + """Get the default string for services, based on recipe + :param recipe: The recipe + + :type recipe: Recipe object + :returns: string with "services" or "" + :rtype: str + + When no services have been selected we don't need to add anything to the kickstart + so return an empty string. Otherwise return "services" which will be updated with + the settings. + """ + services = get_services(recipe) + + if services["enabled"] or services["disabled"]: + return "services" + else: + return ""
    + + +
    [docs]def customize_ks_template(ks_template, recipe): + """ Customize the kickstart template and return it + + :param ks_template: The kickstart template + :type ks_template: str + :param recipe: + :type recipe: Recipe object + + Apply customizations to existing template commands, or add defaults for ones that are + missing and required. + + Apply customizations.kernel.append to the bootloader argument in the template. + Add bootloader line if it is missing. + + Add default timezone if needed. It does NOT replace an existing timezone entry + """ + # Commands to be modified [NEW-COMMAND-FUNC, NEW-VALUE, DEFAULT, REPLACE] + # The function is called with a kickstart command string and the value to replace + # The value is specific to the command, and is understood by the function + # The default is a complete kickstart command string, suitable for writing to the template + # If REPLACE is False it will not change an existing entry only add a missing one + commands = {"bootloader": [bootloader_append, + get_kernel_append(recipe), + 'bootloader --location=none', True], + "timezone": [timezone_cmd, + get_timezone_settings(recipe), + 'timezone UTC', False], + "lang": [lang_cmd, + get_languages(recipe), + 'lang en_US.UTF-8', True], + "keyboard": [keyboard_cmd, + get_keyboard_layout(recipe), + 'keyboard --xlayouts us --vckeymap us', True], + "firewall": [firewall_cmd, + get_firewall_settings(recipe), + 'firewall --enabled', True], + "services": [services_cmd, + get_services(recipe), + get_default_services(recipe), True] + } + found = {} + + output = StringIO() + for line in ks_template.splitlines(): + for cmd in commands: + (new_command, value, default, replace) = commands[cmd] + if line.startswith(cmd): + found[cmd] = True + if value and replace: + log.debug("Replacing %s with %s", cmd, value) + print(new_command(line, value), file=output) + else: + log.debug("Skipping %s", cmd) + print(line, file=output) + break + else: + # No matches, write the line as-is + print(line, file=output) + + # Write out defaults for the ones not found + # These must go FIRST because the template still needs to have the packages added + defaults = StringIO() + for cmd in commands: + if cmd in found: + continue + (new_command, value, default, _) = commands[cmd] + if value and default: + log.debug("Setting %s to use %s", cmd, value) + print(new_command(default, value), file=defaults) + elif default: + log.debug("Setting %s to %s", cmd, default) + print(default, file=defaults) + + return defaults.getvalue() + output.getvalue()
    + + +
    [docs]def write_ks_root(f, user): + """ Write kickstart root password and sshkey entry + + :param f: kickstart file object + :type f: open file object + :param user: A blueprint user dictionary + :type user: dict + :returns: True if it wrote a rootpw command to the kickstart + :rtype: bool + + If the entry contains a ssh key, use sshkey to write it + If it contains password, use rootpw to set it + + root cannot be used with the user command. So only key and password are supported + for root. + """ + wrote_rootpw = False + + # ssh key uses the sshkey kickstart command + if "key" in user: + f.write('sshkey --user %s "%s"\n' % (user["name"], user["key"])) + + if "password" in user: + if any(user["password"].startswith(prefix) for prefix in ["$2b$", "$6$", "$5$"]): + log.debug("Detected pre-crypted password") + f.write('rootpw --iscrypted "%s"\n' % user["password"]) + wrote_rootpw = True + else: + log.debug("Detected plaintext password") + f.write('rootpw --plaintext "%s"\n' % user["password"]) + wrote_rootpw = True + + return wrote_rootpw
    + +
    [docs]def write_ks_user(f, user): + """ Write kickstart user and sshkey entry + + :param f: kickstart file object + :type f: open file object + :param user: A blueprint user dictionary + :type user: dict + + If the entry contains a ssh key, use sshkey to write it + All of the user fields are optional, except name, write out a kickstart user entry + with whatever options are relevant. + """ + # ssh key uses the sshkey kickstart command + if "key" in user: + f.write('sshkey --user %s "%s"\n' % (user["name"], user["key"])) + + # Write out the user kickstart command, much of it is optional + f.write("user --name %s" % user["name"]) + if "home" in user: + f.write(" --homedir %s" % user["home"]) + + if "password" in user: + if any(user["password"].startswith(prefix) for prefix in ["$2b$", "$6$", "$5$"]): + log.debug("Detected pre-crypted password") + f.write(" --iscrypted") + else: + log.debug("Detected plaintext password") + f.write(" --plaintext") + + f.write(" --password \"%s\"" % user["password"]) + + if "shell" in user: + f.write(" --shell %s" % user["shell"]) + + if "uid" in user: + f.write(" --uid %d" % int(user["uid"])) + + if "gid" in user: + f.write(" --gid %d" % int(user["gid"])) + + if "description" in user: + f.write(" --gecos \"%s\"" % user["description"]) + + if "groups" in user: + f.write(" --groups %s" % ",".join(user["groups"])) + + f.write("\n")
    + + +
    [docs]def write_ks_group(f, group): + """ Write kickstart group entry + + :param f: kickstart file object + :type f: open file object + :param group: A blueprint group dictionary + :type user: dict + + gid is optional + """ + if "name" not in group: + raise RuntimeError("group entry requires a name") + + f.write("group --name %s" % group["name"]) + if "gid" in group: + f.write(" --gid %d" % int(group["gid"])) + + f.write("\n")
    + + +
    [docs]def add_customizations(f, recipe): + """ Add customizations to the kickstart file + + :param f: kickstart file object + :type f: open file object + :param recipe: + :type recipe: Recipe object + :returns: None + :raises: RuntimeError if there was a problem writing to the kickstart + """ + if "customizations" not in recipe: + f.write('rootpw --lock\n') + return + customizations = recipe["customizations"] + + # allow customizations to be incorrectly specified as [[customizations]] instead of [customizations] + if isinstance(customizations, list): + customizations = customizations[0] + + if "hostname" in customizations: + f.write("network --hostname=%s\n" % customizations["hostname"]) + + # TODO - remove this, should use user section to define this + if "sshkey" in customizations: + # This is a list of entries + for sshkey in customizations["sshkey"]: + if "user" not in sshkey or "key" not in sshkey: + log.error("%s is incorrect, skipping", sshkey) + continue + f.write('sshkey --user %s "%s"\n' % (sshkey["user"], sshkey["key"])) + + # Creating a user also creates a group. Make a list of the names for later + user_groups = [] + # kickstart requires a rootpw line + wrote_rootpw = False + if "user" in customizations: + # only name is required, everything else is optional + for user in customizations["user"]: + if "name" not in user: + raise RuntimeError("user entry requires a name") + + # root is special, cannot use normal user command for it + if user["name"] == "root": + wrote_rootpw = write_ks_root(f, user) + continue + + write_ks_user(f, user) + user_groups.append(user["name"]) + + if "group" in customizations: + for group in customizations["group"]: + if group["name"] not in user_groups: + write_ks_group(f, group) + else: + log.warning("Skipping group %s, already created by user", group["name"]) + + # Lock the root account if no root user password has been specified + if not wrote_rootpw: + f.write('rootpw --lock\n')
    + + +
    [docs]def get_extra_pkgs(dbo, share_dir, compose_type): + """Return extra packages needed for the output type + + :param dbo: dnf base object + :type dbo: dnf.Base + :param share_dir: Path to the top level share directory + :type share_dir: str + :param compose_type: The type of output to create from the recipe + :type compose_type: str + :returns: List of package names (name only, not NEVRA) + :rtype: list + + Currently this is only needed by live-iso, it reads ./live/live-install.tmpl and + processes only the installpkg lines. It lists the packages needed to complete creation of the + iso using the templates such as x86.tmpl + + Keep in mind that the live-install.tmpl is shared between livemedia-creator and lorax-composer, + even though the results are applied differently. + """ + if compose_type != "live-iso": + return [] + + # get the arch information to pass to the runner + arch = ArchData(get_buildarch(dbo)) + defaults = DataHolder(basearch=arch.basearch) + templatedir = joinpaths(find_templates(share_dir), "live") + runner = LiveTemplateRunner(dbo, templatedir=templatedir, defaults=defaults) + runner.run("live-install.tmpl") + log.debug("extra pkgs = %s", runner.pkgs) + + return runner.pkgnames
    + + +
    [docs]def start_build(cfg, dnflock, gitlock, branch, recipe_name, compose_type, test_mode=0): + """ Start the build + + :param cfg: Configuration object + :type cfg: ComposerConfig + :param dnflock: Lock and YumBase for depsolving + :type dnflock: YumLock + :param recipe: The recipe to build + :type recipe: str + :param compose_type: The type of output to create from the recipe + :type compose_type: str + :returns: Unique ID for the build that can be used to track its status + :rtype: str + """ + share_dir = cfg.get("composer", "share_dir") + lib_dir = cfg.get("composer", "lib_dir") + + # Make sure compose_type is valid, only allow enabled types + type_enabled = dict(compose_types(share_dir)).get(compose_type) + if type_enabled is None: + raise RuntimeError("Invalid compose type (%s), must be one of %s" % (compose_type, [t for t, e in compose_types(share_dir)])) + if not type_enabled: + raise RuntimeError("Compose type '%s' is disabled on this architecture" % compose_type) + + # Some image types (live-iso) need extra packages for composer to execute the output template + with dnflock.lock: + extra_pkgs = get_extra_pkgs(dnflock.dbo, share_dir, compose_type) + log.debug("Extra packages needed for %s: %s", compose_type, extra_pkgs) + + with gitlock.lock: + (commit_id, recipe) = read_recipe_and_id(gitlock.repo, branch, recipe_name) + + # Combine modules and packages and depsolve the list + module_nver = recipe.module_nver + package_nver = recipe.package_nver + package_nver.extend([(name, '*') for name in extra_pkgs]) + + projects = sorted(set(module_nver+package_nver), key=lambda p: p[0].lower()) + deps = [] + log.info("depsolving %s", recipe["name"]) + try: + # This can possibly update repodata and reset the YumBase object. + with dnflock.lock_check: + (installed_size, deps) = projects_depsolve_with_size(dnflock.dbo, projects, recipe.group_names, with_core=False) + except ProjectsError as e: + log.error("start_build depsolve: %s", str(e)) + raise RuntimeError("Problem depsolving %s: %s" % (recipe["name"], str(e))) + + # Read the kickstart template for this type + ks_template_path = joinpaths(share_dir, "composer", compose_type) + ".ks" + ks_template = open(ks_template_path, "r").read() + + # How much space will the packages in the default template take? + ks_version = makeVersion() + ks = KickstartParser(ks_version, errorsAreFatal=False, missingIncludeIsFatal=False) + ks.readKickstartFromString(ks_template+"\n%end\n") + pkgs = [(name, "*") for name in ks.handler.packages.packageList] + grps = [grp.name for grp in ks.handler.packages.groupList] + try: + with dnflock.lock: + (template_size, _) = projects_depsolve_with_size(dnflock.dbo, pkgs, grps, with_core=not ks.handler.packages.nocore) + except ProjectsError as e: + log.error("start_build depsolve: %s", str(e)) + raise RuntimeError("Problem depsolving %s: %s" % (recipe["name"], str(e))) + log.debug("installed_size = %d, template_size=%d", installed_size, template_size) + + # Minimum LMC disk size is 1GiB, and anaconda bumps the estimated size up by 10% (which doesn't always work). + installed_size = int((installed_size+template_size)) * 1.2 + log.debug("/ partition size = %d", installed_size) + + # Create the results directory + build_id = str(uuid4()) + results_dir = joinpaths(lib_dir, "results", build_id) + os.makedirs(results_dir) + + # Write the recipe commit hash + commit_path = joinpaths(results_dir, "COMMIT") + with open(commit_path, "w") as f: + f.write(commit_id) + + # Write the original recipe + recipe_path = joinpaths(results_dir, "blueprint.toml") + with open(recipe_path, "w") as f: + f.write(recipe.toml()) + + # Write the frozen recipe + frozen_recipe = recipe.freeze(deps) + recipe_path = joinpaths(results_dir, "frozen.toml") + with open(recipe_path, "w") as f: + f.write(frozen_recipe.toml()) + + # Write out the dependencies to the results dir + deps_path = joinpaths(results_dir, "deps.toml") + with open(deps_path, "w") as f: + f.write(toml.dumps({"packages":deps})) + + # Save a copy of the original kickstart + shutil.copy(ks_template_path, results_dir) + + with dnflock.lock: + repos = list(dnflock.dbo.repos.iter_enabled()) + if not repos: + raise RuntimeError("No enabled repos, canceling build.") + + # Create the git rpms, if any, and return the path to the repo under results_dir + gitrpm_repo = create_gitrpm_repo(results_dir, recipe) + + # Create the final kickstart with repos and package list + ks_path = joinpaths(results_dir, "final-kickstart.ks") + with open(ks_path, "w") as f: + ks_url = repo_to_ks(repos[0], "url") + log.debug("url = %s", ks_url) + f.write('url %s\n' % ks_url) + for idx, r in enumerate(repos[1:]): + ks_repo = repo_to_ks(r, "baseurl") + log.debug("repo composer-%s = %s", idx, ks_repo) + f.write('repo --name="composer-%s" %s\n' % (idx, ks_repo)) + + if gitrpm_repo: + log.debug("repo gitrpms = %s", gitrpm_repo) + f.write('repo --name="gitrpms" --baseurl="file://%s"\n' % gitrpm_repo) + + # Setup the disk for booting + # TODO Add GPT and UEFI boot support + f.write('clearpart --all --initlabel\n') + + # Write the root partition and it's size in MB (rounded up) + f.write('part / --size=%d\n' % ceil(installed_size / 1024**2)) + + # Some customizations modify the template before writing it + f.write(customize_ks_template(ks_template, recipe)) + + for d in deps: + f.write(dep_nevra(d)+"\n") + + # Include the rpms from the gitrpm repo directory + if gitrpm_repo: + for rpm in glob(os.path.join(gitrpm_repo, "*.rpm")): + f.write(os.path.basename(rpm)[:-4]+"\n") + + f.write("%end\n") + + # Other customizations can be appended to the kickstart + add_customizations(f, recipe) + + # Setup the config to pass to novirt_install + log_dir = joinpaths(results_dir, "logs/") + cfg_args = compose_args(compose_type) + + # Get the title, project, and release version from the host + if not os.path.exists("/etc/os-release"): + log.error("/etc/os-release is missing, cannot determine product or release version") + os_release = flatconfig("/etc/os-release") + + log.debug("os_release = %s", dict(os_release.items())) + + cfg_args["title"] = os_release.get("PRETTY_NAME", "") + cfg_args["project"] = os_release.get("NAME", "") + cfg_args["releasever"] = os_release.get("VERSION_ID", "") + cfg_args["volid"] = "" + cfg_args["extra_boot_args"] = get_kernel_append(recipe) + + if "compression" not in cfg_args: + cfg_args["compression"] = "xz" + + if "compress_args" not in cfg_args: + cfg_args["compress_args"] = [] + + cfg_args.update({ + "ks": [ks_path], + "logfile": log_dir, + "timeout": 60, # 60 minute timeout + }) + with open(joinpaths(results_dir, "config.toml"), "w") as f: + f.write(toml.dumps(cfg_args)) + + # Set the initial status + open(joinpaths(results_dir, "STATUS"), "w").write("WAITING") + + # Set the test mode, if requested + if test_mode > 0: + open(joinpaths(results_dir, "TEST"), "w").write("%s" % test_mode) + + write_timestamp(results_dir, TS_CREATED) + log.info("Adding %s (%s %s) to compose queue", build_id, recipe["name"], compose_type) + os.symlink(results_dir, joinpaths(lib_dir, "queue/new/", build_id)) + + return build_id
    + +# Supported output types +
    [docs]def compose_types(share_dir): + r""" Returns a list of tuples of the supported output types, and their state + + The output types come from the kickstart names in /usr/share/lorax/composer/\*ks + + If they are disabled on the current arch their state is False. If enabled, it is True. + eg. [("alibaba", False), ("ext4-filesystem", True), ...] + """ + # These are compose types that are not supported on an architecture. eg. hyper-v on s390 + # If it is not listed, it is allowed + disable_map = { + "arm": ["alibaba", "ami", "google", "hyper-v", "vhd", "vmdk"], + "armhfp": ["alibaba", "ami", "google", "hyper-v", "vhd", "vmdk"], + "aarch64": ["alibaba", "ami", "google", "hyper-v", "vhd", "vmdk"], + "ppc": ["alibaba", "ami", "google", "hyper-v", "vhd", "vmdk"], + "ppc64": ["alibaba", "ami", "google", "hyper-v", "vhd", "vmdk"], + "ppc64le": ["alibaba", "ami", "google", "hyper-v", "vhd", "vmdk"], + "s390": ["alibaba", "ami", "google", "hyper-v", "vhd", "vmdk"], + "s390x": ["alibaba", "ami", "google", "hyper-v", "vhd", "vmdk"], + } + + all_types = sorted([os.path.basename(ks)[:-3] for ks in glob(joinpaths(share_dir, "composer/*.ks"))]) + arch_disabled = disable_map.get(os.uname().machine, []) + + return [(t, t not in arch_disabled) for t in all_types]
    + +
    [docs]def compose_args(compose_type): + """ Returns the settings to pass to novirt_install for the compose type + + :param compose_type: The type of compose to create, from `compose_types()` + :type compose_type: str + + This will return a dict of options that match the ArgumentParser options for livemedia-creator. + These are the ones the define the type of output, it's filename, etc. + Other options will be filled in by `make_compose()` + """ + _MAP = {"tar": {"make_iso": False, + "make_disk": False, + "make_fsimage": False, + "make_appliance": False, + "make_ami": False, + "make_tar": True, + "make_tar_disk": False, + "make_pxe_live": False, + "make_ostree_live": False, + "make_oci": False, + "make_vagrant": False, + "ostree": False, + "live_rootfs_keep_size": False, + "live_rootfs_size": 0, + "image_size_align": 0, + "image_type": False, # False instead of None because of TOML + "qemu_args": [], + "image_name": default_image_name("xz", "root.tar"), + "tar_disk_name": None, + "image_only": True, + "app_name": None, + "app_template": None, + "app_file": None, + }, + "live-iso": {"make_iso": True, + "make_disk": False, + "make_fsimage": False, + "make_appliance": False, + "make_ami": False, + "make_tar": False, + "make_tar_disk": False, + "make_pxe_live": False, + "make_ostree_live": False, + "make_oci": False, + "make_vagrant": False, + "ostree": False, + "live_rootfs_keep_size": False, + "live_rootfs_size": 0, + "image_size_align": 0, + "image_type": False, # False instead of None because of TOML + "qemu_args": [], + "image_name": "live.iso", + "tar_disk_name": None, + "fs_label": "Anaconda", # Live booting may expect this to be 'Anaconda' + "image_only": False, + "app_name": None, + "app_template": None, + "app_file": None, + "iso_only": True, + "iso_name": "live.iso", + }, + "partitioned-disk": {"make_iso": False, + "make_disk": True, + "make_fsimage": False, + "make_appliance": False, + "make_ami": False, + "make_tar": False, + "make_tar_disk": False, + "make_pxe_live": False, + "make_ostree_live": False, + "make_oci": False, + "make_vagrant": False, + "ostree": False, + "live_rootfs_keep_size": False, + "live_rootfs_size": 0, + "image_size_align": 0, + "image_type": False, # False instead of None because of TOML + "qemu_args": [], + "image_name": "disk.img", + "tar_disk_name": None, + "fs_label": "", + "image_only": True, + "app_name": None, + "app_template": None, + "app_file": None, + }, + "qcow2": {"make_iso": False, + "make_disk": True, + "make_fsimage": False, + "make_appliance": False, + "make_ami": False, + "make_tar": False, + "make_tar_disk": False, + "make_pxe_live": False, + "make_ostree_live": False, + "make_oci": False, + "make_vagrant": False, + "ostree": False, + "live_rootfs_keep_size": False, + "live_rootfs_size": 0, + "image_size_align": 0, + "image_type": "qcow2", + "qemu_args": [], + "image_name": "disk.qcow2", + "tar_disk_name": None, + "fs_label": "", + "image_only": True, + "app_name": None, + "app_template": None, + "app_file": None, + }, + "ext4-filesystem": {"make_iso": False, + "make_disk": False, + "make_fsimage": True, + "make_appliance": False, + "make_ami": False, + "make_tar": False, + "make_tar_disk": False, + "make_pxe_live": False, + "make_ostree_live": False, + "make_oci": False, + "make_vagrant": False, + "ostree": False, + "live_rootfs_keep_size": False, + "live_rootfs_size": 0, + "image_size_align": 0, + "image_type": False, # False instead of None because of TOML + "qemu_args": [], + "image_name": "filesystem.img", + "tar_disk_name": None, + "fs_label": "", + "image_only": True, + "app_name": None, + "app_template": None, + "app_file": None, + }, + "ami": {"make_iso": False, + "make_disk": True, + "make_fsimage": False, + "make_appliance": False, + "make_ami": False, + "make_tar": False, + "make_tar_disk": False, + "make_pxe_live": False, + "make_ostree_live": False, + "make_oci": False, + "make_vagrant": False, + "ostree": False, + "live_rootfs_keep_size": False, + "live_rootfs_size": 0, + "image_size_align": 0, + "image_type": False, + "qemu_args": [], + "image_name": "disk.ami", + "tar_disk_name": None, + "fs_label": "", + "image_only": True, + "app_name": None, + "app_template": None, + "app_file": None, + }, + "vhd": {"make_iso": False, + "make_disk": True, + "make_fsimage": False, + "make_appliance": False, + "make_ami": False, + "make_tar": False, + "make_tar_disk": False, + "make_pxe_live": False, + "make_ostree_live": False, + "make_oci": False, + "make_vagrant": False, + "ostree": False, + "live_rootfs_keep_size": False, + "live_rootfs_size": 0, + "image_size_align": 0, + "image_type": "vpc", + "qemu_args": ["-o", "subformat=fixed,force_size"], + "image_name": "disk.vhd", + "tar_disk_name": None, + "fs_label": "", + "image_only": True, + "app_name": None, + "app_template": None, + "app_file": None, + }, + "vmdk": {"make_iso": False, + "make_disk": True, + "make_fsimage": False, + "make_appliance": False, + "make_ami": False, + "make_tar": False, + "make_tar_disk": False, + "make_pxe_live": False, + "make_ostree_live": False, + "make_oci": False, + "make_vagrant": False, + "ostree": False, + "live_rootfs_keep_size": False, + "live_rootfs_size": 0, + "image_size_align": 0, + "image_type": "vmdk", + "qemu_args": [], + "image_name": "disk.vmdk", + "tar_disk_name": None, + "fs_label": "", + "image_only": True, + "app_name": None, + "app_template": None, + "app_file": None, + }, + "openstack": {"make_iso": False, + "make_disk": True, + "make_fsimage": False, + "make_appliance": False, + "make_ami": False, + "make_tar": False, + "make_tar_disk": False, + "make_pxe_live": False, + "make_ostree_live": False, + "make_oci": False, + "make_vagrant": False, + "ostree": False, + "live_rootfs_keep_size": False, + "live_rootfs_size": 0, + "image_size_align": 0, + "image_type": "qcow2", + "qemu_args": [], + "image_name": "disk.qcow2", + "tar_disk_name": None, + "fs_label": "", + "image_only": True, + "app_name": None, + "app_template": None, + "app_file": None, + }, + "google": {"make_iso": False, + "make_disk": True, + "make_fsimage": False, + "make_appliance": False, + "make_ami": False, + "make_tar": False, + "make_tar_disk": True, + "make_pxe_live": False, + "make_ostree_live": False, + "make_oci": False, + "make_vagrant": False, + "ostree": False, + "live_rootfs_keep_size": False, + "live_rootfs_size": 0, + "image_size_align": 1024, + "image_type": False, # False instead of None because of TOML + "qemu_args": [], + "image_name": "disk.tar.gz", + "tar_disk_name": "disk.raw", + "compression": "gzip", + "compress_args": ["-9"], + "fs_label": "", + "image_only": True, + "app_name": None, + "app_template": None, + "app_file": None, + }, + "alibaba": {"make_iso": False, + "make_disk": True, + "make_fsimage": False, + "make_appliance": False, + "make_ami": False, + "make_tar": False, + "make_tar_disk": False, + "make_pxe_live": False, + "make_ostree_live": False, + "make_oci": False, + "make_vagrant": False, + "ostree": False, + "live_rootfs_keep_size": False, + "live_rootfs_size": 0, + "image_size_align": 0, + "image_type": "qcow2", + "qemu_args": [], + "image_name": "disk.qcow2", + "tar_disk_name": None, + "fs_label": "", + "image_only": True, + "app_name": None, + "app_template": None, + "app_file": None, + }, + } + return _MAP[compose_type]
    + +
    [docs]def move_compose_results(cfg, results_dir): + """Move the final image to the results_dir and cleanup the unneeded compose files + + :param cfg: Build configuration + :type cfg: DataHolder + :param results_dir: Directory to put the results into + :type results_dir: str + """ + if cfg["make_tar"]: + shutil.move(joinpaths(cfg["result_dir"], cfg["image_name"]), results_dir) + elif cfg["make_iso"]: + # Output from live iso is always a boot.iso under images/, move and rename it + shutil.move(joinpaths(cfg["result_dir"], cfg["iso_name"]), joinpaths(results_dir, cfg["image_name"])) + elif cfg["make_disk"] or cfg["make_fsimage"]: + shutil.move(joinpaths(cfg["result_dir"], cfg["image_name"]), joinpaths(results_dir, cfg["image_name"])) + + + # Cleanup the compose directory, but only if it looks like a compose directory + if os.path.basename(cfg["result_dir"]) == "compose": + shutil.rmtree(cfg["result_dir"]) + else: + log.error("Incorrect compose directory, not cleaning up")
    +
    + +
    + +
    +
    + + +
    + +
    +

    + © Copyright 2018-2019, Red Hat, Inc. + +

    +
    + Built with Sphinx using a theme provided by Read the Docs. + +
    + +
    +
    + +
    + +
    + + + + + + + + + + + + \ No newline at end of file diff --git a/rhel8-branch/_modules/pylorax/api/config.html b/rhel8-branch/_modules/pylorax/api/config.html new file mode 100644 index 00000000..c2a6d10c --- /dev/null +++ b/rhel8-branch/_modules/pylorax/api/config.html @@ -0,0 +1,313 @@ + + + + + + + + + + + pylorax.api.config — Lorax 28.14.33 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + + + +
    + + + + + +
    + +
    + + + + + + + + + + + + + + + + + +
    + + + + +
    +
    +
    +
    + +

    Source code for pylorax.api.config

    +#
    +# Copyright (C) 2017  Red Hat, Inc.
    +#
    +# This program is free software; you can redistribute it and/or modify
    +# it under the terms of the GNU General Public License as published by
    +# the Free Software Foundation; either version 2 of the License, or
    +# (at your option) any later version.
    +#
    +# This program is distributed in the hope that it will be useful,
    +# but WITHOUT ANY WARRANTY; without even the implied warranty of
    +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    +# GNU General Public License for more details.
    +#
    +# You should have received a copy of the GNU General Public License
    +# along with this program.  If not, see <http://www.gnu.org/licenses/>.
    +#
    +import configparser
    +import grp
    +import os
    +
    +from pylorax.sysutils import joinpaths
    +
    +
    [docs]class ComposerConfig(configparser.SafeConfigParser): +
    [docs] def get_default(self, section, option, default): + try: + return self.get(section, option) + except configparser.Error: + return default
    + + +
    [docs]def configure(conf_file="/etc/lorax/composer.conf", root_dir="/", test_config=False): + """lorax-composer configuration + + :param conf_file: Path to the config file overriding the default settings + :type conf_file: str + :param root_dir: Directory to prepend to paths, defaults to / + :type root_dir: str + :param test_config: Set to True to skip reading conf_file + :type test_config: bool + """ + conf = ComposerConfig() + + # set defaults + conf.add_section("composer") + conf.set("composer", "share_dir", os.path.realpath(joinpaths(root_dir, "/usr/share/lorax/"))) + conf.set("composer", "lib_dir", os.path.realpath(joinpaths(root_dir, "/var/lib/lorax/composer/"))) + conf.set("composer", "repo_dir", os.path.realpath(joinpaths(root_dir, "/var/lib/lorax/composer/repos.d/"))) + conf.set("composer", "dnf_conf", os.path.realpath(joinpaths(root_dir, "/var/tmp/composer/dnf.conf"))) + conf.set("composer", "dnf_root", os.path.realpath(joinpaths(root_dir, "/var/tmp/composer/dnf/root/"))) + conf.set("composer", "cache_dir", os.path.realpath(joinpaths(root_dir, "/var/tmp/composer/cache/"))) + conf.set("composer", "tmp", os.path.realpath(joinpaths(root_dir, "/var/tmp/"))) + + conf.add_section("users") + conf.set("users", "root", "1") + + # Enable all available repo files by default + conf.add_section("repos") + conf.set("repos", "use_system_repos", "1") + conf.set("repos", "enabled", "*") + + conf.add_section("dnf") + + if not test_config: + # read the config file + if os.path.isfile(conf_file): + conf.read(conf_file) + + return conf
    + +
    [docs]def make_dnf_dirs(conf): + """Make any missing dnf directories + + :param conf: The configuration to use + :type conf: ComposerConfig + :returns: None + """ + for p in ["dnf_conf", "repo_dir", "cache_dir", "dnf_root"]: + p_dir = os.path.abspath(conf.get("composer", p)) + if p == "dnf_conf": + p_dir = os.path.dirname(p_dir) + + if not os.path.isdir(p_dir): + os.makedirs(p_dir)
    + +
    [docs]def make_queue_dirs(conf, gid): + """Make any missing queue directories + + :param conf: The configuration to use + :type conf: ComposerConfig + :param gid: Group ID that has access to the queue directories + :type gid: int + :returns: list of errors + :rtype: list of str + """ + errors = [] + lib_dir = conf.get("composer", "lib_dir") + for p in ["queue/run", "queue/new", "results"]: + p_dir = joinpaths(lib_dir, p) + if not os.path.exists(p_dir): + orig_umask = os.umask(0) + os.makedirs(p_dir, 0o771) + os.chown(p_dir, 0, gid) + os.umask(orig_umask) + else: + p_stat = os.stat(p_dir) + if p_stat.st_mode & 0o006 != 0: + errors.append("Incorrect permissions on %s, no o+rw permissions are allowed." % p_dir) + + if p_stat.st_gid != gid or p_stat.st_uid != 0: + gr_name = grp.getgrgid(gid).gr_name + errors.append("%s should be owned by root:%s" % (p_dir, gr_name)) + + return errors
    +
    + +
    + +
    +
    + + +
    + +
    +

    + © Copyright 2018-2019, Red Hat, Inc. + +

    +
    + Built with Sphinx using a theme provided by Read the Docs. + +
    + +
    +
    + +
    + +
    + + + + + + + + + + + + \ No newline at end of file diff --git a/rhel8-branch/_modules/pylorax/api/crossdomain.html b/rhel8-branch/_modules/pylorax/api/crossdomain.html new file mode 100644 index 00000000..ecd1da89 --- /dev/null +++ b/rhel8-branch/_modules/pylorax/api/crossdomain.html @@ -0,0 +1,264 @@ + + + + + + + + + + + pylorax.api.crossdomain — Lorax 28.14.33 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + + + +
    + + + + + +
    + +
    + + + + + + + + + + + + + + + + + +
    + + + + +
    +
    +
    +
    + +

    Source code for pylorax.api.crossdomain

    +#
    +# Copyright (C) 2017  Red Hat, Inc.
    +#
    +# This program is free software; you can redistribute it and/or modify
    +# it under the terms of the GNU General Public License as published by
    +# the Free Software Foundation; either version 2 of the License, or
    +# (at your option) any later version.
    +#
    +# This program is distributed in the hope that it will be useful,
    +# but WITHOUT ANY WARRANTY; without even the implied warranty of
    +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    +# GNU General Public License for more details.
    +#
    +# You should have received a copy of the GNU General Public License
    +# along with this program.  If not, see <http://www.gnu.org/licenses/>.
    +#
    +
    +# crossdomain decorator from - http://flask.pocoo.org/snippets/56/
    +from datetime import timedelta
    +from flask import make_response, request, current_app
    +from functools import update_wrapper
    +
    +
    +
    [docs]def crossdomain(origin, methods=None, headers=None, + max_age=21600, attach_to_all=True, + automatic_options=True): + if methods is not None: + methods = ', '.join(sorted(x.upper() for x in methods)) + if headers is not None and not isinstance(headers, str): + headers = ', '.join(x.upper() for x in headers) + if not isinstance(origin, list): + origin = [origin] + if isinstance(max_age, timedelta): + max_age = int(max_age.total_seconds()) + + def get_methods(): + if methods is not None: + return methods + + options_resp = current_app.make_default_options_response() + return options_resp.headers['allow'] + + def decorator(f): + def wrapped_function(*args, **kwargs): + if automatic_options and request.method == 'OPTIONS': + resp = current_app.make_default_options_response() + else: + resp = make_response(f(*args, **kwargs)) + if not attach_to_all and request.method != 'OPTIONS': + return resp + + h = resp.headers + + h.extend([("Access-Control-Allow-Origin", orig) for orig in origin]) + h['Access-Control-Allow-Methods'] = get_methods() + h['Access-Control-Max-Age'] = str(max_age) + if headers is not None: + h['Access-Control-Allow-Headers'] = headers + return resp + + f.provide_automatic_options = False + f.required_methods = ['OPTIONS'] + return update_wrapper(wrapped_function, f) + return decorator
    +
    + +
    + +
    +
    + + +
    + +
    +

    + © Copyright 2018-2019, Red Hat, Inc. + +

    +
    + Built with Sphinx using a theme provided by Read the Docs. + +
    + +
    +
    + +
    + +
    + + + + + + + + + + + + \ No newline at end of file diff --git a/rhel8-branch/_modules/pylorax/api/projects.html b/rhel8-branch/_modules/pylorax/api/projects.html new file mode 100644 index 00000000..a718db4a --- /dev/null +++ b/rhel8-branch/_modules/pylorax/api/projects.html @@ -0,0 +1,805 @@ + + + + + + + + + + + pylorax.api.projects — Lorax 28.14.33 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + + + +
    + + + + + +
    + +
    + + + + + + + + + + + + + + + + + +
    + + + + +
    +
    +
    +
    + +

    Source code for pylorax.api.projects

    +#
    +# Copyright (C) 2017  Red Hat, Inc.
    +#
    +# This program is free software; you can redistribute it and/or modify
    +# it under the terms of the GNU General Public License as published by
    +# the Free Software Foundation; either version 2 of the License, or
    +# (at your option) any later version.
    +#
    +# This program is distributed in the hope that it will be useful,
    +# but WITHOUT ANY WARRANTY; without even the implied warranty of
    +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    +# GNU General Public License for more details.
    +#
    +# You should have received a copy of the GNU General Public License
    +# along with this program.  If not, see <http://www.gnu.org/licenses/>.
    +#
    +import logging
    +log = logging.getLogger("lorax-composer")
    +
    +from configparser import ConfigParser
    +import dnf
    +from glob import glob
    +import os
    +import time
    +
    +from pylorax.api.bisect import insort_left
    +
    +TIME_FORMAT = "%Y-%m-%dT%H:%M:%S"
    +
    +
    +
    [docs]class ProjectsError(Exception): + pass
    + + +
    [docs]def api_time(t): + """Convert time since epoch to a string + + :param t: Seconds since epoch + :type t: int + :returns: Time string + :rtype: str + """ + return time.strftime(TIME_FORMAT, time.localtime(t))
    + + +
    [docs]def api_changelog(changelog): + """Convert the changelog to a string + + :param changelog: A list of time, author, string tuples. + :type changelog: tuple + :returns: The most recent changelog text or "" + :rtype: str + + This returns only the most recent changelog entry. + """ + try: + entry = changelog[0][2] + except IndexError: + entry = "" + return entry
    + + +
    [docs]def pkg_to_project(pkg): + """Extract the details from a hawkey.Package object + + :param pkgs: hawkey.Package object with package details + :type pkgs: hawkey.Package + :returns: A dict with the name, summary, description, and url. + :rtype: dict + + upstream_vcs is hard-coded to UPSTREAM_VCS + """ + return {"name": pkg.name, + "summary": pkg.summary, + "description": pkg.description, + "homepage": pkg.url, + "upstream_vcs": "UPSTREAM_VCS"}
    + + +
    [docs]def pkg_to_build(pkg): + """Extract the build details from a hawkey.Package object + + :param pkg: hawkey.Package object with package details + :type pkg: hawkey.Package + :returns: A dict with the build details, epoch, release, arch, build_time, changelog, ... + :rtype: dict + + metadata entries are hard-coded to {} + + Note that this only returns the build dict, it does not include the name, description, etc. + """ + return {"epoch": pkg.epoch, + "release": pkg.release, + "arch": pkg.arch, + "build_time": api_time(pkg.buildtime), + "changelog": "CHANGELOG_NEEDED", # XXX Not in hawkey.Package + "build_config_ref": "BUILD_CONFIG_REF", + "build_env_ref": "BUILD_ENV_REF", + "metadata": {}, + "source": {"license": pkg.license, + "version": pkg.version, + "source_ref": "SOURCE_REF", + "metadata": {}}}
    + + +
    [docs]def pkg_to_project_info(pkg): + """Extract the details from a hawkey.Package object + + :param pkg: hawkey.Package object with package details + :type pkg: hawkey.Package + :returns: A dict with the project details, as well as epoch, release, arch, build_time, changelog, ... + :rtype: dict + + metadata entries are hard-coded to {} + """ + return {"name": pkg.name, + "summary": pkg.summary, + "description": pkg.description, + "homepage": pkg.url, + "upstream_vcs": "UPSTREAM_VCS", + "builds": [pkg_to_build(pkg)]}
    + + +
    [docs]def pkg_to_dep(pkg): + """Extract the info from a hawkey.Package object + + :param pkg: A hawkey.Package object + :type pkg: hawkey.Package + :returns: A dict with name, epoch, version, release, arch + :rtype: dict + """ + return {"name": pkg.name, + "epoch": pkg.epoch, + "version": pkg.version, + "release": pkg.release, + "arch": pkg.arch}
    + + +
    [docs]def proj_to_module(proj): + """Extract the name from a project_info dict + + :param pkg: dict with package details + :type pkg: dict + :returns: A dict with name, and group_type + :rtype: dict + + group_type is hard-coded to "rpm" + """ + return {"name": proj["name"], + "group_type": "rpm"}
    + + +
    [docs]def dep_evra(dep): + """Return the epoch:version-release.arch for the dep + + :param dep: dependency dict + :type dep: dict + :returns: epoch:version-release.arch + :rtype: str + """ + if dep["epoch"] == 0: + return dep["version"]+"-"+dep["release"]+"."+dep["arch"] + else: + return str(dep["epoch"])+":"+dep["version"]+"-"+dep["release"]+"."+dep["arch"]
    + +
    [docs]def dep_nevra(dep): + """Return the name-epoch:version-release.arch""" + return dep["name"]+"-"+dep_evra(dep)
    + + +
    [docs]def projects_list(dbo): + """Return a list of projects + + :param dbo: dnf base object + :type dbo: dnf.Base + :returns: List of project info dicts with name, summary, description, homepage, upstream_vcs + :rtype: list of dicts + """ + return projects_info(dbo, None)
    + + +
    [docs]def projects_info(dbo, project_names): + """Return details about specific projects + + :param dbo: dnf base object + :type dbo: dnf.Base + :param project_names: List of names of projects to get info about + :type project_names: str + :returns: List of project info dicts with pkg_to_project as well as epoch, version, release, etc. + :rtype: list of dicts + + If project_names is None it will return the full list of available packages + """ + if project_names: + pkgs = dbo.sack.query().available().filter(name__glob=project_names) + else: + pkgs = dbo.sack.query().available() + + # iterate over pkgs + # - if pkg.name isn't in the results yet, add pkg_to_project_info in sorted position + # - if pkg.name is already in results, get its builds. If the build for pkg is different + # in any way (version, arch, etc.) add it to the entry's builds list. If it is the same, + # skip it. + results = [] + results_names = {} + for p in pkgs: + if p.name.lower() not in results_names: + idx = insort_left(results, pkg_to_project_info(p), key=lambda p: p["name"].lower()) + results_names[p.name.lower()] = idx + else: + build = pkg_to_build(p) + if build not in results[results_names[p.name.lower()]]["builds"]: + results[results_names[p.name.lower()]]["builds"].append(build) + + return results
    + +def _depsolve(dbo, projects, groups): + """Add projects to a new transaction + + :param dbo: dnf base object + :type dbo: dnf.Base + :param projects: The projects and version globs to find the dependencies for + :type projects: List of tuples + :param groups: The groups to include in dependency solving + :type groups: List of str + :returns: None + :rtype: None + :raises: ProjectsError if there was a problem installing something + """ + # This resets the transaction and updates the cache. + # It is important that the cache always be synchronized because Anaconda will grab its own copy + # and if that is different the NEVRAs will not match and the build will fail. + dbo.reset(goal=True) + install_errors = [] + for name in groups: + try: + dbo.group_install(name, ["mandatory", "default"]) + except dnf.exceptions.MarkingError as e: + install_errors.append(("Group %s" % (name), str(e))) + + for name, version in projects: + # Find the best package matching the name + version glob + # dnf can return multiple packages if it is in more than 1 repository + query = dbo.sack.query().filterm(provides__glob=name) + if version: + query.filterm(version__glob=version) + + query.filterm(latest=1) + if not query: + install_errors.append(("%s-%s" % (name, version), "No match")) + continue + sltr = dnf.selector.Selector(dbo.sack).set(pkg=query) + + # NOTE: dnf says in near future there will be a "goal" attribute of Base class + # so yes, we're using a 'private' attribute here on purpose and with permission. + dbo._goal.install(select=sltr, optional=False) + + if install_errors: + raise ProjectsError("The following package(s) had problems: %s" % ",".join(["%s (%s)" % (pattern, err) for pattern, err in install_errors])) + +
    [docs]def projects_depsolve(dbo, projects, groups): + """Return the dependencies for a list of projects + + :param dbo: dnf base object + :type dbo: dnf.Base + :param projects: The projects to find the dependencies for + :type projects: List of Strings + :param groups: The groups to include in dependency solving + :type groups: List of str + :returns: NEVRA's of the project and its dependencies + :rtype: list of dicts + :raises: ProjectsError if there was a problem installing something + """ + _depsolve(dbo, projects, groups) + + try: + dbo.resolve() + except dnf.exceptions.DepsolveError as e: + raise ProjectsError("There was a problem depsolving %s: %s" % (projects, str(e))) + + if len(dbo.transaction) == 0: + return [] + + return sorted(map(pkg_to_dep, dbo.transaction.install_set), key=lambda p: p["name"].lower())
    + + +
    [docs]def estimate_size(packages, block_size=6144): + """Estimate the installed size of a package list + + :param packages: The packages to be installed + :type packages: list of hawkey.Package objects + :param block_size: The block size to use for rounding up file sizes. + :type block_size: int + :returns: The estimated size of installed packages + :rtype: int + + Estimating actual requirements is difficult without the actual file sizes, which + dnf doesn't provide access to. So use the file count and block size to estimate + a minimum size for each package. + """ + installed_size = 0 + for p in packages: + installed_size += len(p.files) * block_size + installed_size += p.installsize + return installed_size
    + + +
    [docs]def projects_depsolve_with_size(dbo, projects, groups, with_core=True): + """Return the dependencies and installed size for a list of projects + + :param dbo: dnf base object + :type dbo: dnf.Base + :param project_names: The projects to find the dependencies for + :type project_names: List of Strings + :param groups: The groups to include in dependency solving + :type groups: List of str + :returns: installed size and a list of NEVRA's of the project and its dependencies + :rtype: tuple of (int, list of dicts) + :raises: ProjectsError if there was a problem installing something + """ + _depsolve(dbo, projects, groups) + + if with_core: + dbo.group_install("core", ['mandatory', 'default', 'optional']) + + try: + dbo.resolve() + except dnf.exceptions.DepsolveError as e: + raise ProjectsError("There was a problem depsolving %s: %s" % (projects, str(e))) + + if len(dbo.transaction) == 0: + return (0, []) + + installed_size = estimate_size(dbo.transaction.install_set) + deps = sorted(map(pkg_to_dep, dbo.transaction.install_set), key=lambda p: p["name"].lower()) + return (installed_size, deps)
    + + +
    [docs]def modules_list(dbo, module_names): + """Return a list of modules + + :param dbo: dnf base object + :type dbo: dnf.Base + :param offset: Number of modules to skip + :type limit: int + :param limit: Maximum number of modules to return + :type limit: int + :returns: List of module information and total count + :rtype: tuple of a list of dicts and an Int + + Modules don't exist in RHEL7 so this only returns projects + and sets the type to "rpm" + + """ + # TODO - Figure out what to do with this for Fedora 'modules' + projs = _unique_dicts(projects_info(dbo, module_names), key=lambda p: p["name"].lower()) + return list(map(proj_to_module, projs))
    + +def _unique_dicts(lst, key): + """Return a new list of dicts, only including one match of key(d) + + :param lst: list of dicts + :type lst: list + :param key: key function to match lst entries + :type key: function + :returns: list of the unique lst entries + :rtype: list + + Uses key(d) to test for duplicates in the returned list, creating a + list of unique return values. + """ + result = [] + result_keys = [] + for d in lst: + if key(d) not in result_keys: + result.append(d) + result_keys.append(key(d)) + return result + +
    [docs]def modules_info(dbo, module_names): + """Return details about a module, including dependencies + + :param dbo: dnf base object + :type dbo: dnf.Base + :param module_names: Names of the modules to get info about + :type module_names: str + :returns: List of dicts with module details and dependencies. + :rtype: list of dicts + """ + modules = projects_info(dbo, module_names) + + # Add the dependency info to each one + for module in modules: + module["dependencies"] = projects_depsolve(dbo, [(module["name"], "*.*")], []) + + return modules
    + +
    [docs]def dnf_repo_to_file_repo(repo): + """Return a string representation of a DNF Repo object suitable for writing to a .repo file + + :param repo: DNF Repository + :type repo: dnf.RepoDict + :returns: A string + :rtype: str + + The DNF Repo.dump() function does not produce a string that can be used as a dnf .repo file, + it ouputs baseurl and gpgkey as python lists which DNF cannot read. So do this manually with + only the attributes we care about. + """ + repo_str = "[%s]\nname = %s\n" % (repo.id, repo.name) + if repo.metalink: + repo_str += "metalink = %s\n" % repo.metalink + elif repo.mirrorlist: + repo_str += "mirrorlist = %s\n" % repo.mirrorlist + elif repo.baseurl: + repo_str += "baseurl = %s\n" % repo.baseurl[0] + else: + raise RuntimeError("Repo has no baseurl, metalink, or mirrorlist") + + # proxy is optional + if repo.proxy: + repo_str += "proxy = %s\n" % repo.proxy + + repo_str += "sslverify = %s\n" % repo.sslverify + repo_str += "gpgcheck = %s\n" % repo.gpgcheck + if repo.gpgkey: + repo_str += "gpgkey = %s\n" % ",".join(repo.gpgkey) + + return repo_str
    + +
    [docs]def repo_to_source(repo, system_source): + """Return a Weldr Source dict created from the DNF Repository + + :param repo: DNF Repository + :type repo: dnf.RepoDict + :param system_source: True if this source is an immutable system source + :type system_source: bool + :returns: A dict with Weldr Source fields filled in + :rtype: dict + + Example:: + + { + "check_gpg": true, + "check_ssl": true, + "gpgkey_url": [ + "file:///etc/pki/rpm-gpg/RPM-GPG-KEY-fedora-28-x86_64" + ], + "name": "fedora", + "proxy": "http://proxy.brianlane.com:8123", + "system": true + "type": "yum-metalink", + "url": "https://mirrors.fedoraproject.org/metalink?repo=fedora-28&arch=x86_64" + } + + """ + source = {"name": repo.id, "system": system_source} + if repo.baseurl: + source["url"] = repo.baseurl[0] + source["type"] = "yum-baseurl" + elif repo.metalink: + source["url"] = repo.metalink + source["type"] = "yum-metalink" + elif repo.mirrorlist: + source["url"] = repo.mirrorlist + source["type"] = "yum-mirrorlist" + else: + raise RuntimeError("Repo has no baseurl, metalink, or mirrorlist") + + # proxy is optional + if repo.proxy: + source["proxy"] = repo.proxy + + if not repo.sslverify: + source["check_ssl"] = False + else: + source["check_ssl"] = True + + if not repo.gpgcheck: + source["check_gpg"] = False + else: + source["check_gpg"] = True + + if repo.gpgkey: + source["gpgkey_urls"] = list(repo.gpgkey) + + return source
    + +
    [docs]def source_to_repo(source, dnf_conf): + """Return a dnf Repo object created from a source dict + + :param source: A Weldr source dict + :type source: dict + :returns: A dnf Repo object + :rtype: dnf.Repo + + Example:: + + { + "check_gpg": True, + "check_ssl": True, + "gpgkey_urls": [ + "file:///etc/pki/rpm-gpg/RPM-GPG-KEY-fedora-28-x86_64" + ], + "name": "fedora", + "proxy": "http://proxy.brianlane.com:8123", + "system": True + "type": "yum-metalink", + "url": "https://mirrors.fedoraproject.org/metalink?repo=fedora-28&arch=x86_64" + } + + """ + repo = dnf.repo.Repo(source["name"], dnf_conf) + # This will allow errors to be raised so we can catch them + # without this they are logged, but the repo is silently disabled + repo.skip_if_unavailable = False + + if source["type"] == "yum-baseurl": + repo.baseurl = source["url"] + elif source["type"] == "yum-metalink": + repo.metalink = source["url"] + elif source["type"] == "yum-mirrorlist": + repo.mirrorlist = source["url"] + + if "proxy" in source: + repo.proxy = source["proxy"] + + if source["check_ssl"]: + repo.sslverify = True + else: + repo.sslverify = False + + if source["check_gpg"]: + repo.gpgcheck = True + else: + repo.gpgcheck = False + + if "gpgkey_urls" in source: + repo.gpgkey = tuple(source["gpgkey_urls"]) + + repo.enable() + + return repo
    + +
    [docs]def get_source_ids(source_path): + """Return a list of the source ids in a file + + :param source_path: Full path and filename of the source (yum repo) file + :type source_path: str + :returns: A list of source id strings + :rtype: list of str + """ + if not os.path.exists(source_path): + return [] + + cfg = ConfigParser(strict=False) + cfg.read(source_path) + return cfg.sections()
    + +
    [docs]def get_repo_sources(source_glob): + """Return a list of sources from a directory of yum repositories + + :param source_glob: A glob to use to match the source files, including full path + :type source_glob: str + :returns: A list of the source ids in all of the matching files + :rtype: list of str + """ + sources = [] + for f in glob(source_glob): + sources.extend(get_source_ids(f)) + return sources
    + +
    [docs]def delete_repo_source(source_glob, source_name): + """Delete a source from a repo file + + :param source_glob: A glob of the repo sources to search + :type source_glob: str + :returns: None + :raises: ProjectsError if there was a problem + + A repo file may have multiple sources in it, delete only the selected source. + If it is the last one in the file, delete the file. + + WARNING: This will delete ANY source, the caller needs to ensure that a system + source_name isn't passed to it. + """ + found = False + for f in glob(source_glob): + try: + cfg = ConfigParser(strict=False) + cfg.read(f) + if source_name in cfg.sections(): + found = True + cfg.remove_section(source_name) + # If there are other sections, rewrite the file without the deleted one + if len(cfg.sections()) > 0: + with open(f, "w") as cfg_file: + cfg.write(cfg_file) + else: + # No sections left, just delete the file + os.unlink(f) + except Exception as e: + raise ProjectsError("Problem deleting repo source %s: %s" % (source_name, str(e))) + if not found: + raise ProjectsError("source %s not found" % source_name)
    +
    + +
    + +
    +
    + + +
    + +
    +

    + © Copyright 2018-2019, Red Hat, Inc. + +

    +
    + Built with Sphinx using a theme provided by Read the Docs. + +
    + +
    +
    + +
    + +
    + + + + + + + + + + + + \ No newline at end of file diff --git a/rhel8-branch/_modules/pylorax/api/queue.html b/rhel8-branch/_modules/pylorax/api/queue.html new file mode 100644 index 00000000..3ea31988 --- /dev/null +++ b/rhel8-branch/_modules/pylorax/api/queue.html @@ -0,0 +1,875 @@ + + + + + + + + + + + pylorax.api.queue — Lorax 28.14.33 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + + + +
    + + + + + +
    + +
    + + + + + + + + + + + + + + + + + +
    + + + + +
    +
    +
    +
    + +

    Source code for pylorax.api.queue

    +# Copyright (C) 2018 Red Hat, Inc.
    +#
    +# This program is free software; you can redistribute it and/or modify
    +# it under the terms of the GNU General Public License as published by
    +# the Free Software Foundation; either version 2 of the License, or
    +# (at your option) any later version.
    +#
    +# This program is distributed in the hope that it will be useful,
    +# but WITHOUT ANY WARRANTY; without even the implied warranty of
    +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    +# GNU General Public License for more details.
    +#
    +# You should have received a copy of the GNU General Public License
    +# along with this program.  If not, see <http://www.gnu.org/licenses/>.
    +#
    +""" Functions to monitor compose queue and run anaconda"""
    +import logging
    +log = logging.getLogger("pylorax")
    +
    +import os
    +import grp
    +from glob import glob
    +import multiprocessing as mp
    +import pytoml as toml
    +import pwd
    +import shutil
    +import subprocess
    +from subprocess import Popen, PIPE
    +import time
    +
    +from pylorax import find_templates
    +from pylorax.api.compose import move_compose_results
    +from pylorax.api.recipes import recipe_from_file
    +from pylorax.api.timestamp import TS_CREATED, TS_STARTED, TS_FINISHED, write_timestamp, timestamp_dict
    +from pylorax.base import DataHolder
    +from pylorax.creator import run_creator
    +from pylorax.sysutils import joinpaths
    +
    +
    [docs]def check_queues(cfg): + """Check to make sure the new and run queue symlinks are correct + + :param cfg: Configuration settings + :type cfg: DataHolder + + Also check all of the existing results and make sure any with WAITING + set in STATUS have a symlink in queue/new/ + """ + # Remove broken symlinks from the new and run queues + queue_symlinks = glob(joinpaths(cfg.composer_dir, "queue/new/*")) + \ + glob(joinpaths(cfg.composer_dir, "queue/run/*")) + for link in queue_symlinks: + if not os.path.isdir(os.path.realpath(link)): + log.info("Removing broken symlink %s", link) + os.unlink(link) + + # Write FAILED to the STATUS of any run queue symlinks and remove them + for link in glob(joinpaths(cfg.composer_dir, "queue/run/*")): + log.info("Setting build %s to FAILED, and removing symlink from queue/run/", os.path.basename(link)) + open(joinpaths(link, "STATUS"), "w").write("FAILED\n") + os.unlink(link) + + # Check results STATUS messages + # - If STATUS is missing, set it to FAILED + # - RUNNING should be changed to FAILED + # - WAITING should have a symlink in the new queue + for link in glob(joinpaths(cfg.composer_dir, "results/*")): + if not os.path.exists(joinpaths(link, "STATUS")): + open(joinpaths(link, "STATUS"), "w").write("FAILED\n") + continue + + status = open(joinpaths(link, "STATUS")).read().strip() + if status == "RUNNING": + log.info("Setting build %s to FAILED", os.path.basename(link)) + open(joinpaths(link, "STATUS"), "w").write("FAILED\n") + elif status == "WAITING": + if not os.path.islink(joinpaths(cfg.composer_dir, "queue/new/", os.path.basename(link))): + log.info("Creating missing symlink to new build %s", os.path.basename(link)) + os.symlink(link, joinpaths(cfg.composer_dir, "queue/new/", os.path.basename(link)))
    + +
    [docs]def start_queue_monitor(cfg, uid, gid): + """Start the queue monitor as a mp process + + :param cfg: Configuration settings + :type cfg: ComposerConfig + :param uid: User ID that owns the queue + :type uid: int + :param gid: Group ID that owns the queue + :type gid: int + :returns: None + """ + lib_dir = cfg.get("composer", "lib_dir") + share_dir = cfg.get("composer", "share_dir") + tmp = cfg.get("composer", "tmp") + monitor_cfg = DataHolder(composer_dir=lib_dir, share_dir=share_dir, uid=uid, gid=gid, tmp=tmp) + p = mp.Process(target=monitor, args=(monitor_cfg,)) + p.daemon = True + p.start()
    + +
    [docs]def monitor(cfg): + """Monitor the queue for new compose requests + + :param cfg: Configuration settings + :type cfg: DataHolder + :returns: Does not return + + The queue has 2 subdirectories, new and run. When a compose is ready to be run + a symlink to the uniquely named results directory should be placed in ./queue/new/ + + When the it is ready to be run (it is checked every 30 seconds or after a previous + compose is finished) the symlink will be moved into ./queue/run/ and a STATUS file + will be created in the results directory. + + STATUS can contain one of: WAITING, RUNNING, FINISHED, FAILED + + If the system is restarted while a compose is running it will move any old symlinks + from ./queue/run/ to ./queue/new/ and rerun them. + """ + def queue_sort(uuid): + """Sort the queue entries by their mtime, not their names""" + return os.stat(joinpaths(cfg.composer_dir, "queue/new", uuid)).st_mtime + + check_queues(cfg) + while True: + uuids = sorted(os.listdir(joinpaths(cfg.composer_dir, "queue/new")), key=queue_sort) + + # Pick the oldest and move it into ./run/ + if not uuids: + # No composes left to process, sleep for a bit + time.sleep(5) + else: + src = joinpaths(cfg.composer_dir, "queue/new", uuids[0]) + dst = joinpaths(cfg.composer_dir, "queue/run", uuids[0]) + try: + os.rename(src, dst) + except OSError: + # The symlink may vanish if uuid_cancel() has been called + continue + + log.info("Starting new compose: %s", dst) + open(joinpaths(dst, "STATUS"), "w").write("RUNNING\n") + + try: + make_compose(cfg, os.path.realpath(dst)) + log.info("Finished building %s, results are in %s", dst, os.path.realpath(dst)) + open(joinpaths(dst, "STATUS"), "w").write("FINISHED\n") + write_timestamp(dst, TS_FINISHED) + except Exception: + import traceback + log.error("traceback: %s", traceback.format_exc()) + +# TODO - Write the error message to an ERROR-LOG file to include with the status +# log.error("Error running compose: %s", e) + open(joinpaths(dst, "STATUS"), "w").write("FAILED\n") + write_timestamp(dst, TS_FINISHED) + + os.unlink(dst)
    + +
    [docs]def make_compose(cfg, results_dir): + """Run anaconda with the final-kickstart.ks from results_dir + + :param cfg: Configuration settings + :type cfg: DataHolder + :param results_dir: The directory containing the metadata and results for the build + :type results_dir: str + :returns: Nothing + :raises: May raise various exceptions + + This takes the final-kickstart.ks, and the settings in config.toml and runs Anaconda + in no-virt mode (directly on the host operating system). Exceptions should be caught + at the higer level. + + If there is a failure, the build artifacts will be cleaned up, and any logs will be + moved into logs/anaconda/ and their ownership will be set to the user from the cfg + object. + """ + + # Check on the ks's presence + ks_path = joinpaths(results_dir, "final-kickstart.ks") + if not os.path.exists(ks_path): + raise RuntimeError("Missing kickstart file at %s" % ks_path) + + # The anaconda logs are copied into ./anaconda/ in this directory + log_dir = joinpaths(results_dir, "logs/") + if not os.path.exists(log_dir): + os.makedirs(log_dir) + + # Load the compose configuration + cfg_path = joinpaths(results_dir, "config.toml") + if not os.path.exists(cfg_path): + raise RuntimeError("Missing config.toml for %s" % results_dir) + cfg_dict = toml.loads(open(cfg_path, "r").read()) + + # The keys in cfg_dict correspond to the arguments setup in livemedia-creator + # keys that define what to build should be setup in compose_args, and keys with + # defaults should be setup here. + + # Make sure that image_name contains no path components + cfg_dict["image_name"] = os.path.basename(cfg_dict["image_name"]) + + # Only support novirt installation, set some other defaults + cfg_dict["no_virt"] = True + cfg_dict["disk_image"] = None + cfg_dict["fs_image"] = None + cfg_dict["keep_image"] = False + cfg_dict["domacboot"] = False + cfg_dict["anaconda_args"] = "" + cfg_dict["proxy"] = "" + cfg_dict["armplatform"] = "" + cfg_dict["squashfs_args"] = None + + cfg_dict["lorax_templates"] = find_templates(cfg.share_dir) + cfg_dict["tmp"] = cfg.tmp + cfg_dict["dracut_args"] = None # Use default args for dracut + + # TODO How to support other arches? + cfg_dict["arch"] = None + + # Compose things in a temporary directory inside the results directory + cfg_dict["result_dir"] = joinpaths(results_dir, "compose") + os.makedirs(cfg_dict["result_dir"]) + + install_cfg = DataHolder(**cfg_dict) + + # Some kludges for the 99-copy-logs %post, failure in it will crash the build + for f in ["/tmp/NOSAVE_INPUT_KS", "/tmp/NOSAVE_LOGS"]: + open(f, "w") + + # Placing a CANCEL file in the results directory will make execWithRedirect send anaconda a SIGTERM + def cancel_build(): + return os.path.exists(joinpaths(results_dir, "CANCEL")) + + log.debug("cfg = %s", install_cfg) + try: + test_path = joinpaths(results_dir, "TEST") + write_timestamp(results_dir, TS_STARTED) + if os.path.exists(test_path): + # Pretend to run the compose + time.sleep(5) + try: + test_mode = int(open(test_path, "r").read()) + except Exception: + test_mode = 1 + if test_mode == 1: + raise RuntimeError("TESTING FAILED compose") + else: + open(joinpaths(results_dir, install_cfg.image_name), "w").write("TEST IMAGE") + else: + run_creator(install_cfg, cancel_func=cancel_build) + + # Extract the results of the compose into results_dir and cleanup the compose directory + move_compose_results(install_cfg, results_dir) + finally: + # Make sure any remaining temporary directories are removed (eg. if there was an exception) + for d in glob(joinpaths(cfg.tmp, "lmc-*")): + if os.path.isdir(d): + shutil.rmtree(d) + elif os.path.isfile(d): + os.unlink(d) + + # Make sure that everything under the results directory is owned by the user + user = pwd.getpwuid(cfg.uid).pw_name + group = grp.getgrgid(cfg.gid).gr_name + log.debug("Install finished, chowning results to %s:%s", user, group) + subprocess.call(["chown", "-R", "%s:%s" % (user, group), results_dir])
    + +
    [docs]def get_compose_type(results_dir): + """Return the type of composition. + + :param results_dir: The directory containing the metadata and results for the build + :type results_dir: str + :returns: The type of compose (eg. 'tar') + :rtype: str + :raises: RuntimeError if no kickstart template can be found. + """ + # Should only be 2 kickstarts, the final-kickstart.ks and the template + t = [os.path.basename(ks)[:-3] for ks in glob(joinpaths(results_dir, "*.ks")) + if "final-kickstart" not in ks] + if len(t) != 1: + raise RuntimeError("Cannot find ks template for build %s" % os.path.basename(results_dir)) + return t[0]
    + +
    [docs]def compose_detail(results_dir): + """Return details about the build. + + :param results_dir: The directory containing the metadata and results for the build + :type results_dir: str + :returns: A dictionary with details about the compose + :rtype: dict + :raises: IOError if it cannot read the directory, STATUS, or blueprint file. + + The following details are included in the dict: + + * id - The uuid of the comoposition + * queue_status - The final status of the composition (FINISHED or FAILED) + * compose_type - The type of output generated (tar, iso, etc.) + * blueprint - Blueprint name + * version - Blueprint version + * image_size - Size of the image, if finished. 0 otherwise. + + Various timestamps are also included in the dict. These are all Unix UTC timestamps. + It is possible for these timestamps to not always exist, in which case they will be + None in Python (or null in JSON). The following timestamps are included: + + * job_created - When the user submitted the compose + * job_started - Anaconda started running + * job_finished - Job entered FINISHED or FAILED state + """ + build_id = os.path.basename(os.path.abspath(results_dir)) + status = open(joinpaths(results_dir, "STATUS")).read().strip() + blueprint = recipe_from_file(joinpaths(results_dir, "blueprint.toml")) + + compose_type = get_compose_type(results_dir) + + image_path = get_image_name(results_dir)[1] + if status == "FINISHED" and os.path.exists(image_path): + image_size = os.stat(image_path).st_size + else: + image_size = 0 + + times = timestamp_dict(results_dir) + + return {"id": build_id, + "queue_status": status, + "job_created": times.get(TS_CREATED), + "job_started": times.get(TS_STARTED), + "job_finished": times.get(TS_FINISHED), + "compose_type": compose_type, + "blueprint": blueprint["name"], + "version": blueprint["version"], + "image_size": image_size + }
    + +
    [docs]def queue_status(cfg): + """Return details about what is in the queue. + + :param cfg: Configuration settings + :type cfg: ComposerConfig + :returns: A list of the new composes, and a list of the running composes + :rtype: dict + + This returns a dict with 2 lists. "new" is the list of uuids that are waiting to be built, + and "run" has the uuids that are being built (currently limited to 1 at a time). + """ + queue_dir = joinpaths(cfg.get("composer", "lib_dir"), "queue") + new_queue = [os.path.realpath(p) for p in glob(joinpaths(queue_dir, "new/*"))] + run_queue = [os.path.realpath(p) for p in glob(joinpaths(queue_dir, "run/*"))] + + new_details = [] + for n in new_queue: + try: + d = compose_detail(n) + except IOError: + continue + new_details.append(d) + + run_details = [] + for r in run_queue: + try: + d = compose_detail(r) + except IOError: + continue + run_details.append(d) + + return { + "new": new_details, + "run": run_details + }
    + +
    [docs]def uuid_status(cfg, uuid): + """Return the details of a specific UUID compose + + :param cfg: Configuration settings + :type cfg: ComposerConfig + :param uuid: The UUID of the build + :type uuid: str + :returns: Details about the build + :rtype: dict or None + + Returns the same dict as `compose_details()` + """ + uuid_dir = joinpaths(cfg.get("composer", "lib_dir"), "results", uuid) + try: + return compose_detail(uuid_dir) + except IOError: + return None
    + +
    [docs]def build_status(cfg, status_filter=None): + """Return the details of finished or failed builds + + :param cfg: Configuration settings + :type cfg: ComposerConfig + :param status_filter: What builds to return. None == all, "FINISHED", or "FAILED" + :type status_filter: str + :returns: A list of the build details (from compose_details) + :rtype: list of dicts + + This returns a list of build details for each of the matching builds on the + system. It does not return the status of builds that have not been finished. + Use queue_status() for those. + """ + if status_filter: + status_filter = [status_filter] + else: + status_filter = ["FINISHED", "FAILED"] + + results = [] + result_dir = joinpaths(cfg.get("composer", "lib_dir"), "results") + for build in glob(result_dir + "/*"): + log.debug("Checking status of build %s", build) + + try: + status = open(joinpaths(build, "STATUS"), "r").read().strip() + if status in status_filter: + results.append(compose_detail(build)) + except IOError: + pass + return results
    + +
    [docs]def uuid_cancel(cfg, uuid): + """Cancel a build and delete its results + + :param cfg: Configuration settings + :type cfg: ComposerConfig + :param uuid: The UUID of the build + :type uuid: str + :returns: True if it was canceled and deleted + :rtype: bool + + Only call this if the build status is WAITING or RUNNING + """ + cancel_path = joinpaths(cfg.get("composer", "lib_dir"), "results", uuid, "CANCEL") + if os.path.exists(cancel_path): + log.info("Cancel has already been requested for %s", uuid) + return False + + # This status can change (and probably will) while it is in the middle of doing this: + # It can move from WAITING -> RUNNING or it can move from RUNNING -> FINISHED|FAILED + + # If it is in WAITING remove the symlink and then check to make sure it didn't show up + # in the run queue + queue_dir = joinpaths(cfg.get("composer", "lib_dir"), "queue") + uuid_new = joinpaths(queue_dir, "new", uuid) + if os.path.exists(uuid_new): + try: + os.unlink(uuid_new) + except OSError: + # The symlink may vanish if the queue monitor started the build + pass + uuid_run = joinpaths(queue_dir, "run", uuid) + if not os.path.exists(uuid_run): + # Make sure the build is still in the waiting state + status = uuid_status(cfg, uuid) + if status is None or status["queue_status"] == "WAITING": + # Successfully removed it before the build started + return uuid_delete(cfg, uuid) + + # At this point the build has probably started. Write to the CANCEL file. + open(cancel_path, "w").write("\n") + + # Wait for status to move to FAILED or FINISHED + started = time.time() + while True: + status = uuid_status(cfg, uuid) + if status is None or status["queue_status"] == "FAILED": + break + elif status is not None and status["queue_status"] == "FINISHED": + # The build finished successfully, no point in deleting it now + return False + + # Is this taking too long? Exit anyway and try to cleanup. + if time.time() > started + (10 * 60): + log.error("Failed to cancel the build of %s", uuid) + break + + time.sleep(5) + + # Remove the partial results + uuid_delete(cfg, uuid)
    + +
    [docs]def uuid_delete(cfg, uuid): + """Delete all of the results from a compose + + :param cfg: Configuration settings + :type cfg: ComposerConfig + :param uuid: The UUID of the build + :type uuid: str + :returns: True if it was deleted + :rtype: bool + :raises: This will raise an error if the delete failed + """ + uuid_dir = joinpaths(cfg.get("composer", "lib_dir"), "results", uuid) + if not uuid_dir or len(uuid_dir) < 10: + raise RuntimeError("Directory length is too short: %s" % uuid_dir) + shutil.rmtree(uuid_dir) + return True
    + +
    [docs]def uuid_info(cfg, uuid): + """Return information about the composition + + :param cfg: Configuration settings + :type cfg: ComposerConfig + :param uuid: The UUID of the build + :type uuid: str + :returns: dictionary of information about the composition or None + :rtype: dict + :raises: RuntimeError if there was a problem + + This will return a dict with the following fields populated: + + * id - The uuid of the comoposition + * config - containing the configuration settings used to run Anaconda + * blueprint - The depsolved blueprint used to generate the kickstart + * commit - The (local) git commit hash for the blueprint used + * deps - The NEVRA of all of the dependencies used in the composition + * compose_type - The type of output generated (tar, iso, etc.) + * queue_status - The final status of the composition (FINISHED or FAILED) + """ + uuid_dir = joinpaths(cfg.get("composer", "lib_dir"), "results", uuid) + if not os.path.exists(uuid_dir): + return None + + # Load the compose configuration + cfg_path = joinpaths(uuid_dir, "config.toml") + if not os.path.exists(cfg_path): + raise RuntimeError("Missing config.toml for %s" % uuid) + cfg_dict = toml.loads(open(cfg_path, "r").read()) + + frozen_path = joinpaths(uuid_dir, "frozen.toml") + if not os.path.exists(frozen_path): + raise RuntimeError("Missing frozen.toml for %s" % uuid) + frozen_dict = toml.loads(open(frozen_path, "r").read()) + + deps_path = joinpaths(uuid_dir, "deps.toml") + if not os.path.exists(deps_path): + raise RuntimeError("Missing deps.toml for %s" % uuid) + deps_dict = toml.loads(open(deps_path, "r").read()) + + details = compose_detail(uuid_dir) + + commit_path = joinpaths(uuid_dir, "COMMIT") + if not os.path.exists(commit_path): + raise RuntimeError("Missing commit hash for %s" % uuid) + commit_id = open(commit_path, "r").read().strip() + + return {"id": uuid, + "config": cfg_dict, + "blueprint": frozen_dict, + "commit": commit_id, + "deps": deps_dict, + "compose_type": details["compose_type"], + "queue_status": details["queue_status"], + "image_size": details["image_size"] + }
    + +
    [docs]def uuid_tar(cfg, uuid, metadata=False, image=False, logs=False): + """Return a tar of the build data + + :param cfg: Configuration settings + :type cfg: ComposerConfig + :param uuid: The UUID of the build + :type uuid: str + :param metadata: Set to true to include all the metadata needed to reproduce the build + :type metadata: bool + :param image: Set to true to include the output image + :type image: bool + :param logs: Set to true to include the logs from the build + :type logs: bool + :returns: A stream of bytes from tar + :rtype: A generator + :raises: RuntimeError if there was a problem (eg. missing config file) + + This yields an uncompressed tar's data to the caller. It includes + the selected data to the caller by returning the Popen stdout from the tar process. + """ + uuid_dir = joinpaths(cfg.get("composer", "lib_dir"), "results", uuid) + if not os.path.exists(uuid_dir): + raise RuntimeError("%s is not a valid build_id" % uuid) + + # Load the compose configuration + cfg_path = joinpaths(uuid_dir, "config.toml") + if not os.path.exists(cfg_path): + raise RuntimeError("Missing config.toml for %s" % uuid) + cfg_dict = toml.loads(open(cfg_path, "r").read()) + image_name = cfg_dict["image_name"] + + def include_file(f): + if f.endswith("/logs"): + return logs + if f.endswith(image_name): + return image + return metadata + filenames = [os.path.basename(f) for f in glob(joinpaths(uuid_dir, "*")) if include_file(f)] + + tar = Popen(["tar", "-C", uuid_dir, "-cf-"] + filenames, stdout=PIPE) + return tar.stdout
    + +
    [docs]def uuid_image(cfg, uuid): + """Return the filename and full path of the build's image file + + :param cfg: Configuration settings + :type cfg: ComposerConfig + :param uuid: The UUID of the build + :type uuid: str + :returns: The image filename and full path + :rtype: tuple of strings + :raises: RuntimeError if there was a problem (eg. invalid uuid, missing config file) + """ + uuid_dir = joinpaths(cfg.get("composer", "lib_dir"), "results", uuid) + return get_image_name(uuid_dir)
    + +
    [docs]def get_image_name(uuid_dir): + """Return the filename and full path of the build's image file + + :param uuid: The UUID of the build + :type uuid: str + :returns: The image filename and full path + :rtype: tuple of strings + :raises: RuntimeError if there was a problem (eg. invalid uuid, missing config file) + """ + uuid = os.path.basename(os.path.abspath(uuid_dir)) + if not os.path.exists(uuid_dir): + raise RuntimeError("%s is not a valid build_id" % uuid) + + # Load the compose configuration + cfg_path = joinpaths(uuid_dir, "config.toml") + if not os.path.exists(cfg_path): + raise RuntimeError("Missing config.toml for %s" % uuid) + cfg_dict = toml.loads(open(cfg_path, "r").read()) + image_name = cfg_dict["image_name"] + + return (image_name, joinpaths(uuid_dir, image_name))
    + +
    [docs]def uuid_log(cfg, uuid, size=1024): + """Return `size` kbytes from the end of the anaconda.log + + :param cfg: Configuration settings + :type cfg: ComposerConfig + :param uuid: The UUID of the build + :type uuid: str + :param size: Number of kbytes to read. Default is 1024 + :type size: int + :returns: Up to `size` kbytes from the end of the log + :rtype: str + :raises: RuntimeError if there was a problem (eg. no log file available) + + This function tries to return lines from the end of the log, it will + attempt to start on a line boundry, and may return less than `size` kbytes. + """ + uuid_dir = joinpaths(cfg.get("composer", "lib_dir"), "results", uuid) + if not os.path.exists(uuid_dir): + raise RuntimeError("%s is not a valid build_id" % uuid) + + # While a build is running the logs will be in /tmp/anaconda.log and when it + # has finished they will be in the results directory + status = uuid_status(cfg, uuid) + if status is None: + raise RuntimeError("Status is missing for %s" % uuid) + + if status["queue_status"] == "RUNNING": + log_path = "/tmp/anaconda.log" + else: + log_path = joinpaths(uuid_dir, "logs", "anaconda", "anaconda.log") + if not os.path.exists(log_path): + raise RuntimeError("No anaconda.log available.") + + with open(log_path, "r") as f: + f.seek(0, 2) + end = f.tell() + if end < 1024 * size: + f.seek(0, 0) + else: + f.seek(end - (1024 * size)) + # Find the start of the next line and return the rest + f.readline() + return f.read()
    +
    + +
    + +
    +
    + + +
    + +
    +

    + © Copyright 2018-2019, Red Hat, Inc. + +

    +
    + Built with Sphinx using a theme provided by Read the Docs. + +
    + +
    +
    + +
    + +
    + + + + + + + + + + + + \ No newline at end of file diff --git a/rhel8-branch/_modules/pylorax/api/recipes.html b/rhel8-branch/_modules/pylorax/api/recipes.html new file mode 100644 index 00000000..85420ed9 --- /dev/null +++ b/rhel8-branch/_modules/pylorax/api/recipes.html @@ -0,0 +1,1478 @@ + + + + + + + + + + + pylorax.api.recipes — Lorax 28.14.33 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + + + +
    + + + + + +
    + +
    + + + + + + + + + + + + + + + + + +
    + + + + +
    +
    +
    +
    + +

    Source code for pylorax.api.recipes

    +#
    +# Copyright (C) 2017-2019  Red Hat, Inc.
    +#
    +# This program is free software; you can redistribute it and/or modify
    +# it under the terms of the GNU General Public License as published by
    +# the Free Software Foundation; either version 2 of the License, or
    +# (at your option) any later version.
    +#
    +# This program is distributed in the hope that it will be useful,
    +# but WITHOUT ANY WARRANTY; without even the implied warranty of
    +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    +# GNU General Public License for more details.
    +#
    +# You should have received a copy of the GNU General Public License
    +# along with this program.  If not, see <http://www.gnu.org/licenses/>.
    +#
    +
    +import gi
    +gi.require_version("Ggit", "1.0")
    +from gi.repository import Ggit as Git
    +from gi.repository import Gio
    +from gi.repository import GLib
    +
    +import os
    +import pytoml as toml
    +import semantic_version as semver
    +
    +from pylorax.api.projects import dep_evra
    +from pylorax.base import DataHolder
    +from pylorax.sysutils import joinpaths
    +
    +
    +
    [docs]class CommitTimeValError(Exception): + pass
    + +
    [docs]class RecipeFileError(Exception): + pass
    + +
    [docs]class RecipeError(Exception): + pass
    + + +
    [docs]class Recipe(dict): + """A Recipe of package and modules + + This is a subclass of dict that enforces the constructor arguments + and adds a .filename property to return the recipe's filename, + and a .toml() function to return the recipe as a TOML string. + """ + def __init__(self, name, description, version, modules, packages, groups, customizations=None, gitrepos=None): + # Check that version is empty or semver compatible + if version: + semver.Version(version) + + # Make sure modules, packages, and groups are listed by their case-insensitive names + if modules is not None: + modules = sorted(modules, key=lambda m: m["name"].lower()) + if packages is not None: + packages = sorted(packages, key=lambda p: p["name"].lower()) + if groups is not None: + groups = sorted(groups, key=lambda g: g["name"].lower()) + + # Only support [[repos.git]] for now + if gitrepos is not None: + repos = {"git": sorted(gitrepos, key=lambda g: g["repo"].lower())} + else: + repos = None + dict.__init__(self, name=name, + description=description, + version=version, + modules=modules, + packages=packages, + groups=groups, + customizations=customizations, + repos=repos) + + # We don't want customizations=None to show up in the TOML so remove it + if customizations is None: + del self["customizations"] + + # Don't include empty repos or repos.git + if repos is None or not repos["git"]: + del self["repos"] + + @property + def package_names(self): + """Return the names of the packages""" + return [p["name"] for p in self["packages"] or []] + + @property + def package_nver(self): + """Return the names and version globs of the packages""" + return [(p["name"], p["version"]) for p in self["packages"] or []] + + @property + def module_names(self): + """Return the names of the modules""" + return [m["name"] for m in self["modules"] or []] + + @property + def module_nver(self): + """Return the names and version globs of the modules""" + return [(m["name"], m["version"]) for m in self["modules"] or []] + + @property + def group_names(self): + """Return the names of the groups. Groups do not have versions.""" + return map(lambda g: g["name"], self["groups"] or []) + + @property + def filename(self): + """Return the Recipe's filename + + Replaces spaces in the name with '-' and appends .toml + """ + return recipe_filename(self.get("name")) + +
    [docs] def toml(self): + """Return the Recipe in TOML format""" + return toml.dumps(self)
    + +
    [docs] def bump_version(self, old_version=None): + """semver recipe version number bump + + :param old_version: An optional old version number + :type old_version: str + :returns: The new version number or None + :rtype: str + :raises: ValueError + + If neither have a version, 0.0.1 is returned + If there is no old version the new version is checked and returned + If there is no new version, but there is a old one, bump its patch level + If the old and new versions are the same, bump the patch level + If they are different, check and return the new version + """ + new_version = self.get("version") + if not new_version and not old_version: + self["version"] = "0.0.1" + + elif new_version and not old_version: + semver.Version(new_version) + self["version"] = new_version + + elif not new_version or new_version == old_version: + new_version = str(semver.Version(old_version).next_patch()) + self["version"] = new_version + + else: + semver.Version(new_version) + self["version"] = new_version + + # Return the new version + return str(semver.Version(self["version"]))
    + +
    [docs] def freeze(self, deps): + """ Return a new Recipe with full module and package NEVRA + + :param deps: A list of dependency NEVRA to use to fill in the modules and packages + :type deps: list( + :returns: A new Recipe object + :rtype: Recipe + """ + module_names = self.module_names + package_names = self.package_names + group_names = self.group_names + + new_modules = [] + new_packages = [] + new_groups = [] + for dep in deps: + if dep["name"] in package_names: + new_packages.append(RecipePackage(dep["name"], dep_evra(dep))) + elif dep["name"] in module_names: + new_modules.append(RecipeModule(dep["name"], dep_evra(dep))) + elif dep["name"] in group_names: + new_groups.append(RecipeGroup(dep["name"])) + if "customizations" in self: + customizations = self["customizations"] + else: + customizations = None + if "repos" in self and "git" in self["repos"]: + gitrepos = self["repos"]["git"] + else: + gitrepos = None + + return Recipe(self["name"], self["description"], self["version"], + new_modules, new_packages, new_groups, customizations, gitrepos)
    + +
    [docs]class RecipeModule(dict): + def __init__(self, name, version): + dict.__init__(self, name=name, version=version)
    + +
    [docs]class RecipePackage(RecipeModule): + pass
    + +
    [docs]class RecipeGroup(dict): + def __init__(self, name): + dict.__init__(self, name=name)
    + +
    [docs]def NewRecipeGit(toml_dict): + """Create a RecipeGit object from fields in a TOML dict + + :param rpmname: Name of the rpm to create, also used as the prefix name in the tar archive + :type rpmname: str + :param rpmversion: Version of the rpm, eg. "1.0.0" + :type rpmversion: str + :param rpmrelease: Release of the rpm, eg. "1" + :type rpmrelease: str + :param summary: Summary string for the rpm + :type summary: str + :param repo: URL of the get repo to clone and create the archive from + :type repo: str + :param ref: Git reference to check out. eg. origin/branch-name, git tag, or git commit hash + :type ref: str + :param destination: Path to install the / of the git repo at when installing the rpm + :type destination: str + :returns: A populated RecipeGit object + :rtype: RecipeGit + + The TOML should look like this:: + + [[repos.git]] + rpmname="server-config" + rpmversion="1.0" + rpmrelease="1" + summary="Setup files for server deployment" + repo="PATH OF GIT REPO TO CLONE" + ref="v1.0" + destination="/opt/server/" + + Note that the repo path supports anything that git supports, file://, https://, http:// + + Currently there is no support for authentication + """ + return RecipeGit(toml_dict.get("rpmname"), + toml_dict.get("rpmversion"), + toml_dict.get("rpmrelease"), + toml_dict.get("summary", ""), + toml_dict.get("repo"), + toml_dict.get("ref"), + toml_dict.get("destination"))
    + +
    [docs]class RecipeGit(dict): + def __init__(self, rpmname, rpmversion, rpmrelease, summary, repo, ref, destination): + dict.__init__(self, rpmname=rpmname, rpmversion=rpmversion, rpmrelease=rpmrelease, + summary=summary, repo=repo, ref=ref, destination=destination)
    + +
    [docs]def recipe_from_file(recipe_path): + """Return a recipe file as a Recipe object + + :param recipe_path: Path to the recipe fila + :type recipe_path: str + :returns: A Recipe object + :rtype: Recipe + """ + with open(recipe_path, 'rb') as f: + return recipe_from_toml(f.read())
    + +
    [docs]def recipe_from_toml(recipe_str): + """Create a Recipe object from a toml string. + + :param recipe_str: The Recipe TOML string + :type recipe_str: str + :returns: A Recipe object + :rtype: Recipe + :raises: TomlError + """ + recipe_dict = toml.loads(recipe_str) + return recipe_from_dict(recipe_dict)
    + +
    [docs]def check_required_list(lst, fields): + """Check a list of dicts for required fields + + :param lst: A list of dicts with fields + :type lst: list of dict + :param fields: A list of field name strings + :type fields: list of str + :returns: A list of error strings + :rtype: list of str + """ + errors = [] + for i, m in enumerate(lst): + m_errs = [] + errors.extend(check_list_case(fields, m.keys(), prefix="%d " % (i+1))) + for f in fields: + if f not in m: + m_errs.append("'%s'" % f) + if m_errs: + errors.append("%d is missing %s" % (i+1, ", ".join(m_errs))) + return errors
    + +
    [docs]def check_list_case(expected_keys, recipe_keys, prefix=""): + """Check the case of the recipe keys + + :param expected_keys: A list of expected key strings + :type expected_keys: list of str + :param recipe_keys: A list of the recipe's key strings + :type recipe_keys: list of str + :returns: list of errors + :rtype: list of str + """ + errors = [] + for k in recipe_keys: + if k in expected_keys: + continue + if k.lower() in expected_keys: + errors.append(prefix + "%s should be %s" % (k, k.lower())) + return errors
    + +
    [docs]def check_recipe_dict(recipe_dict): + """Check a dict before using it to create a new Recipe + + :param recipe_dict: A plain dict of the recipe + :type recipe_dict: dict + :returns: True if dict is ok + :rtype: bool + :raises: RecipeError + + This checks a dict to make sure required fields are present, + that optional fields are correct, and that other optional fields + are of the correct format, when included. + + This collects all of the errors and returns a single RecipeError with + a string that can be presented to users. + """ + errors = [] + + # Check for wrong case of top level keys + top_keys = ["name", "description", "version", "modules", "packages", "groups", "repos", "customizations"] + errors.extend(check_list_case(recipe_dict.keys(), top_keys)) + + if "name" not in recipe_dict: + errors.append("Missing 'name'") + if "description" not in recipe_dict: + errors.append("Missing 'description'") + if "version" in recipe_dict: + try: + semver.Version(recipe_dict["version"]) + except ValueError: + errors.append("Invalid 'version', must use Semantic Versioning") + + # Examine all the modules + if recipe_dict.get("modules"): + module_errors = check_required_list(recipe_dict["modules"], ["name", "version"]) + if module_errors: + errors.append("'modules' errors:\n%s" % "\n".join(module_errors)) + + # Examine all the packages + if recipe_dict.get("packages"): + package_errors = check_required_list(recipe_dict["packages"], ["name", "version"]) + if package_errors: + errors.append("'packages' errors:\n%s" % "\n".join(package_errors)) + + if recipe_dict.get("groups"): + groups_errors = check_required_list(recipe_dict["groups"], ["name"]) + if groups_errors: + errors.append("'groups' errors:\n%s" % "\n".join(groups_errors)) + + if recipe_dict.get("repos") and recipe_dict.get("repos").get("git"): + repos_errors = check_required_list(recipe_dict.get("repos").get("git"), + ["rpmname", "rpmversion", "rpmrelease", "summary", "repo", "ref", "destination"]) + if repos_errors: + errors.append("'repos.git' errors:\n%s" % "\n".join(repos_errors)) + + # No customizations to check, exit now + c = recipe_dict.get("customizations") + if not c: + return errors + + # Make sure to catch empty sections by testing for keywords, not just looking at .get() result. + if "kernel" in c: + errors.extend(check_list_case(["append"], c["kernel"].keys(), prefix="kernel ")) + if "append" not in c.get("kernel", []): + errors.append("'customizations.kernel': missing append field.") + + if "sshkey" in c: + sshkey_errors = check_required_list(c.get("sshkey"), ["user", "key"]) + if sshkey_errors: + errors.append("'customizations.sshkey' errors:\n%s" % "\n".join(sshkey_errors)) + + if "user" in c: + user_errors = check_required_list(c.get("user"), ["name"]) + if user_errors: + errors.append("'customizations.user' errors:\n%s" % "\n".join(user_errors)) + + if "group" in c: + group_errors = check_required_list(c.get("group"), ["name"]) + if group_errors: + errors.append("'customizations.group' errors:\n%s" % "\n".join(group_errors)) + + if "timezone" in c: + errors.extend(check_list_case(["timezone", "ntpservers"], c["timezone"].keys(), prefix="timezone ")) + if not c.get("timezone"): + errors.append("'customizations.timezone': missing timezone or ntpservers fields.") + + if "locale" in c: + errors.extend(check_list_case(["languages", "keyboard"], c["locale"].keys(), prefix="locale ")) + if not c.get("locale"): + errors.append("'customizations.locale': missing languages or keyboard fields.") + + if "firewall" in c: + errors.extend(check_list_case(["ports"], c["firewall"].keys(), prefix="firewall ")) + if not c.get("firewall"): + errors.append("'customizations.firewall': missing ports field or services section.") + + if "services" in c.get("firewall", []): + errors.extend(check_list_case(["enabled", "disabled"], c["firewall"]["services"].keys(), prefix="firewall.services ")) + if not c.get("firewall").get("services"): + errors.append("'customizations.firewall.services': missing enabled or disabled fields.") + + if "services" in c: + errors.extend(check_list_case(["enabled", "disabled"], c["services"].keys(), prefix="services ")) + if not c.get("services"): + errors.append("'customizations.services': missing enabled or disabled fields.") + + return errors
    + +
    [docs]def recipe_from_dict(recipe_dict): + """Create a Recipe object from a plain dict. + + :param recipe_dict: A plain dict of the recipe + :type recipe_dict: dict + :returns: A Recipe object + :rtype: Recipe + :raises: RecipeError + """ + errors = check_recipe_dict(recipe_dict) + if errors: + msg = "\n".join(errors) + raise RecipeError(msg) + + # Make RecipeModule objects from the toml + # The TOML may not have modules or packages in it. Set them to None in this case + try: + if recipe_dict.get("modules"): + modules = [RecipeModule(m.get("name"), m.get("version")) for m in recipe_dict["modules"]] + else: + modules = [] + if recipe_dict.get("packages"): + packages = [RecipePackage(p.get("name"), p.get("version")) for p in recipe_dict["packages"]] + else: + packages = [] + if recipe_dict.get("groups"): + groups = [RecipeGroup(g.get("name")) for g in recipe_dict["groups"]] + else: + groups = [] + if recipe_dict.get("repos") and recipe_dict.get("repos").get("git"): + gitrepos = [NewRecipeGit(r) for r in recipe_dict["repos"]["git"]] + else: + gitrepos = [] + name = recipe_dict["name"] + description = recipe_dict["description"] + version = recipe_dict.get("version", None) + customizations = recipe_dict.get("customizations", None) + + # [customizations] was incorrectly documented at first, so we have to support using it + # as [[customizations]] by grabbing the first element. + if isinstance(customizations, list): + customizations = customizations[0] + + except KeyError as e: + raise RecipeError("There was a problem parsing the recipe: %s" % str(e)) + + return Recipe(name, description, version, modules, packages, groups, customizations, gitrepos)
    + +
    [docs]def gfile(path): + """Convert a string path to GFile for use with Git""" + return Gio.file_new_for_path(path)
    + +
    [docs]def recipe_filename(name): + """Return the toml filename for a recipe + + Replaces spaces with '-' and appends '.toml' + """ + # XXX Raise and error if this is empty? + return name.replace(" ", "-") + ".toml"
    + +
    [docs]def head_commit(repo, branch): + """Get the branch's HEAD Commit Object + + :param repo: Open repository + :type repo: Git.Repository + :param branch: Branch name + :type branch: str + :returns: Branch's head commit + :rtype: Git.Commit + :raises: Can raise errors from Ggit + """ + branch_obj = repo.lookup_branch(branch, Git.BranchType.LOCAL) + commit_id = branch_obj.get_target() + return repo.lookup(commit_id, Git.Commit)
    + +
    [docs]def prepare_commit(repo, branch, builder): + """Prepare for a commit + + :param repo: Open repository + :type repo: Git.Repository + :param branch: Branch name + :type branch: str + :param builder: instance of TreeBuilder + :type builder: TreeBuilder + :returns: (Tree, Sig, Ref) + :rtype: tuple + :raises: Can raise errors from Ggit + """ + tree_id = builder.write() + tree = repo.lookup(tree_id, Git.Tree) + sig = Git.Signature.new_now("bdcs-api-server", "user-email") + ref = "refs/heads/%s" % branch + return (tree, sig, ref)
    + +
    [docs]def open_or_create_repo(path): + """Open an existing repo, or create a new one + + :param path: path to recipe directory + :type path: string + :returns: A repository object + :rtype: Git.Repository + :raises: Can raise errors from Ggit + + A bare git repo will be created in the git directory of the specified path. + If a repo already exists it will be opened and returned instead of + creating a new one. + """ + Git.init() + git_path = joinpaths(path, "git") + if os.path.exists(joinpaths(git_path, "HEAD")): + return Git.Repository.open(gfile(git_path)) + + repo = Git.Repository.init_repository(gfile(git_path), True) + + # Make an initial empty commit + sig = Git.Signature.new_now("bdcs-api-server", "user-email") + tree_id = repo.get_index().write_tree() + tree = repo.lookup(tree_id, Git.Tree) + repo.create_commit("HEAD", sig, sig, "UTF-8", "Initial Recipe repository commit", tree, []) + return repo
    + +
    [docs]def write_commit(repo, branch, filename, message, content): + """Make a new commit to a repository's branch + + :param repo: Open repository + :type repo: Git.Repository + :param branch: Branch name + :type branch: str + :param filename: full path of the file to add + :type filename: str + :param message: The commit message + :type message: str + :param content: The data to write + :type content: str + :returns: OId of the new commit + :rtype: Git.OId + :raises: Can raise errors from Ggit + """ + try: + parent_commit = head_commit(repo, branch) + except GLib.GError: + # Branch doesn't exist, make a new one based on master + master_head = head_commit(repo, "master") + repo.create_branch(branch, master_head, 0) + parent_commit = head_commit(repo, branch) + + parent_commit = head_commit(repo, branch) + blob_id = repo.create_blob_from_buffer(content.encode("UTF-8")) + + # Use treebuilder to make a new entry for this filename and blob + parent_tree = parent_commit.get_tree() + builder = repo.create_tree_builder_from_tree(parent_tree) + builder.insert(filename, blob_id, Git.FileMode.BLOB) + (tree, sig, ref) = prepare_commit(repo, branch, builder) + return repo.create_commit(ref, sig, sig, "UTF-8", message, tree, [parent_commit])
    + +
    [docs]def read_commit_spec(repo, spec): + """Return the raw content of the blob specified by the spec + + :param repo: Open repository + :type repo: Git.Repository + :param spec: Git revparse spec + :type spec: str + :returns: Contents of the commit + :rtype: str + :raises: Can raise errors from Ggit + + eg. To read the README file from master the spec is "master:README" + """ + commit_id = repo.revparse(spec).get_id() + blob = repo.lookup(commit_id, Git.Blob) + return blob.get_raw_content()
    + +
    [docs]def read_commit(repo, branch, filename, commit=None): + """Return the contents of a file on a specific branch or commit. + + :param repo: Open repository + :type repo: Git.Repository + :param branch: Branch name + :type branch: str + :param filename: filename to read + :type filename: str + :param commit: Optional commit hash + :type commit: str + :returns: The commit id, and the contents of the commit + :rtype: tuple(str, str) + :raises: Can raise errors from Ggit + + If no commit is passed the master:filename is returned, otherwise it will be + commit:filename + """ + if not commit: + # Find the most recent commit for filename on the selected branch + commits = list_commits(repo, branch, filename, 1) + if not commits: + raise RecipeError("No commits for %s on the %s branch." % (filename, branch)) + commit = commits[0].commit + return (commit, read_commit_spec(repo, "%s:%s" % (commit, filename)))
    + +
    [docs]def read_recipe_commit(repo, branch, recipe_name, commit=None): + """Read a recipe commit from git and return a Recipe object + + :param repo: Open repository + :type repo: Git.Repository + :param branch: Branch name + :type branch: str + :param recipe_name: Recipe name to read + :type recipe_name: str + :param commit: Optional commit hash + :type commit: str + :returns: A Recipe object + :rtype: Recipe + :raises: Can raise errors from Ggit + + If no commit is passed the master:filename is returned, otherwise it will be + commit:filename + """ + if not repo_file_exists(repo, branch, recipe_filename(recipe_name)): + raise RecipeFileError("Unknown blueprint") + + (_, recipe_toml) = read_commit(repo, branch, recipe_filename(recipe_name), commit) + return recipe_from_toml(recipe_toml)
    + +
    [docs]def read_recipe_and_id(repo, branch, recipe_name, commit=None): + """Read a recipe commit and its id from git + + :param repo: Open repository + :type repo: Git.Repository + :param branch: Branch name + :type branch: str + :param recipe_name: Recipe name to read + :type recipe_name: str + :param commit: Optional commit hash + :type commit: str + :returns: The commit id, and a Recipe object + :rtype: tuple(str, Recipe) + :raises: Can raise errors from Ggit + + If no commit is passed the master:filename is returned, otherwise it will be + commit:filename + """ + (commit_id, recipe_toml) = read_commit(repo, branch, recipe_filename(recipe_name), commit) + return (commit_id, recipe_from_toml(recipe_toml))
    + +
    [docs]def list_branch_files(repo, branch): + """Return a sorted list of the files on the branch HEAD + + :param repo: Open repository + :type repo: Git.Repository + :param branch: Branch name + :type branch: str + :returns: A sorted list of the filenames + :rtype: list(str) + :raises: Can raise errors from Ggit + """ + commit = head_commit(repo, branch).get_id().to_string() + return list_commit_files(repo, commit)
    + +
    [docs]def list_commit_files(repo, commit): + """Return a sorted list of the files on a commit + + :param repo: Open repository + :type repo: Git.Repository + :param commit: The commit hash to list + :type commit: str + :returns: A sorted list of the filenames + :rtype: list(str) + :raises: Can raise errors from Ggit + """ + commit_id = Git.OId.new_from_string(commit) + commit_obj = repo.lookup(commit_id, Git.Commit) + tree = commit_obj.get_tree() + return sorted([tree.get(i).get_name() for i in range(0, tree.size())])
    + +
    [docs]def delete_recipe(repo, branch, recipe_name): + """Delete a recipe from a branch. + + :param repo: Open repository + :type repo: Git.Repository + :param branch: Branch name + :type branch: str + :param recipe_name: Recipe name to delete + :type recipe_name: str + :returns: OId of the new commit + :rtype: Git.OId + :raises: Can raise errors from Ggit + """ + return delete_file(repo, branch, recipe_filename(recipe_name))
    + +
    [docs]def delete_file(repo, branch, filename): + """Delete a file from a branch. + + :param repo: Open repository + :type repo: Git.Repository + :param branch: Branch name + :type branch: str + :param filename: filename to delete + :type filename: str + :returns: OId of the new commit + :rtype: Git.OId + :raises: Can raise errors from Ggit + """ + parent_commit = head_commit(repo, branch) + parent_tree = parent_commit.get_tree() + builder = repo.create_tree_builder_from_tree(parent_tree) + builder.remove(filename) + (tree, sig, ref) = prepare_commit(repo, branch, builder) + message = "Recipe %s deleted" % filename + return repo.create_commit(ref, sig, sig, "UTF-8", message, tree, [parent_commit])
    + +
    [docs]def revert_recipe(repo, branch, recipe_name, commit): + """Revert the contents of a recipe to that of a previous commit + + :param repo: Open repository + :type repo: Git.Repository + :param branch: Branch name + :type branch: str + :param recipe_name: Recipe name to revert + :type recipe_name: str + :param commit: Commit hash + :type commit: str + :returns: OId of the new commit + :rtype: Git.OId + :raises: Can raise errors from Ggit + """ + return revert_file(repo, branch, recipe_filename(recipe_name), commit)
    + +
    [docs]def revert_file(repo, branch, filename, commit): + """Revert the contents of a file to that of a previous commit + + :param repo: Open repository + :type repo: Git.Repository + :param branch: Branch name + :type branch: str + :param filename: filename to revert + :type filename: str + :param commit: Commit hash + :type commit: str + :returns: OId of the new commit + :rtype: Git.OId + :raises: Can raise errors from Ggit + """ + commit_id = Git.OId.new_from_string(commit) + commit_obj = repo.lookup(commit_id, Git.Commit) + revert_tree = commit_obj.get_tree() + entry = revert_tree.get_by_name(filename) + blob_id = entry.get_id() + parent_commit = head_commit(repo, branch) + + # Use treebuilder to modify the tree + parent_tree = parent_commit.get_tree() + builder = repo.create_tree_builder_from_tree(parent_tree) + builder.insert(filename, blob_id, Git.FileMode.BLOB) + (tree, sig, ref) = prepare_commit(repo, branch, builder) + commit_hash = commit_id.to_string() + message = "%s reverted to commit %s" % (filename, commit_hash) + return repo.create_commit(ref, sig, sig, "UTF-8", message, tree, [parent_commit])
    + +
    [docs]def commit_recipe(repo, branch, recipe): + """Commit a recipe to a branch + + :param repo: Open repository + :type repo: Git.Repository + :param branch: Branch name + :type branch: str + :param recipe: Recipe to commit + :type recipe: Recipe + :returns: OId of the new commit + :rtype: Git.OId + :raises: Can raise errors from Ggit + """ + try: + old_recipe = read_recipe_commit(repo, branch, recipe["name"]) + old_version = old_recipe["version"] + except Exception: + old_version = None + + recipe.bump_version(old_version) + recipe_toml = recipe.toml() + message = "Recipe %s, version %s saved." % (recipe["name"], recipe["version"]) + return write_commit(repo, branch, recipe.filename, message, recipe_toml)
    + +
    [docs]def commit_recipe_file(repo, branch, filename): + """Commit a recipe file to a branch + + :param repo: Open repository + :type repo: Git.Repository + :param branch: Branch name + :type branch: str + :param filename: Path to the recipe file to commit + :type filename: str + :returns: OId of the new commit + :rtype: Git.OId + :raises: Can raise errors from Ggit or RecipeFileError + """ + try: + recipe = recipe_from_file(filename) + except IOError: + raise RecipeFileError + + return commit_recipe(repo, branch, recipe)
    + +
    [docs]def commit_recipe_directory(repo, branch, directory): + r"""Commit all \*.toml files from a directory, if they aren't already in git. + + :param repo: Open repository + :type repo: Git.Repository + :param branch: Branch name + :type branch: str + :param directory: The directory of \*.toml recipes to commit + :type directory: str + :returns: None + :raises: Can raise errors from Ggit or RecipeFileError + + Files with Toml or RecipeFileErrors will be skipped, and the remainder will + be tried. + """ + dir_files = set([e for e in os.listdir(directory) if e.endswith(".toml")]) + branch_files = set(list_branch_files(repo, branch)) + new_files = dir_files.difference(branch_files) + + for f in new_files: + # Skip files with errors, but try the others + try: + commit_recipe_file(repo, branch, joinpaths(directory, f)) + except (RecipeFileError, toml.TomlError): + pass
    + +
    [docs]def tag_recipe_commit(repo, branch, recipe_name): + """Tag a file's most recent commit + + :param repo: Open repository + :type repo: Git.Repository + :param branch: Branch name + :type branch: str + :param recipe_name: Recipe name to tag + :type recipe_name: str + :returns: Tag id or None if it failed. + :rtype: Git.OId + :raises: Can raise errors from Ggit + + Uses tag_file_commit() + """ + if not repo_file_exists(repo, branch, recipe_filename(recipe_name)): + raise RecipeFileError("Unknown blueprint") + + return tag_file_commit(repo, branch, recipe_filename(recipe_name))
    + +
    [docs]def tag_file_commit(repo, branch, filename): + """Tag a file's most recent commit + + :param repo: Open repository + :type repo: Git.Repository + :param branch: Branch name + :type branch: str + :param filename: Filename to tag + :type filename: str + :returns: Tag id or None if it failed. + :rtype: Git.OId + :raises: Can raise errors from Ggit + + This uses git tags, of the form `refs/tags/<branch>/<filename>/r<revision>` + Only the most recent recipe commit can be tagged to prevent out of order tagging. + Revisions start at 1 and increment for each new commit that is tagged. + If the commit has already been tagged it will return false. + """ + file_commits = list_commits(repo, branch, filename) + if not file_commits: + return None + + # Find the most recently tagged version (may not be one) and add 1 to it. + for details in file_commits: + if details.revision is not None: + new_revision = details.revision + 1 + break + else: + new_revision = 1 + + name = "%s/%s/r%d" % (branch, filename, new_revision) + sig = Git.Signature.new_now("bdcs-api-server", "user-email") + commit_id = Git.OId.new_from_string(file_commits[0].commit) + commit = repo.lookup(commit_id, Git.Commit) + return repo.create_tag(name, commit, sig, name, Git.CreateFlags.NONE)
    + +
    [docs]def find_commit_tag(repo, branch, filename, commit_id): + """Find the tag that matches the commit_id + + :param repo: Open repository + :type repo: Git.Repository + :param branch: Branch name + :type branch: str + :param filename: filename to revert + :type filename: str + :param commit_id: The commit id to check + :type commit_id: Git.OId + :returns: The tag or None if there isn't one + :rtype: str or None + + There should be only 1 tag pointing to a commit, but there may not + be a tag at all. + + The tag will look like: 'refs/tags/<branch>/<filename>/r<revision>' + """ + pattern = "%s/%s/r*" % (branch, filename) + tags = [t for t in repo.list_tags_match(pattern) if is_commit_tag(repo, commit_id, t)] + if len(tags) != 1: + return None + else: + return tags[0]
    + +
    [docs]def is_commit_tag(repo, commit_id, tag): + """Check to see if a tag points to a specific commit. + + :param repo: Open repository + :type repo: Git.Repository + :param commit_id: The commit id to check + :type commit_id: Git.OId + :param tag: The tag to check + :type tag: str + :returns: True if the tag points to the commit, False otherwise + :rtype: bool + """ + ref = repo.lookup_reference("refs/tags/" + tag) + tag_id = ref.get_target() + tag = repo.lookup(tag_id, Git.Tag) + target_id = tag.get_target_id() + return commit_id.compare(target_id) == 0
    + +
    [docs]def get_revision_from_tag(tag): + """Return the revision number from a tag + + :param tag: The tag to exract the revision from + :type tag: str + :returns: The integer revision or None + :rtype: int or None + + The revision is the part after the r in 'branch/filename/rXXX' + """ + if tag is None: + return None + try: + return int(tag.rsplit('r', 2)[-1]) + except (ValueError, IndexError): + return None
    + +
    [docs]class CommitDetails(DataHolder): + def __init__(self, commit, timestamp, message, revision=None): + DataHolder.__init__(self, + commit = commit, + timestamp = timestamp, + message = message, + revision = revision)
    + +
    [docs]def list_commits(repo, branch, filename, limit=0): + """List the commit history of a file on a branch. + + :param repo: Open repository + :type repo: Git.Repository + :param branch: Branch name + :type branch: str + :param filename: filename to revert + :type filename: str + :param limit: Number of commits to return (0=all) + :type limit: int + :returns: A list of commit details + :rtype: list(CommitDetails) + :raises: Can raise errors from Ggit + """ + revwalk = Git.RevisionWalker.new(repo) + branch_ref = "refs/heads/%s" % branch + revwalk.push_ref(branch_ref) + + commits = [] + while True: + commit_id = revwalk.next() + if not commit_id: + break + commit = repo.lookup(commit_id, Git.Commit) + + parents = commit.get_parents() + # No parents? Must be the first commit. + if parents.get_size() == 0: + continue + + tree = commit.get_tree() + # Is the filename in this tree? If not, move on. + if not tree.get_by_name(filename): + continue + + # Is filename different in all of the parent commits? + parent_commits = list(map(parents.get, range(0, parents.get_size()))) + is_diff = all([is_parent_diff(repo, filename, tree, pc) for pc in parent_commits]) + # No changes from parents, skip it. + if not is_diff: + continue + + tag = find_commit_tag(repo, branch, filename, commit.get_id()) + try: + commits.append(get_commit_details(commit, get_revision_from_tag(tag))) + if limit and len(commits) > limit: + break + except CommitTimeValError: + # Skip any commits that have trouble converting the time + # TODO - log details about this failure + pass + + # These will be in reverse time sort order thanks to revwalk + return commits
    + +
    [docs]def get_commit_details(commit, revision=None): + """Return the details about a specific commit. + + :param commit: The commit to get details from + :type commit: Git.Commit + :param revision: Optional commit revision + :type revision: int + :returns: Details about the commit + :rtype: CommitDetails + :raises: CommitTimeValError or Ggit exceptions + + """ + message = commit.get_message() + commit_str = commit.get_id().to_string() + sig = commit.get_committer() + + datetime = sig.get_time() + # XXX What do we do with timezone? + _timezone = sig.get_time_zone() + timeval = GLib.TimeVal() + ok = datetime.to_timeval(timeval) + if not ok: + raise CommitTimeValError + time_str = timeval.to_iso8601() + + return CommitDetails(commit_str, time_str, message, revision)
    + +
    [docs]def is_parent_diff(repo, filename, tree, parent): + """Check to see if the commit is different from its parents + + :param repo: Open repository + :type repo: Git.Repository + :param filename: filename to revert + :type filename: str + :param tree: The commit's tree + :type tree: Git.Tree + :param parent: The commit's parent commit + :type parent: Git.Commit + :retuns: True if filename in the commit is different from its parents + :rtype: bool + """ + diff_opts = Git.DiffOptions.new() + diff_opts.set_pathspec([filename]) + diff = Git.Diff.new_tree_to_tree(repo, parent.get_tree(), tree, diff_opts) + return diff.get_num_deltas() > 0
    + +
    [docs]def find_field_value(field, value, lst): + """Find a field matching value in the list of dicts. + + :param field: field to search for + :type field: str + :param value: value to match in the field + :type value: str + :param lst: List of dict's with field + :type lst: list of dict + :returns: First dict with matching field:value, or None + :rtype: dict or None + + Used to return a specific entry from a list that looks like this: + + [{"name": "one", "attr": "green"}, ...] + + find_field_value("name", "one", lst) will return the matching dict. + """ + for d in lst: + if d.get(field) and d.get(field) == value: + return d + return None
    + +
    [docs]def find_name(name, lst): + """Find the dict matching the name in a list and return it. + + :param name: Name to search for + :type name: str + :param lst: List of dict's with "name" field + :type lst: list of dict + :returns: First dict with matching name, or None + :rtype: dict or None + + This is just a wrapper for find_field_value with field set to "name" + """ + return find_field_value("name", name, lst)
    + +
    [docs]def find_recipe_obj(path, recipe, default=None): + """Find a recipe object + + :param path: A list of dict field names + :type path: list of str + :param recipe: The recipe to search + :type recipe: Recipe + :param default: The value to return if it is not found + :type default: Any + + Return the object found by applying the path to the dicts in the recipe, or + return the default if it doesn't exist. + + eg. {"customizations": {"hostname": "foo", "users": [...]}} + + find_recipe_obj(["customizations", "hostname"], recipe, "") + """ + o = recipe + try: + for p in path: + if not o.get(p): + return default + o = o.get(p) + except AttributeError: + return default + + return o
    + +
    [docs]def diff_lists(title, field, old_items, new_items): + """Return the differences between two lists of dicts. + + :param title: Title of the entry + :type title: str + :param field: Field to use as the key for comparisons + :type field: str + :param old_items: List of item dicts with "name" field + :type old_items: list(dict) + :param new_items: List of item dicts with "name" field + :type new_items: list(dict) + :returns: List of diff dicts with old/new entries + :rtype: list(dict) + """ + diffs = [] + old_fields= set(m[field] for m in old_items) + new_fields= set(m[field] for m in new_items) + + added_items = new_fields.difference(old_fields) + added_items = sorted(added_items, key=lambda n: n.lower()) + + removed_items = old_fields.difference(new_fields) + removed_items = sorted(removed_items, key=lambda n: n.lower()) + + same_items = old_fields.intersection(new_fields) + same_items = sorted(same_items, key=lambda n: n.lower()) + + for v in added_items: + diffs.append({"old":None, + "new":{title:find_field_value(field, v, new_items)}}) + + for v in removed_items: + diffs.append({"old":{title:find_field_value(field, v, old_items)}, + "new":None}) + + for v in same_items: + old_item = find_field_value(field, v, old_items) + new_item = find_field_value(field, v, new_items) + if old_item != new_item: + diffs.append({"old":{title:old_item}, + "new":{title:new_item}}) + + return diffs
    + +
    [docs]def customizations_diff(old_recipe, new_recipe): + """Diff the customizations sections from two versions of a recipe + """ + diffs = [] + old_keys = set(old_recipe.get("customizations", {}).keys()) + new_keys = set(new_recipe.get("customizations", {}).keys()) + + added_keys = new_keys.difference(old_keys) + added_keys = sorted(added_keys, key=lambda n: n.lower()) + + removed_keys = old_keys.difference(new_keys) + removed_keys = sorted(removed_keys, key=lambda n: n.lower()) + + same_keys = old_keys.intersection(new_keys) + same_keys = sorted(same_keys, key=lambda n: n.lower()) + + for v in added_keys: + diffs.append({"old": None, + "new": {"Customizations."+v: new_recipe["customizations"][v]}}) + + for v in removed_keys: + diffs.append({"old": {"Customizations."+v: old_recipe["customizations"][v]}, + "new": None}) + + for v in same_keys: + if new_recipe["customizations"][v] == old_recipe["customizations"][v]: + continue + + if type(new_recipe["customizations"][v]) == type([]): + # Lists of dicts need to use diff_lists + # sshkey uses 'user', user and group use 'name' + if "user" in new_recipe["customizations"][v][0]: + field_name = "user" + elif "name" in new_recipe["customizations"][v][0]: + field_name = "name" + else: + raise RuntimeError("%s list has unrecognized key, not 'name' or 'user'" % "customizations."+v) + + diffs.extend(diff_lists("Customizations."+v, field_name, old_recipe["customizations"][v], new_recipe["customizations"][v])) + else: + diffs.append({"old": {"Customizations."+v: old_recipe["customizations"][v]}, + "new": {"Customizations."+v: new_recipe["customizations"][v]}}) + + return diffs
    + + +
    [docs]def recipe_diff(old_recipe, new_recipe): + """Diff two versions of a recipe + + :param old_recipe: The old version of the recipe + :type old_recipe: Recipe + :param new_recipe: The new version of the recipe + :type new_recipe: Recipe + :returns: A list of diff dict entries with old/new + :rtype: list(dict) + """ + + diffs = [] + # These cannot be added or removed, just different + for element in ["name", "description", "version"]: + if old_recipe[element] != new_recipe[element]: + diffs.append({"old":{element.title():old_recipe[element]}, + "new":{element.title():new_recipe[element]}}) + + # These lists always exist + diffs.extend(diff_lists("Module", "name", old_recipe["modules"], new_recipe["modules"])) + diffs.extend(diff_lists("Package", "name", old_recipe["packages"], new_recipe["packages"])) + diffs.extend(diff_lists("Group", "name", old_recipe["groups"], new_recipe["groups"])) + + # The customizations section can contain a number of different types + diffs.extend(customizations_diff(old_recipe, new_recipe)) + + # repos contains keys that are lists (eg. [[repos.git]]) + diffs.extend(diff_lists("Repos.git", "rpmname", + find_recipe_obj(["repos", "git"], old_recipe, []), + find_recipe_obj(["repos", "git"], new_recipe, []))) + + return diffs
    + +
    [docs]def repo_file_exists(repo, branch, filename): + """Return True if the filename exists on the branch + + :param repo: Open repository + :type repo: Git.Repository + :param branch: Branch name + :type branch: str + :param filename: Filename to check + :type filename: str + :returns: True if the filename exists on the HEAD of the branch, False otherwise. + :rtype: bool + """ + commit = head_commit(repo, branch).get_id().to_string() + commit_id = Git.OId.new_from_string(commit) + commit_obj = repo.lookup(commit_id, Git.Commit) + tree = commit_obj.get_tree() + return tree.get_by_name(filename) is not None
    +
    + +
    + +
    +
    + + +
    + +
    +

    + © Copyright 2018-2019, Red Hat, Inc. + +

    +
    + Built with Sphinx using a theme provided by Read the Docs. + +
    + +
    +
    + +
    + +
    + + + + + + + + + + + + \ No newline at end of file diff --git a/rhel8-branch/_modules/pylorax/api/server.html b/rhel8-branch/_modules/pylorax/api/server.html new file mode 100644 index 00000000..1194a0e7 --- /dev/null +++ b/rhel8-branch/_modules/pylorax/api/server.html @@ -0,0 +1,282 @@ + + + + + + + + + + + pylorax.api.server — Lorax 28.14.33 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + + + +
    + + + + + +
    + +
    + + + + + + + + + + + + + + + + + +
    + + + + +
    +
    +
    +
    + +

    Source code for pylorax.api.server

    +#
    +# Copyright (C) 2017  Red Hat, Inc.
    +#
    +# This program is free software; you can redistribute it and/or modify
    +# it under the terms of the GNU General Public License as published by
    +# the Free Software Foundation; either version 2 of the License, or
    +# (at your option) any later version.
    +#
    +# This program is distributed in the hope that it will be useful,
    +# but WITHOUT ANY WARRANTY; without even the implied warranty of
    +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    +# GNU General Public License for more details.
    +#
    +# You should have received a copy of the GNU General Public License
    +# along with this program.  If not, see <http://www.gnu.org/licenses/>.
    +#
    +import logging
    +log = logging.getLogger("lorax-composer")
    +
    +from collections import namedtuple
    +from flask import Flask, jsonify, redirect, send_from_directory
    +from glob import glob
    +import os
    +
    +from pylorax import vernum
    +from pylorax.api.crossdomain import crossdomain
    +from pylorax.api.v0 import v0_api
    +from pylorax.sysutils import joinpaths
    +
    +GitLock = namedtuple("GitLock", ["repo", "lock", "dir"])
    +
    +server = Flask(__name__)
    +
    +__all__ = ["server", "GitLock"]
    +
    +@server.route('/')
    +def server_root():
    +    redirect("/api/docs/")
    +
    +@server.route("/api/docs/")
    +@server.route("/api/docs/<path:path>")
    +def api_docs(path=None):
    +    # Find the html docs
    +    try:
    +        # This assumes it is running from the source tree
    +        docs_path = os.path.abspath(joinpaths(os.path.dirname(__file__), "../../../docs/html"))
    +    except IndexError:
    +        docs_path = glob("/usr/share/doc/lorax-*/html/")[0]
    +
    +    if not path:
    +        path="index.html"
    +    return send_from_directory(docs_path, path)
    +
    +@server.route("/api/status")
    +@crossdomain(origin="*")
    +def v0_status():
    +    """
    +    `/api/v0/status`
    +    ^^^^^^^^^^^^^^^^
    +    Return the status of the API Server::
    +
    +          { "api": "0",
    +            "build": "devel",
    +            "db_supported": true,
    +            "db_version": "0",
    +            "schema_version": "0",
    +            "backend": "lorax-composer",
    +            "msgs": []}
    +
    +    The 'msgs' field can be a list of strings describing startup problems or status that
    +    should be displayed to the user. eg. if the compose templates are not depsolving properly
    +    the errors will be in 'msgs'.
    +    """
    +    return jsonify(backend="lorax-composer",
    +                   build=vernum,
    +                   api="0",
    +                   db_version="0",
    +                   schema_version="0",
    +                   db_supported=True,
    +                   msgs=server.config["TEMPLATE_ERRORS"])
    +
    +v0_api(server)
    +
    + +
    + +
    +
    + + +
    + +
    +

    + © Copyright 2018-2019, Red Hat, Inc. + +

    +
    + Built with Sphinx using a theme provided by Read the Docs. + +
    + +
    +
    + +
    + +
    + + + + + + + + + + + + \ No newline at end of file diff --git a/rhel8-branch/_modules/pylorax/api/v0.html b/rhel8-branch/_modules/pylorax/api/v0.html new file mode 100644 index 00000000..9a0c8c12 --- /dev/null +++ b/rhel8-branch/_modules/pylorax/api/v0.html @@ -0,0 +1,2277 @@ + + + + + + + + + + + pylorax.api.v0 — Lorax 28.14.33 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + + + +
    + + + + + +
    + +
    + + + + + + + + + + + + + + + + + +
    + + + + +
    +
    +
    +
    + +

    Source code for pylorax.api.v0

    +#
    +# Copyright (C) 2017-2018  Red Hat, Inc.
    +#
    +# This program is free software; you can redistribute it and/or modify
    +# it under the terms of the GNU General Public License as published by
    +# the Free Software Foundation; either version 2 of the License, or
    +# (at your option) any later version.
    +#
    +# This program is distributed in the hope that it will be useful,
    +# but WITHOUT ANY WARRANTY; without even the implied warranty of
    +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    +# GNU General Public License for more details.
    +#
    +# You should have received a copy of the GNU General Public License
    +# along with this program.  If not, see <http://www.gnu.org/licenses/>.
    +#
    +""" Setup v0 of the API server
    +
    +v0_api() must be called to setup the API routes for Flask
    +
    +Status Responses
    +----------------
    +
    +Some requests only return a status/error response.
    +
    +  The response will be a status response with `status` set to true, or an
    +  error response with it set to false and an error message included.
    +
    +  Example response::
    +
    +      {
    +        "status": true
    +      }
    +
    +  Error response::
    +
    +      {
    +        "errors": ["ggit-error: Failed to remove entry. File isn't in the tree - jboss.toml (-1)"]
    +        "status": false
    +      }
    +
    +API Routes
    +----------
    +
    +All of the blueprints routes support the optional `branch` argument. If it is not
    +used then the API will use the `master` branch for blueprints. If you want to create
    +a new branch use the `new` or `workspace` routes with ?branch=<branch-name> to
    +store the new blueprint on the new branch.
    +
    +`/api/v0/blueprints/list`
    +^^^^^^^^^^^^^^^^^^^^^^^^^
    +
    +  List the available blueprints::
    +
    +      { "limit": 20,
    +        "offset": 0,
    +        "blueprints": [
    +          "atlas",
    +          "development",
    +          "glusterfs",
    +          "http-server",
    +          "jboss",
    +          "kubernetes" ],
    +        "total": 6 }
    +
    +`/api/v0/blueprints/info/<blueprint_names>[?format=<json|toml>]`
    +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    +
    +  Return the JSON representation of the blueprint. This includes 3 top level
    +  objects.  `changes` which lists whether or not the workspace is different from
    +  the most recent commit. `blueprints` which lists the JSON representation of the
    +  blueprint, and `errors` which will list any errors, like non-existant blueprints.
    +
    +  By default the response is JSON, but if `?format=toml` is included in the URL's
    +  arguments it will return the response as the blueprint's raw TOML content.
    +  *Unless* there is an error which will only return a 400 and a standard error
    +  `Status Response`_.
    +
    +  If there is an error when JSON is requested the successful blueprints and the
    +  errors will both be returned.
    +
    +  Example of json response::
    +
    +      {
    +        "changes": [
    +          {
    +            "changed": false,
    +            "name": "glusterfs"
    +          }
    +        ],
    +        "errors": [],
    +        "blueprints": [
    +          {
    +            "description": "An example GlusterFS server with samba",
    +            "modules": [
    +              {
    +                "name": "glusterfs",
    +                "version": "3.7.*"
    +              },
    +              {
    +                "name": "glusterfs-cli",
    +                "version": "3.7.*"
    +              }
    +            ],
    +            "name": "glusterfs",
    +            "packages": [
    +              {
    +                "name": "2ping",
    +                "version": "3.2.1"
    +              },
    +              {
    +                "name": "samba",
    +                "version": "4.2.*"
    +              }
    +            ],
    +            "version": "0.0.6"
    +          }
    +        ]
    +      }
    +
    +  Error example::
    +
    +      {
    +        "changes": [],
    +        "errors": ["ggit-error: the path 'missing.toml' does not exist in the given tree (-3)"]
    +        "blueprints": []
    +      }
    +
    +`/api/v0/blueprints/changes/<blueprint_names>[?offset=0&limit=20]`
    +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    +
    +  Return the commits to a blueprint. By default it returns the first 20 commits, this
    +  can be changed by passing `offset` and/or `limit`. The response will include the
    +  commit hash, summary, timestamp, and optionally the revision number. The commit
    +  hash can be passed to `/api/v0/blueprints/diff/` to retrieve the exact changes.
    +
    +  Example::
    +
    +      {
    +        "errors": [],
    +        "limit": 20,
    +        "offset": 0,
    +        "blueprints": [
    +          {
    +            "changes": [
    +              {
    +                "commit": "e083921a7ed1cf2eec91ad12b9ad1e70ef3470be",
    +                "message": "blueprint glusterfs, version 0.0.6 saved.",
    +                "revision": null,
    +                "timestamp": "2017-11-23T00:18:13Z"
    +              },
    +              {
    +                "commit": "cee5f4c20fc33ea4d54bfecf56f4ad41ad15f4f3",
    +                "message": "blueprint glusterfs, version 0.0.5 saved.",
    +                "revision": null,
    +                "timestamp": "2017-11-11T01:00:28Z"
    +              },
    +              {
    +                "commit": "29b492f26ed35d80800b536623bafc51e2f0eff2",
    +                "message": "blueprint glusterfs, version 0.0.4 saved.",
    +                "revision": null,
    +                "timestamp": "2017-11-11T00:28:30Z"
    +              },
    +              {
    +                "commit": "03374adbf080fe34f5c6c29f2e49cc2b86958bf2",
    +                "message": "blueprint glusterfs, version 0.0.3 saved.",
    +                "revision": null,
    +                "timestamp": "2017-11-10T23:15:52Z"
    +              },
    +              {
    +                "commit": "0e08ecbb708675bfabc82952599a1712a843779d",
    +                "message": "blueprint glusterfs, version 0.0.2 saved.",
    +                "revision": null,
    +                "timestamp": "2017-11-10T23:14:56Z"
    +              },
    +              {
    +                "commit": "3e11eb87a63d289662cba4b1804a0947a6843379",
    +                "message": "blueprint glusterfs, version 0.0.1 saved.",
    +                "revision": null,
    +                "timestamp": "2017-11-08T00:02:47Z"
    +              }
    +            ],
    +            "name": "glusterfs",
    +            "total": 6
    +          }
    +        ]
    +      }
    +
    +POST `/api/v0/blueprints/new`
    +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    +
    +  Create a new blueprint, or update an existing blueprint. This supports both JSON and TOML
    +  for the blueprint format. The blueprint should be in the body of the request with the
    +  `Content-Type` header set to either `application/json` or `text/x-toml`.
    +
    +  The response will be a status response with `status` set to true, or an
    +  error response with it set to false and an error message included.
    +
    +DELETE `/api/v0/blueprints/delete/<blueprint_name>`
    +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    +
    +  Delete a blueprint. The blueprint is deleted from the branch, and will no longer
    +  be listed by the `list` route. A blueprint can be undeleted using the `undo` route
    +  to revert to a previous commit. This will also delete the workspace copy of the
    +  blueprint.
    +
    +  The response will be a status response with `status` set to true, or an
    +  error response with it set to false and an error message included.
    +
    +POST `/api/v0/blueprints/workspace`
    +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    +
    +  Write a blueprint to the temporary workspace. This works exactly the same as `new` except
    +  that it does not create a commit. JSON and TOML bodies are supported.
    +
    +  The workspace is meant to be used as a temporary blueprint storage for clients.
    +  It will be read by the `info` and `diff` routes if it is different from the
    +  most recent commit.
    +
    +  The response will be a status response with `status` set to true, or an
    +  error response with it set to false and an error message included.
    +
    +DELETE `/api/v0/blueprints/workspace/<blueprint_name>`
    +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    +
    +  Remove the temporary workspace copy of a blueprint. The `info` route will now
    +  return the most recent commit of the blueprint. Any changes that were in the
    +  workspace will be lost.
    +
    +  The response will be a status response with `status` set to true, or an
    +  error response with it set to false and an error message included.
    +
    +POST `/api/v0/blueprints/undo/<blueprint_name>/<commit>`
    +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    +
    +  This will revert the blueprint to a previous commit. The commit hash from the `changes`
    +  route can be used in this request.
    +
    +  The response will be a status response with `status` set to true, or an
    +  error response with it set to false and an error message included.
    +
    +POST `/api/v0/blueprints/tag/<blueprint_name>`
    +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    +
    +  Tag a blueprint as a new release. This uses git tags with a special format.
    +  `refs/tags/<branch>/<filename>/r<revision>`. Only the most recent blueprint commit
    +  can be tagged. Revisions start at 1 and increment for each new tag
    +  (per-blueprint). If the commit has already been tagged it will return false.
    +
    +  The response will be a status response with `status` set to true, or an
    +  error response with it set to false and an error message included.
    +
    +`/api/v0/blueprints/diff/<blueprint_name>/<from_commit>/<to_commit>`
    +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    +
    +  Return the differences between two commits, or the workspace. The commit hash
    +  from the `changes` response can be used here, or several special strings:
    +
    +  - NEWEST will select the newest git commit. This works for `from_commit` or `to_commit`
    +  - WORKSPACE will select the workspace copy. This can only be used in `to_commit`
    +
    +  eg. `/api/v0/blueprints/diff/glusterfs/NEWEST/WORKSPACE` will return the differences
    +  between the most recent git commit and the contents of the workspace.
    +
    +  Each entry in the response's diff object contains the old blueprint value and the new one.
    +  If old is null and new is set, then it was added.
    +  If new is null and old is set, then it was removed.
    +  If both are set, then it was changed.
    +
    +  The old/new entries will have the name of the blueprint field that was changed. This
    +  can be one of: Name, Description, Version, Module, or Package.
    +  The contents for these will be the old/new values for them.
    +
    +  In the example below the version was changed and the ping package was added.
    +
    +  Example::
    +
    +      {
    +        "diff": [
    +          {
    +            "new": {
    +              "Version": "0.0.6"
    +            },
    +            "old": {
    +              "Version": "0.0.5"
    +            }
    +          },
    +          {
    +            "new": {
    +              "Package": {
    +                "name": "ping",
    +                "version": "3.2.1"
    +              }
    +            },
    +            "old": null
    +          }
    +        ]
    +      }
    +
    +`/api/v0/blueprints/freeze/<blueprint_names>`
    +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    +
    +  Return a JSON representation of the blueprint with the package and module versions set
    +  to the exact versions chosen by depsolving the blueprint.
    +
    +  Example::
    +
    +      {
    +        "errors": [],
    +        "blueprints": [
    +          {
    +            "blueprint": {
    +              "description": "An example GlusterFS server with samba",
    +              "modules": [
    +                {
    +                  "name": "glusterfs",
    +                  "version": "3.8.4-18.4.el7.x86_64"
    +                },
    +                {
    +                  "name": "glusterfs-cli",
    +                  "version": "3.8.4-18.4.el7.x86_64"
    +                }
    +              ],
    +              "name": "glusterfs",
    +              "packages": [
    +                {
    +                  "name": "ping",
    +                  "version": "2:3.2.1-2.el7.noarch"
    +                },
    +                {
    +                  "name": "samba",
    +                  "version": "4.6.2-8.el7.x86_64"
    +                }
    +              ],
    +              "version": "0.0.6"
    +            }
    +          }
    +        ]
    +      }
    +
    +`/api/v0/blueprints/depsolve/<blueprint_names>`
    +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    +
    +  Depsolve the blueprint using yum, return the blueprint used, and the NEVRAs of the packages
    +  chosen to satisfy the blueprint's requirements. The response will include a list of results,
    +  with the full dependency list in `dependencies`, the NEVRAs for the blueprint's direct modules
    +  and packages in `modules`, and any error will be in `errors`.
    +
    +  Example::
    +
    +      {
    +        "errors": [],
    +        "blueprints": [
    +          {
    +            "dependencies": [
    +              {
    +                "arch": "noarch",
    +                "epoch": "0",
    +                "name": "2ping",
    +                "release": "2.el7",
    +                "version": "3.2.1"
    +              },
    +              {
    +                "arch": "x86_64",
    +                "epoch": "0",
    +                "name": "acl",
    +                "release": "12.el7",
    +                "version": "2.2.51"
    +              },
    +              {
    +                "arch": "x86_64",
    +                "epoch": "0",
    +                "name": "audit-libs",
    +                "release": "3.el7",
    +                "version": "2.7.6"
    +              },
    +              {
    +                "arch": "x86_64",
    +                "epoch": "0",
    +                "name": "avahi-libs",
    +                "release": "17.el7",
    +                "version": "0.6.31"
    +              },
    +              ...
    +            ],
    +            "modules": [
    +              {
    +                "arch": "noarch",
    +                "epoch": "0",
    +                "name": "2ping",
    +                "release": "2.el7",
    +                "version": "3.2.1"
    +              },
    +              {
    +                "arch": "x86_64",
    +                "epoch": "0",
    +                "name": "glusterfs",
    +                "release": "18.4.el7",
    +                "version": "3.8.4"
    +              },
    +              ...
    +            ],
    +            "blueprint": {
    +              "description": "An example GlusterFS server with samba",
    +              "modules": [
    +                {
    +                  "name": "glusterfs",
    +                  "version": "3.7.*"
    +                },
    +             ...
    +            }
    +          }
    +        ]
    +      }
    +
    +`/api/v0/projects/list[?offset=0&limit=20]`
    +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    +
    +  List all of the available projects. By default this returns the first 20 items,
    +  but this can be changed by setting the `offset` and `limit` arguments.
    +
    +  Example::
    +
    +      {
    +        "limit": 20,
    +        "offset": 0,
    +        "projects": [
    +          {
    +            "description": "0 A.D. (pronounced \"zero ey-dee\") is a ...",
    +            "homepage": "http://play0ad.com",
    +            "name": "0ad",
    +            "summary": "Cross-Platform RTS Game of Ancient Warfare",
    +            "upstream_vcs": "UPSTREAM_VCS"
    +          },
    +          ...
    +        ],
    +        "total": 21770
    +      }
    +
    +`/api/v0/projects/info/<project_names>`
    +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    +
    +  Return information about the comma-separated list of projects. It includes the description
    +  of the package along with the list of available builds.
    +
    +  Example::
    +
    +      {
    +        "projects": [
    +          {
    +            "builds": [
    +              {
    +                "arch": "x86_64",
    +                "build_config_ref": "BUILD_CONFIG_REF",
    +                "build_env_ref": "BUILD_ENV_REF",
    +                "build_time": "2017-03-01T08:39:23",
    +                "changelog": "- restore incremental backups correctly, files ...",
    +                "epoch": "2",
    +                "metadata": {},
    +                "release": "32.el7",
    +                "source": {
    +                  "license": "GPLv3+",
    +                  "metadata": {},
    +                  "source_ref": "SOURCE_REF",
    +                  "version": "1.26"
    +                }
    +              }
    +            ],
    +            "description": "The GNU tar program saves many ...",
    +            "homepage": "http://www.gnu.org/software/tar/",
    +            "name": "tar",
    +            "summary": "A GNU file archiving program",
    +            "upstream_vcs": "UPSTREAM_VCS"
    +          }
    +        ]
    +      }
    +
    +`/api/v0/projects/depsolve/<project_names>`
    +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    +
    +  Depsolve the comma-separated list of projects and return the list of NEVRAs needed
    +  to satisfy the request.
    +
    +  Example::
    +
    +      {
    +        "projects": [
    +          {
    +            "arch": "noarch",
    +            "epoch": "0",
    +            "name": "basesystem",
    +            "release": "7.el7",
    +            "version": "10.0"
    +          },
    +          {
    +            "arch": "x86_64",
    +            "epoch": "0",
    +            "name": "bash",
    +            "release": "28.el7",
    +            "version": "4.2.46"
    +          },
    +          {
    +            "arch": "x86_64",
    +            "epoch": "0",
    +            "name": "filesystem",
    +            "release": "21.el7",
    +            "version": "3.2"
    +          },
    +          ...
    +        ]
    +      }
    +
    +`/api/v0/projects/source/list`
    +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    +
    +  Return the list of repositories used for depsolving and installing packages.
    +
    +  Example::
    +
    +      {
    +        "sources": [
    +          "fedora",
    +          "fedora-cisco-openh264",
    +          "fedora-updates-testing",
    +          "fedora-updates"
    +        ]
    +      }
    +
    +`/api/v0/projects/source/info/<source-names>`
    +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    +
    +  Return information about the comma-separated list of source names. Or all of the
    +  sources if '*' is passed. Note that general globbing is not supported, only '*'.
    +
    +  immutable system sources will have the "system" field set to true. User added sources
    +  will have it set to false. System sources cannot be changed or deleted.
    +
    +  Example::
    +
    +      {
    +        "errors": [],
    +        "sources": {
    +          "fedora": {
    +            "check_gpg": true,
    +            "check_ssl": true,
    +            "gpgkey_urls": [
    +              "file:///etc/pki/rpm-gpg/RPM-GPG-KEY-fedora-28-x86_64"
    +            ],
    +            "name": "fedora",
    +            "proxy": "http://proxy.brianlane.com:8123",
    +            "system": true,
    +            "type": "yum-metalink",
    +            "url": "https://mirrors.fedoraproject.org/metalink?repo=fedora-28&arch=x86_64"
    +          }
    +        }
    +      }
    +
    +POST `/api/v0/projects/source/new`
    +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    +
    +  Add (or change) a source for use when depsolving blueprints and composing images.
    +
    +  The ``proxy`` and ``gpgkey_urls`` entries are optional. All of the others are required. The supported
    +  types for the urls are:
    +
    +  * ``yum-baseurl`` is a URL to a yum repository.
    +  * ``yum-mirrorlist`` is a URL for a mirrorlist.
    +  * ``yum-metalink`` is a URL for a metalink.
    +
    +  If ``check_ssl`` is true the https certificates must be valid. If they are self-signed you can either set
    +  this to false, or add your Certificate Authority to the host system.
    +
    +  If ``check_gpg`` is true the GPG key must either be installed on the host system, or ``gpgkey_urls``
    +  should point to it.
    +
    +  You can edit an existing source (other than system sources), by doing a POST
    +  of the new version of the source. It will overwrite the previous one.
    +
    +  Example::
    +
    +      {
    +          "name": "custom-source-1",
    +          "url": "https://url/path/to/repository/",
    +          "type": "yum-baseurl",
    +          "check_ssl": true,
    +          "check_gpg": true,
    +          "gpgkey_urls": [
    +              "https://url/path/to/gpg-key"
    +          ]
    +      }
    +
    +DELETE `/api/v0/projects/source/delete/<source-name>`
    +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    +
    +  Delete a user added source. This will fail if a system source is passed to
    +  it.
    +
    +  The response will be a status response with `status` set to true, or an
    +  error response with it set to false and an error message included.
    +
    +`/api/v0/modules/list[?offset=0&limit=20]`
    +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    +
    +  Return a list of all of the available modules. This includes the name and the
    +  group_type, which is always "rpm" for lorax-composer. By default this returns
    +  the first 20 items. This can be changed by setting the `offset` and `limit`
    +  arguments.
    +
    +  Example::
    +
    +      {
    +        "limit": 20,
    +        "modules": [
    +          {
    +            "group_type": "rpm",
    +            "name": "0ad"
    +          },
    +          {
    +            "group_type": "rpm",
    +            "name": "0ad-data"
    +          },
    +          {
    +            "group_type": "rpm",
    +            "name": "0install"
    +          },
    +          {
    +            "group_type": "rpm",
    +            "name": "2048-cli"
    +          },
    +          ...
    +        ]
    +        "total": 21770
    +      }
    +
    +`/api/v0/modules/list/<module_names>[?offset=0&limit=20]`
    +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    +
    +  Return the list of comma-separated modules. Output is the same as `/modules/list`
    +
    +  Example::
    +
    +      {
    +        "limit": 20,
    +        "modules": [
    +          {
    +            "group_type": "rpm",
    +            "name": "tar"
    +          }
    +        ],
    +        "offset": 0,
    +        "total": 1
    +      }
    +
    +`/api/v0/modules/info/<module_names>`
    +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    +
    +  Return the module's dependencies, and the information about the module.
    +
    +  Example::
    +
    +      {
    +        "modules": [
    +          {
    +            "dependencies": [
    +              {
    +                "arch": "noarch",
    +                "epoch": "0",
    +                "name": "basesystem",
    +                "release": "7.el7",
    +                "version": "10.0"
    +              },
    +              {
    +                "arch": "x86_64",
    +                "epoch": "0",
    +                "name": "bash",
    +                "release": "28.el7",
    +                "version": "4.2.46"
    +              },
    +              ...
    +            ],
    +            "description": "The GNU tar program saves ...",
    +            "homepage": "http://www.gnu.org/software/tar/",
    +            "name": "tar",
    +            "summary": "A GNU file archiving program",
    +            "upstream_vcs": "UPSTREAM_VCS"
    +          }
    +        ]
    +      }
    +
    +POST `/api/v0/compose`
    +^^^^^^^^^^^^^^^^^^^^^^
    +
    +  Start a compose. The content type should be 'application/json' and the body of the POST
    +  should look like this::
    +
    +      {
    +        "blueprint_name": "http-server",
    +        "compose_type": "tar",
    +        "branch": "master"
    +      }
    +
    +  Pass it the name of the blueprint, the type of output (from '/api/v0/compose/types'), and the
    +  blueprint branch to use. 'branch' is optional and will default to master. It will create a new
    +  build and add it to the queue. It returns the build uuid and a status if it succeeds::
    +
    +      {
    +        "build_id": "e6fa6db4-9c81-4b70-870f-a697ca405cdf",
    +        "status": true
    +      }
    +
    +`/api/v0/compose/types`
    +^^^^^^^^^^^^^^^^^^^^^^^
    +
    +  Returns the list of supported output types that are valid for use with 'POST /api/v0/compose'
    +
    +      {
    +        "types": [
    +          {
    +            "enabled": true,
    +            "name": "tar"
    +          }
    +        ]
    +      }
    +
    +`/api/v0/compose/queue`
    +^^^^^^^^^^^^^^^^^^^^^^^
    +
    +  Return the status of the build queue. It includes information about the builds waiting,
    +  and the build that is running.
    +
    +  Example::
    +
    +      {
    +        "new": [
    +          {
    +            "id": "45502a6d-06e8-48a5-a215-2b4174b3614b",
    +            "blueprint": "glusterfs",
    +            "queue_status": "WAITING",
    +            "job_created": 1517362647.4570868,
    +            "version": "0.0.6"
    +          },
    +          {
    +            "id": "6d292bd0-bec7-4825-8d7d-41ef9c3e4b73",
    +            "blueprint": "kubernetes",
    +            "queue_status": "WAITING",
    +            "job_created": 1517362659.0034983,
    +            "version": "0.0.1"
    +          }
    +        ],
    +        "run": [
    +          {
    +            "id": "745712b2-96db-44c0-8014-fe925c35e795",
    +            "blueprint": "glusterfs",
    +            "queue_status": "RUNNING",
    +            "job_created": 1517362633.7965999,
    +            "job_started": 1517362633.8001345,
    +            "version": "0.0.6"
    +          }
    +        ]
    +      }
    +
    +`/api/v0/compose/finished`
    +^^^^^^^^^^^^^^^^^^^^^^^^^^
    +
    +  Return the details on all of the finished composes on the system.
    +
    +  Example::
    +
    +      {
    +        "finished": [
    +          {
    +            "id": "70b84195-9817-4b8a-af92-45e380f39894",
    +            "blueprint": "glusterfs",
    +            "queue_status": "FINISHED",
    +            "job_created": 1517351003.8210032,
    +            "job_started": 1517351003.8230415,
    +            "job_finished": 1517359234.1003145,
    +            "version": "0.0.6"
    +          },
    +          {
    +            "id": "e695affd-397f-4af9-9022-add2636e7459",
    +            "blueprint": "glusterfs",
    +            "queue_status": "FINISHED",
    +            "job_created": 1517362289.7193348,
    +            "job_started": 1517362289.9751132,
    +            "job_finished": 1517363500.1234567,
    +            "version": "0.0.6"
    +          }
    +        ]
    +      }
    +
    +`/api/v0/compose/failed`
    +^^^^^^^^^^^^^^^^^^^^^^^^^^
    +
    +  Return the details on all of the failed composes on the system.
    +
    +  Example::
    +
    +      {
    +        "failed": [
    +           {
    +            "id": "8c8435ef-d6bd-4c68-9bf1-a2ef832e6b1a",
    +            "blueprint": "http-server",
    +            "queue_status": "FAILED",
    +            "job_created": 1517523249.9301329,
    +            "job_started": 1517523249.9314211,
    +            "job_finished": 1517523255.5623411,
    +            "version": "0.0.2"
    +          }
    +        ]
    +      }
    +
    +`/api/v0/compose/status/<uuids>[?blueprint=<blueprint_name>&status=<compose_status>&type=<compose_type>]`
    +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    +
    +  Return the details for each of the comma-separated list of uuids. A uuid of '*' will return
    +  details for all composes.
    +
    +  Example::
    +
    +      {
    +        "uuids": [
    +          {
    +            "id": "8c8435ef-d6bd-4c68-9bf1-a2ef832e6b1a",
    +            "blueprint": "http-server",
    +            "queue_status": "FINISHED",
    +            "job_created": 1517523644.2384307,
    +            "job_started": 1517523644.2551234,
    +            "job_finished": 1517523689.9864314,
    +            "version": "0.0.2"
    +          },
    +          {
    +            "id": "45502a6d-06e8-48a5-a215-2b4174b3614b",
    +            "blueprint": "glusterfs",
    +            "queue_status": "FINISHED",
    +            "job_created": 1517363442.188399,
    +            "job_started": 1517363442.325324,
    +            "job_finished": 1517363451.653621,
    +            "version": "0.0.6"
    +          }
    +        ]
    +      }
    +
    +DELETE `/api/v0/compose/cancel/<uuid>`
    +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    +
    +  Cancel the build, if it is not finished, and delete the results. It will return a
    +  status of True if it is successful.
    +
    +  Example::
    +
    +      {
    +        "status": true,
    +        "uuid": "03397f8d-acff-4cdb-bd31-f629b7a948f5"
    +      }
    +
    +DELETE `/api/v0/compose/delete/<uuids>`
    +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    +
    +  Delete the list of comma-separated uuids from the compose results.
    +
    +  Example::
    +
    +      {
    +        "errors": [],
    +        "uuids": [
    +          {
    +            "status": true,
    +            "uuid": "ae1bf7e3-7f16-4c9f-b36e-3726a1093fd0"
    +          }
    +        ]
    +      }
    +
    +`/api/v0/compose/info/<uuid>`
    +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    +
    +  Get detailed information about the compose. The returned JSON string will
    +  contain the following information:
    +
    +    * id - The uuid of the comoposition
    +    * config - containing the configuration settings used to run Anaconda
    +    * blueprint - The depsolved blueprint used to generate the kickstart
    +    * commit - The (local) git commit hash for the blueprint used
    +    * deps - The NEVRA of all of the dependencies used in the composition
    +    * compose_type - The type of output generated (tar, iso, etc.)
    +    * queue_status - The final status of the composition (FINISHED or FAILED)
    +
    +  Example::
    +
    +      {
    +        "commit": "7078e521a54b12eae31c3fd028680da7a0815a4d",
    +        "compose_type": "tar",
    +        "config": {
    +          "anaconda_args": "",
    +          "armplatform": "",
    +          "compress_args": [],
    +          "compression": "xz",
    +          "image_name": "root.tar.xz",
    +          ...
    +        },
    +        "deps": {
    +          "packages": [
    +            {
    +              "arch": "x86_64",
    +              "epoch": "0",
    +              "name": "acl",
    +              "release": "14.el7",
    +              "version": "2.2.51"
    +            }
    +          ]
    +        },
    +        "id": "c30b7d80-523b-4a23-ad52-61b799739ce8",
    +        "queue_status": "FINISHED",
    +        "blueprint": {
    +          "description": "An example kubernetes master",
    +          ...
    +        }
    +      }
    +
    +`/api/v0/compose/metadata/<uuid>`
    +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    +
    +  Returns a .tar of the metadata used for the build. This includes all the
    +  information needed to reproduce the build, including the final kickstart
    +  populated with repository and package NEVRA.
    +
    +  The mime type is set to 'application/x-tar' and the filename is set to
    +  UUID-metadata.tar
    +
    +  The .tar is uncompressed, but is not large.
    +
    +`/api/v0/compose/results/<uuid>`
    +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    +
    +  Returns a .tar of the metadata, logs, and output image of the build. This
    +  includes all the information needed to reproduce the build, including the
    +  final kickstart populated with repository and package NEVRA. The output image
    +  is already in compressed form so the returned tar is not compressed.
    +
    +  The mime type is set to 'application/x-tar' and the filename is set to
    +  UUID.tar
    +
    +`/api/v0/compose/logs/<uuid>`
    +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    +
    +  Returns a .tar of the anaconda build logs. The tar is not compressed, but is
    +  not large.
    +
    +  The mime type is set to 'application/x-tar' and the filename is set to
    +  UUID-logs.tar
    +
    +`/api/v0/compose/image/<uuid>`
    +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    +
    +  Returns the output image from the build. The filename is set to the filename
    +  from the build with the UUID as a prefix. eg. UUID-root.tar.xz or UUID-boot.iso.
    +
    +`/api/v0/compose/log/<uuid>[?size=kbytes]`
    +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    +
    +  Returns the end of the anaconda.log. The size parameter is optional and defaults to 1Mbytes
    +  if it is not included. The returned data is raw text from the end of the logfile, starting on
    +  a line boundry.
    +
    +  Example::
    +
    +      12:59:24,222 INFO anaconda: Running Thread: AnaConfigurationThread (140629395244800)
    +      12:59:24,223 INFO anaconda: Configuring installed system
    +      12:59:24,912 INFO anaconda: Configuring installed system
    +      12:59:24,912 INFO anaconda: Creating users
    +      12:59:24,913 INFO anaconda: Clearing libuser.conf at /tmp/libuser.Dyy8Gj
    +      12:59:25,154 INFO anaconda: Creating users
    +      12:59:25,155 INFO anaconda: Configuring addons
    +      12:59:25,155 INFO anaconda: Configuring addons
    +      12:59:25,155 INFO anaconda: Generating initramfs
    +      12:59:49,467 INFO anaconda: Generating initramfs
    +      12:59:49,467 INFO anaconda: Running post-installation scripts
    +      12:59:49,467 INFO anaconda: Running kickstart %%post script(s)
    +      12:59:50,782 INFO anaconda: All kickstart %%post script(s) have been run
    +      12:59:50,782 INFO anaconda: Running post-installation scripts
    +      12:59:50,784 INFO anaconda: Thread Done: AnaConfigurationThread (140629395244800)
    +
    +"""
    +
    +import logging
    +log = logging.getLogger("lorax-composer")
    +
    +import os
    +from flask import jsonify, request, Response, send_file
    +import pytoml as toml
    +
    +from pylorax.sysutils import joinpaths
    +from pylorax.api.checkparams import checkparams
    +from pylorax.api.compose import start_build, compose_types
    +from pylorax.api.crossdomain import crossdomain
    +from pylorax.api.errors import *                               # pylint: disable=wildcard-import
    +from pylorax.api.projects import projects_list, projects_info, projects_depsolve
    +from pylorax.api.projects import modules_list, modules_info, ProjectsError, repo_to_source
    +from pylorax.api.projects import get_repo_sources, delete_repo_source, source_to_repo, dnf_repo_to_file_repo
    +from pylorax.api.queue import queue_status, build_status, uuid_delete, uuid_status, uuid_info
    +from pylorax.api.queue import uuid_tar, uuid_image, uuid_cancel, uuid_log
    +from pylorax.api.recipes import RecipeError, list_branch_files, read_recipe_commit, recipe_filename, list_commits
    +from pylorax.api.recipes import recipe_from_dict, recipe_from_toml, commit_recipe, delete_recipe, revert_recipe
    +from pylorax.api.recipes import tag_recipe_commit, recipe_diff, RecipeFileError
    +from pylorax.api.regexes import VALID_API_STRING
    +from pylorax.api.workspace import workspace_read, workspace_write, workspace_delete
    +
    +# The API functions don't actually get called by any code here
    +# pylint: disable=unused-variable
    +
    +
    [docs]def take_limits(iterable, offset, limit): + """ Apply offset and limit to an iterable object + + :param iterable: The object to limit + :type iterable: iter + :param offset: The number of items to skip + :type offset: int + :param limit: The total number of items to return + :type limit: int + :returns: A subset of the iterable + """ + return iterable[offset:][:limit]
    + +
    [docs]def blueprint_exists(api, branch, blueprint_name): + """Return True if the blueprint exists + + :param api: flask object + :type api: Flask + :param branch: Branch name + :type branch: str + :param recipe_name: Recipe name to read + :type recipe_name: str + """ + try: + with api.config["GITLOCK"].lock: + read_recipe_commit(api.config["GITLOCK"].repo, branch, blueprint_name) + + return True + except (RecipeError, RecipeFileError): + return False
    + +
    [docs]def v0_api(api): + # Note that Sphinx will not generate documentations for any of these. + @api.route("/api/v0/blueprints/list") + @crossdomain(origin="*") + def v0_blueprints_list(): + """List the available blueprints on a branch.""" + branch = request.args.get("branch", "master") + if VALID_API_STRING.match(branch) is None: + return jsonify(status=False, errors=[{"id": INVALID_CHARS, "msg": "Invalid characters in branch argument"}]), 400 + + try: + limit = int(request.args.get("limit", "20")) + offset = int(request.args.get("offset", "0")) + except ValueError as e: + return jsonify(status=False, errors=[{"id": BAD_LIMIT_OR_OFFSET, "msg": str(e)}]), 400 + + with api.config["GITLOCK"].lock: + blueprints = [f[:-5] for f in list_branch_files(api.config["GITLOCK"].repo, branch)] + limited_blueprints = take_limits(blueprints, offset, limit) + return jsonify(blueprints=limited_blueprints, limit=limit, offset=offset, total=len(blueprints)) + + @api.route("/api/v0/blueprints/info", defaults={'blueprint_names': ""}) + @api.route("/api/v0/blueprints/info/<blueprint_names>") + @crossdomain(origin="*") + @checkparams([("blueprint_names", "", "no blueprint names given")]) + def v0_blueprints_info(blueprint_names): + """Return the contents of the blueprint, or a list of blueprints""" + if VALID_API_STRING.match(blueprint_names) is None: + return jsonify(status=False, errors=[{"id": INVALID_CHARS, "msg": "Invalid characters in API path"}]), 400 + + branch = request.args.get("branch", "master") + if VALID_API_STRING.match(branch) is None: + return jsonify(status=False, errors=[{"id": INVALID_CHARS, "msg": "Invalid characters in branch argument"}]), 400 + + out_fmt = request.args.get("format", "json") + if VALID_API_STRING.match(out_fmt) is None: + return jsonify(status=False, errors=[{"id": INVALID_CHARS, "msg": "Invalid characters in format argument"}]), 400 + + blueprints = [] + changes = [] + errors = [] + for blueprint_name in [n.strip() for n in blueprint_names.split(",")]: + exceptions = [] + # Get the workspace version (if it exists) + try: + with api.config["GITLOCK"].lock: + ws_blueprint = workspace_read(api.config["GITLOCK"].repo, branch, blueprint_name) + except Exception as e: + ws_blueprint = None + exceptions.append(str(e)) + log.error("(v0_blueprints_info) %s", str(e)) + + # Get the git version (if it exists) + try: + with api.config["GITLOCK"].lock: + git_blueprint = read_recipe_commit(api.config["GITLOCK"].repo, branch, blueprint_name) + except RecipeFileError as e: + # Adding an exception would be redundant, skip it + git_blueprint = None + log.error("(v0_blueprints_info) %s", str(e)) + except Exception as e: + git_blueprint = None + exceptions.append(str(e)) + log.error("(v0_blueprints_info) %s", str(e)) + + if not ws_blueprint and not git_blueprint: + # Neither blueprint, return an error + errors.append({"id": UNKNOWN_BLUEPRINT, "msg": "%s: %s" % (blueprint_name, ", ".join(exceptions))}) + elif ws_blueprint and not git_blueprint: + # No git blueprint, return the workspace blueprint + changes.append({"name":blueprint_name, "changed":True}) + blueprints.append(ws_blueprint) + elif not ws_blueprint and git_blueprint: + # No workspace blueprint, no change, return the git blueprint + changes.append({"name":blueprint_name, "changed":False}) + blueprints.append(git_blueprint) + else: + # Both exist, maybe changed, return the workspace blueprint + changes.append({"name":blueprint_name, "changed":ws_blueprint != git_blueprint}) + blueprints.append(ws_blueprint) + + # Sort all the results by case-insensitive blueprint name + changes = sorted(changes, key=lambda c: c["name"].lower()) + blueprints = sorted(blueprints, key=lambda r: r["name"].lower()) + + if out_fmt == "toml": + if errors: + # If there are errors they need to be reported, use JSON and 400 for this + return jsonify(status=False, errors=errors), 400 + else: + # With TOML output we just want to dump the raw blueprint, skipping the rest. + return "\n\n".join([r.toml() for r in blueprints]) + else: + return jsonify(changes=changes, blueprints=blueprints, errors=errors) + + @api.route("/api/v0/blueprints/changes", defaults={'blueprint_names': ""}) + @api.route("/api/v0/blueprints/changes/<blueprint_names>") + @crossdomain(origin="*") + @checkparams([("blueprint_names", "", "no blueprint names given")]) + def v0_blueprints_changes(blueprint_names): + """Return the changes to a blueprint or list of blueprints""" + if VALID_API_STRING.match(blueprint_names) is None: + return jsonify(status=False, errors=[{"id": INVALID_CHARS, "msg": "Invalid characters in API path"}]), 400 + + branch = request.args.get("branch", "master") + if VALID_API_STRING.match(branch) is None: + return jsonify(status=False, errors=[{"id": INVALID_CHARS, "msg": "Invalid characters in branch argument"}]), 400 + + try: + limit = int(request.args.get("limit", "20")) + offset = int(request.args.get("offset", "0")) + except ValueError as e: + return jsonify(status=False, errors=[{"id": BAD_LIMIT_OR_OFFSET, "msg": str(e)}]), 400 + + blueprints = [] + errors = [] + for blueprint_name in [n.strip() for n in blueprint_names.split(",")]: + filename = recipe_filename(blueprint_name) + try: + with api.config["GITLOCK"].lock: + commits = list_commits(api.config["GITLOCK"].repo, branch, filename) + except Exception as e: + errors.append({"id": BLUEPRINTS_ERROR, "msg": "%s: %s" % (blueprint_name, str(e))}) + log.error("(v0_blueprints_changes) %s", str(e)) + else: + if commits: + limited_commits = take_limits(commits, offset, limit) + blueprints.append({"name":blueprint_name, "changes":limited_commits, "total":len(commits)}) + else: + # no commits means there is no blueprint in the branch + errors.append({"id": UNKNOWN_BLUEPRINT, "msg": "%s" % blueprint_name}) + + blueprints = sorted(blueprints, key=lambda r: r["name"].lower()) + + return jsonify(blueprints=blueprints, errors=errors, offset=offset, limit=limit) + + @api.route("/api/v0/blueprints/new", methods=["POST"]) + @crossdomain(origin="*") + def v0_blueprints_new(): + """Commit a new blueprint""" + branch = request.args.get("branch", "master") + if VALID_API_STRING.match(branch) is None: + return jsonify(status=False, errors=[{"id": INVALID_CHARS, "msg": "Invalid characters in branch argument"}]), 400 + + try: + if request.headers['Content-Type'] == "text/x-toml": + blueprint = recipe_from_toml(request.data) + else: + blueprint = recipe_from_dict(request.get_json(cache=False)) + + if VALID_API_STRING.match(blueprint["name"]) is None: + return jsonify(status=False, errors=[{"id": INVALID_CHARS, "msg": "Invalid characters in API path"}]), 400 + + with api.config["GITLOCK"].lock: + commit_recipe(api.config["GITLOCK"].repo, branch, blueprint) + + # Read the blueprint with new version and write it to the workspace + blueprint = read_recipe_commit(api.config["GITLOCK"].repo, branch, blueprint["name"]) + workspace_write(api.config["GITLOCK"].repo, branch, blueprint) + except Exception as e: + log.error("(v0_blueprints_new) %s", str(e)) + return jsonify(status=False, errors=[{"id": BLUEPRINTS_ERROR, "msg": str(e)}]), 400 + else: + return jsonify(status=True) + + @api.route("/api/v0/blueprints/delete", defaults={'blueprint_name': ""}, methods=["DELETE"]) + @api.route("/api/v0/blueprints/delete/<blueprint_name>", methods=["DELETE"]) + @crossdomain(origin="*") + @checkparams([("blueprint_name", "", "no blueprint name given")]) + def v0_blueprints_delete(blueprint_name): + """Delete a blueprint from git""" + if VALID_API_STRING.match(blueprint_name) is None: + return jsonify(status=False, errors=[{"id": INVALID_CHARS, "msg": "Invalid characters in API path"}]), 400 + + branch = request.args.get("branch", "master") + if VALID_API_STRING.match(branch) is None: + return jsonify(status=False, errors=[{"id": INVALID_CHARS, "msg": "Invalid characters in branch argument"}]), 400 + + try: + with api.config["GITLOCK"].lock: + workspace_delete(api.config["GITLOCK"].repo, branch, blueprint_name) + delete_recipe(api.config["GITLOCK"].repo, branch, blueprint_name) + except Exception as e: + log.error("(v0_blueprints_delete) %s", str(e)) + return jsonify(status=False, errors=[{"id": BLUEPRINTS_ERROR, "msg": str(e)}]), 400 + else: + return jsonify(status=True) + + @api.route("/api/v0/blueprints/workspace", methods=["POST"]) + @crossdomain(origin="*") + def v0_blueprints_workspace(): + """Write a blueprint to the workspace""" + branch = request.args.get("branch", "master") + if VALID_API_STRING.match(branch) is None: + return jsonify(status=False, errors=[{"id": INVALID_CHARS, "msg": "Invalid characters in branch argument"}]), 400 + + try: + if request.headers['Content-Type'] == "text/x-toml": + blueprint = recipe_from_toml(request.data) + else: + blueprint = recipe_from_dict(request.get_json(cache=False)) + + if VALID_API_STRING.match(blueprint["name"]) is None: + return jsonify(status=False, errors=[{"id": INVALID_CHARS, "msg": "Invalid characters in API path"}]), 400 + + with api.config["GITLOCK"].lock: + workspace_write(api.config["GITLOCK"].repo, branch, blueprint) + except Exception as e: + log.error("(v0_blueprints_workspace) %s", str(e)) + return jsonify(status=False, errors=[{"id": BLUEPRINTS_ERROR, "msg": str(e)}]), 400 + else: + return jsonify(status=True) + + @api.route("/api/v0/blueprints/workspace", defaults={'blueprint_name': ""}, methods=["DELETE"]) + @api.route("/api/v0/blueprints/workspace/<blueprint_name>", methods=["DELETE"]) + @crossdomain(origin="*") + @checkparams([("blueprint_name", "", "no blueprint name given")]) + def v0_blueprints_delete_workspace(blueprint_name): + """Delete a blueprint from the workspace""" + if VALID_API_STRING.match(blueprint_name) is None: + return jsonify(status=False, errors=[{"id": INVALID_CHARS, "msg": "Invalid characters in API path"}]), 400 + + branch = request.args.get("branch", "master") + if VALID_API_STRING.match(branch) is None: + return jsonify(status=False, errors=[{"id": INVALID_CHARS, "msg": "Invalid characters in branch argument"}]), 400 + + try: + with api.config["GITLOCK"].lock: + workspace_delete(api.config["GITLOCK"].repo, branch, blueprint_name) + except Exception as e: + log.error("(v0_blueprints_delete_workspace) %s", str(e)) + return jsonify(status=False, errors=[{"id": BLUEPRINTS_ERROR, "msg": str(e)}]), 400 + else: + return jsonify(status=True) + + @api.route("/api/v0/blueprints/undo", defaults={'blueprint_name': "", 'commit': ""}, methods=["POST"]) + @api.route("/api/v0/blueprints/undo/<blueprint_name>", defaults={'commit': ""}, methods=["POST"]) + @api.route("/api/v0/blueprints/undo/<blueprint_name>/<commit>", methods=["POST"]) + @crossdomain(origin="*") + @checkparams([("blueprint_name", "", "no blueprint name given"), + ("commit", "", "no commit ID given")]) + def v0_blueprints_undo(blueprint_name, commit): + """Undo changes to a blueprint by reverting to a previous commit.""" + if VALID_API_STRING.match(blueprint_name) is None: + return jsonify(status=False, errors=[{"id": INVALID_CHARS, "msg": "Invalid characters in API path"}]), 400 + + branch = request.args.get("branch", "master") + if VALID_API_STRING.match(branch) is None: + return jsonify(status=False, errors=[{"id": INVALID_CHARS, "msg": "Invalid characters in branch argument"}]), 400 + + try: + with api.config["GITLOCK"].lock: + revert_recipe(api.config["GITLOCK"].repo, branch, blueprint_name, commit) + + # Read the new recipe and write it to the workspace + blueprint = read_recipe_commit(api.config["GITLOCK"].repo, branch, blueprint_name) + workspace_write(api.config["GITLOCK"].repo, branch, blueprint) + except Exception as e: + log.error("(v0_blueprints_undo) %s", str(e)) + return jsonify(status=False, errors=[{"id": UNKNOWN_COMMIT, "msg": str(e)}]), 400 + else: + return jsonify(status=True) + + @api.route("/api/v0/blueprints/tag", defaults={'blueprint_name': ""}, methods=["POST"]) + @api.route("/api/v0/blueprints/tag/<blueprint_name>", methods=["POST"]) + @crossdomain(origin="*") + @checkparams([("blueprint_name", "", "no blueprint name given")]) + def v0_blueprints_tag(blueprint_name): + """Tag a blueprint's latest blueprint commit as a 'revision'""" + if VALID_API_STRING.match(blueprint_name) is None: + return jsonify(status=False, errors=[{"id": INVALID_CHARS, "msg": "Invalid characters in API path"}]), 400 + + branch = request.args.get("branch", "master") + if VALID_API_STRING.match(branch) is None: + return jsonify(status=False, errors=[{"id": INVALID_CHARS, "msg": "Invalid characters in branch argument"}]), 400 + + try: + with api.config["GITLOCK"].lock: + tag_recipe_commit(api.config["GITLOCK"].repo, branch, blueprint_name) + except RecipeFileError as e: + log.error("(v0_blueprints_tag) %s", str(e)) + return jsonify(status=False, errors=[{"id": UNKNOWN_BLUEPRINT, "msg": str(e)}]), 400 + except Exception as e: + log.error("(v0_blueprints_tag) %s", str(e)) + return jsonify(status=False, errors=[{"id": BLUEPRINTS_ERROR, "msg": str(e)}]), 400 + else: + return jsonify(status=True) + + @api.route("/api/v0/blueprints/diff", defaults={'blueprint_name': "", 'from_commit': "", 'to_commit': ""}) + @api.route("/api/v0/blueprints/diff/<blueprint_name>", defaults={'from_commit': "", 'to_commit': ""}) + @api.route("/api/v0/blueprints/diff/<blueprint_name>/<from_commit>", defaults={'to_commit': ""}) + @api.route("/api/v0/blueprints/diff/<blueprint_name>/<from_commit>/<to_commit>") + @crossdomain(origin="*") + @checkparams([("blueprint_name", "", "no blueprint name given"), + ("from_commit", "", "no from commit ID given"), + ("to_commit", "", "no to commit ID given")]) + def v0_blueprints_diff(blueprint_name, from_commit, to_commit): + """Return the differences between two commits of a blueprint""" + for s in [blueprint_name, from_commit, to_commit]: + if VALID_API_STRING.match(s) is None: + return jsonify(status=False, errors=[{"id": INVALID_CHARS, "msg": "Invalid characters in API path"}]), 400 + + branch = request.args.get("branch", "master") + if VALID_API_STRING.match(branch) is None: + return jsonify(status=False, errors=[{"id": INVALID_CHARS, "msg": "Invalid characters in branch argument"}]), 400 + + if not blueprint_exists(api, branch, blueprint_name): + return jsonify(status=False, errors=[{"id": UNKNOWN_BLUEPRINT, "msg": "Unknown blueprint name: %s" % blueprint_name}]) + + try: + if from_commit == "NEWEST": + with api.config["GITLOCK"].lock: + old_blueprint = read_recipe_commit(api.config["GITLOCK"].repo, branch, blueprint_name) + else: + with api.config["GITLOCK"].lock: + old_blueprint = read_recipe_commit(api.config["GITLOCK"].repo, branch, blueprint_name, from_commit) + except Exception as e: + log.error("(v0_blueprints_diff) %s", str(e)) + return jsonify(status=False, errors=[{"id": UNKNOWN_COMMIT, "msg": str(e)}]), 400 + + try: + if to_commit == "WORKSPACE": + with api.config["GITLOCK"].lock: + new_blueprint = workspace_read(api.config["GITLOCK"].repo, branch, blueprint_name) + # If there is no workspace, use the newest commit instead + if not new_blueprint: + with api.config["GITLOCK"].lock: + new_blueprint = read_recipe_commit(api.config["GITLOCK"].repo, branch, blueprint_name) + elif to_commit == "NEWEST": + with api.config["GITLOCK"].lock: + new_blueprint = read_recipe_commit(api.config["GITLOCK"].repo, branch, blueprint_name) + else: + with api.config["GITLOCK"].lock: + new_blueprint = read_recipe_commit(api.config["GITLOCK"].repo, branch, blueprint_name, to_commit) + except Exception as e: + log.error("(v0_blueprints_diff) %s", str(e)) + return jsonify(status=False, errors=[{"id": UNKNOWN_COMMIT, "msg": str(e)}]), 400 + + diff = recipe_diff(old_blueprint, new_blueprint) + return jsonify(diff=diff) + + @api.route("/api/v0/blueprints/freeze", defaults={'blueprint_names': ""}) + @api.route("/api/v0/blueprints/freeze/<blueprint_names>") + @crossdomain(origin="*") + @checkparams([("blueprint_names", "", "no blueprint names given")]) + def v0_blueprints_freeze(blueprint_names): + """Return the blueprint with the exact modules and packages selected by depsolve""" + if VALID_API_STRING.match(blueprint_names) is None: + return jsonify(status=False, errors=[{"id": INVALID_CHARS, "msg": "Invalid characters in API path"}]), 400 + + branch = request.args.get("branch", "master") + if VALID_API_STRING.match(branch) is None: + return jsonify(status=False, errors=[{"id": INVALID_CHARS, "msg": "Invalid characters in branch argument"}]), 400 + + out_fmt = request.args.get("format", "json") + if VALID_API_STRING.match(out_fmt) is None: + return jsonify(status=False, errors=[{"id": INVALID_CHARS, "msg": "Invalid characters in format argument"}]), 400 + + blueprints = [] + errors = [] + for blueprint_name in [n.strip() for n in sorted(blueprint_names.split(","), key=lambda n: n.lower())]: + # get the blueprint + # Get the workspace version (if it exists) + blueprint = None + try: + with api.config["GITLOCK"].lock: + blueprint = workspace_read(api.config["GITLOCK"].repo, branch, blueprint_name) + except Exception: + pass + + if not blueprint: + # No workspace version, get the git version (if it exists) + try: + with api.config["GITLOCK"].lock: + blueprint = read_recipe_commit(api.config["GITLOCK"].repo, branch, blueprint_name) + except RecipeFileError as e: + # adding an error here would be redundant, skip it + log.error("(v0_blueprints_freeze) %s", str(e)) + except Exception as e: + errors.append({"id": BLUEPRINTS_ERROR, "msg": "%s: %s" % (blueprint_name, str(e))}) + log.error("(v0_blueprints_freeze) %s", str(e)) + + # No blueprint found, skip it. + if not blueprint: + errors.append({"id": UNKNOWN_BLUEPRINT, "msg": "%s: blueprint_not_found" % blueprint_name}) + continue + + # Combine modules and packages and depsolve the list + # TODO include the version/glob in the depsolving + module_nver = blueprint.module_nver + package_nver = blueprint.package_nver + projects = sorted(set(module_nver+package_nver), key=lambda p: p[0].lower()) + deps = [] + try: + with api.config["DNFLOCK"].lock: + deps = projects_depsolve(api.config["DNFLOCK"].dbo, projects, blueprint.group_names) + except ProjectsError as e: + errors.append({"id": BLUEPRINTS_ERROR, "msg": "%s: %s" % (blueprint_name, str(e))}) + log.error("(v0_blueprints_freeze) %s", str(e)) + + blueprints.append({"blueprint": blueprint.freeze(deps)}) + + if out_fmt == "toml": + # With TOML output we just want to dump the raw blueprint, skipping the rest. + return "\n\n".join([e["blueprint"].toml() for e in blueprints]) + else: + return jsonify(blueprints=blueprints, errors=errors) + + @api.route("/api/v0/blueprints/depsolve", defaults={'blueprint_names': ""}) + @api.route("/api/v0/blueprints/depsolve/<blueprint_names>") + @crossdomain(origin="*") + @checkparams([("blueprint_names", "", "no blueprint names given")]) + def v0_blueprints_depsolve(blueprint_names): + """Return the dependencies for a blueprint""" + if VALID_API_STRING.match(blueprint_names) is None: + return jsonify(status=False, errors=[{"id": INVALID_CHARS, "msg": "Invalid characters in API path"}]), 400 + + branch = request.args.get("branch", "master") + if VALID_API_STRING.match(branch) is None: + return jsonify(status=False, errors=[{"id": INVALID_CHARS, "msg": "Invalid characters in branch argument"}]), 400 + + blueprints = [] + errors = [] + for blueprint_name in [n.strip() for n in sorted(blueprint_names.split(","), key=lambda n: n.lower())]: + # get the blueprint + # Get the workspace version (if it exists) + blueprint = None + try: + with api.config["GITLOCK"].lock: + blueprint = workspace_read(api.config["GITLOCK"].repo, branch, blueprint_name) + except Exception: + pass + + if not blueprint: + # No workspace version, get the git version (if it exists) + try: + with api.config["GITLOCK"].lock: + blueprint = read_recipe_commit(api.config["GITLOCK"].repo, branch, blueprint_name) + except RecipeFileError as e: + # adding an error here would be redundant, skip it + log.error("(v0_blueprints_depsolve) %s", str(e)) + except Exception as e: + errors.append({"id": BLUEPRINTS_ERROR, "msg": "%s: %s" % (blueprint_name, str(e))}) + log.error("(v0_blueprints_depsolve) %s", str(e)) + + # No blueprint found, skip it. + if not blueprint: + errors.append({"id": UNKNOWN_BLUEPRINT, "msg": "%s: blueprint not found" % blueprint_name}) + continue + + # Combine modules and packages and depsolve the list + # TODO include the version/glob in the depsolving + module_nver = blueprint.module_nver + package_nver = blueprint.package_nver + projects = sorted(set(module_nver+package_nver), key=lambda p: p[0].lower()) + deps = [] + try: + with api.config["DNFLOCK"].lock: + deps = projects_depsolve(api.config["DNFLOCK"].dbo, projects, blueprint.group_names) + except ProjectsError as e: + errors.append({"id": BLUEPRINTS_ERROR, "msg": "%s: %s" % (blueprint_name, str(e))}) + log.error("(v0_blueprints_depsolve) %s", str(e)) + + # Get the NEVRA's of the modules and projects, add as "modules" + modules = [] + for dep in deps: + if dep["name"] in projects: + modules.append(dep) + modules = sorted(modules, key=lambda m: m["name"].lower()) + + blueprints.append({"blueprint":blueprint, "dependencies":deps, "modules":modules}) + + return jsonify(blueprints=blueprints, errors=errors) + + @api.route("/api/v0/projects/list") + @crossdomain(origin="*") + def v0_projects_list(): + """List all of the available projects/packages""" + try: + limit = int(request.args.get("limit", "20")) + offset = int(request.args.get("offset", "0")) + except ValueError as e: + return jsonify(status=False, errors=[{"id": BAD_LIMIT_OR_OFFSET, "msg": str(e)}]), 400 + + try: + with api.config["DNFLOCK"].lock: + available = projects_list(api.config["DNFLOCK"].dbo) + except ProjectsError as e: + log.error("(v0_projects_list) %s", str(e)) + return jsonify(status=False, errors=[{"id": PROJECTS_ERROR, "msg": str(e)}]), 400 + + projects = take_limits(available, offset, limit) + return jsonify(projects=projects, offset=offset, limit=limit, total=len(available)) + + @api.route("/api/v0/projects/info", defaults={'project_names': ""}) + @api.route("/api/v0/projects/info/<project_names>") + @crossdomain(origin="*") + @checkparams([("project_names", "", "no project names given")]) + def v0_projects_info(project_names): + """Return detailed information about the listed projects""" + if VALID_API_STRING.match(project_names) is None: + return jsonify(status=False, errors=[{"id": INVALID_CHARS, "msg": "Invalid characters in API path"}]), 400 + + try: + with api.config["DNFLOCK"].lock: + projects = projects_info(api.config["DNFLOCK"].dbo, project_names.split(",")) + except ProjectsError as e: + log.error("(v0_projects_info) %s", str(e)) + return jsonify(status=False, errors=[{"id": PROJECTS_ERROR, "msg": str(e)}]), 400 + + if not projects: + msg = "one of the requested projects does not exist: %s" % project_names + log.error("(v0_projects_info) %s", msg) + return jsonify(status=False, errors=[{"id": UNKNOWN_PROJECT, "msg": msg}]), 400 + + return jsonify(projects=projects) + + @api.route("/api/v0/projects/depsolve", defaults={'project_names': ""}) + @api.route("/api/v0/projects/depsolve/<project_names>") + @crossdomain(origin="*") + @checkparams([("project_names", "", "no project names given")]) + def v0_projects_depsolve(project_names): + """Return detailed information about the listed projects""" + if VALID_API_STRING.match(project_names) is None: + return jsonify(status=False, errors=[{"id": INVALID_CHARS, "msg": "Invalid characters in API path"}]), 400 + + try: + with api.config["DNFLOCK"].lock: + deps = projects_depsolve(api.config["DNFLOCK"].dbo, [(n, "*") for n in project_names.split(",")], []) + except ProjectsError as e: + log.error("(v0_projects_depsolve) %s", str(e)) + return jsonify(status=False, errors=[{"id": PROJECTS_ERROR, "msg": str(e)}]), 400 + + if not deps: + msg = "one of the requested projects does not exist: %s" % project_names + log.error("(v0_projects_depsolve) %s", msg) + return jsonify(status=False, errors=[{"id": UNKNOWN_PROJECT, "msg": msg}]), 400 + + return jsonify(projects=deps) + + @api.route("/api/v0/projects/source/list") + @crossdomain(origin="*") + def v0_projects_source_list(): + """Return the list of source names""" + with api.config["DNFLOCK"].lock: + repos = list(api.config["DNFLOCK"].dbo.repos.iter_enabled()) + sources = sorted([r.id for r in repos]) + return jsonify(sources=sources) + + @api.route("/api/v0/projects/source/info", defaults={'source_names': ""}) + @api.route("/api/v0/projects/source/info/<source_names>") + @crossdomain(origin="*") + @checkparams([("source_names", "", "no source names given")]) + def v0_projects_source_info(source_names): + """Return detailed info about the list of sources""" + if VALID_API_STRING.match(source_names) is None: + return jsonify(status=False, errors=[{"id": INVALID_CHARS, "msg": "Invalid characters in API path"}]), 400 + + out_fmt = request.args.get("format", "json") + if VALID_API_STRING.match(out_fmt) is None: + return jsonify(status=False, errors=[{"id": INVALID_CHARS, "msg": "Invalid characters in format argument"}]), 400 + + # Return info on all of the sources + if source_names == "*": + with api.config["DNFLOCK"].lock: + source_names = ",".join(r.id for r in api.config["DNFLOCK"].dbo.repos.iter_enabled()) + + sources = {} + errors = [] + system_sources = get_repo_sources("/etc/yum.repos.d/*.repo") + for source in source_names.split(","): + with api.config["DNFLOCK"].lock: + repo = api.config["DNFLOCK"].dbo.repos.get(source, None) + if not repo: + errors.append({"id": UNKNOWN_SOURCE, "msg": "%s is not a valid source" % source}) + continue + sources[repo.id] = repo_to_source(repo, repo.id in system_sources) + + if out_fmt == "toml" and not errors: + # With TOML output we just want to dump the raw sources, skipping the errors + return toml.dumps(sources) + elif out_fmt == "toml" and errors: + # TOML requested, but there was an error + return jsonify(status=False, errors=errors), 400 + else: + return jsonify(sources=sources, errors=errors) + + @api.route("/api/v0/projects/source/new", methods=["POST"]) + @crossdomain(origin="*") + def v0_projects_source_new(): + """Add a new package source. Or change an existing one""" + if request.headers['Content-Type'] == "text/x-toml": + source = toml.loads(request.data) + else: + source = request.get_json(cache=False) + + system_sources = get_repo_sources("/etc/yum.repos.d/*.repo") + if source["name"] in system_sources: + return jsonify(status=False, errors=[{"id": SYSTEM_SOURCE, "msg": "%s is a system source, it cannot be changed." % source["name"]}]), 400 + + try: + # Remove it from the RepoDict (NOTE that this isn't explicitly supported by the DNF API) + with api.config["DNFLOCK"].lock: + dbo = api.config["DNFLOCK"].dbo + # If this repo already exists, delete it and replace it with the new one + repos = list(r.id for r in dbo.repos.iter_enabled()) + if source["name"] in repos: + del dbo.repos[source["name"]] + + repo = source_to_repo(source, dbo.conf) + dbo.repos.add(repo) + + log.info("Updating repository metadata after adding %s", source["name"]) + dbo.fill_sack(load_system_repo=False) + dbo.read_comps() + + # Write the new repo to disk, replacing any existing ones + repo_dir = api.config["COMPOSER_CFG"].get("composer", "repo_dir") + + # Remove any previous sources with this name, ignore it if it isn't found + try: + delete_repo_source(joinpaths(repo_dir, "*.repo"), source["name"]) + except ProjectsError: + pass + + # Make sure the source name can't contain a path traversal by taking the basename + source_path = joinpaths(repo_dir, os.path.basename("%s.repo" % source["name"])) + with open(source_path, "w") as f: + f.write(dnf_repo_to_file_repo(repo)) + except Exception as e: + log.error("(v0_projects_source_add) adding %s failed: %s", source["name"], str(e)) + + # Cleanup the mess, if loading it failed we don't want to leave it in memory + repos = list(r.id for r in dbo.repos.iter_enabled()) + if source["name"] in repos: + with api.config["DNFLOCK"].lock: + dbo = api.config["DNFLOCK"].dbo + del dbo.repos[source["name"]] + + log.info("Updating repository metadata after adding %s failed", source["name"]) + dbo.fill_sack(load_system_repo=False) + dbo.read_comps() + + return jsonify(status=False, errors=[{"id": PROJECTS_ERROR, "msg": str(e)}]), 400 + + return jsonify(status=True) + + @api.route("/api/v0/projects/source/delete", defaults={'source_name': ""}, methods=["DELETE"]) + @api.route("/api/v0/projects/source/delete/<source_name>", methods=["DELETE"]) + @crossdomain(origin="*") + @checkparams([("source_name", "", "no source name given")]) + def v0_projects_source_delete(source_name): + """Delete the named source and return a status response""" + if VALID_API_STRING.match(source_name) is None: + return jsonify(status=False, errors=[{"id": INVALID_CHARS, "msg": "Invalid characters in API path"}]), 400 + + system_sources = get_repo_sources("/etc/yum.repos.d/*.repo") + if source_name in system_sources: + return jsonify(status=False, errors=[{"id": SYSTEM_SOURCE, "msg": "%s is a system source, it cannot be deleted." % source_name}]), 400 + share_dir = api.config["COMPOSER_CFG"].get("composer", "repo_dir") + try: + # Remove the file entry for the source + delete_repo_source(joinpaths(share_dir, "*.repo"), source_name) + + # Remove it from the RepoDict (NOTE that this isn't explicitly supported by the DNF API) + with api.config["DNFLOCK"].lock: + if source_name in api.config["DNFLOCK"].dbo.repos: + del api.config["DNFLOCK"].dbo.repos[source_name] + log.info("Updating repository metadata after removing %s", source_name) + api.config["DNFLOCK"].dbo.fill_sack(load_system_repo=False) + api.config["DNFLOCK"].dbo.read_comps() + + except ProjectsError as e: + log.error("(v0_projects_source_delete) %s", str(e)) + return jsonify(status=False, errors=[{"id": UNKNOWN_SOURCE, "msg": str(e)}]), 400 + + return jsonify(status=True) + + @api.route("/api/v0/modules/list") + @api.route("/api/v0/modules/list/<module_names>") + @crossdomain(origin="*") + def v0_modules_list(module_names=None): + """List available modules, filtering by module_names""" + if module_names and VALID_API_STRING.match(module_names) is None: + return jsonify(status=False, errors=[{"id": INVALID_CHARS, "msg": "Invalid characters in API path"}]), 400 + + try: + limit = int(request.args.get("limit", "20")) + offset = int(request.args.get("offset", "0")) + except ValueError as e: + return jsonify(status=False, errors=[{"id": BAD_LIMIT_OR_OFFSET, "msg": str(e)}]), 400 + + if module_names: + module_names = module_names.split(",") + + try: + with api.config["DNFLOCK"].lock: + available = modules_list(api.config["DNFLOCK"].dbo, module_names) + except ProjectsError as e: + log.error("(v0_modules_list) %s", str(e)) + return jsonify(status=False, errors=[{"id": MODULES_ERROR, "msg": str(e)}]), 400 + + if module_names and not available: + msg = "one of the requested modules does not exist: %s" % module_names + log.error("(v0_modules_list) %s", msg) + return jsonify(status=False, errors=[{"id": UNKNOWN_MODULE, "msg": msg}]), 400 + + modules = take_limits(available, offset, limit) + return jsonify(modules=modules, offset=offset, limit=limit, total=len(available)) + + @api.route("/api/v0/modules/info", defaults={'module_names': ""}) + @api.route("/api/v0/modules/info/<module_names>") + @crossdomain(origin="*") + @checkparams([("module_names", "", "no module names given")]) + def v0_modules_info(module_names): + """Return detailed information about the listed modules""" + if VALID_API_STRING.match(module_names) is None: + return jsonify(status=False, errors=[{"id": INVALID_CHARS, "msg": "Invalid characters in API path"}]), 400 + try: + with api.config["DNFLOCK"].lock: + modules = modules_info(api.config["DNFLOCK"].dbo, module_names.split(",")) + except ProjectsError as e: + log.error("(v0_modules_info) %s", str(e)) + return jsonify(status=False, errors=[{"id": MODULES_ERROR, "msg": str(e)}]), 400 + + if not modules: + msg = "one of the requested modules does not exist: %s" % module_names + log.error("(v0_modules_info) %s", msg) + return jsonify(status=False, errors=[{"id": UNKNOWN_MODULE, "msg": msg}]), 400 + + return jsonify(modules=modules) + + @api.route("/api/v0/compose", methods=["POST"]) + @crossdomain(origin="*") + def v0_compose_start(): + """Start a compose + + The body of the post should have these fields: + blueprint_name - The blueprint name from /blueprints/list/ + compose_type - The type of output to create, from /compose/types + branch - Optional, defaults to master, selects the git branch to use for the blueprint. + """ + # Passing ?test=1 will generate a fake FAILED compose. + # Passing ?test=2 will generate a fake FINISHED compose. + try: + test_mode = int(request.args.get("test", "0")) + except ValueError: + test_mode = 0 + + compose = request.get_json(cache=False) + + errors = [] + if not compose: + return jsonify(status=False, errors=[{"id": MISSING_POST, "msg": "Missing POST body"}]), 400 + + if "blueprint_name" not in compose: + errors.append({"id": UNKNOWN_BLUEPRINT,"msg": "No 'blueprint_name' in the JSON request"}) + else: + blueprint_name = compose["blueprint_name"] + + if "branch" not in compose or not compose["branch"]: + branch = "master" + else: + branch = compose["branch"] + + if "compose_type" not in compose: + errors.append({"id": BAD_COMPOSE_TYPE, "msg": "No 'compose_type' in the JSON request"}) + else: + compose_type = compose["compose_type"] + + if VALID_API_STRING.match(blueprint_name) is None: + errors.append({"id": INVALID_CHARS, "msg": "Invalid characters in API path"}) + + if not blueprint_exists(api, branch, blueprint_name): + errors.append({"id": UNKNOWN_BLUEPRINT, "msg": "Unknown blueprint name: %s" % blueprint_name}) + + if errors: + return jsonify(status=False, errors=errors), 400 + + try: + build_id = start_build(api.config["COMPOSER_CFG"], api.config["DNFLOCK"], api.config["GITLOCK"], + branch, blueprint_name, compose_type, test_mode) + except Exception as e: + if "Invalid compose type" in str(e): + return jsonify(status=False, errors=[{"id": BAD_COMPOSE_TYPE, "msg": str(e)}]), 400 + else: + return jsonify(status=False, errors=[{"id": BUILD_FAILED, "msg": str(e)}]), 400 + + return jsonify(status=True, build_id=build_id) + + @api.route("/api/v0/compose/types") + @crossdomain(origin="*") + def v0_compose_types(): + """Return the list of output types and their enabled/disabled state""" + share_dir = api.config["COMPOSER_CFG"].get("composer", "share_dir") + return jsonify(types=[{"name": t, "enabled": e} for t, e in compose_types(share_dir)]) + + @api.route("/api/v0/compose/queue") + @crossdomain(origin="*") + def v0_compose_queue(): + """Return the status of the new and running queues""" + return jsonify(queue_status(api.config["COMPOSER_CFG"])) + + @api.route("/api/v0/compose/finished") + @crossdomain(origin="*") + def v0_compose_finished(): + """Return the list of finished composes""" + return jsonify(finished=build_status(api.config["COMPOSER_CFG"], "FINISHED")) + + @api.route("/api/v0/compose/failed") + @crossdomain(origin="*") + def v0_compose_failed(): + """Return the list of failed composes""" + return jsonify(failed=build_status(api.config["COMPOSER_CFG"], "FAILED")) + + @api.route("/api/v0/compose/status", defaults={'uuids': ""}) + @api.route("/api/v0/compose/status/<uuids>") + @crossdomain(origin="*") + @checkparams([("uuids", "", "no UUIDs given")]) + def v0_compose_status(uuids): + """Return the status of the listed uuids""" + if VALID_API_STRING.match(uuids) is None: + return jsonify(status=False, errors=[{"id": INVALID_CHARS, "msg": "Invalid characters in API path"}]), 400 + + blueprint = request.args.get("blueprint", None) + status = request.args.get("status", None) + compose_type = request.args.get("type", None) + + results = [] + errors = [] + + if uuids.strip() == '*': + queue_status_dict = queue_status(api.config["COMPOSER_CFG"]) + queue_new = queue_status_dict["new"] + queue_running = queue_status_dict["run"] + candidates = queue_new + queue_running + build_status(api.config["COMPOSER_CFG"]) + else: + candidates = [] + for uuid in [n.strip().lower() for n in uuids.split(",")]: + details = uuid_status(api.config["COMPOSER_CFG"], uuid) + if details is None: + errors.append({"id": UNKNOWN_UUID, "msg": "%s is not a valid build uuid" % uuid}) + else: + candidates.append(details) + + for details in candidates: + if blueprint is not None and details['blueprint'] != blueprint: + continue + + if status is not None and details['queue_status'] != status: + continue + + if compose_type is not None and details['compose_type'] != compose_type: + continue + + results.append(details) + + return jsonify(uuids=results, errors=errors) + + @api.route("/api/v0/compose/cancel", defaults={'uuid': ""}, methods=["DELETE"]) + @api.route("/api/v0/compose/cancel/<uuid>", methods=["DELETE"]) + @crossdomain(origin="*") + @checkparams([("uuid", "", "no UUID given")]) + def v0_compose_cancel(uuid): + """Cancel a running compose and delete its results directory""" + if VALID_API_STRING.match(uuid) is None: + return jsonify(status=False, errors=[{"id": INVALID_CHARS, "msg": "Invalid characters in API path"}]), 400 + + status = uuid_status(api.config["COMPOSER_CFG"], uuid) + if status is None: + return jsonify(status=False, errors=[{"id": UNKNOWN_UUID, "msg": "%s is not a valid build uuid" % uuid}]), 400 + + if status["queue_status"] not in ["WAITING", "RUNNING"]: + return jsonify(status=False, errors=[{"id": BUILD_IN_WRONG_STATE, "msg": "Build %s is not in WAITING or RUNNING." % uuid}]) + + try: + uuid_cancel(api.config["COMPOSER_CFG"], uuid) + except Exception as e: + return jsonify(status=False, errors=[{"id": COMPOSE_ERROR, "msg": "%s: %s" % (uuid, str(e))}]),400 + else: + return jsonify(status=True, uuid=uuid) + + @api.route("/api/v0/compose/delete", defaults={'uuids': ""}, methods=["DELETE"]) + @api.route("/api/v0/compose/delete/<uuids>", methods=["DELETE"]) + @crossdomain(origin="*") + @checkparams([("uuids", "", "no UUIDs given")]) + def v0_compose_delete(uuids): + """Delete the compose results for the listed uuids""" + if VALID_API_STRING.match(uuids) is None: + return jsonify(status=False, errors=[{"id": INVALID_CHARS, "msg": "Invalid characters in API path"}]), 400 + + results = [] + errors = [] + for uuid in [n.strip().lower() for n in uuids.split(",")]: + status = uuid_status(api.config["COMPOSER_CFG"], uuid) + if status is None: + errors.append({"id": UNKNOWN_UUID, "msg": "%s is not a valid build uuid" % uuid}) + elif status["queue_status"] not in ["FINISHED", "FAILED"]: + errors.append({"id": BUILD_IN_WRONG_STATE, "msg": "Build %s is not in FINISHED or FAILED." % uuid}) + else: + try: + uuid_delete(api.config["COMPOSER_CFG"], uuid) + except Exception as e: + errors.append({"id": COMPOSE_ERROR, "msg": "%s: %s" % (uuid, str(e))}) + else: + results.append({"uuid":uuid, "status":True}) + return jsonify(uuids=results, errors=errors) + + @api.route("/api/v0/compose/info", defaults={'uuid': ""}) + @api.route("/api/v0/compose/info/<uuid>") + @crossdomain(origin="*") + @checkparams([("uuid", "", "no UUID given")]) + def v0_compose_info(uuid): + """Return detailed info about a compose""" + if VALID_API_STRING.match(uuid) is None: + return jsonify(status=False, errors=[{"id": INVALID_CHARS, "msg": "Invalid characters in API path"}]), 400 + + try: + info = uuid_info(api.config["COMPOSER_CFG"], uuid) + except Exception as e: + return jsonify(status=False, errors=[{"id": COMPOSE_ERROR, "msg": str(e)}]), 400 + + if info is None: + return jsonify(status=False, errors=[{"id": UNKNOWN_UUID, "msg": "%s is not a valid build uuid" % uuid}]), 400 + else: + return jsonify(**info) + + @api.route("/api/v0/compose/metadata", defaults={'uuid': ""}) + @api.route("/api/v0/compose/metadata/<uuid>") + @crossdomain(origin="*") + @checkparams([("uuid","", "no UUID given")]) + def v0_compose_metadata(uuid): + """Return a tar of the metadata for the build""" + if VALID_API_STRING.match(uuid) is None: + return jsonify(status=False, errors=[{"id": INVALID_CHARS, "msg": "Invalid characters in API path"}]), 400 + + status = uuid_status(api.config["COMPOSER_CFG"], uuid) + if status is None: + return jsonify(status=False, errors=[{"id": UNKNOWN_UUID, "msg": "%s is not a valid build uuid" % uuid}]), 400 + if status["queue_status"] not in ["FINISHED", "FAILED"]: + return jsonify(status=False, errors=[{"id": BUILD_IN_WRONG_STATE, "msg": "Build %s not in FINISHED or FAILED state." % uuid}]), 400 + else: + return Response(uuid_tar(api.config["COMPOSER_CFG"], uuid, metadata=True, image=False, logs=False), + mimetype="application/x-tar", + headers=[("Content-Disposition", "attachment; filename=%s-metadata.tar;" % uuid)], + direct_passthrough=True) + + @api.route("/api/v0/compose/results", defaults={'uuid': ""}) + @api.route("/api/v0/compose/results/<uuid>") + @crossdomain(origin="*") + @checkparams([("uuid","", "no UUID given")]) + def v0_compose_results(uuid): + """Return a tar of the metadata and the results for the build""" + if VALID_API_STRING.match(uuid) is None: + return jsonify(status=False, errors=[{"id": INVALID_CHARS, "msg": "Invalid characters in API path"}]), 400 + + status = uuid_status(api.config["COMPOSER_CFG"], uuid) + if status is None: + return jsonify(status=False, errors=[{"id": UNKNOWN_UUID, "msg": "%s is not a valid build uuid" % uuid}]), 400 + elif status["queue_status"] not in ["FINISHED", "FAILED"]: + return jsonify(status=False, errors=[{"id": BUILD_IN_WRONG_STATE, "msg": "Build %s not in FINISHED or FAILED state." % uuid}]), 400 + else: + return Response(uuid_tar(api.config["COMPOSER_CFG"], uuid, metadata=True, image=True, logs=True), + mimetype="application/x-tar", + headers=[("Content-Disposition", "attachment; filename=%s.tar;" % uuid)], + direct_passthrough=True) + + @api.route("/api/v0/compose/logs", defaults={'uuid': ""}) + @api.route("/api/v0/compose/logs/<uuid>") + @crossdomain(origin="*") + @checkparams([("uuid","", "no UUID given")]) + def v0_compose_logs(uuid): + """Return a tar of the metadata for the build""" + if VALID_API_STRING.match(uuid) is None: + return jsonify(status=False, errors=[{"id": INVALID_CHARS, "msg": "Invalid characters in API path"}]), 400 + + status = uuid_status(api.config["COMPOSER_CFG"], uuid) + if status is None: + return jsonify(status=False, errors=[{"id": UNKNOWN_UUID, "msg": "%s is not a valid build uuid" % uuid}]), 400 + elif status["queue_status"] not in ["FINISHED", "FAILED"]: + return jsonify(status=False, errors=[{"id": BUILD_IN_WRONG_STATE, "msg": "Build %s not in FINISHED or FAILED state." % uuid}]), 400 + else: + return Response(uuid_tar(api.config["COMPOSER_CFG"], uuid, metadata=False, image=False, logs=True), + mimetype="application/x-tar", + headers=[("Content-Disposition", "attachment; filename=%s-logs.tar;" % uuid)], + direct_passthrough=True) + + @api.route("/api/v0/compose/image", defaults={'uuid': ""}) + @api.route("/api/v0/compose/image/<uuid>") + @crossdomain(origin="*") + @checkparams([("uuid","", "no UUID given")]) + def v0_compose_image(uuid): + """Return the output image for the build""" + if VALID_API_STRING.match(uuid) is None: + return jsonify(status=False, errors=[{"id": INVALID_CHARS, "msg": "Invalid characters in API path"}]), 400 + + status = uuid_status(api.config["COMPOSER_CFG"], uuid) + if status is None: + return jsonify(status=False, errors=[{"id": UNKNOWN_UUID, "msg": "%s is not a valid build uuid" % uuid}]), 400 + elif status["queue_status"] not in ["FINISHED", "FAILED"]: + return jsonify(status=False, errors=[{"id": BUILD_IN_WRONG_STATE, "msg": "Build %s not in FINISHED or FAILED state." % uuid}]), 400 + else: + image_name, image_path = uuid_image(api.config["COMPOSER_CFG"], uuid) + + # Make sure it really exists + if not os.path.exists(image_path): + return jsonify(status=False, errors=[{"id": BUILD_MISSING_FILE, "msg": "Build %s is missing image file %s" % (uuid, image_name)}]), 400 + + # Make the image name unique + image_name = uuid + "-" + image_name + # XXX - Will mime type guessing work for all our output? + return send_file(image_path, as_attachment=True, attachment_filename=image_name, add_etags=False) + + @api.route("/api/v0/compose/log", defaults={'uuid': ""}) + @api.route("/api/v0/compose/log/<uuid>") + @crossdomain(origin="*") + @checkparams([("uuid","", "no UUID given")]) + def v0_compose_log_tail(uuid): + """Return the end of the main anaconda.log, defaults to 1Mbytes""" + if VALID_API_STRING.match(uuid) is None: + return jsonify(status=False, errors=[{"id": INVALID_CHARS, "msg": "Invalid characters in API path"}]), 400 + + try: + size = int(request.args.get("size", "1024")) + except ValueError as e: + return jsonify(status=False, errors=[{"id": COMPOSE_ERROR, "msg": str(e)}]), 400 + + status = uuid_status(api.config["COMPOSER_CFG"], uuid) + if status is None: + return jsonify(status=False, errors=[{"id": UNKNOWN_UUID, "msg": "%s is not a valid build uuid" % uuid}]), 400 + elif status["queue_status"] == "WAITING": + return jsonify(status=False, errors=[{"id": BUILD_IN_WRONG_STATE, "msg": "Build %s has not started yet. No logs to view" % uuid}]) + try: + return Response(uuid_log(api.config["COMPOSER_CFG"], uuid, size), direct_passthrough=True) + except RuntimeError as e: + return jsonify(status=False, errors=[{"id": COMPOSE_ERROR, "msg": str(e)}]), 400
    +
    + +
    + +
    +
    + + +
    + +
    +

    + © Copyright 2018-2019, Red Hat, Inc. + +

    +
    + Built with Sphinx using a theme provided by Read the Docs. + +
    + +
    +
    + +
    + +
    + + + + + + + + + + + + \ No newline at end of file diff --git a/rhel8-branch/_modules/pylorax/api/workspace.html b/rhel8-branch/_modules/pylorax/api/workspace.html new file mode 100644 index 00000000..360f266c --- /dev/null +++ b/rhel8-branch/_modules/pylorax/api/workspace.html @@ -0,0 +1,299 @@ + + + + + + + + + + + pylorax.api.workspace — Lorax 28.14.33 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + + + +
    + + + + + +
    + +
    + + + + + + + + + + + + + + + + + +
    + + + + +
    +
    +
    +
    + +

    Source code for pylorax.api.workspace

    +#
    +# Copyright (C) 2017  Red Hat, Inc.
    +#
    +# This program is free software; you can redistribute it and/or modify
    +# it under the terms of the GNU General Public License as published by
    +# the Free Software Foundation; either version 2 of the License, or
    +# (at your option) any later version.
    +#
    +# This program is distributed in the hope that it will be useful,
    +# but WITHOUT ANY WARRANTY; without even the implied warranty of
    +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    +# GNU General Public License for more details.
    +#
    +# You should have received a copy of the GNU General Public License
    +# along with this program.  If not, see <http://www.gnu.org/licenses/>.
    +#
    +import os
    +
    +from pylorax.api.recipes import recipe_filename, recipe_from_toml, RecipeFileError
    +from pylorax.sysutils import joinpaths
    +
    +
    +
    [docs]def workspace_dir(repo, branch): + """Create the workspace's path from a Repository and branch + + :param repo: Open repository + :type repo: Git.Repository + :param branch: Branch name + :type branch: str + :returns: The path to the branch's workspace directory + :rtype: str + + """ + repo_path = repo.get_location().get_path() + return joinpaths(repo_path, "workspace", branch)
    + + +
    [docs]def workspace_read(repo, branch, recipe_name): + """Read a Recipe from the branch's workspace + + :param repo: Open repository + :type repo: Git.Repository + :param branch: Branch name + :type branch: str + :param recipe_name: The name of the recipe + :type recipe_name: str + :returns: The workspace copy of the recipe, or None if it doesn't exist + :rtype: Recipe or None + :raises: RecipeFileError + """ + ws_dir = workspace_dir(repo, branch) + if not os.path.isdir(ws_dir): + os.makedirs(ws_dir) + filename = joinpaths(ws_dir, recipe_filename(recipe_name)) + if not os.path.exists(filename): + return None + try: + f = open(filename, 'rb') + recipe = recipe_from_toml(f.read().decode("UTF-8")) + except IOError: + raise RecipeFileError + return recipe
    + + +
    [docs]def workspace_write(repo, branch, recipe): + """Write a recipe to the workspace + + :param repo: Open repository + :type repo: Git.Repository + :param branch: Branch name + :type branch: str + :param recipe: The recipe to write to the workspace + :type recipe: Recipe + :returns: None + :raises: IO related errors + """ + ws_dir = workspace_dir(repo, branch) + if not os.path.isdir(ws_dir): + os.makedirs(ws_dir) + filename = joinpaths(ws_dir, recipe.filename) + open(filename, 'wb').write(recipe.toml().encode("UTF-8"))
    + + +
    [docs]def workspace_delete(repo, branch, recipe_name): + """Delete the recipe from the workspace + + :param repo: Open repository + :type repo: Git.Repository + :param branch: Branch name + :type branch: str + :param recipe_name: The name of the recipe + :type recipe_name: str + :returns: None + :raises: IO related errors + """ + ws_dir = workspace_dir(repo, branch) + filename = joinpaths(ws_dir, recipe_filename(recipe_name)) + if os.path.exists(filename): + os.unlink(filename)
    +
    + +
    + +
    +
    + + +
    + +
    +

    + © Copyright 2018-2019, Red Hat, Inc. + +

    +
    + Built with Sphinx using a theme provided by Read the Docs. + +
    + +
    +
    + +
    + +
    + + + + + + + + + + + + \ No newline at end of file diff --git a/rhel8-branch/_modules/pylorax/base.html b/rhel8-branch/_modules/pylorax/base.html new file mode 100644 index 00000000..6979e5e4 --- /dev/null +++ b/rhel8-branch/_modules/pylorax/base.html @@ -0,0 +1,267 @@ + + + + + + + + + + + pylorax.base — Lorax 28.14.33 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + + + +
    + + + + + +
    + +
    + + + + + + + + + + + + + + + + + +
    + + + + +
    +
    +
    +
    + +

    Source code for pylorax.base

    +#
    +# base.py
    +#
    +# Copyright (C) 2009-2015 Red Hat, Inc.
    +#
    +# This program is free software; you can redistribute it and/or modify
    +# it under the terms of the GNU General Public License as published by
    +# the Free Software Foundation; either version 2 of the License, or
    +# (at your option) any later version.
    +#
    +# This program is distributed in the hope that it will be useful,
    +# but WITHOUT ANY WARRANTY; without even the implied warranty of
    +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    +# GNU General Public License for more details.
    +#
    +# You should have received a copy of the GNU General Public License
    +# along with this program.  If not, see <http://www.gnu.org/licenses/>.
    +#
    +# Red Hat Author(s):  Martin Gracik <mgracik@redhat.com>
    +#
    +
    +from abc import ABCMeta, abstractmethod
    +import sys
    +
    +import pylorax.output as output
    +
    +
    +
    [docs]class BaseLoraxClass(object, metaclass=ABCMeta): + @abstractmethod + def __init__(self): + self.output = output.LoraxOutput() + +
    [docs] def pcritical(self, msg, fobj=sys.stdout): + self.output.critical(msg, fobj)
    + +
    [docs] def perror(self, msg, fobj=sys.stdout): + self.output.error(msg, fobj)
    + +
    [docs] def pwarning(self, msg, fobj=sys.stdout): + self.output.warning(msg, fobj)
    + +
    [docs] def pinfo(self, msg, fobj=sys.stdout): + self.output.info(msg, fobj)
    + +
    [docs] def pdebug(self, msg, fobj=sys.stdout): + self.output.debug(msg, fobj)
    + + +
    [docs]class DataHolder(dict): + + def __init__(self, **kwargs): + dict.__init__(self) + + for attr, value in kwargs.items(): + self[attr] = value + + def __getattr__(self, attr): + if attr in self: + return self[attr] + else: + raise AttributeError + + def __setattr__(self, attr, value): + self[attr] = value + +
    [docs] def copy(self): + return DataHolder(**dict.copy(self))
    +
    + +
    + +
    +
    + + +
    + +
    +

    + © Copyright 2018-2019, Red Hat, Inc. + +

    +
    + Built with Sphinx using a theme provided by Read the Docs. + +
    + +
    +
    + +
    + +
    + + + + + + + + + + + + \ No newline at end of file diff --git a/rhel8-branch/_modules/pylorax/buildstamp.html b/rhel8-branch/_modules/pylorax/buildstamp.html new file mode 100644 index 00000000..0f90dab4 --- /dev/null +++ b/rhel8-branch/_modules/pylorax/buildstamp.html @@ -0,0 +1,261 @@ + + + + + + + + + + + pylorax.buildstamp — Lorax 28.14.33 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + + + +
    + + + + + +
    + +
    + + + + + + + + + + + + + + + + + +
    + + + + +
    +
    +
    +
    + +

    Source code for pylorax.buildstamp

    +#
    +# buildstamp.py
    +#
    +# Copyright (C) 2010-2015 Red Hat, Inc.
    +#
    +# This program is free software; you can redistribute it and/or modify
    +# it under the terms of the GNU General Public License as published by
    +# the Free Software Foundation; either version 2 of the License, or
    +# (at your option) any later version.
    +#
    +# This program is distributed in the hope that it will be useful,
    +# but WITHOUT ANY WARRANTY; without even the implied warranty of
    +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    +# GNU General Public License for more details.
    +#
    +# You should have received a copy of the GNU General Public License
    +# along with this program.  If not, see <http://www.gnu.org/licenses/>.
    +#
    +# Red Hat Author(s):  Martin Gracik <mgracik@redhat.com>
    +#
    +
    +import logging
    +logger = logging.getLogger("pylorax.buildstamp")
    +
    +import datetime
    +
    +
    +
    [docs]class BuildStamp(object): + + def __init__(self, product, version, bugurl, isfinal, buildarch, variant=""): + self.product = product + self.version = version + self.bugurl = bugurl + self.isfinal = isfinal + self.variant = variant + + now = datetime.datetime.now() + now = now.strftime("%Y%m%d%H%M") + self.uuid = "{0}.{1}".format(now, buildarch) + +
    [docs] def write(self, outfile): + # get lorax version + try: + import pylorax.version + except ImportError: + vernum = "devel" + else: + vernum = pylorax.version.num + + logger.info("writing .buildstamp file") + with open(outfile, "w") as fobj: + fobj.write("[Main]\n") + fobj.write("Product={0.product}\n".format(self)) + fobj.write("Version={0.version}\n".format(self)) + fobj.write("BugURL={0.bugurl}\n".format(self)) + fobj.write("IsFinal={0.isfinal}\n".format(self)) + fobj.write("UUID={0.uuid}\n".format(self)) + if self.variant: + fobj.write("Variant={0.variant}\n".format(self)) + fobj.write("[Compose]\n") + fobj.write("Lorax={0}\n".format(vernum))
    +
    + +
    + +
    +
    + + +
    + +
    +

    + © Copyright 2018-2019, Red Hat, Inc. + +

    +
    + Built with Sphinx using a theme provided by Read the Docs. + +
    + +
    +
    + +
    + +
    + + + + + + + + + + + + \ No newline at end of file diff --git a/rhel8-branch/_modules/pylorax/cmdline.html b/rhel8-branch/_modules/pylorax/cmdline.html new file mode 100644 index 00000000..62043fa4 --- /dev/null +++ b/rhel8-branch/_modules/pylorax/cmdline.html @@ -0,0 +1,511 @@ + + + + + + + + + + + pylorax.cmdline — Lorax 28.14.33 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + + + +
    + + + + + +
    + +
    + + + + + + + + + + + + + + + + + +
    + + + + +
    +
    +
    +
    + +

    Source code for pylorax.cmdline

    +#
    +# cmdline.py
    +#
    +# Copyright (C) 2016  Red Hat, Inc.
    +#
    +# This program is free software; you can redistribute it and/or modify
    +# it under the terms of the GNU General Public License as published by
    +# the Free Software Foundation; either version 2 of the License, or
    +# (at your option) any later version.
    +#
    +# This program is distributed in the hope that it will be useful,
    +# but WITHOUT ANY WARRANTY; without even the implied warranty of
    +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    +# GNU General Public License for more details.
    +#
    +# You should have received a copy of the GNU General Public License
    +# along with this program.  If not, see <http://www.gnu.org/licenses/>.
    +#
    +# Red Hat Author(s):  Brian C. Lane <bcl@redhat.com>
    +
    +import os
    +import sys
    +import argparse
    +
    +from pylorax import vernum
    +
    +version = "{0}-{1}".format(os.path.basename(sys.argv[0]), vernum)
    +
    +
    [docs]def lorax_parser(dracut_default=""): + """ Return the ArgumentParser for lorax""" + + parser = argparse.ArgumentParser(description="Create the Anaconda boot.iso") + + # required arguments for image creation + required = parser.add_argument_group("required arguments") + required.add_argument("-p", "--product", help="product name", required=True, metavar="PRODUCT") + required.add_argument("-v", "--version", help="version identifier", required=True, metavar="VERSION") + required.add_argument("-r", "--release", help="release information", required=True, metavar="RELEASE") + required.add_argument("-s", "--source", help="source repository (may be listed multiple times)", + metavar="REPOSITORY", action="append", default=[]) + required.add_argument("--repo", help="source dnf repository file", type=os.path.abspath, + dest="repos", metavar="REPOSITORY", action="append", default=[]) + + # optional arguments + optional = parser.add_argument_group("optional arguments") + optional.add_argument("-m", "--mirrorlist", + help="mirrorlist repository (may be listed multiple times)", + metavar="REPOSITORY", action="append", default=[]) + optional.add_argument("-t", "--variant", default="", + help="variant name", metavar="VARIANT") + optional.add_argument("-b", "--bugurl", + help="bug reporting URL for the product", metavar="URL", + default="your distribution provided bug reporting tool") + optional.add_argument("--isfinal", help="", + action="store_true", default=False, dest="isfinal") + optional.add_argument("-c", "--config", default="/etc/lorax/lorax.conf", + help="config file", metavar="CONFIGFILE") + optional.add_argument("--proxy", default=None, + help="repo proxy url:port", metavar="HOST") + optional.add_argument("-i", "--installpkgs", default=[], + action="append", metavar="PACKAGE", + help="package glob to install before runtime-install.tmpl runs. (may be listed multiple times)") + optional.add_argument("-e", "--excludepkgs", default=[], + action="append", metavar="PACKAGE", + help="package glob to remove before runtime-install.tmpl runs. (may be listed multiple times)") + optional.add_argument("--buildarch", default=None, + help="build architecture", metavar="ARCH") + optional.add_argument("--volid", default=None, + help="volume id", metavar="VOLID") + optional.add_argument("--macboot", help="", + action="store_true", default=True, dest="domacboot") + optional.add_argument("--nomacboot", help="", + action="store_false", dest="domacboot") + optional.add_argument("--noupgrade", help="", + action="store_false", default=True, dest="doupgrade") + optional.add_argument("--logfile", default="./lorax.log", type=os.path.abspath, + help="Path to logfile") + optional.add_argument("--tmp", default="/var/tmp/lorax", + help="Top level temporary directory" ) + optional.add_argument("--cachedir", default=None, type=os.path.abspath, + help="DNF cache directory. Default is a temporary dir.") + optional.add_argument("--workdir", default=None, type=os.path.abspath, + help="Work directory, overrides --tmp. Default is a temporary dir under /var/tmp/lorax") + optional.add_argument("--force", default=False, action="store_true", + help="Run even when the destination directory exists") + optional.add_argument("--add-template", dest="add_templates", + action="append", help="Additional template for runtime image", + default=[]) + optional.add_argument("--add-template-var", dest="add_template_vars", + action="append", help="Set variable for runtime image template", + default=[]) + optional.add_argument("--add-arch-template", dest="add_arch_templates", + action="append", help="Additional template for architecture-specific image", + default=[]) + optional.add_argument("--add-arch-template-var", dest="add_arch_template_vars", + action="append", help="Set variable for architecture-specific image", + default=[]) + optional.add_argument("--noverify", action="store_false", default=True, dest="verify", + help="Do not verify the install root") + optional.add_argument("--sharedir", metavar="SHAREDIR", type=os.path.abspath, + help="Directory containing all the templates. Overrides config file sharedir") + optional.add_argument("--enablerepo", action="append", default=[], dest="enablerepos", + metavar="[repo]", help="Names of repos to enable") + optional.add_argument("--disablerepo", action="append", default=[], dest="disablerepos", + metavar="[repo]", help="Names of repos to disable") + optional.add_argument("--rootfs-size", type=int, default=3, + help="Size of root filesystem in GiB. Defaults to 3.") + optional.add_argument("--noverifyssl", action="store_true", default=False, + help="Do not verify SSL certificates") + + # dracut arguments + dracut_group = parser.add_argument_group("dracut arguments") + dracut_group.add_argument("--dracut-arg", action="append", dest="dracut_args", + help="Argument to pass to dracut when " + "rebuilding the initramfs. Pass this " + "once for each argument. NOTE: this " + "overrides the default. (default: %s)" % dracut_default) + + # add the show version option + parser.add_argument("-V", help="show program's version number and exit", + action="version", version=version) + + parser.add_argument("outputdir", help="Output directory", metavar="OUTPUTDIR", type=os.path.abspath) + + return parser
    + + +
    [docs]def lmc_parser(dracut_default=""): + """ Return a ArgumentParser object for live-media-creator.""" + parser = argparse.ArgumentParser(description="Create Live Install Media", + fromfile_prefix_chars="@") + + # These are mutually exclusive, one is required + action = parser.add_mutually_exclusive_group(required=True) + action.add_argument("--make-iso", action="store_true", + help="Build a live iso") + action.add_argument("--make-disk", action="store_true", + help="Build a partitioned disk image") + action.add_argument("--make-fsimage", action="store_true", + help="Build a filesystem image") + action.add_argument("--make-appliance", action="store_true", + help="Build an appliance image and XML description") + action.add_argument("--make-ami", action="store_true", + help="Build an ami image") + action.add_argument("--make-tar", action="store_true", + help="Build a tar of the root filesystem") + action.add_argument("--make-tar-disk", action="store_true", + help="Build a tar of a partitioned disk image") + action.add_argument("--make-pxe-live", action="store_true", + help="Build a live pxe boot squashfs image") + action.add_argument("--make-ostree-live", action="store_true", + help="Build a live pxe boot squashfs image of Atomic Host") + action.add_argument("--make-oci", action="store_true", + help="Build an Open Container Initiative image") + action.add_argument("--make-vagrant", action="store_true", + help="Build a Vagrant Box image") + + parser.add_argument("--iso", type=os.path.abspath, + help="Anaconda installation .iso path to use for qemu") + parser.add_argument("--iso-only", action="store_true", + help="Remove all iso creation artifacts except the boot.iso, " + "combine with --iso-name to rename the boot.iso") + parser.add_argument("--iso-name", default=None, + help="Name of output iso file for --iso-only. Default is boot.iso") + parser.add_argument("--ks", action="append", type=os.path.abspath, + help="Kickstart file defining the install.") + parser.add_argument("--image-only", action="store_true", + help="Exit after creating fs/disk image.") + + parser.add_argument("--no-virt", action="store_true", + help="Run anaconda directly on host instead of using qemu") + parser.add_argument("--proxy", + help="proxy URL to use for the install") + parser.add_argument("--anaconda-arg", action="append", dest="anaconda_args", + help="Additional argument to pass to anaconda (no-virt " + "mode). Pass once for each argument") + parser.add_argument("--armplatform", + help="the platform to use when creating images for ARM, " + "i.e., highbank, mvebu, omap, tegra, etc.") + parser.add_argument("--location", default=None, type=os.path.abspath, + help="location of iso directory tree with initrd.img " + "and vmlinuz. Used to run qemu with a newer initrd " + "than the iso.") + + parser.add_argument("--logfile", default="./livemedia.log", + type=os.path.abspath, + help="Name and path for primary logfile, other logs will " + "be created in the same directory.") + parser.add_argument("--lorax-templates", default=None, + type=os.path.abspath, + help="Path to mako templates for lorax") + parser.add_argument("--tmp", default="/var/tmp", type=os.path.abspath, + help="Top level temporary directory") + parser.add_argument("--resultdir", default=None, dest="result_dir", + type=os.path.abspath, + help="Directory to copy the resulting images and iso into. " + "Defaults to the temporary working directory") + + parser.add_argument("--macboot", action="store_true", default=True, + dest="domacboot") + parser.add_argument("--nomacboot", action="store_false", + dest="domacboot") + + parser.add_argument("--extra-boot-args", default="", dest="extra_boot_args", + help="Extra arguments to add to the bootloader kernel cmdline in the templates") + + image_group = parser.add_argument_group("disk/fs image arguments") + image_group.add_argument("--disk-image", type=os.path.abspath, + help="Path to existing disk image to use for creating final image.") + image_group.add_argument("--keep-image", action="store_true", + help="Keep raw disk image after .iso creation") + image_group.add_argument("--fs-image", type=os.path.abspath, + help="Path to existing filesystem image to use for creating final image.") + image_group.add_argument("--image-name", default=None, + help="Name of output file to create. Used for tar, fs and disk image. Default is a random name.") + image_group.add_argument("--tar-disk-name", default=None, + help="Name of the archive member for make-tar-disk.") + image_group.add_argument("--fs-label", default="Anaconda", + help="Label to set on fsimage, default is 'Anaconda'") + image_group.add_argument("--image-size-align", type=int, default=0, + help="Create a disk image with a size that is a multiple of this value in MiB.") + image_group.add_argument("--image-type", default=None, + help="Create an image with qemu-img. See qemu-img --help for supported formats.") + image_group.add_argument("--qemu-arg", action="append", dest="qemu_args", default=[], + help="Arguments to pass to qemu-img. Pass once for each argument, they will be used for ALL calls to qemu-img.") + image_group.add_argument("--qcow2", action="store_true", + help="Create qcow2 image instead of raw sparse image when making disk images.") + image_group.add_argument("--qcow2-arg", action="append", dest="qemu_args", default=[], + help="Arguments to pass to qemu-img. Pass once for each argument, they will be used for ALL calls to qemu-img.") + image_group.add_argument("--compression", default="xz", + help="Compression binary for make-tar. xz, lzma, gzip, and bzip2 are supported. xz is the default.") + image_group.add_argument("--compress-arg", action="append", dest="compress_args", default=[], + help="Arguments to pass to compression. Pass once for each argument") + # Group of arguments for appliance creation + app_group = parser.add_argument_group("appliance arguments") + app_group.add_argument("--app-name", default=None, + help="Name of appliance to pass to template") + app_group.add_argument("--app-template", default=None, + help="Path to template to use for appliance data.") + app_group.add_argument("--app-file", default="appliance.xml", + help="Appliance template results file.") + + # Group of arguments to pass to qemu + virt_group = parser.add_argument_group("qemu arguments") + virt_group.add_argument("--ram", metavar="MEMORY", type=int, default=1024, + help="Memory to allocate for installer in megabytes.") + virt_group.add_argument("--vcpus", type=int, default=None, + help="Passed to qemu -smp command") + virt_group.add_argument("--vnc", + help="Passed to qemu -display command. eg. vnc=127.0.0.1:5, default is to " + "choose the first unused vnc port.") + virt_group.add_argument("--arch", default=None, + help="System arch to build for. Used to select qemu-system-* command. " + "Defaults to qemu-system-<arch>") + virt_group.add_argument("--kernel-args", + help="Additional argument to pass to the installation kernel") + virt_group.add_argument("--ovmf-path", default="/usr/share/edk2/ovmf/", + help="Path to OVMF firmware") + virt_group.add_argument("--virt-uefi", action="store_true", default=False, + help="Use OVMF firmware to boot the VM in UEFI mode") + virt_group.add_argument("--no-kvm", action="store_true", default=False, + help="Skip using kvm with qemu even if it is available.") + virt_group.add_argument("--with-rng", default="/dev/random", + help="RNG device for QEMU (none for no RNG)") + + # dracut arguments + dracut_group = parser.add_argument_group("dracut arguments") + dracut_group.add_argument("--dracut-arg", action="append", dest="dracut_args", + help="Argument to pass to dracut when " + "rebuilding the initramfs. Pass this " + "once for each argument. NOTE: this " + "overrides the default. (default: %s)" % dracut_default) + + # pxe to live arguments + pxelive_group = parser.add_argument_group("pxe to live arguments") + pxelive_group.add_argument("--live-rootfs-size", type=int, default=0, + help="Size of root filesystem of live image in GiB") + pxelive_group.add_argument("--live-rootfs-keep-size", action="store_true", + help="Keep the original size of root filesystem in live image") + + # OCI specific commands + oci_group = parser.add_argument_group("OCI arguments") + oci_group.add_argument("--oci-config", + help="config.json OCI configuration file") + oci_group.add_argument("--oci-runtime", + help="runtime.json OCI configuration file") + + # Vagrant specific commands + vagrant_group = parser.add_argument_group("Vagrant arguments") + vagrant_group.add_argument("--vagrant-metadata", + help="optional metadata.json file") + vagrant_group.add_argument("--vagrantfile", + help="optional vagrantfile") + + parser.add_argument("--title", default="Linux Live Media", + help="Substituted for @TITLE@ in bootloader config files") + parser.add_argument("--project", default="Linux", + help="substituted for @PROJECT@ in bootloader config files") + parser.add_argument("--releasever", default="8", + help="substituted for @VERSION@ in bootloader config files") + parser.add_argument("--volid", default=None, help="volume id") + parser.add_argument("--squashfs_args", + help="additional squashfs args") + parser.add_argument("--timeout", default=None, type=int, + help="Cancel installer after X minutes") + + # add the show version option + parser.add_argument("-V", help="show program's version number and exit", + action="version", version=version) + + return parser
    +
    + +
    + +
    +
    + + +
    + +
    +

    + © Copyright 2018-2019, Red Hat, Inc. + +

    +
    + Built with Sphinx using a theme provided by Read the Docs. + +
    + +
    +
    + +
    + +
    + + + + + + + + + + + + \ No newline at end of file diff --git a/rhel8-branch/_modules/pylorax/creator.html b/rhel8-branch/_modules/pylorax/creator.html new file mode 100644 index 00000000..e6c80e69 --- /dev/null +++ b/rhel8-branch/_modules/pylorax/creator.html @@ -0,0 +1,977 @@ + + + + + + + + + + + pylorax.creator — Lorax 28.14.33 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + + + +
    + + + + + +
    + +
    + + + + + + + + + + + + + + + + + +
    + + + + +
    +
    +
    +
    + +

    Source code for pylorax.creator

    +#
    +# Copyright (C) 2011-2018  Red Hat, Inc.
    +#
    +# This program is free software; you can redistribute it and/or modify
    +# it under the terms of the GNU General Public License as published by
    +# the Free Software Foundation; either version 2 of the License, or
    +# (at your option) any later version.
    +#
    +# This program is distributed in the hope that it will be useful,
    +# but WITHOUT ANY WARRANTY; without even the implied warranty of
    +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    +# GNU General Public License for more details.
    +#
    +# You should have received a copy of the GNU General Public License
    +# along with this program.  If not, see <http://www.gnu.org/licenses/>.
    +#
    +import logging
    +log = logging.getLogger("pylorax")
    +
    +import os
    +import tempfile
    +import subprocess
    +import shutil
    +import hashlib
    +import glob
    +
    +# Use Mako templates for appliance builder descriptions
    +from mako.template import Template
    +from mako.exceptions import text_error_template
    +
    +# Use pykickstart to calculate disk image size
    +from pykickstart.parser import KickstartParser
    +from pykickstart.constants import KS_SHUTDOWN
    +from pykickstart.version import makeVersion
    +
    +# Use the Lorax treebuilder branch for iso creation
    +from pylorax import ArchData
    +from pylorax.base import DataHolder
    +from pylorax.executils import execWithRedirect, runcmd
    +from pylorax.imgutils import PartitionMount
    +from pylorax.imgutils import mount, umount, Mount
    +from pylorax.imgutils import mksquashfs, mkrootfsimg
    +from pylorax.imgutils import copytree
    +from pylorax.installer import novirt_install, virt_install, InstallError
    +from pylorax.treebuilder import TreeBuilder, RuntimeBuilder
    +from pylorax.treebuilder import findkernels
    +from pylorax.sysutils import joinpaths, remove
    +
    +
    +# Default parameters for rebuilding initramfs, override with --dracut-args
    +DRACUT_DEFAULT = ["--xz", "--add", "livenet dmsquash-live convertfs pollcdrom qemu qemu-net",
    +                  "--omit", "plymouth", "--no-hostonly", "--debug", "--no-early-microcode"]
    +
    +RUNTIME = "images/install.img"
    +
    +
    [docs]class FakeDNF(object): + """ + A minimal DNF object suitable for passing to RuntimeBuilder + + lmc uses RuntimeBuilder to run the arch specific iso creation + templates, so the the installroot config value is the important part of + this. Everything else should be a nop. + """ + def __init__(self, conf): + self.conf = conf + +
    [docs] def reset(self): + pass
    + +
    [docs]def is_image_mounted(disk_img): + """ + Check to see if the disk_img is mounted + + :returns: True if disk_img is in /proc/mounts + :rtype: bool + """ + with open("/proc/mounts") as mounts: + for mnt in mounts: + fields = mnt.split() + if len(fields) > 2 and fields[1] == disk_img: + return True + return False
    + +
    [docs]def find_ostree_root(phys_root): + """ + Find root of ostree deployment + + :param str phys_root: Path to physical root + :returns: Relative path of ostree deployment root + :rtype: str + :raise Exception: More than one deployment roots were found + """ + ostree_root = "" + ostree_sysroots = glob.glob(joinpaths(phys_root, "ostree/boot.?/*/*/0")) + log.debug("ostree_sysroots = %s", ostree_sysroots) + if ostree_sysroots: + if len(ostree_sysroots) > 1: + raise Exception("Too many deployment roots found: %s" % ostree_sysroots) + ostree_root = os.path.relpath(ostree_sysroots[0], phys_root) + return ostree_root
    + +
    [docs]def get_arch(mount_dir): + """ + Get the kernel arch + + :returns: Arch of first kernel found at mount_dir/boot/ or i386 + :rtype: str + """ + kernels = findkernels(mount_dir) + if not kernels: + return "i386" + return kernels[0].arch
    + +
    [docs]def squashfs_args(opts): + """ Returns the compression type and args to use when making squashfs + + :param opts: ArgumentParser object with compression and compressopts + :returns: tuple of compression type and args + :rtype: tuple + """ + compression = opts.compression or "xz" + arch = ArchData(opts.arch or os.uname().machine) + if compression == "xz" and arch.bcj: + compressargs = ["-Xbcj", arch.bcj] + else: + compressargs = [] + return (compression, compressargs)
    + + +
    [docs]def make_appliance(disk_img, name, template, outfile, networks=None, ram=1024, + vcpus=1, arch=None, title="Linux", project="Linux", + releasever="29"): + """ + Generate an appliance description file + + :param str disk_img: Full path of the disk image + :param str name: Name of the appliance, passed to the template + :param str template: Full path of Mako template + :param str outfile: Full path of file to write, using template + :param list networks: List of networks(str) from the kickstart + :param int ram: Ram, in MiB, passed to template. Default is 1024 + :param int vcpus: CPUs, passed to template. Default is 1 + :param str arch: CPU architecture. Default is 'x86_64' + :param str title: Title, passed to template. Default is 'Linux' + :param str project: Project, passed to template. Default is 'Linux' + :param str releasever: Release version, passed to template. Default is 29 + """ + if not (disk_img and template and outfile): + return None + + log.info("Creating appliance definition using %s", template) + + if not arch: + arch = "x86_64" + + log.info("Calculating SHA256 checksum of %s", disk_img) + sha256 = hashlib.sha256() + with open(disk_img, "rb") as f: + while True: + data = f.read(1024**2) + if not data: + break + sha256.update(data) + log.info("SHA256 of %s is %s", disk_img, sha256.hexdigest()) + disk_info = DataHolder(name=os.path.basename(disk_img), format="raw", + checksum_type="sha256", checksum=sha256.hexdigest()) + try: + result = Template(filename=template).render(disks=[disk_info], name=name, + arch=arch, memory=ram, vcpus=vcpus, networks=networks, + title=title, project=project, releasever=releasever) + except Exception: + log.error(text_error_template().render()) + raise + + with open(outfile, "w") as f: + f.write(result)
    + + +
    [docs]def make_runtime(opts, mount_dir, work_dir, size=None): + """ + Make the squashfs image from a directory + + :param opts: options passed to livemedia-creator + :type opts: argparse options + :param str mount_dir: Directory tree to compress + :param str work_dir: Output compressed image to work_dir+images/install.img + :param int size: Size of disk image, in GiB + """ + kernel_arch = get_arch(mount_dir) + + # Fake dnf object + fake_dbo = FakeDNF(conf=DataHolder(installroot=mount_dir)) + # Fake arch with only basearch set + arch = ArchData(kernel_arch) + # TODO: Need to get release info from someplace... + product = DataHolder(name=opts.project, version=opts.releasever, release="", + variant="", bugurl="", isfinal=False) + + # This is a mounted image partition, cannot hardlink to it, so just use it + # symlink mount_dir/images to work_dir/images so we don't run out of space + os.makedirs(joinpaths(work_dir, "images")) + + rb = RuntimeBuilder(product, arch, fake_dbo) + compression, compressargs = squashfs_args(opts) + log.info("Creating runtime") + rb.create_runtime(joinpaths(work_dir, RUNTIME), size=size, + compression=compression, compressargs=compressargs)
    + + +
    [docs]def rebuild_initrds_for_live(opts, sys_root_dir, results_dir): + """ + Rebuild intrds for pxe live image (root=live:http://) + + :param opts: options passed to livemedia-creator + :type opts: argparse options + :param str sys_root_dir: Path to root of the system + :param str results_dir: Path of directory for storing results + """ + if not opts.dracut_args: + dracut_args = DRACUT_DEFAULT + else: + dracut_args = [] + for arg in opts.dracut_args: + dracut_args += arg.split(" ", 1) + log.info("dracut args = %s", dracut_args) + + dracut = ["dracut", "--nomdadmconf", "--nolvmconf"] + dracut_args + + kdir = "boot" + if opts.ostree: + kernels_dir = glob.glob(joinpaths(sys_root_dir, "boot/ostree/*")) + if kernels_dir: + kdir = os.path.relpath(kernels_dir[0], sys_root_dir) + + kernels = [kernel for kernel in findkernels(sys_root_dir, kdir)] + if not kernels: + raise Exception("No initrds found, cannot rebuild_initrds") + + # Hush some dracut warnings. TODO: bind-mount proc in place? + open(joinpaths(sys_root_dir,"/proc/modules"),"w") + + if opts.ostree: + # Dracut assumes to have some dirs in disk image + # /var/tmp for temp files + vartmp_dir = joinpaths(sys_root_dir, "var/tmp") + if not os.path.isdir(vartmp_dir): + os.mkdir(vartmp_dir) + # /root (maybe not fatal) + root_dir = joinpaths(sys_root_dir, "var/roothome") + if not os.path.isdir(root_dir): + os.mkdir(root_dir) + # /tmp (maybe not fatal) + tmp_dir = joinpaths(sys_root_dir, "sysroot/tmp") + if not os.path.isdir(tmp_dir): + os.mkdir(tmp_dir) + + # Write the new initramfs directly to the results directory + os.mkdir(joinpaths(sys_root_dir, "results")) + mount(results_dir, opts="bind", mnt=joinpaths(sys_root_dir, "results")) + # Dracut runs out of space inside the minimal rootfs image + mount("/var/tmp", opts="bind", mnt=joinpaths(sys_root_dir, "var/tmp")) + for kernel in kernels: + if hasattr(kernel, "initrd"): + outfile = os.path.basename(kernel.initrd.path) + else: + # Construct an initrd from the kernel name + outfile = os.path.basename(kernel.path.replace("vmlinuz-", "initrd-") + ".img") + log.info("rebuilding %s", outfile) + + kver = kernel.version + + cmd = dracut + ["/results/"+outfile, kver] + runcmd(cmd, root=sys_root_dir) + + shutil.copy2(joinpaths(sys_root_dir, kernel.path), results_dir) + umount(joinpaths(sys_root_dir, "var/tmp"), delete=False) + umount(joinpaths(sys_root_dir, "results"), delete=False) + os.unlink(joinpaths(sys_root_dir,"/proc/modules"))
    + +
    [docs]def create_pxe_config(template, images_dir, live_image_name, add_args = None): + """ + Create template for pxe to live configuration + + :param str images_dir: Path of directory with images to be used + :param str live_image_name: Name of live rootfs image file + :param list add_args: Arguments to be added to initrd= pxe config + """ + + add_args = add_args or [] + + kernels = [kernel for kernel in findkernels(images_dir, kdir="") + if hasattr(kernel, "initrd")] + if not kernels: + return + + kernel = kernels[0] + + add_args_str = " ".join(add_args) + + + try: + result = Template(filename=template).render(kernel=kernel.path, + initrd=kernel.initrd.path, liveimg=live_image_name, + addargs=add_args_str) + except Exception: + log.error(text_error_template().render()) + raise + + with open (joinpaths(images_dir, "PXE_CONFIG"), "w") as f: + f.write(result)
    + + +
    [docs]def make_livecd(opts, mount_dir, work_dir): + """ + Take the content from the disk image and make a livecd out of it + + :param opts: options passed to livemedia-creator + :type opts: argparse options + :param str mount_dir: Directory tree to compress + :param str work_dir: Output compressed image to work_dir+images/install.img + + This uses wwood's squashfs live initramfs method: + * put the real / into LiveOS/rootfs.img + * make a squashfs of the LiveOS/rootfs.img tree + * This is loaded by dracut when the cmdline is passed to the kernel: + root=live:CDLABEL=<volid> rd.live.image + """ + kernel_arch = get_arch(mount_dir) + + arch = ArchData(kernel_arch) + # TODO: Need to get release info from someplace... + product = DataHolder(name=opts.project, version=opts.releasever, release="", + variant="", bugurl="", isfinal=False) + + # Link /images to work_dir/images to make the templates happy + if os.path.islink(joinpaths(mount_dir, "images")): + os.unlink(joinpaths(mount_dir, "images")) + execWithRedirect("/bin/ln", ["-s", joinpaths(work_dir, "images"), + joinpaths(mount_dir, "images")]) + + # The templates expect the config files to be in /tmp/config_files + # I think these should be release specific, not from lorax, but for now + configdir = joinpaths(opts.lorax_templates,"live/config_files/") + configdir_path = "tmp/config_files" + fullpath = joinpaths(mount_dir, configdir_path) + if os.path.exists(fullpath): + remove(fullpath) + copytree(configdir, fullpath) + + isolabel = opts.volid or "{0.name}-{0.version}-{1.basearch}".format(product, arch) + if len(isolabel) > 32: + isolabel = isolabel[:32] + log.warning("Truncating isolabel to 32 chars: %s", isolabel) + + tb = TreeBuilder(product=product, arch=arch, domacboot=opts.domacboot, + inroot=mount_dir, outroot=work_dir, + runtime=RUNTIME, isolabel=isolabel, + templatedir=joinpaths(opts.lorax_templates,"live/"), + extra_boot_args=opts.extra_boot_args) + log.info("Rebuilding initrds") + if not opts.dracut_args: + dracut_args = DRACUT_DEFAULT + else: + dracut_args = [] + for arg in opts.dracut_args: + dracut_args += arg.split(" ", 1) + log.info("dracut args = %s", dracut_args) + tb.rebuild_initrds(add_args=dracut_args) + log.info("Building boot.iso") + tb.build() + + return work_dir
    + +
    [docs]def mount_boot_part_over_root(img_mount): + """ + Mount boot partition to /boot of root fs mounted in img_mount + + Used for OSTree so it finds deployment configurations on live rootfs + + param img_mount: object with mounted disk image root partition + type img_mount: imgutils.PartitionMount + """ + root_dir = img_mount.mount_dir + is_boot_part = lambda dir: os.path.exists(dir+"/loader.0") + tmp_mount_dir = tempfile.mkdtemp(prefix="lmc-tmpdir-") + sysroot_boot_dir = None + for dev, _size in img_mount.loop_devices: + if dev is img_mount.mount_dev: + continue + try: + mount("/dev/mapper/"+dev, mnt=tmp_mount_dir) + if is_boot_part(tmp_mount_dir): + umount(tmp_mount_dir) + sysroot_boot_dir = joinpaths(root_dir, "boot") + mount("/dev/mapper/"+dev, mnt=sysroot_boot_dir) + break + else: + umount(tmp_mount_dir) + except subprocess.CalledProcessError as e: + log.debug("Looking for boot partition error: %s", e) + remove(tmp_mount_dir) + return sysroot_boot_dir
    + +
    [docs]def make_squashfs(opts, disk_img, work_dir): + """ + Create a squashfs image of an unpartitioned filesystem disk image + + :param str disk_img: Path to the unpartitioned filesystem disk image + :param str work_dir: Output compressed image to work_dir+images/install.img + :param str compression: Compression type to use + :returns: True if squashfs creation was successful. False if there was an error. + :rtype: bool + + Take disk_img and put it into LiveOS/rootfs.img and squashfs this + tree into work_dir+images/install.img + + fsck.ext4 is run on the disk image to make sure there are no errors and to zero + out any deleted blocks to make it compress better. If this fails for any reason + it will return False and log the error. + """ + # Make sure free blocks are actually zeroed so it will compress + rc = execWithRedirect("/usr/sbin/fsck.ext4", ["-y", "-f", "-E", "discard", disk_img]) + if rc != 0: + log.error("Problem zeroing free blocks of %s", disk_img) + return False + + liveos_dir = joinpaths(work_dir, "runtime/LiveOS") + os.makedirs(liveos_dir) + os.makedirs(os.path.dirname(joinpaths(work_dir, RUNTIME))) + + rc = execWithRedirect("/bin/ln", [disk_img, joinpaths(liveos_dir, "rootfs.img")]) + if rc != 0: + shutil.copy2(disk_img, joinpaths(liveos_dir, "rootfs.img")) + + compression, compressargs = squashfs_args(opts) + mksquashfs(joinpaths(work_dir, "runtime"), + joinpaths(work_dir, RUNTIME), compression, compressargs) + remove(joinpaths(work_dir, "runtime")) + return True
    + +
    [docs]def calculate_disk_size(opts, ks): + """ Calculate the disk size from the kickstart + + :param opts: options passed to livemedia-creator + :type opts: argparse options + :param str ks: Path to the kickstart to use for the installation + :returns: Disk size in MiB + :rtype: int + + Also takes into account the use of reqpart or reqpart --add-boot + """ + # Disk size for a filesystem image should only be the size of / + # to prevent surprises when using the same kickstart for different installations. + unique_partitions = dict((p.mountpoint, p) for p in ks.handler.partition.partitions) + if opts.no_virt and (opts.make_iso or opts.make_fsimage): + disk_size = 2 + sum(p.size for p in unique_partitions.values() if p.mountpoint == "/") + else: + disk_size = 2 + sum(p.size for p in unique_partitions.values()) + + # reqpart can add 1M, 2M, 200M based on platform. Add 500M to be sure + if ks.handler.reqpart.seen: + log.info("Adding 500M for reqpart") + disk_size += 500 + + # It can also request adding /boot which is 1G + if ks.handler.reqpart.addBoot: + log.info("Adding 1024M for reqpart --addboot") + disk_size += 1024 + + if opts.image_size_align: + disk_size += opts.image_size_align - (disk_size % opts.image_size_align) + + log.info("Using disk size of %sMiB", disk_size) + return disk_size
    + +
    [docs]def make_image(opts, ks, cancel_func=None): + """ + Install to a disk image + + :param opts: options passed to livemedia-creator + :type opts: argparse options + :param str ks: Path to the kickstart to use for the installation + :param cancel_func: Function that returns True to cancel build + :type cancel_func: function + :returns: Path of the image created + :rtype: str + + Use qemu+boot.iso or anaconda to install to a disk image. + """ + + # For make_tar_disk, opts.image_name is the name of the final tarball. + # Use opts.tar_disk_name as the name of the disk image + if opts.make_tar_disk: + disk_img = joinpaths(opts.result_dir, opts.tar_disk_name) + elif opts.image_name: + disk_img = joinpaths(opts.result_dir, opts.image_name) + else: + disk_img = tempfile.mktemp(prefix="lmc-disk-", suffix=".img", dir=opts.result_dir) + log.info("disk_img = %s", disk_img) + disk_size = calculate_disk_size(opts, ks) + + # For make_tar_disk, pass a second path parameter for the final tarball + # not the final output file. + if opts.make_tar_disk: + tar_img = joinpaths(opts.result_dir, opts.image_name) + else: + tar_img = None + + try: + if opts.no_virt: + novirt_install(opts, disk_img, disk_size, cancel_func=cancel_func, tar_img=tar_img) + else: + install_log = os.path.abspath(os.path.dirname(opts.logfile))+"/virt-install.log" + log.info("install_log = %s", install_log) + + virt_install(opts, install_log, disk_img, disk_size, cancel_func=cancel_func, tar_img=tar_img) + except InstallError as e: + log.error("Install failed: %s", e) + if not opts.keep_image: + if os.path.exists(disk_img): + log.info("Removing bad disk image") + os.unlink(disk_img) + if tar_img and os.path.exists(tar_img): + log.info("Removing bad tar file") + os.unlink(tar_img) + raise + + log.info("Disk Image install successful") + + if opts.make_tar_disk: + return tar_img + + return disk_img
    + + +
    [docs]def make_live_images(opts, work_dir, disk_img): + """ + Create live images from direcory or rootfs image + + :param opts: options passed to livemedia-creator + :type opts: argparse options + :param str work_dir: Directory for storing results + :param str disk_img: Path to disk image (fsimage or partitioned) + :returns: Path of directory with created images or None + :rtype: str + + fsck.ext4 is run on the rootfs_image to make sure there are no errors and to zero + out any deleted blocks to make it compress better. If this fails for any reason + it will return None and log the error. + """ + sys_root = "" + + squashfs_root_dir = joinpaths(work_dir, "squashfs_root") + liveos_dir = joinpaths(squashfs_root_dir, "LiveOS") + os.makedirs(liveos_dir) + rootfs_img = joinpaths(liveos_dir, "rootfs.img") + + if opts.fs_image or opts.no_virt: + # Find the ostree root in the fsimage + if opts.ostree: + with Mount(disk_img, opts="loop") as mnt_dir: + sys_root = find_ostree_root(mnt_dir) + + # Try to hardlink the image, if that fails, copy it + rc = execWithRedirect("/bin/ln", [disk_img, rootfs_img]) + if rc != 0: + shutil.copy2(disk_img, rootfs_img) + else: + is_root_part = None + if opts.ostree: + is_root_part = lambda dir: os.path.exists(dir+"/ostree/deploy") + with PartitionMount(disk_img, mount_ok=is_root_part) as img_mount: + if img_mount and img_mount.mount_dir: + try: + mounted_sysroot_boot_dir = None + if opts.ostree: + sys_root = find_ostree_root(img_mount.mount_dir) + mounted_sysroot_boot_dir = mount_boot_part_over_root(img_mount) + if opts.live_rootfs_keep_size: + size = img_mount.mount_size / 1024**3 + else: + size = opts.live_rootfs_size or None + log.info("Creating live rootfs image") + mkrootfsimg(img_mount.mount_dir, rootfs_img, "LiveOS", size=size, sysroot=sys_root) + finally: + if mounted_sysroot_boot_dir: + umount(mounted_sysroot_boot_dir) + log.debug("sys_root = %s", sys_root) + + # Make sure free blocks are actually zeroed so it will compress + rc = execWithRedirect("/usr/sbin/fsck.ext4", ["-y", "-f", "-E", "discard", rootfs_img]) + if rc != 0: + log.error("Problem zeroing free blocks of %s", disk_img) + return None + + log.info("Packing live rootfs image") + add_pxe_args = [] + live_image_name = "live-rootfs.squashfs.img" + compression, compressargs = squashfs_args(opts) + mksquashfs(squashfs_root_dir, joinpaths(work_dir, live_image_name), compression, compressargs) + + log.info("Rebuilding initramfs for live") + with Mount(rootfs_img, opts="loop") as mnt_dir: + try: + mount(joinpaths(mnt_dir, "boot"), opts="bind", mnt=joinpaths(mnt_dir, sys_root, "boot")) + rebuild_initrds_for_live(opts, joinpaths(mnt_dir, sys_root), work_dir) + finally: + umount(joinpaths(mnt_dir, sys_root, "boot"), delete=False) + + remove(squashfs_root_dir) + + if opts.ostree: + add_pxe_args.append("ostree=/%s" % sys_root) + template = joinpaths(opts.lorax_templates, "pxe-live/pxe-config.tmpl") + create_pxe_config(template, work_dir, live_image_name, add_pxe_args) + + return work_dir
    + +
    [docs]def check_kickstart(ks, opts): + """Check the parsed kickstart object for errors + + :param ks: Parsed Kickstart object + :type ks: pykickstart.parser.KickstartParser + :param opts: Commandline options to control the process + :type opts: Either a DataHolder or ArgumentParser + :returns: List of error strings or empty list + :rtype: list + """ + errors = [] + if opts.no_virt and ks.handler.method.method not in ("url", "nfs") \ + and not ks.handler.ostreesetup.seen: + errors.append("Only url, nfs and ostreesetup install methods are currently supported." + "Please fix your kickstart file." ) + + if ks.handler.repo.seen and ks.handler.method.method != "url": + errors.append("repo can only be used with the url install method. Add url to your " + "kickstart file.") + + if ks.handler.method.method in ("url", "nfs") and not ks.handler.network.seen: + errors.append("The kickstart must activate networking if " + "the url or nfs install method is used.") + + if ks.handler.displaymode.displayMode is not None: + errors.append("The kickstart must not set a display mode (text, cmdline, " + "graphical), this will interfere with livemedia-creator.") + + if opts.make_fsimage or (opts.make_pxe_live and opts.no_virt): + # Make sure the kickstart isn't using autopart and only has a / mountpoint + part_ok = not any(p for p in ks.handler.partition.partitions + if p.mountpoint not in ["/", "swap"]) + if not part_ok or ks.handler.autopart.seen: + errors.append("Filesystem images must use a single / part, not autopart or " + "multiple partitions. swap is allowed but not used.") + + if not opts.no_virt and ks.handler.reboot.action != KS_SHUTDOWN: + errors.append("The kickstart must include shutdown when using virt installation.") + + return errors
    + +
    [docs]def run_creator(opts, cancel_func=None): + """Run the image creator process + + :param opts: Commandline options to control the process + :type opts: Either a DataHolder or ArgumentParser + :param cancel_func: Function that returns True to cancel build + :type cancel_func: function + :returns: The result directory and the disk image path. + :rtype: Tuple of str + + This function takes the opts arguments and creates the selected output image. + See the cmdline --help for livemedia-creator for the possible options + + (Yes, this is not ideal, but we can fix that later) + """ + result_dir = None + + # Parse the kickstart + if opts.ks: + ks_version = makeVersion() + ks = KickstartParser(ks_version, errorsAreFatal=False, missingIncludeIsFatal=False) + ks.readKickstart(opts.ks[0]) + + # live iso usually needs dracut-live so warn the user if it is missing + if opts.ks and opts.make_iso: + if "dracut-live" not in ks.handler.packages.packageList: + log.error("dracut-live package is missing from the kickstart.") + raise RuntimeError("dracut-live package is missing from the kickstart.") + + # Make the disk or filesystem image + if not opts.disk_image and not opts.fs_image: + if not opts.ks: + raise RuntimeError("Image creation requires a kickstart file") + + # Check the kickstart for problems + errors = check_kickstart(ks, opts) + if errors: + list(log.error(e) for e in errors) + raise RuntimeError("\n".join(errors)) + + # Make the image. Output of this is either a partitioned disk image or a fsimage + try: + disk_img = make_image(opts, ks, cancel_func=cancel_func) + except InstallError as e: + log.error("ERROR: Image creation failed: %s", e) + raise RuntimeError("Image creation failed: %s" % e) + + if opts.image_only: + return (result_dir, disk_img) + + if opts.make_iso: + work_dir = tempfile.mkdtemp(prefix="lmc-work-") + log.info("working dir is %s", work_dir) + + if (opts.fs_image or opts.no_virt) and not opts.disk_image: + # Create iso from a filesystem image + disk_img = opts.fs_image or disk_img + + if not make_squashfs(opts, disk_img, work_dir): + log.error("squashfs.img creation failed") + raise RuntimeError("squashfs.img creation failed") + + if cancel_func and cancel_func(): + raise RuntimeError("ISO creation canceled") + + with Mount(disk_img, opts="loop") as mount_dir: + result_dir = make_livecd(opts, mount_dir, work_dir) + else: + # Create iso from a partitioned disk image + disk_img = opts.disk_image or disk_img + with PartitionMount(disk_img) as img_mount: + if img_mount and img_mount.mount_dir: + make_runtime(opts, img_mount.mount_dir, work_dir, calculate_disk_size(opts, ks)/1024.0) + result_dir = make_livecd(opts, img_mount.mount_dir, work_dir) + + # --iso-only removes the extra build artifacts, keeping only the boot.iso + if opts.iso_only and result_dir: + boot_iso = joinpaths(result_dir, "images/boot.iso") + if not os.path.exists(boot_iso): + log.error("%s is missing, skipping --iso-only.", boot_iso) + else: + iso_dir = tempfile.mkdtemp(prefix="lmc-result-") + dest_file = joinpaths(iso_dir, opts.iso_name or "boot.iso") + shutil.move(boot_iso, dest_file) + shutil.rmtree(result_dir) + result_dir = iso_dir + + # cleanup the mess + # cleanup work_dir? + if disk_img and not (opts.keep_image or opts.disk_image or opts.fs_image): + os.unlink(disk_img) + log.info("Disk image erased") + disk_img = None + elif opts.make_appliance: + if not opts.ks: + networks = [] + else: + networks = ks.handler.network.network + make_appliance(opts.disk_image or disk_img, opts.app_name, + opts.app_template, opts.app_file, networks, opts.ram, + opts.vcpus or 1, opts.arch, opts.title, opts.project, opts.releasever) + elif opts.make_pxe_live: + work_dir = tempfile.mkdtemp(prefix="lmc-work-") + log.info("working dir is %s", work_dir) + disk_img = opts.fs_image or opts.disk_image or disk_img + log.debug("disk image is %s", disk_img) + + result_dir = make_live_images(opts, work_dir, disk_img) + if result_dir is None: + log.error("Creating PXE live image failed.") + raise RuntimeError("Creating PXE live image failed.") + + if opts.result_dir != opts.tmp and result_dir: + copytree(result_dir, opts.result_dir, preserve=False) + shutil.rmtree(result_dir) + result_dir = None + + return (result_dir, disk_img)
    +
    + +
    + +
    +
    + + +
    + +
    +

    + © Copyright 2018-2019, Red Hat, Inc. + +

    +
    + Built with Sphinx using a theme provided by Read the Docs. + +
    + +
    +
    + +
    + +
    + + + + + + + + + + + + \ No newline at end of file diff --git a/rhel8-branch/_modules/pylorax/decorators.html b/rhel8-branch/_modules/pylorax/decorators.html new file mode 100644 index 00000000..9f6be83b --- /dev/null +++ b/rhel8-branch/_modules/pylorax/decorators.html @@ -0,0 +1,230 @@ + + + + + + + + + + + pylorax.decorators — Lorax 28.14.33 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + + + +
    + + + + + +
    + +
    + + + + + + + + + + + + + + + + + +
    + + + + +
    +
    +
    +
    + +

    Source code for pylorax.decorators

    +#
    +# decorators.py
    +#
    +# Copyright (C) 2009-2015 Red Hat, Inc.
    +#
    +# This program is free software; you can redistribute it and/or modify
    +# it under the terms of the GNU General Public License as published by
    +# the Free Software Foundation; either version 2 of the License, or
    +# (at your option) any later version.
    +#
    +# This program is distributed in the hope that it will be useful,
    +# but WITHOUT ANY WARRANTY; without even the implied warranty of
    +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    +# GNU General Public License for more details.
    +#
    +# You should have received a copy of the GNU General Public License
    +# along with this program.  If not, see <http://www.gnu.org/licenses/>.
    +#
    +# Red Hat Author(s):  Martin Gracik <mgracik@redhat.com>
    +#
    +
    +
    [docs]def singleton(cls): + instances = {} + + def get_instance(): + if cls not in instances: + instances[cls] = cls() + return instances[cls] + + return get_instance
    +
    + +
    + +
    +
    + + +
    + +
    +

    + © Copyright 2018-2019, Red Hat, Inc. + +

    +
    + Built with Sphinx using a theme provided by Read the Docs. + +
    + +
    +
    + +
    + +
    + + + + + + + + + + + + \ No newline at end of file diff --git a/rhel8-branch/_modules/pylorax/discinfo.html b/rhel8-branch/_modules/pylorax/discinfo.html new file mode 100644 index 00000000..d6ff6d49 --- /dev/null +++ b/rhel8-branch/_modules/pylorax/discinfo.html @@ -0,0 +1,239 @@ + + + + + + + + + + + pylorax.discinfo — Lorax 28.14.33 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + + + +
    + + + + + +
    + +
    + + + + + + + + + + + + + + + + + +
    + + + + +
    +
    +
    +
    + +

    Source code for pylorax.discinfo

    +#
    +# discinfo.py
    +#
    +# Copyright (C) 2010-2015  Red Hat, Inc.
    +#
    +# This program is free software; you can redistribute it and/or modify
    +# it under the terms of the GNU General Public License as published by
    +# the Free Software Foundation; either version 2 of the License, or
    +# (at your option) any later version.
    +#
    +# This program is distributed in the hope that it will be useful,
    +# but WITHOUT ANY WARRANTY; without even the implied warranty of
    +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    +# GNU General Public License for more details.
    +#
    +# You should have received a copy of the GNU General Public License
    +# along with this program.  If not, see <http://www.gnu.org/licenses/>.
    +#
    +# Red Hat Author(s):  Martin Gracik <mgracik@redhat.com>
    +#
    +
    +import logging
    +logger = logging.getLogger("pylorax.discinfo")
    +
    +import time
    +
    +
    +
    [docs]class DiscInfo(object): + + def __init__(self, release, basearch): + self.release = release + self.basearch = basearch + +
    [docs] def write(self, outfile): + logger.info("writing .discinfo file") + with open(outfile, "w") as fobj: + fobj.write("{0:f}\n".format(time.time())) + fobj.write("{0.release}\n".format(self)) + fobj.write("{0.basearch}\n".format(self))
    +
    + +
    + +
    +
    + + +
    + +
    +

    + © Copyright 2018-2019, Red Hat, Inc. + +

    +
    + Built with Sphinx using a theme provided by Read the Docs. + +
    + +
    +
    + +
    + +
    + + + + + + + + + + + + \ No newline at end of file diff --git a/rhel8-branch/_modules/pylorax/dnfhelper.html b/rhel8-branch/_modules/pylorax/dnfhelper.html new file mode 100644 index 00000000..779d5ce5 --- /dev/null +++ b/rhel8-branch/_modules/pylorax/dnfhelper.html @@ -0,0 +1,310 @@ + + + + + + + + + + + pylorax.dnfhelper — Lorax 28.14.33 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + + + +
    + + + + + +
    + +
    + + + + + + + + + + + + + + + + + +
    + + + + +
    +
    +
    +
    + +

    Source code for pylorax.dnfhelper

    +#
    +# dnfhelper.py
    +#
    +# Copyright (C) 2010-2015 Red Hat, Inc.
    +#
    +# This program is free software; you can redistribute it and/or modify
    +# it under the terms of the GNU General Public License as published by
    +# the Free Software Foundation; either version 2 of the License, or
    +# (at your option) any later version.
    +#
    +# This program is distributed in the hope that it will be useful,
    +# but WITHOUT ANY WARRANTY; without even the implied warranty of
    +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    +# GNU General Public License for more details.
    +#
    +# You should have received a copy of the GNU General Public License
    +# along with this program.  If not, see <http://www.gnu.org/licenses/>.
    +#
    +# Red Hat Author(s):  Martin Gracik <mgracik@redhat.com>
    +#                     Brian C. Lane <bcl@redhat.com>
    +#
    +
    +import logging
    +logger = logging.getLogger("pylorax.dnfhelper")
    +import dnf
    +import dnf.transaction
    +import collections
    +import time
    +import pylorax.output as output
    +
    +__all__ = ['LoraxDownloadCallback', 'LoraxRpmCallback']
    +
    +def _paced(fn):
    +    """Execute `fn` no more often then every 2 seconds."""
    +    def paced_fn(self, *args):
    +        now = time.time()
    +        if now - self.last_time < 2:
    +            return
    +        self.last_time = now
    +        return fn(self, *args)
    +    return paced_fn
    +
    +
    +
    [docs]class LoraxDownloadCallback(dnf.callback.DownloadProgress): + def __init__(self): + self.downloads = collections.defaultdict(int) + self.last_time = time.time() + self.total_files = 0 + self.total_size = 0 + + self.pkgno = 0 + self.total = 0 + + self.output = output.LoraxOutput() + + @_paced + def _update(self): + msg = "Downloading %(pkgno)s / %(total_files)s RPMs, " \ + "%(downloaded)s / %(total_size)s (%(percent)d%%) done.\n" + downloaded = sum(self.downloads.values()) + vals = { + 'downloaded' : downloaded, + 'percent' : int(100 * downloaded/self.total_size), + 'pkgno' : self.pkgno, + 'total_files' : self.total_files, + 'total_size' : self.total_size + } + self.output.write(msg % vals) + +
    [docs] def end(self, payload, status, msg): + nevra = str(payload) + if status is dnf.callback.STATUS_OK: + self.downloads[nevra] = payload.download_size + self.pkgno += 1 + self._update() + return + logger.critical("Failed to download '%s': %d - %s", nevra, status, msg)
    + +
    [docs] def progress(self, payload, done): + nevra = str(payload) + self.downloads[nevra] = done + self._update()
    + + # dnf 2.5.0 adds a new argument, accept it if it is passed + # pylint: disable=arguments-differ +
    [docs] def start(self, total_files, total_size, total_drpms=0): + self.total_files = total_files + self.total_size = total_size
    + + +
    [docs]class LoraxRpmCallback(dnf.callback.TransactionProgress): + def __init__(self): + super(LoraxRpmCallback, self).__init__() + self._last_ts = None + +
    [docs] def progress(self, package, action, ti_done, ti_total, ts_done, ts_total): + if action == dnf.transaction.PKG_INSTALL: # pylint: disable=no-member + # do not report same package twice + if self._last_ts == ts_done: + return + self._last_ts = ts_done + + msg = '(%d/%d) %s' % (ts_done, ts_total, package) + logger.info(msg) + elif action == dnf.transaction.TRANS_POST: # pylint: disable=no-member + msg = "Performing post-installation setup tasks" + logger.info(msg)
    + +
    [docs] def error(self, message): + logger.warning(message)
    +
    + +
    + +
    +
    + + +
    + +
    +

    + © Copyright 2018-2019, Red Hat, Inc. + +

    +
    + Built with Sphinx using a theme provided by Read the Docs. + +
    + +
    +
    + +
    + +
    + + + + + + + + + + + + \ No newline at end of file diff --git a/rhel8-branch/_modules/pylorax/executils.html b/rhel8-branch/_modules/pylorax/executils.html new file mode 100644 index 00000000..3b1d94b5 --- /dev/null +++ b/rhel8-branch/_modules/pylorax/executils.html @@ -0,0 +1,547 @@ + + + + + + + + + + + pylorax.executils — Lorax 28.14.33 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + + + +
    + + + + + +
    + +
    + + + + + + + + + + + + + + + + + +
    + + + + +
    +
    +
    +
    + +

    Source code for pylorax.executils

    +#
    +# executil.py - subprocess execution utility functions
    +#
    +# Copyright (C) 1999-2015
    +# Red Hat, Inc.  All rights reserved.
    +#
    +# This program is free software; you can redistribute it and/or modify
    +# it under the terms of the GNU General Public License as published by
    +# the Free Software Foundation; either version 2 of the License, or
    +# (at your option) any later version.
    +#
    +# This program is distributed in the hope that it will be useful,
    +# but WITHOUT ANY WARRANTY; without even the implied warranty of
    +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    +# GNU General Public License for more details.
    +#
    +# You should have received a copy of the GNU General Public License
    +# along with this program.  If not, see <http://www.gnu.org/licenses/>.
    +#
    +
    +import os
    +import subprocess
    +from subprocess import TimeoutExpired
    +import signal
    +
    +import logging
    +log = logging.getLogger("pylorax")
    +program_log = logging.getLogger("program")
    +
    +from threading import Lock
    +program_log_lock = Lock()
    +
    +_child_env = {}
    +
    +
    [docs]def setenv(name, value): + """ Set an environment variable to be used by child processes. + + This method does not modify os.environ for the running process, which + is not thread-safe. If setenv has already been called for a particular + variable name, the old value is overwritten. + + :param str name: The name of the environment variable + :param str value: The value of the environment variable + """ + + _child_env[name] = value
    + +
    [docs]def augmentEnv(): + env = os.environ.copy() + env.update(_child_env) + return env
    + +
    [docs]class ExecProduct(object): + def __init__(self, rc, stdout, stderr): + self.rc = rc + self.stdout = stdout + self.stderr = stderr
    + +
    [docs]def startProgram(argv, root='/', stdin=None, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, + env_prune=None, env_add=None, reset_handlers=True, reset_lang=True, **kwargs): + """ Start an external program and return the Popen object. + + The root and reset_handlers arguments are handled by passing a + preexec_fn argument to subprocess.Popen, but an additional preexec_fn + can still be specified and will be run. The user preexec_fn will be run + last. + + :param argv: The command to run and argument + :param root: The directory to chroot to before running command. + :param stdin: The file object to read stdin from. + :param stdout: The file object to write stdout to. + :param stderr: The file object to write stderr to. + :param env_prune: environment variables to remove before execution + :param env_add: environment variables to add before execution + :param reset_handlers: whether to reset to SIG_DFL any signal handlers set to SIG_IGN + :param reset_lang: whether to set the locale of the child process to C + :param kwargs: Additional parameters to pass to subprocess.Popen + :return: A Popen object for the running command. + :keyword preexec_fn: A function to run before execution starts. + """ + if env_prune is None: + env_prune = [] + + # Check for and save a preexec_fn argument + preexec_fn = kwargs.pop("preexec_fn", None) + + def preexec(): + # If a target root was specificed, chroot into it + if root and root != '/': + os.chroot(root) + os.chdir("/") + + # Signal handlers set to SIG_IGN persist across exec. Reset + # these to SIG_DFL if requested. In particular this will include the + # SIGPIPE handler set by python. + if reset_handlers: + for signum in range(1, signal.NSIG): + if signal.getsignal(signum) == signal.SIG_IGN: + signal.signal(signum, signal.SIG_DFL) + + # If the user specified an additional preexec_fn argument, run it + if preexec_fn is not None: + preexec_fn() + + with program_log_lock: + program_log.info("Running... %s", " ".join(argv)) + + env = augmentEnv() + for var in env_prune: + env.pop(var, None) + + if reset_lang: + env.update({"LC_ALL": "C"}) + + if env_add: + env.update(env_add) + + return subprocess.Popen(argv, + stdin=stdin, + stdout=stdout, + stderr=stderr, + close_fds=True, + preexec_fn=preexec, cwd=root, env=env, **kwargs)
    + +def _run_program(argv, root='/', stdin=None, stdout=None, env_prune=None, log_output=True, + binary_output=False, filter_stderr=False, raise_err=False, callback=None, + env_add=None, reset_handlers=True, reset_lang=True): + """ Run an external program, log the output and return it to the caller + + :param argv: The command to run and argument + :param root: The directory to chroot to before running command. + :param stdin: The file object to read stdin from. + :param stdout: Optional file object to write the output to. + :param env_prune: environment variable to remove before execution + :param log_output: whether to log the output of command + :param binary_output: whether to treat the output of command as binary data + :param filter_stderr: whether to exclude the contents of stderr from the returned output + :param raise_err: whether to raise a CalledProcessError if the returncode is non-zero + :param callback: method to call while waiting for process to finish, passed Popen object + :param env_add: environment variables to add before execution + :param reset_handlers: whether to reset to SIG_DFL any signal handlers set to SIG_IGN + :param reset_lang: whether to set the locale of the child process to C + :return: The return code of the command and the output + :raises: OSError or CalledProcessError + """ + try: + if filter_stderr: + stderr = subprocess.PIPE + else: + stderr = subprocess.STDOUT + + proc = startProgram(argv, root=root, stdin=stdin, stdout=subprocess.PIPE, stderr=stderr, + env_prune=env_prune, universal_newlines=not binary_output, + env_add=env_add, reset_handlers=reset_handlers, reset_lang=reset_lang) + + output_string = None + err_string = None + if callback: + while callback(proc) and proc.poll() is None: + try: + (output_string, err_string) = proc.communicate(timeout=1) + break + except TimeoutExpired: + pass + else: + (output_string, err_string) = proc.communicate() + if output_string: + if binary_output: + output_lines = [output_string] + else: + if output_string[-1] != "\n": + output_string = output_string + "\n" + output_lines = output_string.splitlines(True) + + if log_output: + with program_log_lock: + for line in output_lines: + program_log.info(line.strip()) + + if stdout: + stdout.write(output_string) + + # If stderr was filtered, log it separately + if filter_stderr and err_string and log_output: + err_lines = err_string.splitlines(True) + + with program_log_lock: + for line in err_lines: + program_log.info(line.strip()) + + except OSError as e: + with program_log_lock: + program_log.error("Error running %s: %s", argv[0], e.strerror) + raise + + with program_log_lock: + program_log.debug("Return code: %s", proc.returncode) + + if proc.returncode and raise_err: + output = (output_string or "") + (err_string or "") + raise subprocess.CalledProcessError(proc.returncode, argv, output) + + return (proc.returncode, output_string) + +
    [docs]def execWithRedirect(command, argv, stdin=None, stdout=None, root='/', env_prune=None, + log_output=True, binary_output=False, raise_err=False, callback=None, + env_add=None, reset_handlers=True, reset_lang=True): + """ Run an external program and redirect the output to a file. + + :param command: The command to run + :param argv: The argument list + :param stdin: The file object to read stdin from. + :param stdout: Optional file object to redirect stdout and stderr to. + :param root: The directory to chroot to before running command. + :param env_prune: environment variable to remove before execution + :param log_output: whether to log the output of command + :param binary_output: whether to treat the output of command as binary data + :param raise_err: whether to raise a CalledProcessError if the returncode is non-zero + :param callback: method to call while waiting for process to finish, passed Popen object + :param env_add: environment variables to add before execution + :param reset_handlers: whether to reset to SIG_DFL any signal handlers set to SIG_IGN + :param reset_lang: whether to set the locale of the child process to C + :return: The return code of the command + """ + argv = [command] + list(argv) + return _run_program(argv, stdin=stdin, stdout=stdout, root=root, env_prune=env_prune, + log_output=log_output, binary_output=binary_output, raise_err=raise_err, callback=callback, + env_add=env_add, reset_handlers=reset_handlers, reset_lang=reset_lang)[0]
    + +
    [docs]def execWithCapture(command, argv, stdin=None, root='/', log_output=True, filter_stderr=False, + raise_err=False, callback=None, env_add=None, reset_handlers=True, reset_lang=True): + """ Run an external program and capture standard out and err. + + :param command: The command to run + :param argv: The argument list + :param stdin: The file object to read stdin from. + :param root: The directory to chroot to before running command. + :param log_output: Whether to log the output of command + :param filter_stderr: Whether stderr should be excluded from the returned output + :param callback: method to call while waiting for process to finish, passed Popen object + :param env_add: environment variables to add before execution + :param reset_handlers: whether to reset to SIG_DFL any signal handlers set to SIG_IGN + :param reset_lang: whether to set the locale of the child process to C + :return: The output of the command + """ + argv = [command] + list(argv) + return _run_program(argv, stdin=stdin, root=root, log_output=log_output, filter_stderr=filter_stderr, + raise_err=raise_err, callback=callback, env_add=env_add, + reset_handlers=reset_handlers, reset_lang=reset_lang)[1]
    + +
    [docs]def execReadlines(command, argv, stdin=None, root='/', env_prune=None, filter_stderr=False, + callback=lambda x: True, env_add=None, reset_handlers=True, reset_lang=True): + """ Execute an external command and return the line output of the command + in real-time. + + This method assumes that there is a reasonably low delay between the + end of output and the process exiting. If the child process closes + stdout and then keeps on truckin' there will be problems. + + NOTE/WARNING: UnicodeDecodeError will be raised if the output of the + external command can't be decoded as UTF-8. + + :param command: The command to run + :param argv: The argument list + :param stdin: The file object to read stdin from. + :param stdout: Optional file object to redirect stdout and stderr to. + :param root: The directory to chroot to before running command. + :param env_prune: environment variable to remove before execution + :param filter_stderr: Whether stderr should be excluded from the returned output + :param callback: method to call while waiting for process to finish, passed Popen object + :param env_add: environment variables to add before execution + :param reset_handlers: whether to reset to SIG_DFL any signal handlers set to SIG_IGN + :param reset_lang: whether to set the locale of the child process to C + :return: Iterator of the lines from the command + + Output from the file is not logged to program.log + This returns an iterator with the lines from the command until it has finished + """ + + class ExecLineReader(object): + """Iterator class for returning lines from a process and cleaning + up the process when the output is no longer needed. + """ + + def __init__(self, proc, argv, callback): + self._proc = proc + self._argv = argv + self._callback = callback + + def __iter__(self): + return self + + def __del__(self): + # See if the process is still running + if self._proc.poll() is None: + # Stop the process and ignore any problems that might arise + try: + self._proc.terminate() + except OSError: + pass + + def __next__(self): + # Read the next line, blocking if a line is not yet available + line = self._proc.stdout.readline().decode("utf-8") + if line == '' or not self._callback(self._proc): + # Output finished, wait for the process to end + self._proc.communicate() + + # Check for successful exit + if self._proc.returncode < 0: + raise OSError("process '%s' was killed by signal %s" % + (self._argv, -self._proc.returncode)) + elif self._proc.returncode > 0: + raise OSError("process '%s' exited with status %s" % + (self._argv, self._proc.returncode)) + raise StopIteration + + return line.strip() + + argv = [command] + argv + + if filter_stderr: + stderr = subprocess.DEVNULL + else: + stderr = subprocess.STDOUT + + try: + proc = startProgram(argv, root=root, stdin=stdin, stdout=subprocess.PIPE, stderr=stderr, bufsize=1, + env_prune=env_prune, env_add=env_add, reset_handlers=reset_handlers, reset_lang=reset_lang) + except OSError as e: + with program_log_lock: + program_log.error("Error running %s: %s", argv[0], e.strerror) + raise + + return ExecLineReader(proc, argv, callback)
    + +
    [docs]def runcmd(cmd, **kwargs): + """ run execWithRedirect with raise_err=True + """ + kwargs["raise_err"] = True + return execWithRedirect(cmd[0], cmd[1:], **kwargs)
    + +
    [docs]def runcmd_output(cmd, **kwargs): + """ run execWithCapture with raise_err=True + """ + kwargs["raise_err"] = True + return execWithCapture(cmd[0], cmd[1:], **kwargs)
    +
    + +
    + +
    +
    + + +
    + +
    +

    + © Copyright 2018-2019, Red Hat, Inc. + +

    +
    + Built with Sphinx using a theme provided by Read the Docs. + +
    + +
    +
    + +
    + +
    + + + + + + + + + + + + \ No newline at end of file diff --git a/rhel8-branch/_modules/pylorax/imgutils.html b/rhel8-branch/_modules/pylorax/imgutils.html new file mode 100644 index 00000000..50240b16 --- /dev/null +++ b/rhel8-branch/_modules/pylorax/imgutils.html @@ -0,0 +1,720 @@ + + + + + + + + + + + pylorax.imgutils — Lorax 28.14.33 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + + + +
    + + + + + +
    + +
    + + + + + + + + + + + + + + + + + +
    + + + + +
    +
    +
    +
    + +

    Source code for pylorax.imgutils

    +# imgutils.py - utility functions/classes for building disk images
    +#
    +# Copyright (C) 2011-2015 Red Hat, Inc.
    +#
    +# This program is free software; you can redistribute it and/or modify
    +# it under the terms of the GNU General Public License as published by
    +# the Free Software Foundation; either version 2 of the License, or
    +# (at your option) any later version.
    +#
    +# This program is distributed in the hope that it will be useful,
    +# but WITHOUT ANY WARRANTY; without even the implied warranty of
    +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    +# GNU General Public License for more details.
    +#
    +# You should have received a copy of the GNU General Public License
    +# along with this program.  If not, see <http://www.gnu.org/licenses/>.
    +#
    +# Author(s):  Will Woods <wwoods@redhat.com>
    +
    +import logging
    +logger = logging.getLogger("pylorax.imgutils")
    +
    +import os, tempfile
    +from os.path import join, dirname
    +from subprocess import Popen, PIPE, CalledProcessError
    +import sys
    +import time
    +import traceback
    +import multiprocessing
    +from time import sleep
    +import shutil
    +
    +from pylorax.sysutils import cpfile
    +from pylorax.executils import execWithRedirect, execWithCapture
    +from pylorax.executils import runcmd, runcmd_output
    +
    +######## Functions for making container images (cpio, tar, squashfs) ##########
    +
    +
    [docs]def compress(command, root, outfile, compression="xz", compressargs=None): + '''Make a compressed archive of the given rootdir or file. + command is a list of the archiver commands to run + compression should be "xz", "gzip", "lzma", "bzip2", or None. + compressargs will be used on the compression commandline.''' + if compression not in (None, "xz", "gzip", "lzma", "bzip2"): + raise ValueError("Unknown compression type %s" % compression) + compressargs = compressargs or ["-9"] + if compression == "xz": + compressargs.insert(0, "--check=crc32") + if compression is None: + compression = "cat" # this is a little silly + compressargs = [] + + # make compression run with multiple threads if possible + if compression in ("xz", "lzma"): + compressargs.insert(0, "-T%d" % multiprocessing.cpu_count()) + elif compression == "gzip": + compression = "pigz" + compressargs.insert(0, "-p%d" % multiprocessing.cpu_count()) + elif compression == "bzip2": + compression = "pbzip2" + compressargs.insert(0, "-p%d" % multiprocessing.cpu_count()) + + find, archive, comp = None, None, None + + try: + if os.path.isdir(root): + logger.debug("find %s -print0 |%s | %s %s > %s", root, " ".join(command), + compression, " ".join(compressargs), outfile) + + find = Popen(["find", ".", "-print0"], stdout=PIPE, cwd=root) + archive = Popen(command, stdin=find.stdout, stdout=PIPE, cwd=root) + else: + logger.debug("echo %s |%s | %s %s > %s", root, " ".join(command), + compression, " ".join(compressargs), outfile) + + archive = Popen(command, stdin=PIPE, stdout=PIPE, cwd=os.path.dirname(root)) + archive.stdin.write(os.path.basename(root).encode("utf-8") + b"\0") + archive.stdin.close() + + comp = Popen([compression] + compressargs, + stdin=archive.stdout, stdout=open(outfile, "wb")) + comp.wait() + return comp.returncode + except OSError as e: + logger.error(e) + # Kill off any hanging processes + list(p.kill() for p in (find, archive, comp) if p) + return 1
    + +
    [docs]def mkcpio(root, outfile, compression="xz", compressargs=None): + compressargs = compressargs or ["-9"] + return compress(["cpio", "--null", "--quiet", "-H", "newc", "-o"], + root, outfile, compression, compressargs)
    + +
    [docs]def mktar(root, outfile, compression="xz", compressargs=None, selinux=True): + compressargs = compressargs or ["-9"] + tar_cmd = ["tar", "--no-recursion"] + if selinux: + tar_cmd += ["--selinux", "--acls", "--xattrs"] + tar_cmd += ["-cf-", "--null", "-T-"] + return compress(tar_cmd, root, outfile, compression, compressargs)
    + +
    [docs]def mksquashfs(rootdir, outfile, compression="default", compressargs=None): + '''Make a squashfs image containing the given rootdir.''' + compressargs = compressargs or [] + if compression != "default": + compressargs = ["-comp", compression] + compressargs + return execWithRedirect("mksquashfs", [rootdir, outfile] + compressargs)
    + +
    [docs]def mkrootfsimg(rootdir, outfile, label, size=2, sysroot=""): + """ + Make rootfs image from a directory + + :param str rootdir: Root directory + :param str outfile: Path of output image file + :param str label: Filesystem label + :param int size: Size of the image in GiB, if None computed automatically + :param str sysroot: path to system (deployment) root relative to physical root + """ + if size: + fssize = size * (1024*1024*1024) # 2GB sparse file compresses down to nothin' + else: + fssize = None # Let mkext4img figure out the needed size + + mkext4img(rootdir, outfile, label=label, size=fssize)
    + + +######## Utility functions ############################################### + +
    [docs]def mksparse(outfile, size): + '''use os.ftruncate to create a sparse file of the given size.''' + fobj = open(outfile, "w") + os.ftruncate(fobj.fileno(), size)
    + +
    [docs]def mkqcow2(outfile, size, options=None): + '''use qemu-img to create a file of the given size. + options is a list of options passed to qemu-img + + Default format is qcow2, override by passing "-f", fmt + in options. + ''' + mkqemu_img(outfile, size, options)
    + +
    [docs]def mkqemu_img(outfile, size, options=None): + '''use qemu-img to create a file of the given size. + options is a list of options passed to qemu-img + + Default format is qcow2, override by passing "-f", fmt + in options. + ''' + options = options or [] + if "-f" not in options: + options.extend(["-f", "qcow2"]) + runcmd(["qemu-img", "create"] + options + [outfile, str(size)])
    + +
    [docs]def loop_waitfor(loop_dev, outfile): + """Make sure the loop device is attached to the outfile. + + It seems that on rare occasions losetup can return before the /dev/loopX is + ready for use, causing problems with mkfs. This tries to make sure that the + loop device really is associated with the backing file before continuing. + + Raise RuntimeError if it isn't setup after 5 tries. + """ + for _x in range(0,5): + runcmd(["udevadm", "settle", "--timeout", "300"]) + ## XXX Note that losetup --list output can be truncated to 64 bytes in some + ## situations. Don't use it to lookup backing file, go the other way + ## and lookup the loop for the backing file. See util-linux lib/loopdev.c + ## loopcxt_get_backing_file() + if get_loop_name(outfile) == os.path.basename(loop_dev): + return + + # If this really is a race, give it some time to settle down + time.sleep(1) + + raise RuntimeError("Unable to setup %s on %s" % (loop_dev, outfile))
    + +
    [docs]def loop_attach(outfile): + '''Attach a loop device to the given file. Return the loop device name. + Raises CalledProcessError if losetup fails.''' + dev = runcmd_output(["losetup", "--find", "--show", outfile]) + + # Sometimes the loop device isn't ready yet, make extra sure before returning + loop_waitfor(dev.strip(), outfile) + return dev.strip()
    + +
    [docs]def loop_detach(loopdev): + '''Detach the given loop device. Return False on failure.''' + return (execWithRedirect("losetup", ["--detach", loopdev]) == 0)
    + +
    [docs]def get_loop_name(path): + '''Return the loop device associated with the path. + Raises RuntimeError if more than one loop is associated''' + buf = runcmd_output(["losetup", "-j", path]) + if len(buf.splitlines()) > 1: + # there should never be more than one loop device listed + raise RuntimeError("multiple loops associated with %s" % path) + name = os.path.basename(buf.split(":")[0]) + return name
    + +
    [docs]def dm_attach(dev, size, name=None): + '''Attach a devicemapper device to the given device, with the given size. + If name is None, a random name will be chosen. Returns the device name. + raises CalledProcessError if dmsetup fails.''' + if name is None: + name = tempfile.mktemp(prefix="lorax.imgutils.", dir="") + runcmd(["dmsetup", "create", name, "--table", + "0 %i linear %s 0" % (size/512, dev)]) + return name
    + +
    [docs]def dm_detach(dev): + '''Detach the named devicemapper device. Returns False if dmsetup fails.''' + dev = dev.replace("/dev/mapper/", "") # strip prefix, if it's there + return execWithRedirect("dmsetup", ["remove", dev])
    + +
    [docs]def mount(dev, opts="", mnt=None): + '''Mount the given device at the given mountpoint, using the given opts. + opts should be a comma-separated string of mount options. + if mnt is none, a temporary directory will be created and its path will be + returned. + raises CalledProcessError if mount fails.''' + if mnt is None: + mnt = tempfile.mkdtemp(prefix="lorax.imgutils.") + logger.debug("make tmp mountdir %s", mnt) + cmd = ["mount"] + if opts: + cmd += ["-o", opts] + cmd += [dev, mnt] + runcmd(cmd) + return mnt
    + +
    [docs]def umount(mnt, lazy=False, maxretry=3, retrysleep=1.0, delete=True): + '''Unmount the given mountpoint. If lazy is True, do a lazy umount (-l). + If the mount was a temporary dir created by mount, it will be deleted. + raises CalledProcessError if umount fails.''' + cmd = ["umount"] + if lazy: cmd += ["-l"] + cmd += [mnt] + count = 0 + while maxretry > 0: + try: + rv = runcmd(cmd) + except CalledProcessError: + count += 1 + if count == maxretry: + raise + logger.warning("failed to unmount %s. retrying (%d/%d)...", + mnt, count, maxretry) + if logger.getEffectiveLevel() <= logging.DEBUG: + fuser = execWithCapture("fuser", ["-vm", mnt]) + logger.debug("fuser -vm:\n%s\n", fuser) + sleep(retrysleep) + else: + break + if delete and 'lorax.imgutils' in mnt: + os.rmdir(mnt) + logger.debug("remove tmp mountdir %s", mnt) + return (rv == 0)
    + +
    [docs]def copytree(src, dest, preserve=True): + '''Copy a tree of files using cp -a, thus preserving modes, timestamps, + links, acls, sparse files, xattrs, selinux contexts, etc. + If preserve is False, uses cp -R (useful for modeless filesystems) + raises CalledProcessError if copy fails.''' + logger.debug("copytree %s %s", src, dest) + cp = ["cp", "-a"] if preserve else ["cp", "-R", "-L"] + cp += [join(src, "."), os.path.abspath(dest)] + runcmd(cp)
    + +
    [docs]def do_grafts(grafts, dest, preserve=True): + '''Copy each of the items listed in grafts into dest. + If the key ends with '/' it's assumed to be a directory which should be + created, otherwise just the leading directories will be created.''' + for imgpath, filename in grafts.items(): + if imgpath[-1] == '/': + targetdir = join(dest, imgpath) + imgpath = imgpath[:-1] + else: + targetdir = join(dest, dirname(imgpath)) + if not os.path.isdir(targetdir): + os.makedirs(targetdir) + if os.path.isdir(filename): + copytree(filename, join(dest, imgpath), preserve) + else: + cpfile(filename, join(dest, imgpath))
    + +
    [docs]def round_to_blocks(size, blocksize): + '''If size isn't a multiple of blocksize, round up to the next multiple''' + diff = size % blocksize + if diff or not size: + size += blocksize - diff + return size
    + +# TODO: move filesystem data outside this function +
    [docs]def estimate_size(rootdir, graft=None, fstype=None, blocksize=4096, overhead=256): + graft = graft or {} + getsize = lambda f: os.lstat(f).st_size + if fstype == "btrfs": + overhead = 64*1024 # don't worry, it's all sparse + if fstype == "hfsplus": + overhead = 200 # hack to deal with two bootloader copies + if fstype in ("vfat", "msdos"): + blocksize = 2048 + getsize = lambda f: os.stat(f).st_size # no symlinks, count as copies + total = overhead*blocksize + dirlist = list(graft.values()) + if rootdir: + dirlist.append(rootdir) + for root in dirlist: + for top, dirs, files in os.walk(root): + for f in files + dirs: + total += round_to_blocks(getsize(join(top,f)), blocksize) + if fstype == "btrfs": + total = max(256*1024*1024, total) # btrfs minimum size: 256MB + logger.info("Size of %s block %s fs at %s estimated to be %s", blocksize, fstype, rootdir, total) + return total
    + +######## Execution contexts - use with the 'with' statement ############## + +
    [docs]class LoopDev(object): + def __init__(self, filename, size=None): + self.loopdev = None + self.filename = filename + if size: + mksparse(self.filename, size) + def __enter__(self): + self.loopdev = loop_attach(self.filename) + return self.loopdev + def __exit__(self, exc_type, exc_value, tracebk): + loop_detach(self.loopdev)
    + +
    [docs]class DMDev(object): + def __init__(self, dev, size, name=None): + self.mapperdev = None + (self.dev, self.size, self.name) = (dev, size, name) + def __enter__(self): + self.mapperdev = dm_attach(self.dev, self.size, self.name) + return self.mapperdev + def __exit__(self, exc_type, exc_value, tracebk): + dm_detach(self.mapperdev)
    + +
    [docs]class Mount(object): + def __init__(self, dev, opts="", mnt=None): + (self.dev, self.opts, self.mnt) = (dev, opts, mnt) + def __enter__(self): + self.mnt = mount(self.dev, self.opts, self.mnt) + return self.mnt + def __exit__(self, exc_type, exc_value, tracebk): + umount(self.mnt)
    + +
    [docs]class PartitionMount(object): + """ Mount a partitioned image file using kpartx """ + def __init__(self, disk_img, mount_ok=None, submount=None): + """ + :param str disk_img: The full path to a partitioned disk image + :param mount_ok: A function that is passed the mount point and + returns True if it should be mounted. + :param str submount: Directory inside mount_dir to mount at + + If mount_ok is not set it will look for /etc/passwd + + If the partition is found it will be mounted under a temporary + directory and self.temp_dir set to it. If submount is passed it will be + created and mounted there instead, with self.mount_dir set to point to + it. self.mount_dev is set to the loop device, and self.mount_size is + set to the size of the partition. + + When no subdir is passed self.temp_dir and self.mount_dir will be the same. + """ + self.mount_dev = None + self.mount_size = None + self.mount_dir = None + self.disk_img = disk_img + self.mount_ok = mount_ok + self.submount = submount + self.temp_dir = None + + # Default is to mount partition with /etc/passwd + if not self.mount_ok: + self.mount_ok = lambda mount_dir: os.path.isfile(mount_dir+"/etc/passwd") + + # Example kpartx output + # kpartx -p p -v -a /tmp/diskV2DiCW.im + # add map loop2p1 (253:2): 0 3481600 linear /dev/loop2 2048 + # add map loop2p2 (253:3): 0 614400 linear /dev/loop2 3483648 + kpartx_output = runcmd_output(["kpartx", "-v", "-a", "-s", self.disk_img]) + logger.debug(kpartx_output) + + # list of (deviceName, sizeInBytes) + self.loop_devices = [] + for line in kpartx_output.splitlines(): + # add map loop2p3 (253:4): 0 7139328 linear /dev/loop2 528384 + # 3rd element is size in 512 byte blocks + if line.startswith("add map "): + fields = line[8:].split() + self.loop_devices.append( (fields[0], int(fields[3])*512) ) + + def __enter__(self): + # Mount the device selected by mount_ok, if possible + self.temp_dir = tempfile.mkdtemp() + if self.submount: + mount_dir = os.path.normpath(os.path.sep.join([self.temp_dir, self.submount])) + os.makedirs(mount_dir, mode=0o755, exist_ok=True) + else: + mount_dir = self.temp_dir + for dev, size in self.loop_devices: + try: + mount( "/dev/mapper/"+dev, mnt=mount_dir ) + if self.mount_ok(mount_dir): + self.mount_dir = mount_dir + self.mount_dev = dev + self.mount_size = size + break + umount( mount_dir ) + except CalledProcessError: + logger.debug(traceback.format_exc()) + if self.mount_dir: + logger.info("Partition mounted on %s size=%s", self.mount_dir, self.mount_size) + else: + logger.debug("Unable to mount anything from %s", self.disk_img) + os.rmdir(self.temp_dir) + self.temp_dir = None + return self + + def __exit__(self, exc_type, exc_value, tracebk): + if self.temp_dir: + umount(self.mount_dir) + shutil.rmtree(self.temp_dir) + self.mount_dir = None + self.temp_dir = None + execWithRedirect("kpartx", ["-d", "-s", self.disk_img])
    + + +######## Functions for making filesystem images ########################## + +
    [docs]def mkfsimage(fstype, rootdir, outfile, size=None, mkfsargs=None, mountargs="", graft=None): + '''Generic filesystem image creation function. + fstype should be a filesystem type - "mkfs.${fstype}" must exist. + graft should be a dict: {"some/path/in/image": "local/file/or/dir"}; + if the path ends with a '/' it's assumed to be a directory. + Will raise CalledProcessError if something goes wrong.''' + mkfsargs = mkfsargs or [] + graft = graft or {} + preserve = (fstype not in ("msdos", "vfat")) + if not size: + size = estimate_size(rootdir, graft, fstype) + with LoopDev(outfile, size) as loopdev: + try: + runcmd(["mkfs.%s" % fstype] + mkfsargs + [loopdev]) + except CalledProcessError as e: + logger.error("mkfs exited with a non-zero return code: %d", e.returncode) + logger.error(e.output) + sys.exit(e.returncode) + + with Mount(loopdev, mountargs) as mnt: + if rootdir: + copytree(rootdir, mnt, preserve) + do_grafts(graft, mnt, preserve) + + # Save information about filesystem usage + execWithRedirect("df", [mnt]) + + # Make absolutely sure that the data has been written + runcmd(["sync"])
    + +# convenience functions with useful defaults +
    [docs]def mkdosimg(rootdir, outfile, size=None, label="", mountargs="shortname=winnt,umask=0077", graft=None): + graft = graft or {} + mkfsimage("msdos", rootdir, outfile, size, mountargs=mountargs, + mkfsargs=["-n", label], graft=graft)
    + +
    [docs]def mkext4img(rootdir, outfile, size=None, label="", mountargs="", graft=None): + graft = graft or {} + mkfsimage("ext4", rootdir, outfile, size, mountargs=mountargs, + mkfsargs=["-L", label, "-b", "4096", "-m", "0"], graft=graft)
    + +
    [docs]def mkbtrfsimg(rootdir, outfile, size=None, label="", mountargs="", graft=None): + graft = graft or {} + mkfsimage("btrfs", rootdir, outfile, size, mountargs=mountargs, + mkfsargs=["-L", label], graft=graft)
    + +
    [docs]def mkhfsimg(rootdir, outfile, size=None, label="", mountargs="", graft=None): + graft = graft or {} + mkfsimage("hfsplus", rootdir, outfile, size, mountargs=mountargs, + mkfsargs=["-v", label], graft=graft)
    + +
    [docs]def mkfsimage_from_disk(diskimage, fsimage, img_size=None, label="Anaconda"): + """ + Copy the / partition of a partitioned disk image to an un-partitioned + disk image. + + :param str diskimage: The full path to partitioned disk image with a / + :param str fsimage: The full path of the output fs image file + :param int img_size: Optional size of the fsimage in MiB or None to make + it as small as possible + :param str label: The label to apply to the image. Defaults to "Anaconda" + """ + with PartitionMount(diskimage) as img_mount: + if not img_mount or not img_mount.mount_dir: + return None + + logger.info("Creating fsimage %s (%s)", fsimage, img_size or "minimized") + if img_size: + # convert to Bytes + img_size *= 1024**2 + + mkext4img(img_mount.mount_dir, fsimage, size=img_size, label=label)
    + +
    [docs]def default_image_name(compression, basename): + """ Return a default image name with the correct suffix for the compression type. + + :param str compression: Compression type + :param str basename: Base filename + :returns: basename with compression suffix + + If the compression is unknown it defaults to xz + """ + SUFFIXES = {"xz": ".xz", "gzip": ".gz", "bzip2": ".bz2", "lzma": ".lzma"} + return basename + SUFFIXES.get(compression, ".xz")
    +
    + +
    + +
    +
    + + +
    + +
    +

    + © Copyright 2018-2019, Red Hat, Inc. + +

    +
    + Built with Sphinx using a theme provided by Read the Docs. + +
    + +
    +
    + +
    + +
    + + + + + + + + + + + + \ No newline at end of file diff --git a/rhel8-branch/_modules/pylorax/installer.html b/rhel8-branch/_modules/pylorax/installer.html new file mode 100644 index 00000000..fce65b11 --- /dev/null +++ b/rhel8-branch/_modules/pylorax/installer.html @@ -0,0 +1,860 @@ + + + + + + + + + + + pylorax.installer — Lorax 28.14.33 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + + + +
    + + + + + +
    + +
    + + + + + + + + + + + + + + + + + +
    + + + + +
    +
    +
    +
    + +

    Source code for pylorax.installer

    +#
    +# Copyright (C) 2011-2018  Red Hat, Inc.
    +#
    +# This program is free software; you can redistribute it and/or modify
    +# it under the terms of the GNU General Public License as published by
    +# the Free Software Foundation; either version 2 of the License, or
    +# (at your option) any later version.
    +#
    +# This program is distributed in the hope that it will be useful,
    +# but WITHOUT ANY WARRANTY; without even the implied warranty of
    +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    +# GNU General Public License for more details.
    +#
    +# You should have received a copy of the GNU General Public License
    +# along with this program.  If not, see <http://www.gnu.org/licenses/>.
    +#
    +import logging
    +log = logging.getLogger("pylorax")
    +
    +import glob
    +import json
    +from math import ceil
    +import os
    +import subprocess
    +import shutil
    +import socket
    +import tempfile
    +
    +# Use the Lorax treebuilder branch for iso creation
    +from pylorax.executils import execWithRedirect, execReadlines
    +from pylorax.imgutils import PartitionMount, mksparse, mkext4img, loop_detach
    +from pylorax.imgutils import get_loop_name, dm_detach, mount, umount
    +from pylorax.imgutils import mkqemu_img, mktar, mkcpio, mkfsimage_from_disk
    +from pylorax.monitor import LogMonitor
    +from pylorax.mount import IsoMountpoint
    +from pylorax.sysutils import joinpaths
    +from pylorax.treebuilder import udev_escape
    +
    +
    +ROOT_PATH = "/mnt/sysimage/"
    +
    +
    [docs]class InstallError(Exception): + pass
    + + +
    [docs]def create_vagrant_metadata(path, size=0): + """ Create a default Vagrant metadata.json file + + :param str path: Path to metadata.json file + :param int size: Disk size in MiB + """ + metadata = { "provider":"libvirt", "format":"qcow2", "virtual_size": ceil(size / 1024) } + with open(path, "wt") as f: + json.dump(metadata, f, indent=4)
    + + +
    [docs]def update_vagrant_metadata(path, size): + """ Update the Vagrant metadata.json file + + :param str path: Path to metadata.json file + :param int size: Disk size in MiB + + This function makes sure that the provider, format and virtual size of the + metadata file are set correctly. All other values are left untouched. + """ + with open(path, "rt") as f: + try: + metadata = json.load(f) + except ValueError as e: + log.error("Problem reading metadata file %s: %s", path, e) + return + + metadata["provider"] = "libvirt" + metadata["format"] = "qcow2" + metadata["virtual_size"] = ceil(size / 1024) + with open(path, "wt") as f: + json.dump(metadata, f, indent=4)
    + + +
    [docs]def find_free_port(start=5900, end=5999, host="127.0.0.1"): + """ Return first free port in range. + + :param int start: Starting port number + :param int end: Ending port number + :param str host: Host IP to search + :returns: First free port or -1 if none found + :rtype: int + """ + s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + for port in range(start, end+1): + try: + s.bind((host, port)) + s.close() + return port + except OSError: + pass + + return -1
    + +
    [docs]def append_initrd(initrd, files): + """ Append files to an initrd. + + :param str initrd: Path to initrd + :param list files: list of file paths to add + :returns: Path to a new initrd + :rtype: str + + The files are added to the initrd by creating a cpio image + of the files (stored at /) and writing the cpio to the end of a + copy of the initrd. + + The initrd is not changed, a copy is made before appending the + cpio archive. + """ + qemu_initrd = tempfile.mktemp(prefix="lmc-initrd-", suffix=".img") + shutil.copy2(initrd, qemu_initrd) + ks_dir = tempfile.mkdtemp(prefix="lmc-ksdir-") + for ks in files: + shutil.copy2(ks, ks_dir) + ks_initrd = tempfile.mktemp(prefix="lmc-ks-", suffix=".img") + mkcpio(ks_dir, ks_initrd) + shutil.rmtree(ks_dir) + with open(qemu_initrd, "ab") as initrd_fp: + with open(ks_initrd, "rb") as ks_fp: + while True: + data = ks_fp.read(1024**2) + if not data: + break + initrd_fp.write(data) + os.unlink(ks_initrd) + + return qemu_initrd
    + +
    [docs]class QEMUInstall(object): + """ + Run qemu using an iso and a kickstart + """ + def __init__(self, opts, iso, ks_paths, disk_img, img_size=2048, + kernel_args=None, memory=1024, vcpus=None, vnc=None, arch=None, + cancel_func=None, virtio_host="127.0.0.1", virtio_port=6080, + image_type=None, boot_uefi=False, ovmf_path=None): + """ + Start the installation + + :param iso: Information about the iso to use for the installation + :type iso: IsoMountpoint + :param list ks_paths: Paths to kickstart files. All are injected, the + first one is the one executed. + :param str disk_img: Path to a disk image, created it it doesn't exist + :param int img_size: The image size, in MiB, to create if it doesn't exist + :param str kernel_args: Extra kernel arguments to pass on the kernel cmdline + :param int memory: Amount of RAM to assign to the virt, in MiB + :param int vcpus: Number of virtual cpus + :param str vnc: Arguments to pass to qemu -display + :param str arch: Optional architecture to use in the virt + :param cancel_func: Function that returns True if the installation fails + :type cancel_func: function + :param str virtio_host: Hostname to connect virtio log to + :param int virtio_port: Port to connect virtio log to + :param str image_type: Type of qemu-img disk to create, or None. + :param bool boot_uefi: Use OVMF to boot the VM in UEFI mode + :param str ovmf_path: Path to the OVMF firmware + """ + # RHEL8 only has /usr/libexec/qemu-kvm so we have to use that. + qemu_cmd = ["/usr/libexec/qemu-kvm"] + if not os.path.exists(qemu_cmd[0]): + raise InstallError("%s does not exist, cannot run qemu" % qemu_cmd[0]) + + qemu_cmd += ["-nodefconfig"] + qemu_cmd += ["-m", str(memory)] + if vcpus: + qemu_cmd += ["-smp", str(vcpus)] + + if not opts.no_kvm and os.path.exists("/dev/kvm"): + qemu_cmd += ["-machine", "accel=kvm"] + + if boot_uefi: + qemu_cmd += ["-machine", "q35,smm=on"] + qemu_cmd += ["-global", "driver=cfi.pflash01,property=secure,value=on"] + + # Copy the initrd from the iso, create a cpio archive of the kickstart files + # and append it to the temporary initrd. + qemu_initrd = append_initrd(iso.initrd, ks_paths) + qemu_cmd += ["-kernel", iso.kernel] + qemu_cmd += ["-initrd", qemu_initrd] + + # Add the disk and cdrom + if not os.path.isfile(disk_img): + mksparse(disk_img, img_size * 1024**2) + drive_args = "file=%s" % disk_img + drive_args += ",cache=unsafe,discard=unmap" + if image_type: + drive_args += ",format=%s" % image_type + else: + drive_args += ",format=raw" + qemu_cmd += ["-drive", drive_args] + + drive_args = "file=%s,media=cdrom,readonly=on" % iso.iso_path + qemu_cmd += ["-drive", drive_args] + + # Setup the cmdline args + # ====================== + cmdline_args = "ks=file:/%s" % os.path.basename(ks_paths[0]) + cmdline_args += " inst.stage2=hd:LABEL=%s" % udev_escape(iso.label) + if opts.proxy: + cmdline_args += " inst.proxy=%s" % opts.proxy + if kernel_args: + cmdline_args += " "+kernel_args + cmdline_args += " inst.text inst.cmdline" + + qemu_cmd += ["-append", cmdline_args] + + if not opts.vnc: + vnc_port = find_free_port() + if vnc_port == -1: + raise InstallError("No free VNC ports") + display_args = "vnc=127.0.0.1:%d" % (vnc_port - 5900) + else: + display_args = opts.vnc + log.info("qemu %s", display_args) + qemu_cmd += ["-nographic", "-monitor", "none", "-serial", "null", "-display", display_args ] + + # Setup virtio networking + qemu_cmd += ["-netdev", "user,id=n1", "-device", "virtio-net-pci,netdev=n1"] + + # Setup the virtio log port + qemu_cmd += ["-device", "virtio-serial-pci,id=virtio-serial0"] + qemu_cmd += ["-device", "virtserialport,bus=virtio-serial0.0,nr=1,chardev=charchannel0" + ",id=channel0,name=org.fedoraproject.anaconda.log.0"] + qemu_cmd += ["-chardev", "socket,id=charchannel0,host=%s,port=%s" % (virtio_host, virtio_port)] + + # Pass through rng from host + if opts.with_rng != "none": + qemu_cmd += ["-object", "rng-random,id=virtio-rng0,filename=%s" % opts.with_rng] + if boot_uefi: + qemu_cmd += ["-device", "virtio-rng-pci,rng=virtio-rng0,id=rng0,bus=pcie.0,addr=0x9"] + else: + qemu_cmd += ["-device", "virtio-rng-pci,rng=virtio-rng0,id=rng0,bus=pci.0,addr=0x9"] + + if boot_uefi and ovmf_path: + qemu_cmd += ["-drive", "file=%s/OVMF_CODE.secboot.fd,if=pflash,format=raw,unit=0,readonly=on" % ovmf_path] + + # Make a copy of the OVMF_VARS.secboot.fd for this run + ovmf_vars = tempfile.mktemp(prefix="lmc-OVMF_VARS-", suffix=".fd") + shutil.copy2(joinpaths(ovmf_path, "/OVMF_VARS.secboot.fd"), ovmf_vars) + + qemu_cmd += ["-drive", "file=%s,if=pflash,format=raw,unit=1" % ovmf_vars] + + log.info("Running qemu") + log.debug(qemu_cmd) + try: + execWithRedirect(qemu_cmd[0], qemu_cmd[1:], reset_lang=False, raise_err=True, + callback=lambda p: not (cancel_func and cancel_func())) + except subprocess.CalledProcessError as e: + log.error("Running qemu failed:") + log.error("cmd: %s", " ".join(e.cmd)) + log.error("output: %s", e.output or "") + raise InstallError("QEMUInstall failed") + except (OSError, KeyboardInterrupt) as e: + log.error("Running qemu failed: %s", str(e)) + raise InstallError("QEMUInstall failed") + finally: + os.unlink(qemu_initrd) + if boot_uefi and ovmf_path: + os.unlink(ovmf_vars) + + if cancel_func and cancel_func(): + log.error("Installation error detected. See logfile for details.") + raise InstallError("QEMUInstall failed") + else: + log.info("Installation finished without errors.")
    + + +
    [docs]def novirt_cancel_check(cancel_funcs, proc): + """ + Check to see if there has been an error in the logs + + :param cancel_funcs: list of functions to call, True from any one cancels the build + :type cancel_funcs: list + :param proc: Popen object for the anaconda process + :type proc: subprocess.Popen + :returns: True if the process has been terminated + + The cancel_funcs functions should return a True if an error has been detected. + When an error is detected the process is terminated and this returns True + """ + for f in cancel_funcs: + if f(): + proc.terminate() + return True + return False
    + + +
    [docs]def anaconda_cleanup(dirinstall_path): + """ + Cleanup any leftover mounts from anaconda + + :param str dirinstall_path: Path where anaconda mounts things + :returns: True if cleanups were successful. False if any of them failed. + + If anaconda crashes it may leave things mounted under this path. It will + typically be set to /mnt/sysimage/ + + Attempts to cleanup may also fail. Catch these and continue trying the + other mountpoints. + """ + rc = True + dirinstall_path = os.path.abspath(dirinstall_path) + # unmount filesystems + for mounted in reversed(open("/proc/mounts").readlines()): + (_device, mountpoint, _rest) = mounted.split(" ", 2) + if mountpoint.startswith(dirinstall_path) and os.path.ismount(mountpoint): + try: + umount(mountpoint) + except subprocess.CalledProcessError: + log.error("Cleanup of %s failed. See program.log for details", mountpoint) + rc = False + return rc
    + + +
    [docs]def novirt_install(opts, disk_img, disk_size, cancel_func=None, tar_img=None): + """ + Use Anaconda to install to a disk image + + :param opts: options passed to livemedia-creator + :type opts: argparse options + :param str disk_img: The full path to the disk image to be created + :param int disk_size: The size of the disk_img in MiB + :param cancel_func: Function that returns True to cancel build + :type cancel_func: function + :param str tar_img: For make_tar_disk, the path to final tarball to be created + + This method runs anaconda to create the image and then based on the opts + passed creates a qemu disk image or tarfile. + """ + dirinstall_path = ROOT_PATH + + # Clean up /tmp/ from previous runs to prevent stale info from being used + for path in ["/tmp/yum.repos.d/", "/tmp/yum.cache/"]: + if os.path.isdir(path): + shutil.rmtree(path) + + args = ["--kickstart", opts.ks[0], "--cmdline", "--loglevel", "debug"] + if opts.anaconda_args: + for arg in opts.anaconda_args: + args += arg.split(" ", 1) + if opts.proxy: + args += ["--proxy", opts.proxy] + if opts.armplatform: + args += ["--armplatform", opts.armplatform] + + if opts.make_iso or opts.make_fsimage or opts.make_pxe_live: + # Make a blank fs image + args += ["--dirinstall"] + + mkext4img(None, disk_img, label=opts.fs_label, size=disk_size * 1024**2) + if not os.path.isdir(dirinstall_path): + os.mkdir(dirinstall_path) + mount(disk_img, opts="loop", mnt=dirinstall_path) + elif opts.make_tar or opts.make_oci: + # Install under dirinstall_path, make sure it starts clean + if os.path.exists(dirinstall_path): + shutil.rmtree(dirinstall_path) + + if opts.make_oci: + # OCI installs under /rootfs/ + dirinstall_path = joinpaths(dirinstall_path, "rootfs") + args += ["--dirinstall", dirinstall_path] + else: + args += ["--dirinstall"] + + os.makedirs(dirinstall_path) + else: + args += ["--image", disk_img] + + # Create the sparse image + mksparse(disk_img, disk_size * 1024**2) + + log_monitor = LogMonitor(timeout=opts.timeout) + args += ["--remotelog", "%s:%s" % (log_monitor.host, log_monitor.port)] + cancel_funcs = [log_monitor.server.log_check] + if cancel_func is not None: + cancel_funcs.append(cancel_func) + + # Make sure anaconda has the right product and release + log.info("Running anaconda.") + try: + for line in execReadlines("anaconda", args, reset_lang=False, + env_add={"ANACONDA_PRODUCTNAME": opts.project, + "ANACONDA_PRODUCTVERSION": opts.releasever}, + callback=lambda p: not novirt_cancel_check(cancel_funcs, p)): + log.info(line) + + # Make sure the new filesystem is correctly labeled + setfiles_args = ["-e", "/proc", "-e", "/sys", "-e", "/dev", + "/etc/selinux/targeted/contexts/files/file_contexts", "/"] + + if "--dirinstall" in args: + # setfiles may not be available, warn instead of fail + try: + execWithRedirect("setfiles", setfiles_args, root=dirinstall_path) + except (subprocess.CalledProcessError, OSError) as e: + log.warning("Running setfiles on install tree failed: %s", str(e)) + else: + with PartitionMount(disk_img) as img_mount: + if img_mount and img_mount.mount_dir: + try: + execWithRedirect("setfiles", setfiles_args, root=img_mount.mount_dir) + except (subprocess.CalledProcessError, OSError) as e: + log.warning("Running setfiles on install tree failed: %s", str(e)) + + # For image installs, run fstrim to discard unused blocks. This way + # unused blocks do not need to be allocated for sparse image types + execWithRedirect("fstrim", [img_mount.mount_dir]) + + except (subprocess.CalledProcessError, OSError) as e: + log.error("Running anaconda failed: %s", e) + raise InstallError("novirt_install failed") + finally: + log_monitor.shutdown() + + # Move the anaconda logs over to a log directory + log_dir = os.path.abspath(os.path.dirname(opts.logfile)) + log_anaconda = joinpaths(log_dir, "anaconda") + if not os.path.isdir(log_anaconda): + os.mkdir(log_anaconda) + for l in glob.glob("/tmp/*log")+glob.glob("/tmp/anaconda-tb-*"): + shutil.copy2(l, log_anaconda) + os.unlink(l) + + # Make sure any leftover anaconda mounts have been cleaned up + if not anaconda_cleanup(dirinstall_path): + raise InstallError("novirt_install cleanup of anaconda mounts failed.") + + if not opts.make_iso and not opts.make_fsimage and not opts.make_pxe_live: + dm_name = os.path.splitext(os.path.basename(disk_img))[0] + + # Remove device-mapper for partitions and disk + log.debug("Removing device-mapper setup on %s", dm_name) + for d in sorted(glob.glob("/dev/mapper/"+dm_name+"*"), reverse=True): + dm_detach(d) + + log.debug("Removing loop device for %s", disk_img) + loop_detach("/dev/"+get_loop_name(disk_img)) + + # qemu disk image is used by bare qcow2 images and by Vagrant + if opts.image_type: + log.info("Converting %s to %s", disk_img, opts.image_type) + qemu_args = [] + for arg in opts.qemu_args: + qemu_args += arg.split(" ", 1) + + # convert the image to the selected format + if "-O" not in qemu_args: + qemu_args.extend(["-O", opts.image_type]) + qemu_img = tempfile.mktemp(prefix="lmc-disk-", suffix=".img") + execWithRedirect("qemu-img", ["convert"] + qemu_args + [disk_img, qemu_img], raise_err=True) + if not opts.make_vagrant: + execWithRedirect("mv", ["-f", qemu_img, disk_img], raise_err=True) + else: + # Take the new qcow2 image and package it up for Vagrant + compress_args = [] + for arg in opts.compress_args: + compress_args += arg.split(" ", 1) + + vagrant_dir = tempfile.mkdtemp(prefix="lmc-tmpdir-") + metadata_path = joinpaths(vagrant_dir, "metadata.json") + execWithRedirect("mv", ["-f", qemu_img, joinpaths(vagrant_dir, "box.img")], raise_err=True) + if opts.vagrant_metadata: + shutil.copy2(opts.vagrant_metadata, metadata_path) + else: + create_vagrant_metadata(metadata_path) + update_vagrant_metadata(metadata_path, disk_size) + if opts.vagrantfile: + shutil.copy2(opts.vagrantfile, joinpaths(vagrant_dir, "vagrantfile")) + + log.info("Creating Vagrant image") + rc = mktar(vagrant_dir, disk_img, opts.compression, compress_args, selinux=False) + if rc: + raise InstallError("novirt_install mktar failed: rc=%s" % rc) + shutil.rmtree(vagrant_dir) + elif opts.make_tar: + compress_args = [] + for arg in opts.compress_args: + compress_args += arg.split(" ", 1) + + rc = mktar(dirinstall_path, disk_img, opts.compression, compress_args) + shutil.rmtree(dirinstall_path) + + if rc: + raise InstallError("novirt_install mktar failed: rc=%s" % rc) + elif opts.make_oci: + # An OCI image places the filesystem under /rootfs/ and adds the json files at the top + # And then creates a tar of the whole thing. + compress_args = [] + for arg in opts.compress_args: + compress_args += arg.split(" ", 1) + + shutil.copy2(opts.oci_config, ROOT_PATH) + shutil.copy2(opts.oci_runtime, ROOT_PATH) + rc = mktar(ROOT_PATH, disk_img, opts.compression, compress_args) + + if rc: + raise InstallError("novirt_install mktar failed: rc=%s" % rc) + else: + # For raw disk images, use fallocate to deallocate unused space + execWithRedirect("fallocate", ["--dig-holes", disk_img], raise_err=True) + + # For make_tar_disk, wrap the result in a tar file, and remove the original disk image. + if opts.make_tar_disk: + compress_args = [] + for arg in opts.compress_args: + compress_args += arg.split(" ", 1) + + rc = mktar(disk_img, tar_img, opts.compression, compress_args, selinux=False) + + if rc: + raise InstallError("novirt_install mktar failed: rc=%s" % rc) + + os.unlink(disk_img)
    + +
    [docs]def virt_install(opts, install_log, disk_img, disk_size, cancel_func=None, tar_img=None): + """ + Use qemu to install to a disk image + + :param opts: options passed to livemedia-creator + :type opts: argparse options + :param str install_log: The path to write the log from qemu + :param str disk_img: The full path to the disk image to be created + :param int disk_size: The size of the disk_img in MiB + :param cancel_func: Function that returns True to cancel build + :type cancel_func: function + :param str tar_img: For make_tar_disk, the path to final tarball to be created + + This uses qemu with a boot.iso and a kickstart to create a disk + image and then optionally, based on the opts passed, creates tarfile. + """ + iso_mount = IsoMountpoint(opts.iso, opts.location) + if not iso_mount.stage2: + iso_mount.umount() + raise InstallError("ISO is missing stage2, cannot continue") + + log_monitor = LogMonitor(install_log, timeout=opts.timeout) + cancel_funcs = [log_monitor.server.log_check] + if cancel_func is not None: + cancel_funcs.append(cancel_func) + + kernel_args = "" + if opts.kernel_args: + kernel_args += opts.kernel_args + if opts.proxy: + kernel_args += " proxy="+opts.proxy + + if opts.image_type and not opts.make_fsimage: + qemu_args = [] + for arg in opts.qemu_args: + qemu_args += arg.split(" ", 1) + if "-f" not in qemu_args: + qemu_args += ["-f", opts.image_type] + + mkqemu_img(disk_img, disk_size*1024**2, qemu_args) + + if opts.make_fsimage or opts.make_tar or opts.make_oci: + diskimg_path = tempfile.mktemp(prefix="lmc-disk-", suffix=".img") + else: + diskimg_path = disk_img + + try: + QEMUInstall(opts, iso_mount, opts.ks, diskimg_path, disk_size, + kernel_args, opts.ram, opts.vcpus, opts.vnc, opts.arch, + cancel_func = lambda : any(f() for f in cancel_funcs), + virtio_host = log_monitor.host, + virtio_port = log_monitor.port, + image_type=opts.image_type, boot_uefi=opts.virt_uefi, + ovmf_path=opts.ovmf_path) + log_monitor.shutdown() + except InstallError as e: + log.error("VirtualInstall failed: %s", e) + raise + finally: + log.info("unmounting the iso") + iso_mount.umount() + + if log_monitor.server.log_check(): + if not log_monitor.server.error_line and opts.timeout: + msg = "virt_install failed due to timeout" + else: + msg = "virt_install failed on line: %s" % log_monitor.server.error_line + raise InstallError(msg) + elif cancel_func and cancel_func(): + raise InstallError("virt_install canceled by cancel_func") + + if opts.make_fsimage: + mkfsimage_from_disk(diskimg_path, disk_img, disk_size, label=opts.fs_label) + os.unlink(diskimg_path) + elif opts.make_tar: + compress_args = [] + for arg in opts.compress_args: + compress_args += arg.split(" ", 1) + + with PartitionMount(diskimg_path) as img_mount: + if img_mount and img_mount.mount_dir: + rc = mktar(img_mount.mount_dir, disk_img, opts.compression, compress_args) + else: + rc = 1 + os.unlink(diskimg_path) + + if rc: + raise InstallError("virt_install failed") + elif opts.make_oci: + # An OCI image places the filesystem under /rootfs/ and adds the json files at the top + # And then creates a tar of the whole thing. + compress_args = [] + for arg in opts.compress_args: + compress_args += arg.split(" ", 1) + + with PartitionMount(diskimg_path, submount="rootfs") as img_mount: + if img_mount and img_mount.temp_dir: + shutil.copy2(opts.oci_config, img_mount.temp_dir) + shutil.copy2(opts.oci_runtime, img_mount.temp_dir) + rc = mktar(img_mount.temp_dir, disk_img, opts.compression, compress_args) + else: + rc = 1 + os.unlink(diskimg_path) + + if rc: + raise InstallError("virt_install failed") + elif opts.make_vagrant: + compress_args = [] + for arg in opts.compress_args: + compress_args += arg.split(" ", 1) + + vagrant_dir = tempfile.mkdtemp(prefix="lmc-tmpdir-") + metadata_path = joinpaths(vagrant_dir, "metadata.json") + execWithRedirect("mv", ["-f", disk_img, joinpaths(vagrant_dir, "box.img")], raise_err=True) + if opts.vagrant_metadata: + shutil.copy2(opts.vagrant_metadata, metadata_path) + else: + create_vagrant_metadata(metadata_path) + update_vagrant_metadata(metadata_path, disk_size) + if opts.vagrantfile: + shutil.copy2(opts.vagrantfile, joinpaths(vagrant_dir, "vagrantfile")) + + rc = mktar(vagrant_dir, disk_img, opts.compression, compress_args, selinux=False) + if rc: + raise InstallError("virt_install failed") + shutil.rmtree(vagrant_dir) + + # For make_tar_disk, wrap the result in a tar file, and remove the original disk image. + if opts.make_tar_disk: + compress_args = [] + for arg in opts.compress_args: + compress_args += arg.split(" ", 1) + + rc = mktar(disk_img, tar_img, opts.compression, compress_args, selinux=False) + + if rc: + raise InstallError("virt_install mktar failed: rc=%s" % rc) + + os.unlink(disk_img)
    +
    + +
    + +
    +
    + + +
    + +
    +

    + © Copyright 2018-2019, Red Hat, Inc. + +

    +
    + Built with Sphinx using a theme provided by Read the Docs. + +
    + +
    +
    + +
    + +
    + + + + + + + + + + + + \ No newline at end of file diff --git a/rhel8-branch/_modules/pylorax/ltmpl.html b/rhel8-branch/_modules/pylorax/ltmpl.html new file mode 100644 index 00000000..eddb9e6d --- /dev/null +++ b/rhel8-branch/_modules/pylorax/ltmpl.html @@ -0,0 +1,1085 @@ + + + + + + + + + + + pylorax.ltmpl — Lorax 28.14.33 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + + + +
    + + + + + +
    + +
    + + + + + + + + + + + + + + + + + +
    + + + + +
    +
    +
    +
    + +

    Source code for pylorax.ltmpl

    +#
    +# ltmpl.py
    +#
    +# Copyright (C) 2009-2015  Red Hat, Inc.
    +#
    +# This program is free software; you can redistribute it and/or modify
    +# it under the terms of the GNU General Public License as published by
    +# the Free Software Foundation; either version 2 of the License, or
    +# (at your option) any later version.
    +#
    +# This program is distributed in the hope that it will be useful,
    +# but WITHOUT ANY WARRANTY; without even the implied warranty of
    +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    +# GNU General Public License for more details.
    +#
    +# You should have received a copy of the GNU General Public License
    +# along with this program.  If not, see <http://www.gnu.org/licenses/>.
    +#
    +# Red Hat Author(s):  Martin Gracik <mgracik@redhat.com>
    +#                     Will Woods <wwoods@redhat.com>
    +#
    +
    +import logging
    +logger = logging.getLogger("pylorax.ltmpl")
    +
    +import os, re, glob, shlex, fnmatch
    +from os.path import basename, isdir
    +from subprocess import CalledProcessError
    +import shutil
    +
    +from pylorax.sysutils import joinpaths, cpfile, mvfile, replace, remove
    +from pylorax.dnfhelper import LoraxDownloadCallback, LoraxRpmCallback
    +from pylorax.base import DataHolder
    +from pylorax.executils import runcmd, runcmd_output
    +from pylorax.imgutils import mkcpio
    +
    +from mako.lookup import TemplateLookup
    +from mako.exceptions import text_error_template
    +import sys, traceback
    +import struct
    +import dnf
    +import collections
    +
    +
    [docs]class LoraxTemplate(object): + def __init__(self, directories=None): + directories = directories or ["/usr/share/lorax"] + # we have to add ["/"] to the template lookup directories or the + # file includes won't work properly for absolute paths + self.directories = ["/"] + directories + +
    [docs] def parse(self, template_file, variables): + lookup = TemplateLookup(directories=self.directories) + template = lookup.get_template(template_file) + + try: + textbuf = template.render(**variables) + except: + logger.error("Problem rendering %s (%s):", template_file, variables) + logger.error(text_error_template().render()) + raise + + # split, strip and remove empty lines + lines = textbuf.splitlines() + lines = [line.strip() for line in lines] + lines = [line for line in lines if line] + + # remove comments + lines = [line for line in lines if not line.startswith("#")] + + # split with shlex and perform brace expansion. This can fail, so we unroll the loop + # for better error reporting. + expanded_lines = [] + try: + for line in lines: + expanded_lines.append(split_and_expand(line)) + except Exception as e: + logger.error('shlex error processing "%s": %s', line, str(e)) + raise + return expanded_lines
    + +
    [docs]def split_and_expand(line): + return [exp for word in shlex.split(line) for exp in brace_expand(word)]
    + +
    [docs]def brace_expand(s): + if not ('{' in s and ',' in s and '}' in s): + yield s + else: + right = s.find('}') + left = s[:right].rfind('{') + (prefix, choices, suffix) = (s[:left], s[left+1:right], s[right+1:]) + for choice in choices.split(','): + for alt in brace_expand(prefix+choice+suffix): + yield alt
    + +
    [docs]def rglob(pathname, root="/", fatal=False): + seen = set() + rootlen = len(root)+1 + for f in glob.iglob(joinpaths(root, pathname)): + if f not in seen: + seen.add(f) + yield f[rootlen:] # remove the root to produce relative path + if fatal and not seen: + raise IOError("nothing matching %s in %s" % (pathname, root))
    + +
    [docs]def rexists(pathname, root=""): + # Generator is always True, even with no values; + # bool(rglob(...)) won't work here. + for _path in rglob(pathname, root): + return True + return False
    + +
    [docs]class TemplateRunner(object): + ''' + This class parses and executes Lorax templates. Sample usage: + + # install a bunch of packages + runner = LoraxTemplateRunner(inroot=rundir, outroot=rundir, dbo=dnf_obj) + runner.run("install-packages.ltmpl") + NOTES: + + * Parsing procedure is roughly: + 1. Mako template expansion (on the whole file) + 2. For each line of the result, + a. Whitespace splitting (using shlex.split()) + b. Brace expansion (using brace_expand()) + c. If the first token is the name of a function, call that function + with the rest of the line as arguments + + * Parsing and execution are *separate* passes - so you can't use the result + of a command in an %if statement (or any other control statements)! + ''' + def __init__(self, fatalerrors=True, templatedir=None, defaults=None, builtins=None): + self.fatalerrors = fatalerrors + self.templatedir = templatedir or "/usr/share/lorax" + self.templatefile = None + self.builtins = builtins or {} + self.defaults = defaults or {} + + +
    [docs] def run(self, templatefile, **variables): + for k,v in list(self.defaults.items()) + list(self.builtins.items()): + variables.setdefault(k,v) + logger.debug("executing %s with variables=%s", templatefile, variables) + self.templatefile = templatefile + t = LoraxTemplate(directories=[self.templatedir]) + commands = t.parse(templatefile, variables) + self._run(commands)
    + + + def _run(self, parsed_template): + logger.info("running %s", self.templatefile) + for (num, line) in enumerate(parsed_template,1): + logger.debug("template line %i: %s", num, " ".join(line)) + skiperror = False + (cmd, args) = (line[0], line[1:]) + # Following Makefile convention, if the command is prefixed with + # a dash ('-'), we'll ignore any errors on that line. + if cmd.startswith('-'): + cmd = cmd[1:] + skiperror = True + try: + # grab the method named in cmd and pass it the given arguments + f = getattr(self, cmd, None) + if cmd[0] == '_' or cmd == 'run' or not isinstance(f, collections.Callable): + raise ValueError("unknown command %s" % cmd) + f(*args) + except Exception: # pylint: disable=broad-except + if skiperror: + logger.debug("ignoring error") + continue + logger.error("template command error in %s:", self.templatefile) + logger.error(" %s", " ".join(line)) + # format the exception traceback + exclines = traceback.format_exception(*sys.exc_info()) + # skip the bit about "ltmpl.py, in _run()" - we know that + exclines.pop(1) + # log the "ErrorType: this is what happened" line + logger.error(" %s", exclines[-1].strip()) + # and log the entire traceback to the debug log + for _line in ''.join(exclines).splitlines(): + logger.debug(" %s", _line) + if self.fatalerrors: + raise
    + + +# TODO: operate inside an actual chroot for safety? Not that RPM bothers.. +
    [docs]class LoraxTemplateRunner(TemplateRunner): + ''' + This class parses and executes Lorax templates. Sample usage: + + # install a bunch of packages + runner = LoraxTemplateRunner(inroot=rundir, outroot=rundir, dbo=dnf_obj) + runner.run("install-packages.ltmpl") + + # modify a runtime dir + runner = LoraxTemplateRunner(inroot=rundir, outroot=newrun) + runner.run("runtime-transmogrify.ltmpl") + + NOTES: + + * Commands that run external programs (e.g. systemctl) currently use + the *host*'s copy of that program, which may cause problems if there's a + big enough difference between the host and the image you're modifying. + + * The commands are not executed under a real chroot, so absolute symlinks + will point *outside* the inroot/outroot. Be careful with symlinks! + + ADDING NEW COMMANDS: + + * Each template command is just a method of the LoraxTemplateRunner + object - so adding a new command is as easy as adding a new function. + + * Each function gets arguments that correspond to the rest of the tokens + on that line (after word splitting and brace expansion) + + * Commands should raise exceptions for errors - don't use sys.exit() + ''' + def __init__(self, inroot, outroot, dbo=None, fatalerrors=True, + templatedir=None, defaults=None): + self.inroot = inroot + self.outroot = outroot + self.dbo = dbo + builtins = DataHolder(exists=lambda p: rexists(p, root=inroot), + glob=lambda g: list(rglob(g, root=inroot))) + self.results = DataHolder(treeinfo=dict()) # just treeinfo for now + + super(LoraxTemplateRunner, self).__init__(fatalerrors, templatedir, defaults, builtins) + # TODO: set up custom logger with a filter to add line info + + def _out(self, path): + return joinpaths(self.outroot, path) + def _in(self, path): + return joinpaths(self.inroot, path) + + def _filelist(self, *pkgs): + """ Return the list of files in the packages """ + pkglist = [] + for pkg_glob in pkgs: + pkglist += list(self.dbo.sack.query().installed().filter(name__glob=pkg_glob)) + + # dnf/hawkey doesn't make any distinction between file, dir or ghost like yum did + # so only return the files. + return set(f for pkg in pkglist for f in pkg.files if not os.path.isdir(self._out(f))) + + def _getsize(self, *files): + return sum(os.path.getsize(self._out(f)) for f in files if os.path.isfile(self._out(f))) + + def _write_debuginfo_log(self): + """ + Write a list of debuginfo packages to /root/debug-pkgs.log + + If lorax is called with a debug repo find the corresponding debuginfo package + names and write them to /root/debubg-pkgs.log on the boot.iso + """ + for repo in self.dbo.repos: + repo = self.dbo.repos[repo] + if any(True for url in repo.baseurl if "debug" in url): + break + if repo.metalink and "debug" in repo.metalink: + break + if repo.mirrorlist and "debug" in repo.mirrorlist: + break + else: + # No debug repos + return + + available = self.dbo.sack.query().available() + debug_pkgs = [] + for p in list(self.dbo.transaction.install_set): + if available.filter(name=p.name+"-debuginfo"): + debug_pkgs += ["{0.name}-debuginfo-{0.epoch}:{0.version}-{0.release}".format(p)] + + os.makedirs(self._out("root/"), exist_ok=True) + with open(self._out("root/debug-pkgs.log"), "w") as f: + for pkg in debug_pkgs: + f.write("%s\n" % pkg) + +
    [docs] def install(self, srcglob, dest): + ''' + install SRC DEST + Copy the given file (or files, if a glob is used) from the input + tree to the given destination in the output tree. + The path to DEST must exist in the output tree. + If DEST is a directory, SRC will be copied into that directory. + If DEST doesn't exist, SRC will be copied to a file with that name, + assuming the rest of the path exists. + This is pretty much like how the 'cp' command works. + + Examples: + install usr/share/myconfig/grub.conf /boot + install /usr/share/myconfig/grub.conf.in /boot/grub.conf + ''' + for src in rglob(self._in(srcglob), fatal=True): + try: + cpfile(src, self._out(dest)) + except shutil.Error as e: + logger.error(e)
    + +
    [docs] def installimg(self, *args): + ''' + installimg [--xz|--gzip|--bzip2|--lzma] [-ARG|--ARG=OPTION] SRCDIR DESTFILE + Create a compressed cpio archive of the contents of SRCDIR and place + it in DESTFILE. + + If SRCDIR doesn't exist or is empty nothing is created. + + Examples: + installimg ${LORAXDIR}/product/ images/product.img + installimg ${LORAXDIR}/updates/ images/updates.img + installimg --xz -6 ${LORAXDIR}/updates/ images/updates.img + installimg --xz -9 --memlimit-compress=3700MiB ${LORAXDIR}/updates/ images/updates.img + + Optionally use a different compression type and override the default args + passed to it. The default is xz -9 + ''' + COMPRESSORS = ("--xz", "--gzip", "--bzip2", "--lzma") + if len(args) < 2: + raise ValueError("Not enough args for installimg.") + + srcdir = args[-2] + destfile = args[-1] + if not os.path.isdir(self._in(srcdir)) or not os.listdir(self._in(srcdir)): + return + + compression = "xz" + compressargs = [] + if args[0] in COMPRESSORS: + compression = args[0][2:] + + for arg in args[1:-2]: + if arg.startswith('-'): + compressargs.append(arg) + else: + raise ValueError("Argument is missing -") + + logger.info("Creating image file %s from contents of %s", self._out(destfile), self._in(srcdir)) + logger.debug("Using %s %s compression", compression, compressargs or "") + mkcpio(self._in(srcdir), self._out(destfile), compression=compression, compressargs=compressargs)
    + +
    [docs] def mkdir(self, *dirs): + ''' + mkdir DIR [DIR ...] + Create the named DIR(s). Will create leading directories as needed. + + Example: + mkdir /images + ''' + for d in dirs: + d = self._out(d) + if not isdir(d): + os.makedirs(d)
    + +
    [docs] def replace(self, pat, repl, *fileglobs): + ''' + replace PATTERN REPLACEMENT FILEGLOB [FILEGLOB ...] + Find-and-replace the given PATTERN (Python-style regex) with the given + REPLACEMENT string for each of the files listed. + + Example: + replace @VERSION@ ${product.version} /boot/grub.conf /boot/isolinux.cfg + ''' + match = False + for g in fileglobs: + for f in rglob(self._out(g)): + match = True + replace(f, pat, repl) + if not match: + raise IOError("no files matched %s" % " ".join(fileglobs))
    + +
    [docs] def append(self, filename, data): + ''' + append FILE STRING + Append STRING (followed by a newline character) to FILE. + Python character escape sequences ('\\n', '\\t', etc.) will be + converted to the appropriate characters. + + Examples: + + append /etc/depmod.d/dd.conf "search updates built-in" + append /etc/resolv.conf "" + ''' + with open(self._out(filename), "a") as fobj: + fobj.write(bytes(data, "utf8").decode('unicode_escape')+"\n")
    + +
    [docs] def treeinfo(self, section, key, *valuetoks): + ''' + treeinfo SECTION KEY ARG [ARG ...] + Add an item to the treeinfo data store. + The given SECTION will have a new item added where + KEY = ARG ARG ... + + Example: + treeinfo images-${kernel.arch} boot.iso images/boot.iso + ''' + if section not in self.results.treeinfo: + self.results.treeinfo[section] = dict() + self.results.treeinfo[section][key] = " ".join(valuetoks)
    + +
    [docs] def installkernel(self, section, src, dest): + ''' + installkernel SECTION SRC DEST + Install the kernel from SRC in the input tree to DEST in the output + tree, and then add an item to the treeinfo data store, in the named + SECTION, where "kernel" = DEST. + + Equivalent to: + install SRC DEST + treeinfo SECTION kernel DEST + ''' + self.install(src, dest) + self.treeinfo(section, "kernel", dest)
    + +
    [docs] def installinitrd(self, section, src, dest): + ''' + installinitrd SECTION SRC DEST + Same as installkernel, but for "initrd". + ''' + self.install(src, dest) + self.chmod(dest, '644') + self.treeinfo(section, "initrd", dest)
    + +
    [docs] def installupgradeinitrd(self, section, src, dest): + ''' + installupgradeinitrd SECTION SRC DEST + Same as installkernel, but for "upgrade". + ''' + self.install(src, dest) + self.chmod(dest, '644') + self.treeinfo(section, "upgrade", dest)
    + + + + + +
    [docs] def copy(self, src, dest): + ''' + copy SRC DEST + Copy SRC to DEST. + If DEST is a directory, SRC will be copied inside it. + If DEST doesn't exist, SRC will be copied to a file with + that name, if the path leading to it exists. + ''' + try: + cpfile(self._out(src), self._out(dest)) + except shutil.Error as e: + logger.error(e)
    + +
    [docs] def move(self, src, dest): + ''' + move SRC DEST + Move SRC to DEST. + ''' + mvfile(self._out(src), self._out(dest))
    + +
    [docs] def remove(self, *fileglobs): + ''' + remove FILEGLOB [FILEGLOB ...] + Remove all the named files or directories. + Will *not* raise exceptions if the file(s) are not found. + ''' + for g in fileglobs: + for f in rglob(self._out(g)): + remove(f) + logger.debug("removed %s", f)
    + +
    [docs] def chmod(self, fileglob, mode): + ''' + chmod FILEGLOB OCTALMODE + Change the mode of all the files matching FILEGLOB to OCTALMODE. + ''' + for f in rglob(self._out(fileglob), fatal=True): + os.chmod(f, int(mode,8))
    + +
    [docs] def log(self, msg): + ''' + log MESSAGE + Emit the given log message. Be sure to put it in quotes! + + Example: + log "Reticulating splines, please wait..." + ''' + logger.info(msg)
    + + # TODO: add ssh-keygen, mkisofs(?), find, and other useful commands +
    [docs] def runcmd(self, *cmdlist): + ''' + runcmd CMD [ARG ...] + Run the given command with the given arguments. + + NOTE: All paths given MUST be COMPLETE, ABSOLUTE PATHS to the file + or files mentioned. ${root}/${inroot}/${outroot} are good for + constructing these paths. + + FURTHER NOTE: Please use this command only as a last resort! + Whenever possible, you should use the existing template commands. + If the existing commands don't do what you need, fix them! + + Examples: + (this should be replaced with a "find" function) + runcmd find ${root} -name "*.pyo" -type f -delete + %for f in find(root, name="*.pyo"): + remove ${f} + %endfor + ''' + cmd = cmdlist + logger.debug('running command: %s', cmd) + if cmd[0].startswith("--chdir="): + logger.error("--chdir is no longer supported for runcmd.") + raise ValueError("--chdir is no longer supported for runcmd.") + + try: + stdout = runcmd_output(cmd) + if stdout: + logger.debug('command output:\n%s', stdout) + logger.debug("command finished successfully") + except CalledProcessError as e: + if e.output: + logger.error('command output:\n%s', e.output) + logger.error('command returned failure (%d)', e.returncode) + raise
    + +
    [docs] def installpkg(self, *pkgs): + ''' + installpkg [--required|--optional] [--except PKGGLOB [--except PKGGLOB ...]] PKGGLOB [PKGGLOB ...] + Request installation of all packages matching the given globs. + Note that this is just a *request* - nothing is *actually* installed + until the 'run_pkg_transaction' command is given. + + --required is now the default. If the PKGGLOB can be missing pass --optional + ''' + if pkgs[0] == '--optional': + pkgs = pkgs[1:] + required = False + elif pkgs[0] == '--required': + pkgs = pkgs[1:] + required = True + else: + required = True + + excludes = [] + while '--except' in pkgs: + idx = pkgs.index('--except') + if len(pkgs) == idx+1: + raise ValueError("installpkg needs an argument after --except") + + excludes.append(pkgs[idx+1]) + pkgs = pkgs[:idx] + pkgs[idx+2:] + + errors = False + for p in pkgs: + try: + # Start by using Subject to generate a package query, which will + # give us a query object similar to what dbo.install would select, + # minus the handling for multilib. This query may contain + # multiple arches. Pull the package names out of that, filter any + # that match the excludes patterns, and pass those names back to + # dbo.install to do the actual, arch and version and multilib + # aware, package selction. + + # dnf queries don't have a concept of negative globs which is why + # the filtering is done the hard way. + + pkgnames = [pkg for pkg in dnf.subject.Subject(p).get_best_query(self.dbo.sack).filter(latest=True)] + if not pkgnames: + raise dnf.exceptions.PackageNotFoundError("no package matched", p) + + # Apply excludes to the name only + for exclude in excludes: + pkgnames = [pkg for pkg in pkgnames if not fnmatch.fnmatch(pkg.name, exclude)] + + # Convert to a sorted NVR list for installation + pkgnvrs = sorted(["{}-{}-{}".format(pkg.name, pkg.version, pkg.release) for pkg in pkgnames]) + + # If the request is a glob, expand it in the log + if any(g for g in ['*','?','.'] if g in p): + logger.info("installpkg: %s expands to %s", p, ",".join(pkgnvrs)) + + for pkgnvr in pkgnvrs: + try: + self.dbo.install(pkgnvr) + except Exception as e: # pylint: disable=broad-except + if required: + raise + # Not required, log it and continue processing pkgs + logger.error("installpkg %s failed: %s", pkgnvr, str(e)) + except Exception as e: # pylint: disable=broad-except + logger.error("installpkg %s failed: %s", p, str(e)) + errors = True + + if errors and required: + raise Exception("Required installpkg failed.")
    + +
    [docs] def removepkg(self, *pkgs): + ''' + removepkg PKGGLOB [PKGGLOB...] + Delete the named package(s). + + IMPLEMENTATION NOTES: + RPM scriptlets (%preun/%postun) are *not* run. + Files are deleted, but directories are left behind. + ''' + for p in pkgs: + filepaths = [f.lstrip('/') for f in self._filelist(p)] + # TODO: also remove directories that aren't owned by anything else + if filepaths: + logger.debug("removepkg %s: %ikb", p, self._getsize(*filepaths)/1024) + self.remove(*filepaths) + else: + logger.debug("removepkg %s: no files to remove!", p)
    + +
    [docs] def run_pkg_transaction(self): + ''' + run_pkg_transaction + Actually install all the packages requested by previous 'installpkg' + commands. + ''' + try: + logger.info("Checking dependencies") + self.dbo.resolve() + except dnf.exceptions.DepsolveError as e: + logger.error("Dependency check failed: %s", e) + raise + logger.info("%d packages selected", len(self.dbo.transaction)) + if len(self.dbo.transaction) == 0: + raise Exception("No packages in transaction") + + # If a debug repo has been included, write out a list of debuginfo packages + self._write_debuginfo_log() + + pkgs_to_download = self.dbo.transaction.install_set + logger.info("Downloading packages") + progress = LoraxDownloadCallback() + try: + self.dbo.download_packages(pkgs_to_download, progress) + except dnf.exceptions.DownloadError as e: + logger.error("Failed to download the following packages: %s", e) + raise + + logger.info("Preparing transaction from installation source") + try: + display = LoraxRpmCallback() + self.dbo.do_transaction(display=display) + except BaseException as e: + logger.error("The transaction process has ended abruptly: %s", e) + raise + + # Reset the package sack to pick up the installed packages + self.dbo.reset(repos=False) + self.dbo.fill_sack(load_system_repo=True, load_available_repos=False) + + # At this point dnf should know about the installed files. Double check that it really does. + if len(self._filelist("anaconda-core")) == 0: + raise Exception("Failed to reset dbo to installed package set")
    + +
    [docs] def removefrom(self, pkg, *globs): + ''' + removefrom PKGGLOB [--allbut] FILEGLOB [FILEGLOB...] + Remove all files matching the given file globs from the package + (or packages) named. + If '--allbut' is used, all the files from the given package(s) will + be removed *except* the ones which match the file globs. + + Examples: + removefrom usbutils /usr/bin/* + removefrom xfsprogs --allbut /sbin/* + ''' + cmd = "%s %s" % (pkg, " ".join(globs)) # save for later logging + keepmatches = False + if globs[0] == '--allbut': + keepmatches = True + globs = globs[1:] + # get pkg filelist and find files that match the globs + filelist = self._filelist(pkg) + matches = set() + for g in globs: + globs_re = re.compile(fnmatch.translate(g)) + m = [f for f in filelist if globs_re.match(f)] + if m: + matches.update(m) + else: + logger.debug("removefrom %s %s: no files matched!", pkg, g) + # are we removing the matches, or keeping only the matches? + if keepmatches: + remove_files = filelist.difference(matches) + else: + remove_files = matches + # remove the files + if remove_files: + logger.debug("removefrom %s: removed %i/%i files, %ikb/%ikb", cmd, + len(remove_files), len(filelist), + self._getsize(*remove_files)/1024, self._getsize(*filelist)/1024) + self.remove(*remove_files) + else: + logger.debug("removefrom %s: no files to remove!", cmd)
    + +
    [docs] def removekmod(self, *globs): + ''' + removekmod GLOB [GLOB...] [--allbut] KEEPGLOB [KEEPGLOB...] + Remove all files and directories matching the given file globs from the kernel + modules directory. + + If '--allbut' is used, all the files from the modules will be removed *except* + the ones which match the file globs. There must be at least one initial GLOB + to search and one KEEPGLOB to keep. The KEEPGLOB is expanded to be *KEEPGLOB* + so that it will match anywhere in the path. + + This only removes files from under /lib/modules/*/kernel/ + + Examples: + removekmod sound drivers/media drivers/hwmon drivers/video + removekmod drivers/char --allbut virtio_console hw_random + ''' + cmd = " ".join(globs) + if "--allbut" in globs: + idx = globs.index("--allbut") + if idx == 0: + raise ValueError("removekmod needs at least one GLOB before --allbut") + + # Apply keepglobs anywhere they appear in the path + keepglobs = globs[idx+1:] + if len(keepglobs) == 0: + raise ValueError("removekmod needs at least one GLOB after --allbut") + + globs = globs[:idx] + else: + # Nothing to keep + keepglobs = [] + + filelist = set() + for g in globs: + for top_dir in rglob(self._out("/lib/modules/*/kernel/"+g)): + for root, _dirs, files in os.walk(top_dir): + filelist.update(root+"/"+f for f in files) + + # Remove anything matching keepglobs from the list + matches = set() + for g in keepglobs: + globs_re = re.compile(fnmatch.translate("*"+g+"*")) + m = [f for f in filelist if globs_re.match(f)] + if m: + matches.update(m) + else: + logger.debug("removekmod %s: no files matched!", g) + remove_files = filelist.difference(matches) + + if remove_files: + logger.debug("removekmod: removing %d files", len(remove_files)) + list(remove(f) for f in remove_files) + else: + logger.debug("removekmod %s: no files to remove!", cmd)
    + +
    [docs] def createaddrsize(self, addr, src, dest): + ''' + createaddrsize INITRD_ADDRESS INITRD ADDRSIZE + Create the initrd.addrsize file required in LPAR boot process. + + Examples: + createaddrsize ${INITRD_ADDRESS} ${outroot}/${BOOTDIR}/initrd.img ${outroot}/${BOOTDIR}/initrd.addrsize + ''' + addrsize = open(dest, "wb") + addrsize_data = struct.pack(">iiii", 0, int(addr, 16), 0, os.stat(src).st_size) + addrsize.write(addrsize_data) + addrsize.close()
    + +
    [docs] def systemctl(self, cmd, *units): + ''' + systemctl [enable|disable|mask] UNIT [UNIT...] + Enable, disable, or mask the given systemd units. + + Examples: + systemctl disable lvm2-monitor.service + systemctl mask fedora-storage-init.service fedora-configure.service + ''' + if cmd not in ('enable', 'disable', 'mask'): + raise ValueError('unsupported systemctl cmd: %s' % cmd) + if not units: + logger.debug("systemctl: no units given for %s, ignoring", cmd) + return + self.mkdir("/run/systemd/system") # XXX workaround for systemctl bug + systemctl = ['systemctl', '--root', self.outroot, '--no-reload', cmd] + # When a unit doesn't exist systemd aborts the command. Run them one at a time. + # XXX for some reason 'systemctl enable/disable' always returns 1 + for unit in units: + try: + cmd = systemctl + [unit] + runcmd(cmd) + except CalledProcessError: + pass
    + +
    [docs]class LiveTemplateRunner(TemplateRunner): + """ + This class parses and executes a limited Lorax template. Sample usage: + + # install a bunch of packages + runner = LiveTemplateRunner(dbo, templatedir, defaults) + runner.run("live-install.tmpl") + + It is meant to be used with the live-install.tmpl which lists the per-arch + pacages needed to build the live-iso output. + """ + def __init__(self, dbo, fatalerrors=True, templatedir=None, defaults=None): + self.dbo = dbo + self.pkgs = [] + self.pkgnames = [] + + super(LiveTemplateRunner, self).__init__(fatalerrors, templatedir, defaults) + +
    [docs] def installpkg(self, *pkgs): + ''' + installpkg [--required|--optional] [--except PKGGLOB [--except PKGGLOB ...]] PKGGLOB [PKGGLOB ...] + Request installation of all packages matching the given globs. + Note that this is just a *request* - nothing is *actually* installed + until the 'run_pkg_transaction' command is given. + + --required is now the default. If the PKGGLOB can be missing pass --optional + ''' + if pkgs[0] == '--optional': + pkgs = pkgs[1:] + required = False + elif pkgs[0] == '--required': + pkgs = pkgs[1:] + required = True + else: + required = True + + excludes = [] + while '--except' in pkgs: + idx = pkgs.index('--except') + if len(pkgs) == idx+1: + raise ValueError("installpkg needs an argument after --except") + + excludes.append(pkgs[idx+1]) + pkgs = pkgs[:idx] + pkgs[idx+2:] + + errors = False + for p in pkgs: + try: + # Start by using Subject to generate a package query, which will + # give us a query object similar to what dbo.install would select, + # minus the handling for multilib. This query may contain + # multiple arches. Pull the package names out of that, filter any + # that match the excludes patterns, and pass those names back to + # dbo.install to do the actual, arch and version and multilib + # aware, package selction. + + # dnf queries don't have a concept of negative globs which is why + # the filtering is done the hard way. + + pkgnames = [pkg for pkg in dnf.subject.Subject(p).get_best_query(self.dbo.sack).filter(latest=True)] + if not pkgnames: + raise dnf.exceptions.PackageNotFoundError("no package matched", p) + + # Apply excludes to the name only + for exclude in excludes: + pkgnames = [pkg for pkg in pkgnames if not fnmatch.fnmatch(pkg.name, exclude)] + + # Convert to a sorted NVR list for installation + pkgnvrs = sorted(["{}-{}-{}".format(pkg.name, pkg.version, pkg.release) for pkg in pkgnames]) + + # If the request is a glob, expand it in the log + if any(g for g in ['*','?','.'] if g in p): + logger.info("installpkg: %s expands to %s", p, ",".join(pkgnvrs)) + + self.pkgs.extend(pkgnvrs) + self.pkgnames.extend([pkg.name for pkg in pkgnames]) + except Exception as e: # pylint: disable=broad-except + logger.error("installpkg %s failed: %s", p, str(e)) + errors = True + + if errors and required: + raise Exception("Required installpkg failed.")
    +
    + +
    + +
    +
    + + +
    + +
    +

    + © Copyright 2018-2019, Red Hat, Inc. + +

    +
    + Built with Sphinx using a theme provided by Read the Docs. + +
    + +
    +
    + +
    + +
    + + + + + + + + + + + + \ No newline at end of file diff --git a/rhel8-branch/_modules/pylorax/monitor.html b/rhel8-branch/_modules/pylorax/monitor.html new file mode 100644 index 00000000..c7128657 --- /dev/null +++ b/rhel8-branch/_modules/pylorax/monitor.html @@ -0,0 +1,395 @@ + + + + + + + + + + + pylorax.monitor — Lorax 28.14.33 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + + + +
    + + + + + +
    + +
    + + + + + + + + + + + + + + + + + +
    + + + + +
    +
    +
    +
    + +

    Source code for pylorax.monitor

    +# monitor.py
    +#
    +# Copyright (C) 2011-2015  Red Hat, Inc.
    +#
    +# This program is free software; you can redistribute it and/or modify
    +# it under the terms of the GNU General Public License as published by
    +# the Free Software Foundation; either version 2 of the License, or
    +# (at your option) any later version.
    +#
    +# This program is distributed in the hope that it will be useful,
    +# but WITHOUT ANY WARRANTY; without even the implied warranty of
    +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    +# GNU General Public License for more details.
    +#
    +# You should have received a copy of the GNU General Public License
    +# along with this program.  If not, see <http://www.gnu.org/licenses/>.
    +#
    +# Author(s): Brian C. Lane <bcl@redhat.com>
    +#
    +import logging
    +log = logging.getLogger("livemedia-creator")
    +
    +import re
    +import socket
    +import socketserver
    +import threading
    +import time
    +
    +
    [docs]class LogRequestHandler(socketserver.BaseRequestHandler): + """ + Handle monitoring and saving the logfiles from the virtual install + + Incoming data is written to self.server.log_path and each line is checked + for patterns that would indicate that the installation failed. + self.server.log_error is set True when this happens. + """ +
    [docs] def setup(self): + """Start writing to self.server.log_path""" + + if self.server.log_path: + self.fp = open(self.server.log_path, "w") # pylint: disable=attribute-defined-outside-init + else: + self.fp = None + self.request.settimeout(10)
    + +
    [docs] def handle(self): + """ + Write incoming data to a logfile and check for errors + + Split incoming data into lines and check for any Tracebacks or other + errors that indicate that the install failed. + + Loops until self.server.kill is True + """ + log.info("Processing logs from %s", self.client_address) + line = "" + while True: + if self.server.kill: + break + + try: + data = str(self.request.recv(4096), "utf8") + if self.fp: + self.fp.write(data) + self.fp.flush() + + # check the data for errors and set error flag + # need to assemble it into lines so we can test for the error + # string. + while data: + more = data.split("\n", 1) + line += more[0] + if len(more) > 1: + self.iserror(line) + line = "" + data = more[1] + else: + data = None + + except socket.timeout: + pass + except Exception as e: # pylint: disable=broad-except + log.info("log processing killed by exception: %s", e) + break
    + +
    [docs] def finish(self): + log.info("Shutting down log processing") + self.request.close() + if self.fp: + self.fp.close()
    + +
    [docs] def iserror(self, line): + """ + Check a line to see if it contains an error indicating installation failure + + :param str line: log line to check for failure + + If the line contains IGNORED it will be skipped. + """ + if "IGNORED" in line: + return + simple_tests = ["Traceback (", + "Out of memory:", + "Call Trace:", + "insufficient disk space:", + "Not enough disk space to download the packages", + "error populating transaction after", + "traceback script(s) have been run", + "crashed on signal", + "packaging: Missed: NoSuchPackage", + "packaging: Installation failed", + "The following error occurred while installing. This is a fatal error"] + re_tests = [r"packaging: base repo .* not valid", + r"packaging: .* requires .*"] + for t in simple_tests: + if t in line: + self.server.log_error = True + self.server.error_line = line + return + for t in re_tests: + if re.search(t, line): + self.server.log_error = True + self.server.error_line = line + return
    + + +
    [docs]class LogServer(socketserver.TCPServer): + """A TCP Server that listens for log data""" + + # Number of seconds to wait for a connection after startup + timeout = 60 + + def __init__(self, log_path, *args, **kwargs): + """ + Setup the log server + + :param str log_path: Path to the log file to write + """ + self.kill = False + self.log_error = False + self.error_line = "" + self.log_path = log_path + self._timeout = kwargs.pop("timeout", None) + if self._timeout: + self._start_time = time.time() + socketserver.TCPServer.__init__(self, *args, **kwargs) + +
    [docs] def log_check(self): + """ + Check to see if an error has been found in the log + + :returns: True if there has been an error + :rtype: bool + """ + if self._timeout: + taking_too_long = time.time() > self._start_time + (self._timeout * 60) + if taking_too_long: + log.error("Canceling installation due to timeout") + else: + taking_too_long = False + return self.log_error or taking_too_long
    + + +
    [docs]class LogMonitor(object): + """ + Setup a server to monitor the logs output by the installation + + This needs to be running before the virt-install runs, it expects + there to be a listener on the port used for the virtio log port. + """ + def __init__(self, log_path=None, host="localhost", port=0, timeout=None): + """ + Start a thread to monitor the logs. + + :param str log_path: Path to the logfile to write + :param str host: Host to bind to. Default is localhost. + :param int port: Port to listen to or 0 to pick a port + + If 0 is passed for the port the dynamically assigned port will be + available as self.port + + If log_path isn't set then it only monitors the logs, instead of + also writing them to disk. + """ + self.server = LogServer(log_path, (host, port), LogRequestHandler, timeout=timeout) + self.host, self.port = self.server.server_address + self.log_path = log_path + self.server_thread = threading.Thread(target=self.server.handle_request) + self.server_thread.daemon = True + self.server_thread.start() + +
    [docs] def shutdown(self): + """Force shutdown of the monitoring thread""" + self.server.kill = True + self.server_thread.join()
    +
    + +
    + +
    +
    + + +
    + +
    +

    + © Copyright 2018-2019, Red Hat, Inc. + +

    +
    + Built with Sphinx using a theme provided by Read the Docs. + +
    + +
    +
    + +
    + +
    + + + + + + + + + + + + \ No newline at end of file diff --git a/rhel8-branch/_modules/pylorax/mount.html b/rhel8-branch/_modules/pylorax/mount.html new file mode 100644 index 00000000..1bc74534 --- /dev/null +++ b/rhel8-branch/_modules/pylorax/mount.html @@ -0,0 +1,302 @@ + + + + + + + + + + + pylorax.mount — Lorax 28.14.33 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + + + +
    + + + + + +
    + +
    + + + + + + + + + + + + + + + + + +
    + + + + +
    +
    +
    +
    + +

    Source code for pylorax.mount

    +# mount.py
    +#
    +# Copyright (C) 2011-2015  Red Hat, Inc.
    +#
    +# This program is free software; you can redistribute it and/or modify
    +# it under the terms of the GNU General Public License as published by
    +# the Free Software Foundation; either version 2 of the License, or
    +# (at your option) any later version.
    +#
    +# This program is distributed in the hope that it will be useful,
    +# but WITHOUT ANY WARRANTY; without even the implied warranty of
    +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    +# GNU General Public License for more details.
    +#
    +# You should have received a copy of the GNU General Public License
    +# along with this program.  If not, see <http://www.gnu.org/licenses/>.
    +#
    +# Author(s): Brian C. Lane <bcl@redhat.com>
    +#
    +import logging
    +log = logging.getLogger("livemedia-creator")
    +
    +import os
    +
    +from pylorax.imgutils import mount, umount
    +from pylorax.executils import execWithCapture
    +
    +
    [docs]class IsoMountpoint(object): + """ + Mount the iso and check to make sure the vmlinuz and initrd.img files exist + + Also check the iso for a a stage2 image and set a flag and extract the + iso's label. + + stage2 can be either LiveOS/squashfs.img or images/install.img + """ + def __init__(self, iso_path, initrd_path=None): + """ + Mount the iso + + :param str iso_path: Path to the iso to mount + :param str initrd_path: Optional path to initrd + + initrd_path can be used to point to a tree with a newer + initrd.img than the iso has. The iso is still used for stage2. + + self.kernel and self.initrd point to the kernel and initrd. + self.stage2 is set to True if there is a stage2 image. + self.repo is the path to the mounted iso if there is a /repodata dir. + """ + self.label = None + self.iso_path = iso_path + self.initrd_path = initrd_path + + if not self.initrd_path: + self.mount_dir = mount(self.iso_path, opts="loop") + else: + self.mount_dir = self.initrd_path + + kernel_list = [("/isolinux/vmlinuz", "/isolinux/initrd.img"), + ("/ppc/ppc64/vmlinuz", "/ppc/ppc64/initrd.img")] + + if os.path.isdir(self.mount_dir+"/repodata"): + self.repo = self.mount_dir + else: + self.repo = None + self.stage2 = os.path.exists(self.mount_dir+"/LiveOS/squashfs.img") or \ + os.path.exists(self.mount_dir+"/images/install.img") + + try: + for kernel, initrd in kernel_list: + if (os.path.isfile(self.mount_dir+kernel) and + os.path.isfile(self.mount_dir+initrd)): + self.kernel = self.mount_dir+kernel + self.initrd = self.mount_dir+initrd + break + else: + raise Exception("Missing kernel and initrd file in iso, failed" + " to search under: {0}".format(kernel_list)) + except: + self.umount() + raise + + self.get_iso_label() + +
    [docs] def umount( self ): + """Unmount the iso""" + if not self.initrd_path: + umount(self.mount_dir)
    + +
    [docs] def get_iso_label(self): + """ + Get the iso's label using isoinfo + + Sets self.label if one is found + """ + isoinfo_output = execWithCapture("isoinfo", ["-d", "-i", self.iso_path]) + log.debug(isoinfo_output) + for line in isoinfo_output.splitlines(): + if line.startswith("Volume id: "): + self.label = line[11:] + return
    +
    + +
    + +
    +
    + + +
    + +
    +

    + © Copyright 2018-2019, Red Hat, Inc. + +

    +
    + Built with Sphinx using a theme provided by Read the Docs. + +
    + +
    +
    + +
    + +
    + + + + + + + + + + + + \ No newline at end of file diff --git a/rhel8-branch/_modules/pylorax/sysutils.html b/rhel8-branch/_modules/pylorax/sysutils.html new file mode 100644 index 00000000..16861cc7 --- /dev/null +++ b/rhel8-branch/_modules/pylorax/sysutils.html @@ -0,0 +1,332 @@ + + + + + + + + + + + pylorax.sysutils — Lorax 28.14.33 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + + + +
    + + + + + +
    + +
    + + + + + + + + + + + + + + + + + +
    + + + + +
    +
    +
    +
    + +

    Source code for pylorax.sysutils

    +#
    +# sysutils.py
    +#
    +# Copyright (C) 2009-2015 Red Hat, Inc.
    +#
    +# This program is free software; you can redistribute it and/or modify
    +# it under the terms of the GNU General Public License as published by
    +# the Free Software Foundation; either version 2 of the License, or
    +# (at your option) any later version.
    +#
    +# This program is distributed in the hope that it will be useful,
    +# but WITHOUT ANY WARRANTY; without even the implied warranty of
    +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    +# GNU General Public License for more details.
    +#
    +# You should have received a copy of the GNU General Public License
    +# along with this program.  If not, see <http://www.gnu.org/licenses/>.
    +#
    +# Red Hat Author(s):  Martin Gracik <mgracik@redhat.com>
    +#
    +
    +__all__ = ["joinpaths", "touch", "replace", "chown_", "chmod_", "remove",
    +           "linktree"]
    +
    +import sys
    +import os
    +import re
    +import fileinput
    +import pwd
    +import grp
    +import glob
    +import shutil
    +import shlex
    +from configparser import ConfigParser
    +
    +from pylorax.executils import runcmd
    +
    +
    [docs]def joinpaths(*args, **kwargs): + path = os.path.sep.join(args) + + if kwargs.get("follow_symlinks"): + return os.path.realpath(path) + else: + return path
    + + +
    [docs]def touch(fname): + # python closes the file when it goes out of scope + open(fname, "w").write("")
    + + +
    [docs]def replace(fname, find, sub): + fin = fileinput.input(fname, inplace=1) + pattern = re.compile(find) + + for line in fin: + line = pattern.sub(sub, line) + sys.stdout.write(line) + + fin.close()
    + + +
    [docs]def chown_(path, user=None, group=None, recursive=False): + uid = gid = -1 + + if user is not None: + uid = pwd.getpwnam(user)[2] + if group is not None: + gid = grp.getgrnam(group)[2] + + for fname in glob.iglob(path): + os.chown(fname, uid, gid) + + if recursive and os.path.isdir(fname): + for nested in os.listdir(fname): + nested = joinpaths(fname, nested) + chown_(nested, user, group, recursive)
    + + +
    [docs]def chmod_(path, mode, recursive=False): + for fname in glob.iglob(path): + os.chmod(fname, mode) + + if recursive and os.path.isdir(fname): + for nested in os.listdir(fname): + nested = joinpaths(fname, nested) + chmod_(nested, mode, recursive)
    + + +def cpfile(src, dst): + shutil.copy2(src, dst) + if os.path.isdir(dst): + dst = joinpaths(dst, os.path.basename(src)) + + return dst + +def mvfile(src, dst): + if os.path.isdir(dst): + dst = joinpaths(dst, os.path.basename(src)) + os.rename(src, dst) + return dst + +
    [docs]def remove(target): + if os.path.isdir(target) and not os.path.islink(target): + shutil.rmtree(target) + else: + os.unlink(target)
    + +
    [docs]def linktree(src, dst): + runcmd(["/bin/cp", "-alx", src, dst])
    + +def unquote(s): + return ' '.join(shlex.split(s)) + +class UnquotingConfigParser(ConfigParser): + """A ConfigParser, only with unquoting of the values.""" + # pylint: disable=arguments-differ + def get(self, *args, **kwargs): + ret = super().get(*args, **kwargs) + if ret: + ret = unquote(ret) + return ret + +def flatconfig(filename): + """Use UnquotingConfigParser to read a flat config file (without + section headers) by adding a section header. + """ + with open (filename, 'r') as conffh: + conftext = "[main]\n" + conffh.read() + config = UnquotingConfigParser() + config.read_string(conftext) + return config['main'] +
    + +
    + +
    +
    + + +
    + +
    +

    + © Copyright 2018-2019, Red Hat, Inc. + +

    +
    + Built with Sphinx using a theme provided by Read the Docs. + +
    + +
    +
    + +
    + +
    + + + + + + + + + + + + \ No newline at end of file diff --git a/rhel8-branch/_modules/pylorax/treebuilder.html b/rhel8-branch/_modules/pylorax/treebuilder.html new file mode 100644 index 00000000..0eb8ee9c --- /dev/null +++ b/rhel8-branch/_modules/pylorax/treebuilder.html @@ -0,0 +1,602 @@ + + + + + + + + + + + pylorax.treebuilder — Lorax 28.14.33 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + + + +
    + + + + + +
    + +
    + + + + + + + + + + + + + + + + + +
    + + + + +
    +
    +
    +
    + +

    Source code for pylorax.treebuilder

    +# treebuilder.py - handle arch-specific tree building stuff using templates
    +#
    +# Copyright (C) 2011-2015 Red Hat, Inc.
    +#
    +# This program is free software; you can redistribute it and/or modify
    +# it under the terms of the GNU General Public License as published by
    +# the Free Software Foundation; either version 2 of the License, or
    +# (at your option) any later version.
    +#
    +# This program is distributed in the hope that it will be useful,
    +# but WITHOUT ANY WARRANTY; without even the implied warranty of
    +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    +# GNU General Public License for more details.
    +#
    +# You should have received a copy of the GNU General Public License
    +# along with this program.  If not, see <http://www.gnu.org/licenses/>.
    +#
    +# Author(s):  Will Woods <wwoods@redhat.com>
    +
    +import logging
    +logger = logging.getLogger("pylorax.treebuilder")
    +
    +import os, re
    +from os.path import basename
    +from shutil import copytree, copy2
    +from pathlib import Path
    +import itertools
    +
    +from pylorax.sysutils import joinpaths, remove
    +from pylorax.base import DataHolder
    +from pylorax.ltmpl import LoraxTemplateRunner
    +import pylorax.imgutils as imgutils
    +from pylorax.executils import runcmd, runcmd_output, execWithCapture
    +
    +templatemap = {
    +    'i386':    'x86.tmpl',
    +    'x86_64':  'x86.tmpl',
    +    'ppc':     'ppc.tmpl',
    +    'ppc64':   'ppc.tmpl',
    +    'ppc64le': 'ppc64le.tmpl',
    +    's390':    's390.tmpl',
    +    's390x':   's390.tmpl',
    +    'aarch64': 'aarch64.tmpl',
    +    'arm':     'arm.tmpl',
    +    'armhfp':  'arm.tmpl',
    +}
    +
    +
    [docs]def generate_module_info(moddir, outfile=None): + def module_desc(mod): + output = runcmd_output(["modinfo", "-F", "description", mod]) + return output.strip() + def read_module_set(name): + return set(l.strip() for l in open(joinpaths(moddir,name)) if ".ko" in l) + modsets = {'scsi':read_module_set("modules.block"), + 'eth':read_module_set("modules.networking")} + + modinfo = list() + for root, _dirs, files in os.walk(moddir): + for modtype, modset in modsets.items(): + for mod in modset.intersection(files): # modules in this dir + (name, _ext) = os.path.splitext(mod) # foo.ko -> (foo, .ko) + desc = module_desc(joinpaths(root,mod)) or "%s driver" % name + modinfo.append(dict(name=name, type=modtype, desc=desc)) + + out = open(outfile or joinpaths(moddir,"module-info"), "w") + out.write("Version 0\n") + for mod in sorted(modinfo, key=lambda m: m.get('name')): + out.write('{name}\n\t{type}\n\t"{desc:.65}"\n'.format(**mod))
    + +
    [docs]class RuntimeBuilder(object): + '''Builds the anaconda runtime image.''' + def __init__(self, product, arch, dbo, templatedir=None, + installpkgs=None, excludepkgs=None, + add_templates=None, + add_template_vars=None): + root = dbo.conf.installroot + # use a copy of product so we can modify it locally + product = product.copy() + product.name = product.name.lower() + self.vars = DataHolder(arch=arch, product=product, dbo=dbo, root=root, + basearch=arch.basearch, libdir=arch.libdir) + self.dbo = dbo + self._runner = LoraxTemplateRunner(inroot=root, outroot=root, + dbo=dbo, templatedir=templatedir) + self.add_templates = add_templates or [] + self.add_template_vars = add_template_vars or {} + self._installpkgs = installpkgs or [] + self._excludepkgs = excludepkgs or [] + self._runner.defaults = self.vars + self.dbo.reset() + + def _install_branding(self): + release = None + q = self.dbo.sack.query() + a = q.available() + for pkg in a.filter(provides='system-release'): + logger.debug("Found release package %s", pkg) + if pkg.name.startswith('generic'): + continue + else: + release = pkg.name + break + + if not release: + logger.error('could not get the release') + return + + # release + logger.info('got release: %s', release) + self._runner.installpkg(release) + + # logos + release, _suffix = release.split('-', 1) + self._runner.installpkg('%s-logos' % release) + +
    [docs] def install(self): + '''Install packages and do initial setup with runtime-install.tmpl''' + self._install_branding() + if len(self._installpkgs) > 0: + self._runner.installpkg(*self._installpkgs) + if len(self._excludepkgs) > 0: + self._runner.removepkg(*self._excludepkgs) + self._runner.run("runtime-install.tmpl") + for tmpl in self.add_templates: + self._runner.run(tmpl, **self.add_template_vars)
    + +
    [docs] def writepkglists(self, pkglistdir): + '''debugging data: write out lists of package contents''' + if not os.path.isdir(pkglistdir): + os.makedirs(pkglistdir) + q = self.dbo.sack.query() + for pkgobj in q.installed(): + with open(joinpaths(pkglistdir, pkgobj.name), "w") as fobj: + for fname in pkgobj.files: + fobj.write("{0}\n".format(fname))
    + +
    [docs] def postinstall(self): + '''Do some post-install setup work with runtime-postinstall.tmpl''' + # copy configdir into runtime root beforehand + configdir = joinpaths(self._runner.templatedir,"config_files") + configdir_path = "tmp/config_files" + fullpath = joinpaths(self.vars.root, configdir_path) + if os.path.exists(fullpath): + remove(fullpath) + copytree(configdir, fullpath) + self._runner.run("runtime-postinstall.tmpl", configdir=configdir_path)
    + +
    [docs] def cleanup(self): + '''Remove unneeded packages and files with runtime-cleanup.tmpl''' + self._runner.run("runtime-cleanup.tmpl")
    + +
    [docs] def verify(self): + '''Ensure that contents of the installroot can run''' + status = True + + ELF_MAGIC = b'\x7fELF' + + # Iterate over all files in /usr/bin and /usr/sbin + # For ELF files, gather them into a list and we'll check them all at + # the end. For files with a #!, check them as we go + elf_files = [] + usr_bin = Path(self.vars.root + '/usr/bin') + usr_sbin = Path(self.vars.root + '/usr/sbin') + for path in (str(x) for x in itertools.chain(usr_bin.iterdir(), usr_sbin.iterdir()) \ + if x.is_file()): + with open(path, "rb") as f: + magic = f.read(4) + if magic == ELF_MAGIC: + # Save the path, minus the chroot prefix + elf_files.append(path[len(self.vars.root):]) + elif magic[:2] == b'#!': + # Reopen the file as text and read the first line. + # Open as latin-1 so that stray 8-bit characters don't make + # things blow up. We only really care about ASCII parts. + with open(path, "rt", encoding="latin-1") as f_text: + # Remove the #!, split on space, and take the first part + shabang = f_text.readline()[2:].split()[0] + + # Does the path exist? + if not os.path.exists(self.vars.root + shabang): + logger.error('%s, needed by %s, does not exist', shabang, path) + status = False + + # Now, run ldd on all the ELF files + # Just run ldd once on everything so it isn't logged a million times. + # At least one thing in the list isn't going to be a dynamic executable, + # so use execWithCapture to ignore the exit code. + filename = '' + for line in execWithCapture('ldd', elf_files, root=self.vars.root, + log_output=False, filter_stderr=True).split('\n'): + if line and not line[0].isspace(): + # New filename header, strip the : at the end and save + filename = line[:-1] + elif 'not found' in line: + logger.error('%s, needed by %s, not found', line.split()[0], filename) + status = False + + return status
    + +
    [docs] def writepkgsizes(self, pkgsizefile): + '''debugging data: write a big list of pkg sizes''' + fobj = open(pkgsizefile, "w") + getsize = lambda f: os.lstat(f).st_size if os.path.exists(f) else 0 + q = self.dbo.sack.query() + for p in sorted(q.installed()): + pkgsize = sum(getsize(joinpaths(self.vars.root,f)) for f in p.files) + fobj.write("{0.name}.{0.arch}: {1}\n".format(p, pkgsize))
    + +
    [docs] def generate_module_data(self): + root = self.vars.root + moddir = joinpaths(root, "lib/modules/") + for kernel in findkernels(root=root): + ksyms = joinpaths(root, "boot/System.map-%s" % kernel.version) + logger.info("doing depmod and module-info for %s", kernel.version) + runcmd(["depmod", "-a", "-F", ksyms, "-b", root, kernel.version]) + generate_module_info(moddir+kernel.version, outfile=moddir+"module-info")
    + +
    [docs] def create_runtime(self, outfile="/var/tmp/squashfs.img", compression="xz", compressargs=None, size=2): + # make live rootfs image - must be named "LiveOS/rootfs.img" for dracut + compressargs = compressargs or [] + workdir = joinpaths(os.path.dirname(outfile), "runtime-workdir") + os.makedirs(joinpaths(workdir, "LiveOS")) + + imgutils.mkrootfsimg(self.vars.root, joinpaths(workdir, "LiveOS/rootfs.img"), + "Anaconda", size=size) + + # squash the live rootfs and clean up workdir + imgutils.mksquashfs(workdir, outfile, compression, compressargs) + remove(workdir)
    + +
    [docs] def finished(self): + """ Done using RuntimeBuilder + + Close the dnf base object + """ + self.dbo.close()
    + +
    [docs]class TreeBuilder(object): + '''Builds the arch-specific boot images. + inroot should be the installtree root (the newly-built runtime dir)''' + def __init__(self, product, arch, inroot, outroot, runtime, isolabel, domacboot=True, doupgrade=True, + templatedir=None, add_templates=None, add_template_vars=None, workdir=None, extra_boot_args=""): + + # NOTE: if you pass an arg named "runtime" to a mako template it'll + # clobber some mako internal variables - hence "runtime_img". + self.vars = DataHolder(arch=arch, product=product, runtime_img=runtime, + runtime_base=basename(runtime), + inroot=inroot, outroot=outroot, + basearch=arch.basearch, libdir=arch.libdir, + isolabel=isolabel, udev=udev_escape, domacboot=domacboot, doupgrade=doupgrade, + workdir=workdir, lower=string_lower, + extra_boot_args=extra_boot_args) + self._runner = LoraxTemplateRunner(inroot, outroot, templatedir=templatedir) + self._runner.defaults = self.vars + self.add_templates = add_templates or [] + self.add_template_vars = add_template_vars or {} + self.templatedir = templatedir + self.treeinfo_data = None + + @property + def kernels(self): + return findkernels(root=self.vars.inroot) + +
    [docs] def rebuild_initrds(self, add_args=None, backup="", prefix=""): + '''Rebuild all the initrds in the tree. If backup is specified, each + initrd will be renamed with backup as a suffix before rebuilding. + If backup is empty, the existing initrd files will be overwritten. + If suffix is specified, the existing initrd is untouched and a new + image is built with the filename "${prefix}-${kernel.version}.img" + + If the initrd doesn't exist its name will be created based on the + name of the kernel. + ''' + add_args = add_args or [] + dracut = ["dracut", "--nomdadmconf", "--nolvmconf"] + add_args + if not backup: + dracut.append("--force") + + if not self.kernels: + raise Exception("No kernels found, cannot rebuild_initrds") + + # Hush some dracut warnings. TODO: bind-mount proc in place? + open(joinpaths(self.vars.inroot,"/proc/modules"),"w") + for kernel in self.kernels: + if prefix: + idir = os.path.dirname(kernel.path) + outfile = joinpaths(idir, prefix+'-'+kernel.version+'.img') + elif hasattr(kernel, "initrd"): + # If there is an existing initrd, use that + outfile = kernel.initrd.path + else: + # Construct an initrd from the kernel name + outfile = kernel.path.replace("vmlinuz-", "initrd-") + ".img" + logger.info("rebuilding %s", outfile) + if backup: + initrd = joinpaths(self.vars.inroot, outfile) + if os.path.exists(initrd): + os.rename(initrd, initrd + backup) + cmd = dracut + [outfile, kernel.version] + runcmd(cmd, root=self.vars.inroot) + + # ppc64 cannot boot images > 32MiB, check size and warn + if self.vars.arch.basearch in ("ppc64", "ppc64le") and os.path.exists(outfile): + st = os.stat(outfile) + if st.st_size > 32 * 1024 * 1024: + logging.warning("ppc64 initrd %s is > 32MiB", outfile) + + os.unlink(joinpaths(self.vars.inroot,"/proc/modules"))
    + +
    [docs] def build(self): + templatefile = templatemap[self.vars.arch.basearch] + for tmpl in self.add_templates: + self._runner.run(tmpl, **self.add_template_vars) + self._runner.run(templatefile, kernels=self.kernels) + self.treeinfo_data = self._runner.results.treeinfo + self.implantisomd5()
    + +
    [docs] def implantisomd5(self): + for _section, data in self.treeinfo_data.items(): + if 'boot.iso' in data: + iso = joinpaths(self.vars.outroot, data['boot.iso']) + runcmd(["implantisomd5", iso])
    + + @property + def dracut_hooks_path(self): + """ Return the path to the lorax dracut hooks scripts + + Use the configured share dir if it is setup, + otherwise default to /usr/share/lorax/dracut_hooks + """ + if self.templatedir: + return joinpaths(self.templatedir, "dracut_hooks") + else: + return "/usr/share/lorax/dracut_hooks" + +
    [docs] def copy_dracut_hooks(self, hooks): + """ Copy the hook scripts in hooks into the installroot's /tmp/ + and return a list of commands to pass to dracut when creating the + initramfs + + hooks is a list of tuples with the name of the hook script and the + target dracut hook directory + (eg. [("99anaconda-copy-ks.sh", "/lib/dracut/hooks/pre-pivot")]) + """ + dracut_commands = [] + for hook_script, dracut_path in hooks: + src = joinpaths(self.dracut_hooks_path, hook_script) + if not os.path.exists(src): + logger.error("Missing lorax dracut hook script %s", (src)) + continue + dst = joinpaths(self.vars.inroot, "/tmp/", hook_script) + copy2(src, dst) + dracut_commands += ["--include", joinpaths("/tmp/", hook_script), + dracut_path] + return dracut_commands
    + +#### TreeBuilder helper functions + +
    [docs]def findkernels(root="/", kdir="boot"): + # To find possible flavors, awk '/BuildKernel/ { print $4 }' kernel.spec + flavors = ('debug', 'PAE', 'PAEdebug', 'smp', 'xen', 'lpae') + kre = re.compile(r"vmlinuz-(?P<version>.+?\.(?P<arch>[a-z0-9_]+)" + r"(.(?P<flavor>{0}))?)$".format("|".join(flavors))) + kernels = [] + bootfiles = os.listdir(joinpaths(root, kdir)) + for f in bootfiles: + match = kre.match(f) + if match: + kernel = DataHolder(path=joinpaths(kdir, f)) + kernel.update(match.groupdict()) # sets version, arch, flavor + kernels.append(kernel) + + # look for associated initrd/initramfs/etc. + for kernel in kernels: + for f in bootfiles: + if f.endswith('-'+kernel.version+'.img'): + imgtype, _rest = f.split('-',1) + # special backwards-compat case + if imgtype == 'initramfs': + imgtype = 'initrd' + kernel[imgtype] = DataHolder(path=joinpaths(kdir, f)) + + logger.debug("kernels=%s", kernels) + return kernels
    + +# udev whitelist: 'a-zA-Z0-9#+.:=@_-' (see is_whitelisted in libudev-util.c) +udev_blacklist=' !"$%&\'()*,/;<>?[\\]^`{|}~' # ASCII printable, minus whitelist +udev_blacklist += ''.join(chr(i) for i in range(32)) # ASCII non-printable +
    [docs]def udev_escape(label): + out = '' + for ch in label: + out += ch if ch not in udev_blacklist else '\\x%02x' % ord(ch) + return out
    + +
    [docs]def string_lower(string): + """ Return a lowercase string. + + :param string: String to lowercase + + This is used as a filter in the templates. + """ + return string.lower()
    +
    + +
    + +
    +
    + + +
    + +
    +

    + © Copyright 2018-2019, Red Hat, Inc. + +

    +
    + Built with Sphinx using a theme provided by Read the Docs. + +
    + +
    +
    + +
    + +
    + + + + + + + + + + + + \ No newline at end of file diff --git a/rhel8-branch/_modules/pylorax/treeinfo.html b/rhel8-branch/_modules/pylorax/treeinfo.html new file mode 100644 index 00000000..ceabf445 --- /dev/null +++ b/rhel8-branch/_modules/pylorax/treeinfo.html @@ -0,0 +1,257 @@ + + + + + + + + + + + pylorax.treeinfo — Lorax 28.14.33 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + + + +
    + + + + + +
    + +
    + + + + + + + + + + + + + + + + + +
    + + + + +
    +
    +
    +
    + +

    Source code for pylorax.treeinfo

    +#
    +# treeinfo.py
    +#
    +# Copyright (C) 2010-2015 Red Hat, Inc.
    +#
    +# This program is free software; you can redistribute it and/or modify
    +# it under the terms of the GNU General Public License as published by
    +# the Free Software Foundation; either version 2 of the License, or
    +# (at your option) any later version.
    +#
    +# This program is distributed in the hope that it will be useful,
    +# but WITHOUT ANY WARRANTY; without even the implied warranty of
    +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    +# GNU General Public License for more details.
    +#
    +# You should have received a copy of the GNU General Public License
    +# along with this program.  If not, see <http://www.gnu.org/licenses/>.
    +#
    +# Red Hat Author(s):  Martin Gracik <mgracik@redhat.com>
    +#
    +
    +import logging
    +logger = logging.getLogger("pylorax.treeinfo")
    +
    +import configparser
    +import time
    +
    +
    +
    [docs]class TreeInfo(object): + + def __init__(self, product, version, variant, basearch, + packagedir=""): + + self.c = configparser.ConfigParser() + + section = "general" + data = {"timestamp": str(time.time()), + "family": product, + "version": version, + "name": "%s-%s" % (product, version), + "variant": variant or "", + "arch": basearch, + "packagedir": packagedir} + + self.c.add_section(section) + list(self.c.set(section, key, value) for key, value in data.items()) + +
    [docs] def add_section(self, section, data): + if not self.c.has_section(section): + self.c.add_section(section) + + list(self.c.set(section, key, value) for key, value in data.items())
    + +
    [docs] def write(self, outfile): + logger.info("writing .treeinfo file") + with open(outfile, "w") as fobj: + self.c.write(fobj)
    +
    + +
    + +
    +
    + + +
    + +
    +

    + © Copyright 2018-2019, Red Hat, Inc. + +

    +
    + Built with Sphinx using a theme provided by Read the Docs. + +
    + +
    +
    + +
    + +
    + + + + + + + + + + + + \ No newline at end of file diff --git a/rhel8-branch/_sources/composer-cli.rst.txt b/rhel8-branch/_sources/composer-cli.rst.txt new file mode 100644 index 00000000..e9f055dc --- /dev/null +++ b/rhel8-branch/_sources/composer-cli.rst.txt @@ -0,0 +1,62 @@ +composer-cli +============ + +:Authors: + Brian C. Lane + +``composer-cli`` is used to interact with the ``lorax-composer`` API server, managing blueprints, exploring available packages, and building new images. + +It requires `lorax-composer `_ to be installed on the +local system, and the user running it needs to be a member of the ``weldr`` +group. They do not need to be root, but all of the `security precautions +`_ apply. + +composer-cli cmdline arguments +------------------------------ + +.. argparse:: + :ref: composer.cli.cmdline.composer_cli_parser + :prog: composer-cli + +Edit a Blueprint +---------------- + +Start out by listing the available blueprints using ``composer-cli blueprints +list``, pick one and save it to the local directory by running ``composer-cli +blueprints save http-server``. If there are no blueprints available you can +copy one of the examples `from the test suite +`_. + +Edit the file (it will be saved with a .toml extension) and change the +description, add a package or module to it. Send it back to the server by +running ``composer-cli blueprints push http-server.toml``. You can verify that it was +saved by viewing the changelog - ``composer-cli blueprints changes http-server``. + +Build an image +---------------- + +Build a ``qcow2`` disk image from this blueprint by running ``composer-cli +compose start http-server qcow2``. It will print a UUID that you can use to +keep track of the build. You can also cancel the build if needed. + +The available types of images is displayed by ``composer-cli compose types``. +Currently this consists of: alibaba, ami, ext4-filesystem, google, live-iso, +openstack, partitioned-disk, qcow2, tar, vhd, vmdk + +Monitor the build status +------------------------ + +Monitor it using ``composer-cli compose status``, which will show the status of +all the builds on the system. You can view the end of the anaconda build logs +once it is in the ``RUNNING`` state using ``composer-cli compose log UUID`` +where UUID is the UUID returned by the start command. + +Once the build is in the ``FINISHED`` state you can download the image. + +Download the image +------------------ + +Downloading the final image is done with ``composer-cli compose image UUID`` and it will +save the qcow2 image as ``UUID-disk.qcow2`` which you can then use to boot a VM like this:: + + qemu-kvm --name test-image -m 1024 -hda ./UUID-disk.qcow2 diff --git a/rhel8-branch/_sources/index.rst.txt b/rhel8-branch/_sources/index.rst.txt new file mode 100644 index 00000000..40acd5a6 --- /dev/null +++ b/rhel8-branch/_sources/index.rst.txt @@ -0,0 +1,34 @@ +.. Lorax documentation master file, created by + sphinx-quickstart on Wed Apr 8 13:46:00 2015. + You can adapt this file completely to your liking, but it should at least + contain the root `toctree` directive. + +Welcome to Lorax's documentation! +================================= + +Contents: + +.. toctree:: + :maxdepth: 1 + + intro + lorax + livemedia-creator + lorax-composer + composer-cli + product-images + modules + +Documentation for other Lorax Branches +====================================== + +* `Fedora 28 `_ +* `RHEL7 lorax-composer `_ + +Indices and tables +================== + +* :ref:`genindex` +* :ref:`modindex` +* :ref:`search` + diff --git a/rhel8-branch/_sources/index.txt b/rhel8-branch/_sources/index.txt new file mode 100644 index 00000000..c9b962d8 --- /dev/null +++ b/rhel8-branch/_sources/index.txt @@ -0,0 +1,27 @@ +.. Lorax documentation master file, created by + sphinx-quickstart on Wed Apr 8 13:46:00 2015. + You can adapt this file completely to your liking, but it should at least + contain the root `toctree` directive. + +Welcome to Lorax's documentation! +================================= + +Contents: + +.. toctree:: + :maxdepth: 1 + + intro + lorax + livemedia-creator + product-images + modules + + +Indices and tables +================== + +* :ref:`genindex` +* :ref:`modindex` +* :ref:`search` + diff --git a/rhel8-branch/_sources/intro.rst.txt b/rhel8-branch/_sources/intro.rst.txt new file mode 100644 index 00000000..01857ee9 --- /dev/null +++ b/rhel8-branch/_sources/intro.rst.txt @@ -0,0 +1,67 @@ +Introduction to Lorax +===================== + +I am the Lorax. I speak for the trees [and images]. + +Lorax is used to build the Anaconda Installer boot.iso, it consists of a +library, pylorax, a set of templates, and the lorax script. Its operation +is driven by a customized set of Mako templates that lists the packages +to be installed, steps to execute to remove unneeded files, and creation +of the iso for all of the supported architectures. + + + + + + +Before Lorax +============ + +Tree building tools such as pungi and revisor rely on 'buildinstall' in +anaconda/scripts/ to produce the boot images and other such control files +in the final tree. The existing buildinstall scripts written in a mix of +bash and Python are unmaintainable. Lorax is an attempt to replace them +with something more flexible. + + +EXISTING WORKFLOW: + +pungi and other tools call scripts/buildinstall, which in turn call other +scripts to do the image building and data generation. Here's how it +currently looks: + + -> buildinstall + * process command line options + * write temporary yum.conf to point to correct repo + * find anaconda release RPM + * unpack RPM, pull in those versions of upd-instroot, mk-images, + maketreeinfo.py, makestamp.py, and buildinstall + + -> call upd-instroot + + -> call maketreeinfo.py + + -> call mk-images (which figures out which mk-images.ARCH to call) + + -> call makestamp.py + + * clean up + + +PROBLEMS: + +The existing workflow presents some problems with maintaining the scripts. +First, almost all knowledge of what goes in to the stage 1 and stage 2 +images lives in upd-instroot. The mk-images* scripts copy things from the +root created by upd-instroot in order to build the stage 1 image, though +it's not completely clear from reading the scripts. + + +NEW IDEAS: + +Create a new central driver with all information living in Python modules. +Configuration files will provide the knowledge previously contained in the +upd-instroot and mk-images* scripts. + + + diff --git a/rhel8-branch/_sources/intro.txt b/rhel8-branch/_sources/intro.txt new file mode 100644 index 00000000..01857ee9 --- /dev/null +++ b/rhel8-branch/_sources/intro.txt @@ -0,0 +1,67 @@ +Introduction to Lorax +===================== + +I am the Lorax. I speak for the trees [and images]. + +Lorax is used to build the Anaconda Installer boot.iso, it consists of a +library, pylorax, a set of templates, and the lorax script. Its operation +is driven by a customized set of Mako templates that lists the packages +to be installed, steps to execute to remove unneeded files, and creation +of the iso for all of the supported architectures. + + + + + + +Before Lorax +============ + +Tree building tools such as pungi and revisor rely on 'buildinstall' in +anaconda/scripts/ to produce the boot images and other such control files +in the final tree. The existing buildinstall scripts written in a mix of +bash and Python are unmaintainable. Lorax is an attempt to replace them +with something more flexible. + + +EXISTING WORKFLOW: + +pungi and other tools call scripts/buildinstall, which in turn call other +scripts to do the image building and data generation. Here's how it +currently looks: + + -> buildinstall + * process command line options + * write temporary yum.conf to point to correct repo + * find anaconda release RPM + * unpack RPM, pull in those versions of upd-instroot, mk-images, + maketreeinfo.py, makestamp.py, and buildinstall + + -> call upd-instroot + + -> call maketreeinfo.py + + -> call mk-images (which figures out which mk-images.ARCH to call) + + -> call makestamp.py + + * clean up + + +PROBLEMS: + +The existing workflow presents some problems with maintaining the scripts. +First, almost all knowledge of what goes in to the stage 1 and stage 2 +images lives in upd-instroot. The mk-images* scripts copy things from the +root created by upd-instroot in order to build the stage 1 image, though +it's not completely clear from reading the scripts. + + +NEW IDEAS: + +Create a new central driver with all information living in Python modules. +Configuration files will provide the knowledge previously contained in the +upd-instroot and mk-images* scripts. + + + diff --git a/rhel8-branch/_sources/livemedia-creator.rst.txt b/rhel8-branch/_sources/livemedia-creator.rst.txt new file mode 100644 index 00000000..e9146776 --- /dev/null +++ b/rhel8-branch/_sources/livemedia-creator.rst.txt @@ -0,0 +1,641 @@ +livemedia-creator +================= + +:Authors: + Brian C. Lane + +livemedia-creator uses `Anaconda `_, +`kickstart `_ and `Lorax +`_ to create bootable media that use the +same install path as a normal system installation. It can be used to make live +isos, bootable (partitioned) disk images, tarfiles, and filesystem images for +use with virtualization and container solutions like libvirt, docker, and +OpenStack. + +The general idea is to use qemu with kickstart and an Anaconda boot.iso to +install into a disk image and then use the disk image to create the bootable +media. + +livemedia-creator --help will describe all of the options available. At the +minimum you need: + +``--make-iso`` to create a final bootable .iso or one of the other ``--make-*`` options. + +``--iso`` to specify the Anaconda install media to use with qemu. + +``--ks`` to select the kickstart file describing what to install. + +To use livemedia-creator with virtualization you will need to have qemu-kvm installed. + +If you are going to be using Anaconda directly, with ``--no-virt`` mode, make sure +you have the anaconda-tui package installed. + +Conventions used in this document: + +``lmc`` is an abbreviation for livemedia-creator. + +``builder`` is the system where livemedia-creator is being run + +``image`` is the disk image being created by running livemedia-creator + + +livemedia-creator cmdline arguments +----------------------------------- + +.. argparse:: + :ref: pylorax.cmdline.lmc_parser + :prog: livemedia-creator + + --macboot : @replace + Make the iso bootable on UEFI based Mac systems + + Default: True + + --nomacboot : @replace + Do not create a Mac bootable iso + + Default: False + + +Quickstart +---------- + +Run this to create a bootable live iso:: + + sudo livemedia-creator --make-iso \ + --iso=/extra/iso/boot.iso --ks=./docs/rhel-livemedia.ks + +You can run it directly from the lorax git repo like this:: + + sudo PATH=./src/sbin/:$PATH PYTHONPATH=./src/ ./src/sbin/livemedia-creator \ + --make-iso --iso=/extra/iso/boot.iso \ + --ks=./docs/rhel-livemedia.ks --lorax-templates=./share/ + +You can observe the installation using vnc. The logs will show what port was +chosen, or you can use a specific port by passing it. eg. ``--vnc vnc:127.0.0.1:5`` + +This is usually a good idea when testing changes to the kickstart. lmc tries +to monitor the logs for fatal errors, but may not catch everything. + + +How ISO creation works +---------------------- + +There are 2 stages, the install stage which produces a disk or filesystem image +as its output, and the boot media creation which uses the image as its input. +Normally you would run both stages, but it is possible to stop after the +install stage, by using ``--image-only``, or to skip the install stage and use +a previously created disk image by passing ``--disk-image`` or ``--fs-image`` + +When creating an iso qemu boots using the passed Anaconda installer iso +and installs the system based on the kickstart. The ``%post`` section of the +kickstart is used to customize the installed system in the same way that +current spin-kickstarts do. + +livemedia-creator monitors the install process for problems by watching the +install logs. They are written to the current directory or to the base +directory specified by the --logfile command. You can also monitor the install +by using a vnc client. This is recommended when first modifying a kickstart, +since there are still places where Anaconda may get stuck without the log +monitor catching it. + +The output from this process is a partitioned disk image. kpartx can be used +to mount and examine it when there is a problem with the install. It can also +be booted using kvm. + +When creating an iso the disk image's / partition is copied into a formatted +filesystem image which is then used as the input to lorax for creation of the +final media. + +The final image is created by lorax, using the templates in /usr/share/lorax/live/ +or the live directory below the directory specified by ``--lorax-templates``. The +templates are written using the Mako template system with some extra commands +added by lorax. + +.. note:: + The output from --make-iso includes the artifacts used to create the boot.iso; + the kernel, initrd, the squashfs filesystem, etc. If you only want the + boot.iso you can pass ``--iso-only`` and the other files will be removed. You + can also name the iso by using ``--iso-name my-live.iso``. + + +Kickstarts +---------- + +The docs/ directory includes several example kickstarts, one to create a live +desktop iso using GNOME, and another to create a minimal disk image. When +creating your own kickstarts you should start with the minimal example, it +includes several needed packages that are not always included by dependencies. + +Or you can use existing spin kickstarts to create live media with a few +changes. Here are the steps I used to convert the Fedora XFCE spin. + +1. Flatten the xfce kickstart using ksflatten +2. Add zerombr so you don't get the disk init dialog +3. Add clearpart --all +4. Add swap partition +5. bootloader target +6. Add shutdown to the kickstart +7. Add network --bootproto=dhcp --activate to activate the network + This works for F16 builds but for F15 and before you need to pass + something on the cmdline that activate the network, like sshd: + + ``livemedia-creator --kernel-args="sshd"`` + +8. Add a root password:: + + rootpw rootme + network --bootproto=dhcp --activate + zerombr + clearpart --all + bootloader --location=mbr + part swap --size=512 + shutdown + +9. In the livesys script section of the %post remove the root password. This + really depends on how the spin wants to work. You could add the live user + that you create to the %wheel group so that sudo works if you wanted to. + + ``passwd -d root > /dev/null`` + +10. Remove /etc/fstab in %post, dracut handles mounting the rootfs + + ``cat /dev/null > /dev/fstab`` + + Do this only for live iso's, the filesystem will be mounted read only if + there is no /etc/fstab + +11. Don't delete initramfs files from /boot in %post +12. When creating live iso's you need to have, at least, these packages in the %package section:: + dracut-config-generic + dracut-live + -dracut-config-rescue + grub-efi + memtest86+ + syslinux + +One drawback to using qemu is that it pulls the packages from the repo each +time you run it. To speed things up you either need a local mirror of the +packages, or you can use a caching proxy. When using a proxy you pass it to +livemedia-creator like this: + + ``--proxy=http://proxy.yourdomain.com:3128`` + +You also need to use a specific mirror instead of mirrormanager so that the +packages will get cached, so your kickstart url would look like: + + ``url --url="http://dl.fedoraproject.org/pub/fedora/linux/development/rawhide/x86_64/os/"`` + +You can also add an update repo, but don't name it updates. Add --proxy to it +as well. + + +Anaconda image install (no-virt) +-------------------------------- + +You can create images without using qemu by passing ``--no-virt`` on the +cmdline. This will use Anaconda's directory install feature to handle the +install. There are a couple of things to keep in mind when doing this: + +1. It will be most reliable when building images for the same release that the + host is running. Because Anaconda has expectations about the system it is + running under you may encounter strange bugs if you try to build newer or + older releases. + +2. It may totally trash your host. So far I haven't had this happen, but the + possibility exists that a bug in Anaconda could result in it operating on + real devices. I recommend running it in a virt or on a system that you can + afford to lose all data from. + +The logs from anaconda will be placed in an ./anaconda/ directory in either +the current directory or in the directory used for --logfile + +Example cmdline: + +``sudo livemedia-creator --make-iso --no-virt --ks=./rhel-livemedia.ks`` + +.. note:: + Using no-virt to create a partitioned disk image (eg. --make-disk or + --make-vagrant) will only create disks usable on the host platform (BIOS + or UEFI). You can create BIOS partitioned disk images on UEFI by using + virt. + +.. note:: + As of version 30.7 SELinux can be set to Enforcing. The current state is + logged for debugging purposes and if there are SELinux denials they should + be reported as a bug. + +AMI Images +---------- + +Amazon EC2 images can be created by using the --make-ami switch and an appropriate +kickstart file. All of the work to customize the image is handled by the kickstart. +The example currently included was modified from the cloud-kickstarts version so +that it would work with livemedia-creator. + +Example cmdline: + +``sudo livemedia-creator --make-ami --iso=/path/to/boot.iso --ks=./docs/rhel-livemedia-ec2.ks`` + +This will produce an ami-root.img file in the working directory. + +At this time I have not tested the image with EC2. Feedback would be welcome. + + +Appliance Creation +------------------ + +livemedia-creator can now replace appliance-tools by using the --make-appliance +switch. This will create the partitioned disk image and an XML file that can be +used with virt-image to setup a virtual system. + +The XML is generated using the Mako template from +/usr/share/lorax/appliance/libvirt.xml You can use a different template by +passing ``--app-template
    + + + +
    + + + + + +
    + + +
    + +
    + +