From e17db4e29a667eef73934ec9c13311120f1d5158 Mon Sep 17 00:00:00 2001 From: "Brian C. Lane" Date: Thu, 19 Dec 2019 14:03:12 -0800 Subject: [PATCH] Add lorax 31.10 documentation --- fedora-31/.buildinfo | 4 + fedora-31/.doctrees/composer-cli.doctree | Bin 0 -> 43020 bytes fedora-31/.doctrees/composer.cli.doctree | Bin 0 -> 261026 bytes fedora-31/.doctrees/composer.doctree | Bin 0 -> 63426 bytes fedora-31/.doctrees/environment.pickle | Bin 0 -> 2364566 bytes fedora-31/.doctrees/index.doctree | Bin 0 -> 7349 bytes fedora-31/.doctrees/intro.doctree | Bin 0 -> 9092 bytes fedora-31/.doctrees/livemedia-creator.doctree | Bin 0 -> 169984 bytes fedora-31/.doctrees/lorax-composer.doctree | Bin 0 -> 117462 bytes fedora-31/.doctrees/lorax.doctree | Bin 0 -> 71296 bytes fedora-31/.doctrees/modules.doctree | Bin 0 -> 2507 bytes fedora-31/.doctrees/product-images.doctree | Bin 0 -> 7155 bytes fedora-31/.doctrees/pylorax.api.doctree | Bin 0 -> 861125 bytes fedora-31/.doctrees/pylorax.doctree | Bin 0 -> 536194 bytes fedora-31/README | 5 + fedora-31/_modules/composer/cli.html | 254 + .../_modules/composer/cli/blueprints.html | 778 ++ fedora-31/_modules/composer/cli/cmdline.html | 250 + fedora-31/_modules/composer/cli/compose.html | 714 ++ fedora-31/_modules/composer/cli/modules.html | 248 + fedora-31/_modules/composer/cli/projects.html | 310 + fedora-31/_modules/composer/cli/sources.html | 352 + fedora-31/_modules/composer/cli/status.html | 256 + .../_modules/composer/cli/utilities.html | 295 + fedora-31/_modules/composer/http_client.html | 458 + fedora-31/_modules/composer/unix_socket.html | 259 + fedora-31/_modules/index.html | 243 + fedora-31/_modules/pylorax.html | 650 + fedora-31/_modules/pylorax/api/bisect.html | 249 + .../_modules/pylorax/api/checkparams.html | 244 + fedora-31/_modules/pylorax/api/cmdline.html | 263 + fedora-31/_modules/pylorax/api/compose.html | 1442 +++ fedora-31/_modules/pylorax/api/config.html | 338 + .../_modules/pylorax/api/crossdomain.html | 264 + fedora-31/_modules/pylorax/api/dnfbase.html | 386 + .../_modules/pylorax/api/flask_blueprint.html | 254 + fedora-31/_modules/pylorax/api/gitrpm.html | 422 + fedora-31/_modules/pylorax/api/projects.html | 897 ++ fedora-31/_modules/pylorax/api/queue.html | 906 ++ fedora-31/_modules/pylorax/api/recipes.html | 1478 +++ fedora-31/_modules/pylorax/api/server.html | 294 + fedora-31/_modules/pylorax/api/timestamp.html | 251 + fedora-31/_modules/pylorax/api/toml.html | 233 + fedora-31/_modules/pylorax/api/utils.html | 249 + fedora-31/_modules/pylorax/api/v0.html | 2186 ++++ fedora-31/_modules/pylorax/api/v1.html | 368 + fedora-31/_modules/pylorax/api/workspace.html | 299 + fedora-31/_modules/pylorax/base.html | 267 + fedora-31/_modules/pylorax/buildstamp.html | 266 + fedora-31/_modules/pylorax/cmdline.html | 515 + fedora-31/_modules/pylorax/creator.html | 947 ++ fedora-31/_modules/pylorax/decorators.html | 230 + fedora-31/_modules/pylorax/discinfo.html | 245 + fedora-31/_modules/pylorax/dnfbase.html | 385 + fedora-31/_modules/pylorax/dnfhelper.html | 310 + fedora-31/_modules/pylorax/executils.html | 549 + fedora-31/_modules/pylorax/imgutils.html | 754 ++ fedora-31/_modules/pylorax/installer.html | 866 ++ fedora-31/_modules/pylorax/ltmpl.html | 1088 ++ fedora-31/_modules/pylorax/monitor.html | 403 + fedora-31/_modules/pylorax/mount.html | 304 + fedora-31/_modules/pylorax/sysutils.html | 360 + fedora-31/_modules/pylorax/treebuilder.html | 603 + fedora-31/_modules/pylorax/treeinfo.html | 263 + fedora-31/_sources/composer-cli.rst.txt | 62 + fedora-31/_sources/composer.cli.rst.txt | 86 + fedora-31/_sources/composer.rst.txt | 37 + fedora-31/_sources/index.rst.txt | 36 + fedora-31/_sources/intro.rst.txt | 67 + fedora-31/_sources/livemedia-creator.rst.txt | 657 + fedora-31/_sources/lorax-composer.rst.txt | 526 + fedora-31/_sources/lorax.rst.txt | 152 + fedora-31/_sources/modules.rst.txt | 8 + fedora-31/_sources/product-images.rst.txt | 27 + fedora-31/_sources/pylorax.api.rst.txt | 174 + fedora-31/_sources/pylorax.rst.txt | 165 + fedora-31/_static/ajax-loader.gif | Bin 0 -> 673 bytes fedora-31/_static/basic.css | 763 ++ fedora-31/_static/comment-bright.png | Bin 0 -> 756 bytes fedora-31/_static/comment-close.png | Bin 0 -> 829 bytes fedora-31/_static/comment.png | Bin 0 -> 641 bytes fedora-31/_static/css/badge_only.css | 1 + fedora-31/_static/css/theme.css | 6 + fedora-31/_static/doctools.js | 314 + fedora-31/_static/documentation_options.js | 10 + fedora-31/_static/down-pressed.png | Bin 0 -> 222 bytes fedora-31/_static/down.png | Bin 0 -> 202 bytes fedora-31/_static/file.png | Bin 0 -> 286 bytes fedora-31/_static/fonts/Inconsolata-Bold.ttf | Bin 0 -> 108360 bytes .../_static/fonts/Inconsolata-Regular.ttf | Bin 0 -> 95960 bytes fedora-31/_static/fonts/Lato-Bold.ttf | Bin 0 -> 657188 bytes fedora-31/_static/fonts/Lato-BoldItalic.ttf | Bin 0 -> 699008 bytes fedora-31/_static/fonts/Lato-Italic.ttf | Bin 0 -> 723544 bytes fedora-31/_static/fonts/Lato-Regular.ttf | Bin 0 -> 657212 bytes fedora-31/_static/fonts/Lato/lato-bold.eot | Bin 0 -> 256056 bytes fedora-31/_static/fonts/Lato/lato-bold.ttf | Bin 0 -> 657188 bytes fedora-31/_static/fonts/Lato/lato-bold.woff | Bin 0 -> 309728 bytes fedora-31/_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 fedora-31/_static/fonts/Lato/lato-italic.eot | Bin 0 -> 268604 bytes fedora-31/_static/fonts/Lato/lato-italic.ttf | Bin 0 -> 723544 bytes fedora-31/_static/fonts/Lato/lato-italic.woff | Bin 0 -> 328412 bytes .../_static/fonts/Lato/lato-italic.woff2 | Bin 0 -> 195704 bytes fedora-31/_static/fonts/Lato/lato-regular.eot | Bin 0 -> 253461 bytes fedora-31/_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 fedora-31/_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 fedora-31/_static/jquery-3.2.1.js | 10253 ++++++++++++++++ fedora-31/_static/jquery.js | 4 + fedora-31/_static/js/modernizr.min.js | 4 + fedora-31/_static/js/theme.js | 3 + fedora-31/_static/language_data.js | 297 + fedora-31/_static/minus.png | Bin 0 -> 90 bytes fedora-31/_static/plus.png | Bin 0 -> 90 bytes fedora-31/_static/pygments.css | 69 + fedora-31/_static/searchtools.js | 506 + fedora-31/_static/underscore-1.3.1.js | 999 ++ fedora-31/_static/underscore.js | 31 + fedora-31/_static/up-pressed.png | Bin 0 -> 214 bytes fedora-31/_static/up.png | Bin 0 -> 203 bytes fedora-31/_static/websupport.js | 808 ++ fedora-31/composer-cli.html | 386 + fedora-31/composer.cli.html | 1103 ++ fedora-31/composer.html | 502 + fedora-31/genindex.html | 1453 +++ fedora-31/index.html | 240 + fedora-31/intro.html | 260 + fedora-31/livemedia-creator.html | 1088 ++ fedora-31/lorax-composer.html | 769 ++ fedora-31/lorax.html | 530 + fedora-31/modules.html | 296 + fedora-31/objects.inv | Bin 0 -> 4128 bytes fedora-31/product-images.html | 233 + fedora-31/py-modindex.html | 481 + fedora-31/pylorax.api.html | 4415 +++++++ fedora-31/pylorax.html | 2229 ++++ fedora-31/search.html | 218 + fedora-31/searchindex.js | 1 + 156 files changed, 57394 insertions(+) create mode 100644 fedora-31/.buildinfo create mode 100644 fedora-31/.doctrees/composer-cli.doctree create mode 100644 fedora-31/.doctrees/composer.cli.doctree create mode 100644 fedora-31/.doctrees/composer.doctree create mode 100644 fedora-31/.doctrees/environment.pickle create mode 100644 fedora-31/.doctrees/index.doctree create mode 100644 fedora-31/.doctrees/intro.doctree create mode 100644 fedora-31/.doctrees/livemedia-creator.doctree create mode 100644 fedora-31/.doctrees/lorax-composer.doctree create mode 100644 fedora-31/.doctrees/lorax.doctree create mode 100644 fedora-31/.doctrees/modules.doctree create mode 100644 fedora-31/.doctrees/product-images.doctree create mode 100644 fedora-31/.doctrees/pylorax.api.doctree create mode 100644 fedora-31/.doctrees/pylorax.doctree create mode 100644 fedora-31/README create mode 100644 fedora-31/_modules/composer/cli.html create mode 100644 fedora-31/_modules/composer/cli/blueprints.html create mode 100644 fedora-31/_modules/composer/cli/cmdline.html create mode 100644 fedora-31/_modules/composer/cli/compose.html create mode 100644 fedora-31/_modules/composer/cli/modules.html create mode 100644 fedora-31/_modules/composer/cli/projects.html create mode 100644 fedora-31/_modules/composer/cli/sources.html create mode 100644 fedora-31/_modules/composer/cli/status.html create mode 100644 fedora-31/_modules/composer/cli/utilities.html create mode 100644 fedora-31/_modules/composer/http_client.html create mode 100644 fedora-31/_modules/composer/unix_socket.html create mode 100644 fedora-31/_modules/index.html create mode 100644 fedora-31/_modules/pylorax.html create mode 100644 fedora-31/_modules/pylorax/api/bisect.html create mode 100644 fedora-31/_modules/pylorax/api/checkparams.html create mode 100644 fedora-31/_modules/pylorax/api/cmdline.html create mode 100644 fedora-31/_modules/pylorax/api/compose.html create mode 100644 fedora-31/_modules/pylorax/api/config.html create mode 100644 fedora-31/_modules/pylorax/api/crossdomain.html create mode 100644 fedora-31/_modules/pylorax/api/dnfbase.html create mode 100644 fedora-31/_modules/pylorax/api/flask_blueprint.html create mode 100644 fedora-31/_modules/pylorax/api/gitrpm.html create mode 100644 fedora-31/_modules/pylorax/api/projects.html create mode 100644 fedora-31/_modules/pylorax/api/queue.html create mode 100644 fedora-31/_modules/pylorax/api/recipes.html create mode 100644 fedora-31/_modules/pylorax/api/server.html create mode 100644 fedora-31/_modules/pylorax/api/timestamp.html create mode 100644 fedora-31/_modules/pylorax/api/toml.html create mode 100644 fedora-31/_modules/pylorax/api/utils.html create mode 100644 fedora-31/_modules/pylorax/api/v0.html create mode 100644 fedora-31/_modules/pylorax/api/v1.html create mode 100644 fedora-31/_modules/pylorax/api/workspace.html create mode 100644 fedora-31/_modules/pylorax/base.html create mode 100644 fedora-31/_modules/pylorax/buildstamp.html create mode 100644 fedora-31/_modules/pylorax/cmdline.html create mode 100644 fedora-31/_modules/pylorax/creator.html create mode 100644 fedora-31/_modules/pylorax/decorators.html create mode 100644 fedora-31/_modules/pylorax/discinfo.html create mode 100644 fedora-31/_modules/pylorax/dnfbase.html create mode 100644 fedora-31/_modules/pylorax/dnfhelper.html create mode 100644 fedora-31/_modules/pylorax/executils.html create mode 100644 fedora-31/_modules/pylorax/imgutils.html create mode 100644 fedora-31/_modules/pylorax/installer.html create mode 100644 fedora-31/_modules/pylorax/ltmpl.html create mode 100644 fedora-31/_modules/pylorax/monitor.html create mode 100644 fedora-31/_modules/pylorax/mount.html create mode 100644 fedora-31/_modules/pylorax/sysutils.html create mode 100644 fedora-31/_modules/pylorax/treebuilder.html create mode 100644 fedora-31/_modules/pylorax/treeinfo.html create mode 100644 fedora-31/_sources/composer-cli.rst.txt create mode 100644 fedora-31/_sources/composer.cli.rst.txt create mode 100644 fedora-31/_sources/composer.rst.txt create mode 100644 fedora-31/_sources/index.rst.txt create mode 100644 fedora-31/_sources/intro.rst.txt create mode 100644 fedora-31/_sources/livemedia-creator.rst.txt create mode 100644 fedora-31/_sources/lorax-composer.rst.txt create mode 100644 fedora-31/_sources/lorax.rst.txt create mode 100644 fedora-31/_sources/modules.rst.txt create mode 100644 fedora-31/_sources/product-images.rst.txt create mode 100644 fedora-31/_sources/pylorax.api.rst.txt create mode 100644 fedora-31/_sources/pylorax.rst.txt create mode 100644 fedora-31/_static/ajax-loader.gif create mode 100644 fedora-31/_static/basic.css create mode 100644 fedora-31/_static/comment-bright.png create mode 100644 fedora-31/_static/comment-close.png create mode 100644 fedora-31/_static/comment.png create mode 100644 fedora-31/_static/css/badge_only.css create mode 100644 fedora-31/_static/css/theme.css create mode 100644 fedora-31/_static/doctools.js create mode 100644 fedora-31/_static/documentation_options.js create mode 100644 fedora-31/_static/down-pressed.png create mode 100644 fedora-31/_static/down.png create mode 100644 fedora-31/_static/file.png create mode 100644 fedora-31/_static/fonts/Inconsolata-Bold.ttf create mode 100644 fedora-31/_static/fonts/Inconsolata-Regular.ttf create mode 100644 fedora-31/_static/fonts/Lato-Bold.ttf create mode 100644 fedora-31/_static/fonts/Lato-BoldItalic.ttf create mode 100644 fedora-31/_static/fonts/Lato-Italic.ttf create mode 100644 fedora-31/_static/fonts/Lato-Regular.ttf create mode 100644 fedora-31/_static/fonts/Lato/lato-bold.eot create mode 100644 fedora-31/_static/fonts/Lato/lato-bold.ttf create mode 100644 fedora-31/_static/fonts/Lato/lato-bold.woff create mode 100644 fedora-31/_static/fonts/Lato/lato-bold.woff2 create mode 100644 fedora-31/_static/fonts/Lato/lato-bolditalic.eot create mode 100644 fedora-31/_static/fonts/Lato/lato-bolditalic.ttf create mode 100644 fedora-31/_static/fonts/Lato/lato-bolditalic.woff create mode 100644 fedora-31/_static/fonts/Lato/lato-bolditalic.woff2 create mode 100644 fedora-31/_static/fonts/Lato/lato-italic.eot create mode 100644 fedora-31/_static/fonts/Lato/lato-italic.ttf create mode 100644 fedora-31/_static/fonts/Lato/lato-italic.woff create mode 100644 fedora-31/_static/fonts/Lato/lato-italic.woff2 create mode 100644 fedora-31/_static/fonts/Lato/lato-regular.eot create mode 100644 fedora-31/_static/fonts/Lato/lato-regular.ttf create mode 100644 fedora-31/_static/fonts/Lato/lato-regular.woff create mode 100644 fedora-31/_static/fonts/Lato/lato-regular.woff2 create mode 100644 fedora-31/_static/fonts/RobotoSlab-Bold.ttf create mode 100644 fedora-31/_static/fonts/RobotoSlab-Regular.ttf create mode 100644 fedora-31/_static/fonts/RobotoSlab/roboto-slab-v7-bold.eot create mode 100644 fedora-31/_static/fonts/RobotoSlab/roboto-slab-v7-bold.ttf create mode 100644 fedora-31/_static/fonts/RobotoSlab/roboto-slab-v7-bold.woff create mode 100644 fedora-31/_static/fonts/RobotoSlab/roboto-slab-v7-bold.woff2 create mode 100644 fedora-31/_static/fonts/RobotoSlab/roboto-slab-v7-regular.eot create mode 100644 fedora-31/_static/fonts/RobotoSlab/roboto-slab-v7-regular.ttf create mode 100644 fedora-31/_static/fonts/RobotoSlab/roboto-slab-v7-regular.woff create mode 100644 fedora-31/_static/fonts/RobotoSlab/roboto-slab-v7-regular.woff2 create mode 100644 fedora-31/_static/fonts/fontawesome-webfont.eot create mode 100644 fedora-31/_static/fonts/fontawesome-webfont.svg create mode 100644 fedora-31/_static/fonts/fontawesome-webfont.ttf create mode 100644 fedora-31/_static/fonts/fontawesome-webfont.woff create mode 100644 fedora-31/_static/fonts/fontawesome-webfont.woff2 create mode 100644 fedora-31/_static/jquery-3.2.1.js create mode 100644 fedora-31/_static/jquery.js create mode 100644 fedora-31/_static/js/modernizr.min.js create mode 100644 fedora-31/_static/js/theme.js create mode 100644 fedora-31/_static/language_data.js create mode 100644 fedora-31/_static/minus.png create mode 100644 fedora-31/_static/plus.png create mode 100644 fedora-31/_static/pygments.css create mode 100644 fedora-31/_static/searchtools.js create mode 100644 fedora-31/_static/underscore-1.3.1.js create mode 100644 fedora-31/_static/underscore.js create mode 100644 fedora-31/_static/up-pressed.png create mode 100644 fedora-31/_static/up.png create mode 100644 fedora-31/_static/websupport.js create mode 100644 fedora-31/composer-cli.html create mode 100644 fedora-31/composer.cli.html create mode 100644 fedora-31/composer.html create mode 100644 fedora-31/genindex.html create mode 100644 fedora-31/index.html create mode 100644 fedora-31/intro.html create mode 100644 fedora-31/livemedia-creator.html create mode 100644 fedora-31/lorax-composer.html create mode 100644 fedora-31/lorax.html create mode 100644 fedora-31/modules.html create mode 100644 fedora-31/objects.inv create mode 100644 fedora-31/product-images.html create mode 100644 fedora-31/py-modindex.html create mode 100644 fedora-31/pylorax.api.html create mode 100644 fedora-31/pylorax.html create mode 100644 fedora-31/search.html create mode 100644 fedora-31/searchindex.js diff --git a/fedora-31/.buildinfo b/fedora-31/.buildinfo new file mode 100644 index 00000000..bdaf0cf6 --- /dev/null +++ b/fedora-31/.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: a0f5869288e3cf083da4dd876b927545 +tags: 645f666f9bcd5a90fca523b33c5a78b7 diff --git a/fedora-31/.doctrees/composer-cli.doctree b/fedora-31/.doctrees/composer-cli.doctree new file mode 100644 index 0000000000000000000000000000000000000000..72f5b9122f4cf953f688c82be8c6b5450994daad GIT binary patch literal 43020 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 A_y7O^ literal 0 HcmV?d00001 diff --git a/fedora-31/.doctrees/composer.cli.doctree b/fedora-31/.doctrees/composer.cli.doctree new file mode 100644 index 0000000000000000000000000000000000000000..5c7734f8955f844c052b06f7d7fac4584a36a789 GIT binary patch literal 261026 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\lV=9 zC3Sbv*}qcgj&FRhL-P=&Aw@4`8q#EH1Qj5f%iJAnWuIk(h#1%2BDptB#GqTb;j4`((9u4(sr@eW_)J_k`Ln-oY zH$w8GOsm*fN=$CVASjO>+cpKm<`1pa{EJ$%6_{+b%V8KpH|Uv`7MAaBw^Me<<>p%_ znhY})I51BtW_YPp`ila#?8y9I7+-TZj?v(JM`M=ur{*!E7o+w(=xGmz=b=5p187=T z!t=*H6~OTPQBPS6&z;J4FFgN?LzU$4{ErUlZiVLutff_Zxmkmj1EIRy03nRezXM9R zN(=`(7&Dc!QdWfE{xChFGqYHWx`nBNPvzy<9dJr`n~Ws1?UVvIY8fM6$R*~ zgII)~BEfSdSh_;pT8@B!{EorS;gnZV`eIZFZeBf!(x2;LHtkJMMZLgn$atY9UBTR6ug3>6eJ*AJ%faklxWwY^!Ixx zNptEB5Y0BHW{uK6=HUn$Ep$YeM=KJM(-e(dV-Kjg`Jjig zG-}^OXJlFlGe+r82)fvlKX@4k7mLz=EOcj0z(+kqX-LsanT9ld1)wP1+#NGT>8=e% za&J0HN4L78^aCz%Md>Q2p(s6fM)YX2msyLaT>Rp%=o?i{17ZAyEhWdHSES^H!?w~6 z2!v854%IzMPtKlhDr#FZJ~^t||LtqhzDA4mB|arPU8MD#Ps!etxzFS^(cm5fa3@H*7l6Obp>}cr z{uYOH&jaxDKnZsMJ}ar`2*5-C#scsop}8;s*S~TG;HWd)*i`^N41epDES&ao0DjQL z^dVok!N6A$N|n-hz1hM8WM+{v)6PSZCu8sxR0cj`hx++Fm%0pV&`0dZ5@+x%@9^z( zHZ2+UC00`H7{BMCA?+Cd1Jx=Aq$t=GTxkWB&>C#ogKJ}#%HrdBE3Cz{RE8sbDgnN# z(yFP$xA3yr%Nq4fB`t-QW}4L!JZ#J_aG7b;N7RGIdaaIr(ju}nnW2{w1id5kzgM2M2(# ze{30C1>$VEf;yWWgF2VEpw5MJ`dljZk_*nK2tLdX=YBnxdYfPgkEX%#YgGj&j;SaW z#~GhXeZQcdh3h*6(E_->ebY1Z)PKPTpc8h90yz6425>HM0h|ka_JAt(m<#N$795)$ z?1TJ(>LY@+Jo;urd{)H0e%KA=NfuJAW`NHjfs0L};J zN4M61%JD;7njWSI5RZ0T5j|?1ckL3JEVv)+U^cTj4kz+BGx_n zQ^d+vEAm`gvi9ciV|slPzT8-w+_*MqPBuMBn(#bmtL(yhs-&UkAks|*4 zBCY47h(DFN&*XK{;2tSrCrG+S5r5O6b}~hLzeBp`6!8t9gqtG1Pg2i85r_VbQN$H! zE~JR{ubdPy>I@qYMG=p}-*ofmX)ja6hY>}LWDKr5>YG>Q)y^@R*i)Lgh)nk6;Z=6+cZD^@1wi=@L!#07OO zoKvb8d&vdo7YRPh4(EPR#a|LE;n6fW{#RAOiDN2C#c@We_+ddk3)c?`qD6512(-cic;r+$Ph0U z6ta+is32Md`AeW}wp}5g4UZw8OI*n3!hvUqQPW&AW|1%su^E#bcB3dU#QS^9Lt=d>0p2t^cqo|ia2LH(jp8O`fsHnj zox}pWBHU!RYZiD7_{PlwzXnuJWPu$!;&MCvLDDuqDyyF7HAH*-fnJtV@4zy0<|SCE zPxRt*vMEpWMjsV!PR>lj`%z58bUG+iCLGtd>T!LGJg(|_-dPk6pXWWX0DT^PyOuE` ze4N+$b}bU?pvXh5Qs3G_mD3;QHA3|7T6mda;kRp9ZKb3MNGkSrEvH72$9U)7e$11k zyt3<5+rq-hf#_3<#(c9xC6qFx6_0+OfM-LIVrt;ajOn>T4|*?53&2@EHDNWhbW$L4 zEo#d5JWaurKxj(vU9_stDS@APs*WjvpD5YAU*fveS@Tu+p1n9Uk0!t+A92tSoy|IkI zzd%P}MnL~^WCZpwPnoNYgHbo~&^D?J`%RS)_yYV*dtaXPazfzQ_@-buemqjEG}gl# zy5M9ou1aQ=O)BQKDYyoF1891I;3C`=(~j`-sHmp=ufWPlk5+g2ba=x&l>d96ZMIxR&1`lo zYUUDG)Xar_qx?|=S`jpqeJTG}2>!*Ppwrg=} zIu_J_Du~)p4?YgU87Ti>f;d~Qpw4E;pw1;OsB__*QvTRWE;xTv@L_g1_lxpBbXEHP zlSk9wxTGpLaZE+2IL=7B-vk74UKJnL8Em zQ&2gc3Q+8+3Hp$#%X=VvnEWfev5}-io>zU>A%W-B)Iu61yPK_y`)!R0Oe!T15=t2d zif8?c00P51A79+GSH4ngr-Nrzg&jOAUW=Nt^Cjt9EMp4ttf48v zPEf6rXSLpFey4f3fIgf+&UJl7q2#Fma*X?V$|B$ARJMD3-^mVDlKH+99MZk!`*sB# z+$K-qDyW!1E+n z4{89Ss)C#Fwy2l>?q^i=Ojqw`T!-2uk%-;?io%OMY$g_QBkEPA!5NtMGu|c`z}rW& zb$+d?;M_V>QR>#&^%6!}{ai&1GId{hzo0B4j5xtN1W|iios|>(0JP11QQK;EN^D!r zC9Z8X7v^|BBi7aT&CUfT<-Po`7QBKEr0poeRoafxcC@8LWqzK&nm_~2zoVo40}mx> zPCWvm+2)k|GDW>55an2BudgWl3Kdnm96efIUs3plha+gT&=Fl8t;o9=X~ZJe*aK>A z?tE$bMhT%sqqYb{vyEED_cI$Z?)b(BJ2Veb8dCI9rXfv^ zfKUO72hH6v)B71+dyC}Wbi9Rbb;ny*fniDU7DX_5W38i2cr#iZhwmVH9jl4HpV7n_ z(T0*w7NvbBz_gY6{YE3y*`f68?Q^3Q%7bveW=cS}36?PK8wXj6`{ve%Vd%GW)MX~A z-FZ2>uHEQq69#~xO~K31ygnbad4s3w7&^XA$>u+3^X?*ji3e@&D$;t+gEseM?lXBw zG{DEe+X<5H1>WCrsGS^mKj4t=b>RJS(7_#ee?!vF5qO90?c5g!W6)d}c<@~?Ajtrxq>>I9fLZTxS-C3b9%G}d&vdo z>jfWXhjYJ<*4!sp!lP+${AE?aiDN2C#c{@?H9rv4vvB>0AX)_1k3!q*359ERLk!nk z;=(l-_Uvd4_LvLfUl9D69pi(1v}Uh0>AOuHeKQZ9r7Ae*0Trdr1Mz6hQb8dL`AY=R zBFG3AhdUv$lWr*JBMV?tI zef3FCYmnv*tqDGXhV_}|{fejRNb`O{$>yhdzf+_yk>-7@Nb5Oi-d|_#GkGC2kVl%= z36k#7yo)Z2@5_>D-USZnUemmv21mPT-t8pq95ip}-WbjM4(KSPdG)V+G%u3Qh!%0mhyqI1YD9v=?|6s;{ZwW3h750V(+uhyB4F z(%rtqN~&e`0uK#|3Vt4{RSrneEtLwc3J&3z!o*V*RlylgQBi6UXOOPN-8+5vYGvP{)G$mjqE8>cMRwoPi3y55(DW1$8z%26ZlRL7fZdlnTaP za>4md!H3!5+%GD4-sSPFmc4o6(KI;zqcYuzV=79;aYib5PeDBk*Sia%MR2_rw9TGS zxMnxRaLpwyTytU1s9@|d7sh|zb&L-(6?~z99v*!&4_2rO&UrvZsq;Xjg4YQOS;${2 zh!#QqD74MCE9A4`G30ZJ3;A3)@Ki8rnrp_KCyYbvu8xY65dpI&0`XLQ$^pre6G_Wh? zO&$8d!gwCE-cScGqc4-JNvmmuX;S zCsZ;NL6R{50^QE7G^bX3(8|i8Sy&MOx2E124|pXYxX5tVbHy36k#7z-KztPNsoR zcSzfjOndw3>R4;@RCPAk5k7Vu*%a-J7ZyQzb<@;%eWc!+y;YUB;M-o+)@f6>WN;lT_lOL>$wNaTgI|hjl><_AOC^KfE;xjv3KLPi zMOAP{R8*82Q3+)5KM3j|f`|;hOAxh}j;v(x$DnPtT*Xstb}XLa5?4IMg?%G~Q3F~n zG?abG;90@HI21$%zd?x(IvM;^!5|)R1NFyM1t-+0s0h^mEU05a{TV^jhI;TN5bnH7 zhBwv2%}teVn!&s)JE6{I$Dqz7E~sU84?vrWblhUS|u{rgj5{A#K>U7Kt(>X6TKLQ zcaNcahk{2voD~i4knlCSNLCWz>xyoZovsPrFM(&=gzqz;aw6gD*bkT6sb6<#^T%t{ zCw3@mj(=f?#q1a5oA2PHeqaYbT(i);nhp3s;0w#OUCf2{Q1sYvtJ0e3{Ju__NI0Ym zuTn$00RBnaO8}_V=XJJ2aYdWfmO$8kMuC?RM!!DP)Fy;q*BP3a9Gw}jE^`>#@d}Jk zr}nC}6Va*%;Xt&O(aPXk5{rIWXKC0}S{^`k3#Y*ka9BGWHj!vJy{jbU130^et(4s_ zTkQC#gZ6|Wg4~4+BSl!BEMUlRkx0KkhjBC~V+PBd^*x(~q3y;V`%=`36`ocg?H*bY zoR0=|(C+!(vUs(p0!V0I;VFysuT$CX(Z4eeRg&r7X@_*T=->SkzN(@S9ez}0C8*$L ze^=CSZM?Q|G=GWomLs_9Ai z5?iyRXGH83i;3ktM}qfa$3ww;P#3Qcsn5v-SFcxmC;7nnB8hIlUh$J21`}iaG1RL} zOTxgsUhzJ`01g#QnDk{;!5Jn|QEHgvdWRw%(smUw!qmOw2ZFM=$tM2y5kb@rp|bM7 zk3!q*7ZpOWQ(_?$m$*VGF3jb)4q1ORTD_cTbP7Ys6Z%E6)Htl;Ex1CIVM;^w!y?MOk4p$AmAz|Wd|Ek zfr9XRuX}oCc6+yHbgP3uuCJ%Nr~CDLuV24kcTaEPDn-eaM4I9NkIlPM5G$p2h?tSd z5@x(!@gV~(@xkxB3GGe4BCfk$@q>ouXjC!sg=?0gs1zx2DU(PC<6t5{V*hY<%yhk? z&aD{Snn2yeRz2$OqGSE2oAFw{*OujjVTdmRyaI5uFV~N^hhg5KaQn95a69=^upO^j zt9sSGU$ixpQlrTE9q%-A^R160>s`ICo3%>V=YK8!B)grL>0O`$!v?Pw-UG$C0-{`+8`9?g%N=+mJ2h{3(nlyephMQC0;Y0&&O{SZt7dLkM#HUs+S5SM^nDWDn9 z?>|~RLBEYk=SOqR`CO$_FE(vuTcZ}LJAV4`+7Igr6`4urn?ey7AGl`NjS)? z&xhi0z4q?h%#0Ebo~sSWh9%Kzx^8u@W{XuAAuzX9#QKad=+23F%|>HWGW1K~*bv`a z{DKzW%dDaJKI3tKB?Eb+84}TV3`OHkeO5&OVbrZS!H8b5p%2lk937%pnR{cxP9Js_N9m0X~tPGa&JKe$w^w`#V#KlBY^DT?3DH4j3#Q_j`+mrBi* z9<0S%Ar-xC-+ydpvtdtri_M+Wxt(66ZQB%?p2vk+B2qnRPwzY~T^cvX<+*InE8!dS zcwy)9uqPL-{)jL81Yh=M=F7SSUxo`)o{rFYi-TVj>olbH`gNMSKyv>&4P)F;cm%&L z^rtZ1J>PDA*lt+#OODojwPw?$b16~z9=#tutE+P0;)HPGhvDgKb@k=vY8|@;kIl1) z;){l}ErZ6yarQA%GM;LJhex^MqU%4_Ur6lHH*8nxO9>3F&s4*M&2%GWPYIDnJ$35T z=^jKrkra*?=Mgs7W={sa$w~5lDJ6M?*H5P`OL$$|mC@n#&uB;)jMtyglwNtf-U1bR zyxuj@r@`wHgZuFMeW)(N>*DD`@j4NWDV_291BgqXPpPLFug~1xY@D>)9w52W-y9hi ze2nciks6vu{@L4b^2+#@QflW65jo}jInkZQBh9afQQ^(|rzHPYWb^*z6bz8A>q|se zUYeX#oA=X7k~~f1@*(O!3W%ZdcDXEP7HK{S?R$-qbj5pa#TaO|0=(r zh5ItA$K!S$jjul#KG<4)+^k{}-d}1c8u!(+!uv7Qt$NPzUUj<<-m4rPyjPi5YNe=T z5$N+V=%@x^AbM@mkZt={3{s7ObW+rmDB(peIx>)ct3iN7q#RARplG(y^qvI2g>B^J zvR%1dSSe%cX_s>_mNUG>$%ZmlY_;r0*~WQI;fyS^mPowItO$B=FR_3IIX3TIdd;O3In z)4Ud{_6cO1h$i?YHZt_uC_M?=95orA(myNY>fmf9L zBy*dCZAPdW1eCRm8y!%7+e7_M>R_O}O;dX1f$~3s)q0@3)kL2LC`SzLbxNJ5(NF}G z#nXiXWg?m^Je^ek3&h1}j|PJoDCZA17vSHW%GvF9v+YiYTiLX2Q);%`cFD_~EMk2w z931IiP{YSL1P+42I}D6elX%|w7Ij8!S|6a7S8CJxffOW47whMVE=4K)2;-*p4Z_Ui z^5tsDfQB!~@-lXSqtN5yRR&gzD4 zDCa5!tyO+O3tDAXk5`xkt*fa=p@xWuBtgGoAc#aSVe2D?qH)hMD{TE3>Q;Sc*s40- z2U}H+4z{Yy9VQVfJ_N?17$Q`!9K>P>U}1Q$Nmm1A%9%HCjfzUImlW4jtK4-y!bQ!1 zHY1SvdJ1CYDEk_UW*cQ|ybku(gfjLhE%aOFDyi^r`L=$&_5Ii&2{Ja8cmPZey|YaRT~{UhZpFBHXOX+ z_r;v$s*|oO)tnNmGeg3ga`vPUh5SZd`V_P~9`es58MzCrbFBu;Nq}=Q6MArd5F`%* z=hE?6&Mxpi9Bn&MT(AoV?>llJjZk2QkEqEs-<*v0QA>2qzne2k84V=JOHhM3OxY*q=`Na0F4;j z2SAUYx(I-Zrwaw3L^PZg2B1d~m%gjgJ~IH_8Jno&*bozM? z$eD7!K@_Ijlf9T$fcIkmRB~uV_G14gMaQL2_5#tBmo_8SUhLH{6)_x3dr6`2%C=Xm z*0g7<4aVkG1I5aR4pHmB@(WtjDzkb3Kt|Mh$-`#dk*M{*4YbE0L{`+g3S_9hGip^G z??bIBM~7Nf=2o4+)X)jE*%(Xoz8K-XMrFuW>pvSf6GNt?hbEUyBGc!&s2Q0mz#`X6 z)U)a>&$2(0Leg@u+>D|b2MZlMnK@>+nx)GA<2aV$R-28Pwq3J}u02z1mnxx!yV_h* z(H*2H44EA!ah;lB@w&;x) za_IKj0kA7k*D`R|_C!T1bq%9HmM4gp zQ+A4ASkx)!JJi1(7}k5RZz3*nno>_QPRn>UR=Qgm z-%?}Fc_(-Y{o7|?shZ&O!9}$n4Buvnrj^=>Jd~p6(yO_h=*ml5lM255-yEeqX6TZ_ zI3d2fpI^}8JDD{U-$lNg_6S?cKo04aM0a&V(YRZe72UN_x9T~gJJszzbfcdOKj7-)wvO7KI36_lW)KFyC@-+i3 zapU5A9EF#M8DBLt7aQ8Iq$nyyN?gh$(&4s6V#aXB&4d|s{>|Xl1ZE_*>M`SWb0*9f z)twIvw>m|aAMy2C>UeDb4O;_lNlJC6HCv%L5+v6W zJ32`ITN+XZL-NmRN{D z$qT56RLrZqO?n)0VH_i6GsEv~_rP}0DI7kwV=vhyOdd^`BryU8WvemaJWI_^IcJHI zblagLG@5AmjO?~{@6+t(ue-O1^Gddd&6BXt@g&txHdW_RbW(bE-zBp0QWB}K^DJ4^ zTpkxtwTf-mo-KeZzD|ly^xj@C*QyO%71mzp)Ya_TbA~r&P$mQMknF&lh7Ksa7$W7@ z`2{UfmRUWnXmTf1cTu#|EL~QT*zuBCr6i6XGZc-xx><4bdep7>!Z=znr4L7|9375U znHO+}G`$-~PLXdoWQX*J25H9-G^uM!H~Tv&YL#wwI5so6**ZHmxVys5{wb2t^Q&OD z*UonuCAMJBxAE+JfO1|yEb+w}yE~dIY_;BBuu1uZ4UdPO9Wp)4ihSOox75O6jd~KO z-{fGQT^@7jstF;=ryrjQk3k?`P7!4H$178n%VHk!s$nKL7!$v9)2-~LcP|YlN*#QN zf!k4JdLh^lrjV`a7J{{|?ctmzuFed$l$$g))Lgo{h4@hJ24nZp7aVT)@vgi;Z=w*4 zFW3#cUG$o5ygyzpdNzKmpx(m6deMx9x=-M7oqX)HYk0yYNy(bS2}8<7b8A2sK2!*< zm~S>c92&J_nRj0rY;^GfNuyJ@mT>a4-bKm;-ObmsFjormSP0%OQm`G)DHeT&Y?W$7 z*9FOFQNExOHng#m-uA4TebTOV?_L$Gs}yVMaZRv=&j`!kB9VpG1Z&FnTxS9GO)M7M z4e-iBy>_vVlyR?(+W@IkT|bzpHd-CevKysl8Kt_xc*mQcxp~H|B7Rje)8db2Eb*~h z8+;~GOZa8vP0fy%tYr1*34SQ>%tP zb%TwyVq>9$sdu?$leBQamu06L7zV-EQC;NK~_lQ^4JZOX81`TCUwGH?5^Q zsnlltymZsG0mGsR3baNR z<9m?Y?(uFg(Xw0kVs+leP@=mZF^VW<4reed((NEeAKtk8_wHR>Tm%^OD$T}hv%Rpl zY@ghVlJ4GaFiCIF)gknTh08s`We;3ki}ac6Znz0-nP|_KdYYk>sF|z6X1rz-qqJ&! z^W03utJl!PxL2IR5GZ? z_EH5-SP4=RV-FG|`(xql6P*@_nSkx_svg)QhWlesl4hyen1`st@qYzb1h+GnEVtRN z&)H=R$x~>nV&m7v9}6Z+wPx{zWdrHetYW#0Gv{Ox{NOUXak2|I7_1eRz$O#6x!NdK z>2ozp{L(5@yaf$GD?Ijbl{PlQx13|^Bc+Nl2M8?5Gs}bX%JBAnsXV)Ue!Hw$?#jtMgWI+t#=*(ABF4ejrV!)c^{Wu$;QAeiaq!^Ph;i`pPQ*Akd@W)eeCs;IIQZf& z#D158>r`;|5FXD^@DinQaPl39aq#9I#5j0-7BLQP+=mzkfBjCxIQaZch;eY+yAb2x z+`AFu;G?%7#=-Vm5#!*?2N2`n);kd6;0+?fy6$ z_^cK_tAy{6P83)l&zU==_;&;g%C@3Yv^I^^!NxP2BiT7;~97O~Ib^;xt&i`8e5 z`VPso!164xEPaRMSYYw_EIOaX<~t;}0*lLMQTZ$;pGD-eczlQCQ(&?94#}m!;_z7% zK8wL;5%|o0pZQ;4w)>sR_K)EEN*>PZEAOrB5o7rd=ijc!kjCPI{LyCRH?0A@B*6W4 zyjIzMyvqfZCm4Es!J4WISG0@zcR6RtR!mjyklx<{ebtKfP_Ob)VJiM*6_kKYMVX8S zn~KkjA;zZSugGYyskoVp2Ahfo84WfSUm&Bwrs8EX8f+>ylhI&Pafpltn~Kw9G}u%; zIfWRTit}VN*i=lD(O^?CM@EB9#krk`v8gyhMuSbob7VBwRQwq1alSyd;TiNUyp*|@ zH&h@EZyc&lu86!9?+6YFd$fldVN>)aiamYE&?Xf~)h1OZ+dLb!$)@h_s3kUar^)EC zsryeddTi=GJ&PEdx|_-9v8j8Bj2@f1-y@^PrtT0KJvMdUC!@!v?qg*1*wkG^MvqP1 zACl2yQ+JSz9-F%7sGF~u`bq^-^_8lVef$=O}iP=Qo*P<4`yuTWIb!BfrC)DllM|3#AyPc=1~ba<-yZJKm=s`*=*ba<+v-)?c9 zpt)rjZB!r?ZP8D6I@h9RNgK~+^n-e0Dx>RRoIK4*!`h?*soIQwy2JT8YL;#Cd`Z{- zi>Z<>6cke>-IySzO8Rs~OqFM7(&VX<76P36Xwn=;8x=@JTeOYh6i~CIjpt)p2krzL z<1ROQfg4Lz{1^_o*zgQR3c;eVoNzbeDWV+QW;ovUxh8I8l?a)OUfGkVN{=UsjfbuB zOIIZ72f}T81gR%`>ykNGWdUeY#U^;Y(t@|^0uPD`6*fyGuUEoF4K|F85ppac0+~}nS|d3mdGRiR7s)uh-tflC*yz~PUP(SA@BhC$ zGhfzwS=H5}fCzf3^8N3<|9b!X|L=YF(?{1et=w!F8QEZzI*1 z)W9Ua5N*1(Gsh%uQ;~PXuSp^I0|zr8owpN2@^*oC-Uk1l3ICrB|DOx&dgl=~&qp@B zqPN@Ib8rNvUjw#5?RM%FMdj2Q(PX>n`Sryar&3|29t#`gu;r@ep|qJ3dsA!%upcNH z?9lRwYGM;pYAg10xJ8ne6$4FhKT-^o@DESA$3}3E zTBFiIRgnd;BT_F(=V-vNwWM@OQP772#W^;s9iojO3ZF|#62IC*5E!hNqn{xh!3)FY zua&?Zz)uQvLN43R7*T>o2pbv3n({uP3dW6+TqgG^nwSLUuZTwcdc|E#tr21E!9O)8mz^5jBb*lrrj!wNV5-h$<#E{ zTsnYZ2-aSGq0pEw=!TzhntrL%s&*kXtOc1LcbYPXnkAKQo>Nw%%Y>(X_L~48z^=y&iwannEx&?|2lZy_xQqy)|2Hz)j~eU zNBxH!qso0F8A-VAzN6FK2C|t+ZLzfqPTX|s6 zX&Q4!HzrT;mbGivBt?q09QEB}Wyl1lVYnlyJu)~AI(bvUDVo0O9u$oMpW#vyJ)e)* zg*?)ouQY0oU++fi+hL^}ZGtQAVzcU({SY>MBnX|>f(u#It`gg#v@sB}I-vC{UGKGM zlnh($dN+bo2HPozlO_%~z`T&dZ1BQb6&Gc&g>>ZWlEx*)j!%i5(u0p|dyGcrearzN zYhn9abc!yl0J|h1g`gje&v&X-nrgm=tLRJM3D2<|N~|IpwaSfpsAl3auUr#N;7VD5 zT*g!UA=-0`3o)`@2tBvJ;-OoCOgr=nVS`+~;?Q-4Rs#}dzL4^C5gruWLe+f8pk`F; zERq(75$F!C1z$Xf!$TenYZ;QldEc#8N{OgLmkFsyNV}pj*~Gdg1Lnp7aFD+N5#f;IlD~db{l38#q#2_Wu}2RhJE30OI5(-os^o2;@?D=CVTgl*@`1oy&^G z)6r$MmXi*eO#|+NBjt9-KR2i;<&H`!p>gu}BM(!-T^6G*QBvGLRDdFxXd(j@O6m~O zz=eO}>!BC~%C%^WCJ$nt6W@g*$tHJTop~j)P3~eK1^9z)a>4tQ*>o%N=g^dx9$^WG zYp~OX?~NAOjY!f`aOxFeY?j>cFx^K_Aym{yXRy^ll#SqTG>T=fcQge_f~JCNEp*2W zjJjK418?HlA!g=$S5~hHoe)F&7R>T&29;rNXtBd;0vm)u&8GW)11|%FB|2RyF1^n% zqhi%#7NmUH64KtmAhv9Kla^pbp)cY;iZAx=bRFrGC_1vcM5C-|qv3w6F&D7XZoX5e z&_A3S07gTu2G4?o(OA7fAvS`{K0|mzkgLe>o_^t|eTd!GE2ZD)xUD5COzKQsJqGBQ z97d1CF-D(FL`?4mejz$t9i#{mYj1(D#j&Ta3d#&HiLJnl*7#a{+2CRvS9lS;;U%D@ z-VhyLIXF>O7{TnmCFI+zYJvxr_{F$1|J70&K$sM1g1=2MAF7*SLF_M*7XnT!LwNjXKIeY<$W36x&0hE94vSXeTzMXu&;4&AI$Fuep{26y< zZ=v4USalr)R}1I8^Sl{?gVfz)Y|x4mI)!6CWTY@IjdFmep;qfl1$Pk;7wEW=F+dJv zX1J<<7Fm<_y_MScW^4Nfhp@+h6@k?W&kqc9EEm&k(=p3?GWUB^YHC@H= z0S(6{s9;wLDrmI)1;6f8#o{XFf(Y(42qm*o1`*s%I%pvR+N8;(b3p{3HgJS1{ZUXI znEwF-sT$X#oT%2nhOwpa3?dN1ryv5+qJs!T<2H;EF^h?X5T)BdLhMOHa5CoW%4}BK zEg95;8e|C7Q9^1&sLrB+C5F+`OBjJj3QKdIxbIn{CNCR!l_p^R_Y&!#^*`D)sQ-P( zz>(sA|II+E`d{$xfH;{~^nj>d2XZMq^FJYc%Kt=*&i_Q?$#R#HhLbL+Z3ZvI{<*#I zn+D~iyf8cGL{bJ!wJk_r=5 zVgT6`WCVDiCQ=WPZm}Dd;8>C#Bj@WRJtAK}aFqinj{*Q#fl(J*=!+Q@^|iuA%?U=` zZow=w?ro?HQyLI6ZhkzfW?*N47?goW`Gy(MyV*`OZ$Zioi@M5X*xuoS;ZZz6Tfx4jL!ZECi_g0kxxckrw zggQqHLM2A(7l%4CF;21FC?A27Vm$Sa-3+y&fYcWaKE?qH1f-q;S{j|AUtTFdDj_u7 z=Z3dENla=oMLbi)!1oQr5OR*4{l41qlLqurr?d-V`nc-ZhFM3bUGRaR<&*UHF98pFtm>al z-086@sqJLl5kq3!u3@twSk)iEXS%ZG5-?*`m)r^%e!(eRb@dHbAHKTK za-pbchvd*5aw@E~@tChgZ)Ljv)|+PGbGzB7x5cT|03(Ps73>3_0T-RtxK1){BpYjS zn9+;CTzils3Udt~Sb3L)+$^JdC-PNfCSFNk#HsjETEo?l34s)`hGn{uRFw}iek~CD~d(q&-Z0zv3jHa`onrh4%AvHdm~d)>h~Dbi=+(P zxs{Nb!JQbUh*c$E18oe9EG&i%9k^rI#~(NFDb2`y_;aL#)`w}+pg#Pffg{C-zhWR& zeK`0i5a$4Pz6Rt{c;>@G_>>Qe7M%}^#vOXINhi%9058Nba(m&U1_hq&eG@aljcWJg;tp`%$ZWXKl&qQzst2vQq6y{rv8i9DoV;kar zPzy?FeG6jngwv4Syx7et7V2O&Lv^gM&2nNlzhJ>Ev)u)#3{$2Nv)zV@Uxvp)VfWWW zDu`>eT^NN_dDj~l8X(ZH`BI_g-G(WZz2-^_Qf6CJS1#N34hRgs;b~|t_(oR>WY0$7 zn~y?_(8D+Pf?&gdZ}wLj$LiIFQz_wNsaD|4S$gnB9j9ODW+u*!lA03WW^bX{YAitQ z)4uF*tK$yk#-axe&c=&*#Bm+~S{kXM+g1$6iR&?e;%td2h+`y)tMRq{SxbQs!I1(5 zkD_b|1m|rAgV6j;0aPK{7$Gnel@Q4S98yo9UQpN zA%LVa(J%m{|DoZ(CxG-lO$Rk0Sq%W`bHIZhK>Aw~cX|LxYC8oW-47#50EvF<4?se$ zVY?#$(kI|E4JmR3ngOI=x{5^&0Ff|`?=7^Qqj(FCFHoc_fB7nTOvlgV2r+&3j-tVX z4m}Jh&bKRsfZ6P$v@b(~EMP}_cEtYhx zK_N0fWOeveq=U8&r%jsdHrEY4cNjQQ>hSj(NY(T>FP2n-v8C{=4j00w>TuDbtHVWO ze^`)My8UBG$bnkBW$$T9et(5Qy-3Qiq{|7Z5lbSNxwuV81tkvMbn9UNmT0CDzfH)H zKs;#RQW}wY@B^fS)`Mx&pdS3Vfg{C(f8Ri=dT`JJ;v7iQ=Yd=b&pcQNpYmYQqVr(U zc(TrD(m}P&m>mHxx&7}G2IZvuueVn-6zNinQCZcBTYzQNdY;9otZL=^U9PHCmw#l7 zORLrv@T9L=*NhLRYTXB~L?8t#<}Ox6tNyVUb(nr@)*b2~MGx+shWD-vr8GSiwAm|@ z;$;GsrrUv*E`*i45nUBDb$`L;cq>gO;}^y9C79E>meOEdDy0d|LBSGr=@`>GEzIN_ zOybw!O5@$n2L@ ze8u4P3xt)5x3HTq#QQ?v1heYTT__Jt;L%Wc8Kf@R9OuJuE6WSQh$KutW)MbZUM%f= zgmloRowUiAc8+tw1aIO(oVOPYyeSFj^9E8i0nJ-NeFesrYG4VdP(vyK6)n01R5b3y zBd{!k3N=JM$-wb(yxa-t!v%)~8! zXu%>|V}A#vu*N=y|B#pa#GXQmF21Ex5B-{Zb*lw$Ht^>Wvno6FdLx7oNp6c0krH0G zhmlhWkFlrUg3$?>f@U6lk1E8ZqfG_lFsNM!tu>pVruRj%uD(Cpc0xsICEm+QX`f(_%4 znUw3Wm)budkX^3xVfroC--_ueA7phN4S3q%T58??B+$~Jw6b+Omsnr7%T}ds7Z*i* zCA-8QSxSR-yObvQ8VZ)E+gJRFfNxv!hL!xE5?cEMj&;`+=Ll;Ej2|J)g4%DJ2 zdyi6b^NPl; z344iU8zoy{cfnq{9qwVmVeg0bV-DBbjoFFpL5opYiH9-Yvc$WXkeatA0lM@CVb*Rk z@5XFn`YFt8+?ZnEwapFqv;wf8lxDXe22a=ylBu51+q|qSpR`a1vl*&mg>9A-Z`p6b zEVJD-D#Mgi#BA5kef?J(7#bk7WZl<)g<(o%Te;kVl-U;5mCLrh0|J9wc*dCva?vI9 z*|Sl|1*5hea=8lx8wTWZi3)R+I`C^4HF!CF#p+&(^R+kl>j&%?hPhZjTndoc3pZ=Q z3-?R&^~+`(_2Jy||4D-%@@gILtGFL%X%LHkeWh;s*Q+9h)SQ|{M_J~&s%UKZH|Jbr!6M6%FGLoL%=6#0 zz}w9Rg~;-qVHY=&4qEJjHVq2A%^NsUu#2*RR4p*_0&gCSErn;;g%Cc4U5FMPb|D&1 z81RN1sMT-w{;pI=*BjJ}qznhShLEl{@b<8QL1{ncybqBMTIZ!rgF5fi296Zx{epp1 zb>84EAkG22JqzSgc;>u9_>}XC7M=5o#w5HZ;=c}f!(O=^?lT6Jq#Uld8#CbTDvMEB zp^q`&ve4g8NLLJa`$r2V*~auEAT@4GvE;)BAsZU-wrNY;6Rd!@ap+`9?3m3^9V=|J zoWR>|3uc+^-j2#JB^5E-^#iq-cZRG!eTdHdBI={ToYB5GRwO1fM~v5;)n4-{thU zC2t6feU8xD17lyzJ$CjI;nd#oNNXv{tA+la$#p)i?L0hcS zra_CTe4f6e#t$WcMbbg*ytHXh=l!ICBgJ_?ZXi{iH@F>$b096B0&*!lb6z2Q z%6UbL&Ur;+E~Eu}<#xD^K_w}N%g(cqlp!r=T8zpnJB<03mE9IXx?)JnYZgqhjp7Il@&u)RY8!&rE( znG0jlI(>@W=M=HF}h z?}^>Kpy{yM*v%sFpvP{WH*u%OZltzT*v+rQh!VS@-}=LDkZahi2zGNPe5QdyE;BQB zb2@pG9wu7kH-X`|8t~N&aDNR4SF;I(*9PCmsi%VPA~$w#sToEnBhbv>FfFVKH1ksn zfmsIpPsmr1S>{a(&Aeq>Zx4_K9;_RI*3F535+d;XAUWZPdTJ$(K)1OBscihOz;%oxFyj{QOCqpvEvfx@d-P{%;d^dgxJVI|V&H2qQ}9k$&qBdPJ^aDr^G2KC^l z4IC*R`~?H4>cPQXK%4`Md=|*1@XUjS@F@=#EjkYtjasl#Y%ZBtB=*nkf1fcZC%^x# z3KsbT1KZLj%pu<(9kdQfn+A2rwI`eRdKOZDYG8g4hg=VANa2}73gJ@@DOz+6DH<){ zMd_Xv#E=@{*twncb%Wwk&e}T!^M^?-MrGIs<|~%i$9_V(Vp!xg7VgE8s;hw1m{i5^ ztP_ew-j3|%#UgLBPzSRas$+$1mJ^FSYQZeCT^p5QN{C~&>j#VcEdxUX1fVP|@}q_+ zap^KF@DMSc|o8!i?ZHfmL?yB!T! zB#tvU7D>3#-+nig`yO92_!x(b5Q}^jXlZ~N0v1WtN6^4;?fzi*o^H__i6rVso0C{1 zxhi&Cf<^v~r9g;9N`ZpcQMT2=B7bbjA!3n#PiXD2$k9`JCtuv0+OdsT3bm!R3bJ6zY59%SNj!%&cyax9A1ng zcSXJj`B^O_vTh+YOT3OCUqxo9H!Tu*+@KIyIkK|(!=!_@Y^F_vmd(Fy;0PU)mCX+s zNY$)0FB17XFt!w)mCZuJYh&Aa-fz}+1rs=_fx@d8q|xV42k>zAw3~T zcKxSaHM$fcMYVf2M139aSkN%e*(D_o_VkkKIOrpMd!hy zu}>rt`{(w*R}9L@?|-X;M4q#wcj_r^!W^7NWDH>TXo6DXEH~Stk^U{8tH2uzIcC{TAwAHbZr+u+4HJkxy7K%WU^JDkGQe z`avT9$iUD50VoTJ{6oW(xO5p3`DF`IW?NKOF5C7F2n>nj)lx1bQdf6o&qk5Rryxe? zk;s1l!FnK(a^PaLv(~6|s_wMz@#t=}lV6_p!mv4AuKI30oTgp6uJ^V(x(G2yvKb^R zQL+Lfb39g-gOR)mZ_3+5Be%C3-aI|one#Ss3=KdrK+THYB)<@y!RMdp)cwU@D^awO zkIa5UM=(i<5;SsWF^n}8jGo#%D?t9Y!sfFc=oAr70}&qN98(dzornqU0_`vjaTP>k zpud(6zpIUMJ`%~N(osIndXZ{wHz+n~9fd3o;3`~2@6CA9Tj@O0Tslx`lo?h5PnpCN z%@~=v4Vb$2@Zm#OHtKcw348c?X1E3O;MxHMz92nhp;)du?REiv*IUN~XyH8FbuDwF zvtidkJAFE4Ckh^U&&I7(^j_c>qVv;y#c#94A17~g!pkn&&#~<*qREQeE|0d_cvbUWzMYG51Vz<46WJ6(ZLuZWs{x0~-E&Lgb&&bQmH;-jN}_8;!Kw zdB4&P-U~eFA@az?ogN~W+D<{_`(Z>0k<)KIA##=D;2QX$LvJ*=7XBezV_5wXINb#> zD&79%`ZPo2m%htsyX^yo10*gUxDykF8JZ}}#J89`_X?uMTmak7ooq?%h{o6;UE#>` z5^(kvqQO`x9-VD5A&nnvqOmIcI#$c6c9l3jmCYy*JH1E*qa@z{M~#V#(S}9vjV?t$ z$D2!#Wx;j`*%f3~JZ}Kq2QQ)Cr-E;2#!yKW=ZYobe-8bkF_Z7!YTb6%~Tk(e|YvM%}#o#qm(YoeR7xiSY;s4c)U}M9zr{%L@ z@LiaQ7%%u9e!}1rd>{Y(82(6m1wVkVnAr)%+4qXk-0+fTIXTH`dZeRgq-Euui#-37w;qfM zq3BHq;(Oe0XTW=seye&N-@`Ha*#opR$giS8L~>=QqBx^?9xoXU-hn)$W`~h%+@Mij z&t&5|O$SxmG8P9ju*Jq=^?tmt3Bs$p*sS_xKg4h>qiwXSL<4hMxcxqL>*mQuG?nc} zU1gsTfnX|lw~1?g5+bdTNPs8Jmft1%<>Rv`RhS*JepH4 z3SwC0g{+k2$MYV%L#}{7@YQUz!a}?0mi>9(tza=)D*1IkES1F1dG*y-EWzM?$nR9J zh$19*57jS}`1*G2L8Eeq32W+k9mo%p=ya1E(g~bI_AUx1jnc5%4W3&ETg9hf>J*q1 zkce3fD2uS>vPVaO7+bp3F}q`uEtaxSu6|d`6@g}otlaMxl({IqY7R9T@Jr>iq|e4F z?C*%l&;T0CQRJvvk<D9U)5YuK-PXN%Fv`&*9-pq!_&~lY z`%29SF&`g=lo}2}y55bk?E4nzC;i`yl+Y^sBIre{Z1fOXWnYIJ2vj6^65WO7bJRrH zK}5*{m0lOac(lsyeay|$EuDL2PuVlwI*QUg59#1>^!;au)3cMXB9kkY1ZoZzmAzRx zF`UNB(-ceZb+D-P=Er|M4;JxMuE)XR1@C6nx|PkKx-O3kWV zVTzQe!i-qzxTnEDL2{;O8y9)H>6DK+3vO3LZ`oFmZHXi1^)xCI&9Ccat!T8}=(Ngi z*V~Pby*Aof?zCFq5pV=buFpoB`IV|)ce}IEIQ&|42zPk5yU|GyJvyOZZO_cNh$B^? ztbUJE?Z5%Az>v4jMiUEe9f0Mq(SrUH@TLm49Xhope1XFuoTdb0AAzqM*;fd&@C|-U zzFe9E`LPwI8^Ob402sH=HyUBR5xPp_!L`wrHh|^zPOY>EuMn(t;mTG#--Yw|My*Di zd^Xxiueep0Tqzy%Ll4gD0dNMEVMf+LT-e-lu`(`I-J@=`dvIN}(Q~Te>qvBxy9hNh zNE3G2oMH4X#XtEvM|FP~GKdt6y(+!jfArH!48YjV3zb z{PZtQw|)40M!d1)wpxu=$%A6O>b5}7$Z9$4Mw4(X8y{tajM9yEC0Y_g1mA)s8f~TH zN*;LcGvW=2&e1lMp$&@iKt)xMsT*ynI`xGPI4fwp0^irU^=@=>%Plurl~ToRy7dZ7 zgQx$qP#`tx^B^W@#IKZ^uoL-IZ+dg&C$x_8{J9AYO zgmF2>7lgMv+6=<9VF}PfZ}1vMR+{&#AROEfvbE_pONd{=QYsU9H{+E#I0Gu7Z$||@ zR%svDx9`}oV{k75pt$v!Mr&bT#XY(YDBJtG(GKi^BVvzI=+;2XA!v0Ru1}x4|K~w1 zTU+zx#58zCPICsICWQQ{J>$FKJekG|YgL$HB6Q|p2~I;wypZ-Q4~i?6WowzZe)p|e=>`~|NH|AU)us5a2UH@9mJ ztf$}T!18TF&y&e_`n6PTlpUtQU1iUKl>%0x%L*)p@uvj6k93;A%vOj!p&x>J=yE>} zPSPm*^?5KgU;o=NBD6bmak_18ZO*O0l3aqhJQt2{jz>Gn)rNDV8C_TYEH4BLOTu@FKrn@xiad5S}Ab;=;>H+zKFEk3sAAFoBAb;*b z9^Qw4@cfkiK@c+_f3T1U$e+iMup^|WBrXc- ziP(q}d{)wFdu)721X>|x9y^j_u@*Q*hP_RYZEZR&*b*Qpv|-z%1Bxvyc6pPyOd`<6 O3ht_G1EM9-%>M@;^#Tq6 literal 0 HcmV?d00001 diff --git a/fedora-31/.doctrees/environment.pickle b/fedora-31/.doctrees/environment.pickle new file mode 100644 index 0000000000000000000000000000000000000000..562bbfe5f45b7e23d53fa38dcebba94fdd54111a GIT binary patch literal 2364566 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

8b3XOHjE4U=?Nh`mB$ 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
~nB&QHY*c84N7R8(QkAV7Y%wJ26I}? zT4w?WEwr2H#~IbB`?G_Cpgq&9-6VNXLn-86ha0%eLteElp^c9*TolLCaqcp^D4Re9wfR4H`SVr2cZX^h}*6L^)yP?&J13L09pD7X#hcwH(js+Ez zZFch_$2Ke53InzcL9z;I7y`?J3Q}R(r&UfO2+dMKb3jMCeOmIA(JI>QAVC4G2DOAv zcI2D28Vm@08v<3KtRw`61O<2r?IBjwM)Y9NL0;u%f=K9Qc~xP+{?OFit_eb?1daPa zy`8fTJg&E6CRE{>f~H6_&qNS#k*8)OKFUtSRkJ*0K;Wayz3TUZ=6bU-r#YabMfi%2 zS1Mo8Vb@WQsacCq@}P#cuK6_%QnR+Mz(LE#+n7!x6v@&s-V_IPv_4<)w|x9OZNjFR z^yrMtX06W@70M`?uj$?x5v*n}b#C$&!#1~NoVq$CYe7b#SHXxWqE)h-#=Al~?GWCfoD zg>y!MZYEv4*`dBdiwUptF$1CQaF13Kqh4iPUG;k(I1ZtSIU>gm@l*xL2Z^-ED9PQno!cQ?mT~`<21UPF{j}c zhc9MA^}11Y$r$gk&DmlTYlcK9-lWS_y0k)<8g!lZexDB5rOjqE2@(|XjD++-%8B@2 zNHWB)`j2#}NqHD<=gQb$>oX!<3x(u0|8cr{lg?fzw07RTTU5OssDZyJ_Ur7a1S;aMOj_e zJvb^vg?ms3#RhwymURzcLXh*Tx>1XF?>$zx^KQ~onQ+=ZWBaHDAzCZ2v2w2z!m@eP zTsgu*`9o`J@p?pcT+w^j=?`XOnVIquR|irCIiy1OhSlv4X`jbn@IzY|;ZN_0qf>JFzu)3GU8$Zv=U|J!k6!-y) zH8m6A{3O<+BkRiJz5SDLjZ2QJ&ye=g-V2`B{ms;X*ga+2g@q%Ah~8f}Cxr(3HNK!m9kL zs2g%Rn5U#Gu$8Kl(I6Q3T8XO0LRI=K3hQhbhjw|N<$-II;}EY%S%&!*S;KWP->yv8 zg17f){XtK4!h&vfeq8~S@2&Bjz$5hVo_L727>~=>;mVGjUV#iu$^s7#efUr4n{j|t zEM%M!7er{vhCl#zglR$jqaz+syG=+@;#QLu0$*hVN#DkUZ@>nDhYewVpojSQm~cpK zHTl7VLm&Pf`GFp3G%9g=W&|0^AJG?nX{3*1x(KIVyp**|PWM!jQrXa_!-6xj8J&pD zvsfav@0@;fF1@HlEWl?bs>sEdL0x!$HtY9zhI<&Anz4yVy=#p1D6sde`knvt_aYK9 zPRb9+nh|sFtblvR_As2i->iW9O@jOF3b@}|?mI83<0pt2=jR>FhH5f(qH~!-AY#wG zEQT-JbS74~k}hMFo_bZ~1s?+P4O&vllbVw@om4_Qw(wC{pV6?zd)j#WDS$%tx_dw! zifuj$(Tr}RrKsT9Px`E6Fk?+xa6@||Ot@F1DVfl`3Y9i5IEO`kk11n%(=uczeIoR( z*=HyHV;c9=(Jz9SF+gM?fuN6s;syIK{~?qz28is-Qc0np;PMK8O~+BO+)}S@WKYvRB3;U+?u$M&Y1CX=C;Ihdo+0DT0*a1{@-#rI6603>fL{ zO*`^xg^V7phpEz3Sm^rU#6bND!)cMwTcah_^ksW?}4bHyEad`T59ku`kjqA`T zheMisex~+P2PaqOR2vDYfC$BPD5?fV7_5v@*&NI9EFkD%tKlf zG>~48XgzNz(JZ|{3KgDG-MJbCkf4AZVZIN1N3$H^SWvlQlJMVV#rR}vcu zY84*Sab%stA`;4Lk)?!uBJ{Xzp`YER)1-GeY@%74)3pLY2FvlF^~tNrA+6*;Xdmgt zh7+1A>Gbw!#EGj9A)B#O&BCU~gD>reBpC*LipTVz#U6FRXtM^5(jJ$4ossM+=hRvV zj&DH)8YX<6HsM&^?V-#O@sKe*4WN#FW0JJOr^Aqs@g8l+8?-6(G}zJM2H4(g+!r=v z%$9*AY)FD3e-p2$rw(bxY_d0@EkeOE>YOH6DivZXgg+9(w0Qlf9MSYX|06=3)9$QP zmRLxCD5TAtNEF>U)mEjj4~48P94b;Kd=|_etzV&in1{5DNnJH78*CX1RS}Xn!7KPM zMrOOoQU8DrkEYqVz3AfjrLtWJhP+Mvm$Vatw~M#UAHi1Mrm3I6Li*#^$AfmSJmx{4 z`%fQl@vtd3nN^_^SuZ2xV5#`Wha?#C*YFe_H`-@2;tBZ-ryD|qz9d8VR``w*)*S^A z?2K#|qN?Q$A4b^Fk7k3x(xC@L$m2^LuMoDO7e6l-dZ4Q1gV2ADc*8JLeg4a+bO014 zRMQa~pYVG$4OTZlq1!ne7|Pg?<0)4cO;N!Kj;QqyF^xk+9~+H((8G zzzkK!;?$-`w(bi<{`6)HAr+YNMLI_4Hi43Mw5r{A!lJ!5V381mVIQRp>&=2YiGF$m z1}PC3Qjw8)T`iThaM$ab$jF`)jQUMFcHEQEwZ5G<5Kn;|jQcEYTz_J`p2$%D`3CHA zN~f7b^ZIeK;*FSOm0(hZ6Nt@u6HY+Z`Cp|I4AtWvuSA=S=>AiYa>W}+xr8L*>(jK6 zv~Mjgh5zveOtV5TsKRyPxu^ub3D+saVA%hYj;ZL|ExPY$)+=Z@LG`Kj_z;L->E|zR zAR=?^Kybc`UQlhY=vxG*uY)D>>g2yO954U@P>o1c;>MFUt^P_uGP^;XbajR#bzqii8#2L~rFQyss6QnVJ7bwJ0$68@ zgTnyTj}QjThKWRZlIL|!iwnz!JZHc0s7qI>_o)-v=H{v#5X%^alnCU8h*}}ZRmJKh zH5HO?{}Sx0{O0uN43>&A0k~`QfkutZT2VS3t9#TB)>db1bux{>pleYS=$lDn;n|{@ZISSD4)3IvpyF0rAo8#u_H4QcI19*jjPiPy|F77o58W*J92s@qitppCO9z=Y9Fgd z`(^v?K8+sH9SxgDwD=w6jt>()t2AL-g+}Dm=NToRQ?Xyx#)Y-QNWhk>u;m^d9!!%<(~|Cq z69!~-a&2Om_hm!~GIX!`x~d?J%HX1=99M&oR|-2cls~k}yo{;n?G(qI(Gi^l*fi8^ zLlEMS9BZp9eTrT(#xrJCPl@r64*g3A`zGC>8Q+$au?qvjaiAR%YBr|t(*doAv7vquVSG5Ft1D!A&gk?bYagh$Wr;S#NJ$^FC89H@ zHEyD_NY@+&3Nc$~AN3DPS_mBMw#e8=hmifuFUx>ACgjc|79Y{^fFfiW`#PW$XB0() z#wXBt%qQY;4gQiLiH!U!bbL!R-$USQ2hvwfmU)++2$o~ zwlMq6l?9wr+C?Pzu;Es0L%J+4QaL33lrzE!zzSOt?sg`PE5a$gE7Mxhpke#OyGN8O zs5esSITnfUMDsAohZTApfO^imeBF7XO|w8Bu%b=llObz8hKqYYhh?m;uCIg~7K*<^ z#`;O!qs2K}*1w4kc*epcYepjCPf@C}Eb_B&%(5yaSa#jU89N{sr+!i`QmrM+p>jfw z4ec+WjejTBDYYr>*g1(7(*kMbk=)1?6@eNhSfz^#jTq2r(zHS=9>2;RHe-Yn4}eh9 zZDsi*T@XQ=Atptz4J)^4Q>W{pVS#Si@Jl>1xmOYB+%{t@9#WyJ8*^5d&!QX!HDGS5 zqCyl%D89en+i&0N$#WuZpWa>N*Hl8{eE=`2FUYmO7}430a&R?cUR81(2KaaO%V4xF z<4l-fx?UjwJi~|9#-s2VrcS0kzNg0=7v(S@zZ)Nin_+8Ab!V_#+W+Nt``({#)4l*T zX&r3N$(U7UfKIlE1hcOgk^AZz8lL|RWHJW(Lm9z>&^aT-Q)I%YWlWxi0*V3fC0bBU zj-oSeZ<;>@K4bL90#sbtPZkHIYxbufb{{{oKl>F$MtQXmsV0z6yk#Gz;ROnvc*xhy z*eqpHQa1svQs?Qd%~TvOt1iG$cd;#g_Cwt~wgnQ3=ekF;;fwYr|5xOpj7d8Es*YNZ z0`&Xc<6e97Snev$aJ>AQhMM;Qyun8*wzqf*5Vi1V%@GYx(=CazXl2yX3ZoS&fKa>@ zDk|~B`lF2QX|<{kh4MN--ks0}Df)*`RS=1j;h@a>Hkg71m7C@%TJcNA{nM0JXTXju z>tiR z#?hKFIA<8CKx!V;WQ-=lw@i!%!x-0DnxzVSvoeTdm|(dtEEJNIWZthdtr-qMWz0VK zh*;4uAxM7P2|gW@cPV=J`(4>`&KURdF_Eaxg|LX+=d?^eQe8H3EwobdQ9ro)b`_Ee z3P~y!E_&G@at`5cx{PrbpAyBchlT8?{tIfAAP?w&Uks^s4i~m$EO-cMkqHS2nDR;Z z@?AD%i`xlw!k8$v88fmWtlAQ*kYPv|C95}t6<`QeJ}ytFn0wXf(_x80Y-FrT2tn!C zuyh#kQTX0H>VzgTX2wK)NJ?7Z;bFpu;fvIcA4E}*v9%%OBn_}|$VV}-X_G|c$W_IF zhldGKE}#bUl&YAZ&RkV4aP%4jQun~G&H&IW4M_W^RT<#uFd)i=KXfKXZ!8m9IOL-o zKrZWe@?$?Zs&!T2cXSvKh2Q#2zuCR2LTKUj@}VzYsl4xoqtMeqYjNzaO5VZ|deQLW zT7cS?e5<|iKTl2{3e9qWU_+ex&aw(J4@8+SV-_q#B|WguhY?XDbc3>_Ktuft@zR6WQ<~Q+deu>p)iUtH6PuCNfIS}zduXSbu-ebZ zS)GPjOF}wq;8HcEi8tQVjEzNVNQZ3U?;m%DbUvYza zJPQM=3pmU9-U(KB=S)&MP-Fv-qB$_M+5bb^n8%Yw@u**3i2*89 zkI>MkQC+L=tn+hb)&RC;gu;#qMQWd^r}@Gxntf1zi+Vd>P$7Ip!Gs_U=|+M-c4UUn z8q#%?Dow^hmc~)t3;y4`<%>cd)0|iMIc?J+j_EMsTzB%aeZNn0?!gQ}#-a&+RR`2# z0DMt{`MQ&6t#8I+n1F3D5k4^q)&w6+eyM2L8TJnj0>`&#w15G-&v3ws*WE&H5&R~@ zpZc+_34mU((CCVuj0UKPY6TWI@~rdkbSe95TDBHvlZ@jV1Ydw)|M{+7_;i=IFpHv| zu}9aut23g{0sW?V;$Hvo0qxoA3~6AT&KeE(H|5L}dF!*Pq0l{N9@)JANS@P~lRsl6 zg#r7bVgK;#!OrtXyCTkVrb=TxNKm+H6dv{W$DQ#B-=`52g`A1)SV!`p_OVr)P6tI@ zGUfCWQ>rO0)GrwIr-LF)tDO8D%NY>($lu#1A--Au)*R5+jrHklowIl)4uE4p1z~tT zq+=FDerpy6%>f-LKx@6jC~B4h1{Cu5HhHV5Fuxh!fWTifX|VT@F8$mN&hyH+vckOX zJ28ujG`4vmY)}{*Y5)a|D+tGqx*IZ%t(*lWadz7CanM4VclV+-xXseUfD(L~4P8N+ z6Q4mbpH6*{t;MGHD-ig|Q(Zn)V!S8UsWeM(i;6XRFO?Qv(3W!9SwQn2?DlV>O%FFvB98Kd& zlc3;A$c%FKN=k?Vf$!3SzYZK#)3h+Cv_{~nmeKHhl?+GVtd`O6yp@;Qk-KV~+QMIX z3Q+-XtROtrW$Q&|{C%X7ao9xCjW}8&)niA}I7O;F$;-0eTTyGrpb!q1Ca(bQLg6{?I*_ULrVaOAF;ieo|LI!!xHXgeAYD~>w7_AdRqU&{H-oGDaI z(OsJ~5sH_3)HzefYm)54eld`{Su(_YfKv3o&_sw`pr48pQ>UUbG_kR`~#I37ad;*Ed%r5vs* z-YgDEYu2XeFVV$l8O<>JdJrTHgUVIfRMbE24D`I~W@1JoV;dD1S}6sD+!`L;9CVIH zg)BoE&H=9rC9q~pNJBWUMBs9~r14fF@hl87HVU8Vvmb>@(fiWp|fEMJ(quh>}8v1(9ok$U{2TEtp!)8Fs0WGQ=vu#M<8_1%sZAn2x zLCLPp(zm5n43>SWF^AZKuUdT* zwA|U z0u|WuMV&2)$oSv6C1z2Jj27(rENK_tZILkQKUQv(Cj^UHNsH7F6AZNK z=4%pZz52Z93BjU|k}>u@9kC!6er4=PN|LJmht_}{rouf^PSg4r9V^d@L++yphc_(wSn65rg#d@$WT|TKbO1GiWa!uZq%P;HDiH6ha%V(7; zZ2c;kM|Q|@3<^`9B<$?1yo9C{VdL+UHa;Ix4%Ex{dkGV}D>pGA2n$V_rCa7F)GTd3 z;1=>@{XwK}##VM6R*<~1fv*G{23(h~arUB=m#y-e!3f#lfKo!-f+2h@5KaWTW>`w< z(zqKP0e$CotIhx;0Da>Nj(Pf?PT8Ov%+wT5n+?6|K8sYyZh0xH9}B0cz$)Yi_57?y zXJIRQ_%C5e&ESNLnzSVW8R{RJG-369YE>z5ZuJQ5>`q!zTXLc7hnpt4sVH!`xA-ri zyODvVcMoY=Q_`1?9}VPGC!B{NSlfxURoq#XSrM|xllHJG)f6N zwNLlf9~N|hocb)(vvY}Id8t!DhYcpL`cLUfEMY~>K&tc-^;QTz>@ca|+mWy!yS&z0 zV93zEq4TwQry>cmYpqIY4-929FkxO15#x{6)J$$=M!Y~n-Hb{Y_3b#@Wsgc!hS@-& zXliM5s~1g?sCrgp^^ASZCb>#?O{nrC)f!jiSWW8~J&wO4uhu8*!}PNyz5M zah0rrLh(#7oE^6x(0@d{ew*P+`9(+1@nVYdqSiS4a z1tnrfMmJ&$yLB9Q=*XKT<5(eJ@kO3J>K>2i4w5nbBhVQu9q_h_5_~WyNL=CX`$HO_ zr{%1JVvGM0IvFz$4q=r-BIMqUH&|utR}T&#(hMMP9pKh>dp1b=9`}s$>`*!+HDt(t z=-$DhA&CwD8BWY`Dzt+G0Is?h?$3_*6QVT>5l~AwMj+}T5z-s(;U}}f;2|PMWS5%R z-BUFs6|!D9`GFOO(?de=@`1WefbJ4#KQw=dAZ9Fubp#!)F%V*B4#wp##W0+x%GiJ} zS4cSw$Y&3x)a%@DKiu6G=4UuN^QN}lQ9!=v$a}kwb_6|RlR}!VNKm+;N<1ByHEB~z zVoIkv&;Zp@DHjUoWHs9BJXIJS7W+|BA^WM5ov48(nuu3-KPA*NMob(nP*1{P#0^@# zpt=X&KY6Z3ul4y?@)E3?g(E0tz$k5e2$>N55D##9s8r2pnt&rzBPe7q9RAWDwZEtT zaOER1Qbq|-FKZ!z0sT7v#uXGiC&qwaD5Y5aCX_HO3)Fz{w;FFwY8V&gm{g+t&SwRy~0A$`k#MMZH%(4X*wlYjd9Yg#=*PUM8V$FNiCkNP2rA$ewAXYvOEMgy~Vg#JaZ&B;SJG+zFq?6e6AwHJiGb*)+yFx3~&3u$eOeQjG?v%)!oJz zRZ+!vSZB3893`^A!$S5qzN}8PQ=%bbt(DJ=jHncWN!mAo1TKlM_jY#Vp=udBY5<5u6b(XG@to4% zqv>Y4ZCnH>qmK$kLdyUlw@xQ5wYd$ybv&X&I)X)<87*3V-^c_YNPI$%5Ssg|d|0_Y zCz+bFi9_8o+Bgmd)fzTT_|Uz@CU9k&P|ql{j+0RLun?xy^uwN5-<&a!;}}U%wPYHC zx7@=VQrc)UqRvAiuo)v}4wcZAWXK2MP3SHgUW0_-$IeI&@8e?H+3rk_5)qwIQ94#4 zzyTTt1i72V9}H=gQo@2|b9cyw2|*lC$Euu-yQv($Y#apWQw&I)y}Bv`3>pS}mIfn zYdjz2*UcFnDu=B!DWw9lK6URqv)GzMLCF|@bF@lpJUEQ_!oB7hp+;%9QYn?OipUYG z4UqycCK)4-%ie5I?2ywIb^dB%#DmuwQQ<*XV}u8X5x;Sf=#oX3wTk?j(cN&&%7lp| zV9;0Y<fgCBT|X+}xThEu$iT3_aR6r+oi^GlUrn$+Hc_B5mex3MrDbUy zn0C_e5r%J0&(6W*EfavdMC%Xl z&G-a!y5Zt!v=A_-XHlAtMFdJ|Jo{<8)0bls%`^-ssX-gGOW7G~sG&hgjd;IMLk$f| zX(Z-Zn`s2o)@M1*>GXlg*3(6E61}O5og={VGxQsK+yHv#^z7+D4Zvq6a^+%70|4`5 zlJo9Ce^R^}P+L&%Q`uaXE*#sUma$uU4aN5AfYOCD5S{bwN1qAF8&ZG{ zUC4k15gVFE<>52Fhf1y*Y8o0xgOE)b`YF79tZB*^6eO+p9zSF zHc5n_&Eq`WkC^pSY3V%fgQ04JNo@d{$w=vD3<}y{Cd-yYL-{w+OWX^2R?@;9o}|(w z;Y0rO^hQm@6cK*}^HNH%>+^`A`$-i>WsE9BzzU;Ocg&N4MH>--wg`6)sbiaprHrw{ zh?h1fRDnGoNAL5LV#=0`q11?#w#8R~9iK+;J}!>S@kz>(A6J%lqy}vHBC_Sl?t_;! z%<-s9=H-kbpNN=_nOFxleG(D=ZC1=|HRt=5i~+j{mNrL7z>+wn)MJmRmB1&Yh*G|~ zl#&{-CH6b;Ier_!kDS%{os<&nic8hb<2PNZdqUq(+S`CzFa2 zwL)8j25kA8r~vHJX4+mVN&U>zS()Rhl!Jv|Mi&004z=u6W$gc0nQaLnSaoIa%W8mrO@hEx@pWoDbjCs!Fk&45A$Jy!KK^0RsKT2< zgfKu~!UKTr`ysh^dO-mq zQUMQQYk2ap&SxSx8T~=LE`KEudV_yGvuRo;I21U4X@|u2GYY7neXAOVz?mYqj#|(!S z!>WI28~mWq&0Q=N1&F1zGAd3g9CytEbi{sSihb8d#O(+;Yh zI-pP#xs20GLQv8UM~4B|!uQnhhY-(L)EYvP;+hQMPr`Tpg|5Ku(0!$<|1S*47>^2J zNdu$;47nP<`-nQuLO){&H)JIB6&SKN!dJF+P8Q0mDg|IeJWBOA(pQ!0np`RTEQ;+_ z32QQhqk`tjqTl3PRY7xf7;r00Z@mvBj`)ln9U&^2+k8HZ_-*)R*Y1Pm1DI1=Vl#%( zLTJ*Qv=R*aGGus_~=N0U`@r!O>#0Y=?`I;Y@F`UIp=h4r|R3J z67lE76LF%Dd%B;ahrAY&htbtJZs%m!O&PoL9OnzctfOcPC^MZC;=ZEegS^ z8cmT1%!z!tdUBg=5_YW0mpeKP_`5K1W%{cO#!VUaD8i)C8_8OA>M;3lGfXyRLReh> zcUcT^7<_J6Ovl}}`meAkqx-2}RZh&O0DXQq)MvCjc@iA;lF>KByPEEUfM3TWjE^=o zW{jKT{YXOWX{A4t z7VPZNv|dodlVJ?kY03g<@@gU~vj+olaDkxqtl#rskRFvwiPV@k$a;fE=s zd;=0|St0~);8_+l`)?3rr;GGa-5fPy0XmVa%8r0YV7+JczwN>QV0N?TgHJ z`}C#~zoy~leE_eF`rQ|F@!7WeM=xCy@Qf*NgV6j04q6w5mYm+p7*(#6ag%%N=9%Y1 z{fE@ZXqzN79Loy_O&ZaT2WtL=*S+UBf>?!OEnJzupoJdj7Q=H#@Ll7~Z>F3{;A6Lm%fFG>{oIipo) zU)FIaP*6B;A9}uZUkK#nWFVyglfXYWD%A-n+fTRe2zFP>Sb5G%gQlSq;gle?^St6npc!Rti`U z`Cv3IY5&nw4svCrN6-ki7=X`@Ce)mn(AF&auP{Bwn+Vf=5b&RlPWE_xlZu~{uDP3A zbw;S@$W~Iu(1l0S(N#}}6>C59V$$}b{y`ZJJ!g~|{kl>NNszdrf1u1(j{DP-SSG`l zMKY2GsdM_dSR$ht8%byi(3kY@{wTWNn#jn_k$}&F%!M(nZZD5%r(u&_u;yiz91;Zn z74!AZ2`$<^PN-zK`-F~a6~)=*@$j5X8(6x$)tQ2#`{WFFbw+)kuN#%bUJ zR%wC5*IM!X{u{Nz;bFz+!hF5`yC!EmKfUS_z&JjV60qjFc-h67U)|*NDEuNBo8Y+6 zy(M*zXn%b#nIkg}?h~klxP-$3>8I=g&CXOm3YPa%34v2AaardLS>gm>iOdb|ci({J zbA#hTSEj}DVgEJUS;9jspB4!LSRy?YKd6gO!j9!VRfLBXmnT0D`qSc0)oRg<(IgOb zd5Ce4x`+oiXX9}5X->1rkfn@9LE;=Fo|TL5a7yu+1Nha+gx1K>sM7R)G3k!`YH5Y2 z({fri#Lyu~!60>krSyWvd%=-nIlUHN!%+Y~$MC1hdO0ed(Rbljt@&U8e35^pGv8_9 zF<;*#q9$WFU$8w4@Rtq#!FXJb&0-+mUF75;-+YqrQIJt_Prp6g{|gPgi9jqG_l^QM zqG*SA%9OH2)F6t00UoyRs7i8K+YJS9Wjoz=_9LxPTh?|D1N<5%FR}XvCw#G_%$hj^ z0e;&090(};^$*ef%%XAcVSvBJb3`;d+Nax=p76m>gZtrX(VWpV2hrusefFTxe0wsL zW8906FcAQ>b)xb1t@OQyIsIq-zA-#tL1oRTB&Ydv%5W@VQP8+R8nf<{4`rl(L^;Um zKkJtf3=ahUt;uYkrW<*`n^~2-DkZJ)I&pm-P7Nu$y4b_at4T; zNGPg#P`d6Z?d;xtw)=d0>&ZiTaB0q%c(tBSh3du0$?=pIT(>s|or!b>Ir$K8>#*UI zWBK4r^SGlmGgkpuKG*FT1G~2 z@9V&XI0$`AhyG66li7%u9`Suq{q8P(^K3?gmC}!A6e-0rdNovNe<-v!2SvwRyC4Fa zkwq$WeIhhJ5}LGLck*;d)22<94pyj2CUiH1?t|gW{Skzs=j_in{FbMtWfL}-30(p6nc%U7P# zCM|V&iwJeba7jf9$6V-tBJ_XijEB@fq&pP&P|?6;Wz0}l$VXVHQ?7nJeMQGpt5dLX zzO-M@WW}~&m|~P5LhsTP19-_J3^LkP4xrT{9;7~UPu3n-kTGfCNTFucAq7|5E7Vs{ z98ZuFtu|`pV zW_?PkZQa-0w5WK134g>TRJTUF^@p*$m8H{&jEVuCyLdR!9@S6X$KKkZfDR)ukG^nLrQ}L`(+r=jFBdv5e3vjAt_Rm2YAC{o|a8bFq4AR z%#WgVSwS!%_@N&m^rK$U6-I1MeO#A=1Q^n{lG2HzuAZDeMeC!YWVPzS=~p6k>7m_m zA${2jB3m(&A%5_h#}Cr+y=;g>HVhEXg5~3_q|26DM}_E3KXIzVoYQ@&%VUxZ@pU0i z1Jt6j%2>4QzaQl+9y7L1@sj`O4^hd@X7?-VAEfkU>Bk2j%$Hj0aB6isn^{|k=;pgA&&amj|U9mzpXF#DY z1N&SEi_%I{4YN@c++|CvqeAquA6i|{h=67sPT&(F=Vy?R6UAj`+Do@Zmn|*=3~5nZ zc319sH4$PL{YVKq5IKFuy1YX;$cTz7YMCrsafxP$D2>zupk^>Fi}nTK<8biDJjDQTgQbpDjg z`>EeMEadq6BK|ZLK!b$bwdt77o1=p9vKV&`3mW{ULr&yuL(b5wg6NWw6o) zLaL&G&3o{=Tf~dzGL}dC3)!LNup%)QK7-k3`7#36ziXGZxzLHQF5ct}#aJHwY9S(WBAsNt3DPXhgVeZUtk+*B(j=#s69+=z5EjJLk45*kJou(rOlc12@9@nWBFAPF zw_u~HLI8N(T=hX$N7IS`YIVOp;VVCcL{3iPYeGzSMg93W1VV7#2&!8&BB_jZqxyYa z{IrxqLFAf#NT2KBjv)3YUUOQSVW2`DmH+EM5)EneX{V!w%i#(I87k z!IVJgUG??0sA(CkxXjBeNjb}_Rtp2StQzy6#>Gv=<*QC#t;7}4m{Z*)($2D=vSw8D zjW=6zS#e&O4kOQ^pm7NrC)0w~gVXaOC^;)b;-K7fFz6sGwD-I}BsV5hnuW!ppnn%! z=wSeIR-Yu`i~$=Zh2|w+(SqM+h3vOAD=8ifI>=KG$K@}@FsxOZRf0=&5SKFU$eytq$;61=!t$S*?D%!_Ld=%~dX&r~}R!SwTOvsyd=LXUf% zT;ZFacerXAHW(p`E0B-~MbstscRAqMtS<3jp$>OEd%Mv9Su-6E1|8(Qr@V&0=&h*z z;M1UlQbap`s3|0ODK@K7K!O7N42?ic%Wkl@u9=^)C}<%4pA|F#HR*@j>YAmC2ZIj6 zlFZW0!eUX-IBQBz*iy-v+losJQ$U87*`XT(Yi1$(ngf zp9UrL>hT+Q^`us_ezxR64c-jD((He9_e;)remz%uZ_@JE?k-iHMDeg8yu^VXw@nV*cZ$L{AJK) z&KX3HGoAr~Z*8Z6N)bWLT4}qC0UPxTe@S~g1-@DR0umI^>gVs{nzC7|-?5;A8s^8& zfX=Urnu5)07!L-Wo3mk`YGT?`icRXf^kI|Es}oU|vBb%ORBy?Cim?Cp>Rs0 zM64Cu1|ik-S{aeJ%c&V4!gkpj#$nr;^`|l?WjH}gh=Zni(7IutWDmo7iO^-NKCqZj zP(W)`mw z^I^tE@=fXysS7%y1j#ruQIZli2sjM5IU5i7JPv(}9Su#>!oNgm&saMqKw7>M4fRjO zOTK#C8OTWnU$EW;&4(Qy3Om#lc!@~JaRc=h_+)5*Ql%Y7LB{cf0v1PsXFy#H?9h?O zDW|`D4EW@940unxi5Q6Ru;TY7>c;v=Ups-XPLH`en;!i@3)I7_F8$a&>BGD$V|LWmct>VA*d{meqRPKd;WNNC#GZ zp0G+qR5}53TGFSNbIwzN2V89$mzv(lv!d4@ z(~7KA4qKhC3RPgytwgNtq)f?gsiT@q)oh&2EFLz5_3KkruhLl(6f1%AUQPWP2*8fe zJCgf(eNtP!t;Rd1bzs$RgA`Iv$4ys%tl>XalA|kxU{{!P)Z=e1=LkG(xE{pKGu_h> z#XG-;SC?@?hBErscqiQ)%s7H12tlgQI5yP767zicVpzT!rec3JB_-X9_orB_ecoT5O#F2VgO9~9=XVe1` zIb%~qKvoD)*IpLGmu)%~^xmvL2+v2%m`qczE2~2g6mHOBMs);ZyUS;M?%|^-EE&V3 zcu%k9x1RziRByg2Ixoh>LHj5AmzH7iiV-?5Io!GW!|5IiAQeb_h^Y|1>_0+hbsUv) zjx}SJ282k_;2^bz2icl%bwtKIA6}1i{52A{@Dz)v`MHXy%-9AGR3sR35yEx6anK)j z2DC~;WSWdQM!YW+EetZ}@EBznp^&i*1g{DO<^cZLtH~iXDGu64delqbin{szR?2H; zIBtuZ9uK~>A1c@|;^X9lDGM^T7h6`P1pq_-mVE_wR)jw%6Cpa2>K+&3pGM+aTRYx! zehVgJbl%dE`Vw7jg5F<+cv`6m5)Bh>Si9*mDOwZO{z3mM@_WXq5*8zZA21>M6`r2- zd5zHCL|qNp{%Pm?Ez__`#Xv?!8(dxLOpZ8J1ZHjE_4tj%RYn=(d*Gd7j)B9B5Aho9 z>=?AU>5@7xIHzh%6^RH6*$c0G>OSjj+A|#tBW6_i=4BO92?Br3eEobliWM@}1SS+L z3L2ljJ|49B&hpW0FyMdhKYgr@)}`%IMMn+?WLy##(sbzRC1A>p@a1hXiB4}21uMg^ zhnS=dU{{Lo-2KySiijZ!0(!m5mUI>*bj%9Daow;aSb>fd;6xUeTt019kF=5t!y#a5)W;r#OrYej{hYm>A zEl@g|iMBcplcS%R6^2i<-pT(mkbo&4aV+`I-QT^RY6fMDe1@c?86F-cM6p3ff%c~- zv{Iv_``YE$$*N)_kbo&4hheCks>&Eq3R%hc5CSm6#t0=0x11(z%16{Bqgsro$%V^V zzz~fRW>g5k5LIV!?(m;;8z23iLdH5CM93+2I6ll!l>(bV1ipTj&Rf4r6>)!mHZ3Mw z)R-4B@?%~(W}bnGD5=zdHD4ecsVAT8MD}D>3X9ldRA7;EbuxaohI9fBw^uqTSC=s( zjX>5%Q7i+SY}RqHq>cgJi7#GRAPb*n4V_+W1YpNa1jN}v7g9tATV(XB0IIhEaOkVH zgG?JL%+FLV7TIQC`WGxuNSL7=XJ9OHiP|X-;m579@rb3dtU0zH)CdEFlgcY(Gb1)K6=ugTcUH|4cAJXj(LLq5z1l1`6do*F@`NV*y+7{`qvFIfH?iD=4eFnhd2G$kZp%=usX zqXQZ%Y)5wzW{lq9T_uSR3IzNm`|Zh}`y(Ed6nP+H(<%T`!_pwMhUZc;8M9Y-UC4ly z5@~W7XO)P!jPn{jMdRCiL8kpH=tN}pUFed8pgQ>f%|^1KWTD^PbyA;^4X(7M_%KSG2KzYRw%IF>Cq}1 zQMenH7{vkgy^}YV#upGO=o1eXUl^fEw!{oc5s(}Sg- zX;{7t$tS-I?zC)9W)jG6k7v^0jFon&49gfW-%H$7+|XJ>0{NZEw2=9%VOdZdP~V%z zO`nGL8WPCw&v@BY&<1Rn+kgW544ppGpF}lg!xoBzf&VU@W!aa*K@Hmw8U*fJGns-7 zJq1xfeDBo}-w+^tMZ@$nB#_^IbwtNy32?(W&>+K|%`b5GqkG&d_2n4c`?%3+(N@9k zi`EgHl-Sy*Nt0e{bkdcUhrd!z?~RFlc;ENi)Q zZ{BKc3F4x*-S%wz7eQ)j+h07QJjS^xv9!duTTdmjrdq0vz|t|_YCT&?xa}yy{H@lG zATF9FcWijyYW*lkO=Iw-NBn6e#8)2iPlC8;XutJH`-0RowEG@Wo?Y9N*!75V-FZ`D z&m+qHYfXtq9o2EiqP61A3&3l*U`a~AZSU2OnUN5cSP(61@Q%&Sj_i2bp zC}#A@)vJLPf2UzkxMUQ11zSktPqHS===4_VIKPEp9CTI~3fS@?tIFmy@IZJ8OZ#T;RpZ- zva0#oQjyZ@f0>lS_OvXysSzc2#$HbKejvu*wV2s*v3K1UQV;MjhzwrF=D2z}kBb0a z^L6RSnrZ6=U4I}-f5t+!dRd2s>UmF9=EW68sh4*BVU#bIj!e#+hKpcba>1h8dLqe; zrFZoa$&vs=^ZKaYeK9CFJ54B$c80@}uKtuYMn+hDN|0T>pIRN;uD|JhO}c$LBzs7g zS-vb}6K8eOu90(DN*@=;rO2?W({$ayt5TCvf!4jgAyqfz6C^Ixn4RPBEdSMo){RJC z6rt_Bp>Vp)B=z2W4w8Cu$Y6Ex>2igP@tO0fpQpJl<;2 zoH^flDZ-Y~yaAv>4^#+V#Ph9Iw3;C2%5M`p6>4H(fhR>fNMyj4mr_WC%8N#taoI0} z?K>Fm*y9yw5OuaeUPX_kg+<}yd35%h4lIZYgS}9JKhgglP)XcmO89knUOxUQaGGt zbzBAEf-^2gZg&}gPYPdYP}~T-OPQ1pTQ)E*H=jY2 z$$r?f0`!NWd&RwwgRh7Z6SSujsiIx>`xz!3t zx4W!>%ckqo@STvNgTyWg9msNsTGowo&D`iu);zH((<2r!~SCr#>E75Wt zzAvL6NndTd@z!eiC-JP*4j0S6PuVdoM=dqa_TOR4DQQ9}6AiDfG%j2R@MJ7_+)ZXhp$4*Rk7}d(^l(%maRlflU5<;>Rdk_2XyjM(0I&P&|%{y=qTg+mcgP; zcMdxdp3`aW`Y~i5{I1FYHS$y2}`& zGk_p3=x@ETnG04Z8qHW%#2aI>BDDBM&ZK87HLDGY0wPDdz#Mn_vOBbFU|bWB&p^>h zlUPu)tc+U@;ABQ8bRofNL*r`7GYE|=o6Cm7l}jrief6>eE^}D{+2UVTz$Lg9kU4i* z0hiQPK(>vR6>y2XPKmtKk_fyXdlSY+OCs=i<0TOQROm%ZBJg~(B@uYLLQO7-z{9Op zlO+*&yFyAVi8zag7hk72w-$DkEd={S*y1k>NCCkAHa$*Xws0vbDXuhHYZc z<{$6|YC2r@_*dRL{dT+E7R^s;zfMP!fBO3CUfG?rwbyQ!q=YRfZ!CK6!KiUD)vwM37GdfzL*xM7lI}6#S5f*x8 zZ*MXvr;~trdm*MGSmc$?{)7i7ryIO|eWN>|s}F_2HEuMKETE|saV_=8l4EW=@6b^6ojNUH_0mI3TL z`@I8M+brf&)$4$r+ozkX#wQ!mjB?Gs*hJtpMQ)DyVE<%F`>KK+u#1&^i-5hC_?ro> z4t-H2|7y*DDsYDRohR$Erfupskp>}wZuG->1+zp-gVsUK|fL`SO`Ji~cky!G#pw$}GG9U=hw!&)9U9$@;6)zRedL0rr%KUNi znxlhiG%O0?ILjja!x>dZA~!Bpd3q3l>D0tA^~7oCmEbPsK^z0v%l4}cUY5XH)djz1 ze`PXSjEyY|gV6ikLORuhpL5uy`z%bRGoYb!x2^LtfUfkywhfm{YPSK5T+lH9_Qq z1DYa?(r&RT!6E=X$L)kv#k*M2sgaeS%3W7qR#ohaMT$j*_4<2s*JgOD?1H^M4M2ok zJQ$Sac%#>U*^ic~ELKM<5Y3?)5ClH3PSvlt7EDGsc|flKx>3>XTdZRV8g_effq~TJ z!_Ii0x@FW$8w{wq78a((>KX&1zL|wV=#1+)`7yPavvLezuiCFRyprrI)U1q5)Rq=U z%Z9CYf!JmHYr1o{U}T|d8u#bcl~BK%uKyP+Yz7tA{%;=!=N;CZ+LMYYdK(dQgMQ!d z3^vqRwiIpD^WC5+zwBwM6kZW&qcE{FktY$|G}T3SZr}!;8z`#R#Y(mV@d1Q3Ods&~ zQFmaml5G))sCW9kU}fuK6`*<@urvMRgI3VUiIc@D5l!KBIBvq^ z1N~(%2((z7S_JH+Xy65}VQXbE&*B)sp2NY+{g<+NzhE?Q2BtAWrbx8P)$-Ji253V8 z`l?r8HYP{2X>=6$V*b#>wJZ)|AJ~y0-{CHpoE$woSS6uhL%#vkA3{1$$5f=9Y0XKC z39m$$*paT&x39`^Z^I6R`q8nNw>GGjMIl<=8_-_oR|$1_>YebEF&M!o4q6%`(g^WdICTzc(oPsyYE*Fitf9!1KqQL#nlp z3z{~UC3~@KrZ6po0sQ@An)?sE++w|T5P)1KiH>sgG{P9Qycf&4j8fj7h8YzKB4_xQ zc))Hk|LhpRzDHk$vAkH~832Gc^ydvaXQ~{~s19}is89#lqh_s5!d+-0?Z^PJrHPPy zFVVkTFbuL+c}@d2_}C+ntrx3VG^M2|u=VZZv0R0)SaXrz2I~D(vt_}YY#Kg5o*U9l zzr79G#T&G*77Mtdv@`|iGyLU*E+?1GfW`8!V*q=}enkba`-1vlBEc3LDz_{uftm%G z^K>lKlwyV!MvtVzVlGKzS{eiR+OT*d>?LkHtGVS~$~`ZZLzrcbSr7d4StUbLz`>b? zi;bfxzJ^Hq)pskhU$MgaWzE^Yaa5MF)45nCbb)9o5<;@Bept=mmqmqxUvH0s%N`bU zu>3aceP4Bmf@y;V^Eh{@yn&)Cqms_Lp>L?0ZyTq65n60a%F*Jc?iw8~p@-R6Yb1|% zT`)l%sl_Bj&=p?-#d(R)cru_t>YScq*|_t^KmJj;hsA0pO=&3#&>!e8`?9KEtgB=Z zfL{E0Mkgd6^r_C^T1A+=*uaVfwG;>fYvY2J>KDT<4?2b$zZXkhOQHrolRSyT*`PB{ z)~t(4C{k3felRJ1o^c>V1T7Z#7Gdq?4Z>8J@=Yhv9)rc~)+FApq)Cu?cQWV)MlUvX zuHOglBDWFyR8CD}+Al+k9GEC={A3eWQ#OIWSYiUI6ZnlYjVZtLe+soHe$1kz%oI|7IKD2Tm7Q-IR^#rpK> zb->Q@r;Ye_pv4*)3~6Zyz-JWrh{mawiD~942C$cDhYIgRrkqVJ)A(@J#l|2ktYu*k zx`O2jtC{NoEj8D3dRB4)NlgQd zZ&sR6Vt;+ReMc|7Rd3JN?{;4d%U6ScK;`rhqt8V2Z_Qv-D2_P14|=QRc13(mJ%!iUU1 z+j2wc8|rU8FNEN6pw8U>R*zlCgsSN<#-aeszj#u-`oqQ+4MWnN;@%%r^gW}~W9h@j zV>Rw#BJ#V25&7Mz5qXYRSW}1RHMt^@D{AUL9FW7WY5|Wie~&W&!6>pWD!6S!34Tqk zOYTyr9cuOUiVa#gJ)8{GJsfPyS!Ij5+ep|^ z)1XS*p%L@5&$$7#!Bob7eCHopba&kJprrNhli7&-M>H%)X<ztT|Z1W|cebf6x(I zjhx@yHgX#~T5dyS9hM_|u73ATYrj8jb-G7f1a9kW}OJdl3 zO>1oIa0~5#Itirv0T!8yNUq6DUG6r0jkipGHOtyvk+#Hcdy*^(xv`18+U<9(%GVdT0s@{op@=o}o8a5XJ##2wvg5JVV2R2L!j zzBg=2w+q!-GDFSJk`gq(a98E^jb}Qqlhk|cHgErf2vJR6#1_BXD1PSsbftQ^(|g&W z{#lPs>8IPF55s1DO)Era`aYf3XreAA&2Qc{UvAu2c&cViLFc@6nU3J0ozy%jZH9Sd z>8@EGZ%UkbpRN;7JE;=9`KNcS2=es?OkP_ic5l`n^qf>dN5%G{{_mnvjxt|=0HUe#IS*dsP!+Gcg}VGxX2zOkMlx6)W`6d8 zW0K5ymgx_>gBdOJ6^U2V6W+M`B;lL1T(nPZ_wk9zrZiqh`%9_)Bx17WKskQ(9krU!50Ml z)Eq`HLeUZCzund>JH?|N#y-~@T!Bz`iJIV?5iSux)z>szPAjcw2v|gX%}}Av0C-&+ z;a?_v+5SWwG&)QpT!N7iqn4oCPO#MR(4u&Uo|HMaCgPA@5uF-HYxjzil1j|vWYVVJ zUvd<^72JeglNqfOQTI!dQ|^go1PNT;rDol$K1~SQHUn$CM~#UhIPJ5hvE_6UjTKFr zUu7kYm0B0|mu7@sMq5qofM~O4{^&$eYLQgAIBhqghNhIRaY?$dz%37IOPZ=eg&&;x4JB#1o*O#~Pp3Ah z0Iw@e8U*L#*ST9HvOrB~hPS}`p0ZDyTY-%SMu0*}Zi`aL96ZpnyEW{RT^ac2)x$b2 z3&g$0(|Zwf(Zy!G3pX zVNH8aBq$N4oyiL?Q6+PJ_O2741l4CN&@*;RY>O_eqg7}}1@ESlqX8MibO=VTcqwhD z;?F;$UJA|4&@3QL2kPL{fVO>H#*P|kim#Qf8B-2pCo;@K&d;izJkLE8?AP_F4-`4% zplH~&N9PiT2R}cl&N-nng^zCJE6b6L7|EW0yrZL@8-wPj4VK+kQy^s2IWLMuna^k; zc&~;=yrjD3K3^AD@)Bs>5HgQ*RM`BfLP0x)O1aH6<1R&rSHyz{o?m{zakcS?R5l)~ zRmdtEToDLmge)aBhksfP{zsk}G)py56N+j^MdnIx(8TYVEMkovX_4vTk;CB_ zUE@*a)aUTXh*+RN=+~tzkn{H+s&j%=aBm>?^&~@UpSO#J-J*+|3QD4rLPSp&s^G~UL)18fZ0oRG@5I>f>zGE6uYo2e2<=rtd2RvEYF-bQ14<91t!>Kvp zi!$b%LJmfBO~OX_`Fc3v$BCm`DU>*)l9pZd^G8X-WKr*%L%ghMV9r0-#-BoSTuw{c ziYtPiaVwzZoA+hmquFpxouAn@f2#6l^E^$`@fd;cYHH3~3InR%mWl>AfA8NknZjtj z3pGaRl2fU+fOpZaOF1Ct?^Baj!Aa0oFq7Fn#Q@LRiV!Z~OdTQ6b>#W^9s5DIr}dFq zl#$%qEu@6BWH-NL0Z?U!r!c?jEZPw1{t>c^XPNdwjqP%zO3R=yzwX(^!*jdJ0jeDN zNy;)_cEGd$(zu$gK$t;KjWo5gK}*c9dDiVZY06ONt#MRSh^&;`IpWMf?*>uCwE0In z^bdD~`oF050Hqk+Z^C;}Rm9j<^|U)`72P9hUJv@zqTv;QQE6HrYEq@CN@D)W?&kIe zi__K-7T-`SH)sgKmbutW8tUR!IG*uc%&N=`Bs??qFR_`IkdijxMRG1s_olO!!_Lpj zJY=1MePrSlSwD7`b_z)a8ilcWS~UfPW6+&(%B8cO%w-6sh^9X+>$WOY=4;RIZ*M%{ zoVKZQ8duD*aVFv4uyLV^XWWj;+@jU+iWh;0OTQNAYo}TbmPsuZU6F141R07L>&|H@ z2kjl7comLFubMH5$YYw7P(c$aAu#{M^OsmRMe{B{X5p&Fls2 zQ=O`~=W7I1uezlL=6`#i*3(mGTP?ECt>Ebf4b7RMd1uR4f5XOpZd`*imYmzP*rT(= zhKa*g{(adpU`gn`7LU;s}Iy)dGMNMGr8lkLtUhTszNgLZ%#Ee>2~+>O-|Jg zl?Gd}`FGEXLo%1v*XYF>!;Oiun%5HYSdkid=F!pEGykq4Os;)F2@`CT{jUWAWZP)6 z4h{n4)MzY})X-Hy$IWIA-K`a+Y=LHFs-p}`47pPIkTwSfFLxLAR6!B8JXye&sKa5SkbY@tHuP_W#hvpX)z`Er zQ%1%D#iu$8^Dk6aD>y9pDzczE+T%XQp6+w#JQWU+EKmig+(PfCQzq>D;AtAa;LcCb zB&{}9HyZ!DjE$S9)>zj>Mc2a?RGQs?y~pb&!v*yVbj(ii;VjXD#Qbk}3R*v@1UJmO z@`-8->}-9%^<-C<)UEG#A3S@^?HfJc)-SEW+;*UbSn2@R1tyZJ^CR=!w3RKC7^W6> zgj4eiOjpz!z+e;x42^oq)VtU_kX7yiL!+l8m+EM=2tWV5>R@bi)G^jHZG@v-RdP{N zwYQ;AsvT-GmYp}<mPP^x6M!q=jYg#+bg!^_OF$; zs9_uJC)k#Y)Ten(x!u$S!j787NH$K?+a^XN324LxtF6<*hT~ShM`K33O+DBcRWtZo zH>n>Y=U29zz{XckXeazcb?GiB^?_P>5nPm3ll-SiTi*PGM?h0h-(@j5QdzTN;}j8^ zF?{!~;^|17j%hA_d{|6*N?oqcs2O5#B8e4bbjH45!u3#+(N^RA*_3wgs$C!=i`2{x zIJI#7O9-5Qyg8dt==#5K$JXj?7(EK|Rr@8cbJoj$W!%;@rR^Ju?F7~o`w&I-)w}qb z4wSNLWX3gX#-ufzBo}*Uxc}G3gZ8BJn)XET31%oeCXxks{t+*gverzV?C8yt2YjFr z*>l;m2dlP1`55^2X;XGZDL=_O+%!;4I2!_Le^L_nIa-F?2N>KU^b zUb~T5>(!VFTT-xQ{U6+x6qG31lJtB}eTAJlEP1{&>#>{U)dMo;<&63BySnv`fi$0n zqV|E(21$}^*AOkxl4p1z4iXxD73v^7Uu>lo1d<9qss z7`nS;dPHmcsHN!bL?FqF`pIPU*VMeo(d665qi$RGmrd#`MGKr?G$we?^^y@)(?-+@ z2^ujqt^>NfNu2I7QywXX%`X{EH36jsD6D7nlXR|*h~bQaONTwEO*XzDW9Hu(p&fJF zkJ(1`|NXzeZm7F%{-FNpjK`gmKhTQF<8pkWE@^Nv&+TNjL(;ERGb%J47HNEB#DXbk)I^-kN9Tsq>qtO|wp_Y8wb0yP+j0l;`P* zqvEw{L`uyXH-=Q!@7gdr&iq~FFuBZ72IgZen)WXA+mH|>RB#t)OA`%5l6#|FH!=)4 z?SLTb_^A1p_xjUUWIr~}(l%4B1o-$0S{SA?69@8rGJ&5H`L-sL_=!fxV5sd$wzO!{ z{3azAUmj)9fnPYcKj;i!&{a)zvZGMV>Os-HLwy=7-=j6|gOf=g(jIbt?jC>I&;k_1 ztNXM*ZP?n^`)=uyB(;^uFBCP0t0Kb$zrA-&tJ0Wke?)O)lyf7yPB=u)uW%#(fe|t`aK2hMCfEg>LOmncZi%NULMqDL zx4%+dN4vwOwDp#%e!Iz+q;F|y>RhUQ(Ym3Rii3>qPAb{c;Q39C3348GMJ%;0b!!% zIt`-og#>3o)k=Tglxm?;v+ue>MVH%O$!nStY>pdXugNtoHNE~ohcf?RgVLT;^8+I* z9axReu5+7OlB&6iqXEvb82Yll^Z2%UAX0Cl;TKKm@es6UP)qtrc6onPw(flQ$AA2` zh4U^%oYt(O$Mav`Y5${9i&?1h-lZcNI`XL0noQxMEgtmIAnkzE->w74Npxj@Oshy} z(H1R6pdIRTFHHV`9dgO5f=-lB6cerla{kdh{jJ)6rG@;6y}Ca;pkWvqVxVbOI_xDb z6g3?olZ=XBOi0nFS*E_G5g#S8p+zVbE*f=eWkh?hYT`Yy2P**0KQxls#f7`D#M87l zOXQ`R=0#n)oSa)6s0I*0@lg^qBVRP{UQ9UOPD9Y$E`obm{%(K5_n4ttH&5 z_Lhm=utw=~{g}k_hr+O$+FmV2{hHqhEDCU(;%0BWKIDv(;j9u@4P2pDQ!%-Suzz{N z8bu9yXx+t$2^+4Bt5m0Y{fJ*Z)u_5tE!g5Ie{`w_MFZaW%IPN|wPz<^uP zLRJ1=H3A^|&|J@^M9FWED4h_ah9^Yo))X`CH~xRx-nBih+ejCkoy5BFuDj&ha<1}> zo3bQ3PCRGtePms1oe?EQq~q+{;nO0UR7WJc)7_Lzf0`eFkJ-<&&)=J0a^9*!0jRam z;8IJ;hgj@xyj1`Sg+igK0BNFTNiPGAh>`CjIX zf?-_oQFWJG7wJxUmdFyLc1T+kMu7Z8T7uv{@U{Pl7JY=HuWT49J>1K2hkQ7=iGZRp zgW5uTY6dyz7&Q0c5GVTyy_HDs6c8Wd>S3hDn*le{%-D343yVj^H%DKg{`b%S=|BAw z{m*?Qgh_4Fzj#^`rvT0O{BvSMrzhp2U`fZhPR2ffxCJ5mRLb)amGjSky4^XVk}c{{ zvGd%b$3XD&+=Ox~4JRX`%HG%?BMN1-^RK9! zg5s8lrbG>mLnO%UBXac+>JzCK|CN~f`Su_GXe1n6n+(Ta-@Hk$xvt9gvN{;;-Mn)% zNSI#DP+PU&f4<#)Zh#6UR}|=Aj9ZQ8elXG8&E32EO}h54ZlhjrZ+9{*dhMT_%yQ0a zKNZ_uxkqFlZmws%_va}lGi300u=Uu|TLtSvyB#CswCfE-ck$^yE>f!(s7~17m{hW@ zXu=kWKD|(uIWiOshWIQt7yI3)oFF*vJ)+4Q+!BA%>5k>a9ZRFdyk>6q z>WI2p&d?VVxZ%tQw%F6?#lW8&`UJC=Fmuhr+o!9I!%5-;)63&dRZhKzSx! z^zbM)?nUSg=X9V7<>|CTi3p`AI#};DpH3?5!Et@%st*a2Te-K73-zQ75HGh2{B393 z$H_qF)Lw`w9M2=!x;i6DHB5Isjm2TA)ixg@q#)5HVMHvQPWUDr)-5%)}O!m`*I3dbvq3u%{mEq_^NqA!pUSDFww43Qwa+M-&jr z)!D&|wWbdR;gka|8q)nt=tV$L;au?060&K)3!A`naF3(#^K>L&*C2K*gI-`=hd)_Y zDT=>`!C8?W(4f_Oo~Uedq^GdxvHexkTLc~JKeE{v^J7K1StYbPmt{P8Yfs$twxqYWKO%^iDpU zLdAV@FTB4#4yDi=vUvs@NK+6CSAtRT=5K!k9;_IJmI*&Nfcs63{Z{M?*BN3aNh7K% zrUP%V+*P6k*WXjthBf#1MR0@~mHjb0CQ*O>ulSeIGKJo%xDWf=FM|n~!*dtGgC`?d zWK4$lmhgq`c0u99L2la52^#i*j*^|ft`xz z(Z5mD69>%iDT#$&5=5y`6i{c&Y=!vPrw1gnx5F)tLZkfv5&5x*unLt*dH~>&$1m9* zmySXUQ$5{*xdRL$vZ;_>1E709s>V#I6gC`xP-3Rl10;Vakh?5h`Vsf-n2u4}FH&z@ zozqNhtCgoM(;BS$8E!O*CYAk+7o9wb*x2Or@r!P~;B!Hubp1_^Mw3*}5CxCqmLf^P z)G|24sZ!N=Z_jRbw*?<=$VpvA5g>VO5Za{n3dNE>(>I>JO5 zTjt?zUn)E2l~Lhjmh?Jc1p48V$O82rA5+a~yLOkr#Td^sgrBz57?FW!s97NQK84MDDc|3<1P;{+x0sWB8_3-+C1%c{Lr3cv2TsRO!?f1vu}e1@Zg zflSwrlL}WVxWiIc2B6_J{`5};q4!%O5rz69=3)9cui4y9U*XA;zl%s z@#pClcWbs#H89ZVcp7@zr0o_)_K{txg)J#={LL7yfaNahJP>p=aA;v%reDd$KRg*o zqRCuI6nsK>gDDyR434|`ZBIgWpgKpC6qFLA6)QJ>yl}_8{as>;HfMULvthlqGW0S> ztcZq^+A*ghB?Gb_$lr9z3GY|K;f<)T`isC%rptjU&&Kr>cWDZ?`~AJ}H65_vu{+|$ zs?=$qx|lh3mfN5hGMq42j9ib?Xknr9a}Pe(u!aQhe1NVtHq*5Ov5{D=4rkyDMx0Gx zOVJmKiIml97TNt5)vlf*ANwd_VMK$Y{_h?s|4Pz=FivoqQB_Ae!C`_iRD+lOa7AvG zc42?gDWyqY6^J182G5=L*W^SDDvrPWYji@yp*c6ID?;6EV z#EGJZ8E&i!GS#?m(|^SyLz@Vsk^)nNX-d_ytnJq#RJUWl7U!+5A8 zPU#_r5>HHFRRPM{EQLkp?D4!&<&wVKbzdKY7@SBirat&xnuu6ErAzjRJhOzE%y9@X3!pf$n^uTi;U( z)_^KXv!^IU!hxGb3EKT+IgrDFtBgFz}I1fq5*<_2-|sOW%4 zOY1Q=|LtT$QlR}vzX2KdYk8ZMWGiqZ5kSIC#oS=6|8s+T4ox0o#z=30Z|*~b`8Jnb z%5(UnEMad`P zf%eLHmB&nbJ|I-rJj)cKMU@5OiZEOjuE+}mmjT6Py{8nVoixMMgb%YY4I70ZnG@Ks zn6Q_?g;{dM#4o2Y!OE9T<<{xaq6(HEnw3SPV%SO05%6DU>@z-!3vuvxXDW~M7FTER z8kqnbWQ2&6NjDQW*_}z?noJkSxm%51$mJ}%{lKC>2U7LkZcNm=qFod98SGyp0tGK% zNd)SU@ageKu|NNcMHb*>p%95w1?5A83I5ivQJ=nQP$-762n|2^bzRG6Vjx zr-ujYC_)4!ED=DB?6LlHJTh8;Fr!78jtupw(C+F(U(i6PB3E6hVkA@@z-in=nZYSq zX*PAx#B?h#8HkS6N!N9Fd=iS(cjsv{B3Upu3nHnTeTwQXXb>>DL?#2Fh4J_>va$n% z=5W&8pSHeR9Mg02gd5Kcu)7R~^o!bZ4bl^Tk?_>9CGlpIo@vk}zEq7+f{)znXSCpK zYNP?_mLCNwv7p3n{A`f{N9$_m7!I)hHr0Eeq7N$Psb8l>$@I*uoj|~S^jJ8kJO@+| zf~rC&2aqhCMTPnY=zyuv?yB;a(*Zh<^wq4bcD%Fj_=xdy{ znKu5b=LnRXiF*cDCG?s+&tJjOQqT>`1R~tmD7yg@)Oq!fe}J6Ek5%4$Sd5pl8g` zh`;J|_pv$Bw$q_Bxei_wt5vL@?Tp!mir%?-dks%wjF3}EA-<^^DBQgj1V3WAvl{^y zN>No0$q`xS*;}sJR8IraEpJlkkd#Vd0FiqTc^vQ50BT~omG6a)HGnF=PH=t8_p&Ge z{S&!I@@wVEObdQGw!5bH!9usTW|k4X12LE~GHnEc+k0ENj^)m(CB~X}-VgCNj_8&)LF4)0$29-$k|z(}FrLH7-k%hF&SBvp zS)-Pl!Uc%oMppzCFqZ67T!1VH3)N%PiV_rvU8 zv@=pzARZhzH)+Q}RFS^r?t3Ed<53YaF0yVvCFRE(jTeCI>ThA5<&vSZxbDJzaQPjj z>ewi~W%@bS8r2K*H?%y`%P$x@?|TwhCBk;PAyQbiD$9h)4P&1K$CDs)iZ|^A{1UPC z2R*V_Y^+v`W0^J%R1zpRPv52!wxU00T13=ztHr@g0W$O$&XG(o4=G(*Bf{8W7g4qJ zNO~=Tw8j3c7&X!IFn0Lcrbw~3KWNyj;E zjQQ+yEaN>-|4C_`4?NK~&}NgandBC+If_sl>4@i6!oO3}QM~Bup9Y8TO1uJ`Th@Q3 zbeELj&IGmnckM-Y3xBjWulHBL+@hdnDdv=IVM--zB~MSG@*;G8r-%4RL=aAnhMi2V zZQ<@KMiX#rY3%#j1a;T%(}#PswNoAzx2ZfusKhhONd3+77UkoIJ3gZ#0J!(@8JBIO zm{Py13w4~_L2FrmN@sg)KGt?>aVguN8G!V}z7j~l4~rP<+AHLR?L^f=lSV*tE7}`G zN_%v4YYBE!B*>=L^MT5Ma{Ue+LMIVhoz`j*xk+LBq4 ziiKCx`AsgiegY+ZuKQh3QY?274>xjVC0zqUn;~Wk>su6yteSAKnbK{uW#mLOfVqo* zIzmz~f+`TEUTxz22)L%W;uJI*-S<#E?#^q(N7&hHA+tY0?F50fNUG9)zSG+^ORk_O zqfJa~k({L|jRb_1;BOY|)j~eR*WDx3-8(rdx5dQ~`Q>~-bcjzb6L9a}7Y3#U>0Z@mzDimn(L@bpPP{GnrEk4<0Ajn-AGPWv$TYTil{_Hb)igP%|Tr_ zpzChqTl<)C?O+YlT~=0p5MmU@O~k;*qHnV$u~0@(3c6Vw1bE~DB?|3GcpP^%gt3vJ zkYH5)D^P{`f=hPl_F?aJ=BBgYCc;)GFN@qnQ$9m&=|T&P)S(e;=jkO;v3%tEy1pED zkMMRJLj8QWYN`hc>qe)8vh4T;3iQtcxf^8E_>b{34r%g#BL1v9LD*jmk;R&|FJ2Y` z4da?^=IIcOTM^3pHaq76zQZ95QxM;CGPB>}z>bTS3HHIsYJ4pxhYBx+rEbus;FVKzq z;REUwggbnnGgMm~xx&DDVQS#H^N}WM28uNd+Lz?9L_CwR2M;V(N;A=^;D0I}4anxN zH5C^x^LnuA1qq>WaK!VK<;fj91Y(P%r90fM?w3q6ef}Hq+V`#5R zr-4Uuq93LwR@meEv7Lv4$=agh@Iqe=?^7xmFsI_B;YO|4C$uWuu&KZmB^&2&OpSX(_Z+i z+C=Go9s-!SuaH-izZfg{3X~=i84)xd$QdYi?IzG~(q}lQNU-SBSoZ4|bQ59v*lJs8 zBt0?=l)4slIIf^LxbTB0b$s5TH;t@h6;y2Kn|T?B$aoxgB_T%8_H2nC<`&S2^_hr* zAISs)YX*NoBhXto$?z@h^!Y`AkSCBX);7|D=IE&sv{-KOKBK3F;1)f>T;Ezq3bn4& zQ>Z{L>EDWP0G){C!p}XXJuFe<$iTPftF$i z*&Y3S$^vG$UZA;PyrnH~a?2(o9ucRxlpXI4T;sA3tVgdC7$>52x~Sa1>lI~xF)`y}9EGIRpP_IME6nXJild&hs(Ds`lf#v)>mBRTUnE&6(`!VzQXl$ z9A^V3Is_~g=XNNvl7b+tU={=-?nBdDHxbgEqn(w5ESTIfkt25xN(xS13~Ki>g`-lF zsPAeWFDlQ$c1JFEalbYq6=Ej1aJ8oUxW5{f)}CAw6h`e}`!8#cpRM1c#914_aS_%1 z$+d#b?Nt{l9AV3~_kdbNk$H^3K@$+q8GC#!thl0td2Sn2+gO3ZxuqJ>+*zL020giX zs~-kur5DlMS-Ev1WayFe+CNxrI7rbu3ub!TL_Op>n83jy6tP)>`nmL^4ZXrfsN$5J zM#aK)+hBVWl9C=(F8Oae{=bybRC6vDv_l)Z9?@O$)G09v60GM7^t#Ri(h;yAOyA#< z2agzdfX5jWN<55?4iDcg4<0e_@Qf*>JS^#41w>9V&Dxu+7jt-W%N=D4`fyf>X>fT+m7GUvqoRz zO~H(nUJzd^G2=mZh{$)t z)~phvSO^91s2GQ^DD*C*VT#PUC=8&R|K49>sX?-=6QK7ErjKoc0c25G1rfm98Gj?e z;~BKlYt&D9LEE+H3cD0%)k+Oe_t6hTr;3w`=iKlPH1-hqKCv34Aav*y*ixhbb!;h!ygWQqGzhQmMbFaLUnT-(aGSNAX}x zA*Boxg(yq8(|SR|7OOf#HDXb9@A#Lj>;sZ?E<>2@=qv)(07T%Vr;&CQ3oa7p^JH$M zTP(OnpOpav>Mkl1aaZQO#|Fz{!Jb z#|v>=^&M(>w7(C;ph0rb2wZ!*_JC+^FwJxZF6>NpG|?!_ON)pS61s60Pen)qmFFdc z3n%F2{cM_*uadEg7mul0ma!EJMnjCH2*+89=GEx2I;#8R5nYv16?#Ykhp%dNj6fMv zw3HU@sEb6wlNNoXl4Pp)s7VPBLUX^q&v(>Rvv^#6)0@2R^$z)g5{_n*d{j1TFZbwL zjAF|UcTm3fRe!G;V$;H!iO+>h!E=`%2q9)5A%wv=O>OGIorOAw@&=i2B%+`QZkfmc zi^)8?|A0IBQEwMs`97o*L9$dmd5f;a5MD;lx7Ol`3JZgtjzv6+W>b603Qd*RXdo@L zyU*?yydg^(@n8Tw9GIzI<9TK(TO63dFX(AmK|+(k9t`f@NZcacWWaUx{t@=6eAe*y z)2~(1b=|`%?X7x5{x`?3O(jvwAbvk-+429*F6|bT8)#{l*&+TKRI&!s#~Hr3weC@= zP4hqB#ZaZZ8A|TL12Hu=!F{R@FQq)@C-K=k<1FIWX7EbN1-WNQbTJi1Ew-p0*mCw# z3T}?vzo1v)N`(xBtA-csHdMfqeqfk+Cz8!mL>pQl;XYZ%pX5^D7a9)npxARno3ryr z*#M8%QXc8`!lS7TO;)fhUc(DJ#?{`<+pAxB zH73H!q!rA4{QVHO?MT?ij)zA+zOEi5B7JN14o#j}a@3rI9i}{Y_3oBjj*`2u3Hskq zpSl{XZQSDOk6W*L z$AULWYlv=%KY$96TQIiE&i3@BJu`WQ9!C2&H1+x`Ai3W?(0^-cD$b*Kksb(3s=7NI z?)QBdIhNycfI)R;R3WuP-NKsY@Cmn>N8I?)ynf|G&+_FfOZ~QTz|nGhLYJBl~r62bSZew3u}t$=0P1X z)La>mXW+fwaIkH4>aCM?Dkb@Qcy6wdItxIX5=h@7S1S#qw?J<7!OmWf*Av&$sWwOb zJ*2pYnED(1`%lx+TpbskVe()*|xpae3J*K0eS>gg} zg!A_T7S6epqsJ?z5_m}N0=s6i@>(FMJ*zz|XtCS^dw0@-oL7ZUo?J7GE$aEBi5C>V zA25im=YL8($OgL5k2rAIJ(fcse2yK-Is!}aNGp~Wt@)MUtoE;Q*=yW_DXpUie@u8I zunDFMA<|*_tDkWSAx)A<6p&T3X+TGSbLSuEXCjD113f$!o0+x&IF*}|rq1=n#DsVRm? z9haG4QdG#eS1CP67%@Sq|Cnlodk>FnzDU7k7@3$1aP@>NGq@hHBOgMH!V<1QL$?QN zxJn^vU|}w@V1=t-3q|Tl;~?R_L&yZ2iv<0q1qS$4U^CdQbZ?fDV404|N9Y)o#c(v9 z987Gt3Mw~tOTuK*$_EjQr_=W_DtqqVgVy9Z~28Daak7;o$_- zBzPMm4}sEO^GdLNFQ}`~ZaR4n=x-uW&*`TDj$O30#MHIxYbhW?vg;W_g&7ac(%g^m zp~r%Kru}3iEuJ*U8{RAjNP=z{swXiNcB?>p`pEbUhL0jso&~4N`H zhKXk9?5@A(Xf3gEwdVD31a#MMT&8lMpeR=$P{eeZCi%G6aQ_lZg1;J*3l~07{J@Mx z;Vv(GfioS|{UN=(p{&Q=2nW+%_1s^m=?k6yM6c{faP6-d_-KzzOiBvC?%}IkqY@Y; z#n6g0oEM6%Oy~S00`BP#FOc>-z&&6W^*2EIfAs%X^)LUq`XB%C@Bas*dw^)%|5c5; zD0+=0nv`aJ{Q_5pv`jT=ui|J|zKc3beQTy_Mry5s0`3I;?(%-=ulZz#w4i{}AW(a4Q{5-0=K{2>HgX&Sm&(dKW zs`@V>p5qA*$cNOS;b5%Ujf2De;~=YcsT5vBr9o<3FqV9LFMoiKB z3Mf@M)>UT4|=u6Osual2pfIJjl#j5XCpc85RpZK;tg%?rilB;k)d^?yu#g7RrMw z2byZVyMqNAQQXIm;$I{d6xAG#G`{Y|nGmv&cDqG-bXt=(V7N06HTDACxf2CeZ)hT)>7tb?$s%)KX<6+n#wwoBb@w)fC zdOjMw#uW`4j`NJ{XV1t&3om)TXs$tYbHw0x668YicQO4s2x>YT1tUa zBKg$SbB=%BJoyxy&~e+Jdh$s?-8rHhPdiKeU6>84L0bfkjbBjureASDjuVUH4l*_= zp=NHG zKS)L#^)_)YRJ)}@b7H*>!ivl*gl9g{kMGeBE#rlQn~u;lpR|BU9;=i)fL$OTVopx; zziJOWwopdCS?taj7_c>I9%%lfG)SB~t-A}p5$vOm-bI-8-a-b0=A|Jz9vdk4pP4+} z>5o6t8l%-?ay#7h&%Wbx;_kuWtNv)f&!bfOVg<|1DX>_#eGBudV;{88Ohx z8(^hN{=9rg?ofJV5^v(zX>PF)_J2C?mkk*#_i^&hjudC7sU|L%B=^xXLGSUxi2iYM zgkp@T92d+zBvefXH+^q;pLveGCI|uO7*w|^FU!k7Q0P?!DWxiqku=nkEMtlpgOCL7 zs5%XPhUyRRlDh=e{pKFSA5nyvAEt5s&4LvqxS`D0Pa*5xPFulSq!RMF*L?}?twU8u z!*h0?f{_=jPW*EJ*o;6y7sUM`=dD*TDT&u`*JFENSIZXkCIVAz7YnXWi5#>xsvwcq zn33EPx<_uDv^LtAU0+nz^sZoY#@)D`=gV!^nPSObiokOTqbB?bcM>zpTx1M!g=*n)T{!5Fcdf;exP z;AnVwRNatZS|}QNAqS6>?;mr4mIdErJUOl}zQUQPsF9`19?<>zdw3)0tV;U<1?l2N z0HMj1o&C=+0*msg-b9)~DChwl1o1MZqaKi;2bd>#M7Vef??>l^9PNgNREu+1lN6)4 zUwSgK8~V_cY7KJOdE7nRJ3=}tiM1bcL9zO-u!^SlQ-M$=Sh~3(na>-?$jAASC_)>E zGY+K}kv3y#w%A5O^K^JIogOVZ`$p9xla|9HeIYc*u@$WvMb26rxB^6jgMjF+Y{F^s zP4Y^JgfRlbxDgcu*Q~B323^kK_NB0lrA=? zA~p}1IsNS;MBp?R89aa}IllK|a5RxhV@NYe1E>~u$p;&H)N*{HcBg<8I{fHa&7kSV zagK>JlkHoq@YvD|0TB=+cYa;GU2r{y4>9f6c7rFf!=-_Po7b%Qg4aDPyQAlDW>M~} z5?2>z9T=-25Urs6cH%LB*5avMJed6X9}WE$W%fpThLhGhoWIx|4Qwf-!nPQvs(IPQ zIPM}XAvx07t@y(3WT8za#M64=qq5h{47>CM>XBnJM97e_pa#3QQ zag=Wv9Ei$KaNGARehb4W$9n`*BEo;;I$%cr8AqX)cxa?-{49Zpxeg>~N=Bx4ge~93 zpw2kG0;J$)xDWNwZ?gpa69THhNHhti20XEL{j9)%QD7MkzOOP8Ipc5$kb?7YH1Z`1 z`*~D?+0%$0B)DrI`hQaWcsfex_0_UUK~@(Pd@24k=V84r@_z*^w;bpu$GPiD6BlJ{ z7@%SedAIACb_EZz*b@=Q($C|4AnWe`%!pvCb7M~)Cqr}W{qv+t%}3E#j- z>}>D#{VCo^OyQKSIt(ps&&D;p8r?b2)o1Gst%BgoM8Zpi+r)|P%Lxp8@A0p6bAjlL zaI-hcN9RA8e&wpY(<&-l`#+#)hilj*O8k)t)IYU*L`k!zuLa{PE|-kWAV@HM`5)0@ zV6%U2uXh;4Iu)5hI;e~+8cLT^1h?{S4`swi=F=fv!EfZ#Y}J%P^iS+rBhIOb>8=Or zVd>#u9ZIMy#U@mW!fxv=w#Kn3!d(Y*OM!Yt8R9&?AMmeG&^Di)7zni{P_4nL|zq|JyabqB1Jxut>HW*v5 z!g>%V=Rwy$_mU#G>RZ9%tA(V9>{@p_#`r)kg(xCTM~Gc9gVy3owxn?C&|yp7>+f?! zwjovsD3Mhk-F2b8yZ!`Gnm(35LN|8k6su22o!Z+UJg?m&%&5yelAM6#kEqW`5SHab zy1v-$;4N}1+6C*h(L3fj!Eqmb%OBD81nwP<{H?XVcg{k82Gqx6)W$bsS~xfA@BLEJ z)>umVPxR@+-cS7@&aY4!VKXrVT4*kU@I*3TZsmdZxseZ$DbZjq$i2JY9t_DAR$*#T zSRi-hS#J-4Jh%>)17x~YoR;5O#nD118PAVmxFsQAHY4Ayk(B5)-6{x(@$|@0dMX~r zo$<6-6qa5fEC}yt?cqVQ$%_LkhXwOfZ3t?Pe=8x2Mco>|fU`EBW46w{=yivg2crtM zp9no|g*dQ#QW3;Foug;yN!Kjux)foL?{x z?A|AiBO_jK0wjM4B(g9%9x7>@eLZKcI-X5OvXOWt(O7lb|CV0B_ zh``X{=7>U$>VbYOBFUIkRJ#VstN%JaG~u zp2HO7uqKpJ4p>Ja=?ocupHi=!x-K_v8 zU$W+Oe;1GGyc3UJe-~CcdGxM8tx%OhJSeyi`(5*Ld3?^|+^~lb$C@{#5bqQ_HbvF~ zAl`G*f1CKf1<)LRp+^QYIW5j!)EH~Z&yPWJ3y;?Bu79CEev&>a-4Sxzht{>0~ zG7{H8^ESvMO^+d=4uck5?D3t2m6cXkwt}F`poZp1IEcWgx1W@{tHS+=E`ItEd16w5 z_;R{Hcn2%3vha!eeD0c}@a)$DS z;d|=qy!<7Z8D_*=$+EOgJL!=mE?K^={AVEd0X`X_nAJ{a4430R4gyFonBbjmq&Qm# zeG6k5&e$G`AyW!R5!U_kk*7*ICXt?`4r~x3EZ;xtTPv;LZi}lq*&sbDhp6nnMy}4$ z_(gw+SMX5n*5*~ckIG{s(fs=zRQV}$Xp!Mk*NEakkXr(e_bOF{IHHWK)?ye=Hwce-@ zIY;-JzGS~yG_AJnDTYu2>E`I}Qwd<*fFNqW;Cxxnt|_e2czZ^Lp3zWy9g*Cx{0-qF ziqZ+k3UWrr>oie`M8A(xaI`%zBc|U4l~`iK0=mnOJb@+y%RB&ByDxI1P$<4rBA>z` z4wgz=PU*RLI&-9F?70PW7yUdm$S+dArFWm6NUdKsKP~4|>!aqaeGiNyQsZvtz zHsfXS#lQqM>yRUquE2r`BCNo2L1IyjnG_9^uRSG;;9i<|1p33HiNEE_p5$BjJo6eL zgX=ClB61sirdX{k`O@H1rxqK-+7#AidQZ(xjvH`=Z$ zBUD#}-!$;@VOB~DcT<*=2B^D*VHgc~=t)dbEOo#89O*w|OW*{B=XX6L{uwu#Ev#ah zExA)QycKM_;!JrccljCW#`k-#h#mQi{hvg3A&{MPw_h5ng?*z;m66;f^4Q?`*&D$< zfd41YD=4Hio55VO(i9|EloY?kO97F?WL^S+yAkH zU?dwkRj@4Eu$IEQ&!=&Sa(oSJ@@f6R&iO5G&_6ZDpZSk18x=B-I>Pl z4?=qy&&?@EW{kb~ddn$iyz-ROPm(EL;c?`0^R%5J*upG;LR8DNkuzBC*IY@Sl*Sz5#}0HGNMH~EJ~U8VGGvDG~#tQcm6vh z!p5*d?WN2$&m;j=#FfF>J0L2u;}fi@r269j4Ql_PPOR79;V8VT9t&wT-H6k7;-=t zy9Yxo{aT3U4C}su=Wd86kG@#zZ^H%~>{3|@PY-F?S|p1`hs;96KH;=V>8})Y+UF^< zN}zCBpEeyiNOxh~6RHwI;6iMZaj!eVTd8!|G}>?m+a!f@n6$ zDLfK|L~O_u;N`FG%ghO7hABv)+((-POf#T@h%l%_JQ7{WX$TC!a|5Qy)p=l7XhHqQ z>Z*W6X2K4PxNuesU~bj-ljzHt2|F`cTb?8_MXjq{JeP}_Bsv_#4P_iRSSnl@pUhG~ zgil$zyhR@o)dd{`a+_H@v~VTr8`TYT;$CpvKR*&eaS7;6LUrSDZ?C(3Tp_H5Ocpjd zStP0Xe)o6)f5L#@`!;K`Ad+%%?QKXq8y3%fl(0pSK%j*ej9(w3EDf` zA>C>Eg@>Pr(6B}(>;k!coU3jTH;d~P$}gh1?oKZvi+q~r>h$J*Wgz>`QI+?l7)?3{>>abM~WQJxpEVTj72)nQb6!Nl=PNgI1I z`lrXjY5b5}U7>qa6^(aU{h{A{X?lO&AKIEYz?>Ed75ayAta5#aw(ip>D65Q;O0-@{ zc6c&<+%sKY9>A3oUvBzY-!9X_0VA%N=9MK91usfi)Z~~=8Q9BX9Q3J6r|@bgo{chN zTF5jilEG8YK%7eIjHYHAVkf7+LEQZalHemfgn|qFKf_X_zAP(&?9wYpioZ|sn3h<; zf__t?Ntn+CqB$8r7fiV?DCqhiA_@^H*AWpt<$n|^8}sz7MDhqZ?$;A+3(NgP;)*AO z%?wq~JPjJ`ze0rQL`XI$MbDU7ZQ%^2_R`@7Qt56&=prp;c-)zgbN(&qrbrs@yZF*R z43w(07ClSfa;hP@#eZYyR9j#6A&MQUJ+_6bYIxQ#*`{9w;k5~kDHaZ;ilsd}6T%_W zJ{80yF8KWRAMo6ne@h}Q7hj^z`B6SP_)SO9B4GsigLDK>?RO8J?{v+G&8EaWkURaD z5qXWBmJh8eE_5OeSwj^olEFW-uQkxpIcZ_2XggU&`WM_I-VoH=)0Al&SW@pnFY^iJ_pHZZf@$23Jy^Zrz*PLQL6itkWf&riqLJKJ3x6BB+2_uQJl=C^ThOEh+?w;#eaY z4DAwCdcxpmBRdM#Npu9D7}C*D&iC3`i|DRD78iq z+eK6G)3)FtK)TDy#OoIWl)VmLfPpz;AQxL!Sg>LgQp4D3g>dskE8T+LqaWIS6$B_Q z*5($$IBtOnp#N}5qm(!La3;JHlWr4lv2_PLcjhsfk^TvqMS1SELscy5_l<>JPuF7l zSZoc+U6Os+r*|iU3hyp{4?+m}M_EK% zsp~EV0SszOq!}+VZcjL_%br=EzB8UYxcm5?iC!VPl=(+b15;QT-`~}lqv#$fE1eG5 z|6cv4|MXAvKlg69OsKePmP`7|S7{dO(d%cbr$G-~q-?pisvf#XTG!Q^$HckFYj`T7 z!DKLTLAfR`0jE|;!Jl8y?g^Mf;MI1IuPVp#LfuZaBTry>Nv0tPQzR)j@@zZT={IBX zmNU}?=d?ZCZB+2S5B8ZLyRH3OCepx%YA%3ZI#=Ssy2F}A>6cfxLx!)vL&Ubf00=0K7tn0ZJ^00CM+Y~QNlJSFEYI?>xos<@~ zFGK8e%FYOzwYMc z2g?2Z=Yt(#y{}*W~mOH)XQ8AvEYm{^VQZa3zGChi&JWo&| z-J++PjOu(K54kbDEO;8ry(A#_iv#)(`UhPgl0+XUCu!$etO*ZM>s*58<_JCM)|Ei@ z?TWMHDc3OFlBb+nndbrrHWaaiZy`_g#oyh}*1n@5g;MiFit+(md&W#$A*QE1aRJSp zUHdK>%qSxVJJxQWSw;xR{bFtH{zEGx_&nF8nPnuwb8|#4=~h_dx$Sz^HLh5Y37Mo+ zCeC8w4!0;h$xK*5B%(zo=3Q6<@o+9l~RH>YzJ%S&LvU^eieCYNcIc z1jvmd@4#fC&!~@7T##LO1B7dMt%fXq1WMx54oAbAVJ$339ae50XxFgZ)%);nSLl|0 zf!BCLtQah(2?ED+Qd5ZY(O&DbHx|S#tPyBxxMN-Z*o;mu91Sw}y#c}@0_0%8$%wQZ z*Y5shYyIx#ceu$rz{}0#TA*RQ;uH8#AAzrB;Sqr#*Iw5uBz;8<)VLj)hI~>@hEr&W zy0T_^PmDa0Hhy-cy<1u1e?Y22MS1jiQGTlB$PAf+gF+`02R`yGulo9ozTQI(6LZU? zeF-ueXiqj6l&R(^+&+2XWwf++0jF-5@-Nxj)_9_+CWHjl(DbJt9UWL=$ zTlOm8*r>wuGQ1RIm|cT~{Xgv(wNJ;;;Azy&Sp@WSIVj&qMnS(Mn`8a*HDbAo$w@SR zj3Jz(zjBX_7f8lcM}hswIMDaXQY=_B2{I_1p>L^y=~-d$ROZFFz+bD1pu_0#+@<@v z$x}L@{>sZeJus1-w-$0wZ3D3s2d9-rAU6#qe$xy!D-31g?oh`^N>8xdR}`BdaqFDh z<7sbFP@4}9O^ZWRcsoUE2VvM(4*KAWGN!YG&|>@pfak1%2UUm9Br99?Yu+=L4p1&) z2Wf{0`|IGpX5L%qI=ZAqvsDkH)Gem_z<|9o3E6w}QS z*`)KoIOvb9A>E>YAhpqMqP4rch7VAcsC(EOpqyzMoOSV_|0CZZP`FlhW(%%VU0L)V z!qHA23;30i&49X#YecKMkJVL2YPn6_q;!`24KOSjpRL5LZP4&K~Y_J z>fiwNYOT6xGl&NsRa(0XYe)MN$S0u82%Z7KW(?6kPrq0}7^ya43W(iV<6IKNW>Y#7 zWNiUIKypcEn-`oB_`*3VDc$v@=iR`#^R)g2Q-f8A+PtTRx(_`Y+*%m?sl)_Do&bFy zHPJSKn-W~~1pWI5rhf%(I+dj2xC_)l|5r*-$8-EQ3PCaSW*JWpBjn_dJ1IHs-|O)n z>M~nz!Yut$93klcN(o++0mUsKRsQl;mFZ@|Rj$h@#Yn}chUz|iAn%CC8zPh}zQ$sP zl0TrHh_5QO)SM~|w>NSaE2Xb6*em(FRCAmbrmf0o@sNmbmXblJXTE~q1=#UD@^p8n zJVagCm*q+hZ?0)!xf~W$3n-9}JEeey2|2>+2K!mH++xEe6@+Mp!OMP64Sb77BT59) z5nVVK_iGg;)2?C4hx!R8ZD3FPH}a8 zHXTkA`reTZPbr*4r$G~hoBQ_rM_RO)q?}o2%j&IJ_bBvsE~2UqkWYr&eE%WK!T8lS zs%g^w4gw9$!Y(*SVsEImmvxKe=HT-o%<9q2r?MBw57_Tz2o)4pfso+1rH6FG{&Yy` zG_b9Ca^??&)Bx6&y?dCAl;F6fr-T=5S0;7kV2niD4ml-JWttw_^x^5LYHDG_nQYx@ znC^qM4Xqtei8~QDSgFx<{eVn~&Ja6Q5BaL8&25Ifz)?n7PRE3=B7TX8Swj%=b&2^w z0aN%*D9$!h+MrO{+=Ly}f*$g~E`*g)Tqdyw+IZYEp$)Fi>o@vLN9~Tku%)$P$tS@9 z)qReeZjQABKV3XEbGQe7NOUWDj5)Fxn}ENMg}>nCLo}b{3`!`ARSJKeZV!gl!vhiE z{Cc$?HfXpdoX9Ct(LcA&;(o2c8NE}3#2L#|i!zrrpeZ~Bba#OssG#ELl2TYPO^nsm z8j#v3mZ28WBsH8oLsQ&JpVS&7Ze)xo0YsBfxjS%ex%taGnzAMpgqtd5K5pLg)N=!c ziw24;u&lkSfePU6jJOx22HN}efr8xcA+ZZbWP1(J;)R?VRDQxze0O<0Qme4@!Y#z{ zJs6!2YiOhyemve%3o+H^o9}4$m_o3?+ya>U@i?_$8a%;iK&7?WiDRejUGZco=sEW+ z*RDcDiZu`l7Po4i?r4we)ym{V7~y z3l_M#`#hFA4@v;#CGi}G2_gVmr;!Wa@b|T_@qIJjDUU&AK`DH+hY}ieRl>e)PiO(3 zj<&;Gr_$8IBH_k?Sc2mOH-^OnhPG)&~KlX9hgbpSsp*sx3th?^XxMEcuy11KEYqX!=d z3=n6{;JHulQ@A&+nFm@yQQq%Fh~jvR*jbz%H-$DvDmfsotl+wAZlonQd+~=B)as(`QnMmoM{Kgp9?k9>ruUEz> z_(3AE#-%lv#W?>Bq7HgpM6H@*_bGgdGoTr>!qk+hKr@~AIsrz}-_)nuN2^hUk_=^1 zbjm!IJM%V(QCmr6pmmt2m|A0D9s z7PL2BZL$uHLO{?7)Kf$^_XK~|2@VIml~_enh!l;ACj83}Ex-eqTX^#QA(CJC_|+ZfFjj>GX}C*6rsBzN^Y0MaG||G%eE@sCN3Ehts_BwhD~z|AyUuVc)Cnbi|_ zA)L8nJ_ntMphvk=!oEQ~aj8ig4=Vd2oT0K`tKloWQkS)TXMA*k07-kbRS>`^{tYv$0qHJ0 z^$bvjdL)bEg(5Dbe^!5LS6$%@9m(c*nh5C5DpBs}`w}E9)oDA>OMd!M4$%^C@x}>W z<&MQ_O1N(RDQ6VMhct){b}Es}nwCCfze7a?>Gmg;`WBX%Lg~~`2X^NvK#evAJW!_8 zu>7tmM9NKbb1J-I5XDfaPv=Eo@n(JGBVNOtdPj4S0d~K>=c(bZvUhByN%Z> z8~ok=xSth@Cd`sLTS@cR+26BuSNA?Y%x zESbOmN3r+&oMis~YpDg#k(w!o*w?%|+@`~REt{cWZJ(e{6wRH!=W#I{zl_9?<&Sqv zC*#g@xUzdNLuAQV-QMDUND*uL6hbluUvl@EcI9dN<;pX5RRKFN<@u06))p@O&2$y+ zj!znw8Y*6`@SkuIS5FIL1>?(449YWfagB>t1IRcwe6%q66s9&nHBh$*uOLzJCO8T2 zC)!jBM9?O@t@%mvq4I1Ci7I7H2Wpqa%gfTlxvv11{ zShpNFQcB<>s`ua%A$jJ>G-EWov62CH=O1XWHjRl;12<8GMXl4(rGr;Rt;syQ2-i{F z(zm>Q@QIq~7~x@u7O{X56{HHXD}8q1nF{YdW>*(kbDnZ_gPuY7G+pi=>cH{)Fe=`- z(1)P+?2)|1K}W%A@{Mb^Ald;M9uU0O5-4KdKy0m0#qj-Fp_s4u2RjGHolL}Ai_2k! z$*`widG}+W;NB-L^;^Wol5=ugdHP`Vx_;-UwUd;3NX_&Xrv*i-v4@YLYEoRc@>J}r zgcewd+Q2sngKO5{?Ao9K>y|wu_q<-@Ed*zEuemv-EPHAxgl3(vfmlqpAmM7sS*1=s z7fJB8)%EoNFmX>j~3Cp5r`(PTUi%c*7}OFIUEeV%P+T^&n}xyTz6?b(5mg| zVHqLp1a2l88vh)KcW)UnZ4q6ia#mX~)6m_ubx#-9^`0_S-UK7GnI`NV$>TgIQVY56 zOa`c|SdX!M3-+dA!U)2~ z%pE8Ya34Gq>Ry%OMh`-v3X{YkS`opOM4`|qC7iC}*{z5=s#|*2+wG0W<5hjjbc{@D zDplBKGOnQ6WpWz2yRxCrIf;a&PN9#&OxBw>Jws1sp2R%1yHsZ^_=qkgY*FTcYz=1C z3hv4ib{`a_jgW4cZld`kKQ1IV7Xy97q#X1Q2e=ru-qIG=nTksl7B7!*mk557-1P^FU?1<^L5 zAQd&i=|05>#_YCH1J+&o0hHLRl>r%3g}nbt67t(HaNKG*7$b%YMgI1qsnFo8MF6y- z)?}tk!~HU_8Tp82MBw=sK)0vL&!^8NksQN?eDn6I&!pqlu$CYi2mPOXfINocXSE3^ z#76~%d9!(ufLrk?;Tp?>(H=I+pGYv973W*{cS5Z#uJqPGa~Gcm0=C@z&jxn9{$=`j z$@S^@SntIUQh!}8CBSwi&p}n+`w{t{I zawg2w7Vh6O9a98Kz~Z7Uh^I)aZIA@fZ~7o^$h?^Z1&Bxo=N`-~wnd()E1F3SkKNRS z>^7&JdP4RzToiPm#O+K@_R?VdBiW1kqMzw@Au6p_+OUq|u0K0Er~b zNAr1Jj>kmU*H*LwTZo_x^GatO0QhZ${^E`VJoh^}bALPP4qtG<3{}yEWMLYp+z1{! z^^XRCq07P$f+0t!>%kWToja@c5~aXY*h$bPWys=nzCh1~DMVHVLL%VY0eWl2OhG}P z1e$U8iWs<`r$4IjR7(Y5+@mASwjHPONX#CK~aB zktwx;O&c7>Fc*9+Q!hXk4lzFZLG?^uq+IaAjzekvh19|gbF2a5n{#WSY60EHn>abx zTBK6Gpt`Ysy#9zUAR^R9FJAS&PmZMvUDGGC2pXCI~eTI7iet;3i6iE9G zgO2?80*eNFq0M)_6kB5vhZnO_$txWETkw>kx_|cXaHYIqlb*)h`@|fXv)%D_AIaZ` z6pyvjd43G@*34ClEVrW(N~t|xD9V$cG9svdqZ?2c`}3o0nCi)Mg1<4BDU`lk&nU&QJ_?KgVg9*#>( zub>fhPYoJ97VND7I-yVn3Z!Lup{jOFrLPdut0aHw56NiPk%R_OAUD5`rJj!AX(F_> zYnS>P*qqEKn(LNyX4o5cKELzD9V3qgn=;vQedb6&aG$I{Sg(NfbwxV!KmPsy&~v${ zzho!Kll;96E0}>K5Zsqc^7jZDc<>_e-qLO zIHEzXrH!hAmv;E}3?24~RWj9IA)@FDp^7jfAN+;vi>DMrgt(IX@g)Rgnb*QYweNp; zYcBrqcXvy;_`}ye^i_)xVE9QbZ{h)QidUvWP|$b$zA0w@Gw}0dh$1DbW3%GT($o8+>G2Ho{`hzI8=?0{$eHNxup3r)ha~^(uL-k# z=ho+MDPxS_Wei|6-SRk4KIWKb7j0}r(;G`RBe)N_vjF=VF{ZeNLedwOu^OI9CvUyw z8oqN22-?Y8Sj6Goh)%eePYw^hlecDBNQuq_RV<_{(#cy`Nwhh`-+{B4e=bZ3y``oE zA!y2Lo)A>!6NHSS3JPfPdxGgm+C?$L#NEQOlzrgVEi8*?INgt-6TUgx#g&OkgjwQM zgkN=zhDd|3w>5=rGc3oDeOU)`k9=Rj0QEJNqpV(`y7rcc)lwr2pm*3(DOaV)H!Zt(0rdWy(o{}xX5LRq5j%jR_3 zuKPEi0RZ^U-^QYYWYd#2Qfjkqk436?-j*r={FZnJR3Avi1solHT3FS^&c8kC(|t(j zYHgz5ysI?Nzv6lR0>k}1>Z$jk;3lJE9BgTbZz8@AK>=*($>@GzcZwNEVxthn@dfq? zQfWSp4MxsG#D3z{)3k@yn4f_h0p_`F>G^zO;(@%?B6&UWC4cTK0#f ztu3atwM8c;aUw>Nf3PM_8mNc+v; zv45tU`=7k1%{0HL8Lw|V)C3^5EB^I$_2>R*LT~mamsWADeo-?b-<%lPkgOU2^>qdR zRA=J_uEZe7@fa4S@r$plDcO#kcjuFpMF4J%rV;s5UQ7N- z&bsHvsCFjd+H@jAZX>)N72T1cz@Sv3f{e`}mkh6E!^2lA=~Kv^SMN#E)O%18ECfMQ z?He4*13btr4qxDLZiEnJ-cu`h3!_Ua?}@LWy2W)*Ccdb)ghClF`F<94hTx_$242B= z8am6(eLrhZZV5%b8MWd%*DPg=o?xz0YKv4vX>I5!k}YIE=jp)XW{Xs`D9V%}!Z7aY zI(3ocOKeAeCk!IOJv-+q4hFXBN#Vw>Fp7kNoW>&rob2MgEnGayiG@k6cv3;sY!?e9 z2nrMvFf8CGpp<4#&Te`?HTC>0D-$#(bmMJgr_DlX$__&^mJcr3h8yQODj4%mks*X} zI6CxyaX?Jq!k?DL?}Cef<<9eRmHT_r&PZn_<)zC8djx_&Yh_SoTQ&j8U3lhENzlH< zo3;M*J?{q`(NeX;X~At>m~g>y*Mds{adDI0?va`0`605Yga0>mB)1@n0=G!?_Nz6; zaZBs?llu3Rv*cN-L27tM(<99^wjhPJ=&F)RaNx3jx_$=|%z2PBc|u2B+HcsU1|7xm zbdvs@rt35G(R8KF4i_$u6@Vh68H!$0_cjB5M4h?le}hot&hQwo7aVr(SR18qd6IZ8 z)S)VLELx8Ioz<_1{E8aWbINf+&KhN zW?&I1#lzYOg<=zz+O-(b)ml1#PN7oo&1YF+{)p;65)FDBsbvSXjTWyHPO;qi z$AnyQ#8OhK>I%rxW!MDgQns*ttcw}kLbOf1F6T=x`ZM%Bi|gK}L(O`PDjr6r!#D{t zBnoey8u|sT6D_aig*D^&%Ru@!LQ19d0+Cr9vgbIf<=U7(+}d~5BDvFvid(?x1px@i zLKt^A1QfWbw?G zkmX>D)A$fzc9>fUPp#OF;^45xh_pY_k$;;!u@wg;;{J}ST3o_!Cx~08YY1HM=_ZtJ zW-acPMHs`dX8@rhnb5irO1JB?AdYGt6n>eKEvSqzh0QSBh~>_LmdE7+uFh6{-A#TYS7L?xiKN?c5C424$`3D_ZM52Sx_R)wUVODpK z*c+yU%zR`?AVfl#S_cE-I^;->V7EZd26QiPhPx1qrc28=3mh8HhVEl1zTA*31oD(f8a!0LPtavSGY`;O*cA@#fuc}Fx z4-r5bsuhxrOj=W^^Ke615ij+fqF{|TH$w#=o#_9~2hvU4nGrC$ya+OTTR0OQZPThZ zeQgy|nJdyvn3U$|G2P`2{Wl%WyVOxC5l-~a_LH6U*p=Ej22`7UInePxZad++u!^Jm>a)W(>iv6Zhj z(ZLe4m+u)I5CW?7u7ci=$8bKuHQDLXO9PU_Zmr}eC+8PT>17_9j31E26?A`_o-|}DE)JRRBn?pd$Pb-zgGsy)F`W@Nr{cz?)A zT^vFwqWbjn9vA2`Y!!~uNmQ&h^_s!L!NH9Wst5Wb(TMaLL@FC%1?xN>Exlt|)u7_w z`i7|ZuErt5<-!fzE`St5!TDftj=M_{j#eMHaY3UIltj`^fpO=UxctEipV%6{vmki*+PbLLUx~Z-0ej9-VUzyYRIm zY8i`bTk=5+!9oUR;sH`eR}t2INq5?MlT9Iobfcd5-oC0RdegIn5C>Fe@v$-(lx>(N zs5sQe@vd$=7o2f%D>i}mbu{!67OsF)Rsr?M5hp}iWodY-D@1mmTIg%HJL0 z;na}by@qt5r*Uw}NvxFV-xTx5P)K4yZH)t5g6kt)AOm@3uQExyJlmWe9twR`f`k}6 zN_8x^>`B9dkFP?{dzxdEM6yTz7ME#>CrPLYiYgSv2Dw^BW?@ytO##CYP8#VTB14$) z+;s_r+1LGnKGsBjjONPl*hklA7e_%o=y2NL{0188xg7uZ{_r7=^Qp;n>Ti?AYkUO- zEpqD1vco4mc!@etFQva83HgiFpC*(%$WaUaw!86%#9Hs$M3`PzfJPR z(G9mW!maM$KwaXtS1p_q(p0E@VvhaS zJ5cWbIs7{3HEywkB=i&kxy4O#iDhsW)W#Cfo9-S3_lqu+gqR0#*D|zXwD2-g?Ge+1 zQr~_&&C+b4V70xU%{rR7XIZ32Lr3|?=?m&rJBK$?@lPdWklZ4K70~ITMAvqX5ZSba zbm-BjUQejSRxAMoN{_KR0n7d2o;dKH5f!prS+Q@@!}FhoEC>9Pf-oejH<{rDJT#51 z5uV%5c5Pp6aUFwIL{Cs9gOP%fbosxjge^Z-g<1^qI3LzBq-%E@^_*+FO<@9(6Q#}Y zjYw|!ncg_T{9O z(lcm<*P?2nX)SbbtO*|w+^W`f;37468=S<2?+s<9Ij9iwlNi{TQprh_qo&<*3hNak zDq?ptJ)_pa5GN;ThIBB-891gsQs1F7^}O@^XwQ-^ytF~T)nPX6@w{~phi&wkvO5tb z2TYKe2buh?UNB@-F;m+_86`k&{u#bYwKB#Mh7}xQiV4rk`hJ_ z|8|7;CAcz%Ss5)1P?+3zSr zxyud@*%3&Ng`><3+KuSB8>+=avrD8o@@|VjOy>(jej;gxgy8^4_sKUtW1BZTr3c4L zV4D~@h3oO7k-cLmY&?;JjHN6{ax*Ki##SbgM*1isc^X@6K?|!$H@DaXi)l<&|w*FRlVa5BoA@O;ns4N29^W50#lc{;{U6Wo4#d1UA^19PIxpkLWIL-2F?) zJW5$u8I%7Pmkjyst%b-kfbV+)%dKqaXDQW1#LB@69}jVcMq-7T*Mh>+9z#h^G{UQf z2k}n3xidS%Qbs|p=Ly`z@5rO@n~WttART;mOx7)wqP^sq$r_GO z?pAnS01wlnAT7#M5goZ88yw<672J67@1auIrsfS{+@thLGd{nWen%?5=DC0sy1{Lc z6S~JyUQ6U^*J0d6`Q*l@)vNKUM6=!CE1iWg0=7Fa=%6WIT2)`5 zmt3#h_F`pVpasbg#QZ&GSj^cx5u!T+Dll*QRdDepbbQRPL6O|`+kZfk)7|PD3gbfd z0G(fHURLy{T=fR(*Y>U;EYqn*C|nIA2kG|jkxI59qQWkFE_1`QEC=*bUOk9^Mh+AT z7sJHCS4eE`@%wqempMJJJr8Mgw(A9jF}>>vmgH35{u0B!0kaa0XYqk+PW7VFN5a;f zTK$K@8E!glkK?OtP!R|{Z#<&&Dcfr%=bEfo*pT~dI$CyYrs(YKAnQ#E8hq{(Vjpp_ zm+CwC%`;?eJ&M`MBD0Sr?+#`5@#(!YmeL|vY_!{FXxsFF*=Zw_@dHkv{G2iwIYS2t zc-WZrauzbb9OgcEF<00(3bU_B$dvW}r1j2G{5S`q?3mxSs=MixU6}SUs*==VR%aRm zkK>jeunP%fHv}2o#*)K3doKp5OEx_owFm{NnUxtpY}86cUAtboyQ`r)0G5dw{i1u!$zl-;c zyw|k>hO*@ze~n_it(QL1h8X}Ksnw$e1uh+>I^!5Z+fN_aM^}eRS><;_eeTV6py{%{wgO(ls2B^ELgQ3%) z7da&2u#03UR3Ou}b>cLjcd#w>tXPL~%St)5elOs@22OVg?#fYZclM}CiunR~@+t+YA4_0E+dPK`z!~hSfPa z8s_{9g^M9F`q_H8DV_s5w(A;B(A=+oz!?R`9-j-q%F&Qgt)i=e_hS-Y&jpS_lzf!R zZeblqF1QcUIAz1bxvNb!a8&YXP8Y{7D3Im#)~oT>POmpawC~WqFi;o>)u7bIQx-Hj zpb#1c7HE1}U!=f`SNVIm!kjA=X{~e&lDUIBgOJBv8h1021ualo8w!O*=>O@{w{TS9 zb+Ryif$Wg%xxZjV#6F?1b}7Yif}5_H3qpwkBG9=^5!V(o#Skeyi{=*SCYnSxl&`%y zenGO1=LC>f^@<4Ru2EY!m<2~^Pr-C6ca@I5R7wlvif4kv38mBXB2@76#^ENqhKB~E zTh@MO5fpR7B0o0FMMCSdP?`+~aS0 zKCA#&uTw?u7$MLp``M{G`PHlO(U2|<>3x(ADLwQPZ;N2%LMqAP#SJ~q6h5pV zUCVzxc`f_)7};bTXQ8W`=Q+hLmX10;xCFhnw8`~@o`Ln?xzg|6e#*TC^&aK$0PKGHMQt0@c|7W^mqswf*1LEn2-i1*Q+>X4^BoozrB$t`-i$@DD= zn;nY09~{-zSwTe=<}X0GtEeU-LD)it^L?2L*7f{YG8dY0R4s;$BOUMQ3geAUIuli>lDZ|M16t3TU_(PW4HdA`#r61E3V@-C43&rvIt zkGu1}r_BhT!a$$YPaoTJQAtW|$r#+TghW)lNYg>A&loqMwx5M#pR7@@7GTn)SqpVY zcMa6LFKLzf1{iEl4&!`%{5QOq*1JQ7;i12&)FqcL-a^hrt?UMk%-PT_^cSR|dmxpN^1gIB~AB`JopoE++*$1QfR>@3tV-A8Mj zPFiXHn;bbIlsFIi5>6MCp%LCn&y9bJ8=ovQDW02qhR4j4J!V0v$_+s(f^9TWZcPXh zjwpYkdfBqq=cHbkLNcqWKd zN+^K1<;R4#vGKU_r%~EYmZ(>UgTv<(hKAK`4t#CAiYcuW$9)(!Ykb^Md_=R5dFK^8 zXycOh2)=9U2!7K}1`xVJ6FfShjghCI4l?w0j`}*;AHTY_b;tCxa7~yUQ^x4rLBa6N z#~anH)jKqjXAuS@Z$caF7F{97XwT=JMG*I4T>LDMQfh*YNt!5-JU1osw{V`({?usd z+I8n_dfO?i^?G^DLZGxi%W@m9H!a@px3 zuO$Y!qzk-oB-E}^V)C}y$xSqv8~#Ii2?}G$(ikWw3OJ=)P-W8X*e-OPdlEm#kvG!T zI6fwRO}mY{{Pa#D6%XDUGzwf5w)`>=O<4DSVC4s)S>207F%yem2_7qQ!l1U!&mh34(`Z{s=d|@IR7&+TQLLcDkZDM*T`L-7oJ}_Z~m0 zy7AQ*;e{@tm9UJ+4h0J1R&NaDVn(D8$fRW^2vN=*D5XQ8lOa534XoKFqXwvx z(Hw^B7zSK$9w3EsGNM?5;e>rE+|QD zNrR`A$P?X);80+Osc)_Gzn%xY+42sfV!6PGcfGA4}+$KBdw9vB}xiHr4CLdu@ z*E}tfLVhk%XP(LWZqlXGn}qf02-BrcI=%tNUERc2Fy2d^1-lqV&TMv4k=$vnUn6d=E90Z*NJxc3 zL9#slzoVzKlwLuYMRCN+xzpfqG_r)!W8hh8)w~!f9E^l488qmXAKHMSH;F5N>1i8WdI~MI8bFZa)i{C(Q$T#wNN8z34?JB z3dbAy1jkER>loP7wmOGph8-IBn>KT&&B_ifRU85m4wvCeeR+#^sOx@F(>mBjc`G>l zvDR5M%=j0CQ5M|Zwnqx2H6ghU>wXPZ{Fl`|(Clwl-*!jO;nhZL;C_;TzBER?-~rw} z>h;FkU8Jm}ny1A)7$dg^A$SS~({L3ReaZC^EpC;Ul-YoPK$1Q#@h*f_)Mlw5%-UZJcY1%MOE7M4$_DkJa?IsR^Z=2W*A;bHbn}Q0o}4w8Es+0W{E47TiWc7C_yIGM@wkZ zhpNgd!x<Fpm*xoK~4K#$8=_b3Kj@H zjj;qPu5KfyBLA#-HCbYPIO*Cf@Kl4jCukLO4$!^5r+vB$liWAMy=Hs z9h^J%j_hJA=v48KC-sA}U{Vg`8>LaL3k@DzynF(uhZ)?06@aNg2s;D<&u{pD`IX^u z+?h@Mt9m3)jG%AifJTf9Jxqw(fDvV-r^}+S+Up16ESCFVlSx!4kpV~EhLF%#plL?0 z=Gt|-!@l98V2HHggYn!)Szd17a`DsZ?)oF*X3=w_+g&;qg?SDVX45KbVAwllFp|CV zeg7K{!a>%7&O&1Z3LzF#Mj#96KJh$oWDW?1Ik~a95y#=Wu$6tqBps8@>8@WL6LQ|> z9!e=tfEM6^n)*zNw6)5u@H$w2fZ%xiOz2#X5B<)rTZ@q4-XFy4-bMrCacbeM2f4oWZlH+*PL^4mu_zg zM@T|~QO8UabuHuiwUi^Rw80Z*{)$p~R@VNWqED;$>T2c-FM*McG`#Yub$Sj>?=wRL z%)q2Hty(kKJ&qcMLY{y8V;=|hX%oubS>RWq1Lrkd=Mnz4z{#Z;IA>1=mH|)LkQ64; zr>+DM$Na-Z$2;STFtYU*l)$fxe_eGk)_qxcakWn?^!NzyI}rMqZl*y$SDtWyc8qoZ{evp}kD`ZxQj*%`GmTDFpk!w~rAVc$jw)`(wG z1D58|;SO%aI?yYnh*5rZ9o7{7qA(x$Y;eSkK+X?`F9yRS3UW3BEoF{!y73M;NLLlC zu;3rQfF~FOp zoBbo)t7#{Jnw5#is;;DAnZGlw&zZlQlM>_eNW0|9fK=|hRc{2RW`z3!@SN(5`JldZ zMX2MKU-6hL@(MM-NvK;miNV(rz{1<^jN+ZFlPZS4QRB%v)Yg_~l z;jG+)NU6Mom%MEi{PHiJcl#JxnqSuijLsrsEcSXiMfpPWs7uF;P@r?n0DglPrV~;m zu2KpREDcuqWB!-dVDwr05SodXWxSQ_q9aQ>V3>cf!C^BJ z!r#Qn1q8QxJTyzj6nse$+6?1|*0C@Nii|DcQfcM*g`96D4s-C%dn!*Icif~zKeJT1 z`$3W6@ux6d%ynNv99*U7jyRSqrKPG16)?@@x@5TW;W^{co9n{7)=1wI(+XC>QLz9w$V;uoWf>dP-gbed{ z=4mYqugq^<$_B{S@{!HME136Kl7f`*$nmm=?2)m9swVuww?wQHjjN+z>pc?ChS=TJ zNwk==i4FxIJsHYe%CyCEHl2Wb>1{FRauI&{*V7#|21TU4#DsvgGpT28AV(Ft@JK#* znjmYH_JFPNS!1gECLv25`w$3L!}WQ(y+$g?bId=T(Z3N)=n|MY?c;9KpzVyXX<)Z; z)Q)MI6ocaUqIj11wM8T+q^p!>y8fka1P&{Ww-sx=H@*?dR-?-4V(tL@*| z9uA{(Zjg9V$+^Yo%+(~yHWthh!~DuDSuWHQih*jgqQ|!_N%R6Ylhw8<5?O(5_~n-Y z4N=5omysi@=xdyn!IkHo#;!f#k<#K0G_VW;Uirtfj&b(1(?x?rF|KqmZZHs`{ty_9 zG|s3zD<){J=BR^_7}@U=E2fZPehZqJ*n1V=R+roYSc#$IMROZjPnvqFl%nUBzo%l3 z0$>713+Qr*vClYcd%7>B*-5UdM*B{yBP(0{WmmR5&F-{$LV}8k1gs`=q90wyf`&}< zi?iV)`qx#mZEd`oRj$W#r%?l4wgV>cc3>FeFPsF>wj?RyHP}vf8?8b!oaxAv(Nk&u z2mJE4XS>@xT{+dUCOClRMF(321~tW&C@U<-$Arw$bO4z1BrMMOFgP`-4SZ9^HjA*y z-=3p9^G+ueM-6>@2FKRI`7vcVRYEMzy2VGDdFI=#4D7B6MDTUPy+v3njfVLD!YC`) zVy#;HRqJ1HfIHE+ZYf#nqF_1yDEXR^|x z@2bv6q$s`WS_cgCTXH&rmWEt_U}u*_mf&q=Q#$roU^*+Y>aL>TIfhOWvBqN<)R{HV zZo7|27h3p4*h$*f(FNTca{HfC|McJfiT=xPO{2!Z!PaQ^Mb;eBx|{(~3RV zwnxDZhZ@d>^~Rfzv3#c>#*>t1lwarVMp9pPT6~Kp;r6cSyOfE(vhTnrpK9+$gO*1P zh3;b5TFWp+NHA6^9Almx&N(B(N|@6U)PG#u?@U98=cl&2_k_G+rot)CijvfX%<>EK z0c*hV0!Te@>bMC7HAOR5KsuM6GR&`dKU**tvdp5{U=k!>E8~rivH_=@2#k611$4-x z;;vL-`OzODm7G#ZVQ>8o{v{aZ_d?uxGLEu2TFOI~Y3cV2yB1w+d(mm2VH?Gvb#Bq) zzR0G>lS_ud2@Zv}_9c6X6?kQfNY{gk0@0h>bW+P;r%Y6_1;(%ezx*;c3f{ma#|Wq~ z8`S*e$=AJ(tg5oTzvZ9O5`_U>b8x%Q4+ls#;S+;Xld}~DPJQc-NWT!PxUdu}Rqm3O0 zND|34$+NRO2!*G8ciIeV8dJd(!?vtGXe?l?z_2|x@BaqSSsKLuHNdzDRaDAmPGyCd z6V7zwNIk}=U)JwrwBUB(Kl}-hSuMY49c>{cJwCRTOdh1M+cIRBf3n`(V*eEG!Xv9H z)ES~jsIj#quW(85>3MBX63;Nd`bYQVy*51K^Qi4K54LuirumahnJVL1c;(j?m}zWb zu=zxHqBn-P(#f`X3TDYe7Vts@GV$b#j?FHo-&$swCJOT7TJYEL3Ktyn>x3l^$$ea~ zhCb(ZX5~cRS=5v&vnrBHoQtWz@yg#MJVs#6&u<&eK?4qHI{6ijsG5utegZzuDHZe0 z-*)?fjGkdT5NA#NNiz&*|2<3w#M7UCIfQSi99Xdt9)=VfA`%U1@Ka3LvY2)E_DIj? zXK)0P{{n;)X6#J2ciP?P0LJUM_K_h{Sz;W~12oxsYkU8&jeh0YvBJPYbRU-n!Sicd zI7O=BIX>i-Uswz{qoN!Z;(RM={e_a1Vo8_g1IsSIE?WA-}+1!Uj20Wz&j?)_j$9#&>F$J>D@RJ^WAuVE1 zQ&vS4?Org;FDu|;(ci2j53qO9Zn%R5G^RsQPHE|qa)=oMI)Xq8v%Sb)BCO0{rkFbA z;X??-DZjyB6ss0319|-5_Q0(;k~q;o^^4hJ)=_TxnI++inz0Sx^n$5ZisfCZm+;9y zn$9qXBTdRy7pCbFT@~#N)Z#EI8;;$b$i-Z9I?PXVWmMvlPc7pgMwvUrGpfc;Rvc+$ zbG;PspCY5No;A$!_m;xC8{0Nb>)TCHNac2p80PP} z3oL2+`6_$b?;aq2OM1ZDO1*yjCEVSn4^nKU(qK|X`PCK2vLX)aFQX<>ejU+iBP`gh zV{Q@`Ma(b1{3nN?^PR6|zuBfxHdDV zoX*vkfi8Jt?Z~SPcf~W(d)h#^6idIP9RgnYO%f+(AR&y2?g@il00`QcwK9(H*cMKi z^NzCynOXh@4ghh*SogW?{SD1cYeXp}jH1$!7BfXUM!4?~5Q;FmmQPYkm2_p0FkfjY zQ-+E3FSIzv4J$)rw9!an*VbHr9oi4J1h*f@X_hQG4Vjh-RWY1z3Z zCH5hn_3%t=@^9y8TT*u}S6hfFaoL#Io|64qEMhrDg?h<(UFl*>#J(}@kYd|Z`T#9U zI%7<++!V?p$#h1&|~zSwx0n8YeLjxUnOxdLIh5n_fVw?jmU zL^8^;Hz~@s+F#_#0WEjN;j#oe)#BqEPu%#&4)lU0$H_IR^(B~+TAa=5!4bBae|6KU zK~7OIj;vUi7-p2Jig>#{?4qWUOeXHu6eU_Rp#xr&4uq2_6JyklhZmnnvZ^!1O>$g| z3Oh{ybSlYBjXvy@KyQ(0J31r_8^to1_!a&~Gvgw0T z=1QjWC?O{tk1Tp}T~G+}Z8~h*@Od?yv(h$d&FrM7O{26vl`Qql=S7FedeQ>bOv_aV zgBeBGcPlQ z<1z;aQ3uxugw~Qsh9kE=8fmOqQXY>M@yp+yaR8XA`CduBe~)LED+G@?Wj&Q_t6I~p z$Mm0JWiv9IB`DgKHTA1;dL3Us=8|91&Df$kmk8qkZrT3P%XZ6->zc{(c%*<=esPf* zXFq|nn884++E%Dhnnk>DtcBD(E_fa{$Ra0s7lUJqxx&$lv93l5leE| zNUjUnUYfR2lX)gR+>AOG()s zpZtprzV`|TvE(Eis{~}Rc-2N40r--GJIjELgGdIu=Kd}1JSK9shNI7KY!Dwl!-U0W z;MSXh)sKU`t%kesH0-OIO1k`!LaIO^pL}XVvO4>VXs^oWCtqSa`>CKafW>Q^K~Ye@ zx(?^&n^FK-9>M9!`G-v7)~r2UDTIe9Ld+0H|J=mM9lJ)CU+Zx-C%D2y=Z3J+YgVGi z7eE>1?`Z=pyNzcz*`Rw7a|22K9f0A#Lp&Qo$|$jRU4poT>pYd6Z;e{!{z!I3!fg@` zC5EvU9}KVYzZ5d>7?jE)?64pTCg8&OM6r|FoS}C@8@jD1mj^)ZBL;!2Rmm{#Rt@*#MKQNMx!P1i2c%fb;24FF&YE z&$XB!X?Cs^|Ybp=_B5CwOop@{1!mg5m4u9J>Ey8=#eUsW|p#L~O31gkvh)hv8v(qoo#>fNx( zzvsCwd)mU@h&uy7hYnU-Zi8=t?2f#E!-Cw=g+UFsgq8GYbt_CN7_JpctgWx+CQ9H0 z0HYD{S|XZedaT(~@`J&3LnsZ^d~tV=ZnNy5C2$uDH5Gta6p$jdJ4 znyiRSayRf-hdhvg@d!7x(LxL+HS2tz(ejG>5cdLaACxcms96O$L?H^Ax)HF#ZOYEL z!DVf@HUxDm;IL_d6i-%|CWKQ~I7eTc?8%A*QU;e!Gvd^_8A}u5Dl4Rr3aaVm)S@6% z?e}~uv(t*g^eU63)~NTo_AWEcug;UBjetnK>uG|Ez8nY9DZ3hbng53rBFJj&s>hWpf32+7EQ=j>b*()woj;2a^$Nqk z3)gsPu8x&#A&M%gtZ1i{v{uo*&jkcReZy4{ZnDPqUc2EeT7#aTwm}(UN6fHTW_-NP z@TFMIG@_(+>3d3t`XX}G)rj-fXiv7Git;N9?N`E+I`d(3WGHnQK)y5@ZXXv^TNCnb zW2L6r@QUFk#kW{o1DWr z0R%_JNo8tWiL#DWGA)gA$O3qtOmjxBcK)jAs2hs%S*~O+hDJx z5u_SZQ29e-afyaQ2-)NpB!w++<)9X4X@?vsQEk5H2jdO>VxQe}$p2X`g>X!<{bq`N za;C&VNA?-LXf|x=8goQjqHN3+a|dy5YpXM(~y3)Sc!?YH-Auwaed z;RHyjJdWexa((>-mN@Rbx1TMvULqY5@`Pfrk~q;GVdbi;#@(fr3~wAXeDaI5K^QKq zu8GcseOGyvd(Hf#XsUHx1uOXF*Pd5i-JX@drBil+r!4H;)$u}DP##y7h<|=oO6F{N zEe{s-6gFzaH9=hqxhT+>S^nWNM4|62UDBZtXHNKq95=M{j84C#H1aB}e$A9v-x0#g z1!X*U9WkJ&MFG9)L4BHz5I12=34^HKh3hK6KK&Bj6OP0+4#vw0jVpq2V#(fcIdOw4 zv-}SGlW27A1d1Y!A%~=z%L*BD%g3>q~1eB&U%CRB$Gxz^@^REm`4G-64)ITL`(rwMyzP4#ly?W-Eq)=DRGj%C9~L z`%PjWX+ePUb@P>|NrTUzT3%FH!1Buw_cDcpVJD{2Zb$)j#@Udrplhrt?&({ZQy7v0)=-t z;3?EKHFks2R2 z&dS_M2A)3@A?`D9g1TJ05%Pn3r%^>h2B-XEMt*Sb2c)vu)ev47!w8R)gv(Zq_L%VD zsTJYj-}3ve2oI5dT#`t;)PS%?XGEJzFz0j!H`uxCKII;HaB4jQPWivOLZL^NTCZT4 z&cH&VT~9L3U?jUkb(Dp58p#fp;KkNc@w7~;DBR--S}fKquI(S=?gm%5$5|tr#^54{ zE!{!p&q=t8AbGwF5O+wEcYq}v_Bks;BT5U!Q^6=l-?nBg)Us_WyOB*CEX$d6Sn-}k51df=4*C%4}B)Oxrnd$5fT z<$Tw=>PJZR|AXz0trnfb+!f@gx(-*nwYHaEYtzFJkD-%p@FD*N{P-{Yzt*LJ_h48YQlb9~*N zJ1~H*%XsZgMMAR4Hcr;MoitAJR_@iu4^FFO;FRCsl0ANaUZprtcqS>rsRH%X`sXqF z=Yc~-|4e6Ien_;%W066L^}D|!;t7|`B9erY98{HR5}j4qOOK(m{@s-dI%~1{0@tt= zyB-Toc*+p}oHgO?;rri_GLa9I!Fk^9cMs{pj>={`wQ2D&rbTDVJbnzN-$4>zy2b<2 zLz@1V<&3;Il|?u;Nq!7TmY#zobGn>HZ@-D~2wuALzP;P_f*@nkuCuUyKZ%i7*>m6| z^YicTL5gR(xZxcN9r~LGI4@yY9ii_qOS%)TBum%T5^q4(hTZLMr(uUyjXzRJD;5s{ zv;3`Id;5j6mx@Kwpw(f0Xg!USEs_de`MKh6RPL6Rut7V99ZV+!*!tUcC!;2&RLLtU z7%|j^%G*lP7z{e@q|#R8j;L||C~?KA$gsm5E$-aYllkTFQuLxTadKgZ4V^fd+hm;? zFw4&e4@P_jqb+ngCvXkdfN6-aOb5(>Sa1enAwt8>pz+;zjqmIrnoNWWUfPoZj$YPj zrkpgKxMH+t%=dv(idp|Rs#UC}`8A?ku?RANX{+hjdJnlF6#zjBZ-8D_fouHM?qRku zcr~6vC99BAVU)ime}pn}@B8X-suUUV@w18@GRx1-XqZ-n*W)0k`_=}W6wfnro0v~W zbfFU)quw3KhmW%Fdr4)4|K$D~Q9D)eT;0KSaA(Q4gEaMBS{3|xK9>J1X!JZq1A;bEOGwWu{ zR^YET^*S%J`;II3Ro9Q0>bwxAvk&QEJQFNA5GZYAoD;dQnT-jKs zCr9@nN0}=WEyHQ^a32dh7DMWEZ-wXp-VPIZU7Bd#=5PzCcHc= zJ-l~niiB8cCqa>jn?}MrDYg*%Yv`;)oCzTzM>lP(KW#j&?4;8hVE1&z{qSDlJJLe& zg5Qm@q;lOqy^#i1`DZLV_c79p@F4aZVKiaRcE1#*iIR=d3KKtVDOxc_h792#`DOjt z^3vk;!oumeTwxp^CBwqPv zv+K0LVMm8cfxF)9k>bUr47k3bh>!?}GlDGQf=sICgcUB;a6Hk>g@N?Fh7`a;f^e{7 z+f+ZzK$2sGYBJrgWNU&J3ehXRrTnr6JWceD2WN(AycZo!=HScH?tWTFm%)@*j>!vQ zqum~vc-iU*_r7BiSws-Q4_V`9>>IqaD(QQ&-XGqdL{F9rA*`Gq5=>$Cwf36Z*gSOh zA0>vw#)=rog``O#Cee$>6v7)G_n{YQ8B-i1THohTGG~y&&)!GQ<*GJ$Fo`;>E)G~Z zBlO_|s6!Z`+ps`+elR^$S&B(!^kYha8J*Wv4MuB)Fb40G(TOdn^6I_Jx>C^nWRbm2@0oNMf6y1RY4Y5=Pll>;|Ge!FylTP-^%h)m> z6?V_2KhuJ^W;w%cOq!b0(8>i4r*cI-UxZ^T-~76Ni&OpjHni_H;a6{WHn}GbEAs}X z*>{mow!v)S0_8jznvPHnEqIy{d57z-C@wC2UrR&Aac+^bdfYkaZp*Q=h+%#Sm)1dr zLM1r_RQb(U``BeQOw`gy#=ZaAfEH+VH? z>Iyuh3`1B*XA=n)J4b_dfv6nwcb|Lq6teNE)jC8?UmymT2JP8b`$x#U*Rh6jO@5!< z=3nl@`-y`X8Z0XG`H#={j}WSYbQXXA>;FqE5z7oj9N~kGMXn8wT|)dB)P~DeL#JeT z`xt9(o~1ZygAHg_zQl97y5=k$2+?Qf)(K zE=_&G9fHkQl2A=AC^)*(RJP{08})i6Ch^GM784X93eR23XHTd9L|D|1TsGu7ut(2p zTDGQ&%qG9Kj(`pN6S9P@+76v&0oas+9gg-|_Ao-tj#Ler+!hc-1+fiU5_CzxlvanJ!he>SMAhJ3cOD=VE)i-yL*!hZMvF z{TRs58x(P2>RJ=!SZJ$C?MR$lmvR^f?Y+DEWzePP=~V-}#OYUbsNVP2RjC&6jPifm z;E~B}Df1#4nPVltVJ$SkY}DIVM?1v^mCJRJkNfoL5}HV3)bzQQ41Q1EyO4Wo4J(`} zK!_ybkLJxrod_HMgwqH3pmeuV&2H!zV9yT8(otJ2fPc+H3()W&aZ;pY6{)xs>m|Kl z*yLXj7P+mEMF9C)@tM1fk{X?eLXo@l>rVf;^P@Gwr)2;&{&b~?IOXSkt~O`v(eEVe z$d#_Af)ag($Du{s@=GhsK0HiygHT=C_+xNuwt|ntE%D2*xY%k)Sa7cCpMO2D+8OOM z>QMTT zEj?i$wr7p;Tm@F*m0u_D7y(jy708?fXyShC9l>yEitv`Xj_Jpm zWG7*L2hCq$h7%W&+7eTSU*%82-h7+jd)tleP8+Vn%JYXc%Z8u`U~C^1IdDL!o?5tR`HY;X|0cqA&Xhl0l&Wh&0trdNa-=VkqW?HI|tpbdw zNN!<=x{4OO@~gj41;~EYPiWq~{96lmg8fC$(prsJ6D3lY3?pWle~mlR*`GuMitmek z=FZ+C__3M&86{Z!Q<%W-Ll=%jp(NuHE7sg=q5bcex%Q}MT$fbwvXDyh4BJo%b7e&- zJS&?!?5ZF+WmU>^Q4ee zD-D$i8rksTMxF=v0C7aou{%F>dz>@z|Nh&TxW!`b>GJB_=JeVxOEa6#=hvSZ!B1#( zge<$}c3c}}hUyENdNTLp{L<#r`6X=p{$g+v26!1KWTqJBpMd-7FPqb|vj!l+$SeUA zoJ!o6PK`S_DfjDA_NNQW%d4BS^FPhc&Y4Qo%uOne$5g_wRJGjq5pEnmb7S`uiqRvl9jC)MAVy=p+HCtSs-B?&YrJ4yd#kj0BtEy7M zdhWO?DLchECpgQirXDqh*ce#=BjtTjc&{u!pR?=}w9hdWaJ&>jdt&u8WlWgG7;76( z)@E!qCYNJjrWo4Wc)h+lJ!419 z&5fm%>6t&8x=b=tdJtu(Smzv8++LH6dBz|{%KM7vt*9roD@*dF5Xw)H-iwjgzSx|> z>~ET`Ci}y&sw~0`I4ioe;o6)PhKbvd7%6XQL%h;DpGq4B{1oYeYs0mL`59{qBrLzG zJIb+A{uhNmX6L0JO|MKc18}dbIbMn&HCW$RSvaK{I9AI4nyUf7tm=(PG$z->a8$Gp z%4mV?g;KCI-V0aVK_PCyTT5_}#!saYJwcBdUWzc~-fk?-tj{km8KIb9KDEpgmKRs1u~=KS)93{A zTfj-VUznX+m|Mq6a2+S@LqVRP^dT$de^Fk}&aKWpH2@RHt>L8zT7#$4kpVDy4Vabk zpAys`7nYw)+bL{)?8eIGdL*PZTgJyt z^2$cbenDPru0OYHx=H%i6_Hsf|Eam9S#gBGCt^f&g8sG46ypNDuJV9PP=}C}^1nFu z^E%$op(3lVJ)aw19szBGb@%2^(+e9`L?;->hL<9o#oNvK^=L&}vn76<0C_&j`P`4N z*rrRYC$I?%Mwa&y+RRAKq`aAt@}6S2=P3E~lgNsiKr$^e#W+i^OHDIDt9w4m`8vJ% zWquB8!KbUsi)D}r)`3+l6>sX<^iP<_R)5@BoLjQJF+potW{PoPesN`ab)73@`g?+L z9I}e}pT;~O{LMU|gN9sYqY_Qt$` z8qaBH7Ck+=eP78_YjjC}t#HTI9CSKP_eIGr^ep;XFTFubW8G=nP%T%#cybJnc>^yx94HSA$r~Y$eab9sXe zfeG|wiJu}}=3f}2>;RZx|0HIoI2YxI<+Y7fJ7^}5Xv0ep&bzm?sbN}c0?i+AvfRr} zG%0t-Nx3^&D)~nyl_ldHxxlrl@QqBM4?|X3cE|s8ylc!~SSf$kHYIy|(zY?y_SE9^ zALlloo{~q^GSl*(!6r}1+MdAcqHL7!KQBcJyXKav68=OprGc72 z^OyK3(i!^Y6ug1TM){s!!IsrJdV9q#U?jn$>o@uV4Eig0#y87_+D4ckH!_;frU<$R9btUp_wvw}0hC@vT&?=$==^6^ff z$&`)qy^8%+xP7OWmX_D2X=}^&>jdMg%uune$WPT_brX!Q5Xk%Me zzdSqlWW#Qy*0`)jbb#)zxdquVZdCBp3SM!)Jz1Tb{^QCrtXk8EHC;6hE#RnF7ai8j z^xE9AU4hl8oN+k9O);(u#`4_i%-jr?dehOSWz8YFu~3GoB3^Ka<*uqRfyN;@W{NPS z2tQ%Z!RqQ7H8CE;u~U>=g0j4{{(Kdiu}^+kpPPyCYR-R+#VavZI# z>1#+rz)`V2bS<_3Q)}jz=krUm%g@)Iu2lm6>G*x!aWy=Sy_Vvgic+kt&(7OurkZf* z6BWR5R&3GxF6XA1UtUA+3pd5M>gwm-!sb}FYNW=*8CS88rJ{-aEG=)W&8@-!wMzLl z$STeGgSJvkj=l^VxUSni?eu^U_du2L0hxZyIn|UdJnO{~`m!Hlr%(=i2RLNH8 zHRhKxV?`F5VC9#Y>6vG9G{?-_nBUj12`p1Z6fMTK?}m+-eT^Ag*(r+1Jh{RU>QXWl zUqj|YmN6QRAk9?_<<~(ASSp%~u#KfB8&97iY}d|cuQ9>`j*2BCjK=a4*rrB9y~YUh z{1it<7}9>)WUH?+!kCxx7pa5O;K_1Sjn|MmWv3|8TG+N}#}^=O;KLTvvqi z!klr8S4M9&H%nO>YNCZ|vNY@=tvc?DMP@i;Gix+)<{QZ$w0dviPO7~_BLg*!r@Kz> zG68oOIbzT3l>1pEVklRmM(d?l<8a4TgrO)Ij;YIOK`~>k)w_~}y|sfRhm_)tQV(+u z4uk!F9dF(g)hs9Qh}zSo*~Gob1yqBQ=J_5x+wAXc9wKwT0k2UR37y!-<-x>JYdi&v z5!bSVo1_fTN=hw*v>=s2BitLzT|qCP#<*Xm+^{t{B2Lh-%-lBR<)V$tsB0+|9owB= zUM%t@&TzSjlvico^%UT$lwpx1(TxUlA+$xF5@g)xhdhI(Ym;i63@iZJyJ%~aXOnV< zm8-mQnpNi9XlBT~fjc+t73wu6Q6W;}q?nj$^)5B_a*guXOvox!qhOV<9ibOJ9?ENa zF=@1nt(x2vLd>;_?>0w!q!a#sQG*I~tQve1rRnxe&6B3fu_Kn*YMsvkWe8>1vPy6< zMP3t-gtelb=NlT!6KE3LxGts3AEPN0S0n7S_u95@NeaF?zp7P0p1ZFe-cTN(y(kCJ zYD#M+A}ap^ld_$cHBQYL(n0}@>p{+>Zq@50zBw7!U^RQV*2^Xm{pr-|Nw+f>7+Tkh zj4d}lnURq+r6jd5AuEF7USM1#cfv)@1~zFzNrn{wMSX+P;u^TqQ0mN7AG^K8yyMmr4&}P3qz>Vi&4E|}%5dmw3 z<2w4x-3BpfbQ4QYF6pf7G@)NuJ<7QL8YP2!T5Vf!*UH}XId73VyyzW+{!5AyFKCac zvZU5+c6dg1Nftx7!mT!kBbVpVpx3z23qc+?ZBasbVsBd`tpwwzHBn?>K=4XDh4M=+ai)w-DU4X4*DsJvnBO5(FiQ zgxMjNx%mNlk>Qaiqt|I38Q>%-N&!~p+PZI+4fQ0ApJH7(){1nFA0a<>S&*c8lF^ub zfQUQMhV7TurB$gHA#vR6cDqwRh??N8=N<>sBPJGNR4Aa zt9iTwM%W^QEwR;pJ%<}7JKX^;0XO46N!^VZ{{?3SJ5P6{qF%j`9g|6FZrDY}Xxx~` z>Jk?_9qRon)(j&E)R7<*_ACm@1g45f^Hz!?@Z1$|O5f~uy3Gk{dJ<3vp~&ZpE-`hj zQ3{2*RnS&W(8bTbVJ{c&HcJln8g(!MrggDj4S)~3WbK;jCbA1AXbOCR0m&+#QX*aTedUa%g z1_KmzLX$?@XJ-kkNT+;ex ztTJKdRz=^~Ytcn0Sd|~As-K^Nfj0ZE9Qmv4qwGcF0Ox!@@enDG2nb? z-ljVXRNT=Ot(s4*WdZ59Yc0>WcVNo5F=yIYB*}bCnMDHrig~6@2F-yr%}+_;waJK4|V$%#x>9zkvOPO*2(9H1+UBa8-U5&$MX7LtGo$9ySl7i#tzg?cWaAE9RLh9h1~)Nh3k_ ztQGAlp|LUWvdT97A1M=6;;KAAiWcYRUbK!jakciy2DY4r0|J~Ij($05>aK0;f^m05|ptoa=0Fc3SWi+DR;FPQlpdv zaB9|2z+c<>Qt__T(5Dv46k$|gmzw$?fNk3PLZ|zx)!*ErumvO2r=o+2cf;}4%D#0_ z4*9FuvM4+=WAy!jRrPP-9_CSWd3%y38n>PozFM6(N^Xi8TehgoICXAfm;U*%X`>Ws zj%Fm8vBXa+Fm>2H#3jg8u7D)9Hm<#tyicGY^PX39_NK*u^>^h_xvwznd8K#i$WTrgL>Oa4`P-IkJd~E@BFX~a-9E+Mp8m2{ zm{a_1aXbZrHyD)tS~W_y(DLJ^Gh%J0vh%$zR8n~t|J1D2fWJ2C4fJ@Myi}OBi*4f|7c7e7%XeZS4z#R<*Ause8xB6L^qc&yagaBIO%fZW1b0^Ja zCqy>Rt`NP{;Qt78)8cQ?IeVj|UMm8JxoNvz2-JyzI2B#wm|IsQEsPUEGSx`$%W=BafiwWp@E}@* zYg&YYi77ymAGn~c+zk^5R`=1-po{8nw4cs#j-Sa4l!WRa zfsnO!9bT#Vl5}n&o{ic2^|%1jQ=49ZP>wJ?N4RAFS*s{%OEP6nBT&a)d-CkBRXZ?A z6U>;&422nbK4fRaXep3 zB?vdCg-f=)^Xs5q)8u;#5AWtVyA5F^})JMU(htyozvsSZ5 zkkccU)~Matq1U|k&E0n1VQqE0_Tbd*abQFtXqTVh?^g3r8<6U7QTUE_ccZ

!h?9>U;(b|oBdHPm3ei!1&<%ToAMW0TtPk$=j)wc)!#myn-rf6m zBQim__5^&gX<`&s;6m}W-EI6T1whBj6fqx!e5V{=B$^t;Q9a*`<19o{@Ut_HN7#?s zt>^&U*nT7mVR&%{e}`oi;n?m*i{9}}LE)L=?~ti9EHSl*%*Hk>lL*_-W{5uPxAqXe z**{|O9>7e4Z$0yY?<6eR-pB}n+0@JzNjC+;+gxo~Ut&WvdQMM>xmD(Gt zYzsO;%hq^>pA|oFzqwO~2!~Ji{-$kr zj2)Txf*Q1b-EOfv#0uEh8WeO2GpC%gXPE5BY#Nv=>dLlWYe(6R$H)EkjSHz zEjABFO|~{fR_O?qsl!-(L==K@dmewcVKx88HtRRp(>4NL{1cgh>-)%fxx+ORHBa<( zB67EF?ZB~WJ|GnQPhBlDTMUQ+F(2Xlu1JD!QykGSl}%_= zA#0IPM4q2;f+h-KdwCs;=p{T0>Ss?+CJ5J; zJ3DZ0(DKy`0%>&D)kb#4*1*wd4VGD03~w1=_zv^m2?v-E3HJ|$J7!LoUW-+HCKdtp zgiJDs7v08*88*Jd0X=q-2?z!AS}}XhD9d8N;d?bXLY%P!uAmc`^MFxKU@tQOk~WWM z;x;`pb_P%?VSRN?xR_oM^9ZqHhWS|Y2n53S!dlDdf0<@oSYy~4W2adr5w25f6hab? zT9HjC46Ni#VaLj*qY=)Zt}%yfy4M4Q6P+ipSg=;0S*O2?m_(8xS?^#0j^mt2JaWR- zLP00E?_h;}0PmX!FIJ1n7hu{AM;2v#Hyo)m=DlU?5TQ1(hu4k7&4~u#`X%6Xs@gjeb_6aOG{g9V`qD!5Uv;3@ps5nR0Vy4k#CASb}km8F|0?2 z?ULhXENdYW*6(dN9$Ii-?X%;C8(fwJ_#p6R>lpGes@HZ*jEW-m{x# zW7UFE3FmidB7=+eD0>E0*#f2IE1WXY6R(i39=hseJt0JbbMrZP1ZxmC47jO~^cw>Y zIRFj+FKXIIz8BWA%*keD1Hg@G&y{nE9Z5@-j^=nEQ6$n}cx-QGes;r`e1 zD($=D%U-4wg!g9yo|&v^f+b-_lq45}yPMFyBe-C?odKO3M~-&*YV7);<|fo}e55?* z|8UsNhV5ae_1{??7G&58iG`tNri{ghdf62kT3OY-I8#9DOCPt8_D1*zbCFoUHh ztHme8G@JFU+&yIJyHU_$=k)-~)wpu^>wDAnNkJ>XaMLljLguNG28|Y|B{xwbn$il| zXU~z|gp@yR?qEh9_3Q!|i*hJ_6UN-!lTiceYw!uYi=K9;yAud z@Hay~MG^?3(jKOjqM(+-d@y}Twu#Rykqx`H?g4nOx%~nw!g3QNfrr!r{yUl=L>;X- z<|qvE&Sqb(9IecA<&jZXbrY*5=OQ+Be~?o5fLPGqDa-X5`=6u1H0X}{+bt@FK}{M= z1+9R7gL=+fCP)|S@`+7_}!?wq9F6{K44Ipw92);`RpaaJ2y zn?ggKTRvc;n!r@NMyphiYM0L`FD(HF0L*0Y$<2KIH31`6tSGUH86RwpQ!o*k0NyD8 z$wOK+0CzU~ZQXhV0i9TtL_L1kdPRnAvg$6%pp;UK+q1YK2R9(?75$u%IX?Iyn;s0{ zm~O#)+wHZtx%b~M^Vx*r?_zt+uIPVAX$~!lXCY%@p1^CNa@z1b$doDnLKfl}j%U$eh#b-ilRz3xV0N%tN80dMdJ%jFoPcVBr{U_?| zDf-wK)ChRZLd6gX$gMfwPKA^S$^{~D87OTB)+`GH5<$4;c1SupbcFdC{&Lhdh5wi1 zB||lL3w$C~Gx;)F(te8E40DLTy+S5KeMuwdui2Mu4`=3V0 z->(Xf`=L#KO6)3GXXluH@I-?5-QWNEzn||PW$l5s6T3f&Es55_5iGU?%MBNcS(Op zCAMXA(SVGtgi;C2=PR;9SxAm7OvyTtPPtF0TCow@&8p+^6=NDf{Ah-s$W`e@i6>+S zMo?E=dlYd6riwKS(wI)$GKfb&Gp={DA4hZ`rhw92?r5$X3sukw)Camh-h|2wYWQsV z`T8;eUT|eBtGAlr5|9YYl=KX<<@x(<{fNAiv}wey64P)sc6ueTVBIBM=6I4ZF(c62 zXS3@Fnr!hT=UkKPF81)UFzhvVu;w0Ec>&+!)J{YuCHMl1q;|AOB3r7h?6U*6mxT76 zax6OCy}el7)hKmCq;0(5cx1lsZko>!GTnWFaKaa+k!#js)zpG^MbT!ID=H(+*gL8k z>SLSHlL^GfI@YBJ?_pL#j9WC$ML-du7KNRS6;LJ-tanyhd!tUX58D$~F0LhpV)yMR zeKhE9zi17uY>e$AAySw%=21P=JPgNRm|jYNVIqOKv?f{-Rmj{p7Un1PHaiip-sUOw zHplHV>SK?2>)y!wscloZe2Wp0Y*c59b?JS=~|RD)s$E{ z6{c8C^BE#3#aCht5thiFPBK;gmMg*opI2bl=;WAA;NLwKo~nsVmTW)Wy*KRMH*H-r zuZ1*%!t_}qo5nf@ml447^TP}y>^_1AX{_~|hXcyW;Ubu>DWAH=VFH=f6 zzAkuWfB);>vZtK>K7*C(&bVf{u8ksX)C#^*a5`wV4>xTIYFay{6a3qon~o2oV}XgZ zsI>9m97kE}@MXK-NpU_^0P2$k*mAB_9BUdFaGJAypybUhYd+Sf z-+)BWJ_I#a*`G*w(!@E6nGTXCxm`mq_RaRL1xgTmq7kI8>2HQwMI0Dg0onk^$vJ2>>T|eI9$tON*?XB+D)ubU(ND(NIypN_9E3_%y8PG}zu1(Xs%<;=y z93|j=KxTR7KEhX{7*+HqW~@`4(-s4d5Q8l05cGL=BxkhoE< zO1Pfz<6{e-54PKO3oK!LD4hT`^qDJ$lP!om8D?9p;j32bFry!3YiD|GW}a7wVKs3d z*#y-Dm7sqG06Z}^cbN0#(k<`sR=6J@6pOb2dVq6SCx<2~f&Od@*-*E|kmpm(?ge=Y zo1HyuJP-E|s9TE`rzkJ@cnoYxiwm6qe@HPE#K(y;J&;oX;ixE1B(1+$?^}wr{&r7r zKHvK79z#gr5zN^m+uRFNz7njaXL zHzc+Y%!Fe)bbiLIlV^UM7Y7tqwm{w=9op$M1(}Eh`FGp&z{u?XAg2evLi?)HFVNr@ zv?0AIXhbAv54P!n(H8MX3r~o1?-V_$P65RJ{YvX^T>2XI?t$ItPU+nPJ=F7P`(TH` zLy0EW15)YJ+8=cmM+0rwwE8Z-g$v-_O{7@N08Vf>5skFK$E=uW@y{aV5HgyYGQ`TN zbIa=~`Wo>qp@p3=6F4eC{K`FXy=RD>J-lBF9j!tWp}ReS{)nKvJ%K*x!H1?!W%`9w zhhK3c$Ap|NvDHmjaR;OV{Aut?(BWV~NB3E%U3?PIZ>i-Ke19i)Ts|6aPDSKWipSAw zE{XT~knN!kO%{91ovw^5aDLVRlWu|6xz z-6wUAzC)Oak;DY=enBb4_@;Qn1))400z|EO%f1KD#gI^ zL0%29!`IqIsBW~Qff#)UXRU;!IxD4s-K71gf?w8ip{gYQekoY|e8+i5>?lZB3YIwt z{N3^|-1G}g9EIN}rxapID1@j3!&_ES-p&UtBEdP>#76Na*!dx?lm*JD;HQ#UoP}mf zjfw;RFg1^NeuE4fK=E25!TIe8r2y9`j*ji68P5_xfv7|A|2l*So?O(GQlK6HTX=Cz zH}t#>k9KkdQvNX6)RJ#`+=U`f3`z+{(nMZKr8t;*xH!a3Tb@2CQjk!K2lHIdI+2p* zxt_Y#Z*SvJ3d5|?QR6NalJM#5v|2rk1pGpm7w|SB*Vr#-={Ib{o3=;!$1P`tOlk^! z!dw_0`}l}ngyKh_=nKq0V!st82i3Z;aQa6*JK$3+93m3zueRxdku{Qr0u;9QTd?S` zQT{8WdoZAjG`Zr%L{DVavz{{BGL=BzoZ%+~C2?$GxajlC*X@DzXQ!A?gO>vE8K|A) zto_7?Hn0)T(dFE?5)DtyS=6c=37k?ZrV`L^xA}>2r)lK0C@NJ=|4b%u9#U?<+7_T3 z?Uho1Fy8AirUC3Zask#`{R6CMJI)tFs*^XdaD^mNui>IPO6o+1q2Rg2gpHOc^r&N5 zUU8@B(STN3<*qB#9p=YHv)Y9h+mJdbSY=sy&BK6A@)WdEp7&-(^iD0!z|Q7o@Y>YBZ8M#T&*-RwB*q_?L$2|c<^-xu}*)ms>h6pO(I422R_jfepMa@K+$*%+aqCB9+69N{v&$r#$rum zRT1J8MCpp%aThMEwp9uV%7=-xb@+h`fhb}3KpnI=zc^Qz8Nrg#Z-qK8G{@s?qG_9i ztx!WOMfu9S`~lV-IeFn1Ba!vCL0}xrLHmWYR;F6a50Dxd!ZRHX)6ou!8etXn*CX5E$WO1oP)kuRbMdGQa<)8FHLmFH zxLKUgEJ4*okpaR%isaUU2hUYM}4r5#Z{C#A-NA6trX)6S339Z2j_S`k=}k@Tjx`><@XC79v?sjWA2!$g4;D)1>_rB1P$ z^wOtI^7bMY*T@0YYumMRg1zVo1-jv1ID4_%9b(i=LPDBFfuV+@^Ur#3VGDb8X0}N1 z77~phe@uTfXt*;+FGDY(U-4l!IkdjA6r+oX1n&#x-~i!P#*Xz)=3cq&5A1>*Y{@F9 z7;!pxS*4RQ;yk6`U-w>UKOtIK-ffOLLk%nnC%*()4rvANtMDCHdv&ur31qjaJ1s2aQp28E74#% zZnZ6B9^7$Z_@}h_NQU(+G6Ze&arPOqHT&&>=8sUDkhoCbW^-tJI$=Bqq*4f%F8Qgj zL*x2!OW(E+vGg?!oG@-Zp+Nk>zu=m>sSDxs*x`eJ^bl?oR@w&;sW#c4`ktL~ClwbZ6rdk@+k`lAyV5BLY+7J1io9Z4C{~ii_8jGZ zApK0KEyEbI^QtZPY!q=#j*)^w%Ja#dJ9!nQN5{D!_7G{hOD|WrQV(Z@PAXT9N+9pK zC$9et_Fs=sD`$7AFOtp~vD(!0NYv?GYk{0L@Jt!Ndfdb$WKxJv<&jH4hnl%@bz{)! z=NOf?Y9~M?GC_R=RNnBV=%YoN49LliZ0oMIixnYj5x9AZLulU4Lv9K?t`qD$qLCup zp})D-tgE&8hx*FJ{pMglR+Hc}PLza95F7I7KoQ6SKQq0;q)&1z z3nlDH?!ocOYQ-COSbO*WVk(9XKQQ8Ft(H z>l8Jy*zCW66fHDq2;pi6i7TKU_U-~AyF*3dRJS31g1f*FOF`h^2sm1_|KL{FlJl zE*YM9q|x9I;J4{-Cwl8J4}#5$prZI%%!RP+lPc;-1&?oi6K(};g;nA`xLjCDvC(e* zR}>MQ;K8)iQV3rB!O<=}xg3;kqbDtg5|bIrZ}X@B?FZssLu0HP6~8@wkS zO_65iXydf38BZwypb>yK=4Th?%=CcW=8_eSkH<|9LMCiKmPc-!`Nip#2UV7|H?Z0V zd;2?fO_X4`J1RlE?VcELmeKl)^q()%D??p6m{G z_L~&iU}~Qb?pfv_MS92OL@EDH1@M!9`8;*P7bnN^cZc?mgJUl~0)|%)NEBl*6Cz-gPC!3$gB}TIu-KOE`Zfl_V>KI}(#MIiV<(;lT*W?Rc3(m_@art|nS&(|!^YO11yPzu@Ng%lZu0 z6uR9N`hfSB*o1BQ>=ShIA6-Mm@^jaJ!9!^}B4KJF8Y#@j^f#B|Ki8I*U=;G6GD|YT zk!XLJ(EJMbMeB&dQw<aZf04xBUyQ>?-69J7i6Ecv9#uFS+R(uB@MG=^ow4 zVn~>39hD$|>7E$YsVedR=}~Mlgfx$g@87D-a$q>Fe}zn-zmP}9*3574*Uq9f$rw0nX@Y^jST;J`f?p~TY^$Gr+}S@RhTl$AeG9WD1#AhNkl=!d@2syf|$awxnu?m$!W@ zT)3Jt-hEzUX9kheuDI@yir^;^>_gbSmIO&78maN`=x=FY81s0t2R8}J>(&EAB}^3J z>+E|yz>NS%;U8$|qWD<(ow)d*k>Y=fR9P|>_#(ar9(#!L;SmwIsk~RfIZu#OZ-Q{6 zkXG>TgzvcDaO);qk?smn1m&SDTS)gT2b%3baUYr5gY8(YKT;b<#yk$Pm;<& zR7Dx+iOYaIo|0^)kxfBdOeeuvc5A%@ZQ2B62BJ zBYMrn6W!P#cRM28<+NdY!08b_7wi9SM0p1qv)|g;bT>bm(#2yApqqB6jL^}a2STy1iBzz0BFd8ak>zA(0T&(l=}lniQu#D@W? zl;KhEip!z?*>1MHw#LW)VMkJ6fn=F#`Q>UM2AIZhlYq_Xk|G8|Cq?;UnVz#B-Qig5 zc}G`wxU)IYEG^qs;fPO|r5%;ve&(LS+KYRFe?UTIN%`r=I(1TPpMcr8xkAVU_8WO* z+-1%TROC2ebHqj7(Pu0GUZ?j?p5O{30{cGxWXScxIjp&^XmEQmqr+baDTgo0j_-tB zpnz0Rukd`h60ii6H?`ckZ=*$0I+0I{3&6j~*>Q4VO79)F-YROy49ecblo}SKQh={r z0hpU>U+>G6qG7z!aX>mNg35b)01>;8=}>?Z>;Wb!styi}Y36A}7~rTged%3Wg#^FY zqex`~3wC2A*pUhF=RNnx&@wuMqr@&0`pC=}nlIA;C#VXg6XgHUXNJxSoi(BbQs;;i zxPHR63hYBz*Sq`!n|a|h)}ssQK3P;!jK1++RvvWWPI<+beR><)if zvF7M?@ym(VJ&sCB@jLhA`eb?KewD#g$X<8Qw*I9Q*&`xB`=&<^3`Y9opo^n}G;3of zTUlP4|5>L|A3j`+`CcD$tC540G0#*2{!x#g7@hSCrD}q2lix-zbC`{!Qw<*2j1_oC zCV)2row?$Eaf7)~%|m;xAz@3TH`Ih2ALCEgZ-dror`v$#;ZhlxLj?uaE4u@bg7r%C zY<<{!a39 zc4zCvo8CR966i17lWSiWP|t_jvaLSueuLc+xLu0zafH)frq(IrgNOw6agQFHgqr(> zUHlJX+}SVDJtP&4LtdSpj2P0Ig| z3Pd`J^rmx7<4zR-nn{`)%``^JfMqHv!Y!GZSDmZFxYm4|m(vC(v^f(A%4aUfjVys_ zw5F!MgC-8*-N6ki~HU4yj~N0aJA?*sofvkCsu?s2D*knJ9a006zPp{xLZWsxfpnffn z3_9I`jz-84^6-N9m$#$H5^Cb0)=s^d?oFz-qZ9lu(75hWSrYJ7eHhVsZq(cD;7DMu zw{-g*(%>Dw3N*Ad6D-|;R7&t5c*U(iS{%G7OhEkv?0x$&=n`rQKg8kcj51dx3~?rs zBHZN%24BD?EpJ^@5JAi3iGvmsO(Py{gFe8HvYj~-(3wck-{l8JpX0>+{5*=UVnFIy z*dx}o2ZwRuCS-#3@AAlKen8_TMG@Np&20|1L6g&@D0-;E2QA9qXaq1pg*z%K&*$!m zi}SpRs9Cf%#jD_A2tL8@QLW-3Ac%<*7YySfaPx>m^cQ4-VADMCg>0{Jl_&n0WJ1ng4PU`JzKX?BjV zG>IYu^rWCNm7w0GD{N6K(q?OLoa-JuOBE+} zr_A-VIgRBrWfw%(`fa!YVsuO+C+s2;jbPuVza29EXi)fC8+Xh=kSS6@!V*u0V)LaNi!#g9BcKPn)(FqxA}XF~M9VWP+2)V}VrRJuf=*aA$(Z(g9Nm;1}+R z@q)-wi7Lgs1s%=HFf%^+em&ETDMG|lz9ZcoeI!K1-5=N;(Fil|#-)z*yQ*^0pKJYa zUQCF!4r!$n--hqF4Ui2_kKeI8ONsd4j`)EJS;mUYG(w6jgGRtVAA~D9Y=z-U>*|G_ zw}%FQK`2n`z5xZdu@jUd6WoWw#r64<23@#v@6NY{3C0y)`_lpqHCbtNJf*ooBe0)Q1U=)j&y73} zG!@cYn1Qg-u(`>#^vh`a3H~Cw3q2IIgk^L=Dd680Z@36%rzrSMtuZc$H$(@+opR(y zf+4DOQix0bNaVWaw<}Z$(q>^64(pjRq?t2XKo)J_Z5alM6jYcDu+~mw&?i+`DFyu+V#bA67VNeboy++qO#M=1nyCchJD0P9 zYdE91ja{@2$9aos8Erci1NZ2_UAq#FtCWE&bW)0kD1|%DN@J_=oe$v&q-7!;eSLPC zOKJJrNMlF2&QmnDPd@N1wpN`;@dj66cF~wZR2n*geJ4hH6|0G(fiurcPo%6Slu(*s z7R7L!xG?bNQWS~CiXhIx^#-?uH3*|sb|4`GgqNCfB}oWTNuj<#q42~da_4W|v$#%t z_z;;fUM|ov>L)3#Ak6yZX%NWWI6U0zMCPumyXVjBtuT(~G}R25(CYoBc`r z>p~_a_(mSN0Fes7Psp=L_iG|Yi3V$VsTj68(9f~KoFEmRP>S%rf5C-VXTCwKNzv%7 zgI=k|DUB|4g7*-~#hDMo`2{|`?e^(j9qrn*M8VVf7cLu%t>yQjdQ^Ta*b#zk8f1#5F#7Be)hmzSmCBugNRp?xe z4=Y5OuP2Vprxa0ELJzJl96CQ$2l#obm?IFw=_RFc5w$3gpK;P*npW2FQgtcS6e6Uz zSx|3!ok;|3D@X}C(@_cNWB0_BTx>Nd)0R2{VKmZ@q{0Ts4BSC6pyCHO*VK~?ncf3F zw0HC*c)*8xLC?p>g{%zR@vU`s9~9#i2fHxZjA)@MW5=r_^PTG+xz=Jg_(d*7>8)>f z?mA$fFK{RvkQ%Owpw}G|PE(46e1TOwq)3gb-?)5h0+{jGd*0qbnhTNw@1Iu6VYC~a z;GYgir5s-duNZ#LXE%Sv(0tAzbB$9jLL>+$DMBF;z6e8iant$>I`N8ta!3T#p3Nz5 zIS;!pTK4!@g5}IaQsr;?fh#+6a=Vg=k!8}zLW;7ZVuQ}NyF7C_*5$z@bCw+tbbV2G zgjHJPl)4j1y z&Sz-j(yU-rIi%8H1&6zoM6IAxN<6K_ZZ!kg34BU*i_UZt%N83|6TAQGXc46r`wrrV_~ahWzAE-Jf!|Ml`_K zLlJgwijWbJ0R4eICX6$Cg!oK2iRq0T7R59}bDTT#LT1aB-eBV#EoQN6%xrjve%9GCOVrFH3 zL|C%~(G5riE(>09i(?_g^Y&~Io#HJue2kPyku92_yp&ErKhViLms0W~^N`8|-C^F0z^f{<3Q|22HaCGh!0^;`k=b#ZSgpTLrj`z?g7K*lS| z#m=G$%f+-(uCE2kIiE<4uTUUK>dwG8`2#6uyKb!r#o<89Y z?hIjJqf~yCF|rQQgjL2!y`x`@My??^Ie_yBxI1)5BbP9s@QW1VanwHXrqT#BUMTQ4 zqi$@>&uStMTGt`{05v6Z8-CnM?58F|BlhylO^)1qsz88Ugy4 z{$`NK+4X$-r=m0c!tqtB`J&(2HG>_T#w{F$OfcVrQ`y8QxJzIX-t!T#Rx!=FhXMycJETeis_yv8MeK);<(bOWF01K!YM^1E*qO zB>M)YujBAekdGU_LMA}B<&kSfvD>p^nM>MxGS6{KD0bnga{eH(GC@3fJ1#@QLE?y9 z%5o=q&1G5y0v55^?DAqoG-Rnjy-}z08U+$^DbNpEAbHIN3Rg(9F5`I%R?ZMv7`T-F zeAkC!SllHxShKfUcMvc~(+vG>gyRos{Z?Wk1^uo-m~#m0K=6GUz9Yes-ZYXlXj(%X zoKqwTWKxFDs0?^4HPYJj&-XYQTq0CVpD{fayQHK;Q!i170`jmag4bM}C&4LO7e6xn zvyTiT!S>dtRN@YW{zgSgus$udl!&{ZN`zk>TQ1YQo&@CrX~ev=kzW=nM~bAgQ&z&V z&=5;$KGByb5i@oDh4%28)hbUEI?BtHFnv)~eQK_+-4g?$o~tV}60pQ7+$F6Hmr7yf ziAzO7&$P-H#8UY$q+EhYs}dBbK_!w`Fhy~epIRU;1JXJa+Y4;F3;(8@gy*) z0BMJ!bj1M`+nP1np^{k8F5sw?2njdg)#78ifB_kyOas=8g%Y74y!RAF5}k`DW|>AQ z`|z_X1zpA1t64_GbOLvk%u2^8Jd756jTn$*<0B#yj1LJzG?-5UxT=c->ad$3VUTt+ zG&*W#_-blFFD3GPulQV|>^FUseF#|NH9DSyfL>Xsh~E!tIY5(lS{0)_sg@zN_M@B| zup|7#qM*2`p+jfV`FN*z_QKlM7`e4f1pmf*x7T2R$aQ!XH=cGW3EEwX)IHpZT*fsc zq(mrCXQ!1BB*(HxdUdOtQ`r-tu)q0yUwq!b;OJFGV9XX^SA3E5io~!5YX)CTCs1c* zI&=*#YmytqH!c7N*ABlj%B02xT}3Mxw-zbaEH;WMs3&_$`Fngmyjz}*^grTY5sZp} z3acq=jQwNC1^F^<;ZPKo5H~5MC2vU6i%W@rPdgW zmP(3nJ)o^(l!E~+i{1_$Z%343NgyqvP1L8`Ny#CU`e6W(Hb$W?w(eP^MT9XJuK!hE}!s6 zqrV+=(J^yZjkQrpEYP3e2I6^l%Ckc`lYKsFa>cs|l{%tOOR#`&GSQBz6tyID0()k$ z*!3+2EKUT(rZ&DGJ767|R_F<0BX*&HpjhGKr#4-y$W>lc$Wh-jQk7C6p%d6U<6(IT zfK4!@31ny5l<$|)?ncdqx*-zqkAIS#jJaSZgNIU>!Ba4gKj80OIgFptKXeT+O(-f9K@m1~g+~qH**8v3A#CS5*tYu<7oQlJ4&A z?(XjH?(XjH20;)6L6B|)>FyE)K@bE%kZ;}F&3@H=zIUI^b@=0cU|!7Mn9o>i%p7CP ztQr3Mb`x0VKNj=1c9S*3f8TBb>-@)J{?=}?X87;hO<Sj^wrP1X$meY**)^B;@( zTf51c;lFP;fpz|4F@I|}Su_0i?Iy6!e=O$T+D)$ix_M^Jkn2AdlS{ja_OCs3)4&`B zEdx{e{dK6<|I#ty-`D(SkztGeD=JVzq<{Ute?OP`UoHp#y4F9F1Gg;xPY2JyFVcNn z#K5U=o-ExuW^K{BSKxZ6|Fl%&LI&={wEJt{-~Wrj05bkjUebT1rT-(SP1qDcf&_l0 z&~9dQ>Gs!?zW<9piT}sse@1=C4rivaz#WRfW%pk`^+Nyu=VgJb6@#iW{-5Iil=h*7 zP))kG2=tBlOZxwEQ|y0D|0C%`a)@TF|29xK&&O@`KXN{#hHCzgx0wIG*xr98eMk=B zM*ClKKXQBjk@F!njDP*xL#hHFR}=rr`cr!AZU&M5WxGE*{hwJM(nAHd`|o!XKJvTq z&!i8@VQq8ZmDGQ`R4Vv!)$%`KAM!)B=<%AB*%F-}!Mf8{7<0EVTL)7#jL4pSH=R+YOy9FjX{OjZW zk8GxY1bxVj5O|&u=vNZhCp7-sDQ=OEtE0cWQY1=9M@l>KeD<0GwDNen4VpAs`=ZCBR}#$@vp28>7jZBCVmaPocqs} z{gK=K&!i8@;d<%t{KxAe{+#}iC%S)1`%pq~-6sDW{gJ0|V*Z)gz5B>%UB|`z$Ju|^ zPJ!{yy#hy%z$04yD&5>_6FhJ)%FmF2pKZb+JR%|zq97`wBL+S}EW|-ve2Vx;h(t(& zq)3hwNQKl$i*(3QbD2MW>h)Sq}s;G_{ zsD;|7i+X5)hG>i?Xolu!iB@QXwrGzI=!DMbif-tEp6HD}=!gCoh(Q>Fp%{)47=_Uo zi*cBMiI|Kjn1<uoja054SJ3#j~cLMr~-?QjG9^fG! z;W3`zDW2guUf?BO;WggiE#Bchf}{)(48ai+p%4aP5gri`36T*M(GUYM5eu;q7x54u z36Kbhkrc_00x6LiX^;--krA1Y1zC|DIgksvkr(+;00mJPMNkaIQ4*z424ztm6;KJ4 zQ5Drt12s__bx;rW(GZQ$1WnN#EzkBuvIsOv4P!#B9vLJj};JEW#2j#d55`Dy+sDti?L4#|CV~ zCTzwQY{fQg#}4eoZtTH6?8iYI!Vw(BF&xJUoWyCI!8x4AMO?xaT*Y5+Wliq9F!iA{JsJ zF5)3R5+D&0BPo(01yUk4(jXnuBO@{)3$h|Rav&FSBQNry01Bcoil7*Zqa;e949cQB zDxeZ7qbjPQ25O=<>YyI#qahlh37VogTA&qLqb=H@13IEJx}Y1nqbGWy5Bj1%24D~d zVK4V9|@5NNstuDkpiiZ8flRZ8ITc~kpQd7)4PGB~TKjQ3mBu z9u-juRZtbxQ3JJ58+B0+4bTvc(FD!V94*lbZO|6&(E**%8C}s0JF#@A78e=gI6EG2zF$L2w9WyZtb1)b4u>gy(7)!AXE3gu)@fp_QbF9Y~*oZH& z8DC*5zQ%TZgPqugJ=lx=IDkVqjHCD#$MGFb;uOx{EY9NsF5xn+;u>z?CT`;n?%{hp zzz=wYAMpe~;Te9$3;cpt_!V#P8{Xk}1W6kpD1svdLLoH5A{-(hA|fLSq9HnB;uFM1 z9K^$?NPvV$j3h{g5jXcPQ{3wV*D1xFWjuI$^(kP2^ zsDO&7j4G&x>ZplYsDrwwj|OOj#%PLWXn~e!jW%e9_UMRC=z^~3jvnZR-sp>d7=VEo zj3F3?;TVZg7=y7Gj|rHB$(V|1n1Pv?jX9Wy`B;cWSc0Wkjulvi)mVeIScmo4fQ{IM z&Desi*oN)cft}cmJ=ll+IEX_yf}=Qw<2ZqnIE^znhx53IOSpooxQ-jRh19UcX*E==>h~paD+rCgh5z@M+8JdWJE(26hm>8L@AU(S(HZw zR6=D`MK#nwP1Hsm)I)tVL?bjoQ#3~lv_fmNMLTprM|4IPbVGOaL@)F~U-ZWS48mXx z#W0M(NQ}l9jKg?L#3W3?R7}SV%))HU#XKy)LM+A-EW>iF#43D-HTWFs@C7#DOKied z*n+RI4c}k~c40U6Vjm9RAP(aQzQr+ohZ8u3(>RNBxPXhej4QZ?>$r(qxP!a+9{2GB z9^ywl#!q;PpYa^O;3a;=Yy5_{_#N*NG<|?z2!W6YjW7s@@Q8>=h=Qnyju`j^u@DDw z@hRdXArc`8k|H@$AQe(0Ez%(aG9ojwARDqHCvqVV@*+P9pb!e9D2ky3N}@E%pd8Ah zA}XN@s-ik-pcZPQF6yBH8lo|ppc$H@C0d~k+M+!=pc6WyE4rZvdZIV_pdb2UAO>Lw zhGIBIU=&7UEXH91CSo$CU>c@lCT3v{=3+h;U=bE$DVAXcR$?_i!&-cf_4ooC@g+9n zD{RHr*p6?o6T7end$At}a0rKS6yM@FzQakJ!Wo>!d0fCHT*g&g!wuZTZQQ{c0;NzIWl;_l zP!W|;1=Ua;HBk$7P#5*l0FBTXP0-DeaR^6n6vuEJCvXy{aR%pb9v5*5S8x^AaRaw-8+UOJ_wfJ^ z@d%Ic1W)k{&+!5;@d~f;25<2W?-3+pfM5uYkO+k^2#fHDfJlgpsECFbh>2K;jkt)1 z_(*_6NQ|UNh7?GN)JTJLNRN!jge=I4?8t#!$c?w!YG1bD2|dSg)%6M@~D7H zsEn$ph8n1e+NgtisE>wdgeGW;=4gRdXpOdLhYsk7&gg<}=#HM~g+Azu{uqEk7>uD9 zh7lNv(HMhq7>|jVgejPc>6n38n2ouZhXq)O#aM!6SdNugh0m}CpJN@qzy^GYP5261 z@HMvK8|=U??8aW~!vP$`VI0A?IEL?V0;g~qXK@Y}a1obr1=nyLH*pJha2Ma>K7PPM z{D{Z+2~Y7ep5qt1#IJab-|!Z{<2{0A3J?q-5E7vg2H_AM5fKSd5Eao81D_xk;vgKxQc7Ift$FEJGh7M@c=*I z5q`uI{Df!t887e)Ug1}~!Ebnn-w`BpfS?GD5D10P2#autfQX2UD2RsWh>1@S8*va1 zpCSPgA~BL68ImI?rvPU1Aq;2h55A}-+yuHrgw;1+JN6@SRf*}M#A~eDv9Ks_aA|VQ*B06H=6U0Is#KotG zkAz5sBuI+nNP$#HjkHLI49JMg$bxJEy0^(5PzS4=7Uf1B$jI7*@v%AhRD zqXH_SGOD5)YM>@+qYmn!J{qDCnxH9~qXk-_HQJ&bI-nyuqYJvBJ9?rQ`k*iRV*mzW zFot3nMqngHV+_V&JSJiireG?jV+LknHs)d;7GNP3V+odFIaXp7KEoP(j&=9~8}KDI z;VW#x*Vu+{umiiW8+)-22XGLFaRlGu7{0>^oWg0G#W`HSMO?-eT*GzT#4X&xU3`!G z_yG^`BOc=?JjKs=j$iN+zv4B1!(050_XwIjKrnn|BQD}0J`x}i5+f;+Aq7$*HPRp*(jy}>Aq%o1J8~cwaw9MDp#Tb^aDeV@iUjmE zC}vR!ltgKiK{=F1MN~o+R7G{vKrPfpUDQJZG(=-GK{GT*OSD28v_*S#KqquYS9C)U z^h9s;K|l1zKn%hV48?Gaz$lEySd7C2OvGeN!8A+uCP;!AACSJ;ZLu^r!FCw5^E_F_K{;1CYuD89vUe20@bg)=yd^SFRZxQwf~ zh8wtv+qi>!_#O}N10LZ=Ji$+RhM(~Qzu*;q#T)#FclaGaas~*B;0S?G2#v4^hX{y> z$cTbyh>n=}1hEkZ@$e}UAR!VX36dc>QX&=7AT81(12Q2qvLYLDASZGo5Aq>D3Zf8- zpeTx?1WKVa%Ay=9pdu=x3aX(xYN8hEpf2j80UDt(nxYw6pe0(P4cehSI-(Q0pewqg z2YR75`l25OU?2u#2!>%eMq(7kU@XRC0w!THreYdqU?yf`4(4G#7Ge>WU@4Yk1y*4- z)?h8xVLdirBQ{|(wqPr^VLNtUCw5~G_F+E`;t-DDD30McPT(X?;|$K>JTBrAuHY)J z;|6ZwHtymc?&AR-;t?L>37+B^p5p~x;uT)w4c_7%-Xln^0KpI(ArT5;5EkJP0g(_H zQ4tL>5EHQw8*vd2@sR+DkQhmk3@MNjsgVZhkRBP430aU8*^vXekQ;fC4+T&Vg;4~> zP#h&u3T03hC&g4js@DozVr|&>cO| z3w_WR{V@Q8Fc?EI3?ncSqcH~KFdh>z2~#i?(=h|HFdK6*4-2pmi?IaDupBF~3ZG#O zKF2zIferW)oA4F3;A?EdH`sw)*p0o|hXXi>!#IL(aSY$#1Ww^J&f**{;36*L3a;Tg zZsHd1;4Z$$ef)rj_z{os6Q1H{JjXA1iC^&=zu_%@$9n|L9UvG&AS6N~48kEiA|eu^ zAS$9G20lS7#6etqiug!~L`Z_9NRAXph15ukbjW~=$c!w=hV00RT*!mG$d3Xjgu*C_ zVkm)$eI&R<=ZsRWQ;XWSVAs*o|p5Q5-;W=L5C0^k*-rz0X;XQ)n2@njy5fY&g24N8% z5fBNH5f#x812GW`u@M*X5FZJU2#Jvt$&dmmks4``4(X8*nUDopksUdZ3%QXO`A`4_ zQ5Z!~48>6rrBDWCQ63dg36)V5)ldU9Q5$to5B1RyjnD*5(Ht$%3a!x=?a%=o(HULP z4c*Zbz0e1J(H{da2!k;c!!QCPF&bkq4&yNqlQ0ESFȽ$rm7^RNI5u^3CR49l?+ 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%0D%z{!4Lu=5gK6-4&f0Ikq`w@5gjoQ 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Ƚ$rm7^RNI5u^3CR49l?+tFQ)Zu^t<+37fGM+pq&Wu^W4^5BqTthj0W(aU3Ub z3a4=v=WqcRaT!-|4cBoKw{Qn{aUT!x2#@g;&+q~-@fvUN4)5_1pYR1=@f|<#3%?Pl zZ2*B06u}SzArTs35DwuH5s?rDQ4t+65DT#p7x9n)36U5{kPOL@5~+{|X^|cokP(@X z8Cj4O*^nJMkQ2F(2YHbn1yBfuQ53~c0wqxzWl#>~Q4y6;1yxZUHBbw+Q5W^l01eR? zP0$R@(GsoD25r$E9ncA#(G}g$13l3jeb5j6F%W|=1Vb?#BQOf1F&5)60TVG9Q!owF zF%z>e2XiqW3$O@_u@uX&0xPi^Yp@RMu@RfF1zWKlJFpA8u^0Pr00(gxM{o?saT2F+ z24`^|7jOxeaTV8a12=IScW@8)@eq&j1W)lCFYpSl@fPp!0Uz-hU+@jz@e{xB2Z7oJ z5ClOH93c=2p%E705CIVp8Bq`o(Ge4|5C?G)9|@2MiIEh^kOC=@8flOY>G2mb;%{We zKgf!IksbdbCvqbX@*zJ8q7aIpD2k&5N})8$q8uuqA}XT_s-Ze+q893)F6yHJ8lf?o zq8VDCC0e5m+MzuRyhG95HVid+;EXHF3CSfwBVj5;( zCT3#}=3zb-ViA^LDVAdeR$(>PVjVVMBQ|3TwqZMVVi)#cFZSaA4&iVBlcL5A9LQ;Y zRCEj{a1y6+2Ip`d7jX$!a23~a1GjJ+cX1C7@DPvj1kdmsFYyX*@D}g!0iW<0U-1n; z@DsoB2Z7rM5Cp*x93c@3VGtJK5do198Bq}pF%T265eM-Q9|@5NNstuDkpiiZ8flRZ z8Sob};csNYKgfoEkpurB7jh#n@}U3c7LN}&wOqC6^~5-OuAs-XsIqBiQF z9_phZ8lefAqB&Zi6dZ7>cqCW;;5C&r?hG7IoVl>8J9L8fJ zCSeMuVmfAE7G`5E=3xOAVlkFr8J1%uR$&d+Vm&rs6E`(jq-F zAR{s%GqNBnvLQQiASZGm5Aq^E3ZM`QqbQ1@1WKYb%Ag#|qarGy3aX+yYM>Tsqb};9 z0UDw)nxGk)qa|9Q4cekTI-nCeqbs_h2YRA6`k){BV;}}$2!>)fMqm_1V=TsD0w!WI zreGSTVBFV=wmM01o0Xj^G%M z<0MYu49?;_F5nU_<0`J<25#au?%*Eo;~^g537+CPUf>m8<1OCd13uz2zTg|a<0pRM z4+3=zAP9mYI6@#4LL)4~Ap#;IGNK?Fq9Z0^Ar9gqJ`x}i5+f;+Aq7$*HPRp*(&H~= z#NWt_e~=abB0K&=PUJ=&6T7end$At}a0rKS z6vuD^Cvh5Qa1Q5j5tncUS8*LTa0|C_7x(Z05AhgJ@C?uK60h(EZ}A=<@Cl#s72og! zKk*xX5V%tSK@beV5fY&g24N8%5fBNH5f#x812GXBaS#vjkr0WH1WAz`DUb@OkrwHY z0e>MA{zex3gKYR0Iq)BHAvf|O9}1u#3Zn>$p*TvS6w071%A*1*p)#tX8fu^>YNHP7 zp*|X-5t^VWnxh3;p*7l~9Xg;RI-?7^p*wn_7y6(t`eOhFVK9bb7)D?uMq>=dVLT>c z5~g4(reg+XVK(Ms9u{CB7GnvPVL4V}71m%a)?))UVKcU38+KqPc4H6rVLuMy5RTv| zj^hMQ;WWO7Vh9K?&AR-;W3`#8D8KeUgHhk;XOX$6TaXpzT*de z;Wq+x4j?dsA{as-Btjz$!XZ2&A`+q?DxxC>Vj(u-A|4VTArd1Ak|8-#A{EjgEz%Z1V~p)s1G8CswvTB8lxp*=dH6S|-)x}yhrp*Q-X9|m9`24e_@VK_!&6vkjI z#$y5|VKSy-8fIW7W@8TKVLldO5td*nmSY80VKvrb9X4PiHe(C6VLNtW7xrK;_TvB! z;V_Qk7*60MPU8&D;XE$l60YDXuHy!7;WqB#9vt+ zdSpOGWI|?SK~`i#cH}@#kIh035R6-S0MRn9bE!0L` z)I$R_L}N5TGc-p_v_c!SMSFBWCv-+vbVCpHL~ry#KlH~y48jl$#c+(kD2&EfjKc&> z#AHmtG)%`#%)%VZ#e6KlA}q#IEW-+{#A>X;I;_V=Y{C|7#dhq#F6_o$?85;Z#917bJi-$^#dEyCE4;>Ayu$~4#AkfLH+;uW z{K6ju>J~r{1VwO!Kq!PpScF3aL_}mnK{P~1OvFMQ#6^50Kq4eYQY1qPq(o|@K{}+z zU&x5Rks1FWEB-}x{D+*#jXcPQ{3wV*D1xFWjuI$^(kP2^sDO&7j4G&x>ZplYsDrww zj|OOj#%PLWXn~e!jW%e9_UMRC=z^~3jvnZR-sp>d7=VEoj3F3?;TVZg7=y7Gj|rHB z$(V|1n1Pv?jX9Wy`B;cWSc0Wkjulvi)mV#l*no}Lj4jxP?bwN3*n_>;j{`V_!#Ij# zIDwNmjWalh^SFphxPq&=jvKgz+qjE+cz}m^j3;=8=Xi-%c!Rfij}Q2S&-jXO_<^7J zjXwz7J%AtxhTsT^PzV!1r{-Y;^mPd@iik*vf~bg&7>I?~h>LhgfP_elBuIwjNQqQP zgS1GG49JK~$c!w=ifqV^9LR}W$b-Ddj{+!!!YGPjD1nkFjWQ^Q@~DVPsDi4fjvA6nRGn1i{Pj|EtS#aN1ESb>#TjWt+@_1K6_*n+Ltjvd&A-PntLIDmsV zj3YRP<2Z>^ID@k|j|;ej%eabbxPhCvjXSu9`*?^)c!H;Rju&`^*LaI}_<)c2j4$|x z@A!#d_=7+_0tkYj2#yd4h0q9#aEO42h>R$RhUkciScrqTh>rwFgv3aSWJrOONR2c| zhxGUh8SytV;~!+jzsQdNkQ2F)2lc0;NzIWl;_lP!W|;1=Ua;HBk$7 zP#5*l0FBTXP03M4JFyFUuowGr0EciG zM{x`%a1y6+2Ip`d7jX$!a23~a1GjJ+cX1C7@DPvj1kdmsFYyX*@D}g!0iW<0U-1n; z@DsoB2Z4JA5Cp*x93c@3VGtJK5do198Bq}pF%T265eM-Q9|@5NNstuDkpiiZ8flRZ z8Sob};csNYKgfoEkpurB7jh#n@}U3c7LN}&wOqC6^~5-OuAs-XsIqBiQF z9_phZ8lefAqB&Zi6dZ7>cqCW;;5C&r?hG7IoVl>8J9L8fJ zCSeMuVmfAE7G`5E=3xOAVlkFr8J1%uR$&d+Vm&rs6E`(jq-F zAR{s%GqNBnvLQQiASZGm5Aq^E3ZM`QqbQ1@1WKYb%Ag#|qarGy3aX+yYM>Tsqb};9 z0UDw)nxGk)qa|9Q4cekTI-nCeqbs_h2YRA6`k){BV;}}$2!>)fMqm_1V=TsD0w!WI zreGSTVBFV=wmM01o0Xj^G%M z<0MYu49?;_F5nU_<0`J<25#au?%*Eo;~^g537+CPUf>m8<1OCd13uz2zTg|a<0pRM z4+8ZLAP9mYI6@#4LL)4~Ap#;IGNK?Fq9Z0^Ar9gqJ`x}i5+f;+Aq7$*HPRp*(&H~= z#NWt_e~=abB0K&=PUJ=&Bt#-4K~f|~3Zz16q(wSpz+cFO zzmWz1ARGQg4*Z8)$c?w!YG1bD2|dSg)%6M@~D7HsEn$ph8n1e+NgtisE>wd zgeGW;=4gRdXpOdLhYsk7&gg<}=#HM~g+Azu{uqEk7>uD9h7lNv(HMhq7>|jVgejPc z>6n38n2ouZhXq)O#aM!6SdNugg*8}<_1J(-*o>{%h8@_6-PnVD*pGuagd;eL<2Zp+ zIE}M7hYPrf%eaDTxQ?5+g*&*5`*?syc#Nlbh8K8=*LZ_>c#n_xgfIAt@A!dV_>Dk) z0|<{iO>jxa0rixh=eGJis*=eScr|dh=&A7h{Q;OWJr#bNQE>=i}c8VjL3w{ z$bziMhV00JoXCYd$cy|afI=vYq9}$ED2dW2gK{X3il~GtsEX>Sfm*1Ix~PW+Xo$vW zf@WxrmS}}GXp8pffKKR)uIPpy=!xFwgMR3bff$4#7>eN-fl(NZu^5L5n25=kf@zqJ znV5w+n2Y&XfJIo0rC5d)Sc%nGgLPPsjo5@O*oy7gfnC^*z1W8XIEceIf@3(2lQ@Ml zIE(YRfJ?ZHtGI?6xQW}igL}A-hj@f1c#7wEfme8qw|IvS_=wN=f^YbapZJA82-Git zAP9=!2!T)tjj#xZ2#AQth=OQ{j+lsrIEah*NPt90jHF106iA8GNP~1pkH3%+eu3Z+pNg4(-tqozMkc(H%X|3%$`7{V)InF&INI48t)Jqc8?zF&+~z36n7u(=Y=w zF&lF*5A(4Qi?9Ssu^cO~3ahae>#zYEu^C&i4coC3yRZj)u^$I;2#0YL$8Z8CaT;fE z4(D+Zmv9AFaUC~s3%79>_wWD@@fc6=4A1crukZ$M@g5)W37_#5-|z!J@f&{-xPJga z5DdW)5}^v^H}WDM3ZNhgqX>$jI7*@v%AhRDqXH_SGOD5)YM>@+qYmn!J{qDCnxH9~ zqXk-_HQJ&bI-nyuqYJvBJ9?rQ`k*iRV*mzWFot3nMqngHV+_V&JSJiireG?jV+Lkn zHs)d;7GNP3V+odFIaXp7)?h8xV*@r}Gqz$Ic3>xVV-NOWKMvv$j^HSc;{;COG|u82 zF5n_A;|i|fI&R_??%*!&;{hJwF`nWXUf?BO;|<>7JwDHv$a^ATWX= z7(yTzr3$h{` zvLgp_A{X)?FY==R3ZXEHq8Lh`Bub+U%Aq_eq7tg0DypLfYN0mjq8=KcAsV9znxQ#b zq7~YpE!v|4I-xVVq8oakCwij~`k_AtVi1O4D28JMMqxC@VjL!5A|_)BreQi}Vix9L zF6Lta7GW`#Vi{IoC01h%)?qz1ViUGtE4E_?c40U6Vjm9RAP(aQj^Q{?;uOx{EY9Ns zF5xn+;u>z?CT`;n?%_Tj;t`(UDW2m6Ug0&~;vGKVBR=B`zTrE5;uroP(7*tKASi+( z1VSM+!Xg|ZAR;0o3Zfx8Vj>peATHt~0TLlGk|G&WASF^G&HohKL$nx35CzcKwr$(C zZQHh!i8Vb-s9tneAsx~qBQhZivLZWjAQy5YFY=)P3ZgKI zpcsmyBub$S%A!0fpb{#hDypFdYN9skpdRX@AsV3xnxZ*cpcPu9E!v?2I-)bWpc}fQ zCwid|`l3GuU=aSo5Ddj|jKC<2##sD~@tA;#n1m^qis|?lGcgNuFc9Wo#zG9wGJAvp)iV~ z7)qcdN}~+Qp*$+05~`pos-p&Kp*HHG9vYw_8lwrCp*dQj722RJ+M@$Hp)>MqI>00whFYBtbGHM@pnZ8l**fWI!flMpk4)4&+2`uD9h7lNv(HMijF%A>(4<=zUreYfY#SF~CY|O#|fOmX`ID5T);(K#uZ${b=<@) z+`(Pk#{)dVV?4z(yueGm!fU+6JAA-Le8v}i!*~3|FZ@BE5dj22Py|N^ghFV9ML0x2 zL_|guL_>7ML@dNXT*OBLBtl{&MKYv7N~A^_q(gdSL?&cGR%AyG(2 z6hm>8L@AU(S(HZwR6=D`MK#nwP1Hsm)I)tVL?bjoQ#3~lv_fmNMLTprM|4IPbVGOa zL@)F~U-ZWS48mU+f}t3W5g3Kh7>mC#9uqJTlQ0ESF&+P6CT3v{=3+h;U=bE$DVAXc zR$?{QU>(+DBQ{|RwqiSWU>9~{FZSU84&pG5;24hMBu?QB&f+{S;1Vw5Dz4!MZsIoX z;2!SdAs*ogp5i%P;6J>=8@$DPe84As##em95B$V${6XN60R%xX1V>1OLKuWactk)X zL`GCZLkz@3Y{Wr4#79CTLJ}lJa-={iq()k#Lk46-W@JG&WJgZqLLTHreiT3<6h=`L zLkW~bX_P@Zlt)EWLKRd+b<{vD)J9#@LjyEKV>CfCG)GIcLL0P2dvri2bVgTnLl5*s zZ}dSw^v6I9!e9)+Fbu~?jKUa<#W;+|KbVNgn1X4Tjv1JV*_eZQn2&{6ge6#t&Der%*p8jpg+17d{WyR_IEh7&l6(>Q~3IFF0Cge$m;>$rhixQ)BG zhX;6w$9RHgc#fC&53lhC@9-WU@d;n>72oj#zwjG@Mgc z0;NzIWl;_lP!W|;1=Ua;HBk$7P#5*l0FBTXP06r zrBDWCQ63dg36)V5)ldU9Q5$to5B1RyjnD*5(Ht$%3a!x=?a%=o(HULP4c*Zbz0e1J z(H{da2!CM+hGIBIU=&7UEdIuLOu$4;!W2x!bo`5%n1wl*i}_f9MOcibScVl?iPczx zby$y$*n}phJIE6Dfi}SdEOSp`yxP}|JiQBk?d$^B> zc!Vc-isyKN|L_WL@D}g!0iW<0U-1n;@DsoB2Z6@~5Cp*x93c@3VGtJK5do198Bq}p zF%T265eM-Q9|@5NNstuDkpiiZ8flRZ8ITc~kpQd7)4PGB~TKj zQ3mBu9u-juRZtbxQ3JJ58+B0+4bTvc(FD!V94*lbZO|6&(E**%8C}s0J3S%%9<1iloU?L`C3Z`K?W?&{}V-DtFJ{DpTmS8ECV+B@WHP&Js zHee$*V+*!nJ9c6h_Fyme;{XofFplCFPT(X?;|$K>JTBrAuHY)J;|6ZwHtymc9^fG! z;|ZSOIbPyFyv7^6!+U(hCw#$Ie8&&`!fyl`8$e(LMKFXwNQ6chghO~lL?lE(R76J% z#6oPuMLZ-xLL^2KBtvqfL@J~~TBJt?WI|?SMKPUJ=&UTl7>Z#Sfsq)EG58zfFaiHy5+-9Rrr}@Az%0zhT+G7)EW~0g!7?nzO02>fti^h4 zz$R?QR&2u#?8I*D!9MKAK^(#n9K~^*z$u)@S)9WKT*PHu!8KgRP29pA+{Jx7z#}}y zQ#`{9yu>TK##_9@2Yke5e8D$-$4~si9|Zb4fFKBp;0S?G2#v4^hX{y>$cTbyh>nw!YG1bD2|dSg)%6M z@~D7HsEn$ph8n1e+NgtisE>wdgeGW;=4gRdXpOdLhYsk7&gg<}=#HM~g+Azu{uqEk z_zOcY6vHtBqc9p{@i)d}0w!V-reG?j<6q3gEX=`N%*O&O!eT7NGOWN#ti~Fw!+LDQ zCTzi0Y{w4l!fx!vJ{-V79L5nG!*QI%DV)JsoW})R!ev~=HQc~W+{PW;!+ku&BRs)V zJjVB>4ftZMm zIEaV%NQgv8f}}`}6i9{CNQ-pHfQ-nDEXaoJ$cbFYgS^O(0w{#SD2iezfs!bVGAM`g zsEA6af~u&F8mNWZsEc}NfQD#{CTND{Xo*&6gSKdo4(No==!$OWfu87%KIn)37>Gd_ zj3F3?;TVZg7=y7Ghw=Ca6EPW6Fb&f&12Zujb1)C{u@H-}1WU0TE3gWyu@>vF0UNOy zTd)n=u@k$n2Yay}2XF|7aTLdJ0w-}AXK)VZaS@kr1y^w$H*gELaToXS01xpPPw))S z@e=>xHQwMI-s2-a;S0XvJAU97ek0KM00JW@f*}M#A~eDv9Ks_aA|VQ*B06Fq7GfhV z;voSNA~BL68ImIWW??qwVjdP?Ar@l^mSH(oVine4E!JZLHeoZi zVjFf~Cw5~G_F+E`;t-DDD30Re@BLqSrG{PbrA|N6nBMPD+I$|Og;vg>K zBLNa2F_Iz~QXnN#BMs6aJu)H_vLGw6BL{LJH}WDM3ZNhgqX>$jI7*@v%AhRDqXH_S zGOD5)YM>@+qYmn!J{qDCnxH9~qXk-_HQJ&bI-nyuqYJvBJ9?rQ`k*iRV*m!>FATv@ z495tJ!f1@e-x!Yxn21T3f~lB}e=!rYFb8un9}BPui?I~TumUTw8f&l)>#-4=umxMO z9XqfKyRjGhZ~zB!7)Njn$8i#;a0X{_9v5&4mvI%>a054S8+ULI_wf*q@B~ls953)6 zUf~Vi;ypg#6F%cBzTpRc;y3;v@IL_rK`;bINQ6QdghhBnKqN#)R767z#6)bwK|I7q zLL@>GBt>$hKq{n0TBJh;WJG3UK{jMZPUJ!!u3Z+pNg4(-tqozMkc(H%X|3%$`7{V)In@fQYT zD28DKMq)I^;BSn>1pI?Zn2f2IhJP^wvoITTF%Ju{5R0({%di|Pu?lOj7VEJAo3I&M zu?;)06T7ho`>-DeaR^6n6vuG_r*Il)aSj)75tnfV*Ki#-aSL~F7x(c1kMI~z@eD8U z60h(YZ}AQv@DZQ!1>f);Kk*BH5NJ{WK@b$d5dxtQ8etI*5fBlP5e3l@9WfCLaS#{r zkpPL17)g-~DUcGWkp}6I9vP7dS&$XkkpsDq8+nlr1yB%$Q3SIHjn2afyhUu7rnV5|^n1}gTh(%a}rC5#?ScTPCi*?w5 zjo6GW*oN)ciCx%(z1WWfIE2GEieor|lQ@ktIEVANh)cMFtGJFExP{xei+gy0hj@%9 zc!uYAiU05#Z}1N9@e!Z!1z+(UKky5`5omG%fe{qJ5CS0)8etF);Smv$5Cu^Y9Wf9K zu@M*XkN^ph7)g)}$&nJNkOpay9vP4cnUNLQkOMi98+niq`B4ysPy|I$93@Z+rBN2; zPyrQD8C6gX)ln0*PzQBU9}Un5jnNd%&;l*d8g0-H?a>jP&;?!59X-$sz0nu_FaQJb z7Y1V}hG7IoVl>9!Z;ZnP{DVoDjH#H0e=!5IFdK6*4-2pmi?IaDupBF~3Tv#+fw zuo+vi4Lh(CyRirRupb9;2uE-f$8iFua2jWE4i|6{mvIHxa2+>s3wLlA_wfLa@EA|= z3@`8!ukadg@eUvG5ufn|-|!tj@e6+tXi5M<5EQ`?0-+EZVG#}y5D}3P14F%b)K z5Et>00Ev(oNs$aGkP@kp2I-I<8IcKDkQLdH1G$hJd65qVP!NSt1jSGsB~c1xP!{D; z0hLf0RZ$H!P!qLL2lY@N4bccq&=k$l0MjcJ<$t&&=>tN0E6%s zhF~a$V+2NFG{)j@jK>5_#3W3?R7}Uen2A}KgSnWG1z3c|Sc+v>ft6T|HCTuB*oaNo zg00w&9oU84*o%EQfP*-UBRGcRIEhm@gR?k~3%G>KxQc7Ift$FEJGh7Yc!)=Mf~R5u^#kr`Q#4cU>MqI>0 z0whFYBtbGHM@pnZ8l**fWI!flMpk4)4&+2`uD9 zh7lNv(HMijF%A>(4<=zUreYfY#SF~CY|O#|fOmX`ID5T);(K#uZ${b=<@)+`(Pk#{)dVV?4z(yueGm z!fU+6JAA-Le8v}i!*~3|FZ@BE=>Y^mPy|N^ghFV9ML0x2L_|guL_>7ML@dNXT*OBL zBtl{&MKYv7N~A^_q(gdSL?&cGR%AyG(26hm>8L@AU(S(HZwR6=D` zMK#nwP1Hsm)I)tVL?bjoQ#3~lv_fmNMLTprM|4IPbVGOaL@)F~U-ZWS48mU+f}t3W z5g3Kh7>mC#9uqJTlQ0ESF&+P6CT3v{=3+h;U=bE$DVAXcR$?{QU>(+DBQ{|RwqiSW zU>9~{FZSU84&pG5;24hMBu?QB&f+{S;1Vw5Dz4!MZsIoX;2!SdAs*ogp5i%P;6J>= z8@$DPe84As##em95B$V${6XM<0|WO+h8T#6*ocF8h>wIw zgd|9cgh7u@=(kO#+D36M$ges_t z>ZpNQsExX)hX!bf#%O|OXpWX>g*Ir5_UM34=!~xDh92mN-sppV=#POIguxhsVHl2) z7=QX&=7AT81(12Q2qvLYLDASZGo5Aq>D3Zf8-peTx?1WKVa%Ay=9pdu=x3aX(x zYN8hEpf2j80UDt(nxYw6pe0(P4cehSI-(Q0pewqg2YR75`l25OU?Bd&U<}1DjKD~Y z#u)sKahQOAFbR_}71Qu9W?&X(V=m@l0TyC0mS7o{VN8lod6Vj&LVB0drz5fURQ zk|70BA~n(=9nvEsG9e4HB0F**7jh#n@}U3c7LN}&wOqC6^~5-OuAs-XsI zqBiQF9_phZ8lefAqB&Zi6dZ7>cqCW;;5dOjt48?Gaz$lEy zSp1Fgn1G3xgejPc>G&5jF$;4r7xS?Ii?A3=u?#D)605NW>#!ahu?btS72B}`yRaL3 zu@47u5QlLD$8a1caSCT}7UyvRmv9+ZaSbqY0X!Ia;C>+Mq4kqXRmjGrFQ1dY~tIqYwI_KL%nD24e_@VK_!&6vkjI z#$i1E!9+~P6imZ(%)m^{#vIJUd@RHwEWuJN#|o^%YOKXNY`{ir#ujV~pnIF`0eU{) zDcX%a*oXZ%h(kDnqd1NeIEB+Vi*vYui@1y{xQ6SviCegXySR@Bc!bAzif4F%mw1KO zc#C)VfRFf$FZhP<_=#WmgFv$b2!fypjt~fi&r+F$jY( z1j8^KBQXkNFc#x59{*q>CSwYwVLE1DCT3#}=3zb-ViA^LDVAdeR$(>PVjVVMBQ|3T zwqZMVVi)#cFZSaA4&gA4;uucgBu?WD&fz>R;u5alDz4)OZs9iW;vOF0As*uip5ZxO z;y=8`8@$7Ne8eYw!B>385B$P!1ey~-U<5@lgg{7yMi_)cctk`bL_t(UM-0S5Y{W%8 zBtSwWMiL}La->8mq(NGwM+Rgk zMio>;b<{*H)InX;M*}oMV>CrGv_MO=MjNz4dvru6bU{~iM-TKuZ}de!48TDAg~1q# zVHkmt7>zOb8{;qm|6md(V=AWMU(CQP%*I^I!vZYCVl2TjEXPW$!Wyi_dThWZY{ph> z!w&4kZtTH6?8iYI!Vw(Bah$*@oW@z4!v$Q#Wn95ET*pn^!X4bjeLTP;JjPQz!wbB` zE4;>Ayu*h8y0`flpex|B=qtYA2Y%u={vhz&0D>SGf+HkCAq>JIJR%?xA|ooIAqHY1 zHsT;2;v*pvAqkQqIZ_}MQX?(WApGZlfmn!* zxQK@YNQlHpf@DaJlt_g%NQ?ByfK14YtjLBO$cfy@gM7%3f+&O{D2n1Jfl?@qvM7fN zsEEp_f@-Lany7_3sEhgmbZ^rjK#i-Bs41GEC0d~^+My#lp)0zfCwieT`e7gjVF-p| z1V&;E#$r4sU=k){8m40=W??SoVIdY_DVAX+R$(pHVFNZ|3$|hhc480q;s6ff2#(?e zPT~yC;sP$>3a;V?ZsHE^;sGAw37+BwUg9<0;5|OzGrr&(zT+o;A<+B)0wWlLBNRd- zEW#loA|WcGAtquWF5)2}5+Ny)Ath2FEz%()G9fFnAt!PnFY=)v3ZW>9p(IM7EXtuG zDxoT>p(bjfF6yBn8lfqgp(R?O4cejuI-(1@q6d1S5Bg#N24XOVU^qr#G{#^Y#$zHT zVJfC!24-Ro=3)UBVhNUF1y*7W)?x!TVhgrn2XsB;yf|$;s<`>4+1R+ASi+%Btju9!XY9e zAu6IF24W%(;vxYOA_c75N~0XgqY^5k z8mglfYNHqa!+@E4ra4dZ91+VIT%!2!>(=Mq&)cVmu~b5+-9B zreh{%VJ_xjAr@gNmSF`}Vhz?}12$p{wqgf%Vh{G>01n~^j^YGP;tbB>0xseTuHpu6 z;tuZO0UqKBp5g^w;x*pjJwD(wzTi84;5Yst$ie`EA_PJr48kHjA|NuNAUa|oHsT;Y z5+E^>AURSX6;dM|(jyZxBO9_KCvqV#@}VFKp$Lki1WKX|%Ax`)q6(^_25O=<>YyI# zqY)aT8JeRNTB9A>qZ2x#E4ra4dZ91+VIT%!2!>(=Mq&)cVmu~b5+-9Breh{%VJ_xj zAr@gNmSH7UVJ+5SBQ{|xwqYlBVK4UKAP(Uuj^QLu;VjPKA}--7uHhzb;V$msAs*og zp5g^w;x*pjJwD(wzTi84;5Yst$f5v(A_PJr48kG;A|eW+A_ih24&ovK5+VtbA_Y<+ z4bmb5G9nAIA_sCJ5Avb_3Ze*#q6A8!49cPcDxwOiq6TWB4(g%-8lnlBq6J!_4ceju zI-(1@q6d1S5Bg#N24XOVU^qr#G{#^Y#$zHTVJfC!24-Ro=3)UBVhNUF1y*7W)?z(2 zU^BL0J9c0<_Fz8_;4qHhI8NX+&fq*Q;4-e@I&R=L?%+Ni;4z-yIbPruUgI6!;}bsP z8@}Tgek1VW0D>SmLLfB4AUq-BRZigx}hg}p)dMj zAO>LwhGGOpVhqM&JSJcgCSw|=VVj~{nBM}lK8ImIvQX?JGBNH+s8?qx8aw8w|qYw(C7>c75 zN~0XgqY^5k8mglfYNHqZ2x#8@i(xdZQouV-WtrPz=LJjKWy_ zjS2V%lQ9L;@h@g!Hs)bI7GW`#VL4V|HP&H0HeoZiVLNtVH}+va4&gA4;W$p=G|u5X zF5xn+;W}>NHtyj*9^o;b;W_@pE4;-!e8eYw#W(!KF9cc|KwtzzaD+l=ghO~lLS#fk zbi_hz#6x@}L?R?bGNeQ*q(wSpL?&cKHsnMuMGLvVybXoN#}L_%alLv+MKY{Wx+Btl{& zLvo}-YNSJYWI|?SMK&)J7fDLwz(v zBQ!x%G)D`xLTj``dvro)bVGOaLT~g#e+Z#SiBTAfzcB&-U^1p)I{w8h%*H&- z$097oGAzeRtioEX!$xevR&2vg?808`!$BOvQ5?fboWfb0!$n-eRb0bO+`?Vl!$Um6 z6FkKWyu@p~!FznbXMDkT{J?MgL6GGE1VsphL>Poc1Vls>L`8JOKy1W8Jj6#LBt|kM zM=GR7I;2M?WJWe*M=s<>KIBIs6h<)=M=6v>Ih02wR7N#aM=jJwJ=8}dG)6NtM=P{O zJG4h9bVfIHM=$h7KlH~S{Dq+yhLISBvG^Mk@DCh=aIDfP_ebq)363NQ1PzL) zhw+$*NtlXhn1Pv?gSl9Mg;;{6Sb>#TgSFUzjo6GW*p408jXl_p12~K$IF1uIjWalp z3%HCcxQ-jRjXSu9`*?)Mc!uZr53leR@9+_y@D<RRDnz48ai!p%D(@5ebnI z4bc$`u@MjPkqC*A49SrSsgVxpkqMcR4cU6jrBM#$Q3;h%4b@Q# zwNV%K&=8H#6wS~QtSt$ z8g0-X9ncwF&>cO{8-36p1Mn9HV;F{G6h`B3jKe>eh$)zge=!5IF$eRp0E@8%%drBh zu?Fk00h_S}+pz3Zf8-q8Lh|6w0C;Dxwmqq8e(V7V4rN8ln-Jq8VDE722X5I-(Q0q8oam z7y6lo@jd+NUL`aNeNRCuUjdVzlOvsFE$c|jdjeN+DLMV)4D2`GnjdCcDN~nx#sE%5w zje4k$Mre#?XpUBBjdo~{PUwto=#F0Kjeh8lLHG+pF$^Oy3S;p%Cg2}T#uQA)znF#D zn1}gTgvD5fw>$r(qxQlyu zh(~yeXLyPK@CI-30Uz-NU-1J!@dtr61P~O#5E7vf7U2*Pkq{Np5EHQw7x9n~iI5b@ zkP@ko7U_@?nUEFPkQ2F(7x_>Sg-{g5P!gq37UfV8l~5JcP!qLK7xmB(jnEX$&=RfC z7VXdxozNBC&=bAT7yU30gD?a`F#;no24gWE6EF#rF%8o(6SFWE^RN($uoTO%605Kl z>#z}XK?`+aRpa#12=I8ckuuZ@dQut0x$6zZ}1); z@EKq59Y63Je-LD206`G~ArS^)5djeq1yKQ2+%|1VvE-B~b=tQ2`ZE1yxZ4HBkq3(Ett61WnNbEzt&T(E%ON1zphtJ<$h! zF#rQG7(*}|BQP3cFb?A}5tA?#(=Y=wF$Z(801L4MOR)kgu?B0g0UNOeTd@N>u?Kr` z00(gdM{xotaRz5`0T*!vS8)S3aR+zt01xp5Pw@gT@fvUN9v|=-U+^72@Ed;+WK#e^ z5dt9*24N8a5fKGZ5d$$12XT=A36TUzkpd}^25FH28Ic89kpnrA2YFEd1yKY=Q354V z24ztJ6;TCMQ3Ewm2X)Z^4bcQm(E=^e25r#+9nl3{(E~lv2YoRB12GswFdQQ=8e=dH z<1rDFFcs4<12ZuPb1@$auoz3Q94oLIYp@<0uo+vh9Xqfad$1n|a2Q8$94BxZXK)@D za2Z!{9XD_rcW@sM@EA|<953(+ukjA=@d=;t4d3w#zY%zI06`EOArKm25FQZ_8Bq`& zF%TPZ5FZJU7)g*EDUcdzkRBP38Cj4WIglH9kRJt57)4MF#Zd~SQ4Zx%36)U|)lmzz zQ4jUe2#wJU&Cv?2(GKm=37ydm-O&rZ(GUGG5Q8uTLoos)F$QBX9uqJLlQ9j`F%z>e z7xSvcx25Yea8?gmju>(7?2YYb<2XO>PaRMiC24`^r7jXqwaRWDT2Y2xR z5Ag&~@d7XL8gK9(AMhDp@Et$!8-EaZO8`L-48ai!p%E705CIVp1yKQ2+%|1VvE-B~b=tQ2`ZE1yxZ4HBkq3(Ett61WnNb zEzufn&>kJo8C}pFJR0kxPZ&Jg6p_}+qi@Kc!0-vg6DXF z|L_WL@eUvH319IIKk*BJwgwOw!4Mpw5E|hS9+40k(GVT65F7CjABm6{$&ehWkQ(Wb z9+{9CS&I4i!-eRZ$H!Q44iZ4-L@>P0LogI0FcM=h7UMAilQ0?6FdZ{73v)3K3$X}Gu?#D*3Tv?r8?gyn zu?;)13wyB-2XP2T1L)r7Sb&CZPl!(8G|u82F5n_A;|i|fI&R_??%*!&;{hJwF`nWX zUf?BO;Wggk9X{YAKI03%;X8if7ycm7wg7@4D1svdLLoH5A{-(hA|fLSq9HnBA{OEx zF5)8r5+N~?A{kO3B~l{|(jh%EA``M8E3zX8av?YJA|DE%APS=hilI14q7=%YEXtz- zDxor}q8e(TCTgP&>Y+Xwq7j;)DVn1NTA?-Cq8&P*BRZoCx}iIIq8Iw0FZyEu2H`IZ z!B7mx2#msLjK$v=j|rHFNtlAEn2vuj6SFV}b1@$aun3E>6w9yzE3q1Dunz075u30D zTd^HGunW7f7yEDk2XPoja16(B5~pwmXK@}Ea0!=j71wYBH*p(xa1ZzK5RdQ#Pw^Zt z@E=~`4c_8CKHw8R<14=52Y%u={vh!70D>SGf+HkCAq>JIJR%?xA|ooIAqHY1HsT;2 z;v*pvAqkQqIZ_}MQX?(WAp)=!M?si+&h@ zf%pr9F%-iv0we!t?|lFyt*SdwM%lm)B#=Oa1oHS&1DP7=uAUiCu$cy$o}QUbPft&} zdl=YeQdCz}ch_|NY3tAQ3`jJQ1UHgs)=4CRL=(;GMiWV7qlsi;g{)+8qgi>YFS<`& z^hI~|J$>pv-G^`8-|w7rzwdtaud90o9JD9#N7r}%-+S)4=bn4+xrAROyovB@gkLAT zh434Mw*neRPXgI}zr{}v5`LTT5aD6M?-AZk_Ee1Y(fgf9~Q3*o;KzC!rF2wx?9jqr8C zHwgcY@c$CNP5AGG=Lz2-{13u+37h^B@G`>LgnvRfhj1=oGvPeK4-?B-AcqQR_!VQE$ z!i|I>!cBx*2*ZRC!fwJI!d}7{;b#f^2@`}#!a>3mVVZD=a2w%v!X1QJ!kvVlC!`4( z!WwVl#|Zz1@HpY$5WUnhK%@ZSjEB7B?h{}G-i{QrdiK{)HffK7y#6V4|55aArcKP7A?oKN^+ z!Ucp22|q@-i16ctR}d~G`~=}L!sUejg>VJorwIwdm4vGZTM0?R)r4yZ{e%=@J7EXm zTEcaNR}ro!yqYjb*hLs3+)TKIa4TViFiO}%*hd&6j1%?~4iF{@KS!7%%n%L{4ij!C z{4>HV;Rxa933m}Pge)OPm?ta{3WTGCBB4a65S9s5LXFTM93vbjoFLpocrD=<2(Kgj zBH@<^_Yr=Xa6jRVgkL4RiSTQLUnjhU@Ee4;5>66+i|{tWZxeop@G#+b32!I7gYXB0 zcM|@P@GlAPA^a=CdkOC&{0ZUxgg*r|j{X^t3*w{v^g+Uh2p=XqMtGd?1mQ`-Q-qHa zo+dm)_!!~igijDYNqCmlzON1{IzC!pa;cJ9%5WY$H z7UA23=Lz2-e3x+6V}O?v&L*5gIG1o9;e5gcgbN855iTZNLb#N08R2rm6@-AWg>WTd zDdqzjf7ogtrjhN;pY)8{t91LxhJ3ZzsHi@J_Pq=_^ zA>ksz#e_=;ml7@`Tu!)x5D>Nyt|V+FBnj6L`UnGr?SyLy*AcEK+(5XIu#0dr;TFOO zVK-qfVIN_fu%9qVI7pZ#%n%L}ZYRtV?j)oMcM-CL9ASa5NLV5i2^GRJp+=|^RtU!l z_Yhu7cpc&Ogf|fGBiv7TBjHVi2MBK_yoK;q!b!s02oDk-B0NlZJK-IKcM{%3csJoa zg!dBOM|eNs5yA%uj}kse_z>a4gvSVv6P_SENqCCzQNq)NX9yo7e4OwJ!Y2vO5Ch! za|q`W&Lf;pxPWjW;UdDtgi8pQ5-uZLPPl>)5VjDmBy1%l3D*$%2m^%eglh@c5w0iP zK)8{xi*PgH7QzT&H(@VfA7PxZpD;-{NSG$f5DpV=C(IJ=B%}#<5we6FVS%tnSRxb& z6~Z#1MyL~32*(Nc5ME1o9pUwaHxTY4+)sET;Z1}G2yZ65h45CwNy6I*4-y_CJWO~y z;T?o`65d64H{m^m_Y&Smct7D0!UqVC5WTdDdqzjf7o?*iN{Xa2?@#!VQEQ3A+e46K)}l5Ox#x67~_s z3Hu3?goA`>!VKXs;da6-;Z8!Da2Fv<$PpF@i-aXYkx(Hl6KaGyVTEv7k1#;kPPi7(IC>qBimX@h(+z}I z6K*8zBHTo{nJ`Sam9U#IO4v)-NBCL7IAMZtfN+rTbA)Na4B?m!lQ&gCw!3b7lgkgJVy8{!sCP|2p=IlN%(8Rzau-lPJd9hGFo-Suf`CPhCK9(=nE7cPx?>+gzkEV|m@+;X& zE}t${a*blXhOfy7F3wg;%avNbnp&*am($r|0ZC3KZ-4%$&pK<%<}JZUW%)$4u&`JU zk|W!Ko!fWZ5Cl{CT(B=w?+eDt+02e0?QT&EFWD zs5F9XrW{oBxk9a8EzC9Q`Jhk_GUePrr5d0+`T)rCA7xMvHQ>q1(dHJ#T zz@cDozMQXSiowCgT(OW1_7}4GaxEWZP%^*N7E!G^X2aBbSc7S+L9nNSd^7bzrF>(M zFCe@c97AW}cd*kHVfpn1l`8T`X6meVHK;5z**4VmL{QA2QZ8ltmPZZD1%=~OmFgiUQ?3tVjhJ%B{ zQ!`^DhxQLo1qTmJ9h{sVO$EU;`Uf3>^j-RPUPh;y4|4f>rckVDoA1DI)=;xzE?CSQ z%VSux`NA>OD-&cvF0Mm6=Ziu!#Y%ZWT8LUi#Dj{B%?ITQh^vMQ?jlhR4h*cUtfUso zjZ~$&Fo3b=xYq`5Vr|eRm1;dGRu&ct<%P}oZ!qM3r55t_{RqfclL<%W{h;u~w#_bG zrRM&soe2LtTC0>d&sQs@piwOr3v;REOcjJ?Md6$L?qg`9EPrp-=&q1dqg*(iu2r&2 zc?`PN@DM)jo0&N{QYn}7S<=+ON~O4Yb1pw0WR?qQWR~QAjV>kkZG)Qw{7WPfQ~7$M zszhKB(A~?K`eIP82x$x-91E%-mi%T(GKgwnDtZ|XVv^<^?YbdiDrS%=F5$naAit0b z65A7+Mg0WmHkJeCuAe)qtht7TdzpE8NW3s@Rhm-Ml$ZlW_9GKwN(3Z0PG4yX`9r|G zt;w2YmGv47Tz=>r`L5Xpl^RB?zL+XkswMuBObnn21IMna4O~@A1Xp2VH+M3qK?h+u zU(Tgp)5up(BvGZlK>m!zU^qt#mybcFy3i7WMdTpzb!AMVq_5xTm`JXPzFzB3z%k520cDtN=lNO4w`1nBBgjQ zp+$0IGZ-6dwgKh1N$+|p?8-tpTWp{)nqQk?mH^Z(jT+T!nCJK#f7bFGu5A)pnCC~0 zkkZ=7ceV}X>*#7qKT>c_kocJdP?AWBe6g0->DQb#ieof~5{(ZeXT#EGw;z!?ti{ak zi2d4mq%W)%v-kc*8C;7bVV(WFUU}q*(JUAo8ArOBSxG9pL2>oP&ddW5!LDnKBKi-6 znF;oe&fo)@RIA5G#LI0kIEXxDYJ8rzzN937ju03$3(I$tjjsNE=F4 zsQsW&1@dzBU~jY|#27VMOO`8?0fbqTZ$Oa2bkefhP!MzGk^%~7&yW3HREnx1E|a9J zcF6>~4D%Hg4@s_?s?{^~21s%!xNiIQh-~szCg*yRDpoSNTC$qr{7vQZ6vUE=Mt#2j zhQv0_h?N8VCN!@E#RsM*6U2XK-S;CbWlttXo=jS*EpSfE=4TW5GjT+CDON4XWj28< zD%D!z$dMS~RWk*2-&CVqFO>45jFLp#5~-t=LOIDCQ8!6oq#m#TR;mBiCSqiB{eJ9B zjXyg*dEonm9NB0#Wp#SY6|!~dQnzxQZi2L->PU5N)Y=SNx=}6`N`-np*D`>8U;vO4 z((~n^1C??UEMoi3bHX$h!N0cM1fox^uwgl64tlPT$%V-a6 z=c017QL6`7$VBdoYE_v#3Ng7RNwr(rY{!o_?&FTxBHx3Hgx-%LZ|h2XM#bpPngsGIK`1@;BoOnzZx>ll)7Bxs4#ZPAUP*Efsqsl}s=*IkBHQ0Pd1E=p`?EjPDhnSUgxcghQMYFM>dpS=L;fmh1GM%8Zt>O6Q|SN zW3ALSWNr51Pz0htflBYdnnDSBu!DvMN_=QY<{Ash#6IN&5I~{5?X$!+o%qz1v?(DW zLN_XD9UY0??UWq{Dmda&9<#fpmN&XC;P%9|pQi_`eZ6`j%6h3UNcRQDC@5=cswWdSCbmH(2(?kQu$GZP0TV4o4)2cC)=p0ywk0+%&r~VZZR*#sZ5I;jwD;oy$#OL>-EGu0BwERE za-LSLC>c>q3mQ=;tNFqzKSQD&;#NOmn zoc@9t=Wu{(b;AIG1#M65oDU{$WsEzka(d{-rB6C1tj$2!F|E~!pCmCa_pe*2OSkq? zqIY!ACe!(1qqc|+lHOm&UI{CY(~@CKamrZBr!jfUE{^Towr@W9oBz0J(^>pSBaw4> zW(pDGeX?glRW#2mXp5ziA4*BHumX;p&lXgbaNA9<@s742iq54TL0Ed9i`~jv! zJO1g0Dba>05%poE%1gkMNDh0|4lc9}lH+do%l2BEH^Yo+W-*T=teru&n5n@gDOll& zKqi-2#u1t*qHAKaHBYN8_5csOWL1_^56cO5Ou?jCViZrPWXxLBVEMFwCA=}0!a3ML zsg{|8QBP&S&bVs*oM$R;4$KuRa|5MJ4F+mqIM`?yu63%yI_8Ac8}%s`D=QQ{Rv-?z zO3P8YXgsLd)5_%7{%SvxZjrO_riy9sKo~1l84Ik#U=5qVYJGr};+n&nNVl~)icflj zkcwMP!9Gt;h9FYOvc|)MG)x@}^>jK}%NOS%P|0waB?J$)v8)fhYP%wvx8w+giDR#%URMKSob1GYev8oeSIQG^#GW6aEv&v!3tvR+MObzczA3890yCam;^yJ8RdU|GRba=w+ z24s-J!L;>{I80r^bDo9TV|Dl-{si2t(O`dL@n@UdJywVy*1SZDW zm$fDgXS2zkKP960PqvLH)6n8=9p47=wOu@;UW<3l_yFSlSZjVKANVK2tttI8$`!3q z*wfARyLNmKk=w9%jqEzkO5Zg;gxIfWpY_S3!Bf~`>|h)bw%gTGW#q2y6xp_884UG> z+y-WVnev{5kb6mJ;|mcXHCJrpWnWc;ocl|6Y{0vL7+ai6GOz+Oqc&7xT zG&^>nky`BMB8)+b`84$xH~@i-R4*kgXR=F~h5Uih+op!qHr%UbwvH)l?|5g_5ZTgOO6MSSUmAGz)UIa8iQ+je!tq%k!xN&~4XHnY=7C zkumjc8L%A+iMG6`$PNt_G>Uc8hq<#A=zO#iaz%#+F&P-pp*LwQ)27BM{mwVaaz#N3 zcCsc~o-So*J9|$k1HksGR>#4t{EM%6gE_x&UPsPRZGUI12)=H(iB=m%+UaatQII8!`Ul7MhkSWk( z4Tn`UJ5F$tCV0cBC8WP!!Xmj{^^IOR439+OP}Rus$rqao;}(JER!VbGu8|r%aj3jh z#>tJ>6gThW@CX}4ul6kk@6c&s)v$7A{Uk?Zo|{1La`P{bM3Hw6!d72?QhjEpQC`zI z9pdLvv0EtYVF-Yj4PupG=P24}%)ZG+eHqulIAfVn+-5T>CB|$#(eeeg-}l-v7~E!e z>g>wPsogGOrwrnjpEkIf=T=-cC5~~bZi2mn(IZb4s#Q*^iCu4nCRS>x6?XI>Zo$bJ zACErB`4}SoEY==S8?fICWoT70IcLPR*nmYcST7VNw3*dNUeR9ea}bDiRH9LmA(ZHj zugc|9BI;9$xrTBX%@+9wvXpg z^)zPGHe}VZZYH%9k4iNq=B-N?O;Vdw)vPvtOQ6eyyEJJ1nhBPRRIj*ED&%14Q-G?h zipc|F|} zFqnWySy%=e2y=oC*sl22@?ZCHR;}{1{?OLaZatmIRV^hF-q&49x-aOAtXlu=<*Qw?Y zf@P*RnliZmVGB&yptzvDvG!r%bX@g}TKn8Uwwrie2Rs~UT?^dODGFfSHRy#6Tui?(ti`&RfHlWmdrtJ(y6N+oZSJmz z?2XqcLU7Y7s>^wi65@*`#S(GMk_U86<~rn3$iogM$)|JPi75dwL|w zjDrIssCxax2zLC1`fhcTkkqJg9_fUU&haTqPzD;h&Q~sA2OnRFwnDceRgqOAz=d0! zDQ0l2$J&^#K_jSbC^9V^E94ru<{h@i_~N)%>vn-EJhkB@QB_mOGnp!HK3mwyBfgeKgG=(CbUB3Bz%0HM?=S*!(tu zGDyHUNb8K%&1J}w9$dsNE#o3B);zSr3#59dP?r!_pQO#Cu9+gs8Wc;Kr7ogP;wgE` z=~*)!cj73`&(!6UV;V$jXFpk&lUn`db4_EfD=H^y z_-_|Aiv3FEE`Mck*cjFzepQ15qlZWBGE{;)%;BPyv_MRr7dzxRqb^*1`e3WmO79fj{)PvKq5kyfrtvLJautkC}# zt4MBI#NmbfL0=d0$4+j@Nfq5x6s_#;MN>?0sh2s0h2BXG{OvD4%FuPuPBSo#6&fC5 z_-6-oLl`+*Pv)Yfd@8yq&-ImOB$=Q|n?wSJC@R`4={Z}^bA!QB{=~pBYX1Eb1ALFx zYNcN=uW7v(XS*aufXsmOC=jIYXX4$!km3+&2#zM`kjDMFqYuA#;sdtG634CQ;h@f{ zPYL$s5@nKHM5~z0lnIi#*`*`UD-G!{7@MevvewXQwv=VNINPcNFLS{Jt8?`Fz&-2Axd|Ulu(O|Vg_g{426eBl~Qi4?z z$0%qYMmHiNsjjpgn;4BIiG@~F#3yBTPbND7OXfTO*%BOr{nC7)iVdCi3-hYMm<_re zPAf@6I*wICBXB5C)fD4FNW`BiY&l`nqq8WrI&YDiI~+;XVumyk=Rw*Dn3U=t4{BuD z5eQ!sR%O>@<1R56JP1vfZeg*5(5MkJ5m8=aMIS>BbAX!;@CC4|=0Reb*+iw7gP6wqB$oG>!91mI><(p9DxO&5ey3)|!D-yEOy9mX^pJi&-7HzcA;0 zx@1MAp!%+5-Z(_ztYgT(qd}czLERXurPKN#=iT{Q7T4T(`%jJz!MtRZXwEWTGIQZS znRnQPhH-~2?W;OLRI!C(IVn<=6~C^p5@p& z->&^F!Ty9;$Edb#dfSSHD-;Fa7BZ3hf>4z~iVnlORju7bb;X8^*maiBr^n88MTk=) zDDhM#rpFMxYBx{GSWq}6+jM(WmA%;TK+hDftT*~CbnMEEaku6f>Qy9~p)Hbkw_?_w zeGd%4t5$4+wXK;~yDqajR!=7B(iO2X+fp_&cu^*G*LfOiQbR-E2X-{g!fikxLw5q&|eWxZ_ffLK*}o1AUR z>^g#8{AdK*P5~Ri7IwP!?0cA;UbSKqrESePQ5-*xFS%Ye@xEn}W@7dt$I5I=&&=R^ zGdaC##@p1TJ<-s%ZA{0>*`=)0H93WRtOB-d@|c6C9I`OEAF;hdt2GU5DO>e-y&myT zBXyIu7V?t$cA`n|#<2wH{fxJ0qeZQEED^J%=`_Y1-aappo@JzHsv@N6l#DH>yZ-TY zw1TWlkKMbOOnBNL=H{*E$uL{)T2>O<%=bX}SxSqaB5!Y*gKDX~ z{#m$NF4be&g~djOmF7-a+R*O0*9+)Nl_P45WW%sjlyTfJihVGww?o5H9er;ix$`GE`<_ zVQfAuG!vUJHTR(b9{3RbO!zgHr&E}~y`wXsZwikzHIa1Rsw-|+bPvUPdPg~O&g1@D z%(M*SkAqJ*Q^h?uzmqthoJA4-q;zgnDVNidNY~*EI&5bx&5K8^bkVDjeh{f+!hv{R zrT9kWCi$NV3Gnj23=75<1B?x($U!_anIb8}(5a5-q-p2hja6f8|OlE*>0{G^3 z5jcAk{i&_N31O4xwUGXsP9!|boe8rS3ZvrqwuqO7z)3tl5wQb~BQDE>#2b-OZLA=iulG!t!@O|xtidSBxHpmnYa5BKV1`vT^~f9Qc81*M4nGF?@BJAM<6 zA6w)py_MKnv0j=X_o-ECmWoCgK}naijbhgQH#tFL*XfYb4KrH zM++`YknG_>In{U4mGY0){M%m8@x`;|{JEs++9da|I_BF>SrKX}S~3-dR0m~+Mi!k# zoC{(?+Ez#|&9W(pXzH2PEoyRFr&lj`(`I+@rfIknROTca$XJ1BV^0Ml-YS#2r9ffL zXkg4Vvb~L_Hmkd7rZIkDM`|Bu>}Xwbw3hf%m!j1aXH^M0Bp|Gqk|ZY5hI%KART%TM z$=2>zCCu439Eg_8^-0j0xf5(j8WaWauxLzXHfGXAT)wK-Z@Yq0v;n}MzN{a16N_jT z%N>vEsf^{Q4E)(rhRu3+3nc8g+8SoRH}jkCh)=tlsVy8V&K5ToS<=%>WsyBSi=b2R zt%++((Os?TJF@N`1@}|q@GrpS*0}DmRnzX4>D5=wZWERA2e-{F6LsV4t0W!slJe$Y zGEUngu+uM9_AYcugfx%c&d=L;iaI@KZ}7siiu~M#6U=1vu2KmO zIiV52tJd{MQnTAhdP&4wb#JWQFNw7qMA1p97OZ*9;~UF$Et#lKFXwYk2h~c@rhbAV zUMbK-*&cOHEy^T%rD`ptS5?v>q&B;Cxqj@OTW`#dm&E+w_{S#5F1?9K^>dfer56?4 zw$9_F95t-gvxg#H3B@%W%_2TqdXsmhI$c*v(N}2!a*4H_;LDyDJxpwgZhvL8xx`hn zmc?vcGoJ-v>N|aisfg@y=8jI6GhZ}D5IUY)KR1w5ir68%>HzI%s-7>w=Xj=iA_&XE zttEU}*sv`VvO428!qK=z3TJmtwf@16^NDrMt*~Oo4eT&w>gh9 zqbqTo{UhPtp_ayW(!5JwCcdaI@WOaSFLXUU4cF6tAT=Nscxb$Uz#sEcs?BW8!k5N> z72y}Dnf-{kJ1|!;7U6;MhnjMyLAM3|?)Vc3JkK-Iw}6j~KZ}6P(M19K{-4IbgzrBZ zCU6%*E%?7q+<^CJ;%$M}K|?17H%&}1_(#3gsBM--nA|jR7b9F0i=Z|$7G-YJ#4j`# z!NX(=e*LD2-)SyFH_8^_;Y|}yGr}vpBAj+5?DdI%ziHyRPO+l){KKY+|IS$cm_y{X zlAhl*asJB?>JKcJMGO9smreW(gD>_f63%RklYH64t%##8$GvzV2{icBk6*lyoP2H9 z$r8}Mb0x^Hs!~ZyR<1K8pj{_Q_jC-EE^aAHCqv6;9oLr6R4|-8+WI-l+wTz>ke0|g z5c0Xh07zJD0?3#4Gfjfx(?~wGn z7=J#xf=}oxT+64ZgC|}}a^H|Y_8vGC=*90MOg855S}E=$LY06E>+mnJ%rCV?aY2Y| zm|ze54hPd#gJ2IIh?MtDZw&HyY6eBvMhwn^%zuRCN0%+gBblkQ+TsBiH+t!E0WZ?S z&0(0beaoW;%C&Y@Wf9sL)Cn1)ea>qluK3S4ihU>voe>-!o7p#cXeJmwa7S=>cxr0+ zz|0*t$_qMhA{t;fP?ko?BRgm%dKK@?)cN2xGME^h8rg>w!?%v@ADg*@E@$?P%^Vn= zo(}d*P6flk!QrWyv5`ajho^#rhol>@1l!fQsAntQegkIlJ1 zu@MjtM^w{J9oIxh;*?w>TJv;7A zq|iI?gqn0FIpI5^3{=DjZgyHxin2LO- z44ePogAz&I=UL)@B<5jg8ISil>C}TzD^iD6t=#g5&g5B(-ohDdMTU4rA*? zizw6WsScw;t8H!VLQI6Y{*2;@`%q2XJf2!_|8|3xA{Jt_d*oUP-h&R( z!|wJq?8gj|iq+~v3H;5W@G8n@le}8(pWNGXl`OL$nHqrhKxmf4pThTTU8|Hq`RFwC zOIR_A>BjWE$|bhrN7!R<<&BBHYW3*x`!;g|j$Q&U?^>DuI(+Pf_23VzczzFUhi^%E z^BICGL9a41@H{p#xqEcg>Kw#$!g2}qI`cKRTkNb6>ixnL;rY>}(eT z*W+A9yA$MXXiA6KLIU7^0{y&dt>xs^WCj>b+0ZzTr4S9o<2E{0$ajmlSEKzL7#*fl z3Eqe~k7dmdpIzp1+s=hL=2;DXx4G0iw&O9+IAhp~7&W{cR_1>_E;TwaJa%CB=u})g ztTSRWwqp-m1XfGKV z4NQA&FY&;1phS1Ud3q^z0-5{mggj5)<4WE^)?3e`JvN=!{9;ebfe}1{v^=%rGRKCi z!#g{UXXC%EcEfyxSRDQ2#o^UlE6L@< zPhJd)CLs9?V!0UZlNU=3?WN%^mVNRfp$XPCVOIR)#VC~MwpZQ~a@okID9UMkGRKub zAv7|jv_n_bFUv_&^!yAS=UKyhIhH@$%K7s>ek=!S1wPZ`gunQ9P~MSR>*)|=Mw29m z+?%i16xt3l6Ud9a`OrVU>kaSqk#GyiS(L9~3zITYskqE$pKu%rT}d+I#>#T%GL@liE5$1BwhA5>p4>e-804!}#+akR z!`!dn3=0(tcP~a7p5Izh1G9^a&ZRynxuOM=Z)uk^9`{{J#G*-s+>t*YPh(fW*{2kY z)`XqH+G~SR)3ATSuTd?+69HrdSq@@qr>AagSO#9x$YaClO@k<s zYg^r@VvJ&pA-HBJsKOO_qnuE`rY^Y~_crZnO)j2rqMix~rA^|scS@MssrO5~(P75k zARAquo{GCU!VcrV>NTf7HvZ_Uv4W)AOY|+L5@Ykh?dyM<_PUDb}drXLw+Mzilgrzl^+P4Zc@>PO>um zXZJnBcaB^MPOEnH)!A*)qY>6pXDlDC624N+D$_bgtUhWG&|<09m5*{mscn?KBd)^h zV{F#2jmum@WM|y*Itk1idALP#5UUClHKvv48HF#JY73&cP47wKHSh9Ps8{eTWUc@k z#yZ}wr+ixus0soxP{P1es`KwTyyc}2PrB(V8yT4}aM5mSsmfGTb13J*aY+!W4OK75 zlN4Fvj$z{S6}I?!KK0359F#tjMv~srYO~~?L?IW6kF)&M#&>4)z?dI5oYrlV*u?S^ zxKHg$uo?IVlG)hq#y-0Ml zGM9Ei+ag(*M8<#In9xUZyJRk?T{1@r?b3x|+wOJxuW2}9mQx^Y7#Au?dCU1M-jd7W z&Tg7Hd<|jy%s@F zGiod6MPd~B*p}cR9G%O=EAdqQ(4n#2o~8cu%<#;iX&F-P<>W0d%{wN4;>jVOr2^l#q~CP*(jM+E*_HRHlC2%M>IfKxBo3< z_14eK-=tM|V7aRQ2610~RsW7xx<6jUKg2-_+rs5Fz#rN<{E@4t(9n5SDVew`n*ggs zc-OU+g?9Ug^d4))uQ+SPaEGfS8BI)17LC|x6_cs7;#oK>C2R{Xf^%aTW~pYj%=0KY z<=T*$We$BG%gk^}9pJ1T%&$_$A-DO~q`)kchxHq_Fg(T6y%fG1@mA$**c=< zr-Y@ajAw;AY)B${;IJRk~PGl#}2L8fJHqEbwAH_szAbWruCgjPKx7hyJ-i zdpRBg#pFFGVDvTeoz2l~XUx|`bsl%zl^egH$OWp3Oy=#WINr43decw3zDYWX%5K&f zb2D~zrM*iJ%@+)&^J8m5pf)dAjIX?P9zNO?*#53e+X7d~UD^XrP4k5X2tW78PnH-7 z7V>%mwwKg!!x$~vy2hmii-7mcygXoFm|aBLL@5IsplYPN3y*+8ZAqAlU+4l5)k)mU zA46B=C>FVx5;3k^^pj{AYi8PX7w58R&$&ShQZLbqw(>JG-uINF+N)rP?9UhW)p+C5 zBTBLK@rR`oYAUXlZlB9ObeqSyMxmHXQ^<5}m8Y_t!wsYSG*0$f8)_2cniQea&?iex zV6<1Kp^a=&z0EmZ0D*lZJ8FYTzZ97Cy40YK;bN?VU5!Q|cT+ICiwe1$mTtB4h#3lG zV%`iJ=-&O(zg)?L6d3fFO^2Bsc*2>paC^9%W^v(RIP z{1>ZjoWpwc*|B}+bvjko%wz|U4K7&T%=#Et*QQ}v37c#TGu9=Yq-f~6TN#vhnrYoM z)qp3$l6Dl868WgNlyg#pkhg+kJs};gakLIGeraw`9J^HOjn)dShhu`AVH^Uv#}q+M z-rZo59G~yweXrvtN=(Klb<`u~Xn`%%kqXA}{-5o17s>3vbUcp9E7_rDcs=aT3SI{X zl$o@4j-dti;*+6QpXuKGZZWd!<}%&QaxLfd%<|ptJprdzbkiJ5oAR3tMVAoH55R<1 zy3z?RZbEg^8;Nid^JoXsjpGnTATsAgWU7>Lv}M^?pnv6u$H~x{E#fj_$OEKvp~=?W zHD8jYex+&6Sr4PIYP@)iLJM^68`k6$UX!l=+QO-F4yqVW58s$l<$x+h#T+42UV5r? zBa{u1;Ri%yAbqt83@X*vdexL5c6)VhMTT>1}KHhOZt+wmpjsi)d@_!->`Q zpG&rywM^T@{OB?Wb@_=S?&Kj-Fm_Ds0@~&h9eGMOxVT;a>oRgepeSoSRcF`442*`r zwwb1~JE)gBYJ;XV;HkK{)^#PuI-s4CUCW4tL{5BHaj)v7ZL#)h1#(0=zJ1sW3CUE5)k zOTHfEq!hRIt+^|*-7*{3-es{~*%gMIO_nsZwypE;bm;C_TGKln+4zyP@|Rj`@$1pl z^)&sh#Esei12X$N#{=s!+?+>nD;XU#(m9zdHNi zn7kmoquue=h5}G%?gv0(AX&v2MkFmrkdqXIC9F?MkbGXeO*o7DKAH2vl27xb_YP*D z@ArBChMe#NA}0u0#U{NR@;NCPR6(6S2}PGsCmKKukkdVA>s5x(jA)vPD+6+$S`~K8 zLDExWA)FM8j9cmDJYWSmIMd1XDE3}to+1r>=`s~@xq6;cBSrpJFCV`Vt~Jkh0X*t4 zw?9MU3-s9OLSW>F%d!?$7=Itae%OU^j9t+C$3N-^iEW^z`kV2uAt!No7x)xrXv_HMS8j^nzTi}wdo%D-r6nlIjoWmt$Yk?@5m$`)d++i8_lkw%p+8b zt0>d^!By0WAKGvgwc#p?8tT$Z!JQ{&+d5oD8AqsMrRBY&U_DNsY|8ZP^r^)TMb%X< zo6hc?ECv_!GswLYWj9ZI8S}j}1gma3>q+qbTuVrQzl1fL=edqplb4^LMoDDC-s7I2 z2xk^~sI2#fntE^z4t}~QOtoE+t4Lgg9#Dczp+Q+Yhvqi8%5s9H^AkmE`4$})zxZUF7wP23Iv=< zJ*{!3nd02ZdD#gEcte#(T0Y~{_o51ObRd?s^2Ld*p_mm(XZ(a~iAnx9JSR>JxIES& z*r}iN<_Cb*EZBv2c6%4>#L5U9$d|obLwo}t##>^f+4%x|#EUht{)KNz72_b>)*9G; zR8P?1&tj#NU#0_4{Ovs&kl4nX2rNQ#I^tOokv>dDybAtk%?ZX*s$QtWL;!9s+-jAA z%|J0JnJi&e*BW!RJPgdr^|ZO4O9YAF>LAIxxl7xw*$MAB+9h5Ica|ZCwg{JTu0VFX zR#krsS70X8y=KCz)~$KPT!c>yc6oS#Wq0{!xz+IOQ8rKG&Gneu#`CuB4G#1ZLce)eU_4nir2{K71jjg6_acv~CirBudYjH8iE(Sh%5tMODoc0m)6gd__ zKSi0GMtzQ}!waR(vHTq=oEh32*JzGzs}vh<)#<;e#cy}ZwynJ~$BNk4xpCH=nL9T} znxukLRpn@2y=rt?Y3@baIlVv!bmnr{x-^tYBMDUWB^HeB&W5@KF8~VB+1!X!goE5- zX^?u@BO4mTyR+)0x!pT+;^vy#0>Li* zrS9`2*sagKX-i_6H7QHPy|J0cYdmku99Ns5u&5`b8f04QP^M@(18iFtoeDEww_ZgO z^TI)kaMr;S2@}Nc_MURXZie^`ue(F_N~uU6aqSdGEH-wfiyu0*dNrp^Ov`_|z13VI z9T-EZ>=J#wi9c7r%E4Hg9TghBCnttTcI|J38O^03)wQzmUPXstxT?h#MrA=Ld^OVz zVS#;rW(x}#cE`3-r2n{^&-G6&I_FoCt{#K)Vn@u}=qhpWOhq?l;sDKiUBQ%f?mcMO z=+x@GZA5jN7ma=EowrUDYT^gia_8kr6V5GV$OxGbo++S?=Ziw>Hl3fi&iTF*%) z_!i&Q>Rzk0M!in$-OfRi)_r46v+K|7IjuwPrga->Wc|}xvu=0!pm{=Q%+*~A$+R@; z?Qt6Lnc(CD=P5zfV%lGr!aZ=l3!s!}8s43v{0&1W(S*9+qev5G27YJ(#qnQ8z>m1h zv^^Gf|M-KZFpeh_)o}O;N|}>K{MRid61$u0cJmRilFi~d+5IGy1cs6K`W5*du)eb{x` zs4M%C&WwZ`SQ+@Lermg)|0b2Jf{wS3nld>~`bf;<*gYs!e92abyDji=M*D%{hZC=g+)d z@|t@{#+exDnmwC9@-VDT2GiNad@19X-dui7Vsxnko9We_t!ioly1z})x57CT9tJaW zP)XL5ZcbygOH0#&Sjy%yiPsEQpdpt-SyM!Qd5+JBnb?s27TO zMg}({legb|{)TL@Asc-E$_94eOj~DNom-U*P|D6^miVNK(<3i7aCuDL_YjvewrE-S zN};|O$q`g1mcXJGp3D;1if))%XJu}kfn zha!Ss`sNGA@_n#{vLf-MCE`omrX(%}6WD8(PPuK}HCqr?R}gDi^o;z1ZE96sn`BqX z7luIhBLOMAa8Rfxp>W-HgsWx&k09{jO)62uKNhv#$L;bj&~$Td{Eq<4cZ%!3_E~{02`HOeMXk!xRQt^zhgr9H>|ZS_z?ot-)66 znpjPJm7!k-HA;3L?F*l;NaaVAm>^Y zyu+HU2hi3*2dU$)hhr*%4C=#erc()z!*~;yPqtQ1c*N;apVmXhL}uYLU=|ICe$tGJ(X8O(mpN&h8@H3yR*{ktp88 zanpqSzkgQjga?nov}B%+G;o)?#De3XR*v9M>f=5 z3hs-gwqI5WK7%SzBU51gtrop)3B)fH<-$g~Ly5hXaq>66zG>50{6{_P4`D%vd7WuS zUooDbm2GSRx1cM>`w(<-yOqgeq{d%`7(d#=Yc2SO@hJqK?-PiH%#5c^9~;(2w5c5m zldyKhNI+8o@~yc+{MhKY%fbfCc}A&n1BPwa-g%wmii$q^|h!ZyumL%q|z{U5RAGC?=%=BGs_q#*hRyP;h zes+j#XD%+XI}~bPYbPdXBO`sz=FKRCUP@vYqoa2wYcP_HcZr(FCam2E_Ikj=Tq_ai z{$v|0)LMl=uYDF~jX;>!92X{%4uj+m=@n|U?zK0tOPNAh6sXba98BO_C@1ER=d(~d zaTCsT_NL(}+DcPqlc9qZOoA5?Mkn7@2>dvBYIan%G!*HM&$uLd1^fN z9vn-L>WtN-)tX2piXA+Mec)`8f-S>aou<-0a+Rz#ErnbgmroQc)y(k}mD*Sv6Lwt5 zpQ&XmFm0B_?XT{~+W5+irLkJWkhK>IqP1Vhm#g$5ELmiK!lhrHNYWP~=NrX7^fKgx z;PBYYzR5!~!SI1Qg2Tg8Q^N;l?zmBOSn$UgnNu>b)80teo-#q_GoBZG<2 zsgZq1F?{RT{;`=mDEjXin>jE#Jss?soC=16gTqrZV^Sq6#x0H-gW*Pfu~JRew&A#80&ly57woNOvW2B!R|(r@{Ba9JGi(!6n4~v> zz;*e`%w^q*GJNaEM82NEwt5azE|aapL*Qa1x7k)oIC0e;YS-cZk z3vR_c+Rq6#!k@{?9DV!r;oPF0kqARpnDOpgnu;U?pb9AsyJomYN+;nPbKcuH^JmHm zhpCjffJjMslk&GSlVTpr*(wemvKg2}ArZXCUV<+>uxNRLezehh~rxEq2n&htWwNvy6|^ zXJ0R-HNib?h8Zzpmf(k%0oG%FVHwOPsv&c>r8Fuatbcr6mAIJ#c09w#OZHHsd|1}+ z5xlwHQV(mOSDmP+*0yA^-xGrH;#&>9vAFtbjt01ei@Z&Zo-T>c?XdH00sg7+E3iYp zv?)?J2`$!7%O3s5n`6n`uqaoKUxkdCOItQl510ESB3;~^k7rzU_4qZ2(NdC7qh-=R zo1Xz&!S>|QQm7e)Qj+}>-)uSeon#3F>GVg0Ah!LOTX^Ky92061rXw$L;v^)GLq)zG z#aZXnMV&=M$c>p|1-m~vVypAPbZmWjJOSBq%rx*d$e6o$U@|x`u(Gm}S|~SCmFfbn zw24-$HgJ=Ufa%)SA;OtxhP{$=vWgeQ!SL+^&mQ(83@dA*b>_gv$jNiLOg&F03hp=W zN;^r8CM?sOX(q*C(de{3qYH8k%6X=E>w|Q^0C!C|GpXTm-3mTtzs|Z5vuXwQ43BmSPBurp|-#R^c zXli6My?c0OG(CE7a%A6DuJ^bmkS`xAR4e89st>Q8$jJ3=D*U5S&r&tT4i^@d4C}!4 zpa1yWe3a{Kn{sKoqj8(>BJpddlJOm)u}i11fOx#6I?w7P6Ib1FRq3kSRr{`*@a}d= zuk(Q{G$(P-_Ip$J?6^0Pf^>x|OE@K3@rKnCkXImg<8>(!x*?+TI)pdSTLKU#2o-yT zmSJpBFBqLW8g3qTQzwjxwo3%2_&^|jxlv-}bJ$E4^_C!ep;h_{qc)Y5LIx2naDL^h zDUp#AY$p{#sc8L?bAPV`g-ghd4(kY5LJ*O2(u#=@bg{Y5Ns+50!=zP~p}Z#E(Jh@}42hkgf3A|dKMb=Y>bw0&*TIrKD(dcMtR#m) zk~;+#-5N67W>NDBIla2jiy%~DGGc1{R?3J`sL6;w#qS~`#==DKYLk~rUhM=e$X^$@ zSpoGfZ^c6Rs*kJiWnVf}6us>6V>^7Gz#*}8Bc;qR? z>`y2rU_VoXEsdNz*-UZDHJ#*}Hyf9=g|y#aNZoD2Iq1&B=#2U)IITo^(3(J5*QlrQJp)(fkvxU73aAG~F;7M8aCMQlH7F*G#{^N6rgxyo>ID6;OR>_ zS!Tfl8paJ{Lh6$mrf?A|?UJPzaDQ<*nFwRKfSN6{E+CdFndn~@>$H9oB=Li8S%wl$ z#AHX~qf0$BQ*GeBCH0h80)`R?rzUqF8kt$8jAL4cjcr(l8|y+2yaveM?NZd#=>E~+>Csh+;=xd&zh4jL!jkkSS^?wI zLcIdR%48{XB7jPtCa4(a5=gKBtFJ)B+ihKZ*oB=u1yOo>Y-V!m4ip2uGipDSP|HMo zaAXb3sTiF!4>USunI@(>zE;m%nHKe7T`7Yi3TaN-DL;%ACbj`|0nHs!LR~R{r2;jG9Gxy>p`8{*^*imw z9^g*xLH*et6V33$QAT3bhFKc1iuFhEw&AHU938FFk#kzG3c0J6g=o@yJc3yWARr5; zC7Xae7R49ese7>M|!=nE=0Nv19}sfa50uC^rWALJjf=$8_K1 z^lB7U(0(YCvHvd?VNFM7>nbtZ#Ve*8kdQlur5+p}86Vy|x@w;}OT>j@Wsa7zRtIo! zEFCa2ZD6T_<)M8})p6#^kG0fljK2HGlW;J3u~RQL@F?E*vc+)sQ#l4>`xmys{h|#J zo5*NryVI9am!!iAkzIuPBn#<{T^A1XFb=y{o8ZSP#X`;_s9s7%8i;3sqzenXZF2wE z?$t^wWwI3eP~NGr6P3J_o8&4k*X~r+Uk)R#x%hdS%1bYif32a!#xnH0IVN3WgQF5v zP>;9RWxGm?p?WeY#_@|p%6KM%P^q;EH`;`Q5P--GT;{9P0Zc(U&h{GvSY8M4O{=jg z2b!rY!*4hAaPTQljUAlU2RZB!vJ@v1!762EaSIA2rWAx-2MB$ytKGW~?19lLGK?ya z3U=#0N-VPCRZOim7gj3OrPEcn!^kVD7L2s8ov32TuLb@6=J3YNiZ$$XjnWI;sxtWmOzlBwj`(%zc3XX1l8%(3(`I)?%uF@5XnvgZSfvE83WKRF z;-Y|Z$56tU-Zwlox_fL2wO!k~cnSOW>4}so=om%;+F8?>(cCHM2&> zOrdVDzvwAu8?OsmpWEkffFWW@Q+WB)SrYJS1jIWbfi{DSV}aW+G&&a~9ke+#-oag4 zREFm50nS?HU`xX*#=K$LQO0!RYw3`!{WWC&wTiZ_hFUJ`ny9r=`{hVTMt_S<@71Usqz64vodzZ~CGswsDmT1#Bx`O$vl z7mTSQESO-v9lN@Tu6fMHt#BGQq2~+7({TM-tqmn^iRS*yBCbed>gRDPQExyhz)g56 zplT=+EDlF}AX0ZABgCSk8D|MDEpDq@T04w#Ddo^eB?wL5!VyaF^#Q#rk0%_x_}s7~ z`%{{bBYm*HBD+dY*Vq-^%EBVNbZUiRF!A;qW&(7~%+2KP)tfnAGYS1vn#yr?tGUSg ztCx$lv53=K*~6~Cli`BJ_EWOMeE{Jrwg_|^fJ})x-czba32sb!YVf9eEhRlq90UdmfOp6}-zIi-%*S%$3SFgp@9dL4=iZ0YhZ zbUip$!?@s%?eIPn*uxlAvZqRqlkgOStKzcB!ooNP$)Ny^4p~xPzW*gQDka@}-6if-ZtBD*#e; zlZRJX0jBiGg8Nz)@9ZY9v|&4e&cy9Wxk@R5kTb%-flJ41RT#ugFkCLps}XZQyGlIu zQnIXK!-?|%N@Om-)f;HW6mCD<%ee!0x};{6grs%k{nD#iBkm%?y&M*eV8$XNNeo2JN{3Y`E9oI zYQLRYrIA%pi-QBf)?=0KWY1BD&d9DuW#6dG1Oq2*T+OqFrzTeC9)(msg-sM3hs2NHLjjRp_2!%?+b9OzslSwR-g@mn2FgM;~Q(#2kHp9%t(!7luE6%QsSbl zd``B!xm2OFu0&Z>gJ1sPTOlP(6a8m+d% zz%ESa3tb1z4Qa4Oh98d0s>Ffo0pXzoIeLsnPHXGk87TH@mGJOHr-PbF>K3E}hwX4A ziW;wHB)T7wcCCoI-%^!Ath2a*fofXA(-Psd_TTPM6OTzEx2QPWS{&B}V=tsHPE9&U zOsz^kyY(zqlwHh@8ht%6=20uN4M_>CQrgpDfSf@=Boz2N@Q|+LOul2kXcsoy3UnyZ zw@ru(yml0`hGM$4EPos-ynaeWTd~Pb%~Q^oZgnYQRW#bP09B}&xVo;;3VIy|J@`H4_@4$$l$BmB(7X>3#qg3rA#w0Pxm|!nW75VI_PE7B4IOS zzeHH`q!VdaR}jYq66TS+`0q<@3v7CF4Y)XAB)_!mHyr zG70d&lc$$4=}Bdlb+WAufv))86w7$Nr?r!t?V3C z2>Eagp^kDr;W};+f-Ni|wG#FMjQ?6^yLQBJeYqFQu?^im;=c`-AG zTX4~0niw|mzKay;b?1I2=cwWiJNE&m@eA|gCT*+Ba%&G{sH4lH!2V3Jus~T*R?XOf z;P%cEu2;7ay_Jyh=Z4(A!;4@%E~KMO)-MwoszX+k(+cr~N)9%G!^56y&5C+m*?rI3 zrlMtIby7*nm6(wWDe+I^e!<{}%t`jdp_6?6!u88qFEy2nz-duW$8*9Ru`X$hVJkzp z6n3*i^%^o9UhDuxxPvKI^{$&6jPhdsgbI@C6DTKb9Nv$UQs_El)em#(VMJb&t*q?y z8tJd_y)afI9?8arg}NWx-jd_ussOIsxFMr?6XsuhndogqSkvx%)9;TVfr^QaYI&sQ z&633NyL)3byi{q)1E{LF7x9^1DmZ?3Ur@ZegstYn-39DBDPGRuubtqP*lf7xCK!>^ zo=nuF;$9|>t9|#8aVgTF8jDr2w!0$WA086@k5sJrhL4WZfPm zZW(tRpQEASVfDo5gkI=sUCDQDzwU;vEw_{T3242ky20L~D4HEr3!6G#lrAW5Av1RZ z<}_|Ny43JkcDcdrQEQD>B@U|*Z6s6+B)!vLD=j;Zi>r6gu`;f|bX|rV3C0V7Bnrjd z30F`m$U{CrWsF_92*01Nl{Z~gFu!`16TIXvH zI9M*5T`cvc)kjM=wzi}0Vbna6V#h1lHYX6Vmt*Hhn*Zwcs2nTJ_fsL~^>bpNQL7G! z@!~)}x3qJBkp_AsE7~N5oo66hRrSi07rSe4Enjzi9xbd|U3 zL7_9F?`D_Mt5~N!PLXbnM*8He9R{A)&|wwib+v3SqTO4^NuaeEp)DxvrPQ<-yG1pi zxjiU>r1k!Vag>*c1$o@ATbzZR@B0Bd`M}Ge+B!M@Q{%r#M_`f3_sOFJe+^f*_f6cm z$$0|v1H}_qJg1}T1+2y0SIh+%HSLuuT!8(@*K~N#a|gYxZagMq7XdaLf1L@Azsy?~ zOjw-DR2)d#uQvWtDY;n^I7PL;sEOlZ>V9LX!7{~n=E5(FeDK!&!uubK#loEX$s1Oi z;X#)Ca-!ARBvcWqVg#JaGd-`VcQG2Nq(X(DRcpp>NqbS$EEGy)o~To)0}G1d^|W|$ z4zKLGx-6eq3QZlctH2RVw!s_3{#hDDXy@Q8jGa;z?urNvCJ%}quh!^T{b4p)hS{oB zYJ569y$@GgCJ!HIjcwD%#pQwLZRYpYI*|hTe(@wqGcQpmq1WcHv4(<)J7eEy))gSE z(`7mgrO<9jbFn~q9K^+7sCuc7$FWyta9Cw+;fKT6>%*(BSj52PSECI3h?(i04>NNov^_(91qP=lqd9-nyEeeUv2a5so{}BGwI!< zdxj6~p8;=~h1(k*chUU~Bn|$-jbRyQ=ed#&i`-h^Rtx#!QY^Hu#bP#x>rHBCDC$eZ zZ!2daSKI@jn3Py9o&ZURrVwAD5u<^wUBbi%ae1%xKv+IgEuMgLuq+rCHEekHcIwc9 znX!pc)Hxx0?b?71Dvc%a?2$h0u?O=H*G406(3Iia6|iASS4doxo27Pbtkx*t^>{Pt zrb3hlreH8lBP`Mw1QQzj)|vtt9n(m3gQ7MLcYm>|&8j%Ai1CG)8Ce7WXDyLkx@|t} zyk8Fml>)(&D2~FaVP0xOyMRa4-pOxj5M0Gs?5iI^}NuTVY zJiz%f!#;@LWc137@?8DWxhSi}~yl zdyEdqp{r#3T~ul=KYSBy1XOc=z=al%ie zevUPR$N{e$R#Cz3?}H}OKgy-GmdI0dBCI>E)K9>;vL1{uRc*G*Q&zLN(-QY zrfNhZZS>I;PD0rcMIt#gby6}hQ>nnJ1Ft5x^pA86?<4a%a&ykoWz5h5gw^12q8g;5 z`XZjoF7m%{>&}HQYzTb2;yG1E6WS~zMlT;FNjOZ0i9vQTDHDb!yiKII7i$V9yRL&! z6XKQFCVHZvLo(76KZ_{s!t*sc6PdA$(g5GmDqMTRt1OQ=bvgRCMHd9%Ex}$DB{4>W zui{zUXaKCK36`RCWnU~Nx(6o~Ek*h&f+a|e?ScX{C|-X}JtFi)^;9OO)WH30$nI_=$SYQ+MURT|o{edl#;&soLF zVQ7c;rX>)y?oh%Mr}SM(ooe_Y92s_q{fm^HLkXxjTR08h>BZI%*IB}rVD!T)(qIPI zA4|se@Fo|(a6u0CG;n*wt!Yj`!4?Wu-_40gv4ep#4r1J}M6k}#B7*_0>zcE0-v{I6 zPWYSe<}}v%O-a}+idN!zpO37IEbBJj>^o~N9qxwXHV6$meu4$KkxZgHw&4wB$oRss z-NxIm1!D!ny=b)}5!0 zRkPgrYH68c$F`V-6IXbnBQg15wBrf=#vG`^)>%Q3N8b+-t5cFuNY-Sd+-`E6Pzn4?}{wO(1K(_wM&y|wd|uL|J(5cga0JPN2&igA-vIUlS{ z7;A`+*iwm=(hv5GOeFHVR1oy4bM~}Jv@)zLa^6tfj=r(FJP4!Y0P!f3OOkf4zIvw? z%wYbrW-?|xEd%F}ZYgX$zi9PRjb$XrCz(pKi~7LYEzRY2DAs6f8l}Oh#r*MHVF6dB zk|v{S1L0sD_1%qZ?a4xNr_h&p=(^wa2K@G8ErOjkE?#9;+HT-kY5C^{A}#i539ScK zMfZKEQ_W(}<*0EW>NsPw8(So7lvvAHZ&Wy45Fw+B(z;ytfnNgAp-6F zXrng-HU-TO?dygFy(PVx?&eT6#Z%IvR-?Swm2azaJ)s$ znQWu+gaBk+;Ju9_8v&i15m|>zaQI$NM1=G9N{@DVY;}jOLf%uN^np&I!j58fU%+Kt z|Dq;UmglCW6^oLpESy}btD>$Iyw_l!Qe%rN%NeAsBdXqr#Z%K1bJipMGe`;($!L&b z5;mt`hL%_(MEljS?t{T@SG3-y#VY8eo90BWm4m^gyvG_wqz$ z`EeCwUkwJ+KyoS4t7apsBFsS~zGKh2b&#DBra_xcllI(}fSRm;F9ZZC*h?<+6wY#U zoaIi_MJ3IUH|0HD(oonvMo5;cuwkVlxGxCE7vvN4J5q}L@Wgbl&Pv!@f|<$PlMs9I zYH!NNvW)m434jTS=uoSaplQft^Qn|-p)hCo0$V#4ML{~8QkY9L$sZ!!aBIrt5Z}VN zhDSuY%~u$@g^#znN8XqO>=X+Z-gOd1img-CIaDXE>q}ZaRY(Pov`*KyJF03CpplQ8 z6tWf2Euapk+be_-sQ8TLYQ+Adp z8f(>`g6GTJCUoyaW2atwhrGYzn};w&cM?n*-;{K1;Waq*xvpyq86kZdTjw<-ta{6U zh9Um;$aL=V^m8>=OJe~|laI-0qi;K*inY$6eqcO^x4k)Z!cn07)jU*2s&=QBg)q3T(hWfRKYEB zq-dk}KiPY?AGxz5&u^)Pc4sv=&E9wInaxQK!DKfpi)6Q2t&(aiHp%WL$RfGCv?O!n zoMcrNS*lBxGOKuzwy}Wi#lW^~_(6X03xF6DJDEu;5>l&trdUytOZ3o*wKy z_n+VGyp`SJ1m8NM3jg|NZw#U0PMUVIVc;HcI23u@^q`*{5nIP3l18RdF@AX|?}$07KGKt*qbh2ek(L z$BqCtSg(a@)$-iJoNz`QzPeI*{p!+yHq!Y3XoE55hPb&YY(_~BV>z*Q5r;bCwnu12 z+FYn_udAFV)3VCu4%yo|*gdK7?&?9$<%Wtq0ovq9+QiONObmWM1sfpkZmoBmOGdK{ zkG)w`ltRV!EewYYfgOd_HYQBLfR!~?z?;4@Io)%}B~Sx+K$FvU-rZ z216M}Kd}YR8(goZ*l9b?AbyngUp6nDSBWIC-B8W5U4kXT@t00W5noT8Q74_ik&N=^ zW|iwz6Sf}Z{=IMC82RmQsCwm!?V_!oVzLvDZ*IjVGn;ja#jZ13A0{&$Tzo{JM_DS0 zYG}RydHW)H^CoE$ebL=%14Dj(JI&mYU#R)cxaOf!z*{WWix<=B7P-}v6(u&|T9{3B zBH-@XbSp;bt==Itat(@@m{pcyB-U+4=k9}5mqA)9oiX3C{5Oy{gO2_4LV2@Urb>ny z*jW-Q5=Ic~5j&4`V-ZUqD+78F(RhuE(I-#lC|e!HI&0Ui-@f|6joa(ru(KJz-$Uon zb8t;Q&Ch6{{AbBVc$NV^*zK*BB`TTKsz)}H#29IboTDWk9=@_sMUp2CaA)3G)bk{e z(q#)Y+I1d64~uw{D%Q|!6G`3;@*VV7(Z^T!l;nhfPh}Y>N_px^)%s~tx)QMk#c32Ex4vMAor5v(alxy3uEwK!qq#+R7A@ zjaC{U$QT@7|0-VeJI)3PO2u`44P|)~UGtc0f=B`^#__-)^lk!PEq@m%TbE7TD7vTr z!%IWynV+ukC3XRPzieUb5+j!#ZxBe3Y2^2O5v*XoL1A<$7}CgDO(0@ zSi){Y2%R<%#4TcnOr^yj?_9x|iL=Q<=;SQ$o?z!R41jk6&9jyVUTyD;+4 z6DHQqfeGqr+*pY1QJ$Pe|7z~}S2`j`-g?;f3)1Te`x9DBJP2o0`}0$n6pdv$3Rvc6 zLJ7NC(i_|VLN()Ps@&hBqu`F zxYw)xb%|z24MZ{vQDuCCW`Hwb#5~vtMJz|+oCxYNAFpcaqLrhO&IowmFv^NYY#kCYmsQ=%3-2P74S}C3fXh9N97pg zkWsO7#PAbG(*=K<*m9A~9ljYnzT_tg5%Uuc34uzpHQX}V2Ev@m6$HN8!HeO&)I003 zl})OUz=W|e*Bn}NdTK?9de2maBlpJpPqxer4vt|E4IxX7xBFZ|s>Gy2Vv8Ls46Yd< z^))ZGEXhWy??@Tl9<$!($Z=UDWw)h>GBm9w_5t^9d4VWwA_SjQXR24C1D$`g?kBy1?5Gss3UV z(4u`${`oVzTq|UPEEG%;d0<;pQ%#4F;^|LRFcq**!A1fsU-sxbEvD;ytYu3 zSob38HWYv*qzwVn?RZ$9(y=^d2**Ffez9rYofiqy1NS(+Cym)=u5s#;kV6~JpS#a< zmu3H+R4qiDP|BwV^*}M%qMBYrc!g!0aMYY0)W5FCk2K*((;2TlFr9s(%d)F`I{3r3 zTb>$#k2g0>)C#y7l4zZLU&2djQ~GMBvn-9WK}`}0n|W?j7>-@vjhhB7mW3O{jyc+D zK?K;k)QsUsJF5okth$Jt;nWwgEXOm_s_TeT6&-DL(A_Gkn1tEc-sVgOwQ8cwJ=Wv+ zVCVbC+f}#PH+qhqXmua$0_ITMtwVBN-%22##{36%x(hjt)q zKDZzR>MrOgPe1AH?acn^8jAH?eLkD{0B@yCTfNI%fpA6tUAnYk0X!Pve1*cWca<_< z(L2VLQD<0-XMhe=lnxFXavbYmQFeF`DA1&N7(k6y)aeMz(p{Y8ly!a={`#=TI+C-M zba@OB5RM67R9^(ywF=@ei4SEBy8Mw1wO4eMZeZ$)ly7@I|1 za@JD&1bN?d!vdBYzOya53AWK#>3~c7O-19;ZrR=n7Y8P}*gNNp+$|L2UV8D!!njp0 z&)jo!E^3Xwn9v}k2ZuN>mq4;0cpFY2e+ZJ<5=uz?^d34*`R0^b&lFzFe6({&P2&LuyF zXD1u_upOCwTa0JP&?T|c-8G;RVzf*2a)i_162wP6lWkts_^qu314A@QuUG$S88q)z$s@Bn(ahlvsmp56G+gvhxO`oIWw zyOQfk%+3+R%Ydcb-S`P13U+eRd{slZK-}sY2}MQH3m4e=Nm*G57(-NEG_^j48KJbP{U2sn;J?Y#4ILpG^eVO9 z0Jqd90p%s~QJM#XCCgIbuClQ+1R_*GH6!A{4dzS@#1uJ`r9rX;=I|Y>^>bG$65h41 zQOfMHnAAWnB1wYAYC(pX}(X$r<16YEVa&ZVi<6m<=R zQ>Sv>Mm?sw`b}%|L4o0;nF-zMG^H50cp1|VI+JlbvSZ}E>B54>@~&JB8dDGYbPFrn zVq2#D-eM!LC?+APEp9hHRPT(pHe^)DhX7MBoQ!{w@xssiEK0FzEYJ`3}b@&PkaIX7$UuBwm9_M8=d>VemAObLccfEJ1 z?M4&$wG4)jXuHH?c+~Kj#R9I$w$y0oL~3{Hz19L8k=1Shuhs+`wR_3z(H%ZFm`-=ZOFXdy;kyE(O`0kqF=Z2IM2#e&_|P)8fxOApe=+MjHt%n(bh&Z%trdm4|XGWvTO z$1TCSU94+Bry%L{)5hy$2S{ej8fNN*=DATGE;P+W_M$}srmAL5!W)?eCx~v3S9^Yx z^qr**wp^LurN05!xUojbp4SUVs*wH`CBl|xDN3r}EW{NzrfT|I<>VT4JA|mLCnqxS zwhPqyn2|L+T?@H3E#mNke<`2!uKPq>7G$s1oM!iVIEYPQOEtpH(uv zSXsB_&5ET`>nmB^kJ(edvUQbJ)E!;62&U!JhWaFdXZi9Kp^+DP57c`pZR)e`QCV&S5D<4yA>oWw-f z*G7s#jngo3{KirtfX9;OA_R!}2ZqTj;dEUKo`^=Ug{y`S^R4RR3^?Z&Ld z98r{r4q8O#o!D-$Lm@=hnQbv+(klftW>mEzmw|hOHF-fC8#h<+g|Q&R8g9%?Fkz;} z@cUdiv39Q3&c}{-x_iW}5O4t?giAy%AeT<2V@MgERzd%tZpz58SY+AELYyDzIcet5dWDrW@1a% z_H9!5%PKHCQSF4V>@<<0cQGwfrSQBdQ^F|wtp>Xs?bb3;HfND}4F!{}ihT3AaPp^% zZGETU(>=C9?i{l!IeTV(D%mZjDpe)vl;dX3h9TELx8b*uqS@|En2<$)CJt4(4gujMoY#gyyB`l)PWh(p_ZG15m| zCQK@nsNp-X{2=+FNUHkI!W_*$#z)ooXdIEu#&>m07_fw>v9or|g|c~B)nvU=f_I`>dC$7Fc|4Q* zj%wv9GLI`0q1#XYo@XV&0@`~uJ?4N+N($pv!+x(!y$bu;S&OkAZ~zSGh6h;Da!=q@llhnEcD6MNR}$>tY~hOgnd(ia5)t=BNwiTEc1!1)^aWEl#M!(1R*>Aoc6G9XpMfJT9QBQxjL1k)z;Dca6Tf!`(xI0BWIP*p zwBW;@9Hf$bnZFnx_S-G93M6!3nTi=wk2)Nyb~@AXLxs*(Q3iy8iE|adpsP#|o{~>z z)mrg@*#ueA`J};DGyQ!$DLaSM7KWB%h;z2;gg8(Q(V(j|8)(J-adiG1JOuJn~OqS!I}hVeVGR8}}Z{_eT7m45^xYnxiuFxZMfX zA)}=eB&?_pkHu2#bFwei&R8V3ZiM3qjMzsf_&Hmx4B&$9dYd~${pL4VFdSw!7~a+c z_Jo3v&Sq5C;w}iR?3p{9l5beahePpk5k2_M1m(@-U&vujzm8eh#rQ91f+z~D!)9EQ zb{dYyq@ffSEApl|*3J^)gbHR@W|3xeN-7L0ToyLF^HGFp14N?p6VJ*LxwSM~u@p0h zk{)2dITD-eT@0ylbvF4>r?}(#HIDFFlI5E|i*C-Vmu1(0SW?!l4BbWe?wr$Wv5=jO zgF5WCkLSMsJ|G_rv88re#?w~wQgPqbXT${=L(}bOfkmhPF3hzo*lIyEQK1M`BWHub z?wbrk)K(Id)5^O#Vu|u=U!-gn0HRs7C$I60@{)3anEOn`QF*K+N(3W)mK~<}iGUi^ zSoQK`Lb}L#S&R8ZtSo3X>%#Yt6d)78$=qG~4)JoWn$6UgW&Ln3m(4x){>=ODA2a8* zzGiYHuUe)Fr=&f(bWJo5FLU!pNp|2;81}XNWy`ir87i22>Czb?t$o3ujON7S*wCB~ zqWJ5_>JJX$#HGV0NmFjL8Vr{)DOZ&RbHFA1f0A}Td96e+RdSF4Bp$HiI9M<##1P7> z;VdurVys5mL)I%&^}Y1&^$ubqSFuIixPSld{k8C8<`F*0Wvt3?z#vt1Ht__pCSEmu zG#ZYycPN7x>v3c+aCcB5MyL9sEJ%BAs8)rJEXHiBT#DFEWbl|ey^&_mQl`N)3tWO) zF#_D@qAyLUt_KMxKx`VVr)5T#o~mKyh9!%ltw_(c7%Q5&PZbg==wUOZ)qZ-{RH%$x z>3uRsRc>NYoQ}GGOnXv}8-rFF=iI?C{x9Xc&FOg0R8?nU<=|Twds!Z?0 zOBI0yS|12qvA3`MC5miNZ4bP>|GShkAJ7XCTY}4BPPWqatEp_+2E=)3@<~%T^_Xv_ z%A%WK*$6L}3>k=!Nn@49IesGqP9JHOdsomm8c*YCJ}ET^nX?bUh@5|&=9f~#5gnQwN98B3V%^Kd=V4oG>-A=>8A&Nh1zWUU-a zk_l$y&_bLd1@nkOJ{M^7sfjZqVZpYYRp#!}e6Nj{r7+t=lZ$iDdQZWQenDflX1CEe z3F?v=QI^C0Ia{Jam%$mtm9^HjLXaW*(+n$jP$RL(+jUz>4i(rL|StB|~osgkAS}3cd3hNUUX8SV9Rcp>-$udCT z8Q9f|!6t^dgX2R}X~_Upbeglh^ePEMPeG;T8Ol7-(|Qpqbq>SID@!W^8tLB|^w)(_ z6*tNCvOgm?HwLK=Q8RXx>%D}5+7!$ghzpk|4wb^*)hbhJSEyJee_Q0Os$8YXC*xiG z&HUM7;v{V8m3k5!1=hw1;DT8r9Yu_;*=onoBn-gt1Pj;xE3}=P-iOV4HsWVdL>iJlhLT^sifl{{;L21X( zUeJV=(?63)?S+$9CBsUPbgl%w65GuT%+mk0QE<6IxUvF4L#-KA{i-CT>1Cn<`9We! zYY~2~(Z0!^@AVK2HPABpRk&dTbFLtxnZ!bQRfaj;v{ebM%rPnOS$UChG|Zki`H$4m z*UP=qCIeio6{oA`cERMABM0tqWG87yqqs}*o42lV$KM_2q6nRJ?t7Ym2wPl5+XR)9qV_LLz&h*PjCHCy!opqd1s^4|Ge?r+@txU-!cW1^H(_y zl)vBj8)r7wRp3`MUvF;3t8bp!_*Ad{nyb~etVw|^r-h^7-#)YP@2TKlSfXl2k^kV# z#(%CNU$SP5rt#*#IJ5DO_2$bNftXnF{{K0%vGE1o|7K@r9HsA?~ku!cRan8M2~GMGJI;01fy5YOu` z63w2sqiK&iEM(748(AxG3U_%s4b|;Ym&5h&_($b(R&9i)vmbLg>z_}T-fbxiSWoBN z&-!=&wBOHK9u7&Ga+X`~t`RTDMdr_rdV^~hbkgl>y0P^uJ?<{-eLQB_!h*Q`+ER;d znNPQmu>DQGF881IVMsTGJq};YsMu-DakI)QiHmAyn3!?!{rgw%Jp9hr&Do{^VVw-MPH_$0-VVKls@z_Q zvz&|QFjU>Rf9+#xT>aqY?VAt3BfaCpn-A~Yc<`Y2;obYatG#pu6H6K?E%{tm+#r&=xbDXxGC`{pgIT^3^c+A*Wi z@!pgb*Gv{>XGayn_qY#YH*M3yj)ejIMr2-o@#4ks>A~@EI(xdx*lXP9tH1Bq1UL4s za-rBrb=6;){j|WOceOo&b)Cw|8l6g1rhKi#`SD}Qa{rvFRHpn`ZQD}bbiArt z{}RjZkN%wd`M~|h-}^`ZC098AXy9ILYJpqF$%uO(s~m7}d4}5-Ul0wyQmfEcI<5wwbsVqT2G?<)A4g)_N+M_dWJH zRRi<%wTLjgm?|1#X|cm`Wv784JOAMBqx;uxjILjOcw=_=SI%j`9A?pU}(=s5B=ZDl?9 zb2afq)&6IwCN9eMQw4h^&tddM(e6f-FE!VWW7ayH5{(vjdynqjzWNaTdt-F-dQ)zQ zL%+Fle4A~B2PC^nDn*Z0N19(FPqZ~Ky>M?&!Ru(ogny!)lHGl0Hk;1m2+wyv5~dm7 z^Qs_WRe!kdi-;Embf#KxW9QL{m1SteU$$Q7d55oGzKXjf%WXk+G31GMQuc$`7X(Qb zC&I3$%90pA=JP$aXY2{rbtfEV{e$hpy<=8oM>rNlqHU5-l@u9V)bs%aOOezvrg`A4 zwqVxT9X7l>ieTVXMbBc|FNaRGvQ$OtTONsK6~yXord8C}c%(5Z;m$s2hKZtO?Tn|w z^|ZyR0G7N)8nPNjR-4qkNG(PO5wGLR_2ssmkkW#8qtNL$ePE)!o+N!V~%Q_k^4~b!0A>7Jp=JA z51CVcDW5v1mzs_2ghS`7l(R zzu2>{b9$oh+ee4#n|JSgomyDf1|ou9wOMCLsY(^=e3_53Qq;eYCn+EP**p{`V${Yw zq@cAG3yGFOWY(ZFZXQrYaLhrHX6~1&8+&cds&F`XluJu)Ti}w?Yeznh)6w!gDm5N9 z#3v$Cm9JWlI@WJEL=z+Nec217Cs2e*WpS)JZDj|AkXCFV^27-DX@E+l{qmgzreb>v z__aIvoln`Q@5^67#DAZT24y(Al9^^HCJv{W)Tt}OnToTEC*g)Abqd+Z$*)0+l>Mq*7b zy`~H0F@dI*+U>1=DIn}KI;@)e3Q5lt&|B(DZ?bz`M$tfJW?S5Lp6%JW9bYyP_y^|>k4;Ux^#OSgQ$r0+SU4O{)RhV(_rX<#;9`ahQ`2U!Q>7ChD@BCFe?swPh>F4#DwOeL!B8HS#UrquoRXaznG-4x8 z$9i$j(;~~^bta=K3G5b;#^(>FThq-s&|E9CRIe(cF*KCVYC-kXfmrrgb|lWYsF(pE zKf+OOYl`Y5VL-2RX&AsKt z^k(*gbdnhG56P#E)O|742^u;6L6GBTn;btg*d6&1S#$fVs9D@bw-Ve^ucNSMN$TAx zr;*RWNBDk3Vw?#0bac!xA==yF3ZZT0u!#KxJx)EcNX#X>s3Pi8b@h`h)Hgo7`snt< zX2T`=w{x9zB+&(`lr0ykLAQf>0NZ8?fFV1yLBHDH5lFQJ3CCANa+8&(5j^KPTNXzQ zAXS4!Oc0j0Fu3qj8EWUMvzBraGZg3aq|~^GW>9T;E$n4KUA&}4YsnI4rCztVBv2KV}pkrv^%%`6T{zbb<7cd!~ZQ z&l1xIsbMobG#`5^q;{~oN-|6iICz3$WPA&8uG+m% z=g-a0Cz60%U|mtCRQNFM`8ZoS*6r=wY+P~aLTtSusFdFodJ!%!a`{)>yK^Jj4Ovq< zxz*H7wQnZ`27ND*x1I?N+mD^&aI?uSwHm#MWX^)3Pbm9Ejc1Vyj;vJGQ@FA!^~=SX z1+kw6e->!4s2^Du`95dRe*z2|%DAVI| zOX&zNi992=uC9U@xd;4z$nV(aO$UCO*Bch*g0Z# zt)RE6fj}k%adQd%N?xP}eGzwR_@*^xdtO|wyBXDBy%DJzqg;EF)K1CD2v&Msrj@&T_G4`?dWh60@TDLBJOAfjJoBgY zAr9g%EHR~rlkBhG`p-O8VtE;lnpp659TC`{1N_^UzBIC}!$|7!`P)*wud}X5 zJY8c;p>3*6yY}M#;eLLGA;7{p@JCFx2HOXrpkbQ6@p7`MkjFpVKKMhHH4mvHHqpcS z*mYo+c*Ru+o<({-OxA3HGiamjg9zGqOJU5F>c@%)nsvNH8W3ASUy$+MqC)n@oQzSi z-Zy&H#a$}w5;QMAo#INE;TNlwvb_#ERyPE3!Z%00EG6K8(Zj*u)Ep-A-ct}DCu*X9 z3&Al}zYR;}e$cSU(p3#MhYhyJW(HsMd`x2o0J85Qs96opKck&!=+Lv!$igo^_yuL+!?P0uU2$G(I|3NWlDQ#S#aT=d-Z}fveJ^ zXdyZR!fVM^*UZNU53fFa^k8)NR$(rY*04*XFn?^o70DWqhv}7F&XN0+Yx>0CYLd%~ z??%DW1v^#iNG8;N1%PcT^b6ThUtF1*?u9X73%O@|aYM2tPoX1L4U;!rVv3{Rl!_-2 zMKE$dtx)NsJwGd&_pS`TGQ8x*>@h~&7diI{9#9gCA6n2jBZaA&QS!@XqdMystj@gf zZ3kB$M%I)S!s*G@WW~fT<_L{G*362rRYFeuNwyRFzJ)<+zJ96dyrEvzV!W$gZ4V2) zTuQ*(rJ!0e+g0FUS;0TcLU7FVA9NREg^wc~bJ$$9L-Dcj^-w~m7-K}M1(vYb0u6@r z2*|WE(#YBu>n`6&bnTDkBYRX)kCF45GW2VXRcgxc-mQ;DH}5dnZr^Sv8muwR+g}{z zbKNMy8lcoBy`vWdz-PK^nrI@^+ug0owkM8F{~l?{@ONmb z!#a_#ckq+{ctCVYcRb&nm$gY)z} z{aXi=`Es{R;PY5-E#~zkv@HPkG zW@FUo^{(m;0v#VykdmEECG1G&%DTa@pPv>}ya7%n`JO*NE!I8Z_cIIwPFw$SNTV>m z2kDmIDW3Nsn`Tt<8!rzDSKLYv6pJ_B%cnlHG_VSNiNB~6@k_?-+orP)`eAIqd|^^! zydT#XEi39r;V4SayGkBLaiumsB7w=uK6jU)5If>W&tx0bN*LCU+uS5lH%5c_*VlV` zuASuwoBQ6@h|nA!>X@6Uin!1bWdb?1#%c$WN=`n$>BRjPvMN9EcL;VRyt5RU{}OF%nF=eKd+EX z1t}e*ICH~hz0CRHy_@%LB<$+v4<26Ud~Vs^LxRyE%sB~2`i&PuUPRR9ILKI zappnBB5y1Sog(bE3ZK=cQgdvaNlS>A)B~)Jxt1n)O((VQ`7ptjo?EI|!#7pU&~);f za4NI`B*gr1vbnRZL(J+?It>jahYBN9Y_f8yCKz>r3{Sh9s?RZjG|oPEa1S9FiSyu= zQ*yTIYuXxT7*R>I@=64ncr3cAZ9X$1noL7jK+_OI0lGv_=h+KWIUvQ}q(cb80O{jA zXR(pXYBC{~Ry6}qa6MQps|w4XUR9H0N!850YfGiM1(rpW?vsg8Ak@XUVoJNH=z4Je zDS#B=@H!~%j9F7eAktU3o9<}w@(*r)G`jxbZ3dKl>9+g^7tiKwVRMn2AKh6PW+fnD zcYN@)fozpvIu^#Ur>B*~Z`Lj$aIFi@r|p^ot}@#z4X?u6jCAQtL3hFwKrTrE(W__j z!m_u>Z@ZIM#O@KDn&*gsBn{o@1PNq4ZvDm}7#kJgUMHh=Wlw2g=4y!=vrN9%U&e^656b zLnGCi?GWAmWaN;->qQ3+GYUN6) zXPI@(m0Dr5k<+lCoN7$+yew_;$mSI#n(36s+9Y3Q0TmAg?}z={*G8Bh`)j@awf?6; zVd|+B|cyWtTq}~d%eR8l8#9P@uFdRaQEX9T<16@Z1kLzysZ&Ag% zh4kB1#dZJl+M+CyD$1YJi*D{sIgz=&6&l^Cs1}A?e0HVIbOS$m)m0Dja0U?z12y^*kLzJ!cN+Rhw|>KC4G5BNk_V~k zM**S$46oQzWN#N{!=?>PqIm5#2;&NwMs#riaGj&ektAm!b{BW%+9ggw&CjvfG}>@ zzh=dN(`ze6Yu$K*6;Dj%W{&*rB5}4P`28Cz z-o)vK)@WVSxKvqxB~)_#MW+0W*cK!qYtzxTb>23d(!Ld5QQ0^Px;$=xmD4IJx`?%& zb`f~Ia{0U3`Sl4>T5L`=nkHzo{r$Gp%%oBUeL8qHb%xyJwR2=$7$}ED#jL6dhSeIo z0Qoh03qeR9Ef{J>TZ0;*<^5DGcvyx}`5$~|qUs!$pY0qD(l#VP2Tz0va2LV(^GKT1 z^u6kIkDPa>X*CB7+D zUNabPNbQ=^xt&G2s0(jG;+Uvu34%D4@#PIrs@nh^G9Sj_B(@OdGReo0w7=vqHS$KI zY-P)2wWZKknb$O0HyGKR?-OBxL0U_19DSnDCa2K!SWkl$7}CxQ*XhTcOw}f%P|+EQ z8Q4l6J8VbtuD5#wkv_yZtlzIrf4Qnwt-6bAx{2}%KjM1KJ>bm-wxLigmhE!6d>pci zev1?n_`c18JP6$*LAJFxwnsi?(q4&;pnD|p(%RWuiIeiDaC~?V8X=l?X-0xK*tTV` z`jS>--%Pe^?{eS8>-TW6XLFj=`aVjn-+QuX!4Jy0R+m&b%EQoELN4s`7(crztep5( zm!g;vf2o1|P0jKr?Z@y0+i-_?wC;wSTe35ga^`4wE!~?Y{r|JN88W9V*Yf{_@9;A7 ze!c-qns7@ADajh+u!q8Q|HK?2E+b#J0kdhFwosC^Qs-i3e-~k{6M<&-^YthM?`Y8o z=2F!DE&G~qC2MjOv)aOTC5sNpg-VK+uedQAyIAv!%|}|L*7G;J*~Sintfx&vyWvS9 zHU6d@Od8fV+~BZiyIC+TGS|k3tgMsM))=FPIl4;+Lx?w8Rje2dbwnY3azE3uk~$en zSL)r*e8JfC{vlLR^2T_%SaD6XvgrSEuNOZn310?nt@o|s1LbkOh!&$+9=}-enlUaQ zVrhz`-MHbyW=1SbO4#F*??mfZVu8=?S3e6saxFeX*Z_L8PIT3 zE8$#H_`gM7gY|pmyKbe6i>o`2@K+;BBGv8|q(truz~UCdRLt_|sS_c~ESv?35XCdIjB$11*NnHYS`w}+ zpvj7r7P?OGkA>i}aGGaIe`?&~SXpfQ^k>Q21elFs`dWrLkWzHQ$c`^|nvaE0Sad6~ zRxPhX8@Cc7m9I1BfJhl}JPG`B@ zxBHcdqK`C<8jSQg(UDZ)193S1CU;S>>8ARviMbeA(|i3jCs6LMQ~ZEs?j-7ot!<8~ zkTEOUXPqn%??S4v>m(6K^$LT<_&GNR>5M>bMeUmAf{)bBEs9durnT~8oOR7@aDij| zT2lvo?x|RLzcTcyK213Y0{YI&Jgm9z&=MmV%M6V@JB%X$~ z_xnEy@}dujn_R{oz~T1KiuzJymSFBA)UimWpEXK=Tgte| z{s)uw%O`IGjSKQdDsQPgK8;{PMZ77fFm2#IqczM)^U}`5{}Or4f;l?NzQ$o;@pNMz zYYchQ2K-lr|M}!*Nw)aZWbaE(C7%U(b8YrKBZt;-k==uw3}tnK!9qT9vo6@q1@B z&Z*Mxy{0A8s-n*MGaJJm{sC4Pf#y3^zpFgc3r}f5PkFvkslnu)KzZ-v3aQ=*Q zXh45(X5(9W`s)qf#>?-V+4wFm?KF5hvUbM0VH11OZPy+y4wOA!GP?FW!-1~W1*ZqBdtCJ3Pe4e>(di=|gxvswS^IJM%_^s)bbYS0j@j`#Ui5)9n z_?b>_%Rr!Qv>6IsbH87jNji%i$Ev3!S<(e7vN`z4>qw)W&Rr{;HdhwyaD0uRweu#W`w__rj(hZIPx6P{?i}q9D;Cv?+5#1 z{e8mkD}13{d1-UIMgeulkCLS$`zfDqp+G{xHa+y$^hmZeH5S@(<6aoJANW*Estver zw>}x~9lJSx(0>$(du!N7uedbX_NsN0ZsSPhtRKq!=L2g$>G0$J%GdfHC)z=n!)U^? z?4;|e1VeK8_-Jqm@~y1c<>%|0v(0y|gyo?Fi@{UB7h!39XonEqK6`&Vwig3^bcC65 zj+F8X7o@n?2vDnB+@pKO^IL&rinvzoa~(*Y^?*Azh_2(1;Z8EKbP;8QVr+~%s-dV` zZ@T}`bIf>3OXe;N#& z`%gx}-&+s5gYcP=Fen&=+0DiDb-BT4`n)Lry3wH7uQOKZ76!jMNCKl8A))6B71ppP z$E3SfQ%sB=r|LNEda3uf`2M%_fdBu#W(?BQcKP{yAvBgSxv+fao<@MtQ#QyrlbD`r zTrMC+;;PuzE@G&x`>B+{W5Z0cXQ+PyJza(4hP`!P>(Uvx)>@flX95-|CsTzQ3j5$| z!L`PdMfy!PpXrK`pPFuhTu;!?O1#%}IUm)4^cCq6vxIu#CzhAeQuNw6Nb%WmnUxZ+ zOD*wwHoo{j-@pa4S43RO=n;e3E*`OVx#5kC+@%) zRW(9~^C0W^s3L)Vf$qO}(y#1y0!|wE9i&m7%3f+bXj$p=_uwHaYh7ESC=-N z?cI`AIo-yxjqM(jm2}7Cmx)VOLZ~%GnU@tPX8$Tp}4bI)cPr!1=P9hxT`+ z&Da3tc~>+M==vJnq$WAz()?@}$BI^_7d`H)Wt+S!2giGR{_Xq6I}>Hk@2`BUe>w8A zX}_jS?M!x2Abn2Os!BIZtfc;;xBUd&g-2L@4vt@%H7rDC)7w)!PopEuURrbeeD}T{ zOu1oY^VoKHMT3ZT%5swGlFAfaLl$!3;ULDFdlJDsemOomn#}`DTV->5B^pd*ez+0^ zyMq!HlTgodA@$V6cKXqfHEF^|Tja$_+=S0Z$&x{+24kUqLDiz}CYY{yQ^7QG%?NoN z8w zK5>01JxjYB2gxSjqn!`9Pi@nBoXL~@MCL&b3KN$EDW|L z%q1`^6p4aF<~%3gv$5jQk=>atPL3cSH5ZYFHx>RsASAC~JsAv?=54yUIhMVe>xjr* zqI}58#um$Aq=68uRhn59V&A4En+A%*AoVN6gip{7#>bW<4kM#Sub5+ge|MW(IW4G) z^P>n&P&3O#^ugmv4W59f&H$VB!1^?wPd9gvC*kQAE;4LNrLajFIL768JdW<(*QpF; z5RqNf!#a`w#Bc1(6_M$E9dpITtoIdSN5Rb}Raz|6vC&J5j%tDBE4v$b7>s$Oaa(`D*H-CYK^Cf&u})8G?`s^hoC z>J$JKm=qO7cN-zmr8@{ii?9G(Ng(Tz+SSL@xVtd->A9}ZMa^-Z6if&zxx)PjFbDSJ7hI}-i0Bf9 zCNIff#=IhtijhEqMHIsfW2p%o3Q+egARMGcW;aicr7r<8ybNDgQ6tL zlF(S^g3YYb!o3yr18v47MGBF4%srjP5iTaQ`S))kFyBJpfA>NgN2GT2A$Sn-iw8AO zF(YH3T&}rPCajM9^s*4Ma&f_jN!y^APYZ~Zd0LQd4y6SMh#8e)hKOjvTBH`TICc;H z+^X|@7r_|2rdcL>Ci;5sofe+sWmkH*-38(y5PX7gD==%D#R~bLOh; zeaxrOwA>m^h4?uRI|WRp>lRlB%YWhXLMF>V6xSW1Cc`ROHk`0}TdnC_X{^~S#8u5Z zh~jqLo>!B%nyX3#Xmi+7Ye{ejFBbi*DMwR-#rMD{CF6%$H>Vy7T{{pdAp;P+!n}gW&!>#>bd-lG}P1o-Ax}&n^MZ$Zs zFYcWsQQj;TUVxZZauZZ+D9ApTES82fL**U{3Gsui>ApWsXJoLJV=_)G>tZR$sOk>O zrr${dd28S0g$v}w42*5vd>KxA%KatbVju4B>MO|@CfhqN*Zm&kA$uVUdC|PZAR^<6 zjYHPkqETKaU7Z_2!Pm7nE#Cd*)=L>>RQV zi*RO}**Q9I12{W9DzIOOM?|4zj1!qB&(m&Z-&}w^upQ_e>a!Xh9CdhgL!~O#qr4`c zZwW%BF-V65Ot7B0q9BRn>JFQ;SikixO>ZW)dENKN*j+t$jPfg6dM7sY1~Bc(oH?N* z$Z4~2fPBJBXS~I&eyj=E)W$r)%nxwi*>8J77ZI0F>C*QTrMJKuuNgv8lO3JXRh0nYXd5l*2DhaVX7qe=o6V5ici$*i zcwE2n!K05ByRyyJTd`wFLrW3LeS5*IK|Omevw;S!ZCcH@lh%Pze(etq&do_uhFMVX z+j_n$HCou$^0u`~3x3gBwTjqWGKqG6Pq&%o<@3Bu4PaRMhXym-M{H=imIhjMBQg9b zQU)ZI7iutr+hEhsM|H;p`KP$Iazl}58S{*`c%!_%4{P;TZri^^XawyG(UQbDH2JScMjtF< zIur#G>h1UmlstNdt~x)u&@KYFwOyf|jyQX{eKa5VpEnur2|KCmS7Pji%$r+D)36)=(|>x5u(VGg6(35J+k$5NWsQ4bl5E}bsX6d z$GL3+;=H5T_k9#mO>VmHF|5zyUfw?k_8KPB7^qC)B&)&NoU3rLn@U^FkjW~ed!-)Uy?&QmE;y!Ky1rsdyl;t@Wu%(R zS7o-;bhCubY9<~I-=m3L8Co2c#@VL*!|`)PZpM#{$ojjNzV;qd3tQte=F<9=ue=un zY<20a|D{{pL?ym~->o~W#GYGYdrh3Or=x%aF81U$YwL>2LKJUSt4;sO(QJEO#dxMh zY2-ck{<1gX!cOex+@vvkCDl&S0{!0?h(zcLCIQ8Vd&eh0y~16?X9*4Bb}f@m_@;f= z{enBOaMbI9UX%q`7`f2_j$9b@pKlW@ieTQKZ%yYZOh6sW^aJ-Rm)?EfD(l4w)aeih zthkAK{%Su~L08exb}Llu!cxE|D!rB4w8ogX=C)uMl&i}|sdIlb)K75<8NaADlzjrn zTDzrv5x{%U;j0 z6s59RFJ9Beaynwa5q>{8%ZA~{2GQ^~9b%W6c=U3l&j-!W^xM9|HH4-_`xq9){|O6YR;2n3RjAWBG0 zXrMQarJ^)+N%M}A=3OJrS1-TwwRf((zl5}3x$^!y@4svKI?nHq!xE!_Etwb)gso7( zjbNc3p=IO>EMCGAJ?>1h5`5asSmi^q{x6fA zAtSJ&N!E_0yRom}Jf%J9E?)_jdR_&ZCSLojf}jGE5NI#kQ+yA@nj!+TMcFLUGPvcD z6{zMDvcyc)+Q29{<(ZwT#a3ahB^QILRh>zFU+Y~@al){aZP*-1ls-vF`+?3_0%UH6 zdjvWPYui5(tC|ek4D_xUvR1Kwt*TEiwwlT^wPYzQ2;15n=lTV2jJMkGR5tZY2at z5ndQtm`OsGzTwVXyNW@6^LD>#5$AM;ZB`ymUB`0swfu!Rv3eychh`UoGTJ#+H#{5C zSq$SCsGCem6rtqpVsy-5+#D;-7*!*ouj)8ndiPhBEfCZ-@}<#iDVqsJmy!XH3~Bpj zS56Ob@D6QP{@5U;c0)T(fWKQE2@{Ug&KAeqjFynC$@-<~SHJQV?X)mvXgQIiu%NtX zD$Mo8mfG?p9P)Tdvw)1Q0cvfxV)dZ49bfRs31w?$&}-fJZyQ(?=k?)#lNQ`oD%>ftcna+?@M#Qt=db@VbH~?c9L5v}o~8)h)$#!HHoDLfhLn^iT?9 zqfPo=8tdGUvBG*e0#G`?timk?HLDw>8_P^qd>l)rjD>xgVz=(j8F5J_Z`#P&!XvVj zE-f-!gLM^RYS370xXD#c2sBBDCV_t?0mw(3LqaLP%ZUgg&g|I{TM?ij4MKkvYXW z9})pS!$%X+XY6d&rhnJZO`l>{oNttNeIiWZMML#FT%uF9UtYm}ta9*^Y=CF|Prq(+6OM9C z3U^;|{Egqh_2-CuOTj+ol|3PdSorvCdpczw`C>*2)$HL*)P}$ES5|@8YI-LZ9U95o zO05`F(>_=+h&D9CKOO+{1jKqqCr@zk5O#2iBPN-EeQKEYb355((@AO*MaosJg^G2i zOv#1yDTmbA=puLUN%;ut^h+iH$6o?g74C4N$X3&p<4Q9#q+dh=3$9ov9}F2o48K`Z z;ULwmQ<|2O>Pn|pA~aAZL$_44MPTBgS{k%a@*-dq+|ZOtVZN~+wbQoh32SsAp!&kl zEx1JVT%YX8j1m?ivdnR*!dtByeW7edQiX{g*M02rA!wb`EFM3h$Mq~fo|7@BskJEd zwsZ*UF`bfVbHE#x?dHjRy2r6jPVO|vd)#ZNyvR?K7+zP^a-7O)X6Bi{I@r`P89a~p z7|4vXL+$}wk2$}OQ8}V1kbpXoJU4qGn&tF_leXgG5P5b;(oL*I_#tU#N3u+>zt}k- z{OovtJl|cvbm^;KT_zS!nz)(8?XEu72yt&qwq!o1;3>OXFE$GnfgCmd--WU)RloOGzHk>CC#A$$D~sOzHVfhlG&_T zI4Tx)^-|2-jj2lLuBR_)F)>mxn7&lSQPzqpROYx}3_d6wAgb=ObmA#U$qX#bL%{io_- zVperfR%f5B%ZD&#%Sbx4xg-Ws>x|8`jK&veV8I40D_=brBg(eM$uOJjE!Py#CG}*r zvX)`{ImzcBn+0bljt^F{%_0sb2p6Jwkl0}=s?2~H&m~693QpzQaBnW&1e44asOV=G zP?)QH$&~-uFtNp?hJbidq>&M*x=_OQfB_;J(C&C+=Yy1!%xpERD+Y{Z2J0S6$b4Uc z7<_4L4;8jHoQ|t~HS!%EvM51Ek=+TFj6!A->gTbt#?naHnv=J5zQkv`a^bJK{B&g7 zuOh=kEz56G?(zJf?EXq6t)ii}*e)yeIcYua_rJ#JF24obIZy8X!MXVbn0SE~)okCQ z30MTTs+2w8mxm)ayfZVhn#ZJhohtR-TJKqkgtx8~t5wNTu%w$6cD5oXNHO(1 zfkCVmv9#m)gRA}QXG-dUzCzeVBq%E0z;sxOyco&Mr@HBsN}O)lB$5Xk7K+I>ryb0U zEncW#_q0n{oJUoOwcfRoy~v6ifhyih*sb+G08g6=QZKw%SoGI&AAG`94Fq;h)||zj*7rJo_Stc*e7MG`cn6(U(f*m3aR2)*jD)wMwoMFAglV@~@;Ij(GYn z-}*Zg|Fa}VP(Fxw_(!+?Er*>lA;j~4`_{k9^ItQwT%3Z8H~;>vzpGa5jh{S>7yt3C z|2DtyK!AAh_ip_Uy!drUQw}i4tN-!V|H7+3mjf8$@&9`3e~ZTrpnq`d|KRZ#O}<3Q ze|YO3^XSjGO(dTE@y1^|!$YX;;nV(jBVn$0-fUZl`|V( z)$3nx_K@*%?aanqz5McR-!XQxOFulb@ol~Tt@1u%W&!|NmLGQjXm2$d#rr?-EX+Up zvjHG-J(Iav$(euj8y3aVZS@b&Y&_B1-%M}YHaE{~Oq$9~i`!>5p6cxvt#Y(Ciif{p zLciPI_s(qWT6^hj+uq)pjRR{hzpi^YJ+pCW?b+LCZzmr9X2*OVRGFRG_}5hDue6I% z7q5Tw%*KDHVt;j^Sc~9)bY|nfUJkCI%ztxc3kB{ED9c zh1_=0(4xqfzOeB-D)Q$SSClBx`@+Usl(2-~Y49z_cHuqy`NbG0`>{X^ds<1l^gGQ( z`@IwidsEAT{2)nzcu?lAJ?KtMf7lT>_HdD#>~Sm1sz*(`9bst2nh~-mS(@9gYRK(( zJ=EzzXevMco;_GTf(cj}bo*UIx%~u}BE;=UyEG&i9@!VoHLHr1NJ~%rkZ~Z&F3LwM zlZCH-9WTkUPU`jFN(qhSWJX_|%zixh_KRoaUdO&6{eNb+`V6jJAlfD+PDhd1>U})s z(96vO&X=g@LuIQVQ3CtveRHVmyvuyLeZ+yN$=7?YrpJ-41+A1Lj!!VYn3{aBg+Wvv zt)1;xfI(SskGoVJT?j-r3fC?^y7Q=Kwq9bA?;Stc!{mD#*ENZ5O~uxe`7?9;0YjezIgFs`1Ig- zIGsIRW$ZQX^VQ$i2t-J?7Qj+Z7)}oIh}=8#$VUcqz9#8-*WxLEaCN~(Tbs>{oitCKYu8H5Xc1bhZ?WvL z??HQt=+V=mHBz0RxD;~=G)XEBMcd!gffPY0Bv7>V$5Wy&SwCA?`_qFRUAz~Az_4%l zlWsAvNri6Cr?zBT^h{e0TY5t+dGF=cnYYE{$4g@vEi2K|Xfod%A96h9OZV^IeK@*z z_2I{GWq%b@^eT{T&$!BEdmiw7(`B#aej41c+u2+l1?odD?D%;uU+T;!s@gW{~dwP#`1gq5@H(rK*DV;jy2T-9+1E z#c^TgF?)#{NSdu)0-~*6PuF`r=V;E1Y!c*P!n$ndM%>=dGf!N`E=_Na$9ra!!IP#L zX=j(PNoj9?q31h4Gk{n=J|{;1#SxhUuzPG5(}j9F+&U%&Lqdi9KG7kBcoCZLE`q_R ze0&H|C#O-lqVXduY?JyIPhBIgt-Q(mKn(0IUcT0;kw{H%J)56`uY#^VTE4~_xI`Lb z3-W-oiW4&yMv1*w!`@YlTAmllBK$ebL7BbDwpQ+==`q>n<2ZTR;x7yhL){&k1z%l8 zgJXgkHk~};u#}-F)(d}J$-S?!Ui8Ba!wGlKbG@-p`SHgLUM^XTQ)~Q(QNekq3T;qR zZd7nnN2>R@@UO0?$}HTFkUZi>Z@a-NIJ#4y;ch`%;BTw2K*FD#yOqd^Ey!dt(h4`Q z_}ulceC-mM3h+Pk?Q37Vh{7@_&FkeWUmafJf0rw}Fsh%qEVnt-ggZ_;maUY`cVtr6 zylav{5x}Hc)gJ|YSn-47{U?)%ML!&y&WI2JfwkTZGIO0=4CT?VTkCxcj=h`rWK)_G z7ryz-D7BVtS08pTWNBEr?2&RrPj5>fj2a&04zBh)v8@7>fM+%1OCS||q%Y*K12n#r56@fav$J?82?URlHBe0vdX zM-d-OopZ1U4^g%ZxJfA>p`#|_x}mH9|L| zRqY1Q!toD_SEbTf%>WG_O9dVq3>mwULfnu^xcLKZm=qwfsif@66c%bUkM}uni8C6O zVj(xWM}rPq=%$48_9StyZ#cb+O)?g#qa_8={^p9Kpe){QabE8$sY00HU9lai4_7ij zRIr`lcjp%5*0j?}`a(mybK+iB01A*~gw}Mz{H9WeuaXlOg@4q*C?_JbJGT|zDvPXHXy!6N2AOU*R-+AZ#_f)=9 z!yYdyKc4M-@wNp$URqp;8%7O6<9NKR%HiSWd+(Cu3s*T&RqptD+aDSooZT-DV?_XMio_paW{R5betB;OJ7?yH0 zO`q>?kJN1|P_4p=C54%3DJIXu9%d#Zr>Wkj9nXBahV9GMJK2ytI!Wt**cisdx|3aZ z4Jbj;$B*Vw8bHl1)L-YOY<*5fDxgw$6yK~~$9qyn z>9|=YP=)8dF*fI;%wi#NbN}jwzyO8Y&-G1!#FYv4WngSdto81gsw*g=?4v3im!mZm zxtTXKx_~#$nV4IF^d!kExsR)=nrKzXf_@TkxQVKc!O6KXY>`5ui)}R(xj7*M+2|vh zPN>uQaF;q>^RwssDF8JC>#4n#1LH~=SNt@5F|jq{U7?o`S_tFcKadmL3&@6WA_5v37IUQ%5)R84HR>CUzYStf?8;CQG@5quGa^XKH>vS zCGo%XO1i+FLx?>+R(>bXLnZRtikhJdP`XpbLd5g3YJPMB3oO$N7%?um-zVb{(+Lfy zMxy`rVv$I*BvBKp3S}hS6uLSm%~F5$cs^TYBedFoJ0YTcqpddMG0&l6xaF)*kcotl z>Cy&F$=(m7Srff!1FMkV8fKB~>1m`35aw4!HLsl1T~YPC3QZF?d*%v>3L1 za{-Wvx}^5pu6$8_D@*lUI?;wR^uvScX!rTPX-5mR!q~XV%d|yTBl>jF^x*;7{&(hgZJWJY^nSH#crnhD|31;h?+dIR$;-JMKdZn%uEaSMAR(U?7ufE~`hITSNfnUM4n*DHezO(!$=EQ^^Bhp@UlZi(1H?GYdNo z8&1;*WdhSaP6vmWVF`T3qAE$+n*PO2*m1Icd@vtxPcBk=b3EJPCkX(GMhoVZc+Q|i zqb@kt!=mw0Dc4y%pmYL++4x04pfhS#g@Gtlt8pj~D^gq}J?_qU-3H{MHf_^`y;ovw zNTi|XKU3>6o}Z;fLgX=r9NO52E+d_%C>Cc)A+_w2TZ>wG0C(r>8pE|!AH*bSQZSWv zf2M@y+|L?{28hPiw1Xkrx2KaU>(92peYVIKbeR^3RUk9=Oc2zjTIHBbuJY?S0D1b9Z^w6g>jBd7pb81i(@1!ZJ zu1f{Xa0H77W~ha&I+oi)HhXmxm85l=i&0c)MKDz}%mf?fh`sIt54`;N#uD>!RvR}Vc#F-E1;=g@i zm5N`qGbT9Mhuf1amO&<%c9X+#M2O>uc{)4=>p(%hck6fn&-h%l-Tk@wMfD|S?!dca z8~vHGI1a#Qg1`02CW3_Fl10fLulm?Vg7ZzC1a<$J~f?R4l2nP)x{($rbO zk3sJEYOHv8>7qoV5htXhW@~Du45G*j5+~?VdfRDwfm?)uScSi7n5}&V$^L5ic|T#$ zF=x-#FTG4RL<_n;i?dEoe@5-L&DMm^eRe%HSzAsed|FeJ^02DS&gk0R>o zLp3{vke8*Cdq!&_V=G`abji7wuOVr)?tiV{pKir!9DzE zCDv!Sm{9z5pL0#HxUYqqGa8-}@xnumau81Fd~@|=$ioUHb*!r4$62CMIuNQYK6fTG ztt?ykD+7JtR#l3=55jqPv3G0o>dBPF<)*R<&W;aB=60&PeOcFiG1p#q(&^J@#t%)1 z(e0>+W@#`th4GPZoLWNElKC_#B|;Z)d0JGn4M-K^EHY9n^{PP&gN2`IwV@|EN0vHF zuojU=Sxr}yLn-F28XBSYnd!B-A_ybbvl@gTtVdC5WwXFT-6B2LJw+ZHb3o9}>}V8y zXA`%%ThA!mb!ZHm#aC>6cumE$zg9pWlw-S!Su&rp#rNZc2n!{+5%8prhJmx9bd|9# zg}j(GT(kY68!1gIP^_lR+g{bp-4>?haJyE@09!Yze#oLo*4Liv2icyVlp*UYX0!^X z*Q$hu0q_E0O2yJhs+OQb0#T@;pjX%%esCH*WN%*+Alp-k^6@NN;e{J#xS61t#F@nm z6HC#Q3$fIt*S48d7i1fhlOW?_9ByHnwL#dRB}=3{x@_6WyjmPP)lD3X`*xixT;r>z z$U_qy?&N!mZi!gdPW-ma^}&s4AV!;{H9t5$#BRauDeOJ>_H3)#@NF|t2cqO*&=i;-V~d;5$>%uq zjQrvXV_lmh`yrVltm3BLIf7Wcu%2P*#BQaF>*yE;FK^lLz$=pisToK!ul8MEtwr-uJ*Y35E5OsI2&rh+Zy^+64 z_l7F`d$KjKn8E(4SaH?fvjsK}ySzhWx35fO16_4$>C#FkF7`$!DwfjPq zd~-iyC3?aQ44q}jtbM*oU?~{;YMM~6cfc2?>*n(0=4^z4+9p+6T+i!n6;;?n(>810 zirJz$K%kDekJsy9o5Sx#lTq0V6jxa4PxtIHz_WSROq*(sIUBy$8jSp52F8PNwQ^W2 zZWzK-3u1q~t#!?cZl^i`Y1)f&W?^S9!m_%HX~*SPc`0KsXhM^b4cSOfgqJz1O-!kK zrr-5=hu>hY(_cf|VqS^Gd^X+EK8+aEY8=BGAgVdRB$W8YHMJadwLDjPr(rQ*F^XOd zP`1OV7{I({7MQ&(*D!-hhgdx z9;%i`tYey0CuvQ6Jgt~!mm!78nZLEn<+5A7P3<6&YGZP$q^{Vj)D8RLhMZKDARdgL zy6Aep(6I(k6-Z#JN3n}e(2U=)dW)T`YxW=|6lfkEzMPCCQA(@Xe({72F}Y1y`E!tB zO$&9aux0Jx%V#sgpA^Zw8;c~)DdDs9&am@w3b zvYfPp_qxSw#8kppyCkWc!*o;PR96Bif#A}bTzeE;m4r%5WG(`&Nf}$7P>?zhX-1YJ zi=aol@`c(}pNyqiYkk%oAg9i&ZdsQV>V4CT25G%L+q--1CKJQ-Tb-|0X4+Myj@h1j zCJdF*r_%y6w-}f@@0gtqp|i)V*}PO?5Xui5;bQt+++>~rqp~iEA)q!e=gWDb1zH0% z{x^JF52&Cbb}eMX7EV7@*_kd&9Gy#f-9{WqM&=C6jm*(?LM_s{qJb`(Vw3DsCw{o_ zsS(v3V`Q3|J_T7K6xQ5+OaiV9btoIQj#`x`vW`bELA5rU46cjWg<~^mTO-?xXZclC z(nd}bRnxxAf~o+r*zY!}o`u{Gv15}V32fV{Y610=p~%gxVV$`YHX78ZtN z3`ziGO%Rthsw;~)UW-X`G(FZ5a<~&$PVbWBZiV=gz4&cXLgX|VemH(=<`g|3cFAL? z^&>Ud?REi+Q^wazq0<_3T;OaM^hw8S2nfvGdgKcvkXVWnUHVgKr#tJm({ zxqfwY@BZEEkFGtub9LheA)O|5A)%ZsuQ6!0Ei3^1j#n#=Ro5D02)3e`JNheT*S1}o@qzzj zzqc&vHc`$K857UM?)2p<>Lq6uCtIu9uj0*}TY5(Sca)w9IBHZQqT3}_93<8%Q%lWp zWo_VWyJgKkboTLcHq5%QmsH+kZWWX)CoDjbD%wOf4Asnz)Pn{4c|SD+qUozq$@5Mv zUoH!@&B@^r=Nj^P)+ILXi@mS{FEjZHk_KG8L0290(_BxuDCjcpt8`e%H;ZAk?izzz zX)oXwM1QZ%(Vw&f54>MYYovPmu$r>-^Q1>6p7O7g@)~))j$}#?)8EfL21}Z4_u~cf z&tg0hw4cGaGz^*Gp0(YZ@2rwC0=E%hM=s6T&c60*43R>5kf7SV#N80Xo^9J+R1vHR zrvA!wQ<}8>9eOastP!k_^uarOL0`BdkuDRxExI;%;O~^lM+QH7syXG zH$?mJ>!cZx7Nd3sR7VY$S@lEyrWxduCzj6zCkTxuJ!Pn!+}8BP0XEeS)+@yZB~tzbnwB5U_CY!gjT@LBS+ZDh5%0vj(w{#JckP?vGDOF`u!?)cx z7&6DSP*~?M?y$(A)w4Hpj0+13i1^M-&U18n49+#50c_RrA=Wu+zukx1q;8sly1qAD z(9$R8R~T^f^=pyV20Ab|d>q@bptk5%2_KjrLa_gKliMK&hcdyf;j;?{Gn6@(cAqFOsX! z@BYf&zReS`$Ss|KK$UCvF5K23S>(;lD6_aBvE{un%O&YF_}ZNO6u&n?DpaY=0E;W9 z5L{6qT?&qhtl{8r``ZO`zCTWLF~uzJKUFlxm}`i0>_!=z1=$hFEm{&RqOz}is93v{ z;MwQ~TE(b!N`s3!CdrE=i_@m0VpikTLxM<@r4eHgQ(a6`v#!XkPf8$|wG~M?M+VMvf{B?r(?LPtWU~oU^bn`UQ~f*nNH;_5lF==g7Kz?c#Z&b@!(l+jZ=Nm``Z38zIeHmkHvmu?-beUaM4?Ui|IT8FrBd=aSo2^Q0XoC4^i zj3P~y;9ePC%k)^%U(M!4tWNBziu(=IS~2H?L;;w9@r++8)KBtUZR%4=UYXOh_;*HT=h?3OeSad1An5ttQXl7EG1 z0h_^QIYYU)VCCwrT;NK3x*{Gh7QlKASVb+*cB-_KyCC|0Qk;oYRIy~To;~Fr1_TU3yTw~>7a48?aLy6$}8e+-h(jRs8^B5K12G4DO;+E{Ooea^z zKVPP*!>Lfr*PsYKGTOV9RZ;@_+BTJC9HI8g)5|xpEcuXkTFPKaNtrfgg{H$IzTW1Y zaN8ZPLvJusE3Nsef&h{+C)ZX08wdP~2r6$P_^hl(%T$D$5AMq4v%f<|1@uaXX7ftT z$orxQ!enHEDU)Rr_3C!0NZ$`O zaqcSrMjb_3bn4hK z%cXS+b9vB5`Heu%35Se3Os`P>q2(Cob6yT8|14s&?uB*$;m%P9!Z~%*LxFDSj7H}? z4waJw>JtuZkU%vG=Z&x#Pb*7Unk1R z*mi!s1_-u(VPPKZ-nr9J%{=t~v-fT>awb`R-*6VvYI}D^d(+NdBsnKJy_LLFR(H>A z?{rPq%&>Xsri#_1NcQ&ZvRk!v$s%)DRasqG)g-5v1_aAm!yfq}w|o&S$bex%5-bRY zUu?mCFeC^z3}0Ss`N1#*0|sRI@*rEV;1~P%Kj*~d`|``G>e=yPWwU0QnfZMYCn8Rq zIC0|KqGJoBpFY=i{;k)7##jBW@zVjPIa04DlPhTrOB_bpNW1u1L0?CTWn-6#gUu0! zJNyR=6*uMX1gRQ%gO!%P{O+H!=eZi>K5L2Thj|~Bo{C<;Ykp(&nSY(+YET`zJIdGC zHY6pKoTSN7XJ*M+Ppz?6Geypumt24$wH0osQeVS9{X(xZJ;h>l8pSCi=cZBHN_Nux z!H7_Thl~SFsufwBtXnE%nIM#vt=jtQhLDv_X93Z<5K@c(A6o~ZSuQh?mi6zRKCx16 zvsG3?>1@u{S!+?lWxF3ZLj_* zUj1x!x^CTWw)$t+e)b$ie!MCYo&VGR=4Uz_s~x&7!yBmbPbSB!_lV5q%eT41fN3D7|K2z0Lf7B>#M|`VpG+{Kzxm{e zKAV;D4O%E_(xqG6vE^zsJ?OZ1YiO%Viio%-X@c&Ne4plyi;VDScl4C2CddIvHUYn5 ziT%M0R8b*0dn#`xB8ZnM{@I+sO_w*DrYE)NCzY3)7dYWW(0$Jn)(G>QLkRrXMJFO{ z<$$1W%VgVxv%SCbXtYZz)6@^UV8XGLoPhUFNJs=q=r{&vnlW)U3na+Nk39AOtEnNdG8R5^E<0GhUq_O9xM~4KArC;DJechUH|KJuW;P=V@ z;x}U%5>scIHwkp4xQ8mtb$vYYRP>dDc=ZZ0t$(3AC7N0(hb``F$#01(?tACS)!}Z~ z=nio#QE8kWrAUOWr6HpToIJ)qumzbSS=>2qMt@AeTe~E}Bn8Ms+0vg(4j;=*1Lbh> zw|S6kPA9v%AJH7Pa&@HWonZ}L@!0CgrMgi!0|+;kZD62U%t1`dx)U;~!^R3jN|(Bb z2Soo#!O@s{g=J=(w!2W20jU9F0YZd0K&FR5dTs4j4n+-fg?b@k+C1I?OsYbBy8>MY z7cZ7xXPh`SHqSreN$8g&{Nhf&_(@QtxW;!_H<2%6FiLIApd~lpn5h7EP&?VLqmNa{ zgDSd8J;NdrnN2!%d42%6TJQzmY>)0Mvd2&*r2l|3d7Pw(K z(F1v#ScyW+jS5C>je=5S>Oo~XJ0ILmzIv8VKab}OuuPfnUCa4S`seZRbTSo^0xNDG zw_U(6!*XCP?CD;_E!|RZu(7YpIwOV%)wU`1!6nWMBV51^;T^Uhq2t=YOABgqL=v0B zNHV2#3FbszJh}`zHv^e@!3@L&VKWpefDN2AsZT>{!b{P$Hu;3XY_I$KfuK|r6Golu z>H5ExMMr=eq`lzCGCH?RN@NleeG_9$5a`R(1)@@D!N{#UX>U~ug0u-uC{PU%gZNeBMdD1*qiATb@X3NId-TA<<@(2S z|55S!XXDZCcF&hmQ&Zz1%iQZV)S+*%@O+`LFuTHzR}Yr0)Q3a7CsgK>s!X`gBN{xK zkO+v~&F@UQz(O5RQ!wxkn?BH&ORokbJusL&sl4<>Ne)Lt3y6U>hFA?qbFb1H?m^bT z6v;z&#!oMK^-Iy6S(;blggV;kF`y+xe}qSOKOo#$f{xcs?olh)o_jDh|ZdAhrQ$WbqO~E z^2nMeC;`1lsIikUaV$6NfR;|B;8MQSBI?7q)1Zy%6i>$8yQBTl;f7sY3U%)i9XYiu zSlkw;OMlHqus^}Wf0r8@zG2{;;w#=^pa_02*&y|@V=zG7WuMdpc%Zv)Vjq){7)j4<#i?nKLJ zSKuD#u-xJ>rI3C(#;`5D}wmWA+0GnlgwlI3gS$HGXezPF9dR*BL=t z{|;`*$DkjLFQyjD(M44E?(O^6??qQHl9ZTBq~W>{+16-V*R9~zWGRYEe#%#e%07#{ z7{e~xS#J=R(zvIwq_fna*GLJ+{Ef(z@B2+;adJn}%L!Ga!5Q}6*JUr}+v*~Q`RWh+ zau3@jf~!=!&E~N8RZMTG`;scLKubuqJKUcX4_X!02PWVCu@fqIG-%;^c`%w=0L zC;pVGF>g4a(Fj{rl|C&wT-(NqnH3itzr4qXS6d?#d!WYAa<(vq0)0FY{O6e)7CoERBm|`KuT62^G4u)S9OgKb+Kpe%S}a z%N}3;SaYQtv8*PsnU208!DYWE1i)Z;Y8N_~3-DUH6W3kAKJ(g7F2x}17JQ#<0P zcEb_dsj@TXwl3G#rfT-0#h9CfMdy?+k0ZZ?0nh1_Tk^J`;GM@oL+(>`{z1Lb-@vpg z<_^evlh-XzwE#V6h;k||OA`qSo@nT>d!#bfkOfKN%&K4~_>1^Z<~pS1G}#T!oyaNA zz5^o#At^qQd>0pp27WSHfSGdnnB4;kUvkFccbdUr)unQv5d>PJ`uOF-o) z#NhZ>BWm?K$IGBiLhKct!zP$_tEj?S#@cUMrV7sGq~ukrK!96Y@hm;K_GSs zQaLWmGgEz8**rvpxacKkW=OkMqT<=vRTIsnVl*TgH43WS_f$0fB?s)8)*2_!eqMHo zrhP53kjZm(^5Rb|H39Y{O%s;b>koBoXdjVNB{XRkNNp74cwvQAn#NQxeNsj%#Moj| zM-CkZM^R;6q5j|^x?p0gw=nl{14$+NBrxbIK()2H3H|z|kNspWVukNJyS&gx2th3& z(x7w|@tq*04h;_`2ZP91nBM90yk^ZB>R%Us(&co^{6^g3|4(E_d1SW9(RSY!|0y#S zh)vBtSbX)vq%N8z)bqAVQwNZSPyrU?Ce5d@UUhS(X)$(p)dV363qF;p=?e`_)>$Yv z`fdHl|UBoQ#z9FBLMaUy{8%H>vC>L3+K z2%q)rM!qnrrTKRVeq0Oqix?XANtgWakY-OhvR!qtUk4Xvl-e+1^n;4K;}oa##b}5} z!-vD32bgXh?Oy0{HyujeBUJR9Ct?`dzb-0w-^B%GFH0AT05ssRZ*wEjBTE6cwV{Iu zFW~4j0NIL)M%46c!h5~VF-&>iZnpt*JG^9rlJfG26fkN`ZQ0t?5A!|OIcI^@>Bxqy zN3QUTA?iSCTv3WiPlcZ35#~vr;7HX-e6-#T4__7nwHg0?UIk| z1kPNA&O7WS7jZ?f^J+=_ubdhoL9l<3i5r#`g5e_hvt(Wp(fPJEPU^c8&a6J0Sz&_f zC7Ke?7hCbyvs}MYZDwgo=Nx-0QOg*)_W`lbzvSJ;UIv}pk5s)nB0-)+ z53=@cF&kg)b%bVtULbHt1Lie(<`G9g_yt^p%q;Gr|9-=q^&_zCrG9$WOu1StN9M4W6==TbL^U8 z?~5Hokq7lYo|jF&8;T=70Wo?oC_0v99l_<^#e>I0dlg{h_Qscjdy}2xs-!rMYQePq zVbTi{%~yg*fMbPc(m(KGU38+_YOJ)S8BEm(^vk^(Lcqf*7W3gp$D_k%*cU@1N%p7< zST2O`flgKH26!d40Fh<7Ki@;ax%6n`$>Y(pd^0x|d*MNju zHvojs2O+Zb#I-zfXh8L!MrX4qMoi>h5X40TQO#m%|9EeZ0M<2z38eMSI+8n)%EwKq zMvf;S)=6gh}X+%Ys%a2hY03-=U& zW1ZS;vW3|hkoom#K%4eUHF}=YNHyU}w$LjS6t*M_$>fZ)>@*qA4c3xNRBi=^$aN7Q z)mqtX%!u1$RVH|Ic!HZGPPNX`Z_R*aG3CFlnb^v~P$YP%znEz>S;u@#{%_SMc;$os zC$Ctw=cU#nk06PyN6(k}rtEoi=((OoGUVs|A>@PkZg5b0Ah6=a7~wb5is4wq&5|xGiWSA?5WH}DxTW1j`#RUs6kti}6Tqm^yLb0$@7ncy_w$%~=I(0j!xeL4i)ITk z{%AVP4fEI&4??!wCQes3C)t5y|KK>;SJaBcmLw88G<8XLTWQ;2m8ufFomy75Y#%*4 zy+~M4ef6-nr!#=f#3?mll2$=NzIHQnULs$D#%iY+<)xS$j7=qJ0y_eEE?4&R)LYm(SjcKed699SQZlDK;X zst`=&CO2D;weM96s0^g0K2beXs(Ex-+1HQ6JEvV1jESpVxi33)&hDtG>S1uO4cit# zk!3}aD4~?`IzrY=v)18eqmnM;4(&9B_l#p!8-HLBhsq>;m{Rw|g+}4tgT=+C-}|k_ z#fRS;AMmls$7_7J$cjfk-`{Z%|Py~DJ=3OJ^8#ixV&!}XL`t1fA zntjLvqbC8w2V;nkSbI4*#1UCqTyz#B_}xj+O#Ln=)(RY&Or}DMM(s3+h$Rr+Xe#{aE+{j(Mex95GPWBaPNYL2<}07vx_$S`cNpt)<#X3%0!yykn5N%D%2gfC^w_TM zp#jreJ$|25U9-|#e7(_&9~jIVy~V}75sH(&@zG+MoRzQs>MO5s-_n_zs789*6w^xh zVh4FKG*=8s?cj4SUTQZmX=;_p`B2(Su~w*6#%1X%Y9XOqS~WhBJ6$Qr3?yVvjCyM6Z_LcxF}_)otlRlQTRe>0-?ucGV9xWMKwUm;s6y*GPR;utNqS+j~1 zuAvK49h1|`${VJ5c2#E8!@lX03O-nTt;mjI0JedpcdwRrbVv%ZBJBesc7JC?{N@A> zp+_-^Je_6A%D17k1h9IVNJ{|DGIrA|8(>4uqH{JF3|Xwq3iHjj5&)4v4Dpo@AH0Sc zFSj9H3n+mxh_5b#pe7V=>^tNaiy zL?iW$yY5;)LrbX-I?PrbtH7>Q- zvJmoiB9+jz0X$yV(*6p`?5AwGbx^HkmUxZmNCNM(0 z%f|`e;LbBt-TRBvqi2ZUhogt1r?~jxBTyvsOuq!8Rn5x6 zIdK_(3gj=J_YZz7a?%ltO?WCIcD|T&DJns#5%>9I}ko(09 z9;S=sJ|ryOXbdmtEaeiO@Zf(=Xjp)vP;bP=9R%u4N2ne#KVb=5_~3(me98GZ;$w8Q zH54tv88&Mn5;m-C;IwXMD%6Yzkjw#bCIqr%@biu+)u3=_^kFU06soWTOk2b4rR{A$ zn{eTcq+GPoV2$pX&U$gYU$#{ZtOkLAJlXv?YL{X)mb;GfX?k>eN0Je<+rhHbBnmx= z!};bjx--yJQsMY$=j&V}yFJ>PY>x&D$NOV_S$E_vT)5Qd9AEMAq~H%;G=;;mr(f=& zyM-N@>o0bsdF&|F?%lh7RY!;3>h)jmagyjg&_6BibAb%bs7jeJl-YDt zRA)*bXqyP^RBLD1($B^q<;t|X>y+`R%ylt#-}~1Gaq2`AD4*gJ1LhGkcH{cB&V;$!BaBpRKElH&us zF1E3K{thtHfbly)PyqT}#!zZ?21V@5+cHfgf{~8v1a6Ruo4&I_+F8)wz;(=FDkr)v za(7eVET)!x4~Mk6X#}R)HqKdpDhWnwQO{Vu#kQ*l&>{93Nj+Lnl~EiaJrB~Yb9&!C zGu5(GIH&|#@N&h#cOqt@!ik7UWtw>L+v>Glo`jU-LSSp4Qb0CYl)d#JC0jye9{~kv zOldT2P=%Ms+vtoGVU9^1jN+;smh_x)Ig{12`QOdYqC_|MIdn;xG4>QFVszEe8lFLQ zUV$h|^yD~git=<0rPJsw+iLTgm(6I3la^TKMw_2GB$kkHHf8Z#MX^!@oNcg_4EYR)QRIVf0GkyVkvYoSl2Hz3YkWJ?bav5+p{OilkB;)Rba6 zhKuOfE`}D+v5xqgeB|t$g+2lWmOHWSObF{LFlto%aLf{PmhwgRWQ!%6eKDVm)-q^w!WXUwOM8 z?R7NiMd=~D;|4fYu%Njb+Qq~SPg1L!F+MuxvgK)b8~RG_R7eR@|L*8$ymhRoP|zhG zJY2+43)m&b+|UY78xFfqj8s>W0aH&}CRbZr$z4jq@O1iU5!wIYh;!WDWAq|B)4{id zM$|tpH+yIqMpQXVqWe=Un(M}FkygKy(@3syM61u``4utd*@y{ zS&DipmM$fZu>(cevBJ?sp;?lf-1DWceBusU`i5f19@>h3NctJ+hblPe8qjlLC(^WW znvh?ude`XrjrZ=}f9LvL3)fuk-SIh5eyCnT63lbk@wKaIR1UBTgzhxR$~ywBlA zH}T>8N_aiKyO%AraQbL+OpLk1lMkjjRMDI8`_A)O)|>5$I{W0pY0kq{lM7GHv0tH! z(yNMAo@#u1UF6)-kq&HF(JiJX)Lb4~#PIr}yMB(uEMkX-8T4bWLop$}MM-JB{zdX& zO$cW&6Vpx)Z;M?nO|B*b@BFNt699_`zigW1m8e}&t+nR+#8*DqdESIWqK|r_YwloC zJc{MfD#*2B6*?PMgwMVxBG4K+5U5iIi|op80)&QDTofj(tw(H6D{Z%v0Pi;7R7w^L zlz+REePukt0aNKD5SfJp$D^!MPCWkato0)rJR7JCYet~KAjMKa$o6(6)4&K7wbtwa zqxPbO^QQhaF_>3{0b2fG-?B(}-6qIJJ+1=uKw9R1JbeT*rpH_84yU>yKT|?n;vjYl}wR`6h&h?8usB2Jt7iMVJAk=3ba&#XLD0r7)!M z%fF}*(8NW8o)F|LH3Ey|qKDJ$KD(IOu5NVik+S7z>=|3MaOG^aUipy~&lVtAhZ@Yi zV9nQ%qO7tVJIARfj3`?SEHT*`E&Q+`JFlTRQ3l0-!OE{dJHDubi_*L5wjjW6;;Ffj4}YL(?X)R1*Xpi*c|zI`)Ldu zDQJ82lt9%W*-9TIHp4=e>0jd|O$u)P+fT`ZlKYT2(JYs&mWj4Q`KV?orRTvDsmY{F zPr%Z^lAYR+Z4Fnk(kiSMY5tZepln*XaKn;r97AQBb1AlOE|IF$9MufJR)gnz_Y{#U z8;$2@xOcqyT~vn>nUEDdByA%(1^3JWJcSWS?>>V!;%(*fb1WIgO7|lEWr`QdE;o$< z*u)BX*ak`oI+66k!GxA;CpGm@eZ)}>fLc?WHl%)Xlj0s~^YQMO+!6N`iRjJkZE)29 zo<(R0AXXqlccg#uzeFsem$&|Kw3Oa_nkE z5TQAv7*Rm(4J4f(XPRdn9f5QmN3a3Dn<%4C);&EOl44O5It)t1dDfDe9wTK1zG(gc_QVFuZR z^DxQcv~f^*lq8s3`gm}FLscdm=3EnQ@~+MUGn1+{9;JnoRI$6uX+Us_HZt?87<(kU z9LA?ur1><<<=7Z=?WJ70f7MN`TG*KDT>54aV4J|Y0-rYUHq!jObqSFfjNbr+f8)t@O_ zK!OI=l2p*$@l?>|-1MvcsaOP^nq7h=kq258rc<-3EkSp*Krg9e@ zsvx;QT`?a7DUR+nho#v0=@uy}Ngjt&^5A8Bmyh?CUPiNWL}a&VdqNX@OkU}lK5m%W zND5%rKcE|tL9@~+TWw3>w>jbja)N$%jZ>HO9GR5Ic7F?5uhNJJV%`SaQ)yKBmIOO%2|(9I2Xbi|ndH-< zI%%>mN_)$Q>FQ0BnRco*(l{GKc{wkA0?_T`K<*J(K4-f;g6afc8FwM%xutX>e5Fa< zGwhFew>)!lR8gJ>#B+qf`rK!dMk5sR5sKYS}HW{5I(D0Py&kjBQRb}+BI58sG}3VWDChcV!@(cukLYb-ceK`8^ zPRi^?+#R&tq_k$4RrvP6v|1KM;ypgx8db}022TV=;}!fYp}5M^USYSfXtyV|-ikzR z27nNL`{#w{)~Jfx!!ivc*B>|3(k-D0sfgq75`!lvti^}-@PBi^E-ojgON%99!_ILZY( zN>>t?S-wyYdcPKQ1XSoKx|L7`dE+^d)Ef?Pvi!FcUuNFYz_)uBoilkZ8dM$9i+IKz za`ZZX$^CDLtKDH~E}U3Lj;G*oygTh#%;V;Gf9Ya1Uipz{)IZ&sie-{{G=|t)nl>xc z0t4n5*bA||h-&?wG6!p#vwx^hw{m|>H_+?ptSLnb|HfS#X>)!&!Z%u}h#7QSD+x6l zoT9%D+&6dHCWwX>S*^IniTrztg=nM)MCk|{k+`X;lQ3*&J~JTtWVW<)1|s7xS4wdm z>49)jSY{cWSWS5@oR}uSpf-nOk6Xd^}=mSx!;9lN37GAUZr zQz4DyZH%7eb4H-HC$g3Um1OoIjVgqr=VtrXa*mhZ$_QaZ6=^ib=5%i?QgoN_#LW~b zWz`_yl@ZU5wgn|>p)qLAEij=hIjNk{!r84{YZ6(Q#fgXbxk54NmOHr{yHX zpNOGMUyXB`*^>?bv&yE8{mI_OE{CT@>DQ+?Q9L3TgTN(8V^*i^Y>(wOtWKY4Q&Z`l zTR!!#b}m^()84jv{rVk$o4%d4w@KepD-4Y0()yUc*SVK?CO)Xmt=wKvHrQPt;y3++c;D( z;Zrh;xPXj3)l)Wa*W0=*Pcs)&je3Jb1Crz|8=PTV$_{t%*D(&L(nU13WwR?qav>2k zLI?aiL=Tkx?1M`fpq2u0OCMZZ@(Eh1bx|j6?nYM}1VjyoSk4ZoOT;{mIXK3zM^E;M zr%k^;CYriwH1d^ZU{WE)HnK1urDH*Rvd)2Zd$O0Y-XRU7gr~NBmGuj= z!|%kY$r9Ui?09a7wHINDEmaC6u`r-n;h7V+Ue4NItAU37wWcRqe48Wo;!z%Yl4b=@ zf63G$GO`X90$}#heG%ye<|<;yI8yaeEy*Be!fmA~W>n(Axp0?^E@(f{0F#+Hrl30Y z3#5-JbuF}o+-;s)fX!(mldqse+eRW1a}g!BrBa&3X+6$G_fn6h23`4WWTY7 z@)GJ_>I|n8F!|$M?&%6??5n;cfs5zola1ZSgJ`N!)@elPFYS&=6cVgU+%D%Fh{^|shErI`5}|m352FbC15jrNMlt}3+L_K zQM4`bv638X5#lt-E|V^+uddfbX_v5}-h?cs&G%(|uEgO(lUT!Q;n!5|{vHwB4o2>> z{5z0*W>GUo@{ttdk?{ETl2|IIp3_gHwo{^VnpJx@-@SSN?zMH2p(>+B{OsxHy_>&L zyFXv`OfT9hJvd6&;8^p9HBg@oL%myfuH3co$YgPAY^>c|Vyj1Up)QF2?bJTGquz^UwR3tSr#pi59&YJtn_oK%({i9vZ9aV_RGZvsFeEO z9PDto#2>g&klJW(_aS>r9th;Qqfva%Z{xDmUXep)jfrM7nQBjEsQ;}9w2 z#K0lX>g3S7NSN=@JfFW@qxXRLCzMjZg@({R_co@FKkU5+N%S7*-S-u0Q-l=`PTv8eKrqV&@nQMt?M{Mh#^rF|7>A*rydwiZQmum)Q+dLVYN)(SllW@6kMR zJF$7vj{XuhtR;uO9iK#*pYMI=JKwQ8Avd^02pLtIZ|(y|&*C6ao+2BxxR~D)dyswnBY$iKbs<5m+qp*)+$&^)19usa?DM8ey^BtDHy`P2&H4%W>opA z!w@A0Je%T|Pa1EW`yQxj8MX@PkIA6ytm||bK4v|Zn=~U3@;J-amU6JTAE5wX2)DjL z^Jj=kDQl)3d*d)=;aUtbTNZKJHxB8N#LMQ|YMc3sj`$+)(-q}*?2oVLg4F{K@= za%ZN;+0(9)@gt4%%uM(K{!Ce%t4%8Agsvp5i+WWJpuvcJ0x9vrCmm_)g-?2Mv47!{ z&ee-%=-N!RI>GyV&obRy$8B)srR&*vfM z78Zr`!YBPP7l^!^j4PknCq0Rmy1TL>qp;6$|@Am!{buZhipHvEhqw0$I zsQAZM?^5w6>Wg{f&HdF6dGq^BzaNj*S0D1|MilJHswd z(Wv!*t^M3Ns{K+|U*e$VCD(rb+}b4-{i7!oMe`b^7tgKTSLt8qDs8H!DEMpV);8w$ zAhHES(XDf9hbsDuT`)bhVw5~OxArGhvJ-D9HCmMYr_QbY3o85NE~tS5x8+8Kf9c%X zUpTFTYoepVUp%+=msFv1ZlZ-ony{$%m(Q*J^|_-+xw4|{zk6=&-&fhriH!VBQS@(| zTlo&2wx2#oTf-ffG9Yt#X~y;)anZ`FGB({auypBnr#b5(WQ< zb8CN31v}Rf96E~q{c~&oV1CP{I*XG3@Z8$Ze;$A*5ii?Hl>WufudS-hGm6sx>F3w}Z>VM=Ve(BbX?x@99*IxUPwO{p?XNwk1 zQMCNVkE}ga;h&y`>kY3hc!^`}i=CxD`TXZT$Hbo8m=$X8i1x5KX1~h%)9-e?O6agx zol7HeEGu!+lCT0NtX6w}rn$C~olLQ?6D!lnM)H1OMNV2uwhvgTlelVPlBX6-?Dy1m zZB<&S&%kS~{CrMhuREtFwlOQvIX%uK?R_T&B<5%(I`LUEg40Sl1F%x3F)l0AImda& zwIXNdX;!>@kim!Nx0$ymE7IBbiUnDrP8u#7yOo&{`0Qz?9BFS_f~-9&@~Ztz60QB{ z5R3Kv`1@brz@hul{Ib_ik3RkWA52femig)6JKy-l&wWmp(YkH(;Mq&(xdB+Y4-dx= zA071uS1mANm6_}SVD0+dtM5?b z%3C*Y-Ms(n@?O4i^ZvVXnz(WMZtn`|#_ry~dG)d}b$ zC*W4*#63B$ZFBb|KVKEx}_=6$;KP4CT>V=`E9Ey;!D-dki+ z=PHn4@74xBns07y?S31QBO8x=+`kE>f%$Z93U{Oqg0c_g^ybj}Ftbqes|sbtOc8fZaFSKPL|rvrPJjcW`~& z#r#==7%B*=`MzZj^;&7w%1=n%y97k&s|b&QncGmgeN0}Ly1hF#PxsYe6;H@zLinXp zn==;*qGJ(@WU^N~y(&L?- zF=4IPc;OI_$)ngVqZ|SGV(U~wQ_u(mjCdbB!OD;vJqMG6l%&xDI6U^#QvlVaw+?YX zXRYF3FvTllW4C_k;Gu=(-r87KW-XJu;2yWC-SM!cIc0CUU9_Iby5xN(yF@U0cPCqR zSvb7R5-9~O&@vprb`$27>*AouUC#yJDJH`neAqR&hyAMiN}{g8 z0M=A)PHe3~Vxe?f;;cFmTZ-?mBq1cyXtce^4x;44=6{q&KkIl~8r4SR$R!=SQ}wkm6<&dc1=>RJ-f49tN$ADYXRQtF7(hg*}$0Wo=&k*%J?$GYYN zYHdV@C6@|yo+09MzB3v0@02VbJPe0@0^Gs}X^YK$AJry4dPFc6rL?hGqTx!GRbMn} zu}L{C@>18D1=JtE;WeW}k2?K=iaVi^K3Q#?3fS&H9(?VUH{?Xv_e(q)zyvULWanVE zeZ3EA3)e!mREDef=`WSr**%^&BeYCfxXKVFCgD|^i9y%iWgurpO*o>(^c2so)Q(S>I@pa56S8oT zp}^1-+ymWyf~RITT8tvN;Z@ZLU!3WPnq>;)@~;Gi%xSfs{zh2#dwif4!U`W z=U-&$YqYNlWi9h9`4EfwYpJoTlB>j!>8trA%d>F6 zVP9}75=fBien6V*Km1Nt=cRjwoaQ;{{?$AFI6B8nUg`0W6RwV8zR$~95^aI;Z!I7( z8BMt%ikPG0y-kWD)N@14gbd>%WaT!u3Od%}%4x||BBv&foSdW%ta@-F#I@I7ae!Js zEk{bBMv@*L@VcLnkBg5v#y4CIYZ|;Kk<)3J?!udOs?5_`FOL9B`fi=g=yx3bJorK5 zknEMK){WTQnf%g@jkh=TbT$)u+Uo|@Rl-TGtMU5z+J>IHUPB4RhJZ0NynEJ)3Tc%*4;T7aYq|UyhLW3 z$+{_I8hAr$m_h8No(qF{`YuBCWtzkl)axeL=47c1m>e4Y4Ek3$NaG1}X>AGHWW^IP z`+1|<=4PdbR%=XtlUg0AK9)k$V%g1ZzEp9VHP?j>JWp(4Erw%XoaB`Z4l_wgm^7o7 zs#W(bAP;Dg>&?z*+s?S|9myzB2%=-y7ZM^`RJEk7NlxQ>uQ&=_=W+lm@)Uti9S%S{ zu$Y|qn3I<2y3Co}_9h(~>WQ?j#5z$* zu7|!Wlj|t$hXY~WDM^_k=8;aJv7oiWbgT`Bl1B~`sG7F$s?lLOTIa!7k<^vBTa|Zz zJ!laYnY6mY`}S?%S5d9h4LaGURnY2d1K@Cb14W`Pr*3EvDqzv_(Dt`<2-a$yaxl=D zpkq6_F(HXpE+EN993`e$e8vYcXR3xF6r9#0U0g-Gvbd)0*jd(kl)3D5K1r`fXiC(VErm`@Y-x<;Kn z=tj0)9nYFAF=b}s<{l!|5r)h^_C+^j@{2oJUYIdom@)UU188404ciMdW;SC^rpYFG z@NA3Q3pQV}OcC*e#bXb%GK;H(P42k!?5YZ1PZ_pfO4Z!S0ACwV2p7d|U0&`T+h-E5 zZ%!v`TCbL=uv@~m_qJtmDOjc7N7mTec+AG8`)5o>-s9+S{5>mDMcljH(=L&6Y3qu_ z7FQgpnxKj*HuxXg>ci1%epj-=kz|A-8GW(+#8+IGgR40c9H_g1G`O)j+6^HzAjB0a z;b0)IuG{yPrXL++aNC&0SwyO9;U03hZOt$DZpSq|GWMFA(ajciM{C zwXIB~WGS|Sx8${-slB0tU=?ttkcKR3$6*XEe&Nuo@d;A$Q{34pa!6=2K(ZeRowsY8lU(gQKa=kCTHF&+{|D+HIH4`JAEp(9?a2b6<@E&ccU*BW5T)3d^f)qe1Fq&wIfz*?_rh*i`x$`rD6h+c-( zg~A!rqzFnx(!Q9@kY+>|N1HOYXoGx@5I1p`Ez?0~ko90@78C72 zTS+hs0kDN+$_$IMicl+-Rn#7u2pf6Yt5o6OF3`+3&RlQR%%}Ryxk>Ny&`o1-AV?40q;^=hB<|#o1jD*#{$a zor`xuukmv?YjL%$B>3gkU*o9$v&}L-)p3~r&guh7{8F<-W3r>*ho<}ZLZe_-RiGBJ zgMa(A9h*-EZbjzw(2v%wV>AcrpG-c&_&S?F&)NF#{3K^1IrVkx5&GD5|At??ee<}9%J&dvh>P+5 zV;z3_2zzl@W?`kT<#b-$jkUqj`f>I+K6tX7%0E0j$X`jsoxV#EINmM4c1KVBypBPe z#A6nCt0So$?XTLiI~#|nr(4JR(bLgZ<6Mt5id0Z9y`t@Dv~7o-A~R0OmTP)r zvwr(t#l93qU>M_|@6MuJg&-0BG1q&Py*_MtN!Eg&?+X5)Y&T6oCd%tI<~?=SW{qU$ zTzD98e$TVIl?wG?FG zZ7CzDE;Z+(z-X4=&{UpP&ZN4SH~{iPB()L_VDw)(GANHv240Y!upNLQKuF*PSF$v! zoq{iW$nNd+bxq-b|H7Li@BdI9`>ZZXjzOqe0zKXzX73;ym(#eR9Mulg5@x@LWMeys z?>Gq_!~Z@W#l08aqvNqsjXkt~7hlbDFBph3CPeAfQM&IHAar@>A3R~w1}c2v!E5gH z2H{w%-L<_T)`n_7JXCEfZPjh?!kb}Sh*NUY;aLAVIhAfeZZ_yNJ9LYzpyPynNjLN) zkJraj2zN(aEv`%>)V>v!Ih|`PuzfpLlT5>@y{-!B!sZLClzxK(Z z?-rMrnNEmCOA*1R*>sE;~ zNjf<_iWTkbmi2k??6vaF2#vuu38K^zF8Ia5D4dkvmY!35YbalKu`A2d83+u%Mmgs- zdmndo=!e*V|5ri$rp_&g&;lWo?T@-v$-2MO^mJM zqrxop%&RAa@vE?=AQnCxtLWK}wrtRLMTE$!;Nv~4H=X#C-av;rSJa!YDQI(_w}BAG zUS>VSp--2f^&U}}JoXptI>BwlWJz7ycC5f z5rzVA)_<^v)9Z)0Z<9&W%du)Uw&MuvL#15juo{J|+Pb@x4^j(`$Uve4dqDEn@%{pW zq-Ixbtt(nD7`Y|&_1R%)cZD-~7EXG56U8b6z%wEp2;aXg)4Go5>*<$1)%c|r+=1oC z^7b1FnO|PLjOOO|*?}P*Em{5|0EY^Qp8bKei$%#jbAAw{o>v{XXtcVWHRhnWWc}C}3%EM~A4k{*SlhHc~x9x5c7xXBXJp z)}zHKUY95+x7=cBRmBdtm3Ifpz|^ltk<55{qTfjQcf>_LD)>N#C0g=cwH1qN(22k#A8KVWvPe_dfFO z)s2HA3x!HtXm3Li#GlyaxG?_e*I!>));7HG^y{x%2J!`uh1T!&*T1HhGq217zB}UG zLVRu1oPPC-lMC^+QFY^R&!P4f_}YH;Xy-t0>sQZR@O^0c zL5@c2>=9f(Mj~@!ZuyQzg@Y7{C_No845`ltxe*`XY`dgG{<< zpa$ZC&Sd@JUYLJZ64jWsYBp4bhl+JE6f+XxfJYkBkd?kS z9aQDjcGM~5(6GW0;>>4!z|89UM2N4~?a- z4y4DLPdZZnB<%GGGgMZL`3z_j6fAr1K*(Nkj7RmA__Qflv1!nVR%|upzNz_+Kke`t zq^VmSHgW~DZw;ZF*Y{S>=3H!{bgzoTiaY4*<#<#v`wA*S4T7O(@gi2u77ovcEq9p z*x5MVwaqM3NV69rZ@+y#_?)fX=*&7BK&!ekbGi~&{OGzNwcEbG$t7$?%aulh z{tXKoO#HIf6WtEn_?g9Ve3##`-%R0U>$g6p`szce*Q zDyF~G2NrKMl9BHP8YvF+i2le!Dk>J0jNZj4JsfmlYjVt8H7d-GU>dWGoJJ!qS@|9& zD7p>VkeEvaTx~ZDylP!nT}jlp;;nTOOE+;v#y7|XGvxE?GbVbqtG_6LbYOX&o`T+Mbxzfsb*o{DPOo^JY@!_K?)*e?H(W8OCY z(KtWqLR+LHl)k2Ijjb&Omb!esu#gASSj1(e6g)APN-WYS2cA%^f3x>Wb86>}^Wtpf z+%D3m+lAXl}KB{cuOZEQ}_)T(IoICk$7>RZ*e- zGZl?{R-DOV^y#~#_8`Q%VMzX@%<*pS#8^|oeXSE%L0@H7!4?v zVllVTfD++{@wsYCr75O>3(8FELK&Z@v&LY6NL}KAAElLrEZAzQ*aC|5S^8y64j{(U zLI5>G0nZA0)Mfpt(QMZTh$@<`Vz#Ik=e^CrppXA4@@o<$-ELpa)B(||^Vi`uyjgXH zn@Xh>mKGmJqvi^%K+UW|@)}9@asv<82Y1*af>vFI^GI>&DD!NT;C12)q<`jz}Gx^1nB5pS_|?9ZlzW0~DG1rpXU z#r7*$yJpBnflV3+NHg<4zsGeA<}CM#1R+S|9ecxdvJYCc6e&#^5h(%?oWh74l&o2@ zARTa1^9n?Vqhrb576_b?e*M;s^|dQ+-@M8jj5kkzb%!Sl^v z4g**^o*v57Zay;hW6G}#8k-VJ7jRw!XB8BBz~CP;%W4gHo&&4?WV8V29M!dFEp61t z7+Ksfa19M=h5n7+`7blmmb%D5qld#*`LNt#4y*Td!5AyqnBK3e_bZle#W%rB=oow# z()bn%^{I{qc}gV}scISDWbope1B}3fr+%OBQ$5J4P5hFu{o)j5-I5~YQ2ZPQnOZH+ zF3bzRU>QCoyu`*ksE^;`jfE}C8HJO7hly6@^v7u#3yF-B(k%_XR&e0&ZTE>nE1G2| zqi&{rzIShf3$iqY-ZFMWh*7_{9vQ_R9FpVkX{MdjhCcK3CAEk^JjilOp0W$em9{Pc zARP&+L5=0X@@pUVRz&6JzudawEfv-++-BQW$3$Y(x{dj-zRUNhod?T!Y@WW@luP<(L*v=+qv_cbQanR=6i2$WRMn=Hc&Y2pE z|FHKy%TewmbV>Onwq&*Ewo>#zSMFWCc@rdaOz7_1EDb36$7mmmKWz}wt>R zmOn^yq`@SGFfBvVq0u+bii#=)ypfv4r{3|VzI6^$fTxc(Ha8H5pgU{Yh)*ta^1wuGlT{wb3bTp)VX+Qe!kG!H$xA~!Y+GRElF zwtA#fkTs!OYJHH1K@jrnx=OG!$MzIBc@Q{nOrDtWptrki*O=fwC3r%b5ToZ2v609RXAkp{)PGW(RdjT|cLgO8$6KWt(VPkZEKF@n z<_s_o@vJ5*h2_H8=tbfavu+$8>GIo>xs?cniRq_WrVmxNdxo8GK%Dlw?P|Sgb%xfd zI`D|mCbxwa$iV{00{NMnfI(@MTJlZCT$%-N5(XOgo0RjfPX0Lapn*KJTU3c`QC8D| zIX^TxAXH`@(n1go=m*pbi?+PMZNXWsGQXoI#(r#o?(GECD0s$Dz1)M92Vk?KEvBm{;$|8ssG?OaX9DsUs8if}a?u}e6Q$v@{)GVRTBk-`a`0FAS zrGu4xg{p&Bzk%7rK$$w1;w(9jy3vrK$ zQILE*(}IQj-m^QkIY1vQqNYQoZ<;>aYM`j^wL(V_twlWhI&)` zodgc1dI$qz?L6Ie?sYEOps60pdc5uTa`RZOk%x@kEo zE7Pz3Sx@;9q4@d@VL@{`n~Fj;!47(qUE;o zS~X`l*Ih;a;bcN8u3aSOUILrW*2(=&%ObTQh)iDg?c6kYzm$k{3+xAlKm-O=h#z0Mcv^@`z&{7vf~SmLE>3YFdAx#xiY(pd7 z@vNAkFDK%OQgDL9jdiuYZd|*sP`}({ayUmG;wl~vK2u92P07RuVj)@<0S+J=cwVIL zaX>*iRKa38HcZf~h{4AX(q17`Yn@50Y&DZb~TD-@3qOGU``7r=99oUSI}a9899&x`cHKnibuO zd>fnh0q&UYCnDCBL~B*7B(ylk%?RHH-(-BJ>uP&AbWd&^50vR8o$@qRV=C&zW!V1K zW1>_0Y<;dak5j)n{hPs`~At~ZCe8NWrgX%t{j0>-c<`hV< zc#oOmsvAu3sWy5(!jE(-&{K+V@K7;pA2mo}IF06TBRP78Ll>Pft&l5HEW3@)vS_fQ zL22D}@I}?%02S>ud)@_(66~c4Z%5kF=5NWl%J@twqmXY-HZFn5+JpXAK5-;JU;N4^ z&4a~r6W0opXN0O6D3jVtYE2s-EF2w}yoA!g{LH{L3-Cl!Vo^2s%1VY^BihXG(w-?k zn+PKojA%qIZhHW*2xQBGX8|dnyR^+^DO->>1u8R^S2R~mtuVSABlA`)J6I+< z74G)h(T$F{i5%jtsCHw;nP z@Us`onZ+(e|C-%K`9jBHOClek)Z=>-ra+UC#4Pl%_y21yPo<)e`~ zxl>orJEp6Pw5)PlMrlGEP32cOOocMhSSjL4cDZ*GVRmo(SMc$(w~}R=FI2W7BH?8{ zyv`A9B^gQYM4{Y_$xAZS&U&#!{tG%Fq5Pkiwp{=^SRgi$nw1%N6PF-7Km4iUg959i z;S+*`{2ufh<6%|PHpOkYvx1z{`1+&Chd@BOmX0J3*49!?#A*9V$P$jIN@q07tpiy9#C}Fpw#ZLT zFzfXgYz8iK^DI+RQKBZ|s@#f%O1(_T7C}1p&Ba2mE6)(J%$Wu@V@48T^fA0K5WCQh z?(qUUDhXb7ROd6;pXJdp*-iT#&@&`sr5k&wKl7vLhvegAb759pycOZlw_4JxhGCLw z4c${rq+VD_W&*_z_jcy?1|#mABy;E+ZzS*kMd5StF)48@yAwCgZU%)cS?3UEMvDjI zk0(d{3)L#B=_Mv3rU$M1QRmd*(%LMle|bpF}u9$8Mn$l;{mq09YMen z1zQ^)U@P*_LepQva@S88A7_?o5RY%&k(hNO?I9|r zU5>)IsqI^83TR)8c;>|0U!tp0ORw~`0VH7(Smdr&;61);)3L5BBtZM)$st|?8&4kN zf%KM+v8yI#EcHG?YGzUQzVfx+^MxdQ=-_G#AZkKe1NSS%*u8M)%Juj#S5tkT?j7jk z>1bacIQ-$OZU7#`gBwYy4zn~k_|}~_L(2K)@Y1(F80vv!hi^XESp42Ai*Kxdc<_HC_wSqdWL~)NtqWhtZkhex>U++W7{CQI>Z%-DK3$6AoG>TRK=vDmKb%}E z)28o@LUVx7>XfUsu2k}>WhoL|w52Pp7&TTszGJq{jD#g-&r0#qBkEjZ`}NRK%XP6* zh)|7V@{aZs4nj^mK49M-4Gi+oGB;U(7ZzBw^@`^U6sHIzM@a5e>B2OfHXU$m=W=Cd zAJCxT*^{j?jir>XOPM<_jgGkKU9eQp0SHBb?lR(&kf-Y4XlIBALWCpCJz^Dzs--_p z5+1=udI4-f@-Ykl34H4-*Lp8)whTq=qutf%fkW-~6u!QP@L?%98VEA@lH#lh`Fkzo zq0jO9%4MVIc5$FjJ#geah?2OGorwgjW5IzV@FTFiQrUb%s124A1zx#+%>#)`Jf|`0!8s<|n`P{GVKa7{iH7%*On6l;#6>z1&C( zUJtIk5Q&p;=NpXOrC=ECuXQN4j$pPlmKi9u;?sNKk{^{WRKig&HkNh3O)wjqN@};{C6I(kO?v2&& zP^i}~6ryB~B?*wfv3fx1pKFzl!cpdM^%Khc;Z~XC)FZl_M#<-^|1>3ku~o8i?~Zc6 zz4|Y9v>Hy;QRdICeoC1?)Pe=0#lbp?{41+}>x7QUu9`abw^#pjN}g{4Yol6+vjF{H zuKqVv_~llGIqnis=f7S3@2S)8t|NPUviwK+zq|UsP`*8#$<7*u{WSqxMV)5!vpIiH9_39^l(YgUE-hKbv+P};@O9?$QL6#4vy{CAM`8RUpVD9ZQBM_~ z9?eS?{^~1A75*z|hqim~Y~Y}9b00agD`EByz%f(o93jb#zG40Vx^4$W5PQHOk_#?f z`1_)OSYpe^^$b>xIK(5nRv@;X=*5LUA&B>0OHJGwZ*k`^T1hgyo$tN4it8VjtGI$1e}GisY&g2QQ{p?)+nF;Y z$z(38TvT@@Cm|0?#2wE{LU1|o)!d|ZNorx|2k8^$xd!F)qItdSv*?n;M~B`c z!q-d*(eTYNosD!-b!UfHO+D+$OOt*)4p$5JZohZ;>h<+&SMFb5zkcWT)ptyr&6#|( z&qcSBDrdE7Xq5Ox?RYfDpG4Gu!(_w5A_dGPDSIGvVfAi)5WsgqLq+b zMi)M@i>a+c{pHfRS&a2}xUhBi8HKQUT4s=$lV(3=fHG+=X3I#$NdeNogzK=926(2C zsMO&H)Q>3@WVtk<_JJAV@-PcudKik$pZb28ddig_k=RFb&gdfc*{YuP zpelRXSTgp0xP$R{WA)HngrudaI@K_gs;G{G*bzT$*$o}+9J2-nHced@;LPySvx}`%A-u zP5qWz;v(702o=~HZ$W=Vy!vz2kG|}X*j$$kotG2Ewi$4)y?evt_95qFWy-{>3(+(WD~FJ70YT&jSyMxPlOQ4Y_Nef84ee5)8J4*T07Q zEe@ozybb!EWmNr%OrrX#%%Hkxp+DYu{cHM+bf6*FY;JwmKmfpOUP@w0tk>6Hr>Mh= zUs*t_c~-Qu(m#;G{a~v@3RZDajIQ+g2blazc2WOT37tu32&W1|zeZLGYkp5cLWiVM zJbS6B1<5FMHNWv^I$QZS_R6h|-O=#Y)%7d4ZegsyilshJLq=f`vwmCJ4+1T* z@rFB;u|mrZnVb%UXTxKl#NoJ#Vt8+3XLNPW$=^E;1z0FU?sbM$%lHGX20q+)S{-Xj zF`XUbHGIO5EQayw848=D7)Vw5wnx<&sv}jT${eb}&_l-(RZkm^Px$;c;ywM^nlN;` zRPKZkmEtM$hK9s>PxoYY^u=&iDtT@MongB$u~fZ2ePr3nIKSaigia!)v1vb6!|`=! zDYMUjL>cWP(06`gbs^f2r-0gG|D21MRuzQ-sLGiuusf+dNuMipDGOmFeDNh>2lYHR zaOC8H6?Y7)lr6xDCpH$FXVNLf3eja@TiR)#=G>4ioWzRCDnc^Gt3}DHW)@SylY?5{ zmHYxD^Pj_O*WY^Y?YyNpXxlpC{mpl8+%A37)>H138_PSMbeT;xgws4NbobBU3dONF zN)L-nmH2;#)nvPAowOSn^b7P3e7qHVk7BtIwH-GKsLMZQRcxti`P2JI zQZX&{Dtk`qKt)DnEuPf#QmP`_SrRM7S`$!|Mx_YoKAfjF(n#b`p?n`w(#>j?(pas8 za(DbvPkYFt-@^epSqgj)o?W@aQE++Z+f*%XFyHaYWVCIB#;rF5YIJsd1t zyLk_x{@3NeckQkB?ycXue(&DR+wZRH`;}|g?((yWZ82SE>G|+raxi!ts#;Bc1)N!Y ztVgAEH9ni9rs!6Z$;~>Gr(J_B*F=9tcu`=5Ev2p}CI>?P@vI&RDM9egPsf_Aw{$wBKZWGq0H* z*=(}}=pl?IfSJf$1fSHpG6-m>=})Q;?w!)1n47a3x6#nNyXej|TRw`8r3wvN)57)qu6nc{F|0CbSB zjz}*frBCh#Y6}z7>{GTAj(yKujO9hmM0V<4-T+SOqhMOi;+WZjNm4xy%z#e0?}h!H zjse+TdD4h>>Jc3h#iF^v4_w*f;}nB&#IwW@3FMiIWiBzJjs>xj68iXXS6?%3)g6fy zgtVu$Qz;}`#|^VGuwgN;5q_UflJT3%*vH%cy#X}GWq0QYpo3yEMmW)Mqk6b*D92BZ z`_D&b;sOh`go{7C;k+QB3Dc)DnJ?)0n32vrM(*{q(l*_?`MVZ+S0 zROM*QS$5D@_6McM)5$jm+iNtY7w#a33pOFDicjX+=sY|@)t_WiSp3ldhvED(%h6ga zWkbpDjc*qHLHY&;#o@&^NY%5g@7QRSkh1U|l^s_7i2Z?$QbACJbg>p~?GFQLwcV+| z6jVwaO2w9tigolJtaWtWSs0UVqYy2%b`&pgS|7dC3B8K~rC-)w*RD}!r4(uK^BGV) z5IxwLgJ9FRWdt8sbBK1eYJo~=Y`qAA$4}X?~`aiSwSq<5>FltxiDindS(08$)i=JlWIBRj<}zDz%4y1?R@kBxp0o3-#A>)+GVY=ubab?wCu83eJYB|Q1C66Ze&yQIF%;S3gEeuo(szD*hljaGb|sEuCrjfWyrx$Q(fy`7&Jffhla{No+nLCq>&7I0z zvXWO;jdDwK>BgU73?PO1$5T;XHsn-;V^t_Mb!tvmU3~Sm=F$kf?SLpGBArC(5%+tO z{37M~Al1z71gt1qI;w)NzE-7+uGWEYFo&(ZYZp8pZd%%Y25o83Bs0YNHuf-puiCKF z;!a3C+@wm=D4e|3JRm=i;-PB(NEm5K`UzV4qz|(f9a;O;0sCYS(R(|9RNqgoR7uM# z)%TMt)yI(OO5@krEBc9}u53>#dTH>67?Ji!H!!JDu$G6;$L%4NQ8}-D z<9uvD=7af`VoLAnhqJ6i-#RhRA^8j_&1Cztv33&UXgmz=aWd)z)@u3cQb&!d{9)>7 zFscfPWqgsTwjBHoTnC&An>6`em~1$}BoAQZ%i#k;C;R!`}6 zYwAPtr>Uw~RhiR;`N;Sv6QNXP=S@U}eW_<23l*0@_Snlev?CylGRCL?I;Jd!5Fx$#!Z_gFnhFl+#xoZ&leO|97Y)_03zzbegA zh@Lj6gu~ohSO1tSu8M~>F&^onI*oXjW*CopZ0VSHrlycQd%n7|9NI z&h9<5gd=G*G9Q>ZCc(4%RxsSUjC^;WxlSyH?!*IH$w94{%I;! z{Zq(l7QsL4k=JpkzgI@hyuboHyKu!-8gzwLkK>jxKdz^+9Fd{-kh`K0fsPHcYDc}c z@{ptMP|7Jleh6Z*hzfq2QoS0B5oMZ|Ute6lF56~<9KCk?-=Mjir#2t2O8(X}K*@^a zmHh1o%jZh>DiPnuQ$3ia>h^d%*JG;U^0;_FF#vp47)3O1z_G_?ffa&9OOsjSfv77V*uoV>De&bK|oNpjoX-kSRnve|;z|$;pkYa19BL zPe&qqN5985QfuQ=5+*D)X547hG^bb&M%sE(LDJyt?rv=#PWE~qjrNZ1pGB@Bm(Q!3 z)?Wj!4pDu`I+?1G!Vnvka%*+9^w9cRDpt!L?;T?RIXA6Nbpo-{s@vUFjPA#Fx6;E< z2wN6f=Q!d+;z_5n9zVX+5??;`si)>hElJV9a;2KGs$nk7J<5fgg~`#nDc%2|XF%KS zTj#TGMTyU%(_ACsOVn4RJN5O1gnFq+!}G8Kv^kT)&l!#+32fs?g8zx%6qu38a;>bT z%~k3z9JhrxShAB@WvEwm*LCrtr0`6^$N4T|rqz@FC#`_>#i&yC*qE{}sxFn0%4g<^ zK?jRPd$Ohmrl*bVThUDEDI4_n3x4$?cj5T^HKgk@5Z^-B>=c-_TD`HV~}g>d%R zo&+b%)e5v&$qluCf@r-UmKg; zRmGLl={GtL^;}LL>Kh5W%KX%3&Q$*N`p(|DCD0HU{S;<6w4fGte#Xye(Ymfum=c+y zrVC2tv606zhc^hmK>tsqQ~%|`#*_fnz0rj!3h@C^&{K@r z7t)sRP)m8>IJ=6GvA-mT7P-x6=F5OuFYWE={xE^Rw)4v=jxT2!AmcLv6k%MzoNH!^ z?s0o-XBxMhYvztSd)}PyU4II~b^QZdkfO-a7Rz|8emvGno=Xa9MQM$@MU$7zsc;*P65DlxT}=bwqffUBQ8+)WO5^@EHdz_8Miz9c{-D zm5sEGqK2p98*eO{T5!CzWKC4uI8mYdl@y(3LIJHyos$!|}<+6gz7L+_zSiOxw33 z6VEN}g6!Q}$A{$U*0rg+=8J4Eh?#N*sqhp}@W08>aQ#CQhSxyB2isdJhTiss7V7?JVxJ5cM>@0oa6VWTfj>TXMS=bR}KPp1#fq@y_UQkBcF7X;uZY z32q)JwDmS@`thkU!2Q$}Btn^ub0Aj4@V~RVrWpS8I%4?WvZr6XrKp{DjX%EnC#dlU z{arFPi~`(muKugM{3(A~&2qf{*H`~7UjKr>?(iXsV*mE)U#8fXs$!BXlH?VI{_5&q zqtK6eAru_(_^+?+E4S9~v*$6K+y3ke4Po2MuYGiG?VnVIFEpgPc=;#Kt^Fmv{35EP z%1tre{*`lUe?xD7ido3?X4Dx4{=;)?e~SX1456Ud5+0-u+K*Xm+T-~cu-7Ny(F)Ya zu?I8bu%~Uj*u$$-3q7(#ef>pJh8Ia0e$OOja94Egi39`f91S)INw%am;o-bHS$T!@)nofvPJB1_ z&9hgT{(E+jyDY#xDk}o!@o0p#lAX(TTH^V+j8!`Y_XUvK-X1pPAY5jmtiZT@V+TN9 zlqcpY)O)%NXj(-$!ptD|;+*Qe6t&8ftggq4b0g__mU}lMW3_-Fl=)eUl)Adh1lZGb zd~N}>x+&YW_cBXiFwD_YlEmsh6z$&D$0wvR@J{0Ntj#q^Wpp`9WuT87@w~vR+Dd(#P|?}g8CSEbkrFtO>vk5B}v-mD!f{UV}Y+t@uGnM}u}*|=P#3p>f%yFYq}m%+y=WjG)}?M#C_ zqdmj34V=WmoZ+ppN8{43J^Y=BX4;)xdNjVUwDg*l6^#IvJ`Xk?P~yW2bWy*aUSK8Y zW(*!)dNr3d=}5h>7xtKRQ${^NW-0p#GQ`l`iKL_N|9CZ1zH_hs)at9h{pob(-E;Q3 zY3KgNw)dra+cWQ0TcA_+zP~zu?|ZTNz1aMI&uo4v0ga9oY*0$rqqQ5FLd54=b{L8n zV@tcv4XnhKMot-W)K7^R^ei&polf?ZtkW){GHyqNGW_4)diwkICx;sc+?k*(CRe!0 z1s+F9d?*+E>)(Uy|A#Y(F~q9YF)(W@(WZeqH(JfU3UGg649`hLFL!!Ydi?o%*s z8_A$-pRxVawi3IGgre8E@z2YufLc(bt3fmst!)bh$e_OogR~Up>w1p~OQC|zheVhO zkfp_AE9Bx8q-eUR-Q}6Cc@WzC!aM?F$c%(S!6Rp5v{dqqfi1^1hp{s`D>G~e9*xLo z=ebsII>gdf#zVWRsT=rWTa1eb4-dh6f=$5$7>wj#$;;71Ocbr=U5pymbH7$l;DgD= znA30Vp^~vG208GF31LbvGa+ydL)jtp#_45yJ+(Wys9pYY@8U&W1@N%G6i0i9>50r$ zEM~tz(`)@{d$Fny=*ELrJ|yawi!k~6>W8z1Re|L&90^;4{@~^51$RRsywYa>|6%WK zf8)%uJF)4uk=WXq@p^10>-BE%xHMXo)M8PR$L%r4^qMVEYKEf3C8_CYvz6*1StP4f zZ&Sq*#qM;H{S+iH0tD$zf-HgnL4w5s`4}L`BEWvw_)CC%4-6zh5FmfR0{Ivuzu$Se zFV9m&7S-J|on8_%E%Lc<=bn4+dAsMH+iU`zXnenPONtHoV@R>Rfo$@vlgZdG^+~Ve zWdY>=ix(i8AKksH;#pgV_J@^u$7(i2zQO8c#PMAUZDaKV&Q&HR>tiypSifU3F)LG< zI8*pRF#c917<&is+O#1Qd*4-q5Est)WoGKWEBjDY%jx-(5$a`WlKHxaFo0vc+lXJF zaZ2QpzEujYa5(9510$t!@xj{8`_G>56e~|ZEIwG-+FE(K^Wje<$_b3Lz$ISo3B0;X zOxugo zLl>K1K;X4wWbqZ5XJqdZ4;F$Z1k+4l&F9;zTLr{xO#)a$ey+z`&z^7c^J%+#FhWW$ zw=D1p$p{ucyZ3pTfI#jW^7@J#!tp2*P`m;k1NYDovCYXjyL9H^zCOe+1O%RyVisa| zcG5?`CH`umpq0@PZXoneHl>nqQE46}e$8Gf({2E+&%Keih3%z}VKJz!CQdoLRHiV9 z>6Bj~8lA8C~}rd5ldqk`$+Q0 zoC6!hbpn~EX(M&uaLB>opBDo299?l_bSZ0wgNeyLwl5Sc@g(E;6o@(p7I}tf3NS*G z2{iKeh2T7fRyHI&)Hw#HeXz0P&QNr%h^>>s`5-~s3P5 zSXlTC(BY%CC#&0YgZ-~>KYJ=fXm81or;^C=PVfH9MQo9iFF1bK68XgtL7rbNp20Qk za))3h5UnPh2q10mY^^=L7^E%DbP-UNFsUELVW`0HhHH${DUb@|0-gmL&hTh^>cZ{9 zqh*bfA&o&e;?y>r;-0&Pc&}>k`Yai=gpGerDD2f&OL1c?B02Hh*!Nmi}d@vTbs4+mn=@@W$RkrzEMf-X}bs*X_a z*`$ZCNT?SLq}_q`3FBr2Tj)GozW3z$>Lw^?2kb4vi z^euMH?@U#L%)*h><@EZ^s-?EhRC}gk=ctkcJLez%73>^&o;5%A;tMH%eC7VTa{ql} zY#UkuU`tTis57V-5@FoeD-hSNtsF>b^3(Qd@l2Cb??4L}Ut5^|bM4v=WOyI7^}2%S z40?os@FJY9yhKJXVG}{nQ(tUY7?BIY#dwZ%&0TO*4r1#%FX+&86`cVG7w{=*_-szX~XG+E}?0kcGSYg zjG$|S?@8R~HF=Um{Ejy)j~ktDqJ;Q@<6wzU!TU$R0kOLH^ne7myX1vaoe0z5vqXH~ zIP^AZ|9k@7iBB0xKM9U;WCs2VjC9qDDD&W0xNV@gxq-(zak8ap=TPF^7Ef1yy0yXt zbT%uvXL0^?z;!{NK0SFV1(-__=>sa#^f70-q0hD8-~q)t&j_M8B~hUd&n^yLaUR2~ ztN_V#AxM@W1;VdRN{`Ur1OqyC=!h5wCJ<@Tp^?)&@p+1{1I#=jGcz74{$(BA(E%Wm zuafv(zIK2t^>ZU%8m7PYOkDy%2Og%>lKpn4>u`*Z`8cQ6nIOrD*WvF!vJ~IA-4_tZ z)quNopO*;uR=RlI5l&k0>X&;TLTw}^qOtFtuKT9jl+V@buGku&%vAJK)pe(PHaxTi zKE*6fMzUeVTpvD=h+sTg+i4u(_RFy6aM?XN{fGpI!&2UNwt&X;2{utUM)1Fz2kjwZ zgJ0qJwDPG*=FlW&sPGS){r0O-s|t*_b8t3oC^`GAR!4fm4#~`r#N%qf%x_I>Rc2fl zN=SX5WC@^b+`G3%JKN0%TdR0D>ERs>`)-CRP8nJIL9ff#08a34-a8#Y-YLVpG-rEW z2lpCDWC3C`Lz{A&Rh-v(eaYkNoj$=a?~cV6ZcT6xd6ZX%N|<#XViZ9Wpi#AVEROyJ zNJxT6aWMgxL*U41H=%#WkP6(ZgGR2)N)FQIxeN|pgpHAvdAOq;n9Fkw5*gvel7>e##~4ofgn=9!)`m0g!b5r+h+3%!GI;G226L<>&)#Q{ zYgI^Oo%K5Xf#CjRag#0>G zP|Iu_7)G2d`-Er$&7s4fi@zL)_0z}gvy1k=l(2MNfao}PC!Zt*5kw}7|G{3kJe4N|~7+cKdgz=p5 zA$lP4JY2BiIQ)6Zi)AJDNjR+?a{uyNXuL9NKVmu;Ki3iG8-#$qQ@=J&3e&!2YN7W> zaCNHiNHOtF?V~i|=g(`aa)g<1j2paZF|HLiih4?Y;5JCm#G5Lam00T5m=(oP^JLI`Ij$qdS~7Fu zKYr^e@tdd0EYGv#G)0&d4z-!fR^pK~M#s3)XsO_f9bz-fr6k}P8xBeWtbS!fvX4=Z zIl{Im5s3h64mj|T9HAk@sFAhFABl5?+rYlZBlM(a=>pi$Piig$X^{~CZ`3>qyLi+2 z?AVBCSR~Zk)GW5<1Xk`QDPHN}Kuzi@5jY&TLhl1ZY012i*R|b3gfmsku}wyK4%wHe zf$9T6M|pe`jtxPoQ00gbypN87;P)OE3k&>}%KO5COA0mb<{!fEU(Vf6zKy2=j?^vFD&uPY2A2P>@3#L`sk2a$=s**5=ygv!dL5Q zoa_vZ)`D!N3L#seUL(c8h8Y7LP6p~`A@t0fh43i{!+j<)Lu}gDN!pNzB`HW@k`KDx zXi2o=7S18Lmr)4oFO1gS>#? zB)WWf>zC#YlBg;B?c!NVa`r5pKG7?Ga!^QMQ*^-e!l*xrw^D;{BZ;4Tj9q4{Kl0i#8#MjLGCquYpXgmO% zEY3f+XKRJ(iZ=>7m|{L*m(Rx=<*{ed3*J!UlW9sRQ#qn9xx6aPCgAqoU^n)owi9<- zT+B;!9vfxd$IqVZaHf8Anvcrk0QJ#-*=@ zN6J>B;Cn+R>40Cz@ghMPXZ!4PnbU=QE{x#(t&3#132)<{6PoW)BBjiY#U;iTT4ach zoK2cso~!MMDyELHI0SL4vdziDt}DsxulU!O=3fETk-`!Uhouc!P~Pt`N`dXFOV7mt zpW;QFP{@45_hMhHQtl6@T6hFge5+}%_m-^NFVC0+Vp3$fM@q^Y>zvDw!jvw-i0nbd z&{T!6av!yKj3J4+q`zzF+`Nfmoz7z)!&KWmB|(t=Z^)N)9v5<@TzPYdpxx7G4|?G= z^~(mR>Ti}g>_Wcg9qiWPu+HLOA@2=Zql1jiA?f$YbROr`D}0VkW-z(X=FJ#gXx?qf zAlxQpHb?#Yip%k&bEcDfZY@pG9NALBl6)y(ZYkA3ZAw<9#K62#GNcQ;w!6`xm~_Izr0>pc%}!BA_hYV431!10zIF} zeS==B;dyM3t4{)CjGWFfjYCsi^^idb%ZnU`+He=Ivx7GAhUPn|N|`rJ^5Z8wKGX>m zHe&>XeC8P5{(@mFZKKzwAucHyIG1ETj?0b zUxQ;4oKjm5FJcWfTH5;NIVm&|iNOHU+r5t98AF5~jy6v!ft-7!*H7XLCDaZA3YWjVz09QS%9V1&CHohVgC}R2m?5Skc#|wl0kTE0{*_B-AAZz2K10$7g!LJRGB?)F1801}gtC0YT zdm#vN^@|yr-vi@=mrJi4$Jag&l?&kOLz$@v)-k$6NNc$*xdAsSR9x($RFppy9U{l_I zpiUD~@9jQa{b1q2vyF|Frwzhs={HYH`{Zo=>q8uI=*f%bc$?L>c#@kR?;+Z=sy3f7OAEN2^{~j=*HO>kGbXW zGczFT!j?DVVDN+S{E4<49z^T6@y72CZvVfi_7TH6mN59P6CrZ+8~?>qp2vKG@It)g@j0k-CzSxV z>wnD+Txg)DFY|-w4YA6v{p1EuZ7eLjLdq98@|ld!0XukDWX1ijxxo$%F2Ca56rh?0 zcn+9BxC)s5*W6%wgSpXqo`v-(v2FJt?KTZ#{8fAAFR_p?)NvZZ+(x{NfV@XcSsL=JP?r!%gNNfo^IdeO zlE9|`DaCOcavgb0F;GXH1PHGvQU2*#d|W|n*U1T!F2i-1}Oj_2NZKhEbA&%JIJ-PwA%!*@J6S@ zQ|%`LLKI#w=pJJA^kE-1tAcLhb{IKt$K# zZg{3tQHG0RML{P^YV~*IQn#eJJsKdf+1BY;CtZM*^d75HVAR-HO#9Mvrq_2>izEdj-4o;cfdGaL2NbC_q4g7Q%eM#?Pf|N z_M98pf*2tIpvBHo6^iRVJpw>W4jt-(2Xr|cf;J!;A@gT)o+C>lU%5<&_FmmhYmd8b zoCNkFudaR6*Sl-@v|E!@v^Wc61qRTc)n2&Ek^TGhrVN5&xG(D3Fw}dI3P#PocS}qR z{hgwDxAw#Pdq0HCs{Qa?{pSyVh*4*MDoc|mQh}FKK zd`BjVoz6}2MqC01C7vWeritYIT?lCI;(X_uE5w?2xY6H4G{Uso5`$1p)y{ z6tYwJV2~SiWIbuGOkeg2$x(A|@J-wE*9(slH^ulE$<=VH{M@CJI@!W$ ztF#|vueqQX=DN9oN;fdriOC$c%7oR?h25Y=r5m=&x=B*eUI5h*648$T69Y3IaexmFshE{ zX_dl9xK?G};!a+&4bfaYC|!q=b|mR(m)w(i!q^sPI8{pN#=>L*LbYzjyW~@qc{$CM z00=!{)8#~G{bW=ZY9|W`tFW2h%;aKLjyvdd&#P5*Y*G2MgN`q6F4%E~AbkF7s!V{X zO=N+PK_bmVK+6F#2NIaC)wGzP3I6GxX!nV8I!GhwDW!-U52cgWs$jVpbVT@lUqUO6 zYM`o6GC;l0Eizi$Ekkhh$*J?UyRlPU+LP!_KSy}jmOnHdBoh!`{T1*6eEF%+`XXCsIt4$M7GK?BC2`;2FlTU2PpX=gRAiTmw zT1Y};-V5{rk%-hlU4`0D{WuNtk7yTyJC5igjnA3r69ZLfOZX3VB-bg}kzp(O0KxN^ zm4wC|e0pP+7^!&DrWDd7rd80LJ9?oDo^Li~f(G}(!;D`Rioo+li0wy-V7&0&oE7yxB5N2Y#adnW^S<=OE zryxK@KCyLhOi0=vjZ|@gBrr>TbK{w}D$Y7E8QZ9Ga;g$EX2^j1W7KLgf0t(R3Q6Tk zIo`Be$nh=B*&*!!pC%yljGkOavKDo&YMMC#)I6Y`ns5Hhed_lNP$dsSW0;eW^;;^y z4+^m_X;ryocB{`5*lA)KDbP-_>-c(xWY@FI5X`d&QSRV7AJw$joS3Q=IwgrO$vX)F zCaRi1b$ViVMh#QObS1Z&Fg$%IaZINKw5iuWepf(Jjci?B)$Ahz zK|(St{#9p2^~vEUH|2^l-R;RKW4Bm`euoykj*x_)Kze-h7f$rZ-d@5POpfp*m@MXa z(&d#aD6<|@iw7VNq1^UQx@Wl$2wN>(Yl)O~#Mk1cGq)b@(h3r;GwMMGYvIjipcp$u zGs4jTptm9!}DyR9!AS5o?|2w~~gK1>B|<(&`5r5VkQ*Xq{1athmhoNYXR@ zqQvE^Krc<2zs8#btf}@Cb1A4{26_ zOLvgJi@)sQZKVBUx8Wp{YR(FgDVixy`HJ`Q-Na(wW`cZKYE2m}OKE%$V=XZ|5+1tn zX8_W}9pxliM|jdm>!w{8q~Iu&93=4%C%yNu)}s8xJc-&ydJIialdaP3%rs0c!;=sd za^aEEgVzdt?H9;7pZ7aI$3fNFLzy7=t3U?~gE=snHcT}LNeMWI3(Y2gj-%p$MX*80-1GboX}1)sB{3m7>IfGODYWX|fEEhW&LHK-pk zUB`JEwelWwQj;$5;*7JtTOxzi#jIO-HVx3s++wf(>!V8@b|< zpZz2mV^mOpe{#b3q3$if5^0gzs^!~N8BM}OR&!8Ij1pqYFq*gL`GTuR#$p6oV;Ci9 ziCNsZK*DI}AUvt3OwQ9u*S$FcN&x#5rV}*92ZP=o?P)Na37#C1tsi7D`GDfDYz2^!&6pZ{O6TL$%x({^{s)4+3-zP4gY% z)^V&`Phfc`9T7we3wPPxG#)M$e8&-JKIH>vx|*CZCS?gLxV99m^;+bDCLJV<*G&Wy zfukh%qxl@jO`r;nJA2TpG!z?aHXI<)SWECd!qWiC+nwnu`&Jc!=&n#OUNdW_bj(V1 zQ?c3yF@ZTAHCR3`%Xv=Zj!LJlhFBLOr5Ij=KqCZBjoO;4SSLJ39$sS5TpWpn41^_l zcd@}V&#q7eXEV(@-ZXDuwh|$4uZk02kI-Wv^)0&6$RmRHFzAgY1i(YdfCPpl((Eh9 zTb=ZV1(`Qz_4VQ_$XAV_nKq94^EV_3WrB=Kj%w;!+$KQIBUh!n(0W5PoYQaYvXujTi+<8yK=3D(1{7-nges9tP zOXt>yZVg3)!6Q-~&)2}hy>}OBob|>GZyfY-L8sM4vRK4c!mWKv*>DaOpywfEiRHeN zgLQ(ioLaYqx0AAI7cc-Y2WqISA;Aa1HQ=mL%s@ z0A(5U*D6ELfeHa|4L+Yy0WRs}T;Q~x^uhHI06e&Yh{K~FpTfnEfTv$fnFH3Whr?03 z{b?KTqk0DX1cGyLtG#`>Ib;w`pNhwc06eH}c$)%eD#7m%DORS>DO`ko)|n1;Xnii) zxn_+6ZuvTLJ(v%%w#3Gt$7R@NDtTrL=1X-NL=*@nCql08BI~Zn`?sa5|m%B(9Lzoenf^>?0(2cysgBgmq ztldmLrd-4o%xUnH5^AgNtB9jLVhbuLlyRX=T)<%8S*T5BI4VD&cNT6i(L?THuuu}Bf9^rKZbRl5N=+%9CJzssaCiOfXI8+Xp+sA7bBWePG z3Jz%e7aGk;x3$;qN*qFHk%|mCyou@qH$>+I@5`$4(=RsOE9!VkSzckA3?pvBs50Op z24f58TRM5ZFILiJibd!}_kVQz_I>A>h7USx@>5W~Ua1euxdsHU5Kx6M4!c#D96UNK z-pR!`dlRA|{^fEH*?CSg-Y-h@-LCqi*KP#BC*ng}r#Yfr_MgG#3J3#O{UR8&e4S?a9 zb)HtPX-xE3rYuc1u=Mi(LBlUY+?-wd$>EqaesFM7Bu=lj_)%oOE7n`C}S zYQq~^uWfFv?(BTne7dr+3JalDS{r1hQs>*$wlf>q46z_n+x>KPYkTe4)8^X4sYAXR zz{@QSEfqtYhdKwzo`rOz5}mqJA8JqpV(mq2fe`5;31K|mX=E|}1yNt1N3YLx8MW7+ zTGF4iHwD3i6TS6${Y9YtfX`bs)NNS*ENsvklo-F;ON!*rE<`m|q2w|!w-hB^TG#er zyl5{S3_j>W}T^^%~za4KBpqaq*xyqWTQOz>=lvS9150aW~+a-Fu z3rvC?h7E)`C0cmkxEKaB0mnNa1lYJ_N!VoSnB(wIIfYT*i2 z-lx#%4$A$ENY0utU9rSfCIm@np%hTO7boM9Ju)oE{)>j7(c(w9U+P()2cX*gEHlrp z3zQ(q@y0L&`5(LxcQao9LGPk3L_{XXOhKDoye$^XEgpE_fZLZ+xJ51wl>$@52s$j! z=4|mC&On_?#0xI?@+0PCE%IoV(8R-8a7&XC_G2rM02oM}kF`7Y9A>~jk{6vMLQ^tI z7$RHH!ze8gGb8tL=)=SDEF5@u)W;s zowvWs3PZLIUWTo+RiUC6Ecxlw^0pu(0gdO0A5uiH)1W;U72bpgE<4#83{ zm+WHyOJnm@>j=RtnbL3x;?y~0NHEf!dm_Z5ge4x1q2a;kqe&}0zEKyUwZL(A9-7eS zklC<_(2JvfoX#bhli$RKDP0>v@XvM6xDzh~@E!$>Y)v)*cD3_t-+GC2Hg=7oVhxGyA!;xavyRd-#4d3zZDe1gLm?2Za5=G-8k=eUv} zIy?=&kTB9KNu_Hd|5cIOx{_3Qtw9u+D@jGVkbQF{salAqq+)#~shnk)G_9~_lwV0I zMbej$RJ^p1h~D!g)x6jirdBZk2h3k9CQe76ES2h(%uy$or6~C4h{0LTodPVSAOV767NLSbeY#;fUO`0(Ai#;fodxjOb3IGKe%HE^V^TY zYup~B+niyva@YN)H@Z28Wjfnxo133}JIppLchzDOq|Ym+*uyjv-Bi)J3F<31AVcIr z`+yHl(KC6TSe|>~XUpYzQ6@cHiDivDW~s?9a8S|Z#Gx=FY5%?vKN94dSlW(vjSy0|jAM9N*6T;DpAE3&XF!%MX5c_qrX zG7@D)#f;8`nt_7@}_yrKUepzjIM88 zpyaFLgG`AB@m`51-NC}i)NcEl;v_F8XMGoD>vg#Xp%To_MOg8t%^}7S0h* zwFLx%AcN#&4>z1}3u^hW^SXU-2Y>9h_4dP;jNwntp$SU^^U{X|M#38;h- zU0GNG8CL=-pyFG7740hWBCfOiR+~#mUIhm#vcB@ji=)BdD9^lfc&QV= zD<2@2_S=31jTtfLF+7x~ers-_Ni-phsm2lVdCYObHrwt}2ji%9I#)l;oaBl2@^mG& zqfa}-OZ8Drda_$v_~Y7K2I)E1;^u+6D2&nR2=} zK&n;$Zf`c|6UX)kA9jeZ6>p%rGl4q3^zNCQkq91R?kWSvPN}_!so?GLC?c>P(|k*H?UR^;7eaebM}eend4Ux1 z$*7u%9gjJsV=*yMGS>Ct+2mx1iAVx&vQWH6G2n|7_M9DF!ec5{e$+RdWW4br9`fai z@iiGdPLABJNO~=kCr7^I3_SG=;g1teW-@K6Q)ed$VqWmAjEG&oSdq;7lJN1FVT}j4 zB!vFz$%BMooldcaNPRRI;qk0J;9nlS$4cR4t?poeMDN|sOMPriGJ%&~mqEo!ruYhh z;2l>yG-2ZT;Z-&y|$EUvuPVa5OH`hSJu@A55#Pmu+;EUdevb`VG67w9ga2#&pK~-k z6udWRjSiAV|M$kVw@~z33a1r!TW5GuKq1}u-dh{L%PQYJ1WlacVW-%7<8QsSai3)Z zZ79#7-T1?|Hr|&G@D|sr&VGBGbg=%`#*vh9d@r|wKY458QgZt*2coyX!-rnQXUYt z(z|bOtg!S4)yIXb#>2Na{w-(syU)k7W;di}|?+97LgJ0SBXTOTF-<~Gntj=Hl>c(H8&V)2S752~H{?2!%QnnP7 zhLvw+IOXH-%vcodC6J4dzI>ap(o**QG75DFehocE!jr;jn@N1D$N)5pZ${`eCIpY@jS`{JUWSIOpi~B`h#1= z{k!-6sKBEq2gUoXlRE{tcjFps$-^0ViU|q%dldJ4FSHmB4o^<;(8W&*a3^{BYlPQa z@pM23B8n28@_rH070=sr4$sgHKB-zjU5rmwjs0cJ$4{RZkK28`KiDlcCwtw_KGOf~ zBLWLjZCnibWqb^<_Sg+uKOzL%20`(NFVe{qWIrj|ctsqK#`|kr_k9TK?+)ZW`l#cX z4}d+ghd=QAYyYh1;`PJOa{A2U1mz75f^v*dF~EclF+YE%11obl>E6Lel-D1u?Y#f& z`A)I&^uywVm94Fnr#m11L>`_5UoYCP@JK6r>hzFk0J8*E`SJnZ4MhhVt6LA=M~jvB z)}E~Gd`Nxe(b~?_)$Q%#(X*{$rPy5A+F5(>{K?8zvH5&!^V#-lqrkI*q9LRGIk@FJ zCOy8QhZn?Jo$grY{2`Wed_0&y1wQ5@rjXxl=z0gG*Gy;ki$Po60ff4|)+G5Fjd%dq z+998;!t3b(@K26UPKJ0S@$~exanzqQ2BV`ztUcF#y!fYt1}GWe1w&QEp<`p)`8Pbm z?Y|Dj{@d{M;Mz4&Po3(xe>eUD(H;YuI+bQ<1w~??3K|2QTOrS4Y!C6)zEL7 zGOn2)G*`%fOaj)&?d~CGv(NXIL0$5Y%pE@X(!yKH$vb@6tKU?7{WTwS&_IvqDeFU3 zD^_g3-fs_cBs5k>qroWZTuFa6@-=_VM~xWhZkU+3FPHV@x%{yqu#Em8E`LxIQ?)}S z{3RNgVq{s)526hw%@>T(K!p~xP4Ivy(2!eHKJHSn$+w!#PSXZrffXU zFJc8WOA2_Q=NNoi6m}5kxWPBv@FH-l%U=?!(J_D)l}D-Yq~v)c*aKZ4nK}D^)f!=| z?=9w3h{qYv9Y(Z%8nj<_9CkEr99%Ts0jP~Qzub5yy#Kq~(m*sqgsP%CZ%N()Fvo1A_r;_u@NytNqqq z7fJ-)ziqvOh?Bp#`0D!MBU;Wc$wI69O9-X1x%4ZB!q`nsd?arpkA3*inLrq-!}$Sl zaQh7pwK|a1F+mGn2-}@za>_*nH|+nqFdoqy*azN6<>6E)PR#z!m?cpHBvL5=N+y=n zP!?_?irt%|jt`CvPW$ZxvXlCd|GiU8ItO>~*78A=4jZTkeF3HFw-Db?=LEVOI8pxu zY#4~44PCIakraz9mx&JPeknW<9(x1l)d#?3w(6F%%2Yt@?PQY-fNqH(QWKQXl15Sn zUz~nYevgSPaW>QHOIfI|=ov4`W8thWZV!F4Z)rpuF&0s%$S4nv+xssmI~YQbw*;Yn zL2*17;8A-nwWwT!cSffLLQmwS*Fhf+Hi|IQF`U6^ETqjV$1s49M9maux1g+8-pEUX4 zX7P6lfwuVl<@9My&P@>rLyDS1y%wEV>52^cc>3}VmTWq%z;Onr?Sls1DaXLTfC+W> zpTR;x0|-KIqXb40Y!$Slk@yxdPpH4t8jnV3S;zlxHLNUPjzdknIuv78AD*J$I{qIq z!)m1&<5^EL0QT^r3U@nc?Z$XX-w_RqC7olv6exc@)tH9u1@-TP3YrvgLJDLjvzZ1A zF?-;+K#RaaI@lip6teuKD!*XI`g)`?L{mq(+0a4|V=jEDn5$h{tSkTs`i8I!uFkBD zP4jKYryzH0#4YDc$wFyEMDzDl)=MSPF%s{#(57x1Q43ppW6=uPnOG%J!^FGSrkoKd z60!Jjiv&V4+K3 z_hZ^y%X_VZ1qAwYvo9zszUB@?99ACDUckTLjP@6K$rBW`M|C`KKWe=WelFT&=19cm zNPca2N8)_stK05yM0uAdC{UwRXs733~W@A%>Bqm}1RcAA?{ zR(9YC-e|5pJm2+s2nV+^JokM*eENuE)dzc@z)p+e^Zfx9Qe1J+0^S1)D71#yA+3UK zs8pe|lhFXCbr5fzlZFabxK7=EWs)@B;ViAq{C8moKOZp&|~sfX-F#}rJx@FY4AVwTg5xD*{}|2Pr5vR<|`sy5fy}6 zU`gf*RH?N}ZGdVekc@K{ptU|3(|DJW#pNr*@)(679w(ELo@lUB9gv#Inl6-hL%2R? zSe-H67{>93_6ytZq}>|97(UhZBtz^oB|-EZCa%^$JPgo8_{w^tkTWX23`Y${Z98RA9?6_q*dBBxR2JvlMR<Z?^5 z+tYr$RC_TvgBA~py2J#6C5!fgit9Xov0y%5A+RQ2(lR}^N8bGdxQe+q@DV?#NU5#>>n{QXzjv4%q}w%Y08ji)O2IJb#`6_YZ<|#} zSZnGU^U~SvWh;gVNCKC(_fo|X!AnTRe+{6sHeG-~!mhPcKVdSj=4re264umkj9PN= z7n(zlqFW4tGhm>86T*Frqkr^zQ-v5$>A{TgzgBVD?u-tKn=9f@dnV_jH(3n%L3Q9x zae531z#sx_Logw|0g5x^{gVlBd{(FiKf0Hy(E}DTG(l zRQ8heyfdCQBKCD!-6*pNMd&0fw#@0e3v4~$5Cs5;ha=dIG4Q1o)I?x;Wc+ineX_rZ z$uIJg9@ZyfD+uK{n&cos0WB0Q~D)q=gx=x=rvY#3UGSiQYAe_@UIstqZxS- z#sL|VG>>sPuh8|7en@*sCjbX{Z;Xb$20}WZ(kEqc(s9Dc0Lwb(q=90HNXV)sHJm9^ zoc=-MJ`{sCb|p5WXx;F#PrB_U_SFeglwK1KZESFCLri3J+JPQI1~UKw7pH^%O$5&j zMlZ4C5-{35OY!8~RCeYVGa-cy#tQ~mE!kF_90F+iU;~wUD9{l1;bB8Mt8@5+NpDz>S_u0#V#lTwrX**~5H2)PAqVx?6I5o=MLd8Q zOHGPiB3l#nopTYgLTFEL_4=bY{RI;%=I zysseoqm$u)K`aMN>{RR`^alk`W_lg&NV{-=h@u@N^6KNoDa95OY9uC!GXX8 z@P8neE(*Ac5Rxdw;SUQ_IqB>lYh2$U0tjpXwHk)h7`&mX2?7Yna*SBB_5qyVl?LRhY?@wFMNUF3LeD_ zb-OS0nhggTBdihWdi9z`UnwdQwHkOBAZm5QI03@P2phRc(vxW~GJDns#Yz(}RH`+x ze->seSgL`)ylV9|h7$;dnk{gUT*LZM;wB?1HrO41K(!$5NfzC}o*Rax8~}sP3wQ6n zAmWMH-GJ8Q3`~bmxK$Al`pKY^=~6F%M38k^7KxAmtmK)Dna_ZO1mrV(EZ~wQxme&A z{*)m06X|r~m|Gl2uJ1@`q?YNJiRBS9@mqSJqmaytoY==K{KOg&ZXe^#@DqEiy~t1$ z3*t}-ifsGLK#-Lt=<)6L#*{<(#tl0YHC7&>{gQ|Y5a(zK!vqqP4MUchBjcdmjVxg| zp>?x*ps9*KP~@#k@90B`W&)Tq<=A)#1rfeJi?pUsSR}Iws6;7YuiSp5WpU-=AQw>6 z8)d3c7EMdG1>xRpj-jp9>8479vMh2nOjem3>QFXQXgHQxFvZ(s;kQ(*^;a<|R>_X3 zF(f$S4CH9DUV8*tp~72x4Dg$60bg~!Z7iSTk6KiSw+hhYxa@4vs3n>!tKTT1jL5$0+$hTB06ED_>fF z59R-|m4ETcpYb}@@5{&ED7oFN#l!V~Vke)ml^#k~>g%E8)YC_tO8%ZlbMtZo^yKl& z<{oVNAv~8SIGx=7^%_5odEde)M(p_;d{x#pK#*nsXcxqLDitJCZhH%Q2HX~>Eddkufkg%E55 zm`yyiz6rAgcDh=Ch+N_EjsPY2LVO#KSoYfZt1}ouZyw-y=9+l-P7&gHz-u8l33rpd z+|*D=8!CW|G1PH2hHWIb99pBZMzMzbt59gi*9fC|I8q2WsRIB2Gu@{%Y9FCRdxT@g zN5De+bqkkfj0KDHKIIgz?)q8jE43u6HSUEP_tbdc#V&O3<3v7Fe}#w?DCA8b5bt8( zf&`e+;;XyvO1f;rd%R!~5I0`ltt|$gHb!hb6n*u}p40KYX%L}f7(zSrzY0b8RK!B1 zJM=D>To+pJV|{E>`S^|=@RDM1G3nznKp)%vEv=&}^A?xAy|EH3HH zK5Wc;A78u10}fdk;q1O3fq0U#M#NC1nw$)5BlHu;<$ALx^bm`-L8$d9-_3zEj4R128IU9P!O4B;@{i2!=6#%dRgd0o&jUY2zx_fvl z$nyFnpfaPFQ)4haDVRIej=cFRj=cK^L-^KDmL(xn@v754Z5~eg`}X(k+cxWDR#X|$ zRyL;?S3GBq^U4*;xh9uEm&0`@f^?^d&{P*XTi)4=dYe~t+0#q73XjIgw91f9Lw>on zG7chG!m{AxoM^1EBl#l2$?jGOF$DSmu^8?f!@;m#ix>v?*iCFd)Bk1=kgfJbfMgV` zdSsMU`7R2yXi;wU_1n-6e>h`&xwPb@XD#lmH_+l=ozcSL^lnO}eD*OO2)5!{KwWhr8GN#}M>z(YKCNBT{(SF`Mul0cYFvz$<8~FH_mN23NhEjH63jnrQV~ z@Le9@6r5^O0EOL1a-4=}KNj}~|G^suBOjW9X$62A2tKjy_`8$?4id}26pAK49eZ6-lF zp%vTc_ar(8z7;OF`1#pY00Tm-1d2dnfjej>T~VdwcazGs2c$tzge(&84TYH$H*bt@ zg4%eUh?j*NOU$z~MEWI0!3)~>;gEkzycKAk5q?naRM&mnIayJ{-f4~YU{9$61~_zR z+YyoYg^~mDhv{+m1=xHRQ`BMuD%G4M($Ky`ZL!}34Mc^g!RkYN$`nx0g3}h5-mu3* zi`t8KY7K1E#_Lb*RFA`J#upN$sWRHr_+b_mLz=Sra?z6Qt^`9kjA&x}crTsjK(wv1 zZE7eB^U!-5X>%@mC>FbmY)H)LNI2%kBz~oP6f2YRB@xmf)bNt-cMh2dA}mCVP23T( z=CunRq(brD+T3`$vaxCyOA>5E2m@@sovcPF>U5BpX+LgIu-?~qC zIttnig)qXv4yQVNgVWf1CP$cxS+nZc6M|&-Pq`+Dl7L?ozb8KJ3i?oK{}^Y`$-V#S zE0c`CQK(YdU6~+4Apn(@LCQveflSz@Oe)d=iH6%-w>VSP^sp)T_4TL4!oE2@*qlEz zsDeew5-K4uGF*x0JSc3xali%M3V<(X3i&!OLI|~F!l=p9sMD#r#MzLTuCioc+>z2R zm{(=VrcU;9RL?Hnkn$bc3iUhVdNcZGw^R1O&3JGU`&Y4vr7CI=k~b+OD;O48nXNlV z_!2*r5wM2IfsLe|?4IR*4l-3uHz`Sd;3ENhMKH&yYO#XC492h z0R!r6N!(iHj-qEpcDSs1qH-wxJRO{@QOoTiwxfL@3_P|A2Tf#ogeGZ@8Es0?C*9AK zgF1WliMA3Mh_)Kf18x8(wKO$^{JCNMgWDt4t_DB#)yRoXw%6CzykB(JT{c6KOf7BSWGdGz2!v|2TK5F2oeP zy3FK2s$nXJu$m=2bP-;a&-GUEC&eG;$e6+baNizrw}_bW>4f7>PBL3hs=u5afAY;z z8n}dnDTI*Bo#Vz3F6BM2={m?6Kq67}&6;cpzOP}%I^C%g&Id<;^HCq!y_&*y#>)&k zNyvfjR?t=xa+vml;3OCu`7T+JQ=UYdCJmJN0}q=-nWU-iK)#`c#^!z>T8tmw<%5+L z`V}o34$%pMOHI)R$wzbT`PLJ{NO&;EM8Spmgm2>sl#Y>xm~t#NKlj|gr)sJdQ@hmq zOO)lzSke%^03plZ2_7@t!O%hsnR7rsxq$PXghIn1hK0u>*SqCKOuH3=krmw zY&}MS;+2{<_gK?DK)QwAL*-=tby626Kh>tMwzY(N_1g3P%RX)oCHzYj&b9tQ`!)Dq z7)(FcAD2y82Q`tt(#DctHH9A+?;sYGB)ahW)gg59kNQD(HvQHDSY+524gE+G?yH0%$Hg%NPD*eHGo`>^@m^R*`rn_JJG z?JPQC9H)ud&D3aF_me$e9WFi9ZFS4lK__sB$>T6fKyU>@|GKDy})<#oJi!08llU4zN#Y1q3OT zaNbFNBXUJ>6GxHZMdyZn=N<;ro~GFC&T^Dry&(^r$^YWXu3CxHn4Fts{a~vZ_X3*L z-5GofdfkTXO7~IOrJ1p;L_ZX!hHYVv4P7mMBsNp#6*LG5x^=&hy6VzAlWco9VBQ?n zMBCki@zPS{`B)PAhnA4fPR{6YDVqjqTz6EklV{Yq*SMRNSe!je;&)?x_$Y^4uKvOW zq(fjX!|vdWnq_Q69*7p3D?9HO&mI+z*LI4n)y-$PM^-#|^6cqqS`&8#Yp*g;66~OC z5r=z=I@Y3jyKYm()QOTixfsJo$`4&wc%{2cvd;K$m=?sGDvbpj(k;YKiNKbig$)j zt%|6cu!EFS`q;52Q^y%oTDQijd@*0ds$@1r5Yp^G$_IXWgMpPm(49Hlpw3bz@MoGK zF}o=|2-db@#@qZ##**pHW_bB^Bw7k2D4!u}!2=+!ej!-_dDw%yAL1YPGW0OXI+0Cl zge7}}#IIa5dCfr5XX&P=wvM@r4u)G1l6r?~0S^=QJ43%)2s$$maIAuRD%@1Yqr+(i zy1~hr-*wjJnXpQ_kM3~=LpO5lR6v$>P>Gc__45#ufjW|==+fW0tw2k$(*}_Sek<7< z!d~~TInN~=8}VNqQ?UsbtZ!1{vNUh(a#OB6D_?Ngi!k*w#KbdS>LJK5?($@Y@5m_) zBDn+@MG%6k1icv5%w=C*_-B*J8JAW(U=b%c&D0*aWX*l)5?f=+guweHM9;6O$UPRG zUhn`@trF&7Fv$>!Ou9@6!psdiP8m|ijpS?!6f1MXp%k?{0BZ|IWMUen&)`xdiS*`x z(K#?L9g})d1uP``EfP%9X@O$Kt`Q7#r1(y=i+|QfVx6J_Sryi2OeV@Mv;&^w$ZcN* zJHV$07fB4i1d5=ksC?K=SugIvPS*wAVymMr-6<~WjQLjl)bqP;-@s){XezE++qr^& z5ODC=+B_h}D`ynb7;5y*Ryw4y6)%}8N>+$~j&rtI>D>W_N=Z+NrHj1}Q43~%cX#L-?4nhs_Lt6hIueVVA zH_{G7ESk5|YVEHdqZa2CJ5eXGdE%_zC+ow?V611wqxDxP{=KxDk_X2szFz+V75`dN z(dPT-Qt;iB-mS@hEN`6rKo>O?Ggkgj*Z((*jGBf_32C}uJ)}+!lYBaVK2n84M$A#S z`{I)+1&S&uI2YGaP8G z1SResLrH6yA)V>yNN~5!oOVdLkW?4htLic;z@w}mf||S|-HTanC7P$&HFekj+)6=p zq)Z+iO1x2m3X4Nxct}^uPIww4<_c%0Dc3+A_3)daf%b_{6{>nDo;lA@g8^Q=7a^86 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

2E)q3y>v4hT??WA1rX4Zb^&MwMr+47_r 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 F{|92uq~HJm literal 0 HcmV?d00001 diff --git a/fedora-31/.doctrees/index.doctree b/fedora-31/.doctrees/index.doctree new file mode 100644 index 0000000000000000000000000000000000000000..9f150f3ca9e2f06064391d9cb46756e8379f872f GIT binary patch literal 7349 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 literal 0 HcmV?d00001 diff --git a/fedora-31/.doctrees/intro.doctree b/fedora-31/.doctrees/intro.doctree new file mode 100644 index 0000000000000000000000000000000000000000..ec1909d39d1fbebf86804ae67022337a4c06d3d8 GIT binary patch literal 9092 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 VlOwWSEVOx%fGVugZEN1`{0AE-2F(Bf literal 0 HcmV?d00001 diff --git a/fedora-31/.doctrees/livemedia-creator.doctree b/fedora-31/.doctrees/livemedia-creator.doctree new file mode 100644 index 0000000000000000000000000000000000000000..b9e640925e160e47be142746b4e4fa916e3f149d GIT binary patch literal 169984 zcmeFa37lLt?q;H2ad-fzH}S?pU+dZsh&h&I(ZEi=}d*;a6wxpDnKFoYwU7tx~OO=!>h0 ztBa@IKRbXQSG7v5vhV!VIjdZn@hg6zl*{HDey&w(%n~tZPaXA-(^q?uJUq*+pz5riH3iU{6bPwC7ByrvUA#SyH%_;nj)}`_Ss73 znPB}Uh^6=p$f9@=P5Ho#r;cj;eq1D&KX^F zv!*%GpTPNk=6Ego&4(I5CmjiG2y>_f)&1Ihp!j@Lc(k9qI;-)acB3@g*;vVy%B|Xt zu1}Cak0`b_c2?fzaE}N1!SCB0dsSDg0`Z;wc%e`22GRERME@GEQ8k_l;w&k0Qmt2m zkTqTxgpBtI`irZM{uyjVMB%+Qz~zk(S9AGVwUF~}Ew)4flEOCtsLx5!)w;cu;sOC6D%+v6GXnvgUOoq z8(e?pVBN1CZo%*k8UQ{$rgI%tjwONOJPc)do>rF54f9e7jnp+-pPX;oclg+A`l)i~ zR5qC%Tf)M3OG^D@3rT>cX07O~M(<4dt^w~{m8i2u*QHt77I)U@A7*pfE{EPJ8*P{_ zzKtON_D;qayTa_=m5R5Gol~}D95K;Tq&J>9Z=~rSS!>|ue9L)>PkuB_pSVRH>0Fi2 z8xHD29r6yNXW7JFaO!{|CLhCegu{&OiO|bPSNtA#Me)Oq{8usj9I>bukzN>@qs7v) zU&V&b{eZl{2fmg@=Bj-0kyuYiYov+h?DfWO|&!_X&(W387`50T_0+b4V&MP%ZD`_}>z^}Ar zOg0vh?ExGDJ&5t}KL}3%Wir~eC{_6g-fsc17IZtnUH}<4$DQe~}R!9`wo1 zrqS16HDF!b6r74b{R|k{1Kl%c^z51YqdrSETlC9ybV<4FVJe%)tkC!1e0sG>a`3!b zU3{b53>sNMLuV?uLqEvryt;{&r|)*2pMQX?YBso|L_u0jP$YT8@Ge7{_35gtPGE>ncR zs>PSFtT=<1`xd%zWpbN?%SAjMlS1Kdm{+?T9_CpA*cBdvE5M5JMNT)(hs1Q_*Qmx{ z<$Tt@Lrpv8(eSmlKaBEpoR@~dbXM=Yo;oy4%`xiJto!-WKnHsdyJY-HtFcJ=E5%RGspU(G(W#Rvpq)@@q))RI3*Jsr2Z`U7pc`ne<|BXt6( `y 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

>EOJhthhWik<-0$u5 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 cF^G0~71PJSdn<4-Nk5}B(?%qfzIr literal 0 HcmV?d00001 diff --git a/fedora-31/.doctrees/pylorax.api.doctree b/fedora-31/.doctrees/pylorax.api.doctree new file mode 100644 index 0000000000000000000000000000000000000000..d42681502fd7c348784327a0d9c7363852150ae6 GIT binary patch literal 861125 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Ķ=N8I>RFP>LGJDfFWfPiQ59*Yv3kbzNHEh(`h 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 z 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 NKubE!` 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

Zk~nVuz!ND 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�zb%n+mZv>2f7ZRKCE zGvTUO^B?r&^bPU$ShK6D=)n}H$ld}Zo3mz9ce)X|kFue((LS~I7~Zg|iu9`@YIkYV zEvvL8w8@s$UbQAnGGMq?C}wdw6gF?IsIA^+Mf61WUJXKk7u^~&lBh!$p2vIVsk zB##zP?i{Pg6`|aokzy^I^S#Mrv$*g@e5p$L-wo}`l*N0cESL~kDgwRK5Y(d{r@U46 zvoV8I8B-J{=97A$PTQcMU9)CynLc#j?=>Yo-9Or``+CCGkn~#~wFWFJzfHpE9Pa+m5kY6JZi?{o z>1RDO*be!5%(zf?2x-cX$+0^#WUzE_;7ZL%7(B-y>ivOmW~z2Ccuvo~;kgtoVCOnY zTP(4IiyV>(*v6smQR9l0a9|v^4xwwv9TK`f0{M;56;CY*U5`0?AC|bhV+b`FG2u}? z6ip91+N`dUG5}JIs z9k3soga0TJ)NJqRXci{dX)%O14BGn%k7;J7r_jeNPMY5@Afq3+$QCWZf{sT!vdv`x z9ds(5ox@(LVCzw-fIEJ%q2Jy)^f_VzD3I#WhI4N_ zaH3gnU;)vLe{UB6bz7nNv;+BQh2|5E(le~ktcquTF6HK-ILsZ&jUjzVxw!__8RbSi zwX59xBcUdhn+)>Osi1p1R=HVo9t(gJLd?pDs+zk)(;+FU)EYIATlhkcb?+C1Td(&s zLN}2)>0L`-h!9eb$%e&!DYX?B9ipd9b8ThL+nZ=B0>w_Wl}%C>D%!WJv1~}Lu>?Uy zYc0j;)LO!5#Az;7_v8&$l#UUF9cnL!Mf8}O9g)B5xxn`GQ5aXvhO=LbIRa(Hyly-R zUGo2jCUaskdMiz49T)GCCUaKjupRn}+DI1GaqN+{rE};?bx|wRQn9h&JhvS<(QG-O z$(T9dod7`H)?}&<l~$LSd%$E88dWgGZS&xJG2=?{*X4a4AmKJMm)8v&Aft8 zliJLo$V+WT_js%}vr=m_*t~&&X-YT*b(q+4dTe`dB|Lh)y9l*pn#*$fLTD~;mW_z} zQfe-)Hb+m9=9K%nh?R3mjXj~w?kk=uG{M+1`UdD~jz& z?$GYCtMTbtGe(rp+fBY@Dtf+sYoC_Te0Fu3_d4F$)J&mYEN>)?8Z+##;_ zX;f#po_K1P>+SbW!}UIgdL`G>J?!9m_U4mkUOa(o@QOuy(@D0(_YM~_MO>Futxcw^ z{U?%C*8Y=@>(NutTaGqCKV3#mYcdOoNy{4~KT9na8ut?VIQh;K7tPvb@BIKB#oj%E zVkcVd8Iz?-Rg%6{Hjg7&#Zo!5r@zT&KVS9Htp3_*(fKUUaqRxcfbQb^*x?;n;QLwW z#MV1K?pPJx6f@}jtp6N2)ZinTA+mJ9{tdF;cEY>M?0>{Tw`lf%t)uh|v;W@cQRGs5 zua3jmAp#7^Ln7cAsLqH0@zkyexRFqkitky-OA(-ZIaUO0JinBxl(3(hrb?gWFpBS& z$~$f5@0(AS0O+t5Jq^8AQyXwxmYS7}{cof%1p9AD0>phOofb@9|LTYrL3lWhHC$V;}aJ2;lD4{Vx{x1wjN*mE^e%}wC;)6%H8m``Z^ z+`gv5>7^kcXltd zimLG%c&kSvv-^!PL($Lf&yWKU?0&`wWpVvRk7+%(&fXvt{1pM+{IBeWZ%x*4wIOLs z!s0Thn<16AnW)xfiQ_r2iIzBHj?yzMae_9fJy0EjCmV;eL+}`)hXl_lsLlu;@zk#1 zc@d!|1tPtvR3!zMExG=_Ih^5fZv6MBF zTl`9ocJCPA3&C?Vp`A?de1=*j1kcmxLKJbS6rkm>bRZ`h3b)O)x-Q zVS?=Pb)+$g46JhsxUnu(sFaGC;am|xRcu0eF8PsN7S3 zEV7ysIIpZD(8(hu`q?Jkt;tBI^plr!aoZ@5jY#+A&SA_EouF(a^=P-{J)OguD;bUg zq@Qg_4|M^OyWm$Y#n4V(_&M_s3m<>u3HxxYlbM z?tgU-Hyo}|PPgz6HtfH44%-#9PeOP7WW!(hp5|(rltazteN@0ci9^)SHXbWF$KxQs zs8&61zqDbl=^W<4VTC|JcKu|-KfN9J(R!rnDrpnC1Y8$m7+&T;KH4T6bd;W1o6vg! zW}3tD+Z>0P!}2qv4OxCy0E)5v#8XR_Uw)3qv6Kj1<$HV%^3v?nT9U);3!M5m^jw^! zsBB1W7%65dl?~U5Qx(_p_)NoFF<1U>0_~euP>^n9!c0R9!+j2lw-&?jC5{@b(G(HG za0=hG9>Z`Cz7jDEsZT@$vbl&gpL0wHNb@1-o;(Dweu zf=_Zlu+rZnG^|u5U#b9&!r}E zyNi4Kh7q{Ds*Zi8^l}wO*bG9{oYi|DHNV%pk9sJP|6zKJD(*nj6>Ue^I+4g5dGym~ zADJ+U$Hmy{{aj_hVppiH@aIvTk-*}qB?-)$f)K)U?=wR9i>Ox$Vcoe7AsjhYeEvaKRnc5N=pVF$ z{H+FxVYemEW;K)BJxO!sNNIBKP_~>Isa1#arP9vG^)g>S8#Z)O92*K%AIXv$Bi*0! z4(L2zoAAA3eeLWIeV=9$DSx1GVj-ePfQ-sSaQtF3$g^ntH4$Qd2Dt%c#rT{-YS|vM z*-Qa$o$VU({Q$KQSE zE-symL)yWm4b?+jdOfN$Tv|M}%cWmTsL5>_rz0=9wC-pJmkyXpFFg-aly?Kt2u@W- z%7sbn5JXrL9?{5DOTo>8t1BrE*x8er$l}iDYOOqh&~CJ?gVxg!D`*@)AY6C}J3K1< zS8&qQ?tE?{#j&kuUkLPQsN4lCD~yj;6k~YG;G^fL_j)2MVyY9Zn{XtbNpc!}A(r)~ zWUpY2eLW)Uu6f}UN7ilJCCOXyQ4VLUin)r|Y0pMR2K({lUQJ)`a717tp1AQdC5g)= zV1wjFs-^PYo^)=kKXp}l)fs1~knMfMjr(?1`YZWW>r$%*iiP0;@$CR3Gk|cbeUpV< zrRu6RR|{qimi5#})b!LlL{Ht@a!<`h|C*kPR!DrBjBC0@f7o1;`3w+_(qud_m^#_{ zbCzF`8KPUnqqd*=cw-7{K$E$0buVtpiq&UA0A^I5aX^pLXDlh;_#UQDI&T&>=PP2Q z6rb|F(c_OTyYI#fKBc(O^5!>byux1r%WfLfJV&#bEI$3rQA8N6OT)j|&HQP?W|9GG zn&~}CEha3?RPi3hJ0lRqQ=0;@5!0_qR(@R*-e43jD^J=cWF7HlnnfhxD9@)V{cO0R zPHq3Hv)N_l|45hjWhCc<7)EuVHchE9tG zofhIxLOCtzM1gP&oy^D#UX|qI{;mNO{b6(Np9aE_++U#B3HN_`fvyU~-Vq${%buEq z^N;7M`BD~q-*qWuzfVT=TUAH${P>M9D@$c7H!-;$5DEQjk_Zv$C1mhdv+Yc zF2jz<%%dY@*qw@>j2shBZOSpPMyM&nPJ=X^>=0H-+;68ls%n>Q-G;iN*p{5}?YiIA z@644aa>YbWH>H_@U9FCDyUA)hU{sd>Usu<@w)h_E=O#v_VoanhzC(9j<2l`DOu8`v z9dWMyLGW4qY;)L;C2Rf!K2NI<*KUP ziS+}ZHBA$1Ls?v6J;Z*OY@!LKwSj@S=@qCva+)b6#RwgdTSt#G5G^bBi-mUR)Fq>hbI8{$xQ=!J&nA-(Vy zn6yToiKjN@nfDw*P3nce*37_kvqOB@4*x5+zze-iNP!fE{2~X2lm_JWr^hPxy7Z?m zrjWG6_t+00Hq7L*I0%p#$qT=I7Ora4fQ>Tc+ys2p^bD_v{3=7P?MiJF>=H#rOK>en z+Qa$Z-(yve+w7}**D>(i9;_qK@_;}prLMjcfJzACKqpBN$AGJl^^>Q8KU8AJOkDY2D@@u$xTDm5v!>ew5^B)+Nd*c*f@)DIl!RWt}y9n-i<9oHgr1Wd5wQp~(3L z9xDP;ryS}uj9BM!GhZD6t-6)tW~+SFq-ifBE?Vk^?io%Cn+ z5m24ysgjDfm=`vJ|C9_tr7(Yoi`xqG0^e9r;H-Bx#K+o!7(GP;YOIThUEIch!2MzS zB3h08YfMwk=4x*lG_1ya*okx!s4y|*EvFX?@FKTovRD`?RHydw?_&Las*&ubWbaEr z!J)1GDGoD-wrWTl(pDcpbw*niPc3PyY8yYHt5nqokrxx&Hy;Lk`ypc7-acXEsw#R& z1%=VP(b~jF70TO`_eX&DHee8h#Zgxn|7pP>_JxVjQW6Q^yhhknSqGwEt*gE?1QS;O z_{=fi%{z$8GnAjBiy~pGW9IoyLcd7Zg0fO1JhwYuBUj5qvLSS10(G9^i0&V4);N@~ zjU+8h8@+3&xnXH>h^uE@!eWjns4!KJHg4A?!%Yc_aV~BPii6Yzh%`hLH2b9u^9Aj| zjGos4QQ@Ls7e&SE9mq$Eiq|8qQaEOZ6#$o0V6^67SQE?%vGonH~wIwPD zT_q|mMqY{vGa1?w6|SnHhg6)Xcm#+|lc?ygRLgLA3>8bebLAu=!eu*Hl|+h$#lAL1{b77x=PSRSKslwdWDY>l7jaW;)4F~-J0ehO%YX}z===Hm(5LIT9J z#rr)qD=a|f2uKXr=H&igu-#KV+Q`g*AQ54e#F(A1xb#=M(C;GmKE{DfH1|$9O3yI& z{vY(AgL@wphna(W8`6fj_xAzCaBuO{7WXD}75Dxj4L{x<;Twrz?rr;|8@+O49X62@ z2OOcB(8Pf4S5u`~5j|GDtsoKR!(a@h$efU#!XFUA!c(}JJ{F$B+j`7aZDE>tZwS3g zdvEc*YxHc*U?+R73g@sw+W$%;$OHLM!b_M8V&@`+Z;~cGlkVqXg|z zeSN9zELdo_o~A4#m-asAt3=Ow8MwgB1a`;Z>^*`i>qOhn3d}3~0hr2xgo-(A%@oi- zE_30isnu})46@Moa-<2;#JUZ+$9uiWm}XD|-X|JBr1x)CbvYwnFN!`dL9J7ws2XRw zQ^`4Gb>P|^c`QlLk_CC2c_9V%7)F*}p}~Sl5qH~F^!#Y$6HQ$2okYZ5@9hbYx91CO zm{;wHqmc9>yI4c}+Sq4-a+EeE=L*Q$_SxgUS~j<9C|4QDOy-g(WKOTGuZ~E4Ot9r< zLBbC9Rg>nxU(=vDeK%$V_)YR}(x71;->viGz7~co@deh8(o5@qr$;lhm7gYT2&qk` zA>O0Zrm)&Ho9XS)ntVUdu|84E#^i})m?)j;w+V|&oymoJ7j>qC-yc@^qIIUlj?y!% zGd%|KIdrCj;xKdQOop@}o$0H9Vss|))RxXf=qjD*>&Qzyf2Ub)!SM|%r6JVLJACq9_UDY2?c`ERI_t7TJ}yd*S{ZGOHt zzd+C|zXs~ttzh*%>TI1*iPHJS>P6!)|56)y@>Hc#---NP&uH&CpaodQ6*1$9kXwXu zJE%DGNXGB>4n)xrA>_$VTcgOtjl&!?7oN&FgVm`FVKZf6)3_+w{HG6bN7#mJX+$cJ z6r#S9!JU}>Z8 zOZ4FBYIl)7WW4xGLp`gk7RN7kTkc5M7IL$gws^Nwvq;9~jay`%>Inthys%-uJt0hz z>n@n~>g&lmz-8iomuA!Je2Z2M9Z^#95&dlA{?TN(D^1{oT-^53%$0a5GU;a<(m!+q zl9&Jnl62B$7N67ovD{A}r0I2}P-KQF}X)|?p%6lhB?NHthj6=(zycxO%H5Bh=Krzaj zcycIjOM;AX%3Fs?ua>n5SEae#g1pq+G;@pHf!XLVI^C&Em1&4hcdmontwpCh%Ta?h zjv}JdU4rk-s#rsA%?fUrpr}o|Gv$e?eO`vv?oYy3B03%QiHJ^jK4Ac@hoaMUSJi=B z5tNUf;sC7Niq`-S=~g_Mvg}rD+Z%Br?Vhh7umd(OkT)VYLbXn0LJ(Pz&}g>lGX1{F z0&WR~YLZB3$0*6|uP-f;L@07x`l9?4M%*v3U`u1(|ITK?*HdpMSkED$ze|!C9lxVn zIji>Ez{@RB_3&xWVzK5dhyxvFZHr+GlJ zIZunOnUqht(&jQtqCX6>S?gfL9w$cZ-IQF`RGf}>M`{l&`+tc`hMm8WPS~cNU-GOr z@%%2ngk7bfD+WXFHAnGYiYAj2iH1uP-IInAd3tZ5;>Oc^R|hUpWqGEIgLjeb;0*{9 z1H17|H=`cnliou^k$&BC;Nd)RzjF$gSlYZ7Snv)XAW^6_z?o%_r}KRr^&EVBL7DTi%XI3YDX8HbNhWT%vz#F z{-0xTH;$9mPo69ZI_Hc}?mGbM@X7rl4jYGbH{=XS_xGVXW3h-QhjgDSXNc{JBNUZH ze*k%DrRd@Akm!MpXRGB!5bB}`H4(`(-A`=sqEa!ND<{4=;sowlpKnfILD95k?>zsi zf)<1UEYwVm{N0`+Pj`&6*4%mP9W_|WW`sNMJbY(HWm0$EYJ4T!dDO4MowtE7knX&$ zNH{Pl(MLvYQLE3s^=0M7+X3*>iy|nygSnXYuf-WK!jPP&U)UpSl6s|yYNX^QiG-r0TeLqmv5Mj& z0}C@F?XOI2Ox>_LQyyQvA;o{z@t^$Yr0+%Hl&7CYk9+V3zfVq%oVLE0qc@YZ>2z|0 z-r~oh)7GnEH>oK%eE@9Az91oGX_eSe)_Xn?nP_50wKs-$hO>&NSkCJ4)T3K?8jb;@ zcx^%Vse$a^wMjfeuBuEUf>SeSs?68ZMjq$87np?&D4r*sI)&CCT=Hq_dHy0svv$F& zX=TmeqZGGSzxMk-?qC)#kEk#(lMk}NiP>zww8!1YLARtc`Xjpc8(TUwIs#+~%&eKQu>$|+}@xQFIzA%oe9znKj9Dzd^7faciV$2L{Il#nVk8x2*wFA{+Qv++T^ zGqX`VwK5wcI$q7l59&TK(A%7muBtkik-r9J&1YnEmnLSPmc%fnmTqM8(j2$0u{?6qJbXZg)1l7JHwTEBsO0tLaAsC8 zL0RbrKC{holys)u7CLy+D?;32qRfIUhG%Js@B`Sg!$|oDzNeQ8m zTH}P)z2&Y=4pgEo#B&{`Ej_)1<*p_c;wb>@un?aahmFHRG~^6fhzn4i;hf?rmUF7j z8ib5Km}kA<}O=uFj)-1`}I}lT0C>m3XYv{&dxDTZ$_bQ(;Td zF0WMAre*92a1-N|vGlgqEXKW#8my5RVKLV6UF#NO5nl<5k@{I!j4vPzq{Y}N*Wv)` zqO+o94GAfEHsisQ|m*r;nB-xJ~*hEXRe{+{!1Kc4zXrv8xm{xp*kbh#8a$T^O(=^CAohjbmVI0`;eECO?RO~ zvRQoHPgP=Ja_P`jRW$Dl>e==VjTIkuss7B0I#smSQgBG-Nr;&+Hip;EJI#3EZedljDVhUoLeZCHSV}7n?hr1S%)xpM5ARHTsB+9kI^1 zhz7fM#~sy_2+TtRyXEGHFO=${9_*fMf0XGjiQH9xPAU|<%_UXrt3*(hf8!r z1h$-w-~g#UT3F5%bMO@Dv!#5I#BdFlt`#|3s2~z;rnvEfOp!|ME|ob9D}~nMSd5dk zDxEzQ&w2xmeBM&?YoSla$PM`$&XfsN)yGsq8V!cmtp0zxLbt^&3T(ur!o4Hvg%_| zRw~VBcf_h0r4Vbrau0^k{|%fcXW+PukXh&qCG|OP51nTu8#>DTIGu~z=7&Be-2B+^ z#a)1u?AY)XU4SH+oT3~YHO%w^QJ-?1L+X(y^uan6F#jvNw3?Oz`+Vo{7TMZ>f*E{m!~J$w;QF-=A6)CT4fn^L!(AHEZWL(8FE;f5 z>Kyu#pdzJ!hkvkP|FsLSgDRVb9s0qBz3`)n)SzavY>rS46-4!D!&%WeoP+&}rcg2! zOxI5~{574!KhzK3sH_TysGn^-PVXF#!y*)Gg-GP@HYS@o$7DqalQ3DDma#F~-Z@4K zeCC6qhxN{enCTqia;J@=U`PCFV^QiHi)9XzNa5i8&BoxSb})#x`vcA-V?KGOfz@@} znRL4Y`Dka-l%wuzb z*(MR!mpagbJ0zVq8wTgA*67e>zBe|D`1hD0s&@R-w!t5xtn`;eL||#Vy~e+@z#@k5 z^H}d}{C}Sif7;q-@b`X4O(9B~f$IG$-kIqoo?4h*4M)eQ+4ciXIRn`-+X6e(j=TUD zjEQ?2rEe~Uv5R0arSe`K9=LfSO)PKeLuhfYw-|q#`Nx2<+Vu2qOe5YZbr5~bo1W}& z##e7GjO=6#M+@aj)u4wf8F9KQRmo?{6kTsXb!w$QJCG`j;u=12A77=v=Th9&SKeJf zU~q_Bu1kHTB;7PaF*I5!XmnJ|G@1p<8XB1~6+GrZ)Rp@&Ttg!I!{%J`=|DJ&YkHy^ zt)boot%YXCiQY?@94%`*_61I?y0RVnSi0cNIG~B0hi>1)d86<9K+#{Xtqy4_XXZJy5HZ2Y3z$Z1k>@HuhOx9W#^_d#8QY&p}zq-n&W%!`m0x z%~ta}_*zd$J{nz2*aYJ6rU~9oYE8%|-*{ScQZq`nPdCXI*!&k)%x={4lQl}&=hr7J zE_eR9$k4@8&UZMliPp?-bCjNb&D@&+SjT>n*TiAtP{|EBLn`@pRA+Ps@f52ws6Fh2 zqS6qajl9&y&Bz__9Uc}7{Q(W3_ky5?P@x+kAV{@-(5#3aliuGG_+IaC38N+(9emos z<@ANPUgI+ocWk!}U$2qw^8Fg$O@N}jU*lVZSK5=9qG7T3Yi#gwhZNmrw1)1t*ioAF zX*Qs*2p^on&DSaQfw&nYaQTL%x5_0U>z(cZ=5#-gXq@|FrNcb>A-S~{OJi5 zDO(I5@1Jl{g?iPPg$61f%y}D~{XZ5z7``VizW7TF=Kf1F8wX78opMEhtnQu6i7){E zJ2bsnKts12;U9ZF-R%9>xLfVMmqdSdT(S<;)MzC9K%yq6u^4u-dY8Pr@31`r#4+FWeitAME2Vei5YETCex41WlCvKuzp&KP-^fCGk{H48#9Ux10N8 zX98qpf8>cEE%8Fb9Rf@QJ>uXNH^<=OX93=!D4d)H2yiwJxG@HtuS@qPC@Q;@sMJ!I zMw>>2fV>t+$wy6pI+$Wz3p6UOtS{&2YM_jn0sUE@;1MRZnjJ6|$XM>7+n->0Pt?YT zbFj62<#Q9&@?NU2oU7K#6S=I`31$kM9;G#@b1H{enRqd#Qd08c6Je<;2~ z@FwJM0OhcEK-l3@Il_Q!JB0BuW4Y>(USf|j#g{8n+$tSui3>%$>E%gQMYKUr?GpXlb0^rn|sGJ#;V9!obhM2O4;*2PO-G#}ndDHnPFr`#m)!Y$NM^ zQnn$iUy}f!tyDG+^FQ8PT~w<_w_%I|joAr{OOw`xbr((AV;tB-o3trMX}>-(J?AF8 z|3P;-OxmO3uyL5QhMXaj_TK=-n6%<4u}MoPLh^BV;UCiI5;~X}Xkn8!a_>4xP{|No zRmCtwHZ$A|@hT83iXlqIbDJ`fgxwU0V`DB!*+Q-|MJq6OH&)~P5#qTQ3lp_HL)d>? zb>A`Pj|CO_B9bY#y~^YO5$B;?7WzgXt7wD2mScvfpTAC^tmLolt}=yi5AoQgjv|83 zI)1VF+zS)7g?O!Li+3|ME5vJKhL_@*k_o!1>mn1p)6ueMCiq52=^0>xF9KKx6TBl1 z8wV3KcK zXRVfmcrEVI@X=Qd-N0KtPFbIw|B2>Jhn7bVMij#flV zma`qDXF#$n09c1)*%*h7L$Vlhh9t{>VY(T~BAyaU7D7=;mjBlC);I3Mk|nTWbm(@P zj4WK}v_+{_!TsT5+VLCpvmTV*Bv2sDCWb1cybDiG*SHGrMA=E;#ZHv)T2s8E+kbDn z^so9~>1Hw)dQpNlO84r`gjQO1#AXOs*HY65eTy$b@k@ITh2Gh!z=@J6@oE&JVeo?`JW<%+~_pxwB}sZR>ZG2wfoDZ+E}=P~%}zEWfLG5)|gR^?Ak$Lb=xNlI=9U)xCT z|Hv}*wsHS3H7FKcq9B9#wdN+ z@)&(Ih9;pg8m;$G(GQ5>{OSa?%H<&9>Is*FZc0$ATn;m=Qa3h-FAbk1h8JJTeLyoawK1nss+C7@E7clm{Qiwa z(#jr^?*|(PsWh`MALki*%XsNjxkNV1`ilPCWL=M}!Q()52!bF96}Z-1ETzZ;#~5JgUY$dQn@;Bx)5^Xm(?E z7MH(|p}s|Qktb+{5)>u|Z{}CanUNedYO3B?RG7fg(4pMKNGXd_Q;qq!BdqV~eU$?8 zN7_FQ<;vw!c_^Qm$QB_m&~a$nNEM?&95D6OGMj6eY8(~#B~XR;at!>&B2llwL4AFs z{X^j6#u92n1%%3jL`Ae|smw z9&F4Jp%aNBh3wEI-H^Kn{)5J%Os!fPGOrp3;O5-M!fb7P60T%9@IY98QNWBVBcudX zxR~F7x)T-Ze)DRwlB;D)Lwm+)NG-|jnJiUuxGu z5Q;R359g{0kzdm|2#u*=3S{V_Qv9}17UM{5c*OFFh!*;nPIqVL=MYGktfR)eXs;F)GNU@aJIg}gE6pBMQ z@mJ0<1E@D<yty7p{=xi%-fqY& zk<32;IZj?nIZlq6g&ZgEpd2U9JPm0C!?#88=>SQRD_dP%twxsdC)ODP7XW>IZk>OA;-z1i;?5xo~6if^1#8!aq@{} z$Z?W6963(j(Tf}>zc>;(PByMYj+5Nc$Z>MSD&#o%^D)SAvhsN3I5|9x+;U28Bg8p* z%^KuxrQ|~Tfs;k_$jQcjfgC3fpM@MJm1iQy$q{EG z$I0u@L5`D^!^j;;$?{Dqd4h7BJbVFioIG$La-6*NBIGzJUyK|l$3F`>PQJYvIZpO% zL5`E7FF}rzZ&Qww*9{`aN<DadPKY-5OSRSk#d~e ze=TyHT%JLWlb2SJdod-0L{3irNI6b!%Oc0gFDb{#S)<5ta(W&)PTo~Oj*}nmM2?eJ zjU&g&(UZt=a`$z}aq^idaf4CF5$0_*( zz2oHPZ$^%jUGxJd$Gio(6eauKhU9N3*+!3?{0HSYDc^-0Cx_jQ94B9*94Do>BFD)S zl;h;G_aiq*$w#SDPJVO`a-3XqFLInLdpmNRe1USDY-mL94G7VLynV&DaXmF??sN2w^ELiUr>&d2i}JqCl}t294FtW z94B9W069)x@B!p*q~vC5DkpTKw8shE!|HKzHN>#@TuSKnHj&V6Lwo^|M>m~_gd+EQ zoKUc1j}wZl>2X3a?mSNDz_P~)ovq~KmL8p$5D9HG@i?K?R*w_%j(e2U8uLj@plz|F zGYCClFh4e!zj=@~gu(oSb=C{&tP|8(AE>h~P-i`$&N@Jy<$v8H1z?cnew}50-6Nqt z$g;l9a=z}7pdV!UUT4`}XSrTynOnvmI9tqh&maTP`t96#Cb(W`S#WScp$ntPdEFbGE8vz}{vCcBF&hij%E}=Ih2kR^Y>n#83Ec;OBW%Qn89=_U6DaktE za5<$UMYypEZ5K%&!zVy&+078>MY0VEW_$7zv?Wz>MXbF9to~NmRI-{EvmDe zsMW1Yib=|o9IAUHhz42y)LHh_S?<(X=3t~j=%D=dl#-kQ ztvDt50(wHg)LE|7S*Cyj5Gr++CBXa^%99MKv;3&D?5MNcsI$zdv%ILYtN=a`7Il^p zb(RlxmJM~53mE^eq+dxM)L9nPSq^|ouc0@@|Le^AF|N=eP!-H}koi5v^#e=Bel%Fx5KqQjBD@k6=7;DVFhukYSRmeWO8l?RysyrDug*NL⁢iORMi=^Z1UfSw`eZUXqKQ1h+8}|qIWeaQ30m!k1bqD3x!df*8IkvFwqa0gU=O2h1 zTUdXl99vj717Yt3@LTVzfETf?jteBg)}!hK!rogb%Qy=Q?)?ObEw~5fAjcNm$prYt z;O$MJQ-MU#sX7V$GRg|*Y$0X|5?hFWq8wX@FDJmmt7D*3fke>%Ut?z*npGLbaYcw` zxzRLeY|I)mgUTqSa0P3k^tQ}uB%!5l%W`S?vS~55URS!NmZp`ZWtrPFwbVtRB2nR& zFl-oQ&as@Kb)N}7r&j|yRZ8`=NZp^{qFNT$K55_Hya~673dyk zq5@r+C!zw)A1tB*&AU)U1zM0Vq5}Q3Ktu)FeUXR?w5L!+1^UTQ5f$h|mx!o9x9aUI zD$wI4A}Y{v!$nk}k6b1yDpM$RpaLB^?$?gW3vb(z^ z`z~W-r$XQFOjPJMIo-$C_LI{MGUar4NzQ4;$mvx`!#oEJK;hLQ48Ud+24IX9Bw+v! zn=k;)*N89xf15A>`#jVm;}z0g6>gAeyzVX;@At+SFNWa{XTmV_juv4UCXNwd7=F55 zgkdPSL4;xG)$%9|!xNRFBCU`bN*yo^>#IZrVK5Gx zFc@!66k#w%-zmaiY@8&*V9dNrguysv!eH#XTZF+_evb%)QB@M$Hrv2IHIiMHr0M2SgZ*%4s4D#=z;K?G8N-7>p@1L>P=R zU!-Rn71FMh8)Ujt?k>4fRmOO=VMuD6=^uvybqW}gwe=zl$q5sNWc*AKhUCVFMHrH8 zvqTt@pS2_nL$YR$2tzV*t_VZYIZuQkY4?=&yrPgcFE_|EFL#&BtJ@g!!ocj-&tYH= zHHk1V2N#MkFzt&(7??6Gi^IT_YiS$?rl47bf%(dWfmyv+gn?P#BErDTXcb{#ramc} z{*=Ol4j7p0o)%$XDxVQyV6M;-ItQ~ zHZ2ulV7l5x7?>R|iZC!&b%-!9w=WZUwcU{KfPu+dA;Q31`jQ9(^W)1R3{1;P5eDYG zRU!<`IuizFoUTh4m`_dnwVqDBj&6|YI=Z{$Ivz2`b;R(Ta3&1Tpfw^4PlpM^)B36i z!}FUd49{yK4A0V>;W=c&@Jv!c5QeAQgyC8Ch6uyc;wfQx4w(K@Wso{UH^?+YcbClY zcVo;DgY=&>VUUim6S*2`SnPm7I%yjImO|Qpj2mPchr3J0QKG*|#(|+KcapYu`^n@6 znKHS%B-4a5nJ{3Joe2YW%ryUPg+&e+u#ycT4A_?@3|QkkA`I9`69%lqL%rieg|su{ z2ARg|?vn9tF~$|bu+U+W`}XZE~jw!}hre!&cQL!m#Z% zVc5oYi!f}TnJ{cqRSJe-`(ld-!&dRW2*cKE!mw3r6=B#qO&GR6O&GSGZ6XX?^>z`4 z?FSQvt@i^FhONdYuz9C{ky8D*L8i0l?vk^(z!+x{gV*Lv7`%l$L>RmQPK?3xr#&0) z(-2a};Rcz;apo(N8aAlsWE^P1oz8?NoV`ngCiEke!w~v$pkWC81hp`Peq2u&LO(bo z457aTF$|%+lxc$X6aT1?@wyWF^+h@ z{dBw7$2|K;wA1dUc68^|J~lhIJxtSK=N!zn&g;`--s!CTQDL9{b?e0ZM&GM(@wt5^ zztKl{bvHn+S^iu-d_mj5+Mm^p2GL<|)4$K*3v!3qvmIRT`w)^Xd%tX&YDfJK^S; + + + + + + + + composer.cli — Lorax 31.10 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+ + + +
+ + + + + +
+ +
+ + + + + + + + + + + + + + + + + +
+ + + + +
+
+
+
+ +

Source code for composer.cli

+#
+# composer-cli
+#
+# 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 logging
+log = logging.getLogger("composer-cli")
+
+from composer.cli.blueprints import blueprints_cmd
+from composer.cli.modules import modules_cmd
+from composer.cli.projects import projects_cmd
+from composer.cli.compose import compose_cmd
+from composer.cli.sources import sources_cmd
+from composer.cli.status import status_cmd
+
+command_map = {
+    "blueprints": blueprints_cmd,
+    "modules": modules_cmd,
+    "projects": projects_cmd,
+    "compose": compose_cmd,
+    "sources": sources_cmd,
+    "status": status_cmd
+    }
+
+
+
[docs]def main(opts): + """ Main program execution + + :param opts: Cmdline arguments + :type opts: argparse.Namespace + """ + + # Making sure opts.args is not empty (thus, has a command and subcommand) + # is already handled in src/bin/composer-cli. + if opts.args[0] not in command_map: + log.error("Unknown command %s", opts.args[0]) + return 1 + else: + try: + return command_map[opts.args[0]](opts) + except Exception as e: + log.error(str(e)) + return 1
+
+ +
+ +
+ + +
+
+ +
+ +
+ + + + + + + + + + + + \ No newline at end of file diff --git a/fedora-31/_modules/composer/cli/blueprints.html b/fedora-31/_modules/composer/cli/blueprints.html new file mode 100644 index 00000000..deb19c81 --- /dev/null +++ b/fedora-31/_modules/composer/cli/blueprints.html @@ -0,0 +1,778 @@ + + + + + + + + + + + composer.cli.blueprints — Lorax 31.10 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +
+ + + + + +
+ +
+ + + + + + + + + + + + + + + + + +
+ + + + +
+
+
+
+ +

Source code for composer.cli.blueprints

+#
+# 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 logging
+log = logging.getLogger("composer-cli")
+
+import os
+
+from composer import http_client as client
+from composer.cli.help import blueprints_help
+from composer.cli.utilities import argify, frozen_toml_filename, toml_filename, handle_api_result
+from composer.cli.utilities import packageNEVRA
+
+
[docs]def blueprints_cmd(opts): + """Process blueprints commands + + :param opts: Cmdline arguments + :type opts: argparse.Namespace + :returns: Value to return from sys.exit() + :rtype: int + + This dispatches the blueprints commands to a function + """ + cmd_map = { + "list": blueprints_list, + "show": blueprints_show, + "changes": blueprints_changes, + "diff": blueprints_diff, + "save": blueprints_save, + "delete": blueprints_delete, + "depsolve": blueprints_depsolve, + "push": blueprints_push, + "freeze": blueprints_freeze, + "tag": blueprints_tag, + "undo": blueprints_undo, + "workspace": blueprints_workspace + } + if opts.args[1] == "help" or opts.args[1] == "--help": + print(blueprints_help) + return 0 + elif opts.args[1] not in cmd_map: + log.error("Unknown blueprints command: %s", opts.args[1]) + return 1 + + return cmd_map[opts.args[1]](opts.socket, opts.api_version, opts.args[2:], opts.json)
+ +
[docs]def blueprints_list(socket_path, api_version, args, show_json=False): + """Output the list of available blueprints + + :param socket_path: Path to the Unix socket to use for API communication + :type socket_path: str + :param api_version: Version of the API to talk to. eg. "0" + :type api_version: str + :param args: List of remaining arguments from the cmdline + :type args: list of str + :param show_json: Set to True to show the JSON output instead of the human readable output + :type show_json: bool + + blueprints list + """ + api_route = client.api_url(api_version, "/blueprints/list") + result = client.get_url_json_unlimited(socket_path, api_route) + (rc, exit_now) = handle_api_result(result, show_json) + if exit_now: + return rc + + # "list" should output a plain list of identifiers, one per line. + print("\n".join(result["blueprints"])) + + return rc
+ +
[docs]def blueprints_show(socket_path, api_version, args, show_json=False): + """Show the blueprints, in TOML format + + :param socket_path: Path to the Unix socket to use for API communication + :type socket_path: str + :param api_version: Version of the API to talk to. eg. "0" + :type api_version: str + :param args: List of remaining arguments from the cmdline + :type args: list of str + :param show_json: Set to True to show the JSON output instead of the human readable output + :type show_json: bool + + blueprints show <blueprint,...> Display the blueprint in TOML format. + + Multiple blueprints will be separated by \n\n + """ + for blueprint in argify(args): + api_route = client.api_url(api_version, "/blueprints/info/%s?format=toml" % blueprint) + print(client.get_url_raw(socket_path, api_route) + "\n\n") + + return 0
+ +
[docs]def blueprints_changes(socket_path, api_version, args, show_json=False): + """Display the changes for each of the blueprints + + :param socket_path: Path to the Unix socket to use for API communication + :type socket_path: str + :param api_version: Version of the API to talk to. eg. "0" + :type api_version: str + :param args: List of remaining arguments from the cmdline + :type args: list of str + :param show_json: Set to True to show the JSON output instead of the human readable output + :type show_json: bool + + blueprints changes <blueprint,...> Display the changes for each blueprint. + """ + def changes_total_fn(data): + """Return the maximum number of possible changes""" + + # Each blueprint can have a different total, return the largest one + return max([c["total"] for c in data["blueprints"]]) + + api_route = client.api_url(api_version, "/blueprints/changes/%s" % (",".join(argify(args)))) + result = client.get_url_json_unlimited(socket_path, api_route, total_fn=changes_total_fn) + (rc, exit_now) = handle_api_result(result, show_json) + if exit_now: + return rc + + for blueprint in result["blueprints"]: + print(blueprint["name"]) + for change in blueprint["changes"]: + prettyCommitDetails(change) + + return rc
+ +
[docs]def prettyCommitDetails(change, indent=4): + """Print the blueprint's change in a nice way + + :param change: The individual blueprint change dict + :type change: dict + :param indent: Number of spaces to indent + :type indent: int + """ + def revision(): + if change["revision"]: + return " revision %d" % change["revision"] + else: + return "" + + print(" " * indent + change["timestamp"] + " " + change["commit"] + revision()) + print(" " * indent + change["message"] + "\n")
+ +
[docs]def blueprints_diff(socket_path, api_version, args, show_json=False): + """Display the differences between 2 versions of a blueprint + + :param socket_path: Path to the Unix socket to use for API communication + :type socket_path: str + :param api_version: Version of the API to talk to. eg. "0" + :type api_version: str + :param args: List of remaining arguments from the cmdline + :type args: list of str + :param show_json: Set to True to show the JSON output instead of the human readable output + :type show_json: bool + + blueprints diff <blueprint-name> Display the differences between 2 versions of a blueprint. + <from-commit> Commit hash or NEWEST + <to-commit> Commit hash, NEWEST, or WORKSPACE + """ + if len(args) == 0: + log.error("blueprints diff is missing the blueprint name, from commit, and to commit") + return 1 + elif len(args) == 1: + log.error("blueprints diff is missing the from commit, and the to commit") + return 1 + elif len(args) == 2: + log.error("blueprints diff is missing the to commit") + return 1 + + api_route = client.api_url(api_version, "/blueprints/diff/%s/%s/%s" % (args[0], args[1], args[2])) + result = client.get_url_json(socket_path, api_route) + (rc, exit_now) = handle_api_result(result, show_json) + if exit_now: + return rc + + for diff in result["diff"]: + print(pretty_diff_entry(diff)) + + return rc
+ +
[docs]def pretty_dict(d): + """Return the dict as a human readable single line + + :param d: key/values + :type d: dict + :returns: String of the dict's keys and values + :rtype: str + + key="str", key="str1,str2", ... + """ + result = [] + for k in d: + if type(d[k]) == type(""): + result.append('%s="%s"' % (k, d[k])) + elif type(d[k]) == type([]) and type(d[k][0]) == type(""): + result.append('%s="%s"' % (k, ", ".join(d[k]))) + elif type(d[k]) == type([]) and type(d[k][0]) == type({}): + result.append('%s="%s"' % (k, pretty_dict(d[k]))) + return " ".join(result)
+ +
[docs]def dict_names(lst): + """Return comma-separated list of the dict's name/user fields + + :param d: key/values + :type d: dict + :returns: String of the dict's keys and values + :rtype: str + + root, norm + """ + if "user" in lst[0]: + field_name = "user" + elif "name" in lst[0]: + field_name = "name" + else: + # Use first fields in sorted keys + field_name = sorted(lst[0].keys())[0] + + return ", ".join(d[field_name] for d in lst)
+ +
[docs]def pretty_diff_entry(diff): + """Generate nice diff entry string. + + :param diff: Difference entry dict + :type diff: dict + :returns: Nice string + """ + if diff["old"] and diff["new"]: + change = "Changed" + elif diff["new"] and not diff["old"]: + change = "Added" + elif diff["old"] and not diff["new"]: + change = "Removed" + else: + change = "Unknown" + + if diff["old"]: + name = list(diff["old"].keys())[0] + elif diff["new"]: + name = list(diff["new"].keys())[0] + else: + name = "Unknown" + + def details(diff): + if change == "Changed": + if type(diff["old"][name]) == type(""): + if name == "Description" or " " in diff["old"][name]: + return '"%s" -> "%s"' % (diff["old"][name], diff["new"][name]) + else: + return "%s -> %s" % (diff["old"][name], diff["new"][name]) + elif name in ["Module", "Package"]: + return "%s %s -> %s" % (diff["old"][name]["name"], diff["old"][name]["version"], + diff["new"][name]["version"]) + elif type(diff["old"][name]) == type([]): + if type(diff["old"][name][0]) == type(""): + return "%s -> %s" % (" ".join(diff["old"][name]), " ".join(diff["new"][name])) + elif type(diff["old"][name][0]) == type({}): + # Lists of dicts are too long to display in detail, just show their names + return "%s -> %s" % (dict_names(diff["old"][name]), dict_names(diff["new"][name])) + elif type(diff["old"][name]) == type({}): + return "%s -> %s" % (pretty_dict(diff["old"][name]), pretty_dict(diff["new"][name])) + else: + return "Unknown" + elif change == "Added": + if name in ["Module", "Package"]: + return "%s %s" % (diff["new"][name]["name"], diff["new"][name]["version"]) + elif name in ["Group"]: + return diff["new"][name]["name"] + elif type(diff["new"][name]) == type(""): + return diff["new"][name] + elif type(diff["new"][name]) == type([]): + if type(diff["new"][name][0]) == type(""): + return " ".join(diff["new"][name]) + elif type(diff["new"][name][0]) == type({}): + # Lists of dicts are too long to display in detail, just show their names + return dict_names(diff["new"][name]) + elif type(diff["new"][name]) == type({}): + return pretty_dict(diff["new"][name]) + else: + return "unknown/todo: %s" % type(diff["new"][name]) + elif change == "Removed": + if name in ["Module", "Package"]: + return "%s %s" % (diff["old"][name]["name"], diff["old"][name]["version"]) + elif name in ["Group"]: + return diff["old"][name]["name"] + elif type(diff["old"][name]) == type(""): + return diff["old"][name] + elif type(diff["old"][name]) == type([]): + if type(diff["old"][name][0]) == type(""): + return " ".join(diff["old"][name]) + elif type(diff["old"][name][0]) == type({}): + # Lists of dicts are too long to display in detail, just show their names + return dict_names(diff["old"][name]) + elif type(diff["old"][name]) == type({}): + return pretty_dict(diff["old"][name]) + else: + return "unknown/todo: %s" % type(diff["new"][name]) + + return change + " " + name + " " + details(diff)
+ +
[docs]def blueprints_save(socket_path, api_version, args, show_json=False): + """Save the blueprint to a TOML file + + :param socket_path: Path to the Unix socket to use for API communication + :type socket_path: str + :param api_version: Version of the API to talk to. eg. "0" + :type api_version: str + :param args: List of remaining arguments from the cmdline + :type args: list of str + :param show_json: Set to True to show the JSON output instead of the human readable output + :type show_json: bool + + blueprints save <blueprint,...> Save the blueprint to a file, <blueprint-name>.toml + """ + for blueprint in argify(args): + api_route = client.api_url(api_version, "/blueprints/info/%s?format=toml" % blueprint) + blueprint_toml = client.get_url_raw(socket_path, api_route) + open(toml_filename(blueprint), "w").write(blueprint_toml) + + return 0
+ +
[docs]def blueprints_delete(socket_path, api_version, args, show_json=False): + """Delete a blueprint from the server + + :param socket_path: Path to the Unix socket to use for API communication + :type socket_path: str + :param api_version: Version of the API to talk to. eg. "0" + :type api_version: str + :param args: List of remaining arguments from the cmdline + :type args: list of str + :param show_json: Set to True to show the JSON output instead of the human readable output + :type show_json: bool + + delete <blueprint> Delete a blueprint from the server + """ + api_route = client.api_url(api_version, "/blueprints/delete/%s" % args[0]) + result = client.delete_url_json(socket_path, api_route) + + return handle_api_result(result, show_json)[0]
+ +
[docs]def blueprints_depsolve(socket_path, api_version, args, show_json=False): + """Display the packages needed to install the blueprint + + :param socket_path: Path to the Unix socket to use for API communication + :type socket_path: str + :param api_version: Version of the API to talk to. eg. "0" + :type api_version: str + :param args: List of remaining arguments from the cmdline + :type args: list of str + :param show_json: Set to True to show the JSON output instead of the human readable output + :type show_json: bool + + blueprints depsolve <blueprint,...> Display the packages needed to install the blueprint. + """ + api_route = client.api_url(api_version, "/blueprints/depsolve/%s" % (",".join(argify(args)))) + result = client.get_url_json(socket_path, api_route) + (rc, exit_now) = handle_api_result(result, show_json) + if exit_now: + return rc + + for blueprint in result["blueprints"]: + if blueprint["blueprint"].get("version", ""): + print("blueprint: %s v%s" % (blueprint["blueprint"]["name"], blueprint["blueprint"]["version"])) + else: + print("blueprint: %s" % (blueprint["blueprint"]["name"])) + for dep in blueprint["dependencies"]: + print(" " + packageNEVRA(dep)) + + return rc
+ +
[docs]def blueprints_push(socket_path, api_version, args, show_json=False): + """Push a blueprint TOML file to the server, updating the blueprint + + :param socket_path: Path to the Unix socket to use for API communication + :type socket_path: str + :param api_version: Version of the API to talk to. eg. "0" + :type api_version: str + :param args: List of remaining arguments from the cmdline + :type args: list of str + :param show_json: Set to True to show the JSON output instead of the human readable output + :type show_json: bool + + push <blueprint> Push a blueprint TOML file to the server. + """ + api_route = client.api_url(api_version, "/blueprints/new") + rval = 0 + for blueprint in argify(args): + if not os.path.exists(blueprint): + log.error("Missing blueprint file: %s", blueprint) + continue + blueprint_toml = open(blueprint, "r").read() + + result = client.post_url_toml(socket_path, api_route, blueprint_toml) + if handle_api_result(result, show_json)[0]: + rval = 1 + + return rval
+ +
[docs]def blueprints_freeze(socket_path, api_version, args, show_json=False): + """Handle the blueprints freeze commands + + :param socket_path: Path to the Unix socket to use for API communication + :type socket_path: str + :param api_version: Version of the API to talk to. eg. "0" + :type api_version: str + :param args: List of remaining arguments from the cmdline + :type args: list of str + :param show_json: Set to True to show the JSON output instead of the human readable output + :type show_json: bool + + blueprints freeze <blueprint,...> Display the frozen blueprint's modules and packages. + blueprints freeze show <blueprint,...> Display the frozen blueprint in TOML format. + blueprints freeze save <blueprint,...> Save the frozen blueprint to a file, <blueprint-name>.frozen.toml. + """ + if args[0] == "show": + return blueprints_freeze_show(socket_path, api_version, args[1:], show_json) + elif args[0] == "save": + return blueprints_freeze_save(socket_path, api_version, args[1:], show_json) + + if len(args) == 0: + log.error("freeze is missing the blueprint name") + return 1 + + api_route = client.api_url(api_version, "/blueprints/freeze/%s" % (",".join(argify(args)))) + result = client.get_url_json(socket_path, api_route) + (rc, exit_now) = handle_api_result(result, show_json) + if exit_now: + return rc + + for entry in result["blueprints"]: + blueprint = entry["blueprint"] + if blueprint.get("version", ""): + print("blueprint: %s v%s" % (blueprint["name"], blueprint["version"])) + else: + print("blueprint: %s" % (blueprint["name"])) + + for m in blueprint["modules"]: + print(" %s-%s" % (m["name"], m["version"])) + + for p in blueprint["packages"]: + print(" %s-%s" % (p["name"], p["version"])) + + return rc
+ +
[docs]def blueprints_freeze_show(socket_path, api_version, args, show_json=False): + """Show the frozen blueprint in TOML format + + :param socket_path: Path to the Unix socket to use for API communication + :type socket_path: str + :param api_version: Version of the API to talk to. eg. "0" + :type api_version: str + :param args: List of remaining arguments from the cmdline + :type args: list of str + :param show_json: Set to True to show the JSON output instead of the human readable output + :type show_json: bool + + blueprints freeze show <blueprint,...> Display the frozen blueprint in TOML format. + """ + if len(args) == 0: + log.error("freeze show is missing the blueprint name") + return 1 + + for blueprint in argify(args): + api_route = client.api_url(api_version, "/blueprints/freeze/%s?format=toml" % blueprint) + print(client.get_url_raw(socket_path, api_route)) + + return 0
+ +
[docs]def blueprints_freeze_save(socket_path, api_version, args, show_json=False): + """Save the frozen blueprint to a TOML file + + :param socket_path: Path to the Unix socket to use for API communication + :type socket_path: str + :param api_version: Version of the API to talk to. eg. "0" + :type api_version: str + :param args: List of remaining arguments from the cmdline + :type args: list of str + :param show_json: Set to True to show the JSON output instead of the human readable output + :type show_json: bool + + blueprints freeze save <blueprint,...> Save the frozen blueprint to a file, <blueprint-name>.frozen.toml. + """ + if len(args) == 0: + log.error("freeze save is missing the blueprint name") + return 1 + + for blueprint in argify(args): + api_route = client.api_url(api_version, "/blueprints/freeze/%s?format=toml" % blueprint) + blueprint_toml = client.get_url_raw(socket_path, api_route) + open(frozen_toml_filename(blueprint), "w").write(blueprint_toml) + + return 0
+ +
[docs]def blueprints_tag(socket_path, api_version, args, show_json=False): + """Tag the most recent blueprint commit as a release + + :param socket_path: Path to the Unix socket to use for API communication + :type socket_path: str + :param api_version: Version of the API to talk to. eg. "0" + :type api_version: str + :param args: List of remaining arguments from the cmdline + :type args: list of str + :param show_json: Set to True to show the JSON output instead of the human readable output + :type show_json: bool + + blueprints tag <blueprint> Tag the most recent blueprint commit as a release. + """ + api_route = client.api_url(api_version, "/blueprints/tag/%s" % args[0]) + result = client.post_url(socket_path, api_route, "") + + return handle_api_result(result, show_json)[0]
+ +
[docs]def blueprints_undo(socket_path, api_version, args, show_json=False): + """Undo changes to a blueprint + + :param socket_path: Path to the Unix socket to use for API communication + :type socket_path: str + :param api_version: Version of the API to talk to. eg. "0" + :type api_version: str + :param args: List of remaining arguments from the cmdline + :type args: list of str + :param show_json: Set to True to show the JSON output instead of the human readable output + :type show_json: bool + + blueprints undo <blueprint> <commit> Undo changes to a blueprint by reverting to the selected commit. + """ + if len(args) == 0: + log.error("undo is missing the blueprint name and commit hash") + return 1 + elif len(args) == 1: + log.error("undo is missing commit hash") + return 1 + + api_route = client.api_url(api_version, "/blueprints/undo/%s/%s" % (args[0], args[1])) + result = client.post_url(socket_path, api_route, "") + + return handle_api_result(result, show_json)[0]
+ +
[docs]def blueprints_workspace(socket_path, api_version, args, show_json=False): + """Push the blueprint TOML to the temporary workspace storage + + :param socket_path: Path to the Unix socket to use for API communication + :type socket_path: str + :param api_version: Version of the API to talk to. eg. "0" + :type api_version: str + :param args: List of remaining arguments from the cmdline + :type args: list of str + :param show_json: Set to True to show the JSON output instead of the human readable output + :type show_json: bool + + blueprints workspace <blueprint> Push the blueprint TOML to the temporary workspace storage. + """ + api_route = client.api_url(api_version, "/blueprints/workspace") + rval = 0 + for blueprint in argify(args): + if not os.path.exists(blueprint): + log.error("Missing blueprint file: %s", blueprint) + continue + blueprint_toml = open(blueprint, "r").read() + + result = client.post_url_toml(socket_path, api_route, blueprint_toml) + if handle_api_result(result, show_json)[0]: + rval = 1 + + return rval
+
+ +
+ +
+ + +
+
+ +
+ +
+ + + + + + + + + + + + \ No newline at end of file diff --git a/fedora-31/_modules/composer/cli/cmdline.html b/fedora-31/_modules/composer/cli/cmdline.html new file mode 100644 index 00000000..4c6e2968 --- /dev/null +++ b/fedora-31/_modules/composer/cli/cmdline.html @@ -0,0 +1,250 @@ + + + + + + + + + + + composer.cli.cmdline — Lorax 31.10 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +
+ + + + + +
+ +
+ + + + + + + + + + + + + + + + + +
+ + + + +
+
+
+
+ +

Source code for composer.cli.cmdline

+#
+# 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 composer import vernum
+from composer.cli.help import epilog
+
+VERSION = "{0}-{1}".format(os.path.basename(sys.argv[0]), vernum)
+
+
[docs]def composer_cli_parser(): + """ Return the ArgumentParser for composer-cli""" + + parser = argparse.ArgumentParser(description="Lorax Composer commandline tool", + epilog=epilog, + formatter_class=argparse.RawDescriptionHelpFormatter, + fromfile_prefix_chars="@") + + parser.add_argument("-j", "--json", action="store_true", default=False, + help="Output the raw JSON response instead of the normal output.") + parser.add_argument("-s", "--socket", default="/run/weldr/api.socket", metavar="SOCKET", + help="Path to the socket file to listen on") + parser.add_argument("--log", dest="logfile", default=None, metavar="LOG", + help="Path to logfile (./composer-cli.log)") + parser.add_argument("-a", "--api", dest="api_version", default="0", metavar="APIVER", + help="API Version to use") + parser.add_argument("--test", dest="testmode", default=0, type=int, metavar="TESTMODE", + help="Pass test mode to compose. 1=Mock compose with fail. 2=Mock compose with finished.") + parser.add_argument("-V", action="store_true", dest="showver", + help="show program's version number and exit") + + # Commands are implemented by parsing the remaining arguments outside of argparse + parser.add_argument('args', nargs=argparse.REMAINDER) + + return parser
+
+ +
+ +
+ + +
+
+ +
+ +
+ + + + + + + + + + + + \ No newline at end of file diff --git a/fedora-31/_modules/composer/cli/compose.html b/fedora-31/_modules/composer/cli/compose.html new file mode 100644 index 00000000..dafcb060 --- /dev/null +++ b/fedora-31/_modules/composer/cli/compose.html @@ -0,0 +1,714 @@ + + + + + + + + + + + composer.cli.compose — Lorax 31.10 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +
+ + + + + +
+ +
+ + + + + + + + + + + + + + + + + +
+ + + + +
+
+
+
+ +

Source code for composer.cli.compose

+#
+# 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 logging
+log = logging.getLogger("composer-cli")
+
+from datetime import datetime
+import sys
+import json
+
+from composer import http_client as client
+from composer.cli.help import compose_help
+from composer.cli.utilities import argify, handle_api_result, packageNEVRA
+
+
[docs]def compose_cmd(opts): + """Process compose commands + + :param opts: Cmdline arguments + :type opts: argparse.Namespace + :returns: Value to return from sys.exit() + :rtype: int + + This dispatches the compose commands to a function + """ + cmd_map = { + "list": compose_list, + "status": compose_status, + "types": compose_types, + "start": compose_start, + "log": compose_log, + "cancel": compose_cancel, + "delete": compose_delete, + "info": compose_info, + "metadata": compose_metadata, + "results": compose_results, + "logs": compose_logs, + "image": compose_image, + } + if opts.args[1] == "help" or opts.args[1] == "--help": + print(compose_help) + return 0 + elif opts.args[1] not in cmd_map: + log.error("Unknown compose command: %s", opts.args[1]) + return 1 + + return cmd_map[opts.args[1]](opts.socket, opts.api_version, opts.args[2:], opts.json, opts.testmode)
+ +
[docs]def compose_list(socket_path, api_version, args, show_json=False, testmode=0): + """Return a simple list of compose identifiers""" + + states = ("running", "waiting", "finished", "failed") + + which = set() + + if any(a not in states for a in args): + # TODO: error about unknown state + return 1 + elif not args: + which.update(states) + else: + which.update(args) + + results = [] + + if "running" in which or "waiting" in which: + api_route = client.api_url(api_version, "/compose/queue") + r = client.get_url_json(socket_path, api_route) + if "running" in which: + results += r["run"] + if "waiting" in which: + results += r["new"] + + if "finished" in which: + api_route = client.api_url(api_version, "/compose/finished") + r = client.get_url_json(socket_path, api_route) + results += r["finished"] + + if "failed" in which: + api_route = client.api_url(api_version, "/compose/failed") + r = client.get_url_json(socket_path, api_route) + results += r["failed"] + + if results: + if show_json: + print(json.dumps(results, indent=4)) + else: + list_fmt = "{id} {queue_status} {blueprint} {version} {compose_type}" + print("\n".join(list_fmt.format(**c) for c in results)) + + return 0
+ +
[docs]def compose_status(socket_path, api_version, args, show_json=False, testmode=0): + """Return the status of all known composes + + :param socket_path: Path to the Unix socket to use for API communication + :type socket_path: str + :param api_version: Version of the API to talk to. eg. "0" + :type api_version: str + :param args: List of remaining arguments from the cmdline + :type args: list of str + :param show_json: Set to True to show the JSON output instead of the human readable output + :type show_json: bool + :param testmode: unused in this function + :type testmode: int + + This doesn't map directly to an API command, it combines the results from queue, finished, + and failed so raw JSON output is not available. + """ + def get_status(compose): + return {"id": compose["id"], + "blueprint": compose["blueprint"], + "version": compose["version"], + "compose_type": compose["compose_type"], + "image_size": compose["image_size"], + "status": compose["queue_status"], + "created": compose.get("job_created"), + "started": compose.get("job_started"), + "finished": compose.get("job_finished")} + + # Sort the status in a specific order + def sort_status(a): + order = ["RUNNING", "WAITING", "FINISHED", "FAILED"] + return (order.index(a["status"]), a["blueprint"], a["version"], a["compose_type"]) + + status = [] + + # Get the composes currently in the queue + api_route = client.api_url(api_version, "/compose/queue") + result = client.get_url_json(socket_path, api_route) + status.extend(list(map(get_status, result["run"] + result["new"]))) + + # Get the list of finished composes + api_route = client.api_url(api_version, "/compose/finished") + result = client.get_url_json(socket_path, api_route) + status.extend(list(map(get_status, result["finished"]))) + + # Get the list of failed composes + api_route = client.api_url(api_version, "/compose/failed") + result = client.get_url_json(socket_path, api_route) + status.extend(list(map(get_status, result["failed"]))) + + # Sort them by status (running, waiting, finished, failed) and then by name and version. + status.sort(key=sort_status) + + if show_json: + print(json.dumps(status, indent=4)) + return 0 + + # Print them as UUID blueprint STATUS + for c in status: + if c["image_size"] > 0: + image_size = str(c["image_size"]) + else: + image_size = "" + + dt = datetime.fromtimestamp(c.get("finished") or c.get("started") or c.get("created")) + + print("%s %-8s %s %-15s %s %-16s %s" % (c["id"], c["status"], dt.strftime("%c"), c["blueprint"], + c["version"], c["compose_type"], image_size))
+ + +
[docs]def compose_types(socket_path, api_version, args, show_json=False, testmode=0): + """Return information about the supported compose types + + :param socket_path: Path to the Unix socket to use for API communication + :type socket_path: str + :param api_version: Version of the API to talk to. eg. "0" + :type api_version: str + :param args: List of remaining arguments from the cmdline + :type args: list of str + :param show_json: Set to True to show the JSON output instead of the human readable output + :type show_json: bool + :param testmode: unused in this function + :type testmode: int + + Add additional details to types that are known to composer-cli. Raw JSON output does not + include this extra information. + """ + api_route = client.api_url(api_version, "/compose/types") + result = client.get_url_json(socket_path, api_route) + if show_json: + print(json.dumps(result, indent=4)) + return 0 + + # output a plain list of identifiers, one per line + print("\n".join(t["name"] for t in result["types"]))
+ +
[docs]def compose_start(socket_path, api_version, args, show_json=False, testmode=0): + """Start a new compose using the selected blueprint and type + + :param socket_path: Path to the Unix socket to use for API communication + :type socket_path: str + :param api_version: Version of the API to talk to. eg. "0" + :type api_version: str + :param args: List of remaining arguments from the cmdline + :type args: list of str + :param show_json: Set to True to show the JSON output instead of the human readable output + :type show_json: bool + :param testmode: Set to 1 to simulate a failed compose, set to 2 to simulate a finished one. + :type testmode: int + + compose start <blueprint-name> <compose-type> + """ + if len(args) == 0: + log.error("start is missing the blueprint name and output type") + return 1 + if len(args) == 1: + log.error("start is missing the output type") + return 1 + + config = { + "blueprint_name": args[0], + "compose_type": args[1], + "branch": "master" + } + if testmode: + test_url = "?test=%d" % testmode + else: + test_url = "" + api_route = client.api_url(api_version, "/compose" + test_url) + result = client.post_url_json(socket_path, api_route, json.dumps(config)) + (rc, exit_now) = handle_api_result(result, show_json) + if exit_now: + return rc + + print("Compose %s added to the queue" % result["build_id"]) + return rc
+ +
[docs]def compose_log(socket_path, api_version, args, show_json=False, testmode=0): + """Show the last part of the compose log + + :param socket_path: Path to the Unix socket to use for API communication + :type socket_path: str + :param api_version: Version of the API to talk to. eg. "0" + :type api_version: str + :param args: List of remaining arguments from the cmdline + :type args: list of str + :param show_json: Set to True to show the JSON output instead of the human readable output + :type show_json: bool + :param testmode: unused in this function + :type testmode: int + + compose log <uuid> [<size>kB] + + This will display the last 1kB of the compose's log file. Can be used to follow progress + during the build. + """ + if len(args) == 0: + log.error("log is missing the compose build id") + return 1 + if len(args) == 2: + try: + log_size = int(args[1]) + except ValueError: + log.error("Log size must be an integer.") + return 1 + else: + log_size = 1024 + + api_route = client.api_url(api_version, "/compose/log/%s?size=%d" % (args[0], log_size)) + try: + result = client.get_url_raw(socket_path, api_route) + except RuntimeError as e: + print(str(e)) + return 1 + + print(result) + return 0
+ +
[docs]def compose_cancel(socket_path, api_version, args, show_json=False, testmode=0): + """Cancel a running compose + + :param socket_path: Path to the Unix socket to use for API communication + :type socket_path: str + :param api_version: Version of the API to talk to. eg. "0" + :type api_version: str + :param args: List of remaining arguments from the cmdline + :type args: list of str + :param show_json: Set to True to show the JSON output instead of the human readable output + :type show_json: bool + :param testmode: unused in this function + :type testmode: int + + compose cancel <uuid> + + This will cancel a running compose. It does nothing if the compose has finished. + """ + if len(args) == 0: + log.error("cancel is missing the compose build id") + return 1 + + api_route = client.api_url(api_version, "/compose/cancel/%s" % args[0]) + result = client.delete_url_json(socket_path, api_route) + return handle_api_result(result, show_json)[0]
+ +
[docs]def compose_delete(socket_path, api_version, args, show_json=False, testmode=0): + """Delete a finished compose's results + + :param socket_path: Path to the Unix socket to use for API communication + :type socket_path: str + :param api_version: Version of the API to talk to. eg. "0" + :type api_version: str + :param args: List of remaining arguments from the cmdline + :type args: list of str + :param show_json: Set to True to show the JSON output instead of the human readable output + :type show_json: bool + :param testmode: unused in this function + :type testmode: int + + compose delete <uuid,...> + + Delete the listed compose results. It will only delete results for composes that have finished + or failed, not a running compose. + """ + if len(args) == 0: + log.error("delete is missing the compose build id") + return 1 + + api_route = client.api_url(api_version, "/compose/delete/%s" % (",".join(argify(args)))) + result = client.delete_url_json(socket_path, api_route) + return handle_api_result(result, show_json)[0]
+ +
[docs]def compose_info(socket_path, api_version, args, show_json=False, testmode=0): + """Return detailed information about the compose + + :param socket_path: Path to the Unix socket to use for API communication + :type socket_path: str + :param api_version: Version of the API to talk to. eg. "0" + :type api_version: str + :param args: List of remaining arguments from the cmdline + :type args: list of str + :param show_json: Set to True to show the JSON output instead of the human readable output + :type show_json: bool + :param testmode: unused in this function + :type testmode: int + + compose info <uuid> + + This returns information about the compose, including the blueprint and the dependencies. + """ + if len(args) == 0: + log.error("info is missing the compose build id") + return 1 + + api_route = client.api_url(api_version, "/compose/info/%s" % args[0]) + result = client.get_url_json(socket_path, api_route) + (rc, exit_now) = handle_api_result(result, show_json) + if exit_now: + return rc + + if result["image_size"] > 0: + image_size = str(result["image_size"]) + else: + image_size = "" + + + print("%s %-8s %-15s %s %-16s %s" % (result["id"], + result["queue_status"], + result["blueprint"]["name"], + result["blueprint"]["version"], + result["compose_type"], + image_size)) + print("Packages:") + for p in result["blueprint"]["packages"]: + print(" %s-%s" % (p["name"], p["version"])) + + print("Modules:") + for m in result["blueprint"]["modules"]: + print(" %s-%s" % (m["name"], m["version"])) + + print("Dependencies:") + for d in result["deps"]["packages"]: + print(" " + packageNEVRA(d)) + + return rc
+ +
[docs]def compose_metadata(socket_path, api_version, args, show_json=False, testmode=0): + """Download a tar file of the compose's metadata + + :param socket_path: Path to the Unix socket to use for API communication + :type socket_path: str + :param api_version: Version of the API to talk to. eg. "0" + :type api_version: str + :param args: List of remaining arguments from the cmdline + :type args: list of str + :param show_json: Set to True to show the JSON output instead of the human readable output + :type show_json: bool + :param testmode: unused in this function + :type testmode: int + + compose metadata <uuid> + + Saves the metadata as uuid-metadata.tar + """ + if len(args) == 0: + log.error("metadata is missing the compose build id") + return 1 + + api_route = client.api_url(api_version, "/compose/metadata/%s" % args[0]) + try: + rc = client.download_file(socket_path, api_route) + except RuntimeError as e: + print(str(e)) + rc = 1 + + return rc
+ +
[docs]def compose_results(socket_path, api_version, args, show_json=False, testmode=0): + """Download a tar file of the compose's results + + :param socket_path: Path to the Unix socket to use for API communication + :type socket_path: str + :param api_version: Version of the API to talk to. eg. "0" + :type api_version: str + :param args: List of remaining arguments from the cmdline + :type args: list of str + :param show_json: Set to True to show the JSON output instead of the human readable output + :type show_json: bool + :param testmode: unused in this function + :type testmode: int + + compose results <uuid> + + The results includes the metadata, output image, and logs. + It is saved as uuid.tar + """ + if len(args) == 0: + log.error("results is missing the compose build id") + return 1 + + api_route = client.api_url(api_version, "/compose/results/%s" % args[0]) + try: + rc = client.download_file(socket_path, api_route, sys.stdout.isatty()) + except RuntimeError as e: + print(str(e)) + rc = 1 + + return rc
+ +
[docs]def compose_logs(socket_path, api_version, args, show_json=False, testmode=0): + """Download a tar of the compose's logs + + :param socket_path: Path to the Unix socket to use for API communication + :type socket_path: str + :param api_version: Version of the API to talk to. eg. "0" + :type api_version: str + :param args: List of remaining arguments from the cmdline + :type args: list of str + :param show_json: Set to True to show the JSON output instead of the human readable output + :type show_json: bool + :param testmode: unused in this function + :type testmode: int + + compose logs <uuid> + + Saves the logs as uuid-logs.tar + """ + if len(args) == 0: + log.error("logs is missing the compose build id") + return 1 + + api_route = client.api_url(api_version, "/compose/logs/%s" % args[0]) + try: + rc = client.download_file(socket_path, api_route, sys.stdout.isatty()) + except RuntimeError as e: + print(str(e)) + rc = 1 + + return rc
+ +
[docs]def compose_image(socket_path, api_version, args, show_json=False, testmode=0): + """Download the compose's output image + + :param socket_path: Path to the Unix socket to use for API communication + :type socket_path: str + :param api_version: Version of the API to talk to. eg. "0" + :type api_version: str + :param args: List of remaining arguments from the cmdline + :type args: list of str + :param show_json: Set to True to show the JSON output instead of the human readable output + :type show_json: bool + :param testmode: unused in this function + :type testmode: int + + compose image <uuid> + + This downloads only the result image, saving it as the image name, which depends on the type + of compose that was selected. + """ + if len(args) == 0: + log.error("logs is missing the compose build id") + return 1 + + api_route = client.api_url(api_version, "/compose/image/%s" % args[0]) + try: + rc = client.download_file(socket_path, api_route, sys.stdout.isatty()) + except RuntimeError as e: + print(str(e)) + rc = 1 + + return rc
+
+ +
+ +
+ + +
+
+ +
+ +
+ + + + + + + + + + + + \ No newline at end of file diff --git a/fedora-31/_modules/composer/cli/modules.html b/fedora-31/_modules/composer/cli/modules.html new file mode 100644 index 00000000..de83bd7b --- /dev/null +++ b/fedora-31/_modules/composer/cli/modules.html @@ -0,0 +1,248 @@ + + + + + + + + + + + composer.cli.modules — Lorax 31.10 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +
+ + + + + +
+ +
+ + + + + + + + + + + + + + + + + +
+ + + + +
+
+
+
+ +

Source code for composer.cli.modules

+#
+# 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 logging
+log = logging.getLogger("composer-cli")
+
+from composer import http_client as client
+from composer.cli.help import modules_help
+from composer.cli.utilities import handle_api_result
+
+
[docs]def modules_cmd(opts): + """Process modules commands + + :param opts: Cmdline arguments + :type opts: argparse.Namespace + :returns: Value to return from sys.exit() + :rtype: int + """ + if opts.args[1] == "help" or opts.args[1] == "--help": + print(modules_help) + return 0 + elif opts.args[1] != "list": + log.error("Unknown modules command: %s", opts.args[1]) + return 1 + + api_route = client.api_url(opts.api_version, "/modules/list") + result = client.get_url_json_unlimited(opts.socket, api_route) + (rc, exit_now) = handle_api_result(result, opts.json) + if exit_now: + return rc + + # "list" should output a plain list of identifiers, one per line. + print("\n".join(r["name"] for r in result["modules"])) + + return rc
+
+ +
+ +
+ + +
+
+ +
+ +
+ + + + + + + + + + + + \ No newline at end of file diff --git a/fedora-31/_modules/composer/cli/projects.html b/fedora-31/_modules/composer/cli/projects.html new file mode 100644 index 00000000..5094381b --- /dev/null +++ b/fedora-31/_modules/composer/cli/projects.html @@ -0,0 +1,310 @@ + + + + + + + + + + + composer.cli.projects — Lorax 31.10 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +
+ + + + + +
+ +
+ + + + + + + + + + + + + + + + + +
+ + + + +
+
+
+
+ +

Source code for composer.cli.projects

+#
+# 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 logging
+log = logging.getLogger("composer-cli")
+
+import textwrap
+
+from composer import http_client as client
+from composer.cli.help import projects_help
+from composer.cli.utilities import handle_api_result
+
+
[docs]def projects_cmd(opts): + """Process projects commands + + :param opts: Cmdline arguments + :type opts: argparse.Namespace + :returns: Value to return from sys.exit() + :rtype: int + """ + cmd_map = { + "list": projects_list, + "info": projects_info, + } + if opts.args[1] == "help" or opts.args[1] == "--help": + print(projects_help) + return 0 + elif opts.args[1] not in cmd_map: + log.error("Unknown projects command: %s", opts.args[1]) + return 1 + + return cmd_map[opts.args[1]](opts.socket, opts.api_version, opts.args[2:], opts.json)
+ +
[docs]def projects_list(socket_path, api_version, args, show_json=False): + """Output the list of available projects + + :param socket_path: Path to the Unix socket to use for API communication + :type socket_path: str + :param api_version: Version of the API to talk to. eg. "0" + :type api_version: str + :param args: List of remaining arguments from the cmdline + :type args: list of str + :param show_json: Set to True to show the JSON output instead of the human readable output + :type show_json: bool + + projects list + """ + api_route = client.api_url(api_version, "/projects/list") + result = client.get_url_json_unlimited(socket_path, api_route) + (rc, exit_now) = handle_api_result(result, show_json) + if exit_now: + return rc + + for proj in result["projects"]: + for k in [field for field in ("name", "summary", "homepage", "description") if proj[field]]: + print("%s: %s" % (k.title(), textwrap.fill(proj[k], subsequent_indent=" " * (len(k)+2)))) + print("\n\n") + + return rc
+ +
[docs]def projects_info(socket_path, api_version, args, show_json=False): + """Output info on a list of projects + + :param socket_path: Path to the Unix socket to use for API communication + :type socket_path: str + :param api_version: Version of the API to talk to. eg. "0" + :type api_version: str + :param args: List of remaining arguments from the cmdline + :type args: list of str + :param show_json: Set to True to show the JSON output instead of the human readable output + :type show_json: bool + + projects info <project,...> + """ + if len(args) == 0: + log.error("projects info is missing the packages") + return 1 + + api_route = client.api_url(api_version, "/projects/info/%s" % ",".join(args)) + result = client.get_url_json(socket_path, api_route) + (rc, exit_now) = handle_api_result(result, show_json) + if exit_now: + return rc + + for proj in result["projects"]: + for k in [field for field in ("name", "summary", "homepage", "description") if proj[field]]: + print("%s: %s" % (k.title(), textwrap.fill(proj[k], subsequent_indent=" " * (len(k)+2)))) + print("Builds: ") + for build in proj["builds"]: + print(" %s%s-%s.%s at %s for %s" % ("" if not build["epoch"] else str(build["epoch"]) + ":", + build["source"]["version"], + build["release"], + build["arch"], + build["build_time"], + build["changelog"])) + print("") + return rc
+
+ +
+ +
+ + +
+
+ +
+ +
+ + + + + + + + + + + + \ No newline at end of file diff --git a/fedora-31/_modules/composer/cli/sources.html b/fedora-31/_modules/composer/cli/sources.html new file mode 100644 index 00000000..7602dba0 --- /dev/null +++ b/fedora-31/_modules/composer/cli/sources.html @@ -0,0 +1,352 @@ + + + + + + + + + + + composer.cli.sources — Lorax 31.10 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +
+ + + + + +
+ +
+ + + + + + + + + + + + + + + + + +
+ + + + +
+
+
+
+ +

Source code for composer.cli.sources

+#
+# 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 logging
+log = logging.getLogger("composer-cli")
+
+import os
+
+from composer import http_client as client
+from composer.cli.help import sources_help
+from composer.cli.utilities import argify, handle_api_result
+
+
[docs]def sources_cmd(opts): + """Process sources commands + + :param opts: Cmdline arguments + :type opts: argparse.Namespace + :returns: Value to return from sys.exit() + :rtype: int + """ + cmd_map = { + "list": sources_list, + "info": sources_info, + "add": sources_add, + "change": sources_add, + "delete": sources_delete, + } + if opts.args[1] == "help" or opts.args[1] == "--help": + print(sources_help) + return 0 + elif opts.args[1] not in cmd_map: + log.error("Unknown sources command: %s", opts.args[1]) + return 1 + + return cmd_map[opts.args[1]](opts.socket, opts.api_version, opts.args[2:], opts.json)
+ +
[docs]def sources_list(socket_path, api_version, args, show_json=False): + """Output the list of available sources + + :param socket_path: Path to the Unix socket to use for API communication + :type socket_path: str + :param api_version: Version of the API to talk to. eg. "0" + :type api_version: str + :param args: List of remaining arguments from the cmdline + :type args: list of str + :param show_json: Set to True to show the JSON output instead of the human readable output + :type show_json: bool + + sources list + """ + api_route = client.api_url(api_version, "/projects/source/list") + result = client.get_url_json(socket_path, api_route) + (rc, exit_now) = handle_api_result(result, show_json) + if exit_now: + return rc + + # "list" should output a plain list of identifiers, one per line. + print("\n".join(result["sources"])) + return rc
+ +
[docs]def sources_info(socket_path, api_version, args, show_json=False): + """Output info on a list of projects + + :param socket_path: Path to the Unix socket to use for API communication + :type socket_path: str + :param api_version: Version of the API to talk to. eg. "0" + :type api_version: str + :param args: List of remaining arguments from the cmdline + :type args: list of str + :param show_json: Set to True to show the JSON output instead of the human readable output + :type show_json: bool + + sources info <source-name> + """ + if len(args) == 0: + log.error("sources info is missing the name of the source") + return 1 + + if show_json: + api_route = client.api_url(api_version, "/projects/source/info/%s" % ",".join(args)) + result = client.get_url_json(socket_path, api_route) + rc = handle_api_result(result, show_json)[0] + else: + api_route = client.api_url(api_version, "/projects/source/info/%s?format=toml" % ",".join(args)) + try: + result = client.get_url_raw(socket_path, api_route) + print(result) + rc = 0 + except RuntimeError as e: + print(str(e)) + rc = 1 + + return rc
+ +
[docs]def sources_add(socket_path, api_version, args, show_json=False): + """Add or change a source + + :param socket_path: Path to the Unix socket to use for API communication + :type socket_path: str + :param api_version: Version of the API to talk to. eg. "0" + :type api_version: str + :param args: List of remaining arguments from the cmdline + :type args: list of str + :param show_json: Set to True to show the JSON output instead of the human readable output + :type show_json: bool + + sources add <source.toml> + """ + api_route = client.api_url(api_version, "/projects/source/new") + rval = 0 + for source in argify(args): + if not os.path.exists(source): + log.error("Missing source file: %s", source) + continue + source_toml = open(source, "r").read() + + result = client.post_url_toml(socket_path, api_route, source_toml) + if handle_api_result(result, show_json)[0]: + rval = 1 + return rval
+ +
[docs]def sources_delete(socket_path, api_version, args, show_json=False): + """Delete a source + + :param socket_path: Path to the Unix socket to use for API communication + :type socket_path: str + :param api_version: Version of the API to talk to. eg. "0" + :type api_version: str + :param args: List of remaining arguments from the cmdline + :type args: list of str + :param show_json: Set to True to show the JSON output instead of the human readable output + :type show_json: bool + + sources delete <source-name> + """ + api_route = client.api_url(api_version, "/projects/source/delete/%s" % args[0]) + result = client.delete_url_json(socket_path, api_route) + + return handle_api_result(result, show_json)[0]
+
+ +
+ +
+ + +
+
+ +
+ +
+ + + + + + + + + + + + \ No newline at end of file diff --git a/fedora-31/_modules/composer/cli/status.html b/fedora-31/_modules/composer/cli/status.html new file mode 100644 index 00000000..121ca1f1 --- /dev/null +++ b/fedora-31/_modules/composer/cli/status.html @@ -0,0 +1,256 @@ + + + + + + + + + + + composer.cli.status — Lorax 31.10 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +
+ + + + + +
+ +
+ + + + + + + + + + + + + + + + + +
+ + + + +
+
+
+
+ +

Source code for composer.cli.status

+#
+# 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 logging
+log = logging.getLogger("composer-cli")
+
+from composer import http_client as client
+from composer.cli.help import status_help
+from composer.cli.utilities import handle_api_result
+
+
[docs]def status_cmd(opts): + """Process status commands + + :param opts: Cmdline arguments + :type opts: argparse.Namespace + :returns: Value to return from sys.exit() + :rtype: int + """ + if opts.args[1] == "help" or opts.args[1] == "--help": + print(status_help) + return 0 + elif opts.args[1] != "show": + log.error("Unknown status command: %s", opts.args[1]) + return 1 + + result = client.get_url_json(opts.socket, "/api/status") + (rc, exit_now) = handle_api_result(result, opts.json) + if exit_now: + return rc + + print("API server status:") + print(" Database version: " + result["db_version"]) + print(" Database supported: %s" % result["db_supported"]) + print(" Schema version: " + result["schema_version"]) + print(" API version: " + result["api"]) + print(" Backend: " + result["backend"]) + print(" Build: " + result["build"]) + + if result["msgs"]: + print("Error messages:") + print("\n".join([" " + r for r in result["msgs"]])) + + return rc
+
+ +
+ +
+ + +
+
+ +
+ +
+ + + + + + + + + + + + \ No newline at end of file diff --git a/fedora-31/_modules/composer/cli/utilities.html b/fedora-31/_modules/composer/cli/utilities.html new file mode 100644 index 00000000..ea4eab2e --- /dev/null +++ b/fedora-31/_modules/composer/cli/utilities.html @@ -0,0 +1,295 @@ + + + + + + + + + + + composer.cli.utilities — Lorax 31.10 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +
+ + + + + +
+ +
+ + + + + + + + + + + + + + + + + +
+ + + + +
+
+
+
+ +

Source code for composer.cli.utilities

+#
+# 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 logging
+log = logging.getLogger("composer-cli")
+
+import json
+
+
[docs]def argify(args): + """Take a list of human args and return a list with each item + + :param args: list of strings with possible commas and spaces + :type args: list of str + :returns: List of all the items + :rtype: list of str + + Examples: + + ["one,two", "three", ",four", ",five,"] returns ["one", "two", "three", "four", "five"] + """ + return [i for i in [arg for entry in args for arg in entry.split(",")] if i]
+ +
[docs]def toml_filename(blueprint_name): + """Convert a blueprint name into a filename.toml + + :param blueprint_name: The blueprint's name + :type blueprint_name: str + :returns: The blueprint name with ' ' converted to - and .toml appended + :rtype: str + """ + return blueprint_name.replace(" ", "-") + ".toml"
+ +
[docs]def frozen_toml_filename(blueprint_name): + """Convert a blueprint name into a filename.toml + + :param blueprint_name: The blueprint's name + :type blueprint_name: str + :returns: The blueprint name with ' ' converted to - and .toml appended + :rtype: str + """ + return blueprint_name.replace(" ", "-") + ".frozen.toml"
+ +
[docs]def handle_api_result(result, show_json=False): + """Log any errors, return the correct value + + :param result: JSON result from the http query + :type result: dict + :rtype: tuple + :returns: (rc, should_exit_now) + + Return the correct rc for the program (0 or 1), and whether or + not to continue processing the results. + """ + if show_json: + print(json.dumps(result, indent=4)) + else: + for err in result.get("errors", []): + log.error(err["msg"]) + + # What's the rc? If status is present, use that + # If not, use length of errors + if "status" in result: + rc = bool(not result["status"]) + else: + rc = bool(len(result.get("errors", [])) > 0) + + # Caller should return if showing json, or status was present and False + exit_now = show_json or ("status" in result and rc) + return (rc, exit_now)
+ +
[docs]def packageNEVRA(pkg): + """Return the package info as a NEVRA + + :param pkg: The package details + :type pkg: dict + :returns: name-[epoch:]version-release-arch + :rtype: str + """ + if pkg["epoch"]: + return "%s-%s:%s-%s.%s" % (pkg["name"], pkg["epoch"], pkg["version"], pkg["release"], pkg["arch"]) + else: + return "%s-%s-%s.%s" % (pkg["name"], pkg["version"], pkg["release"], pkg["arch"])
+
+ +
+ +
+ + +
+
+ +
+ +
+ + + + + + + + + + + + \ No newline at end of file diff --git a/fedora-31/_modules/composer/http_client.html b/fedora-31/_modules/composer/http_client.html new file mode 100644 index 00000000..74ffc02d --- /dev/null +++ b/fedora-31/_modules/composer/http_client.html @@ -0,0 +1,458 @@ + + + + + + + + + + + composer.http_client — Lorax 31.10 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +
+ + + + + +
+ +
+ + + + + + + + + + + + + + + + + +
+ + + + +
+
+
+
+ +

Source code for composer.http_client

+#
+# 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 logging
+log = logging.getLogger("composer-cli")
+
+import os
+import sys
+import json
+from urllib.parse import urlparse, urlunparse
+
+from composer.unix_socket import UnixHTTPConnectionPool
+
+
[docs]def api_url(api_version, url): + """Return the versioned path to the API route + + :param api_version: The version of the API to talk to. eg. "0" + :type api_version: str + :param url: The API route to talk to + :type url: str + :returns: The full url to use for the route and API version + :rtype: str + """ + return os.path.normpath("/api/v%s/%s" % (api_version, url))
+ +
[docs]def append_query(url, query): + """Add a query argument to a URL + + The query should be of the form "param1=what&param2=ever", i.e., no + leading '?'. The new query data will be appended to any existing + query string. + + :param url: The original URL + :type url: str + :param query: The query to append + :type query: str + :returns: The new URL with the query argument included + :rtype: str + """ + + url_parts = urlparse(url) + if url_parts.query: + new_query = url_parts.query + "&" + query + else: + new_query = query + return urlunparse([url_parts[0], url_parts[1], url_parts[2], + url_parts[3], new_query, url_parts[5]])
+ +
[docs]def get_url_raw(socket_path, url): + """Return the raw results of a GET request + + :param socket_path: Path to the Unix socket to use for API communication + :type socket_path: str + :param url: URL to request + :type url: str + :returns: The raw response from the server + :rtype: str + """ + http = UnixHTTPConnectionPool(socket_path) + r = http.request("GET", url) + if r.status == 400: + err = json.loads(r.data.decode("utf-8")) + if "status" in err and err["status"] == False: + msgs = [e["msg"] for e in err["errors"]] + raise RuntimeError(", ".join(msgs)) + + return r.data.decode('utf-8')
+ +
[docs]def get_url_json(socket_path, url): + """Return the JSON results of a GET request + + :param socket_path: Path to the Unix socket to use for API communication + :type socket_path: str + :param url: URL to request + :type url: str + :returns: The json response from the server + :rtype: dict + """ + http = UnixHTTPConnectionPool(socket_path) + r = http.request("GET", url) + return json.loads(r.data.decode('utf-8'))
+ +
[docs]def get_url_json_unlimited(socket_path, url, total_fn=None): + """Return the JSON results of a GET request + + For URLs that use offset/limit arguments, this command will + fetch all results for the given request. + + :param socket_path: Path to the Unix socket to use for API communication + :type socket_path: str + :param url: URL to request + :type url: str + :returns: The json response from the server + :rtype: dict + """ + def default_total_fn(data): + """Return the total number of available results""" + return data["total"] + + http = UnixHTTPConnectionPool(socket_path) + + # Start with limit=0 to just get the number of objects + total_url = append_query(url, "limit=0") + r_total = http.request("GET", total_url) + json_total = json.loads(r_total.data.decode('utf-8')) + + # Where to get the total from + if not total_fn: + total_fn = default_total_fn + + # Add the "total" returned by limit=0 as the new limit + unlimited_url = append_query(url, "limit=%d" % total_fn(json_total)) + r_unlimited = http.request("GET", unlimited_url) + return json.loads(r_unlimited.data.decode('utf-8'))
+ +
[docs]def delete_url_json(socket_path, url): + """Send a DELETE request to the url and return JSON response + + :param socket_path: Path to the Unix socket to use for API communication + :type socket_path: str + :param url: URL to send DELETE to + :type url: str + :returns: The json response from the server + :rtype: dict + """ + http = UnixHTTPConnectionPool(socket_path) + r = http.request("DELETE", url) + return json.loads(r.data.decode("utf-8"))
+ +
[docs]def post_url(socket_path, url, body): + """POST raw data to the URL + + :param socket_path: Path to the Unix socket to use for API communication + :type socket_path: str + :param url: URL to send POST to + :type url: str + :param body: The data for the body of the POST + :type body: str + :returns: The json response from the server + :rtype: dict + """ + http = UnixHTTPConnectionPool(socket_path) + r = http.request("POST", url, + body=body.encode("utf-8")) + return json.loads(r.data.decode("utf-8"))
+ +
[docs]def post_url_toml(socket_path, url, body): + """POST a TOML string to the URL + + :param socket_path: Path to the Unix socket to use for API communication + :type socket_path: str + :param url: URL to send POST to + :type url: str + :param body: The data for the body of the POST + :type body: str + :returns: The json response from the server + :rtype: dict + """ + http = UnixHTTPConnectionPool(socket_path) + r = http.request("POST", url, + body=body.encode("utf-8"), + headers={"Content-Type": "text/x-toml"}) + return json.loads(r.data.decode("utf-8"))
+ +
[docs]def post_url_json(socket_path, url, body): + """POST some JSON data to the URL + + :param socket_path: Path to the Unix socket to use for API communication + :type socket_path: str + :param url: URL to send POST to + :type url: str + :param body: The data for the body of the POST + :type body: str + :returns: The json response from the server + :rtype: dict + """ + http = UnixHTTPConnectionPool(socket_path) + r = http.request("POST", url, + body=body.encode("utf-8"), + headers={"Content-Type": "application/json"}) + return json.loads(r.data.decode("utf-8"))
+ +
[docs]def get_filename(headers): + """Get the filename from the response header + + :param response: The urllib3 response object + :type response: Response + :raises: RuntimeError if it cannot find a filename in the header + :returns: Filename from content-disposition header + :rtype: str + """ + log.debug("Headers = %s", headers) + if "content-disposition" not in headers: + raise RuntimeError("No Content-Disposition header; cannot get filename") + + try: + k, _, v = headers["content-disposition"].split(";")[1].strip().partition("=") + if k != "filename": + raise RuntimeError("No filename= found in content-disposition header") + except RuntimeError: + raise + except Exception as e: + raise RuntimeError("Error parsing filename from content-disposition header: %s" % str(e)) + + return os.path.basename(v)
+ +
[docs]def download_file(socket_path, url, progress=True): + """Download a file, saving it to the CWD with the included filename + + :param socket_path: Path to the Unix socket to use for API communication + :type socket_path: str + :param url: URL to send POST to + :type url: str + """ + http = UnixHTTPConnectionPool(socket_path) + r = http.request("GET", url, preload_content=False) + if r.status == 400: + err = json.loads(r.data.decode("utf-8")) + if not err["status"]: + msgs = [e["msg"] for e in err["errors"]] + raise RuntimeError(", ".join(msgs)) + + filename = get_filename(r.headers) + if os.path.exists(filename): + msg = "%s exists, skipping download" % filename + log.error(msg) + raise RuntimeError(msg) + + with open(filename, "wb") as f: + while True: + data = r.read(10 * 1024**2) + if not data: + break + f.write(data) + + if progress: + data_written = f.tell() + if data_written > 5 * 1024**2: + sys.stdout.write("%s: %0.2f MB \r" % (filename, data_written / 1024**2)) + else: + sys.stdout.write("%s: %0.2f kB\r" % (filename, data_written / 1024)) + sys.stdout.flush() + + print("") + r.release_conn() + + return 0
+
+ +
+ +
+ + +
+
+ +
+ +
+ + + + + + + + + + + + \ No newline at end of file diff --git a/fedora-31/_modules/composer/unix_socket.html b/fedora-31/_modules/composer/unix_socket.html new file mode 100644 index 00000000..d6728862 --- /dev/null +++ b/fedora-31/_modules/composer/unix_socket.html @@ -0,0 +1,259 @@ + + + + + + + + + + + composer.unix_socket — Lorax 31.10 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +
+ + + + + +
+ +
+ + + + + + + + + + + + + + + + + +
+ + + + +
+
+
+
+ +

Source code for composer.unix_socket

+#
+# 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 http.client
+import socket
+import urllib3
+
+
+# These 2 classes were adapted and simplified for use with just urllib3.
+# Originally from https://github.com/msabramo/requests-unixsocket/blob/master/requests_unixsocket/adapters.py
+
+# The following was adapted from some code from docker-py
+# https://github.com/docker/docker-py/blob/master/docker/transport/unixconn.py
+
[docs]class UnixHTTPConnection(http.client.HTTPConnection, object): + + def __init__(self, socket_path, timeout=60): + """Create an HTTP connection to a unix domain socket + + :param socket_path: The path to the Unix domain socket + :param timeout: Number of seconds to timeout the connection + """ + super(UnixHTTPConnection, self).__init__('localhost', timeout=timeout) + self.socket_path = socket_path + self.sock = None + + def __del__(self): # base class does not have d'tor + if self.sock: + self.sock.close() + +
[docs] def connect(self): + sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) + sock.settimeout(self.timeout) + sock.connect(self.socket_path) + self.sock = sock
+ +
[docs]class UnixHTTPConnectionPool(urllib3.connectionpool.HTTPConnectionPool): + + def __init__(self, socket_path, timeout=60): + """Create a connection pool using a Unix domain socket + + :param socket_path: The path to the Unix domain socket + :param timeout: Number of seconds to timeout the connection + """ + super(UnixHTTPConnectionPool, self).__init__('localhost', timeout=timeout) + self.socket_path = socket_path + + def _new_conn(self): + return UnixHTTPConnection(self.socket_path, self.timeout)
+
+ +
+ +
+ + +
+
+ +
+ +
+ + + + + + + + + + + + \ No newline at end of file diff --git a/fedora-31/_modules/index.html b/fedora-31/_modules/index.html new file mode 100644 index 00000000..9ea3b573 --- /dev/null +++ b/fedora-31/_modules/index.html @@ -0,0 +1,243 @@ + + + + + + + + + + + Overview: module code — Lorax 31.10 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/fedora-31/_modules/pylorax.html b/fedora-31/_modules/pylorax.html new file mode 100644 index 00000000..b2ba6358 --- /dev/null +++ b/fedora-31/_modules/pylorax.html @@ -0,0 +1,650 @@ + + + + + + + + + + + pylorax — Lorax 31.10 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"]
+
+# Used for DNF conf.module_platform_id
+DEFAULT_PLATFORM_ID = "platform:f30"
+
+
[docs]class ArchData(DataHolder): + lib64_arches = ("x86_64", "ppc64le", "s390x", "ia64", "aarch64") + bcj_arch = dict(i386="x86", x86_64="x86", + 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, + squashfs_only=False): + + 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) + if squashfs_only: + # Create an ext4 rootfs.img and compress it with squashfs + rb.create_squashfs_runtime(joinpaths(installroot,runtime), + compression=compression, compressargs=compressargs, + size=size) + else: + # Create an ext4 rootfs.img and compress it with squashfs + rb.create_ext4_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"] + + 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) + fmt = logging.Formatter("%(asctime)s %(levelname)s: %(message)s") + fh.setFormatter(fmt) + 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")
+
+ +
+ +
+ + +
+
+ +
+ +
+ + + + + + + + + + + + \ No newline at end of file diff --git a/fedora-31/_modules/pylorax/api/bisect.html b/fedora-31/_modules/pylorax/api/bisect.html new file mode 100644 index 00000000..ffbe8b57 --- /dev/null +++ b/fedora-31/_modules/pylorax/api/bisect.html @@ -0,0 +1,249 @@ + + + + + + + + + + + pylorax.api.bisect — Lorax 31.10 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +
+ + + + + +
+ +
+ + + + + + + + + + + + + + + + + +
+ + + + +
+
+
+
+ +

Source code for pylorax.api.bisect

+#
+# 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/>.
+#
+
[docs]def insort_left(a, x, key=None, lo=0, hi=None): + """Insert item x in list a, and keep it sorted assuming a is sorted. + + :param a: sorted list + :type a: list + :param x: item to insert into the list + :type x: object + :param key: Function to use to compare items in the list + :type key: function + :returns: index where the item was inserted + :rtype: int + + If x is already in a, insert it to the left of the leftmost x. + Optional args lo (default 0) and hi (default len(a)) bound the + slice of a to be searched. + + This is a modified version of bisect.insort_left that can use a + function for the compare, and returns the index position where it + was inserted. + """ + if key is None: + key = lambda i: i + + if lo < 0: + raise ValueError('lo must be non-negative') + if hi is None: + hi = len(a) + while lo < hi: + mid = (lo+hi)//2 + if key(a[mid]) < key(x): lo = mid+1 + else: hi = mid + a.insert(lo, x) + return lo
+
+ +
+ +
+ + +
+
+ +
+ +
+ + + + + + + + + + + + \ No newline at end of file diff --git a/fedora-31/_modules/pylorax/api/checkparams.html b/fedora-31/_modules/pylorax/api/checkparams.html new file mode 100644 index 00000000..d3e3199a --- /dev/null +++ b/fedora-31/_modules/pylorax/api/checkparams.html @@ -0,0 +1,244 @@ + + + + + + + + + + + pylorax.api.checkparams — Lorax 31.10 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +
+ + + + + +
+ +
+ + + + + + + + + + + + + + + + + +
+ + + + +
+
+
+
+ +

Source code for pylorax.api.checkparams

+#
+# 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 logging
+log = logging.getLogger("lorax-composer")
+
+from flask import jsonify
+from functools import update_wrapper
+
+# A decorator for checking the parameters provided to the API route implementing
+# functions.  The tuples parameter is a list of tuples.  Each tuple is the string
+# name of a parameter ("blueprint_name", not blueprint_name), the value it's set
+# to by flask if the caller did not provide it, and a message to be returned to
+# the user.
+#
+# If the parameter is set to its default, the error message is returned.  Otherwise,
+# the decorated function is called and its return value is returned.
+
[docs]def checkparams(tuples): + def decorator(f): + def wrapped_function(*args, **kwargs): + for tup in tuples: + if kwargs[tup[0]] == tup[1]: + log.error("(%s) %s", f.__name__, tup[2]) + return jsonify(status=False, errors=[tup[2]]), 400 + + return f(*args, **kwargs) + + return update_wrapper(wrapped_function, f) + + return decorator
+
+ +
+ +
+ + +
+
+ +
+ +
+ + + + + + + + + + + + \ No newline at end of file diff --git a/fedora-31/_modules/pylorax/api/cmdline.html b/fedora-31/_modules/pylorax/api/cmdline.html new file mode 100644 index 00000000..e34934da --- /dev/null +++ b/fedora-31/_modules/pylorax/api/cmdline.html @@ -0,0 +1,263 @@ + + + + + + + + + + + pylorax.api.cmdline — Lorax 31.10 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
+
+ +
+ +
+ + +
+
+ +
+ +
+ + + + + + + + + + + + \ No newline at end of file diff --git a/fedora-31/_modules/pylorax/api/compose.html b/fedora-31/_modules/pylorax/api/compose.html new file mode 100644 index 00000000..ecfd87d1 --- /dev/null +++ b/fedora-31/_modules/pylorax/api/compose.html @@ -0,0 +1,1442 @@ + + + + + + + + + + + pylorax.api.compose — Lorax 31.10 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 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
+import pylorax.api.toml as toml
+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 in compose_types(share_dir): + # 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 + if compose_type not in compose_types(share_dir): + raise RuntimeError("Invalid compose type (%s), must be one of %s" % (compose_type, compose_types(share_dir))) + + # 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 the supported output types + + The output types come from the kickstart names in /usr/share/lorax/composer/\*ks + """ + return sorted([os.path.basename(ks)[:-3] for ks in glob(joinpaths(share_dir, "composer/*.ks"))])
+ +
[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, + "squashfs_only": False, + }, + "liveimg-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, + "squashfs_only": False, + }, + "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", + "squashfs_only": False, + }, + "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, + "squashfs_only": False, + }, + "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, + "squashfs_only": False, + }, + "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, + "squashfs_only": False, + }, + "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, + "squashfs_only": False, + }, + "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, + "squashfs_only": False, + }, + "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, + "squashfs_only": False, + }, + "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, + "squashfs_only": False, + }, + "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, + "squashfs_only": False, + }, + "hyper-v": {"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": "vhdx", + "qemu_args": [], + "image_name": "disk.vhdx", + "tar_disk_name": None, + "fs_label": "", + "image_only": True, + "app_name": None, + "app_template": None, + "app_file": None, + "squashfs_only": False, + }, + "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, + "squashfs_only": False, + }, + } + 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")
+
+ +
+ +
+ + +
+
+ +
+ +
+ + + + + + + + + + + + \ No newline at end of file diff --git a/fedora-31/_modules/pylorax/api/config.html b/fedora-31/_modules/pylorax/api/config.html new file mode 100644 index 00000000..1afabc65 --- /dev/null +++ b/fedora-31/_modules/pylorax/api/config.html @@ -0,0 +1,338 @@ + + + + + + + + + + + pylorax.api.config — Lorax 31.10 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
+import pwd
+
+from pylorax.sysutils import joinpaths
+
+
[docs]class ComposerConfig(configparser.ConfigParser): +
[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_owned_dir(p_dir, uid, gid): + """Make a directory and its parents, setting owner and group + + :param p_dir: path to directory to create + :type p_dir: string + :param uid: uid of owner + :type uid: int + :param gid: gid of owner + :type gid: int + :returns: list of errors + :rtype: list of str + + Check to make sure it does not have o+rw permissions and that it is owned by uid:gid + """ + errors = [] + if not os.path.isdir(p_dir): + # Make sure no o+rw permissions are set + orig_umask = os.umask(0o006) + os.makedirs(p_dir, 0o771) + os.chown(p_dir, uid, 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 + u_name = pwd.getpwuid(uid) + errors.append("%s should be owned by %s:%s" % (p_dir, u_name, gr_name)) + + return errors
+ +
[docs]def make_dnf_dirs(conf, uid, gid): + """Make any missing dnf directories owned by user:group + + :param conf: The configuration to use + :type conf: ComposerConfig + :param uid: uid of owner + :type uid: int + :param gid: gid of owner + :type gid: int + :returns: list of errors + :rtype: list of str + """ + errors = [] + 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) + errors.extend(make_owned_dir(p_dir, uid, gid))
+ +
[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) + errors.extend(make_owned_dir(p_dir, 0, gid)) + return errors
+
+ +
+ +
+ + +
+
+ +
+ +
+ + + + + + + + + + + + \ No newline at end of file diff --git a/fedora-31/_modules/pylorax/api/crossdomain.html b/fedora-31/_modules/pylorax/api/crossdomain.html new file mode 100644 index 00000000..d8f653fe --- /dev/null +++ b/fedora-31/_modules/pylorax/api/crossdomain.html @@ -0,0 +1,264 @@ + + + + + + + + + + + pylorax.api.crossdomain — Lorax 31.7 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
+
+ +
+ +
+ + +
+
+ +
+ +
+ + + + + + + + + + + + \ No newline at end of file diff --git a/fedora-31/_modules/pylorax/api/dnfbase.html b/fedora-31/_modules/pylorax/api/dnfbase.html new file mode 100644 index 00000000..b046b7e2 --- /dev/null +++ b/fedora-31/_modules/pylorax/api/dnfbase.html @@ -0,0 +1,386 @@ + + + + + + + + + + + pylorax.api.dnfbase — Lorax 31.10 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +
+ + + + + +
+ +
+ + + + + + + + + + + + + + + + + +
+ + + + +
+
+
+
+ +

Source code for pylorax.api.dnfbase

+#
+# 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/>.
+#
+# pylint: disable=bad-preconf-access
+
+import logging
+log = logging.getLogger("lorax-composer")
+
+import dnf
+import dnf.logging
+from glob import glob
+import os
+import shutil
+from threading import Lock
+import time
+
+from pylorax import DEFAULT_PLATFORM_ID
+from pylorax.sysutils import flatconfig
+
+
[docs]class DNFLock(object): + """Hold the dnf.Base object and a Lock to control access to it. + + self.dbo is a property that returns the dnf.Base object, but it *may* change + from one call to the next if the upstream repositories have changed. + """ + def __init__(self, conf, expire_secs=6*60*60): + self._conf = conf + self._lock = Lock() + self.dbo = get_base_object(self._conf) + self._expire_secs = expire_secs + self._expire_time = time.time() + self._expire_secs + + @property + def lock(self): + """Check for repo updates (using expiration time) and return the lock + + If the repository has been updated, tear down the old dnf.Base and + create a new one. This is the only way to force dnf to use the new + metadata. + """ + if time.time() > self._expire_time: + return self.lock_check + return self._lock + + @property + def lock_check(self): + """Force a check for repo updates and return the lock + + Use this method sparingly, it removes the repodata and downloads a new copy every time. + """ + self._expire_time = time.time() + self._expire_secs + self.dbo.update_cache() + return self._lock
+ +
[docs]def get_base_object(conf): + """Get the DNF object with settings from the config file + + :param conf: configuration object + :type conf: ComposerParser + :returns: A DNF Base object + :rtype: dnf.Base + """ + cachedir = os.path.abspath(conf.get("composer", "cache_dir")) + dnfconf = os.path.abspath(conf.get("composer", "dnf_conf")) + dnfroot = os.path.abspath(conf.get("composer", "dnf_root")) + repodir = os.path.abspath(conf.get("composer", "repo_dir")) + + # Setup the config for the DNF Base object + dbo = dnf.Base() + dbc = dbo.conf +# TODO - Handle this +# dbc.logdir = logdir + dbc.installroot = dnfroot + if not os.path.isdir(dnfroot): + os.makedirs(dnfroot) + if not os.path.isdir(repodir): + os.makedirs(repodir) + + dbc.cachedir = cachedir + dbc.reposdir = [repodir] + dbc.install_weak_deps = False + dbc.prepend_installroot('persistdir') + # this is a weird 'AppendOption' thing that, when you set it, + # actually appends. Doing this adds 'nodocs' to the existing list + # of values, over in libdnf, it does not replace the existing values. + dbc.tsflags = ['nodocs'] + + if conf.get_default("dnf", "proxy", None): + dbc.proxy = conf.get("dnf", "proxy") + + if conf.has_option("dnf", "sslverify") and not conf.getboolean("dnf", "sslverify"): + dbc.sslverify = False + + # If the system repos are enabled read the dnf vars from /etc/dnf/vars/ + if not conf.has_option("repos", "use_system_repos") or conf.getboolean("repos", "use_system_repos"): + dbc.substitutions.update_from_etc("/") + log.info("dnf vars: %s", dbc.substitutions) + + _releasever = conf.get_default("composer", "releasever", None) + if not _releasever: + # Use the releasever of the host system + _releasever = dnf.rpm.detect_releasever("/") + log.info("releasever = %s", _releasever) + dbc.releasever = _releasever + + # DNF 3.2 needs to have module_platform_id set, otherwise depsolve won't work correctly + if not os.path.exists("/etc/os-release"): + log.warning("/etc/os-release is missing, cannot determine platform id, falling back to %s", DEFAULT_PLATFORM_ID) + platform_id = DEFAULT_PLATFORM_ID + else: + os_release = flatconfig("/etc/os-release") + platform_id = os_release.get("PLATFORM_ID", DEFAULT_PLATFORM_ID) + log.info("Using %s for module_platform_id", platform_id) + dbc.module_platform_id = platform_id + + # Make sure metadata is always current + dbc.metadata_expire = 0 + dbc.metadata_expire_filter = "never" + + # write the dnf configuration file + with open(dnfconf, "w") as f: + f.write(dbc.dump()) + + # dnf needs the repos all in one directory, composer uses repodir for this + # if system repos are supposed to be used, copy them into repodir, overwriting any previous copies + if not conf.has_option("repos", "use_system_repos") or conf.getboolean("repos", "use_system_repos"): + for repo_file in glob("/etc/yum.repos.d/*.repo"): + shutil.copy2(repo_file, repodir) + dbo.read_all_repos() + + # Remove any duplicate repo entries. These can cause problems with Anaconda, which will fail + # with space problems. + repos = sorted(list(r.id for r in dbo.repos.iter_enabled())) + seen = {"baseurl": [], "mirrorlist": [], "metalink": []} + for source_name in repos: + remove = False + repo = dbo.repos.get(source_name, None) + if repo is None: + log.warning("repo %s vanished while removing duplicates", source_name) + continue + if repo.baseurl: + if repo.baseurl[0] in seen["baseurl"]: + log.info("Removing duplicate repo: %s baseurl=%s", source_name, repo.baseurl[0]) + remove = True + else: + seen["baseurl"].append(repo.baseurl[0]) + elif repo.mirrorlist: + if repo.mirrorlist in seen["mirrorlist"]: + log.info("Removing duplicate repo: %s mirrorlist=%s", source_name, repo.mirrorlist) + remove = True + else: + seen["mirrorlist"].append(repo.mirrorlist) + elif repo.metalink: + if repo.metalink in seen["metalink"]: + log.info("Removing duplicate repo: %s metalink=%s", source_name, repo.metalink) + remove = True + else: + seen["metalink"].append(repo.metalink) + + if remove: + del dbo.repos[source_name] + + # Update the metadata from the enabled repos to speed up later operations + log.info("Updating repository metadata") + try: + dbo.fill_sack(load_system_repo=False) + dbo.read_comps() + dbo.update_cache() + except dnf.exceptions.Error as e: + log.error("Failed to update metadata: %s", str(e)) + raise RuntimeError("Fetching metadata failed: %s" % str(e)) + + return dbo
+
+ +
+ +
+ + +
+
+ +
+ +
+ + + + + + + + + + + + \ No newline at end of file diff --git a/fedora-31/_modules/pylorax/api/flask_blueprint.html b/fedora-31/_modules/pylorax/api/flask_blueprint.html new file mode 100644 index 00000000..34453b42 --- /dev/null +++ b/fedora-31/_modules/pylorax/api/flask_blueprint.html @@ -0,0 +1,254 @@ + + + + + + + + + + + pylorax.api.flask_blueprint — Lorax 31.10 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +
+ + + + + +
+ +
+ + + + + + + + + + + + + + + + + +
+ + + + +
+
+
+
+ +

Source code for pylorax.api.flask_blueprint

+#
+# Copyright (C) 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/>.
+#
+""" Flask Blueprints that support skipping routes
+
+When using Blueprints for API versioning you will usually want to fall back
+to the previous version's rules for routes that have no new behavior. To do
+this we add a 'skip_rule' list to the Blueprint's options dictionary. It lists
+all of the routes that you do not want to register.
+
+For example:
+    from pylorax.api.v0 import v0
+    from pylorax.api.v1 import v1
+
+    server.register_blueprint(v0, url_prefix="/api/v0/")
+    server.register_blueprint(v0, url_prefix="/api/v1/", skip_rules=["/blueprints/list"]
+    server.register_blueprint(v1, url_prefix="/api/v1/")
+
+This will register all of v0's routes under `/api/v0`, and all but `/blueprints/list` under /api/v1,
+and then register v1's version of `/blueprints/list` under `/api/v1`
+
+"""
+from flask import Blueprint
+from flask.blueprints import BlueprintSetupState
+
+
[docs]class BlueprintSetupStateSkip(BlueprintSetupState): + def __init__(self, blueprint, app, options, first_registration, skip_rules): + self._skip_rules = skip_rules + super(BlueprintSetupStateSkip, self).__init__(blueprint, app, options, first_registration) + +
[docs] def add_url_rule(self, rule, endpoint=None, view_func=None, **options): + if rule not in self._skip_rules: + super(BlueprintSetupStateSkip, self).add_url_rule(rule, endpoint, view_func, **options)
+ +
[docs]class BlueprintSkip(Blueprint): + def __init__(self, *args, **kwargs): + super(BlueprintSkip, self).__init__(*args, **kwargs) + +
[docs] def make_setup_state(self, app, options, first_registration=False): + skip_rules = options.pop("skip_rules", []) + return BlueprintSetupStateSkip(self, app, options, first_registration, skip_rules)
+
+ +
+ +
+ + +
+
+ +
+ +
+ + + + + + + + + + + + \ No newline at end of file diff --git a/fedora-31/_modules/pylorax/api/gitrpm.html b/fedora-31/_modules/pylorax/api/gitrpm.html new file mode 100644 index 00000000..20050568 --- /dev/null +++ b/fedora-31/_modules/pylorax/api/gitrpm.html @@ -0,0 +1,422 @@ + + + + + + + + + + + pylorax.api.gitrpm — Lorax 31.10 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +
+ + + + + +
+ +
+ + + + + + + + + + + + + + + + + +
+ + + + +
+
+
+
+ +

Source code for pylorax.api.gitrpm

+# Copyright (C) 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/>.
+#
+""" Clone a git repository and package it as an rpm
+
+This module contains functions for cloning a git repo, creating a tar archive of
+the selected commit, branch, or tag, and packaging the files into an rpm that will
+be installed by anaconda when creating the image.
+"""
+import logging
+log = logging.getLogger("lorax-composer")
+
+import os
+from rpmfluff import SimpleRpmBuild
+import shutil
+import subprocess
+import tempfile
+import time
+
+from pylorax.sysutils import joinpaths
+
+
[docs]def get_repo_description(gitRepo): + """ Return a description including the git repo and reference + + :param gitRepo: A dict with the repository details + :type gitRepo: dict + :returns: A string with the git repo url and reference + :rtype: str + """ + return "Created from %s, reference '%s', on %s" % (gitRepo["repo"], gitRepo["ref"], time.ctime())
+ +
[docs]class GitArchiveTarball: + """Create a git archive of the selected git repo and reference""" + def __init__(self, gitRepo): + self._gitRepo = gitRepo + self.sourceName = self._gitRepo["rpmname"]+".tar.xz" + +
[docs] def write_file(self, sourcesDir): + """ Create the tar archive + + :param sourcesDir: Path to use for creating the archive + :type sourcesDir: str + + This clones the git repository and creates a git archive from the specified reference. + The result is in RPMNAME.tar.xz under the sourcesDir + """ + # Clone the repository into a temporary location + cmd = ["git", "clone", self._gitRepo["repo"], joinpaths(sourcesDir, "gitrepo")] + log.debug(cmd) + try: + subprocess.check_output(cmd, stderr=subprocess.STDOUT) + except subprocess.CalledProcessError as e: + log.error("Failed to clone %s: %s", self._gitRepo["repo"], e.output) + raise RuntimeError("Failed to clone %s" % self._gitRepo["repo"]) + + oldcwd = os.getcwd() + try: + os.chdir(joinpaths(sourcesDir, "gitrepo")) + + # Configure archive to create a .tar.xz + cmd = ["git", "config", "tar.tar.xz.command", "xz -c"] + log.debug(cmd) + subprocess.check_call(cmd) + + cmd = ["git", "archive", "--prefix", self._gitRepo["rpmname"] + "/", "-o", joinpaths(sourcesDir, self.sourceName), self._gitRepo["ref"]] + log.debug(cmd) + try: + subprocess.check_output(cmd, stderr=subprocess.STDOUT) + except subprocess.CalledProcessError as e: + log.error("Failed to archive %s: %s", self._gitRepo["repo"], e.output) + raise RuntimeError('Failed to archive %s from ref "%s"' % (self._gitRepo["repo"], + self._gitRepo["ref"])) + finally: + # Cleanup even if there was an error + os.chdir(oldcwd) + shutil.rmtree(joinpaths(sourcesDir, "gitrepo"))
+ +
[docs]class GitRpmBuild(SimpleRpmBuild): + """Build an rpm containing files from a git repository""" + def __init__(self, *args, **kwargs): + self._base_dir = None + super().__init__(*args, **kwargs) + +
[docs] def check(self): + raise NotImplementedError
+ +
[docs] def get_base_dir(self): + """Place all the files under a temporary directory + rpmbuild/ + """ + if not self._base_dir: + self._base_dir = tempfile.mkdtemp(prefix="lorax-git-rpm.") + return joinpaths(self._base_dir, "rpmbuild")
+ +
[docs] def cleanup_tmpdir(self): + """Remove the temporary directory and all of its contents + """ + if len(self._base_dir) < 5: + raise RuntimeError("Invalid base_dir: %s" % self.get_base_dir()) + + shutil.rmtree(self._base_dir)
+ +
[docs] def clean(self): + """Remove the base directory from inside the tmpdir""" + if len(self.get_base_dir()) < 5: + raise RuntimeError("Invalid base_dir: %s" % self.get_base_dir()) + shutil.rmtree(self.get_base_dir(), ignore_errors=True)
+ +
[docs] def add_git_tarball(self, gitRepo): + """Add a tar archive of a git repository to the rpm + + :param gitRepo: A dict with the repository details + :type gitRepo: dict + + This populates the rpm with the URL of the git repository, the summary + describing the repo, the description of the repository and reference used, + and sets up the rpm to install the archive contents into the destination + path. + """ + self.addUrl(gitRepo["repo"]) + self.add_summary(gitRepo["summary"]) + self.add_description(get_repo_description(gitRepo)) + self.addLicense("Unknown") + sourceIndex = self.add_source(GitArchiveTarball(gitRepo)) + self.section_build += "tar -xvf %s\n" % self.sources[sourceIndex].sourceName + dest = os.path.normpath(gitRepo["destination"]) + # Prevent double slash root + if dest == "/": + dest = "" + self.create_parent_dirs(dest) + self.section_install += "cp -r %s/. $RPM_BUILD_ROOT/%s\n" % (gitRepo["rpmname"], dest) + sub = self.get_subpackage(None) + if not dest: + # / is special, we don't want to include / itself, just what's under it + sub.section_files += "/*\n" + else: + sub.section_files += "%s/\n" % dest
+ +
[docs]def make_git_rpm(gitRepo, dest): + """ Create an rpm from the specified git repo + + :param gitRepo: A dict with the repository details + :type gitRepo: dict + + This will clone the git repository, create an archive of the selected reference, + and build an rpm that will install the files from the repository under the destination + directory. The gitRepo dict should have the following fields:: + + 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/" + + * rpmname: Name of the rpm to create, also used as the prefix name in the tar archive + * rpmversion: Version of the rpm, eg. "1.0.0" + * rpmrelease: Release of the rpm, eg. "1" + * summary: Summary string for the rpm + * repo: URL of the get repo to clone and create the archive from + * ref: Git reference to check out. eg. origin/branch-name, git tag, or git commit hash + * destination: Path to install the / of the git repo at when installing the rpm + """ + gitRpm = GitRpmBuild(gitRepo["rpmname"], gitRepo["rpmversion"], gitRepo["rpmrelease"], ["noarch"]) + try: + gitRpm.add_git_tarball(gitRepo) + gitRpm.do_make() + rpmfile = gitRpm.get_built_rpm("noarch") + shutil.move(rpmfile, dest) + except Exception as e: + log.error("Creating git repo rpm: %s", e) + raise RuntimeError("Creating git repo rpm: %s" % e) + finally: + gitRpm.cleanup_tmpdir() + + return os.path.basename(rpmfile)
+ +# Create the git rpms, if any, and return the path to the repo under results_dir +
[docs]def create_gitrpm_repo(results_dir, recipe): + """Create a dnf repository with the rpms from the recipe + + :param results_dir: Path to create the repository under + :type results_dir: str + :param recipe: The recipe to get the repos.git entries from + :type recipe: Recipe + :returns: Path to the dnf repository or "" + :rtype: str + + This function creates a dnf repository directory at results_dir+"repo/", + creates rpms for all of the repos.git entries in the recipe, runs createrepo_c + on the dnf repository so that Anaconda can use it, and returns the path to the + repository to the caller. + """ + if "repos" not in recipe or "git" not in recipe["repos"]: + return "" + + gitrepo = joinpaths(results_dir, "repo/") + if not os.path.exists(gitrepo): + os.makedirs(gitrepo) + for r in recipe["repos"]["git"]: + make_git_rpm(r, gitrepo) + cmd = ["createrepo_c", gitrepo] + log.debug(cmd) + try: + subprocess.check_output(cmd, stderr=subprocess.STDOUT) + except subprocess.CalledProcessError as e: + log.error("Failed to create repo at %s: %s", gitrepo, e.output) + raise RuntimeError("Failed to create repo at %s" % gitrepo) + + return gitrepo
+
+ +
+ +
+ + +
+
+ +
+ +
+ + + + + + + + + + + + \ No newline at end of file diff --git a/fedora-31/_modules/pylorax/api/projects.html b/fedora-31/_modules/pylorax/api/projects.html new file mode 100644 index 00000000..dfe4e98f --- /dev/null +++ b/fedora-31/_modules/pylorax/api/projects.html @@ -0,0 +1,897 @@ + + + + + + + + + + + pylorax.api.projects — Lorax 31.10 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
+from pylorax.sysutils import joinpaths
+
+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' + return list(map(proj_to_module, projects_info(dbo, module_names)))
+ +
[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) + + if repo.skip_if_unavailable: + repo_str += "skip_if_unavailable=1\n" + + return repo_str
+ +
[docs]def repo_to_source(repo, system_source, api=1): + """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 + :param api: Select which api version of the dict to return (default 1) + :type api: int + :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" + ], + "id": "fedora", + "name": "Fedora $releasever - $basearch", + "proxy": "http://proxy.brianlane.com:8123", + "system": true + "type": "yum-metalink", + "url": "https://mirrors.fedoraproject.org/metalink?repo=fedora-28&arch=x86_64" + } + + The ``name`` field has changed in v1 of the API. + In v0 of the API ``name`` is the repo.id, in v1 it is the repo.name and a new field, + ``id`` has been added for the repo.id + + """ + if api==0: + source = {"name": repo.id, "system": system_source} + else: + source = {"id": repo.id, "name": repo.name, "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_repodict(source): + """Return a tuple suitable for use with dnf.add_new_repo + + :param source: A Weldr source dict + :type source: dict + :returns: A tuple of dnf.Repo attributes + :rtype: (str, list, dict) + + Return a tuple with (id, baseurl|(), kwargs) that can be used + with dnf.repos.add_new_repo + """ + kwargs = {} + if "id" in source: + # This is an API v1 source definition + repoid = source["id"] + if "name" in source: + kwargs["name"] = source["name"] + else: + repoid = source["name"] + + # This will allow errors to be raised so we can catch them + # without this they are logged, but the repo is silently disabled + kwargs["skip_if_unavailable"] = False + + if source["type"] == "yum-baseurl": + baseurl = [source["url"]] + elif source["type"] == "yum-metalink": + kwargs["metalink"] = source["url"] + baseurl = () + elif source["type"] == "yum-mirrorlist": + kwargs["mirrorlist"] = source["url"] + baseurl = () + + if "proxy" in source: + kwargs["proxy"] = source["proxy"] + + if source["check_ssl"]: + kwargs["sslverify"] = True + else: + kwargs["sslverify"] = False + + if source["check_gpg"]: + kwargs["gpgcheck"] = True + else: + kwargs["gpgcheck"] = False + + if "gpgkey_urls" in source: + kwargs["gpgkey"] = tuple(source["gpgkey_urls"]) + + return (repoid, baseurl, kwargs)
+ + +
[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 + :param dnf_conf: The dnf Config object + :type dnf_conf: dnf.conf + :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" + ], + "id": "fedora", + "name": "Fedora $releasever - $basearch", + "proxy": "http://proxy.brianlane.com:8123", + "system": True + "type": "yum-metalink", + "url": "https://mirrors.fedoraproject.org/metalink?repo=fedora-28&arch=x86_64" + } + + If the ``id`` field is included it is used for the repo id, otherwise ``name`` is used. + v0 of the API only used ``name``, v1 added the distinction between ``id`` and ``name``. + """ + repoid, baseurl, kwargs = source_to_repodict(source) + repo = dnf.repo.Repo(repoid, dnf_conf) + if baseurl: + repo.baseurl = baseurl + + # Apply the rest of the kwargs to the Repo object + for k, v in kwargs.items(): + setattr(repo, k, v) + + 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() + 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_id): + """Delete a source from a repo file + + :param source_glob: A glob of the repo sources to search + :type source_glob: str + :param source_id: The repo id to delete + :type source_id: 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_id isn't passed to it. + """ + found = False + for f in glob(source_glob): + try: + cfg = ConfigParser() + cfg.read(f) + if source_id in cfg.sections(): + found = True + cfg.remove_section(source_id) + # 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_id, str(e))) + if not found: + raise ProjectsError("source %s not found" % source_id)
+ +
[docs]def new_repo_source(dbo, repoid, source, repo_dir): + """Add a new repo source from a Weldr source dict + + :param dbo: dnf base object + :type dbo: dnf.Base + :param id: The repo id (API v0 uses the name, v1 uses the id) + :type id: str + :param source: A Weldr source dict + :type source: dict + :returns: None + :raises: ... + + Make sure access to the dbo has been locked before calling this. + The `id` parameter will the the 'name' field for API v0, and the 'id' field for API v1 + + DNF variables will be substituted at load time, and on restart. + """ + try: + # Remove it from the RepoDict (NOTE that this isn't explicitly supported by the DNF API) + # 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 repoid in repos: + del dbo.repos[repoid] + + # Add the repo and substitute any dnf variables + _, baseurl, kwargs = source_to_repodict(source) + log.debug("repoid=%s, baseurl=%s, kwargs=%s", repoid, baseurl, kwargs) + r = dbo.repos.add_new_repo(repoid, dbo.conf, baseurl, **kwargs) + r.enable() + + log.info("Updating repository metadata after adding %s", repoid) + dbo.fill_sack(load_system_repo=False) + dbo.read_comps() + + # Remove any previous sources with this id, ignore it if it isn't found + try: + delete_repo_source(joinpaths(repo_dir, "*.repo"), repoid) + except ProjectsError: + pass + + # Make sure the source id can't contain a path traversal by taking the basename + source_path = joinpaths(repo_dir, os.path.basename("%s.repo" % repoid)) + # Write the un-substituted version of the repo to disk + with open(source_path, "w") as f: + repo = source_to_repo(source, dbo.conf) + f.write(dnf_repo_to_file_repo(repo)) + except Exception as e: + log.error("(new_repo_source) adding %s failed: %s", repoid, 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 repoid in repos: + del dbo.repos[repoid] + + log.info("Updating repository metadata after adding %s failed", repoid) + dbo.fill_sack(load_system_repo=False) + dbo.read_comps() + + raise
+
+ +
+ +
+ + +
+
+ +
+ +
+ + + + + + + + + + + + \ No newline at end of file diff --git a/fedora-31/_modules/pylorax/api/queue.html b/fedora-31/_modules/pylorax/api/queue.html new file mode 100644 index 00000000..ee70af62 --- /dev/null +++ b/fedora-31/_modules/pylorax/api/queue.html @@ -0,0 +1,906 @@ + + + + + + + + + + + pylorax.api.queue — Lorax 31.10 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")
+program_log = logging.getLogger("program")
+dnf_log = logging.getLogger("dnf")
+
+import os
+import grp
+from glob import glob
+import multiprocessing as mp
+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
+import pylorax.api.toml as toml
+from pylorax.base import DataHolder
+from pylorax.creator import run_creator
+from pylorax.sysutils import joinpaths, read_tail
+
+
[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 + + # The anaconda logs are also copied into ./anaconda/ in this directory + os.makedirs(joinpaths(dst, "logs"), exist_ok=True) + + def open_handler(loggers, file_name): + handler = logging.FileHandler(joinpaths(dst, "logs", file_name)) + handler.setLevel(logging.DEBUG) + handler.setFormatter(logging.Formatter("%(asctime)s %(levelname)s: %(message)s")) + for logger in loggers: + logger.addHandler(handler) + return (handler, loggers) + + loggers = (((log, program_log, dnf_log), "combined.log"), + ((log,), "composer.log"), + ((program_log,), "program.log"), + ((dnf_log,), "dnf.log")) + handlers = [open_handler(loggers, file_name) for loggers, file_name in loggers] + + 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) + finally: + for handler, loggers in handlers: + for logger in loggers: + logger.removeHandler(handler) + handler.close() + + 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) + + # 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` KiB from the end of the most currently relevant log for a + given compose + + :param cfg: Configuration settings + :type cfg: ComposerConfig + :param uuid: The UUID of the build + :type uuid: str + :param size: Number of KiB to read. Default is 1024 + :type size: int + :returns: Up to `size` KiB from the end of the log + :rtype: str + :raises: RuntimeError if there was a problem (eg. no log file available) + + This function will return the end of either the anaconda log, the packaging + log, or the combined composer logs, depending on the progress of the + compose. It tries to return lines from the end of the log, it will attempt + to start on a line boundary, and it 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) + + def get_log_path(): + # Try to return the most relevant log at any given time during the + # compose. If the compose is not running, return the composer log. + anaconda_log = "/tmp/anaconda.log" + packaging_log = "/tmp/packaging.log" + combined_log = joinpaths(uuid_dir, "logs", "combined.log") + if status["queue_status"] != "RUNNING" or not os.path.isfile(anaconda_log): + return combined_log + if not os.path.isfile(packaging_log): + return anaconda_log + try: + anaconda_mtime = os.stat(anaconda_log).st_mtime + packaging_mtime = os.stat(packaging_log).st_mtime + # If the packaging log exists and its last message is at least 15 + # seconds newer than the anaconda log, return the packaging log. + if packaging_mtime > anaconda_mtime + 15: + return packaging_log + return anaconda_log + except OSError: + # Return the combined log if anaconda_log or packaging_log disappear + return combined_log + try: + tail = read_tail(get_log_path(), size) + except OSError as e: + raise RuntimeError("No log available.") from e + return tail
+
+ +
+ +
+ + +
+
+ +
+ +
+ + + + + + + + + + + + \ No newline at end of file diff --git a/fedora-31/_modules/pylorax/api/recipes.html b/fedora-31/_modules/pylorax/api/recipes.html new file mode 100644 index 00000000..87249c87 --- /dev/null +++ b/fedora-31/_modules/pylorax/api/recipes.html @@ -0,0 +1,1478 @@ + + + + + + + + + + + pylorax.api.recipes — Lorax 31.10 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 semantic_version as semver
+
+from pylorax.api.projects import dep_evra
+from pylorax.base import DataHolder
+from pylorax.sysutils import joinpaths
+import pylorax.api.toml as toml
+
+
+
[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
+
+ +
+ +
+ + +
+
+ +
+ +
+ + + + + + + + + + + + \ No newline at end of file diff --git a/fedora-31/_modules/pylorax/api/server.html b/fedora-31/_modules/pylorax/api/server.html new file mode 100644 index 00000000..986e3af8 --- /dev/null +++ b/fedora-31/_modules/pylorax/api/server.html @@ -0,0 +1,294 @@ + + + + + + + + + + + pylorax.api.server — Lorax 31.10 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +
+ + + + + +
+ +
+ + + + + + + + + + + + + + + + + +
+ + + + +
+
+
+
+ +

Source code for pylorax.api.server

+#
+# 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 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
+import werkzeug
+
+from pylorax import vernum
+from pylorax.api.errors import HTTP_ERROR
+from pylorax.api.v0 import v0_api
+from pylorax.api.v1 import v1_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")
+def api_status():
+    """
+    `/api/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="1",
+                   db_version="0",
+                   schema_version="0",
+                   db_supported=True,
+                   msgs=server.config["TEMPLATE_ERRORS"])
+
+@server.errorhandler(werkzeug.exceptions.HTTPException)
+def bad_request(error):
+    return jsonify(status=False, errors=[{ "id": HTTP_ERROR, "code": error.code, "msg": error.name }]), error.code
+
+# Register the v0 API on /api/v0/
+server.register_blueprint(v0_api, url_prefix="/api/v0/")
+
+# Register the v1 API on /api/v1/
+# Use v0 routes by default
+server.register_blueprint(v0_api, url_prefix="/api/v1/",
+                          skip_rules=["/projects/source/info/<source_names>", "/projects/source/new"])
+server.register_blueprint(v1_api, url_prefix="/api/v1/")
+
+ +
+ +
+ + +
+
+ +
+ +
+ + + + + + + + + + + + \ No newline at end of file diff --git a/fedora-31/_modules/pylorax/api/timestamp.html b/fedora-31/_modules/pylorax/api/timestamp.html new file mode 100644 index 00000000..ced9919b --- /dev/null +++ b/fedora-31/_modules/pylorax/api/timestamp.html @@ -0,0 +1,251 @@ + + + + + + + + + + + pylorax.api.timestamp — Lorax 31.10 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +
+ + + + + +
+ +
+ + + + + + + + + + + + + + + + + +
+ + + + +
+
+
+
+ +

Source code for pylorax.api.timestamp

+#
+# 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 time
+
+from pylorax.sysutils import joinpaths
+import pylorax.api.toml as toml
+
+TS_CREATED  = "created"
+TS_STARTED  = "started"
+TS_FINISHED = "finished"
+
+
[docs]def write_timestamp(destdir, ty): + path = joinpaths(destdir, "times.toml") + + try: + contents = toml.loads(open(path, "r").read()) + except IOError: + contents = toml.loads("") + + if ty == TS_CREATED: + contents[TS_CREATED] = time.time() + elif ty == TS_STARTED: + contents[TS_STARTED] = time.time() + elif ty == TS_FINISHED: + contents[TS_FINISHED] = time.time() + + with open(path, "w") as f: + f.write(toml.dumps(contents))
+ +
[docs]def timestamp_dict(destdir): + path = joinpaths(destdir, "times.toml") + + try: + return toml.loads(open(path, "r").read()) + except IOError: + return toml.loads("")
+
+ +
+ +
+ + +
+
+ +
+ +
+ + + + + + + + + + + + \ No newline at end of file diff --git a/fedora-31/_modules/pylorax/api/toml.html b/fedora-31/_modules/pylorax/api/toml.html new file mode 100644 index 00000000..8ed80b14 --- /dev/null +++ b/fedora-31/_modules/pylorax/api/toml.html @@ -0,0 +1,233 @@ + + + + + + + + + + + pylorax.api.toml — Lorax 31.10 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +
+ + + + + +
+ +
+ + + + + + + + + + + + + + + + + +
+ + + + +
+
+
+
+ +

Source code for pylorax.api.toml

+#
+# Copyright (C) 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 toml
+
+
[docs]class TomlError(toml.TomlDecodeError): + pass
+ +
[docs]def loads(s): + if isinstance(s, bytes): + s = s.decode('utf-8') + try: + return toml.loads(s) + except toml.TomlDecodeError as e: + raise TomlError(e.msg, e.doc, e.pos)
+ +
[docs]def dumps(o): + # strip the result, because `toml.dumps` adds a lot of newlines + return toml.dumps(o, encoder=toml.TomlEncoder(dict)).strip()
+
+ +
+ +
+ + +
+
+ +
+ +
+ + + + + + + + + + + + \ No newline at end of file diff --git a/fedora-31/_modules/pylorax/api/utils.html b/fedora-31/_modules/pylorax/api/utils.html new file mode 100644 index 00000000..99c2decc --- /dev/null +++ b/fedora-31/_modules/pylorax/api/utils.html @@ -0,0 +1,249 @@ + + + + + + + + + + + pylorax.api.utils — Lorax 31.10 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +
+ + + + + +
+ +
+ + + + + + + + + + + + + + + + + +
+ + + + +
+
+
+
+ +

Source code for pylorax.api.utils

+#
+# Copyright (C) 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/>.
+""" API utility functions
+"""
+from pylorax.api.recipes import RecipeError, RecipeFileError, read_recipe_commit
+
+
[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
+
+ +
+ +
+ + +
+
+ +
+ +
+ + + + + + + + + + + + \ No newline at end of file diff --git a/fedora-31/_modules/pylorax/api/v0.html b/fedora-31/_modules/pylorax/api/v0.html new file mode 100644 index 00000000..f4ffa4c5 --- /dev/null +++ b/fedora-31/_modules/pylorax/api/v0.html @@ -0,0 +1,2186 @@ + + + + + + + + + + + pylorax.api.v0 — Lorax 31.10 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +
+ + + + + +
+ +
+ + + + + + + + + + + + + + + + + +
+ + + + +
+
+
+
+ +

Source code for pylorax.api.v0

+#
+# 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/>.
+#
+""" 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.
+"""
+
+import logging
+log = logging.getLogger("lorax-composer")
+
+import os
+from flask import jsonify, request, Response, send_file
+from flask import current_app as api
+
+from pylorax.sysutils import joinpaths
+from pylorax.api.checkparams import checkparams
+from pylorax.api.compose import start_build, compose_types
+from pylorax.api.errors import *                               # pylint: disable=wildcard-import
+from pylorax.api.flask_blueprint import BlueprintSkip
+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, new_repo_source
+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 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, VALID_BLUEPRINT_NAME
+import pylorax.api.toml as toml
+from pylorax.api.utils import take_limits, blueprint_exists
+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
+
+# Create the v0 routes Blueprint with skip_routes support
+v0_api = BlueprintSkip("v0_routes", __name__)
+
+
[docs]@v0_api.route("/blueprints/list") +def v0_blueprints_list(): + """List the available blueprints on a branch. + + **/api/v0/blueprints/list** + + List the available blueprints:: + + { "limit": 20, + "offset": 0, + "blueprints": [ + "atlas", + "development", + "glusterfs", + "http-server", + "jboss", + "kubernetes" ], + "total": 6 } + """ + 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))
+ +
[docs]@v0_api.route("/blueprints/info", defaults={'blueprint_names': ""}) +@v0_api.route("/blueprints/info/<blueprint_names>") +@checkparams([("blueprint_names", "", "no blueprint names given")]) +def v0_blueprints_info(blueprint_names): + """Return the contents of the blueprint, or a list of blueprints + + **/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 Responses`_. + + 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": [] + } + """ + if any(VALID_BLUEPRINT_NAME.match(blueprint_name) is None for blueprint_name in blueprint_names.split(',')): + 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)
+ +
[docs]@v0_api.route("/blueprints/changes", defaults={'blueprint_names': ""}) +@v0_api.route("/blueprints/changes/<blueprint_names>") +@checkparams([("blueprint_names", "", "no blueprint names given")]) +def v0_blueprints_changes(blueprint_names): + """Return the changes to a blueprint or list of 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 + } + ] + } + """ + if any(VALID_BLUEPRINT_NAME.match(blueprint_name) is None for blueprint_name in blueprint_names.split(',')): + 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)
+ +
[docs]@v0_api.route("/blueprints/new", methods=["POST"]) +def v0_blueprints_new(): + """Commit a new blueprint + + **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. + """ + 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_BLUEPRINT_NAME.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)
+ +
[docs]@v0_api.route("/blueprints/delete", defaults={'blueprint_name': ""}, methods=["DELETE"]) +@v0_api.route("/blueprints/delete/<blueprint_name>", methods=["DELETE"]) +@checkparams([("blueprint_name", "", "no blueprint name given")]) +def v0_blueprints_delete(blueprint_name): + """Delete a blueprint from git + + **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. + """ + if VALID_BLUEPRINT_NAME.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)
+ +
[docs]@v0_api.route("/blueprints/workspace", methods=["POST"]) +def v0_blueprints_workspace(): + """Write a blueprint to the workspace + + **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. + """ + 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_BLUEPRINT_NAME.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)
+ +
[docs]@v0_api.route("/blueprints/workspace", defaults={'blueprint_name': ""}, methods=["DELETE"]) +@v0_api.route("/blueprints/workspace/<blueprint_name>", methods=["DELETE"]) +@checkparams([("blueprint_name", "", "no blueprint name given")]) +def v0_blueprints_delete_workspace(blueprint_name): + """Delete a blueprint from the workspace + + **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. + """ + if VALID_BLUEPRINT_NAME.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)
+ +
[docs]@v0_api.route("/blueprints/undo", defaults={'blueprint_name': "", 'commit': ""}, methods=["POST"]) +@v0_api.route("/blueprints/undo/<blueprint_name>", defaults={'commit': ""}, methods=["POST"]) +@v0_api.route("/blueprints/undo/<blueprint_name>/<commit>", methods=["POST"]) +@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. + + **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. + """ + if VALID_BLUEPRINT_NAME.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)
+ +
[docs]@v0_api.route("/blueprints/tag", defaults={'blueprint_name': ""}, methods=["POST"]) +@v0_api.route("/blueprints/tag/<blueprint_name>", methods=["POST"]) +@checkparams([("blueprint_name", "", "no blueprint name given")]) +def v0_blueprints_tag(blueprint_name): + """Tag a blueprint's latest blueprint commit as a 'revision' + + **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. + """ + if VALID_BLUEPRINT_NAME.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)
+ +
[docs]@v0_api.route("/blueprints/diff", defaults={'blueprint_name': "", 'from_commit': "", 'to_commit': ""}) +@v0_api.route("/blueprints/diff/<blueprint_name>", defaults={'from_commit': "", 'to_commit': ""}) +@v0_api.route("/blueprints/diff/<blueprint_name>/<from_commit>", defaults={'to_commit': ""}) +@v0_api.route("/blueprints/diff/<blueprint_name>/<from_commit>/<to_commit>") +@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 + + **/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 + } + ] + } + """ + 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)
+ +
[docs]@v0_api.route("/blueprints/freeze", defaults={'blueprint_names': ""}) +@v0_api.route("/blueprints/freeze/<blueprint_names>") +@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 + + **/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" + } + } + ] + } + """ + if any(VALID_BLUEPRINT_NAME.match(blueprint_name) is None for blueprint_name in blueprint_names.split(',')): + 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)
+ +
[docs]@v0_api.route("/blueprints/depsolve", defaults={'blueprint_names': ""}) +@v0_api.route("/blueprints/depsolve/<blueprint_names>") +@checkparams([("blueprint_names", "", "no blueprint names given")]) +def v0_blueprints_depsolve(blueprint_names): + """Return the dependencies for a blueprint + + **/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.*" + }, + ... + } + } + ] + } + """ + if any(VALID_BLUEPRINT_NAME.match(blueprint_name) is None for blueprint_name in blueprint_names.split(',')): + 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)
+ +
[docs]@v0_api.route("/projects/list") +def v0_projects_list(): + """List all of the available projects/packages + + **/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 + } + """ + 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))
+ +
[docs]@v0_api.route("/projects/info", defaults={'project_names': ""}) +@v0_api.route("/projects/info/<project_names>") +@checkparams([("project_names", "", "no project names given")]) +def v0_projects_info(project_names): + """Return detailed information about the listed projects + + **/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" + } + ] + } + """ + 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)
+ +
[docs]@v0_api.route("/projects/depsolve", defaults={'project_names': ""}) +@v0_api.route("/projects/depsolve/<project_names>") +@checkparams([("project_names", "", "no project names given")]) +def v0_projects_depsolve(project_names): + """Return detailed information about the listed projects + + **/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" + }, + ... + ] + } + """ + 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)
+ +
[docs]@v0_api.route("/projects/source/list") +def v0_projects_source_list(): + """Return the list of source names + + **/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" + ] + } + """ + 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)
+ +
[docs]@v0_api.route("/projects/source/info", defaults={'source_names': ""}) +@v0_api.route("/projects/source/info/<source_names>") +@checkparams([("source_names", "", "no source names given")]) +def v0_projects_source_info(source_names): + """Return detailed info about the list of sources + + **/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" + } + } + } + """ + 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, api=0) + + 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)
+ +
[docs]@v0_api.route("/projects/source/new", methods=["POST"]) +def v0_projects_source_new(): + """Add a new package source. Or change an existing one + + **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" + ] + } + + + """ + 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: + repo_dir = api.config["COMPOSER_CFG"].get("composer", "repo_dir") + new_repo_source(api.config["DNFLOCK"].dbo, source["name"], source, repo_dir) + except Exception as e: + return jsonify(status=False, errors=[{"id": PROJECTS_ERROR, "msg": str(e)}]), 400 + + return jsonify(status=True)
+ +
[docs]@v0_api.route("/projects/source/delete", defaults={'source_name': ""}, methods=["DELETE"]) +@v0_api.route("/projects/source/delete/<source_name>", methods=["DELETE"]) +@checkparams([("source_name", "", "no source name given")]) +def v0_projects_source_delete(source_name): + """Delete the named source and return a status response + + **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. + """ + 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)
+ +
[docs]@v0_api.route("/modules/list") +@v0_api.route("/modules/list/<module_names>") +def v0_modules_list(module_names=None): + """List available modules, filtering by module_names + + **/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 + } + """ + 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))
+ +
[docs]@v0_api.route("/modules/info", defaults={'module_names': ""}) +@v0_api.route("/modules/info/<module_names>") +@checkparams([("module_names", "", "no module names given")]) +def v0_modules_info(module_names): + """Return detailed information about the listed modules + + **/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" + } + ] + } + """ + 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)
+ +
[docs]@v0_api.route("/compose", methods=["POST"]) +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. + + **POST /api/v0/compose** + + Start a compose. The content type should be 'application/json' and the body of the POST + should look like this + + Example:: + + { + "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 + + Example:: + + { + "build_id": "e6fa6db4-9c81-4b70-870f-a697ca405cdf", + "status": true + } + """ + # 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_BLUEPRINT_NAME.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)
+ +
[docs]@v0_api.route("/compose/types") +def v0_compose_types(): + """Return the list of enabled output types + + (only enabled types are returned) + + **/api/v0/compose/types** + + Returns the list of supported output types that are valid for use with 'POST /api/v0/compose' + + Example:: + + { + "types": [ + { + "enabled": true, + "name": "tar" + } + ] + } + """ + share_dir = api.config["COMPOSER_CFG"].get("composer", "share_dir") + return jsonify(types=[{"name": k, "enabled": True} for k in compose_types(share_dir)])
+ +
[docs]@v0_api.route("/compose/queue") +def v0_compose_queue(): + """Return the status of the new and running queues + + **/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" + } + ] + } + """ + return jsonify(queue_status(api.config["COMPOSER_CFG"]))
+ +
[docs]@v0_api.route("/compose/finished") +def v0_compose_finished(): + """Return the list of finished composes + + **/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" + } + ] + } + """ + return jsonify(finished=build_status(api.config["COMPOSER_CFG"], "FINISHED"))
+ +
[docs]@v0_api.route("/compose/failed") +def v0_compose_failed(): + """Return the list of failed composes + + **/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" + } + ] + } + """ + return jsonify(failed=build_status(api.config["COMPOSER_CFG"], "FAILED"))
+ +
[docs]@v0_api.route("/compose/status", defaults={'uuids': ""}) +@v0_api.route("/compose/status/<uuids>") +@checkparams([("uuids", "", "no UUIDs given")]) +def v0_compose_status(uuids): + """Return the status of the listed uuids + + **/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" + } + ] + } + """ + 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)
+ +
[docs]@v0_api.route("/compose/cancel", defaults={'uuid': ""}, methods=["DELETE"]) +@v0_api.route("/compose/cancel/<uuid>", methods=["DELETE"]) +@checkparams([("uuid", "", "no UUID given")]) +def v0_compose_cancel(uuid): + """Cancel a running compose and delete its results directory + + **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" + } + """ + 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)
+ +
[docs]@v0_api.route("/compose/delete", defaults={'uuids': ""}, methods=["DELETE"]) +@v0_api.route("/compose/delete/<uuids>", methods=["DELETE"]) +@checkparams([("uuids", "", "no UUIDs given")]) +def v0_compose_delete(uuids): + """Delete the compose results for the listed uuids + + **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" + } + ] + } + """ + 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)
+ +
[docs]@v0_api.route("/compose/info", defaults={'uuid': ""}) +@v0_api.route("/compose/info/<uuid>") +@checkparams([("uuid", "", "no UUID given")]) +def v0_compose_info(uuid): + """Return detailed info about a compose + + **/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", + ... + } + } + """ + 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)
+ +
[docs]@v0_api.route("/compose/metadata", defaults={'uuid': ""}) +@v0_api.route("/compose/metadata/<uuid>") +@checkparams([("uuid","", "no UUID given")]) +def v0_compose_metadata(uuid): + """Return a tar of the metadata for the build + + **/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. + """ + 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)
+ +
[docs]@v0_api.route("/compose/results", defaults={'uuid': ""}) +@v0_api.route("/compose/results/<uuid>") +@checkparams([("uuid","", "no UUID given")]) +def v0_compose_results(uuid): + """Return a tar of the metadata and the results for the build + + **/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 + """ + 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)
+ +
[docs]@v0_api.route("/compose/logs", defaults={'uuid': ""}) +@v0_api.route("/compose/logs/<uuid>") +@checkparams([("uuid","", "no UUID given")]) +def v0_compose_logs(uuid): + """Return a tar of the metadata for the build + + **/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 + """ + 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)
+ +
[docs]@v0_api.route("/compose/image", defaults={'uuid': ""}) +@v0_api.route("/compose/image/<uuid>") +@checkparams([("uuid","", "no UUID given")]) +def v0_compose_image(uuid): + """Return the output image for the build + + **/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. + """ + 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)
+ +
[docs]@v0_api.route("/compose/log", defaults={'uuid': ""}) +@v0_api.route("/compose/log/<uuid>") +@checkparams([("uuid","", "no UUID given")]) +def v0_compose_log_tail(uuid): + """Return the tail of the most currently relevant log + + **/api/v0/compose/log/<uuid>[?size=KiB]** + + Returns the end of either the anaconda log, the packaging log, or the + composer logs, depending on the progress of the compose. The size + parameter is optional and defaults to 1 MiB if it is not included. The + returned data is raw text from the end of the log file, starting on a + line boundary. + + 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) + """ + 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
+
+ +
+ +
+ + +
+
+ +
+ +
+ + + + + + + + + + + + \ No newline at end of file diff --git a/fedora-31/_modules/pylorax/api/v1.html b/fedora-31/_modules/pylorax/api/v1.html new file mode 100644 index 00000000..1261df88 --- /dev/null +++ b/fedora-31/_modules/pylorax/api/v1.html @@ -0,0 +1,368 @@ + + + + + + + + + + + pylorax.api.v1 — Lorax 31.10 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +
+ + + + + +
+ +
+ + + + + + + + + + + + + + + + + +
+ + + + +
+
+
+
+ +

Source code for pylorax.api.v1

+#
+# Copyright (C) 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 v1 of the API server
+
+"""
+import logging
+log = logging.getLogger("lorax-composer")
+
+from flask import jsonify, request
+from flask import current_app as api
+
+from pylorax.api.checkparams import checkparams
+from pylorax.api.errors import INVALID_CHARS, PROJECTS_ERROR, SYSTEM_SOURCE, UNKNOWN_SOURCE
+from pylorax.api.flask_blueprint import BlueprintSkip
+from pylorax.api.projects import get_repo_sources, new_repo_source, repo_to_source
+from pylorax.api.regexes import VALID_API_STRING
+import pylorax.api.toml as toml
+
+# Create the v1 routes Blueprint with skip_routes support
+v1_api = BlueprintSkip("v1_routes", __name__)
+
+
[docs]@v1_api.route("/projects/source/info", defaults={'source_ids': ""}) +@v1_api.route("/projects/source/info/<source_ids>") +@checkparams([("source_ids", "", "no source names given")]) +def v1_projects_source_info(source_ids): + """Return detailed info about the list of sources + + **/api/v1/projects/source/info/<source-ids>** + + Return information about the comma-separated list of source ids. 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" + ], + "id": "fedora", + "name": "Fedora $releasever - $basearch", + "proxy": "http://proxy.brianlane.com:8123", + "system": true, + "type": "yum-metalink", + "url": "https://mirrors.fedoraproject.org/metalink?repo=fedora-28&arch=x86_64" + } + } + } + + In v0 the ``name`` field was used for the id (a short name for the repo). In v1 ``name`` changed + to ``id`` and ``name`` is now used for the longer descriptive name of the repository. + """ + if VALID_API_STRING.match(source_ids) 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_ids == "*": + with api.config["DNFLOCK"].lock: + source_ids = ",".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_ids.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, api=1) + + 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)
+ +
[docs]@v1_api.route("/projects/source/new", methods=["POST"]) +def v1_projects_source_new(): + """Add a new package source. Or change an existing one + + **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:: + + { + "id": "custom-source-1", + "name": "Custom Package 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" + ] + } + + In v0 the ``name`` field was used for the id (a short name for the repo). In v1 ``name`` changed + to ``id`` and ``name`` is now used for the longer descriptive name of the repository. + """ + if request.headers['Content-Type'] == "text/x-toml": + source = toml.loads(request.data) + else: + source = request.get_json(cache=False) + + # Check for id in source, return error if not + if "id" not in source: + return jsonify(status=False, errors=[{"id": UNKNOWN_SOURCE, "msg": "'id' field is missing from API v1 request."}]), 400 + + system_sources = get_repo_sources("/etc/yum.repos.d/*.repo") + if source["id"] in system_sources: + return jsonify(status=False, errors=[{"id": SYSTEM_SOURCE, "msg": "%s is a system source, it cannot be changed." % source["id"]}]), 400 + + try: + # Remove it from the RepoDict (NOTE that this isn't explicitly supported by the DNF API) + with api.config["DNFLOCK"].lock: + repo_dir = api.config["COMPOSER_CFG"].get("composer", "repo_dir") + new_repo_source(api.config["DNFLOCK"].dbo, source["id"], source, repo_dir) + except Exception as e: + return jsonify(status=False, errors=[{"id": PROJECTS_ERROR, "msg": str(e)}]), 400 + + return jsonify(status=True)
+
+ +
+ +
+ + +
+
+ +
+ +
+ + + + + + + + + + + + \ No newline at end of file diff --git a/fedora-31/_modules/pylorax/api/workspace.html b/fedora-31/_modules/pylorax/api/workspace.html new file mode 100644 index 00000000..a9746804 --- /dev/null +++ b/fedora-31/_modules/pylorax/api/workspace.html @@ -0,0 +1,299 @@ + + + + + + + + + + + pylorax.api.workspace — Lorax 31.10 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)
+
+ +
+ +
+ + +
+
+ +
+ +
+ + + + + + + + + + + + \ No newline at end of file diff --git a/fedora-31/_modules/pylorax/base.html b/fedora-31/_modules/pylorax/base.html new file mode 100644 index 00000000..e7946cf7 --- /dev/null +++ b/fedora-31/_modules/pylorax/base.html @@ -0,0 +1,267 @@ + + + + + + + + + + + pylorax.base — Lorax 31.10 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))
+
+ +
+ +
+ + +
+
+ +
+ +
+ + + + + + + + + + + + \ No newline at end of file diff --git a/fedora-31/_modules/pylorax/buildstamp.html b/fedora-31/_modules/pylorax/buildstamp.html new file mode 100644 index 00000000..352a78b7 --- /dev/null +++ b/fedora-31/_modules/pylorax/buildstamp.html @@ -0,0 +1,266 @@ + + + + + + + + + + + pylorax.buildstamp — Lorax 31.10 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
+import os
+
+
+
[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 + + if 'SOURCE_DATE_EPOCH' in os.environ: + now = datetime.datetime.utcfromtimestamp( + int(os.environ['SOURCE_DATE_EPOCH'])) + else: + 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))
+
+ +
+ +
+ + +
+
+ +
+ +
+ + + + + + + + + + + + \ No newline at end of file diff --git a/fedora-31/_modules/pylorax/cmdline.html b/fedora-31/_modules/pylorax/cmdline.html new file mode 100644 index 00000000..7e6418c1 --- /dev/null +++ b/fedora-31/_modules/pylorax/cmdline.html @@ -0,0 +1,515 @@ + + + + + + + + + + + pylorax.cmdline — Lorax 31.10 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=2, + help="Size of root filesystem in GiB. Defaults to 2.") + optional.add_argument("--noverifyssl", action="store_true", default=False, + help="Do not verify SSL certificates") + optional.add_argument("--dnfplugin", action="append", default=[], dest="dnfplugins", + help="Enable a DNF plugin by name/glob, or * to enable all of them.") + optional.add_argument("--squashfs-only", action="store_true", default=False, + help="Use a plain squashfs filesystem for the runtime.") + + # 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=2048, + 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="29", + help="substituted for @VERSION@ in bootloader config files") + parser.add_argument("--volid", default=None, help="volume id") + parser.add_argument("--squashfs-only", action="store_true", default=False, + help="Use a plain squashfs filesystem for the runtime.") + 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
+
+ +
+ +
+ + +
+
+ +
+ +
+ + + + + + + + + + + + \ No newline at end of file diff --git a/fedora-31/_modules/pylorax/creator.html b/fedora-31/_modules/pylorax/creator.html new file mode 100644 index 00000000..6bf0c53d --- /dev/null +++ b/fedora-31/_modules/pylorax/creator.html @@ -0,0 +1,947 @@ + + + + + + + + + + + pylorax.creator — Lorax 31.10 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 and not opts.compress_args: + # default to bcj when using xz + compressargs = ["-Xbcj", arch.bcj] + elif opts.compress_args: + compressargs = [] + for arg in opts.compress_args: + compressargs += arg.split(" ", 1) + 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) + + rb = RuntimeBuilder(product, arch, fake_dbo) + compression, compressargs = squashfs_args(opts) + + if opts.squashfs_only: + log.info("Creating a squashfs only runtime") + rb.create_squashfs_runtime(joinpaths(work_dir, RUNTIME), size=size, + compression=compression, compressargs=compressargs) + else: + log.info("Creating a squashfs+ext4 runtime") + rb.create_ext4_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")) + rc = execWithRedirect("/bin/ln", ["-s", joinpaths(work_dir, "images"), + joinpaths(mount_dir, "images")]) + if rc: + raise RuntimeError("Failed to symlink images from mount_dir to work_dir") + + # 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 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 + with Mount(disk_img, opts="loop") as mount_dir: + # TODO check rc + make_runtime(opts, mount_dir, work_dir, calculate_disk_size(opts, ks)/1024.0) + + if cancel_func and cancel_func(): + raise RuntimeError("ISO creation canceled") + + 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)
+
+ +
+ +
+ + +
+
+ +
+ +
+ + + + + + + + + + + + \ No newline at end of file diff --git a/fedora-31/_modules/pylorax/decorators.html b/fedora-31/_modules/pylorax/decorators.html new file mode 100644 index 00000000..26a53df3 --- /dev/null +++ b/fedora-31/_modules/pylorax/decorators.html @@ -0,0 +1,230 @@ + + + + + + + + + + + pylorax.decorators — Lorax 31.10 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
+
+ +
+ +
+ + +
+
+ +
+ +
+ + + + + + + + + + + + \ No newline at end of file diff --git a/fedora-31/_modules/pylorax/discinfo.html b/fedora-31/_modules/pylorax/discinfo.html new file mode 100644 index 00000000..b81f1e6c --- /dev/null +++ b/fedora-31/_modules/pylorax/discinfo.html @@ -0,0 +1,245 @@ + + + + + + + + + + + pylorax.discinfo — Lorax 31.10 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 os
+import time
+
+
+
[docs]class DiscInfo(object): + + def __init__(self, release, basearch): + self.release = release + self.basearch = basearch + +
[docs] def write(self, outfile): + if 'SOURCE_DATE_EPOCH' in os.environ: + timestamp = int(os.environ['SOURCE_DATE_EPOCH']) + else: + timestamp = time.time() + + logger.info("writing .discinfo file") + with open(outfile, "w") as fobj: + fobj.write("{0:f}\n".format(timestamp)) + fobj.write("{0.release}\n".format(self)) + fobj.write("{0.basearch}\n".format(self))
+
+ +
+ +
+ + +
+
+ +
+ +
+ + + + + + + + + + + + \ No newline at end of file diff --git a/fedora-31/_modules/pylorax/dnfbase.html b/fedora-31/_modules/pylorax/dnfbase.html new file mode 100644 index 00000000..91796818 --- /dev/null +++ b/fedora-31/_modules/pylorax/dnfbase.html @@ -0,0 +1,385 @@ + + + + + + + + + + + pylorax.dnfbase — Lorax 31.10 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +
+ + + + + +
+ +
+ + + + + + + + + + + + + + + + + +
+ + + + +
+
+
+
+ +

Source code for pylorax.dnfbase

+# 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 logging
+log = logging.getLogger("pylorax")
+
+import dnf
+import os
+import shutil
+
+from pylorax import DEFAULT_PLATFORM_ID
+from pylorax.sysutils import flatconfig
+
+
[docs]def get_dnf_base_object(installroot, sources, mirrorlists=None, repos=None, + enablerepos=None, disablerepos=None, + tempdir="/var/tmp", proxy=None, releasever="29", + cachedir=None, logdir=None, sslverify=True, dnfplugins=None): + """ Create a dnf Base object and setup the repositories and installroot + + :param string installroot: Full path to the installroot + :param list sources: List of source repo urls to use for the installation + :param list enablerepos: List of repo names to enable + :param list disablerepos: List of repo names to disable + :param list mirrorlist: List of mirrors to use + :param string tempdir: Path of temporary directory + :param string proxy: http proxy to use when fetching packages + :param string releasever: Release version to pass to dnf + :param string cachedir: Directory to use for caching packages + :param bool noverifyssl: Set to True to ignore the CA of ssl certs. eg. use self-signed ssl for https repos. + + If tempdir is not set /var/tmp is used. + If cachedir is None a dnf.cache directory is created inside tmpdir + """ + def sanitize_repo(repo): + """Convert bare paths to file:/// URIs, and silently reject protocols unhandled by yum""" + if repo.startswith("/"): + return "file://{0}".format(repo) + elif any(repo.startswith(p) for p in ('http://', 'https://', 'ftp://', 'file://')): + return repo + else: + return None + + mirrorlists = mirrorlists or [] + + # sanitize the repositories + sources = list(sanitize_repo(r) for r in sources) + mirrorlists = list(sanitize_repo(r) for r in mirrorlists) + + # remove invalid repositories + sources = list(r for r in sources if r) + mirrorlists = list(r for r in mirrorlists if r) + + if not cachedir: + cachedir = os.path.join(tempdir, "dnf.cache") + if not os.path.isdir(cachedir): + os.mkdir(cachedir) + + if not logdir: + logdir = os.path.join(tempdir, "dnf.logs") + if not os.path.isdir(logdir): + os.mkdir(logdir) + + dnfbase = dnf.Base() + # Enable DNF pluings + # NOTE: These come from the HOST system's environment + if dnfplugins: + if dnfplugins[0] == "*": + # Enable them all + dnfbase.init_plugins() + else: + # Only enable the listed plugins + dnfbase.init_plugins(disabled_glob=["*"], enable_plugins=dnfplugins) + conf = dnfbase.conf + conf.logdir = logdir + conf.cachedir = cachedir + + conf.install_weak_deps = False + conf.releasever = releasever + conf.installroot = installroot + conf.prepend_installroot('persistdir') + # this is a weird 'AppendOption' thing that, when you set it, + # actually appends. Doing this adds 'nodocs' to the existing list + # of values, over in libdnf, it does not replace the existing values. + conf.tsflags = ['nodocs'] + + if proxy: + conf.proxy = proxy + + if sslverify == False: + conf.sslverify = False + + # DNF 3.2 needs to have module_platform_id set, otherwise depsolve won't work correctly + if not os.path.exists("/etc/os-release"): + log.warning("/etc/os-release is missing, cannot determine platform id, falling back to %s", DEFAULT_PLATFORM_ID) + platform_id = DEFAULT_PLATFORM_ID + else: + os_release = flatconfig("/etc/os-release") + platform_id = os_release.get("PLATFORM_ID", DEFAULT_PLATFORM_ID) + log.info("Using %s for module_platform_id", platform_id) + conf.module_platform_id = platform_id + + # Add .repo files + if repos: + reposdir = os.path.join(tempdir, "dnf.repos") + if not os.path.isdir(reposdir): + os.mkdir(reposdir) + for r in repos: + shutil.copy2(r, reposdir) + conf.reposdir = [reposdir] + dnfbase.read_all_repos() + + # add the sources + for i, r in enumerate(sources): + if "SRPM" in r or "srpm" in r: + log.info("Skipping source repo: %s", r) + continue + repo_name = "lorax-repo-%d" % i + repo = dnf.repo.Repo(repo_name, conf) + repo.baseurl = [r] + if proxy: + repo.proxy = proxy + repo.enable() + dnfbase.repos.add(repo) + log.info("Added '%s': %s", repo_name, r) + log.info("Fetching metadata...") + try: + repo.load() + except dnf.exceptions.RepoError as e: + log.error("Error fetching metadata for %s: %s", repo_name, e) + return None + + # add the mirrorlists + for i, r in enumerate(mirrorlists): + if "SRPM" in r or "srpm" in r: + log.info("Skipping source repo: %s", r) + continue + repo_name = "lorax-mirrorlist-%d" % i + repo = dnf.repo.Repo(repo_name, conf) + repo.mirrorlist = r + if proxy: + repo.proxy = proxy + repo.enable() + dnfbase.repos.add(repo) + log.info("Added '%s': %s", repo_name, r) + log.info("Fetching metadata...") + try: + repo.load() + except dnf.exceptions.RepoError as e: + log.error("Error fetching metadata for %s: %s", repo_name, e) + return None + + # Enable repos listed on the cmdline + for r in enablerepos: + repolist = dnfbase.repos.get_matching(r) + if not repolist: + log.warning("%s is an unknown repo, not enabling it", r) + else: + repolist.enable() + log.info("Enabled repo %s", r) + + # Disable repos listed on the cmdline + for r in disablerepos: + repolist = dnfbase.repos.get_matching(r) + if not repolist: + log.warning("%s is an unknown repo, not disabling it", r) + else: + repolist.disable() + log.info("Disabled repo %s", r) + + dnfbase.fill_sack(load_system_repo=False) + dnfbase.read_comps() + + return dnfbase
+
+ +
+ +
+ + +
+
+ +
+ +
+ + + + + + + + + + + + \ No newline at end of file diff --git a/fedora-31/_modules/pylorax/dnfhelper.html b/fedora-31/_modules/pylorax/dnfhelper.html new file mode 100644 index 00000000..7334e2c1 --- /dev/null +++ b/fedora-31/_modules/pylorax/dnfhelper.html @@ -0,0 +1,310 @@ + + + + + + + + + + + pylorax.dnfhelper — Lorax 31.10 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: + # 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: + msg = "Performing post-installation setup tasks" + logger.info(msg)
+ +
[docs] def error(self, message): + logger.warning(message)
+
+ +
+ +
+ + +
+
+ +
+ +
+ + + + + + + + + + + + \ No newline at end of file diff --git a/fedora-31/_modules/pylorax/executils.html b/fedora-31/_modules/pylorax/executils.html new file mode 100644 index 00000000..40e08fda --- /dev/null +++ b/fedora-31/_modules/pylorax/executils.html @@ -0,0 +1,549 @@ + + + + + + + + + + + pylorax.executils — Lorax 31.10 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")
+
+# pylint: disable=not-context-manager
+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) + + # pylint: disable=subprocess-popen-preexec-fn + 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)
+
+ +
+ +
+ + +
+
+ +
+ +
+ + + + + + + + + + + + \ No newline at end of file diff --git a/fedora-31/_modules/pylorax/imgutils.html b/fedora-31/_modules/pylorax/imgutils.html new file mode 100644 index 00000000..30486040 --- /dev/null +++ b/fedora-31/_modules/pylorax/imgutils.html @@ -0,0 +1,754 @@ + + + + + + + + + + + pylorax.imgutils — Lorax 31.10 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +
+ + + + + +
+ +
+ + + + + + + + + + + + + + + + + +
+ + + + +
+
+
+
+ +

Source code for pylorax.imgutils

+# imgutils.py - utility functions/classes for building disk images
+#
+# 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/>.
+#
+# 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. + + On rare occasions it appears that the device never shows up, some experiments + seem to indicate that it may be a race with another process using /dev/loop* devices. + + So we now try 3 times before actually failing. + + Raises CalledProcessError if losetup fails. + """ + retries = 0 + while True: + try: + retries += 1 + dev = runcmd_output(["losetup", "--find", "--show", outfile]).strip() + + # Sometimes the loop device isn't ready yet, make extra sure before returning + loop_waitfor(dev, outfile) + except RuntimeError: + # Try to setup the loop device 3 times + if retries == 3: + logger.error("loop_attach failed, retries exhausted.") + raise + logger.debug("Try %d failed, %s did not appear.", retries, dev) + break + return dev
+ +
[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", "--preserve=timestamps"] + 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]def kpartx_disk_img(disk_img): + """Attach a disk image's partitions to /dev/loopX using kpartx + + :param disk_img: The full path to a partitioned disk image + :type disk_img: str + :returns: list of (loopXpN, size) + :rtype: list of tuples + """ + # 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", disk_img]) + logger.debug(kpartx_output) + + # list of (deviceName, sizeInBytes) + 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() + loop_devices.append( (fields[0], int(fields[3])*512) ) + return loop_devices
+ +
[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") + + # list of (deviceName, sizeInBytes) + self.loop_devices = kpartx_disk_img(self.disk_img) + + 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 {} + mkfsargs = ["-n", label] + if 'SOURCE_DATE_EPOCH' in os.environ: + mkfsargs.extend(["-i", + "{:x}".format(int(os.environ['SOURCE_DATE_EPOCH']))]) + mkfsimage("msdos", rootdir, outfile, size, mountargs=mountargs, + mkfsargs=mkfsargs, 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")
+
+ +
+ +
+ + +
+
+ +
+ +
+ + + + + + + + + + + + \ No newline at end of file diff --git a/fedora-31/_modules/pylorax/installer.html b/fedora-31/_modules/pylorax/installer.html new file mode 100644 index 00000000..ef0a6677 --- /dev/null +++ b/fedora-31/_modules/pylorax/installer.html @@ -0,0 +1,866 @@ + + + + + + + + + + + pylorax.installer — Lorax 31.10 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 + """ + # Mapping of arch to qemu command + QEMU_CMDS = {"x86_64": "qemu-system-x86_64", + "i386": "qemu-system-i386", + "arm": "qemu-system-arm", + "aarch64": "qemu-system-aarch64", + "ppc64le": "qemu-system-ppc64" + } + + 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 + """ + # Lookup qemu-system- for arch if passed, or try to guess using host arch + qemu_cmd = [self.QEMU_CMDS.get(arch or os.uname().machine, "qemu-system-"+os.uname().machine)] + if not os.path.exists("/usr/bin/"+qemu_cmd[0]): + raise InstallError("%s does not exist, cannot run qemu" % qemu_cmd[0]) + + qemu_cmd += ["-no-user-config"] + 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 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: + unshare_args = [ "--pid", "--kill-child", "--mount", "--propagation", "unchanged", "anaconda" ] + args + for line in execReadlines("unshare", unshare_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", + "/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)
+
+ +
+ +
+ + +
+
+ +
+ +
+ + + + + + + + + + + + \ No newline at end of file diff --git a/fedora-31/_modules/pylorax/ltmpl.html b/fedora-31/_modules/pylorax/ltmpl.html new file mode 100644 index 00000000..f16d7c5d --- /dev/null +++ b/fedora-31/_modules/pylorax/ltmpl.html @@ -0,0 +1,1088 @@ + + + + + + + + + + + pylorax.ltmpl — Lorax 31.10 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +
+ + + + + +
+ +
+ + + + + + + + + + + + + + + + + +
+ + + + +
+
+
+
+ +

Source code for pylorax.ltmpl

+#
+# ltmpl.py
+#
+# Copyright (C) 2009-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/>.
+#
+# 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)
+ + # pylint: disable=anomalous-backslash-in-string +
[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.")
+
+ +
+ +
+ + +
+
+ +
+ +
+ + + + + + + + + + + + \ No newline at end of file diff --git a/fedora-31/_modules/pylorax/monitor.html b/fedora-31/_modules/pylorax/monitor.html new file mode 100644 index 00000000..08216bb5 --- /dev/null +++ b/fedora-31/_modules/pylorax/monitor.html @@ -0,0 +1,403 @@ + + + + + + + + + + + pylorax.monitor — Lorax 31.10 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. + """ + + simple_tests = [ + "Traceback (", + "traceback script(s) have been run", + "Out of memory:", + "Call Trace:", + "insufficient disk space:", + "Not enough disk space to download the packages", + "error populating transaction after", + "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 .*" + ] + +
[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 + + for t in self.simple_tests: + if t in line: + self.server.log_error = True + self.server.error_line = line + return + for t in self.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, log_request_handler_class=LogRequestHandler): + """ + 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), log_request_handler_class, 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()
+
+ +
+ +
+ + +
+
+ +
+ +
+ + + + + + + + + + + + \ No newline at end of file diff --git a/fedora-31/_modules/pylorax/mount.html b/fedora-31/_modules/pylorax/mount.html new file mode 100644 index 00000000..0db60b45 --- /dev/null +++ b/fedora-31/_modules/pylorax/mount.html @@ -0,0 +1,304 @@ + + + + + + + + + + + pylorax.mount — Lorax 31.10 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
+import pycdlib
+from pycdlib.pycdlibexception import PyCdlibException
+
+from pylorax.imgutils import mount, umount
+
+
[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"), + ("/images/pxeboot/vmlinuz", "/images/pxeboot/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 + """ + try: + iso = pycdlib.PyCdlib() + iso.open(self.iso_path) + self.label = iso.pvd.volume_identifier.decode("UTF-8").strip() + except PyCdlibException as e: + log.error("Problem reading label from %s: %s", self.iso_path, e)
+
+ +
+ +
+ + +
+
+ +
+ +
+ + + + + + + + + + + + \ No newline at end of file diff --git a/fedora-31/_modules/pylorax/sysutils.html b/fedora-31/_modules/pylorax/sysutils.html new file mode 100644 index 00000000..7a2d9666 --- /dev/null +++ b/fedora-31/_modules/pylorax/sysutils.html @@ -0,0 +1,360 @@ + + + + + + + + + + + pylorax.sysutils — Lorax 31.10 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +
+ + + + + +
+ +
+ + + + + + + + + + + + + + + + + +
+ + + + +
+
+
+
+ +

Source code for pylorax.sysutils

+#
+# sysutils.py
+#
+# Copyright (C) 2009-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/>.
+#
+# 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'] + +def read_tail(path, size): + """Read up to `size` kibibytes from the end of a file""" + + # NOTE: In py3 text files are unicode, not bytes so we have to open it as bytes + with open(path, "rb") as f: + return _read_file_end(f, size) + +def _read_file_end(f, size): + """Read the end of a file + + This skips to the next line to avoid starting in the middle of a unicode character. + And returns "" in the case of a UnicodeDecodeError + """ + f.seek(0, 2) + end = f.tell() + if end < 1024 * size: + f.seek(0, 0) + else: + f.seek(end - (1024 * size)) + data = f.read() + try: + # Find the first newline in the block + newline = min(1+data.find(b'\n'), len(data)) + text = data[newline:].decode("UTF-8") + except UnicodeDecodeError: + return "" + return text +
+ +
+ +
+ + +
+
+ +
+ +
+ + + + + + + + + + + + \ No newline at end of file diff --git a/fedora-31/_modules/pylorax/treebuilder.html b/fedora-31/_modules/pylorax/treebuilder.html new file mode 100644 index 00000000..9b5c1cb3 --- /dev/null +++ b/fedora-31/_modules/pylorax/treebuilder.html @@ -0,0 +1,603 @@ + + + + + + + + + + + pylorax.treebuilder — Lorax 31.10 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',
+    '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_squashfs_runtime(self, outfile="/var/tmp/squashfs.img", compression="xz", compressargs=None, size=2): + """Create a plain squashfs runtime""" + compressargs = compressargs or [] + os.makedirs(os.path.dirname(outfile)) + + # squash the rootfs + imgutils.mksquashfs(self.vars.root, outfile, compression, compressargs)
+ +
[docs] def create_ext4_runtime(self, outfile="/var/tmp/squashfs.img", compression="xz", compressargs=None, size=2): + """Create a squashfs compressed ext4 runtime""" + # 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) + + 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()
+
+ +
+ +
+ + +
+
+ +
+ +
+ + + + + + + + + + + + \ No newline at end of file diff --git a/fedora-31/_modules/pylorax/treeinfo.html b/fedora-31/_modules/pylorax/treeinfo.html new file mode 100644 index 00000000..3633cfb0 --- /dev/null +++ b/fedora-31/_modules/pylorax/treeinfo.html @@ -0,0 +1,263 @@ + + + + + + + + + + + pylorax.treeinfo — Lorax 31.10 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 os
+import time
+
+
+
[docs]class TreeInfo(object): + + def __init__(self, product, version, variant, basearch, + packagedir=""): + + self.c = configparser.ConfigParser() + + if 'SOURCE_DATE_EPOCH' in os.environ: + timestamp = os.environ['SOURCE_DATE_EPOCH'] + else: + timestamp = str(time.time()) + + section = "general" + data = {"timestamp": timestamp, + "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)
+
+ +
+ +
+ + +
+
+ +
+ +
+ + + + + + + + + + + + \ No newline at end of file diff --git a/fedora-31/_sources/composer-cli.rst.txt b/fedora-31/_sources/composer-cli.rst.txt new file mode 100644 index 00000000..36cc92ec --- /dev/null +++ b/fedora-31/_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, hyper-v, +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/fedora-31/_sources/composer.cli.rst.txt b/fedora-31/_sources/composer.cli.rst.txt new file mode 100644 index 00000000..50ff52f2 --- /dev/null +++ b/fedora-31/_sources/composer.cli.rst.txt @@ -0,0 +1,86 @@ +composer.cli package +==================== + +Submodules +---------- + +composer.cli.blueprints module +------------------------------ + +.. automodule:: composer.cli.blueprints + :members: + :undoc-members: + :show-inheritance: + +composer.cli.cmdline module +--------------------------- + +.. automodule:: composer.cli.cmdline + :members: + :undoc-members: + :show-inheritance: + +composer.cli.compose module +--------------------------- + +.. automodule:: composer.cli.compose + :members: + :undoc-members: + :show-inheritance: + +composer.cli.help module +------------------------ + +.. automodule:: composer.cli.help + :members: + :undoc-members: + :show-inheritance: + +composer.cli.modules module +--------------------------- + +.. automodule:: composer.cli.modules + :members: + :undoc-members: + :show-inheritance: + +composer.cli.projects module +---------------------------- + +.. automodule:: composer.cli.projects + :members: + :undoc-members: + :show-inheritance: + +composer.cli.sources module +--------------------------- + +.. automodule:: composer.cli.sources + :members: + :undoc-members: + :show-inheritance: + +composer.cli.status module +-------------------------- + +.. automodule:: composer.cli.status + :members: + :undoc-members: + :show-inheritance: + +composer.cli.utilities module +----------------------------- + +.. automodule:: composer.cli.utilities + :members: + :undoc-members: + :show-inheritance: + + +Module contents +--------------- + +.. automodule:: composer.cli + :members: + :undoc-members: + :show-inheritance: diff --git a/fedora-31/_sources/composer.rst.txt b/fedora-31/_sources/composer.rst.txt new file mode 100644 index 00000000..dd0c06cb --- /dev/null +++ b/fedora-31/_sources/composer.rst.txt @@ -0,0 +1,37 @@ +composer package +================ + +Subpackages +----------- + +.. toctree:: + + composer.cli + +Submodules +---------- + +composer.http\_client module +---------------------------- + +.. automodule:: composer.http_client + :members: + :undoc-members: + :show-inheritance: + +composer.unix\_socket module +---------------------------- + +.. automodule:: composer.unix_socket + :members: + :undoc-members: + :show-inheritance: + + +Module contents +--------------- + +.. automodule:: composer + :members: + :undoc-members: + :show-inheritance: diff --git a/fedora-31/_sources/index.rst.txt b/fedora-31/_sources/index.rst.txt new file mode 100644 index 00000000..c19a1fe9 --- /dev/null +++ b/fedora-31/_sources/index.rst.txt @@ -0,0 +1,36 @@ +.. 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 30 `_ +* `Fedora 29 `_ +* `Fedora 28 `_ +* `RHEL7 lorax-composer `_ + +Indices and tables +================== + +* :ref:`genindex` +* :ref:`modindex` +* :ref:`search` + diff --git a/fedora-31/_sources/intro.rst.txt b/fedora-31/_sources/intro.rst.txt new file mode 100644 index 00000000..01857ee9 --- /dev/null +++ b/fedora-31/_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/fedora-31/_sources/livemedia-creator.rst.txt b/fedora-31/_sources/livemedia-creator.rst.txt new file mode 100644 index 00000000..4b4fea7f --- /dev/null +++ b/fedora-31/_sources/livemedia-creator.rst.txt @@ -0,0 +1,657 @@ +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 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 + + +Quickstart +---------- + +Run this to create a bootable live iso:: + + sudo livemedia-creator --make-iso \ + --iso=/extra/iso/boot.iso --ks=./docs/fedora-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/fedora-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 + grub2-efi + memtest86+ + syslinux + +User created repositories +~~~~~~~~~~~~~~~~~~~~~~~~~ + +If you are using your own repositories and installing groups (eg. @core) make +sure you create the repodata with groups like this ``createrepo -g +/path/to/groups.xml /path/to/rpms`` + +Using a Proxy with repos +~~~~~~~~~~~~~~~~~~~~~~~~ + +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. You can use all of the `kickstart commands `_ in your kickstart. Make sure there +is only one ``url`` command, other repos have to use the ``repo`` command and cannot be +named ``updates`` which is reserved for Anaconda's use. eg.:: + + url --url=PRIMARY-REPO-URL --proxy=PROXY-URL + repo --name="repo1" --baseurl=FIRST-REPO-URL --proxy=PROXY-URL + repo --name="repo2" --baseurl=SECOND-REPO_URL --proxy=PROXY-URL + + +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=./fedora-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/fedora-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