From c21913337663888f880ed3f6253a072d4abb6dbe Mon Sep 17 00:00:00 2001 From: "Sean M. Collins" Date: Tue, 14 Apr 2015 15:04:06 -0400 Subject: [PATCH] Add "Writing your First OpenStack Application" Guide Written during a book sprint in Taipei, from March 30th 2015 to April 3rd 2015. Co-Authored-By: Sean M. Collins Co-Authored-By: Tom Fifield Co-Authored-By: James Dempsey Co-Authored-By: Nick Chase Co-Authored-By: Christian Berendt Implements blueprint openstack-firstapp Change-Id: I55ae32d0c04f641c818bda4714d9bc691a98e6b1 --- .gitignore | 1 + openstack-firstapp/README.rst | 44 + openstack-firstapp/doc/Makefile | 207 +++++ openstack-firstapp/doc/source/appendix.rst | 54 ++ openstack-firstapp/doc/source/conf.py | 273 ++++++ .../doc/source/images/architecture.dot | 9 + .../doc/source/images/fractal-example.png | Bin 0 -> 61597 bytes .../doc/source/images/network-topology.png | Bin 0 -> 36223 bytes .../source/images/screenshot_webinterface.png | Bin 0 -> 207211 bytes .../doc/source/images/work_queue.dot | 7 + openstack-firstapp/doc/source/index.rst | 31 + openstack-firstapp/doc/source/section1.rst | 618 ++++++++++++++ openstack-firstapp/doc/source/section2.rst | 511 +++++++++++ openstack-firstapp/doc/source/section3.rst | 348 ++++++++ openstack-firstapp/doc/source/section4.rst | 303 +++++++ openstack-firstapp/doc/source/section5.rst | 275 ++++++ openstack-firstapp/doc/source/section6.rst | 199 +++++ openstack-firstapp/doc/source/section7.rst | 797 ++++++++++++++++++ openstack-firstapp/doc/source/section8.rst | 119 +++ openstack-firstapp/doc/source/section9.rst | 60 ++ openstack-firstapp/samples/fog/section1.rb | 55 ++ .../samples/libcloud/section1.py | 119 +++ .../samples/libcloud/section2.py | 133 +++ .../samples/libcloud/section3.py | 110 +++ .../samples/libcloud/section4.py | 93 ++ openstack-firstapp/setup.cfg | 23 + openstack-firstapp/setup.py | 6 + test-requirements.txt | 10 + tox.ini | 20 + 29 files changed, 4425 insertions(+) create mode 100644 openstack-firstapp/README.rst create mode 100644 openstack-firstapp/doc/Makefile create mode 100644 openstack-firstapp/doc/source/appendix.rst create mode 100644 openstack-firstapp/doc/source/conf.py create mode 100644 openstack-firstapp/doc/source/images/architecture.dot create mode 100644 openstack-firstapp/doc/source/images/fractal-example.png create mode 100644 openstack-firstapp/doc/source/images/network-topology.png create mode 100644 openstack-firstapp/doc/source/images/screenshot_webinterface.png create mode 100644 openstack-firstapp/doc/source/images/work_queue.dot create mode 100644 openstack-firstapp/doc/source/index.rst create mode 100644 openstack-firstapp/doc/source/section1.rst create mode 100644 openstack-firstapp/doc/source/section2.rst create mode 100644 openstack-firstapp/doc/source/section3.rst create mode 100644 openstack-firstapp/doc/source/section4.rst create mode 100644 openstack-firstapp/doc/source/section5.rst create mode 100644 openstack-firstapp/doc/source/section6.rst create mode 100644 openstack-firstapp/doc/source/section7.rst create mode 100644 openstack-firstapp/doc/source/section8.rst create mode 100644 openstack-firstapp/doc/source/section9.rst create mode 100644 openstack-firstapp/samples/fog/section1.rb create mode 100644 openstack-firstapp/samples/libcloud/section1.py create mode 100644 openstack-firstapp/samples/libcloud/section2.py create mode 100644 openstack-firstapp/samples/libcloud/section3.py create mode 100644 openstack-firstapp/samples/libcloud/section4.py create mode 100644 openstack-firstapp/setup.cfg create mode 100755 openstack-firstapp/setup.py diff --git a/.gitignore b/.gitignore index cf085844f..789b8cd4a 100644 --- a/.gitignore +++ b/.gitignore @@ -18,3 +18,4 @@ target/ *~ .*.swp .bak +build/ diff --git a/openstack-firstapp/README.rst b/openstack-firstapp/README.rst new file mode 100644 index 000000000..6993bc31f --- /dev/null +++ b/openstack-firstapp/README.rst @@ -0,0 +1,44 @@ +**************************************** +Writing your First OpenStack Application +**************************************** + +This repo contains the "Writing your First OpenStack Application" +tutorial. + +The tutorials works with an application that can be found at: + +https://github.com/stackforge/faafo +-------------------------------- + /bin +-------------------------------- + +This document was initially written in 'sprint' style. +/bin contains some useful scripts for the sprint, such as +pads2files which faciliates the creation of files from +an etherpad server using its API. + +-------------------------------- + /doc +-------------------------------- + +/doc contains a playground for the actual tutorial documentation + +It's RST, built with sphinx. + +The RST source includes conditional output logic, so specifying + +tox -e libcloud + +will invoke sphinx-build with -t libcloud, meaning sections +marked .. only:: libcloud in the RST will be built, while others +won't. + + +sphinx and openstackdoctheme are needed to build the docs + +-------------------------------- + /samples +-------------------------------- + +The code samples provided in the guide are sourced from files +in this directory. There is a sub-directory for each SDK. diff --git a/openstack-firstapp/doc/Makefile b/openstack-firstapp/doc/Makefile new file mode 100644 index 000000000..bf3e803f2 --- /dev/null +++ b/openstack-firstapp/doc/Makefile @@ -0,0 +1,207 @@ +# Makefile for Sphinx documentation +# + +# You can set these variables from the command line. +SPHINXOPTS = +SPHINXBUILD = sphinx-build +PAPER = +BUILDDIR = _build + +# User-friendly check for sphinx-build +ifeq ($(shell which $(SPHINXBUILD) >/dev/null 2>&1; echo $$?), 1) +$(error The '$(SPHINXBUILD)' command was not found. Make sure you have Sphinx installed, then set the SPHINXBUILD environment variable to point to the full path of the '$(SPHINXBUILD)' executable. Alternatively you can add the directory with the executable to your PATH. If you don't have Sphinx installed, grab it from http://sphinx-doc.org/) +endif + +# Internal variables. +PAPEROPT_a4 = -D latex_paper_size=a4 +PAPEROPT_letter = -D latex_paper_size=letter +ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) . +# the i18n builder cannot share the environment and doctrees with the others +I18NSPHINXOPTS = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) . + +.PHONY: help clean html dirhtml singlehtml pickle json htmlhelp qthelp devhelp epub latex latexpdf text man changes linkcheck doctest gettext + +help: + @echo "Please use \`make ' where is one of" + @echo " html to make standalone HTML files" + @echo " dirhtml to make HTML files named index.html in directories" + @echo " singlehtml to make a single large HTML file" + @echo " pickle to make pickle files" + @echo " json to make JSON files" + @echo " htmlhelp to make HTML files and a HTML help project" + @echo " qthelp to make HTML files and a qthelp project" + @echo " devhelp to make HTML files and a Devhelp project" + @echo " epub to make an epub" + @echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter" + @echo " latexpdf to make LaTeX files and run them through pdflatex" + @echo " latexpdfja to make LaTeX files and run them through platex/dvipdfmx" + @echo " text to make text files" + @echo " man to make manual pages" + @echo " texinfo to make Texinfo files" + @echo " info to make Texinfo files and run them through makeinfo" + @echo " gettext to make PO message catalogs" + @echo " changes to make an overview of all changed/added/deprecated items" + @echo " xml to make Docutils-native XML files" + @echo " pseudoxml to make pseudoxml-XML files for display purposes" + @echo " linkcheck to check all external links for integrity" + @echo " doctest to run all doctests embedded in the documentation (if enabled)" + +clean: + rm -rf $(BUILDDIR)/* + +html: + $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html + @echo + @echo "Build finished. The HTML pages are in $(BUILDDIR)/html." + +libcloud: + $(SPHINXBUILD) -t libcloud -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html + @echo + @echo "Build finished. The HTML pages are in $(BUILDDIR)/html." + +openstacksdk: + $(SPHINXBUILD) -t openstacksdk -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html + @echo + @echo "Build finished. The HTML pages are in $(BUILDDIR)/html." + +jclouds: + $(SPHINXBUILD) -t jclouds -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html + @echo + @echo "Build finished. The HTML pages are in $(BUILDDIR)/html." + +fog: + $(SPHINXBUILD) -t fog -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html + @echo + @echo "Build finished. The HTML pages are in $(BUILDDIR)/html." + +dotnet: + $(SPHINXBUILD) -t dotnet -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html + @echo + @echo "Build finished. The HTML pages are in $(BUILDDIR)/html." + +node: + $(SPHINXBUILD) -t node -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html + @echo + @echo "Build finished. The HTML pages are in $(BUILDDIR)/html." + +dirhtml: + $(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml + @echo + @echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml." + +singlehtml: + $(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml + @echo + @echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml." + +pickle: + $(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle + @echo + @echo "Build finished; now you can process the pickle files." + +json: + $(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json + @echo + @echo "Build finished; now you can process the JSON files." + +htmlhelp: + $(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp + @echo + @echo "Build finished; now you can run HTML Help Workshop with the" \ + ".hhp project file in $(BUILDDIR)/htmlhelp." + +qthelp: + $(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp + @echo + @echo "Build finished; now you can run "qcollectiongenerator" with the" \ + ".qhcp project file in $(BUILDDIR)/qthelp, like this:" + @echo "# qcollectiongenerator $(BUILDDIR)/qthelp/FirstApp.qhcp" + @echo "To view the help file:" + @echo "# assistant -collectionFile $(BUILDDIR)/qthelp/FirstApp.qhc" + +devhelp: + $(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp + @echo + @echo "Build finished." + @echo "To view the help file:" + @echo "# mkdir -p $$HOME/.local/share/devhelp/FirstApp" + @echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/FirstApp" + @echo "# devhelp" + +epub: + $(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub + @echo + @echo "Build finished. The epub file is in $(BUILDDIR)/epub." + +latex: + $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex + @echo + @echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex." + @echo "Run \`make' in that directory to run these through (pdf)latex" \ + "(use \`make latexpdf' here to do that automatically)." + +latexpdf: + $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex + @echo "Running LaTeX files through pdflatex..." + $(MAKE) -C $(BUILDDIR)/latex all-pdf + @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex." + +latexpdfja: + $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex + @echo "Running LaTeX files through platex and dvipdfmx..." + $(MAKE) -C $(BUILDDIR)/latex all-pdf-ja + @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex." + +text: + $(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text + @echo + @echo "Build finished. The text files are in $(BUILDDIR)/text." + +man: + $(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man + @echo + @echo "Build finished. The manual pages are in $(BUILDDIR)/man." + +texinfo: + $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo + @echo + @echo "Build finished. The Texinfo files are in $(BUILDDIR)/texinfo." + @echo "Run \`make' in that directory to run these through makeinfo" \ + "(use \`make info' here to do that automatically)." + +info: + $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo + @echo "Running Texinfo files through makeinfo..." + make -C $(BUILDDIR)/texinfo info + @echo "makeinfo finished; the Info files are in $(BUILDDIR)/texinfo." + +gettext: + $(SPHINXBUILD) -b gettext $(I18NSPHINXOPTS) $(BUILDDIR)/locale + @echo + @echo "Build finished. The message catalogs are in $(BUILDDIR)/locale." + +changes: + $(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes + @echo + @echo "The overview file is in $(BUILDDIR)/changes." + +linkcheck: + $(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck + @echo + @echo "Link check complete; look for any errors in the above output " \ + "or in $(BUILDDIR)/linkcheck/output.txt." + +doctest: + $(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest + @echo "Testing of doctests in the sources finished, look at the " \ + "results in $(BUILDDIR)/doctest/output.txt." + +xml: + $(SPHINXBUILD) -b xml $(ALLSPHINXOPTS) $(BUILDDIR)/xml + @echo + @echo "Build finished. The XML files are in $(BUILDDIR)/xml." + +pseudoxml: + $(SPHINXBUILD) -b pseudoxml $(ALLSPHINXOPTS) $(BUILDDIR)/pseudoxml + @echo + @echo "Build finished. The pseudo-XML files are in $(BUILDDIR)/pseudoxml." diff --git a/openstack-firstapp/doc/source/appendix.rst b/openstack-firstapp/doc/source/appendix.rst new file mode 100644 index 000000000..a7bd23370 --- /dev/null +++ b/openstack-firstapp/doc/source/appendix.rst @@ -0,0 +1,54 @@ +======== +Appendix +======== + +Bootstrapping Your Network +-------------------------- + +Most cloud providers will provision all of the required network objects necessary to +boot an instance. An easy way to see if these have been created for you is to access +the Network Topology section of the OpenStack dashboard. + +.. figure:: images/network-topology.png + :width: 920px + :align: center + :height: 622px + :alt: network topology view + :figclass: align-center + +Specify a network during instance build +--------------------------------------- + +.. todo:: code for creating a networking using code + +Requirements of the First App Application For OpenStack +------------------------------------------------------- + +To be able to install the First App Application For OpenStack from PyPi you have to install +the following packages: + +On openSUSE/SLES: + +.. code-block:: shell + + sudo zypper install -y python-devel and python-pip + +On Fedora/CentOS/RHEL: + +.. code-block:: shell + + sudo yum install -y python-devel and python-pip + +On Debian/Ubuntu: + +.. code-block:: shell + + sudo apt-get update + sudo apt-get install -y python-dev and python-pip + +To easify this process you can simply run the following command, which will run the commands above, depending on the used distribution. + +.. code-block: shell + + curl -s http://git.openstack.org/cgit/stackforge/faafo/plain/contrib/install.sh | bash + diff --git a/openstack-firstapp/doc/source/conf.py b/openstack-firstapp/doc/source/conf.py new file mode 100644 index 000000000..f9cfc7eda --- /dev/null +++ b/openstack-firstapp/doc/source/conf.py @@ -0,0 +1,273 @@ +# -*- coding: utf-8 -*- +# +# FirstApp documentation build configuration file, created by +# sphinx-quickstart on Wed Feb 11 12:27:57 2015. +# +# This file is execfile()d with the current directory set to its +# containing dir. +# +# Note that not all possible configuration values are present in this +# autogenerated file. +# +# All configuration values have a default; values that are commented out +# serve to show the default. + +import sys +import os + +import openstackdocstheme + +# If extensions (or modules to document with autodoc) are in another directory, +# add these directories to sys.path here. If the directory is relative to the +# documentation root, use os.path.abspath to make it absolute, like shown here. +#sys.path.insert(0, os.path.abspath('.')) + +# -- General configuration ------------------------------------------------ + +# If your documentation needs a minimal Sphinx version, state it here. +#needs_sphinx = '1.0' + +# Add any Sphinx extension module names here, as strings. They can be +# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom +# ones. +extensions = [ + 'sphinx.ext.todo', + 'sphinx.ext.ifconfig', + 'sphinxcontrib.blockdiag', + 'sphinxcontrib.nwdiag', + 'sphinx.ext.graphviz', + 'sphinx.ext.todo' +# 'oslosphinx', +] + +# Add any paths that contain templates here, relative to this directory. +templates_path = ['_templates'] + +# The suffix of source filenames. +source_suffix = '.rst' + +# The encoding of source files. +#source_encoding = 'utf-8-sig' + +# The master toctree document. +master_doc = 'index' + +# General information about the project. +project = u'FirstApp' +copyright = u'2015, OpenStack Docs Team' + +# The version info for the project you're documenting, acts as replacement for +# |version| and |release|, also used in various other places throughout the +# built documents. +# +# The short X.Y version. +version = '0.1' +# The full version, including alpha/beta/rc tags. +release = '0.1' + +# The language for content autogenerated by Sphinx. Refer to documentation +# for a list of supported languages. +#language = None + +# There are two options for replacing |today|: either, you set today to some +# non-false value, then it is used: +#today = '' +# Else, today_fmt is used as the format for a strftime call. +#today_fmt = '%B %d, %Y' + +# List of patterns, relative to source directory, that match files and +# directories to ignore when looking for source files. +exclude_patterns = ['_build'] + +# The reST default role (used for this markup: `text`) to use for all +# documents. +#default_role = None + +# If true, '()' will be appended to :func: etc. cross-reference text. +#add_function_parentheses = True + +# If true, the current module name will be prepended to all description +# unit titles (such as .. function::). +#add_module_names = True + +# If true, sectionauthor and moduleauthor directives will be shown in the +# output. They are ignored by default. +#show_authors = False + +# The name of the Pygments (syntax highlighting) style to use. +pygments_style = 'sphinx' + +# A list of ignored prefixes for module index sorting. +#modindex_common_prefix = [] + +# If true, keep warnings as "system message" paragraphs in the built documents. +#keep_warnings = False + + +# -- Options for HTML output ---------------------------------------------- + +# The theme to use for HTML and HTML Help pages. See the documentation for +# a list of builtin themes. +#html_theme = 'default' +html_theme = 'openstackdocs' + +# Theme options are theme-specific and customize the look and feel of a theme +# further. For a list of options available for each theme, see the +# documentation. +#html_theme_options = {} + +# Add any paths that contain custom themes here, relative to this directory. +#html_theme_path = [] +html_theme_path = [openstackdocstheme.get_html_theme_path()] + +# The name for this set of Sphinx documents. If None, it defaults to +# " v documentation". +#html_title = None + +# A shorter title for the navigation bar. Default is the same as html_title. +#html_short_title = None + +# The name of an image file (relative to this directory) to place at the top +# of the sidebar. +#html_logo = None + +# The name of an image file (within the static path) to use as favicon of the +# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32 +# pixels large. +#html_favicon = None + +# Add any paths that contain custom static files (such as style sheets) here, +# relative to this directory. They are copied after the builtin static files, +# so a file named "default.css" will overwrite the builtin "default.css". +#html_static_path = ['_static'] + +# Add any extra paths that contain custom files (such as robots.txt or +# .htaccess) here, relative to this directory. These files are copied +# directly to the root of the documentation. +#html_extra_path = [] + +# If not '', a 'Last updated on:' timestamp is inserted at every page bottom, +# using the given strftime format. +#html_last_updated_fmt = '%b %d, %Y' + +# If true, SmartyPants will be used to convert quotes and dashes to +# typographically correct entities. +#html_use_smartypants = True + +# Custom sidebar templates, maps document names to template names. +#html_sidebars = {} + +# Additional templates that should be rendered to pages, maps page names to +# template names. +#html_additional_pages = {} + +# If false, no module index is generated. +#html_domain_indices = True + +# If false, no index is generated. +#html_use_index = True + +# If true, the index is split into individual pages for each letter. +#html_split_index = False + +# If true, links to the reST sources are added to the pages. +#html_show_sourcelink = True + +# If true, "Created using Sphinx" is shown in the HTML footer. Default is True. +#html_show_sphinx = True + +# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True. +#html_show_copyright = True + +# If true, an OpenSearch description file will be output, and all pages will +# contain a tag referring to it. The value of this option must be the +# base URL from which the finished HTML is served. +#html_use_opensearch = '' + +# This is the file name suffix for HTML files (e.g. ".xhtml"). +#html_file_suffix = None + +# Output file base name for HTML help builder. +htmlhelp_basename = 'FirstAppdoc' + + +# -- Options for LaTeX output --------------------------------------------- + +latex_elements = { +# The paper size ('letterpaper' or 'a4paper'). +#'papersize': 'letterpaper', + +# The font size ('10pt', '11pt' or '12pt'). +#'pointsize': '10pt', + +# Additional stuff for the LaTeX preamble. +#'preamble': '', +} + +# Grouping the document tree into LaTeX files. List of tuples +# (source start file, target name, title, +# author, documentclass [howto, manual, or own class]). +latex_documents = [ + ('index', 'FirstApp.tex', u'FirstApp Documentation', + u'OpenStack Doc Team', 'manual'), +] + +# The name of an image file (relative to this directory) to place at the top of +# the title page. +#latex_logo = None + +# For "manual" documents, if this is true, then toplevel headings are parts, +# not chapters. +#latex_use_parts = False + +# If true, show page references after internal links. +#latex_show_pagerefs = False + +# If true, show URL addresses after external links. +#latex_show_urls = False + +# Documents to append as an appendix to all manuals. +#latex_appendices = [] + +# If false, no module index is generated. +#latex_domain_indices = True + + +# -- Options for manual page output --------------------------------------- + +# One entry per manual page. List of tuples +# (source start file, name, description, authors, manual section). +man_pages = [ + ('index', 'firstapp', u'FirstApp Documentation', + [u'OpenStack Doc Team'], 1) +] + +# If true, show URL addresses after external links. +#man_show_urls = False + + +# -- Options for Texinfo output ------------------------------------------- + +# Grouping the document tree into Texinfo files. List of tuples +# (source start file, target name, title, author, +# dir menu entry, description, category) +texinfo_documents = [ + ('index', 'FirstApp', u'FirstApp Documentation', + u'OpenStack Doc Team', 'FirstApp', 'One line description of project.', + 'Miscellaneous'), +] + +# Documents to append as an appendix to all manuals. +#texinfo_appendices = [] + +# If false, no module index is generated. +#texinfo_domain_indices = True + +# How to display URL addresses: 'footnote', 'no', or 'inline'. +#texinfo_show_urls = 'footnote' + +# If true, do not generate a @detailmenu in the "Top" node's menu. +#texinfo_no_detailmenu = False + +# Set to True to enable printing of the TODO sections +todo_include_todos=False diff --git a/openstack-firstapp/doc/source/images/architecture.dot b/openstack-firstapp/doc/source/images/architecture.dot new file mode 100644 index 000000000..2e585e790 --- /dev/null +++ b/openstack-firstapp/doc/source/images/architecture.dot @@ -0,0 +1,9 @@ +digraph { + API -> Database [color=green]; + API -> Database [color=orange]; + Database -> API [color=red]; + API -> Webinterface [color=red]; + API -> "Queue Service" [color=orange]; + "Queue Service" -> Worker [color=orange]; + Worker -> API [color=green]; +} diff --git a/openstack-firstapp/doc/source/images/fractal-example.png b/openstack-firstapp/doc/source/images/fractal-example.png new file mode 100644 index 0000000000000000000000000000000000000000..dd756f3acaefb2094b248df626f0c3cadc7664a4 GIT binary patch literal 61597 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 z zQV$}a*YE8a`iA<)Rr>1Jq|gpqioWe15Ixua0kKZaXRA|{AD92rse`Wx1&4@4H+l4e zeSe;?l`r_b`ptSTa~m=8up`@Q{i=)nu1*tywkr(cgIms^P{%>N9tYz;{Dfvy2 zcMs^>0o3#c#)t!D-6xun45KB5CcQUgtlbp1?ds}V#)$@VeKi7W#5J)XE@EfW(`j-UEKHK*w@@;G;L zKj3D!hP!an15 z3|1Fh{=A6h@|Ei3>e}~bEU@5yh8>+p&Syeii!Q;4Iw^;}(((`kFISyi;u)JZ$4}`@ zvB6yfgycMEr3tn#@G1D52pg^Jc3ad1y4u4N5Y$7%wa3suX{r#o z#Cl!aSe0#m9n?a51Oys|SJ<@9rN{(zJOb!!q4!0yr zuskNF9P@j`(Ojx#@&gAwHH+ zA|DNRYdD{ShvFdH3Yny(DL2Owx8Y_(whnbJQoh-vlkAXN^Nrdj`%bovaHlGZM@dhUGVkba*5QA2v6!$J&K%)AlGgc}REE!-9*A&X zM|Nad($9MZW~!%r!D9Znp>wH}yn(#Sgz`TsNteh$?duC5N;>a{JNERV!pA^-#cpB&`qDi48DAU4o(K#7HeN5P zMc}vl3(D4FNZDX3f70eX=ElTgAXe0_Y{`u4-8s!4T-ehs!-`-;l0lRylgFYKH<$MF z-IuR+#i~-$OzD?k>c?OD$9wU~Ea*$71Ub?ACaC)Iy+b-xb>|4xG#*?bVw~f8i}2z( zD%(Jt9-gp0lgX#ibgwvP)0m+Wor5|Jx-3_l)6Eaw$Ht_GYwma`=Mn;R>9#{CxF|9; zrBOBou5&KA5CGmfw=^@rd7h`Jg0E;pj^l^rO*K&@b>p;)Bz6@D>DRPWkDu}V&0{&U zXn-Hh`X*7}b1`lia11UOw^$UrET8Yfg{7d)_A!5SJIO#(z0_f^dCxVz=YphdJ$Z>1YP2rVTXv4&icw2n4hn1wy)v4PuV~Hke9@H^;4DAG|#mhS4&YPE% zrIujG`dG`(4S+g>$R!?o$?u z56Z7~*zVumHbUP$DU8s_{gm&Iqkz;QS6P zqC}@^NE*-=;tyE0{$*BzY~JzLm32RrEGj+Z%0(|E#nw~luAcZgYj+|QhE@05|JvyLkP8)SN|Y1|J<@R#jJV#S_fh|sy1j?8>V}60`)s0L{NTwRe-p1uMeYA zo67!N9D`v=H${&bOP+JgiP;o1_gm2jNePWf%f-H2UE3G&?&`N#3=U9xSBbf4Kk^+`{3b=`0+$iD*0T+scU3LX&9YZ!%xZdCrG2## zeMsYZlo$8K1`pNCP~ko^MGmS@MGY{D<;mR z4f`-WRyS68C?TGzU(z5@ZPaqHlE)~N%}elhPE$_*t@HkP9UD{^i++An>v>W2>eaX+ zc|yT?pl#Ax(;54;#nWherHr271QToQ&|ai@xWepotG7|Har)>C&J86m@5~Gj=Al7z z<=JSpX0FB)5Zu~=9R5T))_mt`1)1BD&6_b56dK*cMRZ8M%OGEQc%H&X*Jb0bg=_9uVvM9#iq;#ZHpC)qC;e20}Qw?@F zG2ud~RPG9o-XtLHPtoc|ymGJqnLhnCN4XR`eq}DM&(r@b16-6_VFv_7e8)kx5rjJs zd|lpHdev1iTi>(3`aGIlBeE))MU^kVcmypyxcptKU;WE{B*~sd@U4@kdBB(L{`{_- zgx2WalH5uXg)q>q;U*>=^^+myQP0Nx=yaR&CJmClq@rhad9L0?vTnX4)885Is>j9Z zZk@{KC*^Q)2722WhkUX!&Cdy}hBX)UejMRcK4|6}MM;qexQ=r!{@LTH9BX zcTr2mbiPFwy(YRP&!zbqjMt4epX%3sTAue@&AlP3|IzRa)E*avK180prBL`=vZSGR z82uRkdCHwmwnzrk>K{3_>5)(@u$REdgtuqm6hjPT_t8&}<8-YwsPkog&uC>0w8r2T zWJ-GaJmFFz)Y1E>fl5l9}|e#vGZI+@1azKF4GqkKGx{Fe#bQB-(=0{?Dg}m4L_V~|80*md7l046T z*XXs}&ABi{y3=l|D~rC|-fg=TD2tVAkzKYo=&aPA^e`ZIw#cJLT_$$S(xCK5Pa@dz z9T6plu~;V)#}nk*+2v-|V7$8Xev2GSZI5~>UZB4Vop_BY62!Nt!%1`Ms8Z*C{I`7l zBM{Mv1TQ1KMwPl9LKF-{`h2mXJ?Yz}pN2SB*w5Jy##>oL7SH#iQ(iHvxfJ9-t}WA=^d*E#37mEMEOLELA8Ke&%W*en{^=%GxDkW2{% zg3nL0$35NL%xdY%G!Q^$g?0X>`b6-oVLt!7c93l9aO!A7vm~7r_l1B?F-7~frf3=Q zcvgrr-Kn;(^8OPFDJAi~PSu|D15|5Ti%#9e5&AY?<>F%C@=)h;2&UV(_FnF+GKye} zc&pyP11?b4@{w1Yzz%ZbG@#sBmr6{F;kFR^87ZYip$=$MmnM{E>=~v(D=M zsEs<|V$2IH1wDq4DKBB|e5*6!sWItdmKg6|q8;KpR`z3${_i70#^s-C&1ETyPPS2j zFK&JEX`NAhN64mK{^{@czB_N2-Ml5nE%Ed+ z$)zb}{iV&ODiY!IS%FK>)spK_Ip$AWckrQ`A3J zJiH+v_`%w9rY0cd{PxQ}S7Hb_tsk~cQY;%BVx?NKcbaTf_*%S5tFhXUZ+`>3@&n7^ zIsD+~cw_;RZ4_!HqSyzRpr6Q?R$I^8kUG6#d@kCYphQKjvyD8~pO=F?m>W>`hO{1U zCKFg$m2QfVa#|nQlJn+0uVT5D>lfwDcs+9>?Fxow6m1`I6bmTVk24 z>XP|l3fmr0ti{{)ow?D3f!9&G<*t)zTt8FZHIr#|!*rwhO1fmIcP*wH-k&eIu7pYL z76}Lm66u4~i#>-s>y8eiDeq+jk{kv-QRP4kn+_u>LW2suVv=0n^1Ew%iSJZvGGs}H zA!X*ZK22@h1L>!rG8AU{h>$Gaq)q(vsTF+q+UD(W{twj}7t<#%wma(d*qx}e9h*bX z!-O1}C#b3oVv`-%nhFUcC!b1DiH^xPN;JfkQlGZ^sgJC{4JdyJ2uFfn&a8BFPR+MG ziM`H~i_}(1pC2-(?f66|aQ)L(uR%dKF3CO>eJ3EBvBG8QM>nQzgUW~dyum2*`2Dri zBTUcjf$+F(Um$5IBwajo-jsUE&GG6nQ{l~8`L>)05q=kBCXQWiIwMLccQrQ=+?uALW ztk9>ETOT6Q-nkrTzxCFP$g-pQrKdhcokUg7t6kzgHITF#ZBLCI+k=WmOI*t6%twt` zMQ*#8`yJXp`PkbRtqWHDZ?KpgoPE5qcc<$&syZ0IW*R2H&5M$^98+;IJ-~>us&L{# zmcM9Ubi;)==Js9036IGun-I-n&(au0d*`Wb2~Il709TJJG{tqXHI|+3-)y5)=XU&c zG|niATTJquB9+np(w}f zZ)=naP6?NEX_knrUj#KvIMf?IH(;~?ffbgi(9#6YgQ(5zkUyu{@FfI~|whj0$ecNYqp?J8kq6|GUPS z`qeSrxOKKkSf$xxAYwZ<}r&2sJ4Jj?^J(r{aQ)O&t9KS)EQ$w05as( zF(a$g9jKN!Z&YpM5QGttB=qzBRkHnyF=lXDBgr7*V?;EjR7(O!HYy)4E%))ZwPGvS zVTFjq-JlRwdLfWjGaXbTP&zknY_j`gIv;}{&0$4IVDmm(U})RoX2-3XwvWvxuuZ(% zFrsp|s0LiBUG@#!UOms~NY0gsoD+B(>UlxG*M&7c{l|${lki5_Vv6m$P$XY7gN}m2 zIe)bnCD%fiGViU5a3x+_5wj=Tm5W}_*rW(Q8>iV#kI~|ujgEx9bEC%V+q`tzoRdt} z_8zKQQp307nx_74W#W`%XFBn^B<&39&9pBsRb=8^ry`g(#{Hb~ z0QyjkP5z{)(CuFRGZamvE_5Gfz;qBiYtsbx?u@(==Ip zWT#pF8uJM2Z$=wuQ7moNdaTA(T^sgT@i%Fw&@U}x5<=&bF3(RklDuW0ToqJ)lQdL= ziJ&ZTief{$rJj&jd%Say#`XJHHgCQN+dK{%;y2|iT2$uk0YR+`IsDbk-lcHm zd2R=Ux*kV&EHjQXk%G6?J{~@*_m8dNTWrs+qf5XtQmS zHk)xCqNZ}tV@-s{SS(kCS}?g&#cJ2TH8|AJhm0x8@wVk&NN0?w6^HZvoYSM5cl$`e!LYK>izxNmt%h8@P>c47X}X+oNU2 zSrsmfYi&07lUr{Mv8+COWU|&AY%aEsmv+Xktwe1ZkOB_q@<~3;a{5DBC^jxc%BKNEM+WFtrkk!oSuD%=~IvdHJmPd=RdJ8Ku5KqMIJKhWT)HEw zJLgh&hJOL1)2Q-sG)d*iwyEZYq)Cft&CDye?bIx12(WF`X_7`{MvU<7Pw>%z3mI6^ zIW;HQ1>5n=U>5o`+R3wzZDp#U27wPG$aDC8ApB~J?L=z&W;@d7J7Td^m83tuH@JKp zhSjLQqZ|tg5uViX6>*}VjHFX15FEt2E1CK%b8>JKuc<52EXyQQjiPt@n_B<4PvAYD zn4ul_LCWW*cf!9nv;3vrq^V1zNjW}I_4ZGIyJrv%X0tnTpXa3RhXE?yoNDD0!vKNk50SaHd!lcm4=o@qI&Sb3S~4xRyrEa_FNwGa`et-S z@$=FetkxD}A>#>=Qr1~N0_aB^_FV2>il#JxO$+_mVcLgJKqCrX;?`3zPAwa~;B~a^#wed{uc)TIlzjI- zxs5sVZQIFhI4CLDb{!%IL?*A<{|u~6RP%jS)wpqDnvP`XzP4OcU(|Y&_Ee=R6%7EB zARZyaAAM;d?$c(5_)08e#PkxC^EsK@4w3R<6jZ;IugtzvdcN`obl4*{rM+eZpL1!* z`d(ZbPM7CI)Z{LtnZ6(G`#tjE9iFdBQ)_6LeM7{XiVkfy3P0A!IJSm)ncBcAs_%@e zroXNFrNp|-zT6Df%#}aF!Ln2)1p>Jw%D@o=+mn>>hK0`E!O_n1aeNv@FNAnW!&%5& zA9l6v`!dLln6}_jPI6X;Q?`--ca66Z7d#F5PCMC2+3QGNs`@c8GYP2gOC+C#`!6@W zD&ZZ`fb`1FVeqH%CTsWYFmAtNVq7&^ek``_o#grWcZ{M<9{QlCOwYjQ{sJFO#L)PN z{E`MqYwCe4SipQPn}sI*qm@hPJBlz{y8RIzOs>eFdbP2kZ9R9k;6 z(@{%2bdcYOyuNeRPMD2%L$B33GN^1_Ty=KxX^(u-BT$E(R*!!qLYopwU1j)C-J>2s z2@AdePqhay+nYv1e|!1PeJpiN#w#(ojn{!Rm?5*46G*m}H5wahvF5e6c`t-lAJhkP<6lEm)*0gJ}5Y4ELkJ>-gc68CBtcc#R1~$#7WFI zdF}VMW8G`l1HjZi7}4HG6bQ56eHwiN|8cFFV61LQZ~1KYZzjwk=M8y*3CgyvqSLK_ z$)iNEAo07(AUBetXd&Jn3$_z)78$L+0q!J=!~j`r!dr!n*-DISYkDMM)EaLTqIZA2 zl{AUO2}$6!R@fIJB3cW!aXzx!v|LrDh-4YgGER>*ZkCKV+K94Kq>Sg$oYruNO4gXwNyJHzEACT{YhWYQ(PP&j+Vmk zV+<|G)xw;1tQN4Htz{Pbq;1VLa@rF8#Gqt4k!@Wmi2mU45eUhgKVSX$*sRga&LN`l zH$E8%bH#-aDz)S^uDt(wipq68$IfT+2|E^pf~!?3xNR{E_1dMbJx;(eH(44uTBX-7 zp9=(y&245u-+HPZk;KoV4)CdGYOnuGP#9jSKDnmf> zSD>^fopOh%gnqSMHXx|EXmqNWwd=aYT=|188bm+a(HJ8f(ce*hIy*lA*=Tzzj_7M=pXa7yaSP*#q-;kJNn_%Z{7ZI>ru4W z4Q1ewoq0Jk0~df0ywt-XmK1K^_sDILjvn8p=(hB*N(#5&u+`(;AiC*CpsC99y=|1o zPRnUxB{#9~nc$P&zb{x{u}Ou8MBdGCc)MZ}QgJC4wgB-g_DW8TIyK84jsSYYQlaw^ zlXv0_5Bzju;VO5u-2(tHs3N8rh&{hCw7kq#(bSNH=H|-cjBk?*6#F;&m&|=3E~$5> zP=Bq>$iX5T9&ekw30H5D`!urhaVO}|b9E^B1&O0yjCk3Z)`KGeK&Wl#D!q6Ww-8+O{P`V`&ll1 z=Xq~ltYrI}P?fEjg`(1?W^d23F9jMC5g-5Ml?5jL!SN+!aT>pYiFcN2dl{zwtLP8k zX^hNL!|e#yvEw$^xA7I{47c`TdFs3K4M(Y{Zy0{QtCK>;nvElDjy2J=`mh$cKMjae zdmV}zj?^za0uif8&n?tR6>s9F7o?(J5tZw_; zxNN32etGbL74+s>ifm%8DueEJ0Sh^3!9M`(K7gu~3-|{b1oXCL9HJrUkT;|}xcFy? zmG8H%H=W|&rfH!*_*^%_C$Ka(dF!54A?W!^;~a61i~Q;Oh`a?tiz@=Db)t%{JUU_5 z;b{~Zof7@^>vabYrUO}7J!fY1k|10k+GJdk4FtR&>#E;de&H#*fX_wk7T?@mrWJPQ zFZpGpxK$E>ns zlv^|ZJJJBttAjSZhHJ}spn+aLCW7N+Ri}F+m@%WbfgS6LIkCVLPQFHof1A0n=Ib9u zJ=aV9%e1W`&3#CUb3ChS=XgV#@749WqzI?{DeNd;7w-e{D5|I^B}W^0CRWn$@mP!E=VC_n2^<_bzI@){jN*rJ+FC>Vh73 zM(|>z-u`MZH@Pl*@a7k9CZh<9j;c2S?YkI4oFA7NkFXwCwVzgNA5#2&KfMTn}>fAKEi!)5bqRw6~ z8?!&*8l%z)aDNW|Qg`P>cOc#hz{gnUI`PObXbc6I;6HM7ZqCmlE@x~Ho{h=h(-1#k zi{FYuel{I^xQm<$-(|p08R;o^R|c0=&l|P)T}M~_$f%gF0Fb)YhuX~<9nek;bYG#7WG>9R#z84<3UU2?D9=2+>CPPM=3|)EGgyc z&T+DxCCElw;CgwC13YVj%-?G}v#!cSt%YWK^}&D=q<`~E5dyMew-kZT`wBA6hL}!| zPpK4l)bd*^zLvPjQY;>oPm(}qHr6h-GXadXa>KnU)PnzS6VI3ZQxW}*S%t2kTDw0@ zC{`h5GqPox^v;`eu%~SwMuEjYpmgM!0j&R47f*9(!qHt=s!_fW4ayzA^P5nFM8SIk zw>tM18PqnaYJTX|)Zw(t;!?jA)I4X2qtQf}GH2a~VqEzR^r{>-^aJ+rUH>-bB?=wo zPSPYD=S^kcEj_FxlT@9$=)*~ zX+1yU&CHbL%W+KgPNC2>EIpwvRd>%5v^9{{L^^8vZ-s<1Rt5BgCFCHR_ z-)_6C$Up!#wf_a?6#@Wwlx1PQXEsDWALAmYs5#x9jy31)vcINeABg|5wO{&Y6EgeoiN?)#RRn*rlef*Uao~B zKk=&N&>RAz#ZWi5_!liN)`x5tkUTlfxX-<)d%%t3^jnXL)dhhIUzB&yja=bY0Tx0h z6mTv2#P&sLUrWrRSMciEzitUi`BYtPL~uu#PuQ38yZD|9T0g}>imfA@+c;ARcr6Z2 z#ALW8-0KDzx`5F|sDgQHJ5l@sNSU%|_HMmAisQlpkB z0=nAmiE%Lf!c>u{#S@%-tg|2mLc)64?^@TlZfWWFg<6g_)5O}_N?Kifzdblef}ZZq zUMi$Ko3De<<#`>s?5QO4nY*{pK7EeCk7y$t?esiE661VTu$&^LGv`ROTG|&poHegr zvL1=^pGbT$z5Qzc8RY{W>pgjS{S!l}FhlS0nvI2y&RC&?9JCftmMv9>r> zlJZujZ~p!x>pi+cJsuEp7+QtkM(GI7{qYa)N`#%%mqN+R0|V zsFTrmyj4!XL`sr=`|`AFcj_#!tPuWprK;xPqw(8p9c$KlXCff)m(<8LVgFQuZpF_o zj<0TPHhIU}gA%8oW*S=MX49~Yd21)K>|X=_ODLy<&|cIiT4e{9f%H6YbxK9}frz_gs4mi~t7i%oQ4SUY`Ps^*y9$USDazE@L)hLh zI%E99dj;3lApEai$sVM=UdD58aR^#!j>TO!DT28t-Z!R?d3wT7&d~B%EiSv0V4v!d zIyOt8^H!qDSr(o>?M|7%+!KCGEG!1D3SF@`F4~_yf(W)v+JI*w+#=+q_q*?ThP}PM zZ?4?QcMe?RN2Br1rv0{HI9|u6z+RSYGU;wL)7@&8niO*%FrI4^o!HOa#^mX&+X*${ zkH-G)FrhwULylz0XSHDmBfoHWc)oTEJ?o5__<3vBbg89vpL+>0v1eXIYLmpfI+%gC z)}OZrUp%{MXTPpz^0xkNgk+w+l3z!4Ga7wXx5_Mdc&C4!5{L%s6nOS@oMPs!2w9&T zBOSMwD<5iqoQS;hGvynXX~lg@u`c_&)l;z)3@#@-Hh1;nqT~7V5AU1VEC$aYtV@sF zK60yAOr}JBW~nXuyioCOA)p!yk|fy|DxojE-Uz&eewyzq=MU4qnW)bgl={v*Q1b3< z2Qh=`KN;LHB|vqWeO+<3x^D<+&>%8LZZ!u%N=C!hsi@A}1QGgxoZ1mz5?= zM#WguwknqZP80SPiGy8yL6r1IuEeU$uz5K9u?2bYrYX50>o||&wTO8d>PuFFEF1?G zJ)(*i9R=Y5zz>jW#6(>h5prCLy%v$CLxCtR*Y^jB0@<{s^$sF6G#YPy0!g=DiB<7d z#5fu=mbM#FdB#n$YPr2czm2=#W6h<-O#NB;_=*+4y8_skepph0A4WCgVkYWl|5N*T z@3Q0KgfH;A>&6(-!4t5LeU&tvbgg&sRb>{NVs`cVF;m7($x;>`lFtN866W2{@LnpL zUo;`E}{pc-QR?nC;-FO|1TW-osV@I+&3bOI>6m)PlZhSm+LzfD=6`qRf!W+DSXoR-!n4@_PykwL^cZ`ZM{gI%JNmkBtcWF%T)ts>9a73 z1X0!n5But$<@iUFD(?cjdw7U&ay%jeOK99F_pyZ|cCUYHY8fhXhg;U~hzBZH$ zt!2)Rl-lX9V?#l^1Fsg~XQvbE?A&)R{mpYGv2kVx{{FfwQgq4KY*j}@fGu-$UAH7_ zFhE?^4pW6UlhWr*uEEfqzN|_gYT}2+XTJC%65TO7e;xTvY84Z?4edT)@y;n{Hj~#;zivb#ne>H(1tx z?&iyuk6H9UWDACZrA^K0hP;{OA|*NHu`=&syi$UG{Lauc($FjMIj9?P)sRZc@05Xg%QW(#un|#m|k`nZ}KVQU{=Bz9>fh+ zuI_W_8A@7;56Fz;D@Ao>$A3UdUU=$_^EMi3U(Ls{@LV(Vi*fB%NK6Zvdqo@!0BB^} zlqc^fi+o6lA1dZQJkGQ^W;v-1)!RCklX@4_U7Tb)UP%1OwR3uOu*Wm$IyM?TF+Guv zb^A4HRx!u*&rrFipCpxhIYW7>x^o|o29H32S|5!4rKJ`7NkaZhs5aiIp5#& z7i_Pyv(LHDeO=f43hJ94Hwc3gmdO+R-jp6halHxhV$3#BL|clBiMuN`#YfhOXd>oW z5BGn+-{M$$9&S~MUz0;Ox9a_`?umDDrwZgR_Nn(%s7Jl-1JTt|)UfuF%{tfR{3kE}1^X!r_D|~p58=~+H%6*+6igqJ4|1*fWc*M?P%$`J zva04EDsEf$QNu0T)LLLKnOu+0uE=>wf;Z7UOHuG5;Irr(UF|uHw~>dvKd7QnkZ(m@ zjTqF?&$OMjxvZOWhx5ljdsFJdZ4=*@ii`9kG8A_RPYY#TjBYP+iBAqiQbcwPCFOZh zZ9aWpoIhU3?iPf^I`LFY2Qy&S*uzvSxI)F>0?!*R|U`97bNjuA5PLs%u&6&rrW z^unGcHj3DWg|wpq|CD<*144xO+dAgXL}ohg9Ffl2X92}H=}llRA#1kR{7y{OMXvLD zU(Ku^XNInG1j7BwD4>cd!wBYr%<#p7o6QkUktPub#S&AwI?Vm#Zdx=f#Wvr6);`Gf zDF4w97onc{oY-ZG$7A?-HSx;;`J^e#YeB1@dx3+$BQf}6gUeiUTDOAr?n8kS~wAI$i_*s+fOv5NL3ph%&Gc%sIJ4L6Vt+OsMQFus{Y+&p?xiP z;h7|mo60db$U^_m+dPkdb;H_Ro{>ImnQT}(RY)Uh<#!Kbc<8`q(f4~e2UA6T_uU&%G>`DkcJJ4X)^4+)Ic|CGv#QkaM|ht! z_(!~B!4bLv@ns!PpxeSf?2+J4id%(2J|q>?m+tpw;OooJHJWezulYSu?Fv2F{n2s+ zn*Z!#HdCUke)(GJAnqcTUA?ppTCB6tL44m*bVMr}rVY3-glnM?p3kXfOM{*IjvLz| z3mmYkghrFLDZ@`-eLN~tY*2xL$a3dGC3736=RV8zA$|gA9(#DmIT)nl>nt?Gmu$Nv#cOd*mcSbs zY82V4@Y~jbs=vs?jpTf}RUcUN!qt8=Nt&HJBYNFIk_$+PM zv3N1U$#@!@97tPJo5j{#a$b9)JAdMHAQ|Mvw$)WGEufxEF9d>DG&z1QkZ&wPG78-y zdFe?Dj5ql@Za=VT%;)+tMjFI4L7?O%dXuLI_4QSR=0E(SS&Z23y_`{!Nkj^&2H6uk*k1ww=4e{mx+=JF!A*)FADJHWn4WR|2glP1}) zI8eJXlg(O%*PI|1fqXNSd{~a~tOeVM*3L^di)QEV&Zk?`4WC6wK_C@p_{lZBxqvLAwnhR^Kw9VRLI}oNc zR>D9CM;QhhrTClD{e-V-0PGccu-~KD=?4LB8MYdtQ~0mzHOgzse?fBh?|latLbIR{ zSf}@j6Hl5ZY4+L?*m=w70*MTFv!+4%Bq?uv+@JrYep4D*R@c)gvhrj5cI+TG4a1zU z*>TwkM*Vwk63So-9W*?gbDvlpPNiebRbeeSg5Ay~gHM^KBWHsf7Yk|$(!wpro6hVT zX7EA9=Jdut`KWvZK^l{%--XByru|B`L96<}#p_;2ZPgqAfKQk!kz9Z?E*A z;LLY`C_I=+`T7t$d6?&G|FgJ3mb6NhoDHwoQR%D@`)W*%&O5xZfp|pjGqJIfT%AIl zRVh=&IdqqiXBXD#vEnyTMZ?-A7$UKdtnB02a=pT|UTt%c61H-0c+8obpTF_5kb!s2 z{~{nq&$kvm$kluNL<&*p+6Q-W@DsLdVZ_ro^!<~ynnG({|8mz|(8RF0M>vu3Q&mk` z7$?(I4@+grxsM4gm}1pJIWew*uab$KYFedkBDFrvLuXXSv%t=gc40dZ;gK7@U_B=S zsoe+%)hvaB(!xcMb46pHMKs9sylgfal)vjvz&e`RAVE${83U?J8TwGTfpR@D-l$=1 zA;i$C9QJNGGu`yq6UnmM@?bte&_OJ6xW9mmqMALX5gg|1L4KC+dg@zzxOrHQA<2hS-H zG}Mm~#U?F2+s%Ho2(`>G1(-zj{`Y0kq_4&)&8Hpmr_EcPYSqs_>h0=n-qu)W-F>`p zybI;_sKoo(OT6Fx)Wqppsy|plJ-w){V_E+EZzm8N)-UZZaeRp2w+3Iksvr*0qb`5|&$ z%ix8P;_iS~q@LBfzWcb=29u59fzF-(RcKaQ6KXUs_52aO^e*kz-<)#$*BK0HFPy|h zIry=710|1lz;~(St!&7wIQuouK1v*KRo`#MU7xukzxVdY??mnKzx{F zI5~q|BE)y2!7-Dpl0Mr8G2s5%*~W`^SMGyGi6NF2-z2y>xr2-cI^?v&U>{ z02UMX*Ng+>2GLQ0*1DhGDgusDLOzbgX4kp~qI9pCv!!YPt{kmrca*}gZdJD<^?Ye@`2*!yDk<%erM#f-xo~i=SeKwzY_Gy7=}A-+v=nv*^PlF5f(Pd87MFQ9CaYhbwHn8T!*xIJkO%LQ3d*Yh)m0!kz4nmGTY1>T}Jh!FaW8K)f zGZukL-1wRgav^q_%Rk(F-Bs4z1 zl*xB#6-u4TFIshoVUz9W_NbT`S8C8@Z;E=2hI+KKX4^YY*Oe0&cRx8f9Bvd`rUkSZ zvL6(CK@+yzwqpeK0j3QN=K}tlJ-_IW(@K(syv+>UvOSyix&dL4?#{@I^2(f(d$n3{AuAjZXHxLo)_~CWZXV%J#h9Ukk*_l7lLUKJ;_VmPLf&%tWr<$lyk@c+B2c1r^O~Z>4|vZ?3;OQv z#Z4k2!&QVJV1;D*sax!1JopnNz1sTSpy)(REdUxFHxy(SEv-n8^GQr$%Fx&`xu63< z+;UvEg)-W93zbb|L_95MpW_#Zlc)QqtELOwU#3n+Q?_l?SZ}WX??14B#FH;35>x@} zaF92mkMt$;UKZAcyvDq;SR$oS`GTS%1z)wol!)=jr`cyHINla*pb9rsvwhhS?vKx2 zhwoKSi2m^(crL6mGQNu553P)pY})H!`cO_)nDTg@=ABI_KHI?UAc)A&PE)I$zj4K{ z(MW3O?fW_N<=JW&Xg2qmcEb0Q0Y6N4AU2D!z}54iTEepJwW(2ax&wYkWo7b40>y@p zTH1}wHayi$Jnp1<`>Q}O>YBxb?PjPg&}0LS{<~{^Fy3t))R-;RgAVWyl5~<*#pcCV z(LwzljTXO5%HH22G4{blD-tb4pxT}1-wOy;#QZ9b%PT2UA`6NmOx2v_8!XibLC!@iXXlLlgi zO#~|oB1HNym4f@`x*E6<#>(sAg~^j0o20txPgvEv82l9HEZD3L7tkZ4{n$MZtd%|8 zj8oCsr#=Bm&jm)2P>F9!-nX=EezawItx$wbM?-8y0#TKcevoL5;QlynKFH_lMdjX` za)rS13O*b*>x=?8m84I@GatdKj7KAYymeh38NE`2iGBj)cwscROwWSZD1ULohxL9X zXvnmUQ4TgJ(*IdvK&IVC)zDY)k5OHb7@NyMXR+R5a0W+~-qJ^fe5XzqU|G42KIbY# zmFkNYio1i_ci(ksURqA^{H3i?@@q>EQuCBl=#vAY!BZTi2Dh$B3UTdx z+;RStwGg5z1B>HUkJ9q$r{xVRnb)a4w7wd!Fs`!dVD~4k@Di1kRxsJ$?x3*0`lC@- zg75BLyR^mboZ9-74f(!C47~BzQ|e{<^g;;!fRJuE+)U1qs9(q#I8tA9P zYs?>ky}g=vT~g}$xgcB%V?lw^uK60ns*;QNi=#Mke9r2A5I=4P_Ctl~RwUmC-duW9 z5sI$)i=<4?5RndBLAwOh^SmhSu1e2LZMinRA1l8C5^@F`Ho?&@(g@mJf(^%hL6xue z{iF{sCc2L4Nd8>jCvxMwTyLMM<|*Rz)>*>7*7)``gQpcdMK%X;&|dl+Mfc{h&^e-& zWp+R#S$p*(tLcd1d93$7&;>#^Mmi^6@Yb0gzguF8qvEpunQ(S8=VJIFNlIU|%E7IJ zf|-L>%~+_=#Nt%fKGffE=||!o+s!;59$@O(Hp_K=b5CW(kuyh3)e~Z-#)IGty!}&n z%GF-~H8HAWQQ7UMouWTgcW~eS-t#?&?xZllT?2TSh{P7Mou1v;9es31w4U8*31@fa zz=G`euHYsh0>Jq~35d_)bKhM#3+kYw$7ie(Fye*^CZt z1K)V@ElK;O)+zmbP_u7wQ-~4ezLyA#vT?2U8rDb}ge1Pt^jJzJ|J#`RrL14ncE5zj zOEym06Wr*dFw~Z6@_YX5zjNq+mRY`j;E@E6CTbtOIawNB`m(7#3ta8?opTflkbL-e ztXL26k=wUT7(b)4@d#(|D=4ePZv|{Dpx>e$(wT3?hiSI>1)f~0J2;iOfAzS_-_?3| zM$z#;gjD^N^xyL6BolYD;e4yms%@gN21WHKzum;o3mle5LLf6d1XdtpDdRWn9$#0j3iw4W_pt=JY*?h19v)YoD+0iY0r=2%_8_tK9u$j7Tv zfc0Kf`6SqhJ#U&+_Y9_T#^4(gou2+ssWW!2((Dx3e7bXZakGi`wA~`2cy&EW)HyTE zslc{>IwZdSM+(uZd%JS~oD5GH4(@+4l=4DS8oFu@SM_wLy*gGc*o&=$!VToNpC? z^c!60j&iY^wn_qf)SMlThq8)T?UQTCP;EV#sN@OmyPGEQ2Fuaj{3TTWH`Q0m$mNlH z(c7?`%p0fdH7EY$rPkntHDD<&C3bHQH}F{`opuQETM(zFRM?7nx6RrAj{~3GKP$3M z^FGK7Z$GeC%eCRob9hT2t$eEbFBz5dr|}wy@7=oPM9yZ2xlB^Ti@9JW4jUHuTaH8> z73HK{nrXzub1Q`iarYN--KmED=*G;0`Afy#Tgc`U@Zvyxy ztc|V+Og)wCR-)xlE(Sh?ADVF^d&4xhCN1Ze;{n3W$OKer3c4!5D1*#$6)a{#Hahb3 zLV9ZD>)__n2=iftQ7vS)0@Cdco)I_VhlXjz{8BtEAVB(a*%gC)Lz= z6~ImY;~)tj%|32`?SSlQlnUAAyq(5W`PAAVL{gb^NS+Wz>tH|p)x`yOMSyK3B0)5r zGfR;rxUc7xYf`EA#OKo5Sa8wDJ0v@(wZ%amx-zW_B0<8v8wXw;WoWbqCsu2 z2xWzCeAFl?BS&L6AP~&Hz-Roaw&(DQlsiW8yU?54%Uyk6A=_8BJ7Amlw4&HJK@s{K*dM^A2b^0U2wl8atq;)z?c;!0vHe#v<$V0>+&0#xcKL;m$db_tQ3#F zsgkyo|LTnH2^3szoqj zbLG)!YmN5f(eNo;iMlczw5!64O_;>7cd@j3IU_bd1;skRI#&ru6F0#Sv;F?5v2))y z*|bW`aKm&Xc|V{F7;CT&{1z9(tSViuaCi&)%LqSwCQ`hA4lp(!n4a)+K8EZqKnGgVbEH|Qw53e|T{LMR(e*=3!Hf(|V@SSO%WoNUqIxb-#qfy?Rh|Eu^-q10P zCd&nz6Inho2cl&Mv|#7To;AEC@%hKhsMc--sFd%fO1Gmy@jxGAfGxLsSK`c zh}6R$kG%kO;DEqh;aVq*P;Pe*2E2L63q}~h(ozqc? z^^>-74`y7Mw^Bet$F4nXsTZP6f+_4Bxyp8~J(15^a`q&wjB9(bZDSx~mX4Y~UgqiK zq$=?jyHb;V$^OCkx7&8VXj2cX&(8txs`&RBPEwKl0|>aeE0AKA@`laclBNy! z#{+Pm_n(?$Y=H4BZ>41ad?9@{1`4r_6i=<^EYjyyi6!}Ga=iR!%!LN4$*VP7J$B=O z?M6#z+#WOLOg&m}|4e)PgwpmvGDq_s_+LR3PzLho3I(cd-GQO3V~O#Ox?CTV!6hc= z;bPky(pRH5t_yc1BF05HyG2MBbfVQ}zGOrcrCK3g#T7_B2FICH_ey--_F$I64&Ppe zP{uMH$Vww${9-9nH)?3j%X)=00+haI)S92S{UdpeJOY8>d(hFDea#Rh`TIQm3K`-H zS-mo%?$4IGkN`FMC!l8YpJTf$vT!UF{;`!mq>Ba~k3-qkcWgxaP~ro>V#)Jz^zlI^ zPPNG*CH=zp1$~EY-~q(lsuR1N#;VuCe-p)xj3on<`$KUCX>FxnTdaTdGD&T{1IvK! z#tU@%X(=H^##hodSZ^6CAh1M>szR7SaU3ZvH>8EWv{D$M%kp({j3mwPloVmagHipe zzSY4k2aXABz!W~6a#}2X=4Jdd^__8ef^|v|u>&212cva-oyikfL;6%uTBO&#E-DtK z;8S^qg8Y%z2g@vIHwBX^1(J}M+PaEhj8)o0H9~CR(VUm)ZYz$M5>ll>r;?wd=Pk-= ztD%^AUt0_ga`!J)qtO$l_Ty2|ZB$ z+$%U*?`^>MvfKCUbfK}u6^u^p(6V*>iuan_JYTS+xk&hwHeKh;(XXgDMOqE}z)Vo! zWWwC?pu)}9v!ZEgpg~h5x{J>U{sc#svW-QRy%WZ5&6B*f+QWV-@4acDax&C}LB4fC zM4|l=uxDIxHFs#qXYbZ+`sZ)?EagBi;_SGP>UDw_H|OfHpZ4ROCoJ9nsH`}tv;W?! z;cFghvAXjR3zlk!hD`np@LyTV?&pn?!k`FUt{$LHTJEm!aRPRH)-0e=7Z6xVD9)+U zKwFB>t&9?pRvuGkje2`9?5=-o96)bJ6xR2?Pe%0|V&h zTML!k4HWi@(`5UtS=^ZI?FD*yBHjDsv{#}>Mevm79(wx9j+~5xR^LLZ(pOw<3Kd`n zDI77dR5v11=+woi#~aVeFLINr+V!&*gOi{>6#v)AH?@PVA%Mnc$XBdyMZ*i~5X1qi zi&pl%70EE3sliq*lXSBAf zqCsL*mU+sNh9?9FrGgkB+Zdf=KWb2*b8p_aR5r!+Ym1v1+pDGQiL~}ISs?S|Jz9rfiz36>nXg@kd!fvM?0&Wb z`H-Z72|3jFMHIKa_hnz{x4&&9gj6qP1r#g7UyL7jV(juwlB5A)SSPHm_e`^I6o6~T z?I83u3-zY1yCwEYz^kWwwGx$rm<0w9i?$j>$Tnyz%C|Ik3x~=7@@$oQ>Ys2@%>;~a z@ps%zAYGamb@#c$h|`+f-!`=g$(D4P-33Z3n0};Xe^R9j2b8&r8PMa9i|DIZI8orY zRl>P04v@OPUIz)m7iJS3@Dqq_IyAYIahDvxw#FT_1qbCyq&(!g21<#3ba zNZtym%#wjROi(eNk2{tsMuvUVSwiGRJs^_{iko^5RX3o{+zH}j?*iqh+-H-)7n+uM znf=RzY!M39&?JA6lN!jBli`I%X6O|KU$OLJi_}X$7KgvdI89HX`Q6kD3dadfrp?UL z-X9Rm6)k2&lmbso&3~b?^=|88{>)ra2Pz{)ekpQIqZF8*9cuOGv3EnoJbXI!nvXTF za=hNxcJ5Wkw5S+Mk51oHhh2*nuGP)lx&q|z`;jf9bqjt1k9J8R-5lWO`h_ER!+Ds!QveB{LSS zykqOo+`;~HK+o?J-p{ZuZ_*;YKy4tuoNq-z=#h)CkCcD8{N4Fy9=-+FQQ7# z;#KavxnSuoGHsq7|Mn)C%7gZ5spt698hi4cVcUOtisD+loLH!i=!~~J0l&L|>mn+* z_4oP$qpll@Q{|PZA;l@Dj_AVkCD)=em&|Vw+%5OwJkPN}AblBQ((}V{IFJzS-&z`4 zjh;ufC@KrVbabczeaq)l3#vD2p7G|CLjLZS8X#Am&@4v%?t#s^D!kiymy?Qnr2jqi zlsL`HRyIAz5o1jwHhaz+Km>($3E)&+tzIr8u01#Q+Z;)b2%P&ZwnrOm|3Y!J2Bnr= zHVfwsSIWlOkVLo!-zzE2rcv+BN^x5rsC15-p4b$v&L-o3uVfE8Ba>sainglm!V;~8 z^7KX2V%gmGT&7qtwifP4de6#^-ahfIG`@FoMa4hwJ-I~w_x?8yQP=0zfrPPqux9bf zs>`Dw2JJorOS12Lx2*rZ(dt7?KxNwG zJY2_0x%9hTFmm{A<(b+5)4zYHD+BNv|CJAm?F`PZS;>Z(hIdPPfHf8P`DE#G1%M)| zVL@X>JTKRn{7$~?F+O`r$IVBE$6iV>(^+dKWYFJG5!D6`XsiS?&4mkYQ;t>6<~yf( zk?|CysY-4Vm_@SQOc<17PPqt9Tj0CME!SX@S)2t@@$CZzqch5@CaoEPejhNziAkKOLKm*y*QXdC5M^(A)i_;pg z1p<35J9iwydmlLhQ#(N8G`ioA^Bv?0jnkHHFw;6Lm@oaLYU5rgTGnBgdyfB(+X4TJ zeO#d`iKM+PRo8k&(aqq@sx0Z56i>rQX9IV$U9~5S(S4I&8!s@DdC^A4L{NqCV!?t6 zYx)bpWs88;sG7_4b=yShOu3i*SYuUP@fqIknQQNehXX#p?MARHKWbUg!YMrnTWq{s zl)|G)ldZuobb3^DEcw23p!cO;hQD&cm#bz|psXP*prGWyDC5yS60qA|$Zsq^)ho-a z3cb6OpIq)J&rfH23bFHWT~9<-?w6=d!A{uxs*m&|n%WBWh&q^zYSoiG*mBTInsJD! z_zqI$+%yKk`vIAvRk6c~k4>&i>@T@KI%q_Psr*#G&v;a{p#eJwTX7nDOXc6OHAP}h z$+VXMc-0YnBp&6V=Iv|>hqSS@g%~TAIV~@Nk?qvn^wRfihIKI41M`0?;^K(ruHLtK zmVasVUXK%pZZ1uF_|D)EbS-n5c18Gx`~6x}U*COK2dP=ULKIR*cc-TPW~DpTHQFmr zFyLD#y`?h)9HAA0!AP5>66$RA*#6DL`A6$&j}Yt0r`7>&L1BMPP<>7JQo2;XllqE# zcF=CmXKkiSRie~u^x1qpX66(gzK!i}J5*4T>NdB_X66qzG)wT%)i^m!{h-Tz`Du;1 zI%`Ao-fgTO9W5u4VOmXWQg56>yOiKAiLo?<3@y;ooe0!HGN&tEHC4-Es-+zSZd#W@ z{OS$m4A2HIQ@1f?_}+cD8WG6BEcGN--=F&oU||VlA*XAvFPWgUIIKlK$8OtIdq5}cKTL(FdnG?kaV8}AtN)`8AiFB= zb@KI@Drq!!2=*RV#9X#)1NB3(MhrLddY?T{rt87+oNw`L2#$9Y9@pK4Q-W3bZEEdU zsdB$)h%1`3RZ1FW-}$#a6xVrotp=8`mCzO1%K0`$qrTT4PT)vtS%_fxaZWs8;>G?GhW!mV(qnstivEaM&MB=K7NwfLjHj`7Z=*gG=F`rJDCy_4s&KC z$w*K9j<>l%qX7_p{NC!ppn2|_*))Uy6Ex;Z&SZ7gV)(<0{iY%}jf)MN7e!?Q5Ix+a6eon`Yn)=>v$5G=Q|Qd|i#pDtRgJX5^Qz8GuyoMHvNm&? zvXQ|8#pZ`*_G9mZql1!`n0p4_5_E(7>t}Q-Ju9jQr_)y|%ie)7OvN`yBA=Cdv{?#x z#*OO`l7#{nv!IS)T56b}k)C>Ps@pl3S=$e$1~0=GU4~`i^+l$dyVq&VC5&o%FmLm( zc1Y&@jA#J1aT|)E zl9!{oy{#=Gn{$+)34ZI(z*pksRi|m}&B7&aAG6u#ZEc96NAr(nF%~o!*=$s?Uwq{& z{sDk9&Ah%S*CQ7DKFRMXjm7V&Ul_pEBy*}}1^Aw5m3h^j6;x4<;c!kITPENwl`bBR z*_sYCEFp$m(~Gd4d)0c+E7eDCmMewe{ylRm*O5V7Fv7mv3-=x~tjA2#yP-0#$>n@6 z?>Ytd4x-bvmK)kG_2#U;mYy6ii6;F+q(+jL#tEfN9k?dl8cRFLJ-t>>h68|Kh{?z& zJWbUZndY}vTLh$i;mkH2uYjrus}p;I{QRomTWygD8+X2?;o`0Kv{Wl}(0(33M)jhv zXsJZP!;3^Ngt0vuc&;3IIq0!TF1Dh8(Cq50vc7GEr2m16e_{MaHzTmyE+my}I3|j= z)75;d`3GM24yE`p61aCn7BzqTZ~l~jsI?PyeB%5?;BleoM^y6 zF`d4;gnEl7P7N9Ol}&R6%V#LOY2WqjBKgj!_NVML1UvXsX*2V?m3`>*i(P;eew01^ zrf9q}9g^GhmnK)io{=v|#cOS4KZL9L#&tR*;9zUX@n17HvL&u$vye}Lynep zdSw;8oiii|vd8C+B~A~Vy=Z~nA4$AKUkpS^VK(q!G#xv{X4={n*DS1}55z3k zKBz3NVNW#RNnbSg(Cj|I;jB?f( zaifFDna0(eUby^$ehQK-oS(CL!Moaf(f3U?ply?y{Y3kV68}5OmEdaoZ9yBk%S}5LVUS;L??_@$tpB}Y z5-Tr&^l$n1Jy@wyYO#=dB?nqZr9dU|61@TWstSgmP*y9_9*-WP#cwUjI|3nlM0VujoVDVnp zU*I%wfCl|&BP6Il*Dqf#nI63)ucKJ*1&sl zhS1-=dMAQm*MH5&;q|>!6hJnlS#yYjS|%U$7WVWV$gdfmLV08?e9CcDw2`g#lp8hg zVSi*id^N=L5}0+%Ttpqs*Ay?DS=Q?sCyP1BP{;D~eB-ay566)MR-EQ}qNbIWPWbzt z)m8i{FP>>*7K58MjRJ=bK3Ka`Qv2S-THk)-?o&)%U*o+6J7*>z)3r$q{`4|J5G*~U^v2@!N(T`OfrCzG~Zy|&u8i*Z3Sg>+RQOaV^Yk{l3n(N zZ}U_hm}U6suNgXdg{!4Z>K_e%h+(Zu^1|1Te>;zL?9U7otvPz=DCn z@kd+r0N@*E$*PaE=1d9U%gAE&p~CrQwY=c)o&zPr-@CJfHz zvL)PlrFkW%W~mbwMX!&}o_$sHJ8JA%VX+wSM1fYMdj42GlXa?eM|I=E@W}uaZsfN6 zn2`B+5b)B?N47L^TO}*M@6O}gp@HVTnvNPT5|7}ZyY?(hlw8Q`Oy02M;{P`R9D9OB zwJnk>ua7BCnHF#9eQh%(9RRLK9jbxvaP15f5u~=43#$6LnE{DUghMl-S%cbg`w#9T#8}EFoNWG~LTveX6QYSf zZFNs}FZ&MKT)eo&Gs4<+AlH<@(KOWiN0m9dliO|vqnzrH|3R;AT00x#JKrM*#X8tj zl^Ij9QWlo4L7?Yuz7$j5>B)~-sPGGDZR*CqAx#g55M2MPR0+R!ME7nO^vb4ona-kp zNhZ0A*1Q$PoRca9Fm;6c$LJD$(KxRaY4j_8IrN>bPF(3wTgeZB;AS+kpU#u zOHe2KsU7a~SmaHeRhm-_Lfq4K$mkMoT<;q)Po;c!kdps3_XS+a#JI*&xxtRACzrhTYl{XM0g*1= zZZyBu`dA`=_L$iv7&Mv;Cj6Rx6U7FN9DTDwhyJpr`3iU``tm#VJ>c)W^bw|P?-u>0+hu!BVgSCE ztNRUc9u4Rv;9RrHgwqAYcH(Pf08#*0~`48{(2JG>!vT1 z5_9B0k(y*=cG-y}aMVfS2b@Nj8n2-uGe-kHj{NFPIP4OsR`LB}o~&qR#0!?eka4+i zdYk{@P@0cygfPmA6FGWY%55ENEF;jUM)06zRJ<|k+@CZy3%om*#;-=Q5|f6W*RZRK z82P%%A!*jNUgzqNWwMt9y|S6OqrTk~tq=K={TOuq5R{B~pMPzvyGeepBrD-I4rJXQ zhC6=@G&MKw45u<;D(<5w!d*2S#3a-h2|)llWg&~}sp~p_?r#R9dRgWSflu$0!0@gl zF@69xBm4APg+A1I z)*43z{R4)pj~U2NKTe+h=i53CD&m8yy?3_&fe$eO|IkMdZdg<>nTW+{W~u`|JUXZG zasUc54VsutoSvfy<}jB>ds17FbkjNXuH&LC0XxSL^*FP}3b3l-P$E zQGiglGXG&+kaV3g^KRT?d^$Q` z)69q7Yx42wX8`1?5#q5z2jS%_Jf?^Xh*16K!Vuct=6OYp^Yi#M3T1FA(8uVG?W!Vw zF#Lq@o24UB+TS2Q{2hVt-92a}C&Aipq|YCq{J+A_KrWS^67+!^E0cNbghi=TC)p4nUX@tQUpzM^Cu@v`D(Dfv;00a1G!us1xl zd%&nOMP=W(f}oLtG@E>X{(Fc~QQL{0rS4i#osvpKt4^eJrT5~Zgc|%H|2(p;xkdqi zM4CF%<^l`54BOf0bF+QMwO+tuq;rWZp@q*Hky2MsAbKVdyt}37p>){~1ddgt52H3-09cm^Qa2dbh`b0Rr zB@#c@K&q~P3?y?KN7wz?-oMONLhAbsxev3hkzSaLCXr{d(LQOli&?7(Y->jNdR`Z6sd zzXy%O^-c$T(@{rO;bsaO-*+E6AH!S<<*Nfe>ZT2%0eS^cKGD-f?YFK) zEqO?3A;Xq^BfvzqH9{ROWJ2U!XJ||Sanp!XM3Qo5tYGiyiA6*PBx~OPmLmuVj|^z- zdRf`AG;}HpZI7E7^;h3}^^uJ^16OTF{ZbK?@j9ICEvfpvR_V6LtM|!QPKN{bujoI1Sw{9xf{DMjYYWfkTb9GP zX}+Fv=E8u|p8hYzu#6whz@DjpU5xUdP_^GP;K+7*wT_eJibIn9V9TLFO4XG%ro<1} z)FKHzVG|xM)!2b4mm|qwHCGp7T7*_KHMNK3V79P}YEKI0x^pl`BFlRe@Ne5M@a$iG z4tQa6%RQ~{%*CFNQV|kh+PPneQV%AJ7?=ZRNX^JMZaG@z;eR9y{yOv@JaYf6ayz49 zW-fs_bWNo10$p;bcOw9)?8NEjZ1cdvcCFP6%mDzHQ|R}%s? zGR^;}N8~b>X>O=F*Yzu$OsCLf6(vSKGp}K;icpIIoAx}|PIf%-KYMy|&~)8je(NE3 zPac1?5Pp4|&B{+8L4Y~Zne1hBb>!sOG_B~OLN-CS%V3QjXzAgl-QID>73~+{$VWy9 zf3fw-80+E?e>zgVsCv8XUMwRrAWrih9QJ(F6%|vraQG#(Ok$Dd&Np9zRW0M;l+@TH z*YbG7^YkPJ=(^1YW`RCO+L?k%vSt&uVJ)ogPtvQ z`zLdmv>O<{K7R%FLgJlb_E}1xWcz98P`+2iEdGZXV7ha}J;nDs&I?r(`{BBzECBhy z&whA>Hr@LT^%>Y-883c0Y3Ucc#A~Ylr6NwuxplCUCC;K1#rSKDiK>pZq6QAQf00Q^ zs&9~s!rz=vK@4akJtXtnCj@lR_9iUWA8@O&*o^N%HH8I~%K zxbBUGoDEYusVH`~uN3XSx%{yi9*L{KMaRm)f=OR5XF5;E=j78D4m=C#1#8#*WV@ni zugRbG?F{?sp|!ivy=}FJItb~5egVC7xc2|m=`GL=HY{S5WzSkDZ%v~NWx{)@B>_IY|sP7EQO>gLXsHoz&<8<8{Fu=<~Bt3y0W;FFBLG#9OBmjjJ;*6?p7@pAf`zV zpQspRsgK;UeEG%UZ@njAR}Qx>heWd0_0UXMgK?;`5z8vz2yk&*@(_Bmp*MWCy5o?o z=SLRTf5cn?mHzJ|o$2+VnEP$~Qa_0YPi)J)U5k89_m{#McEh-v=mA+sF)7uFDQ`kKL?NxUoQlpTgQ$Ph7IVZ4+ zE3w<+rvi~Q=$cteJ-F0t-S7R-<;|K^p!}5H;x7jEW!+w)RpFGcjGcec&ay;{FMmU1 zDfj;`>a@s!H^sN&pjF&C3er%tVV_N zoLkVa?VW=!y5e2~XhxaI&x39S3!awFq0r7kEnE4k>v@a(Ql-fxz(y^C)h#T8$6gu3 zcs!6@zaC&`a6H5+xId5#{mWls@T`$3qaaO|^xX07U6cBlUh}T)+&wo5j~LKBl^iD2 zmCOq#yh(y=be1yPA7D+G$U;~vdnR#Q4-4_W_zKTaz)SH6DYREaOu0DdGAvI4z_=1% z*$_ndeZ;m9hQbF#VbMC$vvyUlK(7db6}kq;r;@QpFi!x>On#cP0#t*ohx8Up5UiSM z;034tP0RUS?E+YG0L*n(kfO8PA%407-aHB5c@l7-UZb7H*Hc9!Kw$5XS5U%JT!k%3 zP)VQJ&9PQ#Dmg%D^}!i3w~eD9NSAa-H%z29N@6AY$-;XLa4UxLt+63{XP0*lh~EF_v8wm!~PE;T0y%6w{O;BH1o{ zy^m=>Oo^gWvssHT(_7}Bp(I`Xu)v!74HsRM5~5Fj;sWSM2cHfkiDA7g+|aV60KkT< zdJiEngs17*a34L=U7F_f=@wX_v=>LJ<&4hx2IikY={Q-|SYJhL2}k_{WMQ}N9Ph6w z>q7FdzsmpV+y)W-!OPQiJqN9>*ciZ216OlM1buV5aD5)wa@WI&?ln#+ORQ~-o z2ITtMymymQWR3dE0}sIH`T2XgP6-NnU3XT_ZgV367@ce?3H?A)3wI!>UO(A{}`ENpSnIB!~UYyCx*W z27x^5+>Za07R(yMN6%YisQaOQyF0kfKk1=lELH$Y7!rNlW*Rb=@vRysL&^aI84Dbq zP_Jl)SYvJ$$EoOyA)147GC@gZs(;?9j^)3VOkemez%*pZQt-#MFUrKyW|KxhT}G}l ze->Cs(xDxZ0Ay7m2`Bm8+jk3_?#ISMTtncV`^B=Um%E`rTZA=;-pLvjOPAsdBEhH?s-z1dENVpAa)z#Ti22jqGJ;+2?PgydG{abNsr^HMVA8=lCMRK><))zbC76xs07cIW~5l-|u8zQWy)I?E3J zm&pq1K_=L7n&)Aa#eSLtre0~mPNo)m*rw?5A~j=u45Q+J7^itJS!+?AT`htdD-Q8V zi*VkRW0IVvsTg~TL2f>+oNY50A4P~NxOD@42v$9XbEbDs}?>XGl;wq#ysE#6qd zwCbaOO8eNCY`z=dLW?gzgCS9*vg+-}>ZKv=cgY~R1d*&$CK(}4{> z9y@FLMk=Lvj<~Hp);g}pb8HWAn;9krKaI@rYj) zKx}}_iYB#ac%qaj@jYx>CDZ>AMv)yw;va(eDp1-g?WE$daalc4AE>F?p z!|Rz$LFy~Uvi#~oR&<3$5i0*~balt-DV$@NP~iya4E7t;kN>p3OBkqT3<6UhOZ_fKQcSZbxh?0q`C5`u!mf7zk(hp~))ez;|m?=ct=QeHw zTGEc_86uy{ib`Ra?RMkI#!M8UBJF+YeZIy#0I|#2HL#hqnIu#5N8LEimxrZip#jSIVyzV~ubNN)__V0l<7500ECpMmDK4@DYdvJHUIOUgPR=4k?xQSg1 zfssGd83ke0_kaEpPZ;^P^raxDxA!;|rz3LW04G!Kc;EJ^gOq+xT(ZzD`DFq+1~sQA=WDAL3|bcq>l*kk zpn~gafSDC4R?Q07TzwJ3k#28F!@Ssn|JCt}WBjC`t{X0Ji!9U#H#pkYs7puyHC&dd zfn4tI|25ksdY)HQo-;lL?mM%ISi589&!vARc#mbX!Z6$C#e*PGoAK zLvtSk?qvF%BNy1553|aC*4+~R<3CHD|3gse(B*#OKKht! zH&mJO{#M35@2z^bYW=aaV(|px0(!Kr|2Tg9RAR4ln64Kuo#(GL@<~==0J+<`y+}xs zwLe6zdXi8&6J{`^AY0eNfHz0~G`9K)ZI6z>Z6h1Vh9jBCW)iTIf!YL{33vXnc_VLN z#1DrBF@Fww{Q2(_H12LxTb!++X?fVLAH+;>3j#j#_!&-b0wBxXsJyBwh0Di8GXifs zLqsZB;g2zZ?$u=9VjIhb?Q>AYDo`QXb=G9P>nnzL@X*EN)^vrrug^`&D$aBXYZM(G z(I@j7y4!*0f_Rp@=KzdPA|7rm_7NbG+!@{d+$SokzRHX*d8=pH!X#-E6Sqszw1R|70lH|{1RhK`1%;g{aV&`+qq;V0WxwP(Pxczu@IUM{&$TV`q$uOI!$R@vfFZj z>52cY{Bc~IUSo67pZzvTsr$nPox)zs<=&KZ;~7+^bo1EJoYVcjQa*m!O-9%QhBNKg zw;kd=rV`P5_pftL_7lZTEpu8pClH3W=VceIAzD=WAA+QT?1QU|Hz;621lA#LaKS6# zY-@eHO{NCymccklKW`d{{qnnb;s3~?rEUZ8DJ>jXL01O&g>f$Op!s~SZ4wgL>hZpi z3}R*00*QCANkIGw1CDLHsQ$0i)l=fjX5p5cIzIP)}b=RNrUH_ODf{;Mnb3odQ{w?)?LP5 zzm!RBKcS#~0o_aBC6p0*gp4cY_e7>w0cpZ-%%R}Fi_O$h2c={uT)S6$aDtEg37nPa7m4=HV0F%93MxSkYcH-~yW z0r!0oLHuJ-AC&{2Ww2XZxx9)3b%~J+a=6o&VitL7G8lma`GNB$UhVNDzUlr4A&(v3 z3C2W)q9K6bp^KbpfVK2(F8;zlRdCWpYVo6x?$z#oP1ylgS)s~xc6bE` zPd?Hl^T)Imx4)jo!ci=1c&swCvI~1|EJb2ZPVfH)*aM0CbpBR+?_r60f@~-|M4MWd zig(3Ku8H2SEL?Hj*T9ZiA^)IFjdJCTJxoJMr%5fRHgDi7u+FJ9MGr{N9kZ?tU9?5; zwz=BL+l0ug)2n!aPLpdESiHtvU&*}KtCpAL@osiYs7(Ff6OR@pA;6|}?C;=~V29uy z`2KPPXycWn4`L@RaARlXF}@fxUA#P)Y|07bJ{6bszSZfBE+#~vhJAA_HGtCE5%z6& zAiyaF)yY;9if)qmgQn7g=JOB;I{op;0S8d)Dr&Qyc`J zCp>1S0tz>cBeq;8Jpx*kRN1x-?-v1Ow@mz9Nko=J>i%pOzDFq;F!@75NG2QC zc_Ux-DW$=dj!iY%K?)96b+cW7eIySRzP zDZdg8mRnoaESYK@7w4l~R9GapH6uoQ(_Mv4!a6lLakkISdy~8_keluR}a%XX!4$1=`YJiN}_Nh-RoK>YgBsuek=wRUQ|WkPN5Z9APcZX(l!8hw$5WPSFTV>Ra6mAyPC zr)M^j>aEzsA&Zbvs#?Q9Ve)bjr+B8e{%5MtXnxZJ`1eOWttQ1V>&RP50$WMeIr_{t zfmIYMvyT?qFZOGvIl|sb@O)#il6~&Rm1BcoHl?@08$GbEs2Ffr5qQnLvhKgjmjEg< zZNVaZYc%vIm3`VG$V!%M9CM+O<{2H*5FclWCFC1xh{fy{r?8%bZ${nJW-zO#iV4>1 zkDM!56+1geCO82iFVi}_ZZu#;8h3DcIHS7pV^#c7%?tiHS%rxWK zI`HnhV1XBJo+rz{n%m6u+tB!QW{0qHBIu+Q%4$Yq^#9|;b4itUEl_9Dl1a{$U|dLhUKc5Eu9;z74>BNDrnztq7JP10fU9@O_B6VJe=}c>OGqxHmve)u1knj4AXOzqRHW2=F0nLwJg}QXK0uBSb zoGXn_(vvLG_8vj3bKa#A_G+KMI+F>9)P^J}3R-!%vef+Nf(6O=a*nuf`n3?bb}Yuq zoUa~-U^8e4vYQ$R6bkDNGvMoD+w-EDExr){j5nq~S}@82&pO5bnS z!_U;)fi3vz7Z^X2LUf8DD~l&O#X+laVO|AKfj!flFd?fsu2xH_KWt2zEf{+aV|p<4 zC#d!*4bPFvWDIv|>i1bB;>dBII4{##s~KprJ(0hiJWd5Lgc*7N3h}18$~;dQ-&o~- zQ6y*tyhLVbsM5y2zLUQtkr29xvkJ_!8Pz(8`HnQ?VUzjMiV6JrJ3ZpPiNQ{PYFr46HYd8%1JNY}ulQ(Y&Yg`0QY3?_h*tTw`Zv%Nu!gk=@{MxgMc-P~r zG?}Ds)13(sVj#t*``g}QwK(~&E|A<`Q2!UA!sNi~5}PVPCyd(hFaVOF^~=)B8}gr# zjrZA&ZtMq@)*C?q4$icX1keXP3?fYFfo3}cWjEgE;)4cCq1Dw_a}$gs4BbfcqH!NJ zQ{k2bP~Fc^(a8onGhp;3xx=Z^FlHgq6E8g<&tp6vE(I9Ik$JcCjM_SJf=38~{a5XP zp#t_*)3&fjQoVSrcux(G32)S}}s;)LnblMOt*@mT$F_~Z7sdh}U9bU{8$KfD1E znA=l`-ksjTrtzfU3cMJFC0rn8WtylL?UknEDN#~0k9%`y+ZS>ubT9yautBCTO>lL) z1cRC$&mqmXb!6Qjg>;k(5c_j@WP8i)c9qQ9lfPr;t2-7U%aVKRh_P=&L#eLlxs8e;=Mu0Ni3m#Oml4N&wgWiLNf zRt}MwJEhUm2U{wcoazxbJ{bzh8+${vN_c*&Dlqz~=3bxY1pkP?Ugzt@S0`rNg&)7X zljnQRA$|%;+%-SgD4G;iy-&)Bu{L9~c6u#iY0KqW-C-eFT99>bLWkWgj&040QQS;C(V5auy8q8M|wV&%c_*R5RcJ04AF$aPVjuq_b zAVU16;C))8llr={xklcqCV4<7*Mqf7%hInYfdDZ6lF23mOe%E`pSIAG4?v%J{HW@B zHz<&oTkU(ad%oW z154@71VvJ z!)lf5x#3;J|1#o(+Z@gtR^jQ4B(;Beb1_WPrSwn?vu3JhE!`;Y&{;|??z%>@H<4^# zC*@`94oMp)x`Hju4O;D0mjdj^?9E&1%r}CV_dYx`Q~|b%ns6`xP!!XUrm6u31~}_) zmFu+cq4y|7u?d&?#sG~t%iJ3grD{*U^>_>=Qyn{2a#|uz=RI71a8?mU;ar)Uhx0w- zU9~*m!a)O#yxWx{#Nw{OD}g87sjt-k$xh+NwBYhhLGgVhkQcsV3O7I-&r^cA6elA= zV>NLkb2-&dI4lqrTtv-{LkNs7%_IhwM49nQw?_v|ixn0vlqA(3jf;z^)@P=IF1JO>UXk z;KIz&yw<;2%tOx?XR&wFpJHH4`k89e)^gHxV9Za}@xBvY>dm#`Xs2wp^ph8=y!bcQ zWOB5gR3LGA342TvNgo*_kC0c?L6pXn8vXxc79|$eMApQ_UUm4#CbrkydHl@_r}JAa z{Dgf691saV&xdhDe+Ra4d90pd<&h(AIYpXR)Sc=Bnd#lT$HrogOB7ySba?^c5ZE>R zIpfiauG-OeQ09g$L=5$`wl`wlTRVX8;Px?-^Xq|Fa{FDX5APHoyDH+Mv}*I#h&*o{ zM8of(H_tZ3Ph^9yu?gAsMmu8#jj6eq%9acN zoudZgS}CUbNfBO7iR7|mH^&R(h@Lm*PkG!(Xx^vxY-+g#y$Jc%h!y^fzD)3;>+9*z zqF5Oy-$6oJM0N9&J20unLk(8xfns8*^m%&uy>r=o6Vofn9fBaakTi2q$&8RkDNc8Ua1f|G9 zQ2PtBj|3^?5@-tbjkGunmZcJd7}4NdU!4`gzCrX4M1q*|_N$ z*5cR)^{!d}3=f!^NSx{B!-A(JOT9BAn#00gx3!}1YF@_)l^S6#&KRpk>qxv#z+B9q z=KOioOrH+@J1dYoGa=y^xyYmeA2Ngz!#xJv5XgKUl|RmqEt`|yQ-s!ft>Ljv(*`lz z1bDc*Wk{!fH^US}z>4&V_fZn>@yc3mqAsrDn6QZh^dlEesPe4^^t4;Jypty16V2h$ z<`l&t^jGUCjj7)FIoH;E1p$?sV9Ld#f)KwIvD2CbvuqRaaD!HCt-`^s_u~8);#d$y zt#i! z2vYA$jTMqahhCnMBJo*0phgqu_5%AY6hREu%6}IC1rPGki3*qiWZ@m=2y=a&K^*@{z$^$qNh8M^A)nSz{b12h82eAMgBuN3Hkf)hFk23 zg8wZlOQg`54))R@kg0Ho7W{aDe7QS1*Y^qJ1mDZNQZq8U=P$%o36|wS`cnM}3=~+3gK+$L96z82IhzDu{Jm z4TjK#;?tl>0w{~ajii%=7Hv!Rna?;mKCRKEslpzL&)bwvN}Npc9Mg~4`Wy3pNvptd zQ3mftM_oVli*n)4I@I@rNvsStKHHmgr-2`Niy% z(RwgW)ffF1wNC4?E zsj^ejW-ipKGb8+SumKq#xBK(Ae(BRL6?kB-9!Vm5gXl`yweS91L@6?%%82qeB})s&GyL>ZMbLK6xdG zjHle@aWW)EzrwU=TaSkre{}_Bb#6+VR+e?q@?VDWRtk0e=qp&qFE4|jxfz`u(N`7b z42F=kPL}AL4jl?zzF*aSeWg!mq4il+iGdw7kJEFaJvYm^bmzPadZ~o8&`EFRzTQR< z+g-r4NyOuM=yT=@Nl%d?TpuZ`$n2jjr&ly+zYNcO?6Sf zW?7=ucn2rkI{bdW;=3K8trS42^eq_#JAnV_3Bt4{FE1M^SdXC)5%sdl@m(FWX5s`>oYO1B7Db%)z%;WY4ANkF{6BTxvZmVvmslrxS}}c|&6PXovgNIRPX~ zKC)g(Mu5rHfQN3<715j+xV|r65?W^Zov1K>zU)sm`&Ij=GNHkVcBE5&-%<6Sv2z-~ zTB)Zyk1U+Z)PHnOwAVW2d;Qvdtj%(1y|XYb-lUGl_fCySw=>o6ij`n+<*N6%Q&Kd+ zvM6`B;ZE_OE0g~FwDqvY}zE^gbKsz-I&#u#JFCCLFVry!zpB1I32nrd|nAqJa zI)Y|3LGP|kZA;ZfRcbcucE7(J_a?YK%D=VPELKQqUJ{!{z)tP%#~GTMj86Id6C?g{ z#DA`wx?Eo+?mNB-c0%FB#z-KLliq9im4jVrTm8D_*?B85@KMh`eOxtyLu%Ah)Wy&u zmAyJvIH!0=d$77V#n|Q%rI~&Y{Z{8oYk8uZ{J(2Pgw|@MPRP639ce)Z35_A;P$5vz zdss)dTIn?0Xn(G*t+v}e#!OaA_-E^uZA?7yqp!tra*G-pw!gKyqs6obyNyjZPPn3x z`N{RO#S+d!%+|SjZnZ8OMgzJ-OA-09>jVP#cD8vDo69i? z&$-1r((!hQ*XWS7qI7hsB~&j^16+s_%EH~iPM{4cVE(my~Bg6WfH+iBB=(4S~ z{|<(@S3L77H_@^h$%HCs2^yXxcEl|dR1GDOTC{CiW& zS`>lyEveoJs2=zcd%>u?g}pA=Vlo}zd_XD;|S7J6}1QhohykCv{wo62EQGz|{|oe)!sE^Lv zEaRHYuIO`=A<|>$+;!69`o4(xcAy;Cyb7K)ECQ9$HOO;j*6Flvr zJq^5&E|8ClfFB3fUSNp3Dz!LMlj6dkS4G-Hjw?K6dHT336^2vbt1dFLg)wFlN>$q5 zz{0tr-fKkO#RT3v%qf2I*e#MiG58=bgxcoowD`yCzw?1|C2)dH_qz#sh&wiMSRj=p zw(D%=er@*>g>`Kv zYqk=(G;{N|ju?2a_4g<@IWLC}fih~cB!|`Lg^eU9hf`Wpa3$K?kat2rnxL}bCx7i_ zGUgIQ;}AchSTv)1V172`F|(|T+7TlIMmbK0fPTR)wKwcq1O<97y4)_<;kST4ll+wMwOJfv1}Et; z=ISfASN~Ss*hF4Lsbvr&nM#f?Y$#C8J}!)iR-+0A>RjwG9Cd2(uP zSH+r|bE3eH3s-aWuQFq-4mJF~v_z`(tjLD(V&y_AjdAza;z9&0AMh7z%^OJKBzv@i zYl$w^{)AW{6>Pz`3aslb-XcHSC_8>NBO+ z-pRt=>Ta2WwO%w(2EM9dX{61%)+)gG;~!@b6!znal_T^{yH-0F@U{4B=H>M};oI`* zl`~`Rq3zQ(ek?sR-87=8EYzx;w{xshjlW!yx2r6gqy?g}1a=LoConDT+LTxN(_wZH zD43VdacZ~QeidY+e%wDBDYREohLnI3hfUS-8(400&*uc{$4vy)ot>jOUT zF#6ev6gE z)%{uJKbG)ougfbar#S&{WPZ9)MmXF_cUCQ3?OE3;rgL0EWG|YAB2<2r=}FF4Uc*-BN>S8u)bysi z)mz3r$4!-nRfo{Wlsv`zZ4(mK28M^dn?_J>!}b#qI1N;azkc<7E=_kFXSTFr+^P0+ z3X51#75t^aLP6B8IQxGwZ%L%9fAN~`>GO&CrKu-A3h$*cow3`1e;JUj8AZrf5S}m8 zW#w4P$qSI9YvAM%xy~Hdvv~;(?`Jrxu{VlJeqLM?=BGs^ri-y7R)++)R+x=mVdh6+ z>pzf-MZ*!BG5!S?uhDO&J4#KBAU!V&O~t^jVcFMTn_x!`R20xQ3Cyt&=$o1O-9ZK0 zlOD^ig7NFX#ZUo>K^*bGIC*)|jCw?B@7G>Zebd2^-bUP+`98IQhRP)5;iqgh#%P?^+E~4 zfzNOxtk;9NIHx~tmeE&@R3s*^1tcnOuM15#Bu{KXTiiV3?!k7rN~n&cC>aWg=$u4* zJK59lgO7sCyz*yCoGNbF5)%k}?A6hqVg~I-Gm_=YWe7>2{(_y}d1U5$u-ZBKbQoita_8&kU27w5>BcGkJElA&Y}E*+w#IXvXGe~YNWyR# zYj|gA5uKCywy^3R9<`bYSAk}BmW_7<4ZK@ycD0|b=Kd<4-Pf$$`t?xVV!Pe$>i)C; z@W622l4b(S(;IA2O0iK^gLApMc$B+9I7@jGqovkwT!XNlwryav%ieticn1h%uXMmk z!}DpSgbL6ln!bttiv*L_`>nzwyhp;witaJHt2TMaSP;a=oDCGSf3DR1RWOV}JpZq; ze7AL+ho*w&rgU1*=rTBX-f65vrJgj5ca3g`KG3w@G;SFqO`Vzk(skr(uXz)0O&o(7 zlsJo?)I-3X5gun_22tB1v3ieAwy@_HGjI%Y>TdXiiSuv+}c^L82Rzg;lB+K2g?H=s;G5opetBc{4QGT`K_!x*4CrZv8ymR zGs}p3^Mz6zuW6|{6Ytr4p)d8h31Zfdd)p;0wT%vJ@<2Q|?J|J#dFKtyaTCx9WB$u> zYr4i1U>rHS8q?L>FCfC_+e@2D*r&?BsSkd(0OB)x&)u&evf@Hbw5`R!uw=i~`9u|* z7LiOXOc+PP`LDJC>10z(ue-9F4Il7nUJ&23_znuhH-K%r899JEzQ=cZgfz6mE#rx3 zq?x69+p2$VfbWMUVQ&RD1+cCUS_)vd&K1W5jmRGkXC`+eyuVeja*7!mu zaY#Z5+1;TEnW8AUMQhXnXU!AJ?d4a^YSSxOT9O_zWzodcH5c>*NObLfuAFtDP`*_* zd$Wz@CLt%ib5Ea+v6H}G9~yUb!86oi zxCWmyluP$rZ@{A${HWGr8)wnK?4g63ywPQ$0ox>l*!*u;!lS%H6bwK5%7uCFmzWq+ zXB>HqR?TgbhYkqI?m4swp}q`vo7Hrb8xu;IGF3^UaYZ;*@h^9OHu(@DAa7Y#)mIE9 zZt*=`>gW;3d3G~c=<>*n&N=>~-FME2R>oE*E`IvEj71vej5zyUBFYN)U(Pt2iyOl| z-F&Xh*)wCI-Bt3xm{W#dNUxmpbiR!tgdXfZCnu$^h~QI+Gms|+=wMHXS#2+I~WSXyoWO7k6!EEn3Ug~S6>Yq zZD+KRJ0C;(ssFsI6BiIW>Iq2>H$r4;I18RP**z0{7JoJg233R^i6RyGGZvKtYt$RP z(VABYAJuuNE$yey&ezRHvZCb0)IZ=~aT5#ps&zL=R%9sfafE~-ZTe=u!jHRX1I?*a z9Efnmm*Z_tmpxSlQ?w1I+i9W3Kq>y@-J#Dl6?WLZlpIk%i(N%D>Z`PMNdJ4Fa+##A zjpjf=o(Qia^au6lAPdC3fI{zQEPlE{N3fhP_l_8UdoLV5HA=u%feMQ_y!r~*OqX`q zhJy|d_J*%Dun=cm25Dl5O^0dWCv`ZcgPmd)_J)JGcI;$6mM0$mw&n+3jX|v+BEEZs zb)o4a>H}m{ij(Oy{Ctwcf2XF$g4B}zV?Go5cN$Dg@>XgAgO1LA9)#aN{~ABCmF(;? zkd**0ybm&WW5Iv@J%R)jcK(iftL-hU`f{f8lg{3+-bhr_P1q^U^RGwcHUnKT5%osd zHX{<>$XseEj%=kTF3vuFvHhJwR|RQg%8~RO2Q?%lys2UDZ%FT>>A~e<-s#-XTIr_* zp;9Y{@&XdG&tu6*t#Qg`B5z=Jr`!$x^m}qt`V_~>nD{p`dRHb?s`4fdrq-V{NeM)#g5m_h(wN%qq`lmw~7pQz|1xR4> zofGY22kAkCLWvh1!g1>v%FGJ#T(ezaONAt3H0ROrECRqBoj6i#eZ`3wM)Z zc1?ftE>{EU6D7JWPb|-(dH`p#!qWck8<@vndcQtw+IeLj6;8`bkft6h)D3c|_DYO5 zo~KSzuhmno4)>-7{cD=jMXMsux&~`-I+EmPoa<*bMOb(2nB9=_NhEvpzXRKVJ~e*? z77KE?=g{XZMd`PdhZ#z2N3RUd%u)db<-12Z?F)|Qel*y|=tz(C8KA-tXg@uGSg0GO zIkZ2eNzr-r(selY`jYh6TK$A~@89@U<*x_03H@g>UgC%YrB!PBKXfAeHX1iUL*TDV zf4J9|U07JGm(OklXk9r(!|h33jeptC{l?l{)Gsbj3zo+_V!i01u5<3S5@X4r(&!#)elrIJwVesf5Ngq{WO~L<8;1kT~^!-mUjJe+0X6 zh!R`pto^MJ^7h-p`~GXUX^%;Ps$FpxvUW+!A`RI$cAK_#nWOnCe$0LMQT-oX#IL%QY9o~%KbKiXV0^h7GUR^s zZ%y@ptml~!g7VE*20k4{(=8={YBzyJuWqW0Ag{FmP09ZIMPUOG{i)ITM1Kha*tT*#gzNH5(!}jF%cb zC_T$1r+F(Vv02?R0r{a<7xYV5oDUV6I8{XAbJM7&h5U9>vYX+dY*3bSYK-VEIL$rm z)!kTCp3O|k)GpB%b(g`eV42&5i1Mv@5Nbv2vlLBNMmw?BX+cA39L)$5ZmCc=)pUy3 z)5#M;JawinVx&waF*W+AY>_|9O}slT%u70ds`6gBAV0+UV~S(_X?-yc#9H+kobn%m zYH&3!?6$*D3MCu^23v(TY2yp0=oUwC+HM^L+h7xQ_{Ip5^_vcqbOSGQYjD5hyDBepKY2P8m# zJT-Iu?rzenbxo2uF5_^s+(odVR;YA?exj?^UrritjSj29we|}UMw9j&=IRr9 z!%n0oi0L;f$8zj>9p~MISou-mA8A33n9{4E=ihGoGMI~*hUvp~o7^mY0Xfm4}65O1~`RP#tM`vt8NPwA3 z2HR2_=OgpP5ZttgifmdEUNf-VIChK$mLO|3E!r+Pi_z#{J+@vm2z+_%^rI#+;#H{W z-_1+cm5umZ_}DO542W31HHdB~jc%xa1XW~1hhdSlrhR?X%G*4m2% z;Ng)GPf35T$3RXgMw9y+ge25IR^_ee8Xl?~&X9F%YS~_dTqg;+`u!oS2Pl(SzJDr9 zs)h={9+#*n~|;@9oAPfN1aqcX-*FJLF_5W+iw?#*5TV7ucW?{{*1WN zy6Tc%>=DQ}{1kQM<`97A${95a>z_d4cbvwOcOmc}#s#fv*{#h=SkzOUE{>7Y;ksJ^ znCaDd7aM^%p1wx>gv=kWWNHW$=$+e-Fvp}xAZg_U))8%VHS&$6>u=00S2jdV>@zwF z3O!-7-!@JDNrEFzdfnX++A?5D{)X9h-9sbHpkDi3hFrs?=Agu^QLnCbXq=_luelp` zNzBxv7p&N-wj&~=I^vx0Jf=7SGDU17*!7Z|rMJ(~p~6VKVyD+D;9uY+arN1~-=LXQ z+RwFl&Irn$_C_?z>hN}*;(jN<4t6lK=)8ISlR~J3{}Xu{e}jR&>Bk4Sxp&pubPGQR z)mw|98BGW|RD*N;Dl9U_>E=Rsoo-K9R+O+|EV5UuT$B@m)N~Y<=;dmBB+IV>^oV|w z%Ul769hKS9#3R2yj9X@`%2>9WCiPCnf~=BD$#;e712dMnU)PAh^))`vvoZ9Qt9?ix ztqM|c0#{#02|0nkUBs4jZ)zFtg_ytut6K(sf^p9co7@!jrB{huMJunzXgEGF+AKX2 zQDULz?@~)Td+6u$reX=;s=i4>UwpYbCwh?mg~a~?iCLhK32=l;aB@D|?Bke4xzuiJ zno|gYIlRhsY6)-8e>d1NF?#*+<4x0ePmfGXNTT1QW}rJ+C`Z3egsDID(RlE5s!0$} zn)5xkCU^EPw?#3gpW6LH4)CV6d8o$?{x*9CH6N9m+kZC%fN!MA!Hb)`2w)guSikxu zq83C%m=TWlRp^&8v~LKkh+g)X*9i%EZOTZET>B-9Nor`>N+g1f(-Yrg_hNIc?b@7; z<$*#{7U$pXxc%oxDSwyS!;cYECmwCVL5*im0rTq|=2x01q+X510vYs4#eeYMkIba(Z5@9DQZ>_DP_^T;1jO*E6~JR0v9!U*{vA z{uGe2xMsn&8qQC`>-h#kv?XJ&F4w(+u^!2AJPTl;4_2{?_;lGtK*N!K{IrCwZa;#i zQ83=CUTA)S=a#Hjjg-5#SrslkPJM^W-RjNx_`^zlEoYN+Rj_WrLlW!fP01y% z_VD)Lvjfiht94U#SHTEe6T-lOig5A|YxQPACd}ZwaLF@YqY4`ErO+G7WCnp_g#Hu= z86b1d_`Z0BfX3F`KlrCa{H9%?yh4~z_=$hwtJ3LNs$In6h#{Ocvl}znHGKN8zgs{5 zuG2an!M=18iV?H0L>ZHIQ?2%HU}lAFP2Rez%xCjI+tQO}Jc~e|uJv)G!-Xo4BxxNK z<-BIppU&xFV($H!skVZ0`D=(=+uGkg>mPm&eR~ztvU4-F{z z2qO$y!Oluxc{y=mHW$phHH(U59N$b98m4Jb%{ZUFwQHMbe{O9dQFKqZDDd|Jw@gN1 ziP6HXUtuq~nz9_hS#{mN*{~9Ga*)K)8TOH!`$O-wmHK|$q{N!ZQuHwET<~WNol236 zY_>IgT_Av|K(TWY-V#eS<#Jn2Kb+%(rdmkWeGXcSu0=Y@AFMAo$NwVtkQG6y??Y~% z#V35jv{rHCY&`d8&i?j{K7dgj!Wnt>@j0QjfFbR#TMN+47|e#D#rJcBhK}N=ni@Z)Z;B$4(n-a z<=({UZC#f5mn0L9@qNyU6@rxlJCy<*Z!)`tL;W@SyM|3 zWRN8`%*r+fVq4fJT7jxI9V~X!^Qg*@ZKsztgxfL4T8M&de(NXJeh1Y$zhH5yDd5zu zjUyt04`2Z)k2V!XFY6bMmK#%%v-3Iff4w_LFeKlgE4JH(rvt#=9Y%-EB--|A!=cqO zGOcc9jrff4i04sd2hmEqv!6M|JRLj2t*O6(6mA@-K=$=H4G(!iqj+Lfjzha_sjn*8 zJscHiNQl01kv@V1=Gaebt~ms~AU{ynW4R4nQK^wv$+V# za@mhLDtB))a}qTT6kBQ8B8az#8u_rkFN*?14mf{soj%Fu<^Jxh3Gwa2_{W)#1cYTPw@=_quFG9cR*@nM^}i zH^9Af&S9T)bUhpO!sTh||EAD+rWwN{uIi4y7~gK_5&stRTVky7chih?f=R78gf`mE zGSj5c;%>#R`gfnVT`~7y=lNRgW!LN{2min-#lWOgp{WgA z%MPG2XO}%WybYU0+)up{pT|MJMTQ*g4SvWWRCJ%8lsG3xdrnS<>3^s%$B8;6xT+Ky z8-VDd>%uGSXoLZkv-BDJ(%uSKWk&v_X!sJf_~df`YS41$RTGL^?7MnP@+_*s!PeU@ z6}r&R6-vUOPKJJAPbbM*yZ^vbDKNj6Bs7{_>z-|4;NkSqjXyS}s7&2m^q{Lix^=TW zqaE|*0PC7y_-=Z1Pj=gaplI~bs>cuae#jo_=;S6*B(KKl=$D1!C#0m1(W2uY(*|)u zmFb3yp4W>fNw&00%h~13Nk5S|#D~kSYW@-FK<5shPqgeSFhEO*SQu{6ITHU=WlNiG zByD20<|}iMPJ;C#+$w}nNvP$BGOx)lgWF{$`NaU=Q5j33-ij?RJUO}AS8pl=Z?1jb2?KPHT@rAU0E`u_i`TBE2f zVy_xiRMlS9#ww+yt-V`OGqw^`%`|4IQ9$jOD4l=2stdr0l+b23fZ5%@)xR#(^C?E8_ zw{cVHniCgW9VKP@F%d~tLEL<`c1@`UVcR9Ov7Svc6+6~%IO@g67h&=vKE-{uAwQyU zNeNX-l8gH9m^76hNh#V|B|W=0@kYTB?;&1UA2(7P{ncd+WH5L>G7kT^p_TnhZYC>Q zN)Zh(twF6ORYGlFyyE3xxE{kSo&7ek`nJHcEp#yXa^ntd@!|+ z;3%8$N!6N^MZKum&SDPTnBol9dCDf$TX-LX271vkUlc+Z12derYW&f%0SnxL4tH+m z9~C&L${H%YZ=rS;iM6D zC-t)RCH>L|$0sDFMU=T-nc%WT(x+xc4@SK}x+*hwhNKdE212hx3*Y1EviBmkWQ|MU zt5hzC72>;wCJwg~`YUbauxG%C*iz19nG5$&pATAbxEdPXrN3Ur#Pqbgb|$*}6H)${ zY(+e$!cx;}D6MAU+IsgSRR6GnBOTq+_S6C+X+pkka0}Ju3$$nO-3+R;D3E&0>w$+@ zr9opR67$;(5h9SOL*=xh3H=5t>>G=t1z0$zGCw3S}e zVh}HhH(~yO(D-PMEw%P&X&0oA5NeV&WS;=Ne@nbWKWp00bWp5XDWdyieOr*mvZsEG z=h3uMz1MzG$A*mMLIe&)!rcshQ`h3VA&WY6oc7M^OF=X_bsb%1SC5yud&r($4!g%L zJ7jZO_@s#PR&7iFhKfn~#TWHJ0KnKEzket}^>{PUblO)z5DJ3|x zo1HX>xNK2lr@D?2jit)?ABd9RtTQwVa0 z6PK)0FR6uZbfmuFj(HIxAU02Lk{Kw?xCEWd$cD-UkKGi)N%yx1D z6V&={hp(#ztvyD-Fz-BIB3r?HZazL;3i|RJTX+#jOel;;%^+zL*q(Nu-puxN-r*Nl z-JGifJmQLf!Dm+P+QtU!4h3v_4r_D;Q)cB*%H$6vaI}nben-^`okFB7f@hySN1W|K z9E%>>6Hf7(PE_G<#KRrs0SnO04J2;%x*}vgQBo3XgU$_XWfZ+)7ZcQKb9lslaGXaP zjVxL<8tIHPzAA~fx--UO)D7ZNBbzF*bBK4IvBn?Vlx+JOGvFTl!;XuYBoDfR%(o{8 zw%ehsZ>|z+%*3a8%U`rMEiIP1X*5#&i$c~t7Z(uTeQbt`xBkfhIOBqf!cl<}&o^aU zdRfJNoJ;$7x9b`b43>%U(D08Q@$pj2UsCS0``I)W6BQYuBsy*c~@+ zGHD8#S}zvBuZKQjwos7+UrN9Io!O(t{j-BBqu|4h_Y(7=cL$$ln?e7GUAsu+E?siZ zEV=krJt2-fB@iD`JiIq~;ju?oRz%aTa=ziw{rRcbht%>ChO7MO-6UhoIcKithnN7_ z)4CV%O){g$y!{8k-|xL_9Tou+W^%JAK?f4Y%01?(#8^#Z)nuQMr}D8T=EKR^mv`Jj zS7#fNpVnJma=S{UR7T?&?GKhq3uymqi!v9AHM}ibk9sT;(Zl#hpM|!BT17fl<;*R4 zS{1*FObL6~RoO=6YkL%=ppxEN{t|5T{s%E&M(q|sgkOMvjLg7xmzwWRk9O`(bF3 z8}XruxMNxJFFCkl-J2@!R?*eRajuiv_;=Yj38C(A4jNu|IlWUz(=+GR+1Dz$Z$V~|Iwc?Kb~GvVpM2H;83 z@4(orW~A%3laZ_jMoQls-8B~6i%Wg@Wv4<*GMS;M`eu2f$MBDbT2?!Kwnz)?^Q{JG zRxP!Xp7)mPBC@`eyV&xLc+e}i^j~64@@F^GL9I$_#|p!5OD?XEP~y<7%Go8OXnuh^ z$Gvqv($?Nv2nU3_EZt1V(ze8xvjI5z6{$@w*}L^sRG#WPJGR}TzQSjm2K)@giAuuI z>hYnZ#zW(78O@|6-lEt}T?%XaZL&I;2M>NgE>cf+*ew3hAc-wpaN$?`HWezH>ciJ6 z3(&+j>Q~_gk$YE+pA~@cjWIW`umRnEOB9b!6#F%wG^B*{)5k~2EHnvQKbyf8PH~3&{~}=NZR{wx523w zr|03m`wrM|Eifx?Tmt5*jqZ^rBT(L>3gKc6ZvM-!1;zcvI6mF=SN38 zj|O5Z0wtW2uO4?wDlPKf`P!%UZJ|cJf)yHIi6(1sT`U)Ra?@YT@!(5u+{4(ew{o98 zlcIal(dJe(%$7%vpPik)c1)g32bw?bx57}sud8Afh{k7dikuf-ZqUX*+)_&-n>*UX z_BZ>teh_j9y{WP$oOn(=6Le{FF%|-kyyAUzi3>Jv-qGEhb-+L+rTEOvb17Y&d+TdW zX<%^EUp7#39QnRlh_2CcdvkeF$7uM${jB5GMfyN(Baow;5a?KezkJvHn8iQqK?**5*{Y7J;G@1**@*A6%U7aXna?kb zp3|R2*usTD;Utk!_yLtpq6Mv^^p)J7wmk7kmkI?682ypOQ1ds-PYO=UQqLbjipB7g zjI`n!XRSI@u};r-B^om$pCG%a)Zfa@^odc+p$0ynd~0Aaq&ykt%t@nw?f2m2)`!-+ z@3c&TRnfbC%EV)3=V|4)fzjwIX)9HG26}OZ&^je%65}j>x!q|bBGJ2#oaoWP_@K0< zKSpkSul=I7y*cc5iX2){EN2vEN5RN(O?L&1tv()Kyo`CeRA1UduBd1VZxL9)ZD7WO zV`ndadh!OE=DVRhY6(;h~}Jc*UJl z=@CY})oe%lX;1kq{zFChN046xa%-?nCU?HOJn3-r$iJYLy3u`bltJZ?f2Ucnm)@xF zmn12h^uX@pPsnw8)Xn)E@H!oZm}WdP=buH%%=tFa7b{2I{zZZtm|UX9HnKEu_Q7h2 zj-UzYwWZI?=7xj^P>7Y(60o}Elrt))C7#8Yed$X{4_SYu7jfjsYh5U7Ev{hz>C6oN zuCQ;j-T$!nfKV%O;y}6+#wM0Ox6VnDfWchkXEwxpXfb^Z)Kfc_;1>xM$Z*BG3UucyJMl&V2D_+Wep&WQi z_@MO{(hvK5L8pg7$Qo6|>gK*UpYt7`v>rHCjWR{=^l1!#yUY2bZ~V_jtmsKlP=X8w zyd(!z+rQABHV<+4L}op#a{YvI8h!r(#CA~85> z8Bm}{Z3waUaN1DyOGViq&<3b0YgtpF{Xgq4Grr)gG)gI|UFIs#y#2SOf8tzQ=3n5}oE&q=RP-eulII3*`y2$rKQ}%Z&Z61U z9;n>UyTVE3e4z8rx8mLp?$mOlH$9R3Mr)ijC#vk#&Pr{ys!BbIA<4yKD)XQiKLPA< z?CbfpT3|%7@Idv2xfL-x`9f;2C5E*8*oE?SRSG;2MF!@KzZ>-7z)HgacV%|k%;`U>mp;Z)R*Y@=OqwB?=zUIec=6GU*`OaxLmko49!e%X%1@PPzGAovtghH6 z6N@(u-~48@3aU@SzbRb&Ug&vp8UEpswFL9Yg)*-$vYz@r-xHx!<9gI&<0Ctln$JF- ztI>lU+m>-0{yT1Vu^xuOfu6k1vBJ6XHMzn>Na965U-vkuB*B)d2)znVNiGkb*Ed974I z3=4y>Y23Q;GhDfr4Ze%7n!VeyYQ1Vbf8OpZfTJLPx#G3olKLr$ik(B8hHVxZ`5Qv+ zznt1o4^XwkjVfUWF7aaZbbWOU02PEWRXn>DrYCdeVAN!YCBN%VfNgTiSa|dy3$yku z{>&sHl9IO1T2=3vfTbYAe^krH6hm;g5K~6QC5b1Cy;|ah&c^M%6TII+k17>6B9g;R zZg4a~F2zLGZ_rPkFkKV#L5~MseTK?c)2+Du=nf6Kk~fr7VH^Wn$X0)Tw`RAm#ElVl zP2)vpQiED^*P}Pnk04gR5v5RT+(=`PtrhS$b1*(*MrXFwaj<+}R?+-Rq}J69uq2BO z?!ChovBUFQQF-7Wu+SAqyotLF#egfF)=-=e+N5cvmDSxNoAw!nSa&UlN6tD#tIxJ? ziZ4V5`_XT~eo*#h`*GBTPn>0ey&?N@-GvIVX_X8|N_Kz!k-Fbx7S%`gFC41kR9M26 z8EwI3FnTC!+q*td1-ln3$A|F{195+|py?xm)%klp&PqFU-nXmURC3oA|g zXoy>;AltC&3%uTVM##QF;W{#F-gImK)R~w+=__2jha<n*uMoznIYJv3zI( znM_0`{5b6XBMS4(m`|;;56*KZyo=<~5&lAqSfYF%wQ{LaFh&lTYcUY(9>0~g$MewD zFJCd+3uRtO7l)h6mX7QkF_b0xBnpLf9*6|b_O>ziRme4Rm?icRHr*HAA6cZyrS4#(PeCY28f7T>d>tA4rt6YnVPb?@Ubc2)B z?>u(Y&M_6bdpR}rIwmw@EYcyrb9RGAirzOPeWdt^_9Yf&HdIL?DPgj1Wf5| z6|MDGVp+7L$&$zSoxa=>ZM8K{yAR^}V{JUo$n=9uW>#aP;$NOQ_SXqmO!1$sDXQBHEUi*%|Cig;r zZQOh~t>FA?$Vd7qLtvS|4G86DS=FaqSUWRbbWt(d0)t>Vbia!Wk}Br8|3qK(j6&^2 zl~>!70NLr0+vw48^xzI@-)Pp<+`&P9n)W-I=E+V+;g#NtSMKQKR|KHH1N%fOF>#!{ zR^3vpEO>6lib0HVRr-=y<8^VO;+K8juU%qaQme{-c->(Zr9-K7qn(5SjtSQ>wm&gAZ65j zG4kB#3Jpn&U`M2THW?8#h-e)tfL@^kz3`dC961841Bs!a086*sQllY%i$CmIT&JV& zV{h%`+sctq?8EOGWPrs-ZvxEdR**2p4uz99Dy7S#Avg5%5Vz^sErYpWoBv})_FGgHg&(GY*f9G4>L`;edut+xYwx_10UgftL^Zri_Lr8*Q-2NsQ^ zw3=#N(HUyC%@c60*2#*vbPZfWoPEOF(wN++VhB_%5bfe0m#8krK^fUEQ_b{DYo6XL zF5;?PMwtMqq%^Q7jY}x$QF&6y<@cd4Lr>XJx1HL8CW1jMo@4OO3&4atw2>4oN1p+$ z$Rz|8uHX4cc+55}0TYi=uX7^$i0flV?j9FN#Z?D%vEeW$QA;#E+IG2Z0%& z)Vq{z(CN1xulaJ?cV8ywdydnUW_pUB5tX8$pD3*_KIEwqmiRWe#;eBR@~myy2Uq*D<-O5jRui9CVq%J5_!uuH{#mjRP8ikJr6g$}h z)ixGV<4;+|mk~ChAFh01y`|5hT*hJTQ4<>3AbsOuQ0_Q9+FubqQBj|ys2o<|8P-Zw z%1{y}@{xw;5`Pk|upo9t?uQMy&zoR8iq8nrtITb-{=C35m{1znX(dw|<6?jl&=2>j zM1#w!)&J6Nq{m2#aY)=yvYP8;q6K#{0|(Yf(x=Hd|0K<5ibc(j#W=-q$FdLfY& zN0xp9pDzLx<}^6xcu%_EnT;VH#>2y2?SS|wH$71XCYv^w%*%`nl~SCKLb)7Mv1sY} znQ45Sa6J|cwYM#|--*3XVhE*uOS5zCQ=2xEeerOH%GwYTTGwr%KaYIybK9)$L$e=4 zibPz`s|o4TFD_edm4Eg(T*7<7kZxvR7VOtSE;y(V7I&?<79~|FubTt4Y8hwIOqJW- zZ3Ew#8c37beja)fg zQL^=Fy}v3#bd8{_R)3`>z1LeKiQgH4t=?j`fpVJ$Ta*yQhWP>%3Dtkr*l8&Xd<|Gt5;47lADP0{JDZO z%+h(+q3BG(I~P=yArM@gm((p2ADtVuo+D70X>`C#T@Ijq^@J}Yz4p=OhpvJ@Nw=#G zAM3W*FBy?b<3=XQth~Hn&ZpHQ`%i`s7o#5WuRf1&GCF{)Sa??KYEQdwfYWL@RUxXr}3W2>9~# zAzsp}2Pz2YizP;)PD3Vo9B5n*Wf}*!IJ`9&YPc)pW53-A!V72wL{F^R*oDU4z46D! zocw-2>39dZKYE#d;-yx19U+R+TVlN~rpU$JEZ|9T1^+T#ks+=^jxSXbJ`L%q2w%qB z&A0#>svK+mMdy?!yBezd_kIJp!K=H9X{xGvcgb57G?Y3-I*w^bhm@6!{Hc$o74no= z=7hkkciSzi>BB5Z%1wKM4bI|xs}fBqepr<0mO7YkyWv4V!$53%{eP(&PbQg>No3xM$W_)@Wvd zOfm3iQDF#5Y;8{pzKcy;$Cr$0fc^K4t>CYS^sf@Pff*kvl}C19?8(4pDge* zyoX`IH1e5_V`X1SU#^FAlD8e-IVtFb<4gtp3^a6*-4WQ>U09ph5gX0plyNY?YBbla zO3welycz9+$T6JPzM}hH`d+F4%cmc%lJ1*?{T5*>cLq(c9xLwVEd~N|c#U!3`)grk z$aOJSctj%yKdxIp2QaU35#8PX*VGT5L6`H92pq=#9=f);w1w^1t&%#?=vsd7%PExC7m{H;gmWJ#7# z5uq@^JPn`aN6uO4Gj=~$?71W=ASe6eo%{_pXso`81&4 z;o!Ta{&A5mgB5?n{_uOLx|z*wdySFWboX1yh@7IDnm$omD^EsP5}WlVcIwqpUw;sJz(XT$7#XF%pXRtc!*>We zn<}2(PwoK8bqHByd73e{*rBDwgFW!ckM;VOnhhYRZHuW?EdyvyDRzzrWa-w##c{BX5e~rsqsIUN9Ov5rTM`%5 zXO-ovb?A={Pew+Bcg++wXlypkWN_yBf1Z5^E=L7=`xT(19%agZu?K$+Zwt)linWx2 zT&>xH_3qt(Z)R=@e9;wc(Dj`3C7f9sCjG4qw=>ubS+ooPz;9vAHRNsoiIR07(<2POe$D@tFka%6U{z&3d>{^wdyArVF z&Kz&t_qA2~!;8$`50fbaV`WUzdJ1;ql$z)Q6Z}sIEp{z!JJW3n>n}+*)`pDw;f!OS zu-GJEuQfllt4DY8S;gMi)JPk1n@xf0+FE2o|3(+j#Cz2x)g3ps#H;Wh6V9Ml~GMDY!D$dokdoQF4CqvFp>+(ljxEVJ#tg`ixa|@upW6RGO2=cv)KUJCWB=>_>01CeCV4}U5 zb=n}|t^a9&RW2=F*3oR|!~P5LZ9D$^2aDOiylk}%fUfQm&5wI&u`QcEYXGTA7~GTB&Wl~WZ#nN;vOtwJ0_vTeGRqKb5p&<} zcJMbN>+xAtBRNL0fVzF^8BN%*^jU_d@2&K5j7^LSJSO5^bS-sd{g}0TX{g85N_kWw z?RSKnf}L_@2WZrKt~-4yh8pfZ*mlxDUI`BD7v~9&Bh#K81P6lPHuur%77j=At+@v{ zP(_M|#0t>@ttL;D}hAma(yr~YaJ3;&Rdq7^qcFP?E3 zpVpk&MoxCjKbug1j)B%R0*DVLDZkg*NROd<2|!5VF@Qw<)FJq&iWlez={ViNCcje7 zhSe}hlB4 zr#AAjQ?pNHSsty=WC3gI-P6kBiSqs`Fbmus<=>|it5@Z#dP4h`#@Y}OX(X7?M7dM*{u}gJWFNfC4YSJK6$K)+7t`TE`1BBS zV_$n(9Pv0shb)pCH<4RZObgmx1{}B%#t{y$&O?somekN@kSdUbSX)iylIRDy)6e|GIeq&4nx zB}6f%m@5%flk3Qr1~UOi#gzzFDRtxPJG=T*Ow3-M^`=}7ZFuxXn z+D>b3u3wO0wCN3SrwNH^R}@N^Y>EI90MK?jZLVf01jwd)Z*J~bfPqL9CV90A3wx7J zQ)2$+Cj-?;Z1Z2+BrAN1IF%APdk~~@5_^8_5BcdQ!YReSwCf2d>^__%r$>bA0%XyBBkajz@v`lW=-tzigHzQ4#BA3+XR~!TqcqU=*1?xFS0a>5B zcki|a5{W7UU4#01dU|9}cyD{!vXY>nAR*hE9b{TSi~_DLObrmCKqr8O1(gK$qW+TA+&aLGC zvlFKZ`xkxxD&^X2`!73PU8JqrowrHhB9zMi@Qc`2oiY9AffJ^?<-nC~sq8&~ZyPK70h3pSq!nsPfF?r zmrouvC<%Z&0W9YtWnzG8^FOm*vsI#t_x`^jY8d4^_4NM?K{0()3r_#J7o-A@uHzd9 zUK=XliL?@lYm3B>zOu=jfFlH1?{e*vNLMyWkuD)1N#U*Q8hrJ?I+I>CaK{;UwBK?3 z2M^z>C^eLK?<1#xJ_i7(>GhUyUSairfaJ)YtlRbVoO<#9ybdL2MU$JF|5vhsh-Ld7 z9*dOt?F|4p-EKQJIcEb=B2s_{fqrdAx=N=0ub{@NV9zP1sh?5_Rm{|CSr BoKOG& literal 0 HcmV?d00001 diff --git a/openstack-firstapp/doc/source/images/network-topology.png b/openstack-firstapp/doc/source/images/network-topology.png new file mode 100644 index 0000000000000000000000000000000000000000..e427671752a078bff586b9dad4780916c3f20a9b GIT binary patch literal 36223 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®v zKp->7GLu<_YT09&0?wYZ2^=;*nQdeD81mja&aq+04;m5bMj0BvdLmX0Rr97!j3xtx zX*G`#r)GI?OXGZE3gQ|V1yD4mW&LJw<9BK>qm9`jW zzCI@o>{GADh;52b^2HVk8_dHH%>F7_k5ka}BGuF0~iuNn;t(yRD(kr_PG z3KX|}eJF5HrO5vzHH61W>SF6t?5up<8na+WmWs9X6bekyT@DI=!rX}iza>UJdGaZ-!GzU0`H_hteD)4- z1s%*r%FxHTI<($d4K7w73Ka*hR2;PamTtw{>@{huu%8V$yLS+?liwu%X7GhoF5U&^ zSJbnfJrtRSi+ai#;Q(R845|4fB}7PGc|AkS?Ru)S=hnE-xA>Cq){fKx*UYm*s75aL z6$`bYMCvmk2vx{*c*!Zc1C|PkC$U_?n}?Pjku5VKTLuhD{Z#I=e;SHD&7BR8U&BHS zL34>dJJW8xj7`MQn;`JMrczP{>Tp@O;8c9S zfdp9&6`V_Y1z8Ss(kZ)gvPsr1i={H(O)Sdpxf6Wl)Y2abzYN9n?qC7n>aurB#}$;j z_LO>GP?x=gEj~ZlN(qSyJ-2}+&!9?}nqE(1Q|mfFhNISQ%;a}&J3Ova2LEpekT;R|j+8IHH84^Mu1#CCv2e;ikcW3o(CzLjh4oiE>IWE_mwn5ylKR;B ze#~iqCy0JYe?;tVtRp{PbJ6ZiSNnYA-)eF7;xd)pTT)?;WAhQC^ROr{!D<+jiK}g6 z|BR8QT@r>itao^sbME`TT5{nPhqnA_%em%hnlW)Ze7 zm8(PlNlo#A9u6J68SnSFCl)wMtC@KkD)Ux%jdh5whF0e$^h_e%E$`QMcKn4vBm8wP zjIDR$L#`D*D$}E*y3F_=^WYaB6q%DO7TfWX00{Bume!A-K6$~L{|IEh`THu&|I6s+ z{~iq;SiK19SqeFEad7~Fq+x$~a}ysQ|23BHM+aaAYXQqQDXg!rZ&2XAuDJM6!?vub z$ZjQoQ|SGBSufCl8D8gaLihUhWRdoJ0Xce1b`B1c$)cs62)frFzV5D73`ynM>MFkG&UCp1J?^=4XI56$ zOV)2zykIDsT7gA{z{i|ESyjcQsku;8RK!R~Nll%rKnrnL_NBhLx!I#R1r2$hg97_M zxm8tF{_q10vK9I@LVRs+uGUu{Hk|I_;_@1d3cejY)7N2bd)vqfla#d4Xrf?sRd*!_ z27`6L*P#bb$-5rDD{N_L881*ba;i6)U`&@2gM!nChld@W5>br8nc!h|3h=kzqok+L ztE;Q~a&6?|(s0-g5L0T;;{m_nGlRaMmEP*Y5E5nSahcR>!lxYx+S=P+YMw{xTvo?^ z1PJ}i2!O=+-!@=`82gJhd<_16ep@ANzrQ+C@YcQ@12gZD7Q%JcmaBwHsl(~Qy?j0= zLk{2NIlJnw(fYk%Gn&ezPxlDY&bP4`cabNt2?$A=!y_Z9DJlNWy2nRHHoMbfhf{Do z7ZDvTRb6f(!MWmFJ*WAEZzECtgasr#p*+2Von8n@b0zPhyloH4NF6@wJJc8fu;A|Q z?#s)|47W-LUZ1P(M&3F)oV#=RS>O`VVrx=IZF5;#VRWh$u+@=#7iE=G$ba5{m)c(L z07))gs1tTQs5jnfpda2XLq})mN#pH``)!NT zMBh@}<+uC8g>V3-7SNd|%=CEDl5oIS#novC=a5Nn>s7v8Z>JT>>8Y#fZOY`z*l&T) z_mMT6`AI4=Pym>9(2l7QSw;He!TiPCCj2D^1PJu_Cd-YY4m-QLx&n>B@^*J;XSO~w zkK-WT+tw2d3xXEQpH@?IkwKT{+&xhh!S|W%SKAAFqIBnKh&y+4LX!w{{T39IpN(5=HqFFJiEFmyNZJ07wv6zJ>(I z8Na?=cW+F$@bN)ILRY3^2Zqz(!SlqMbQK2rtctV4gVzEHwu)0^j5*~PW-oG%M~RB7 zZUdgS3k{FvoI=|${X8?wawc#{x!&pWwSUl8)4IQ&&{!kkbJ^)lbsQW2lG*2|9T

KixgDRPUMJbQLM_TZ^&D8 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 R_(37~F~glYdH;k<{69+VV!QwV literal 0 HcmV?d00001 diff --git a/openstack-firstapp/doc/source/images/work_queue.dot b/openstack-firstapp/doc/source/images/work_queue.dot new file mode 100644 index 000000000..8a63a79d7 --- /dev/null +++ b/openstack-firstapp/doc/source/images/work_queue.dot @@ -0,0 +1,7 @@ +digraph { + rankdir=LR; + Queue [shape="doublecircle"]; + API -> Queue; + Queue -> "Worker 1"; + Queue -> "Worker 2"; +} diff --git a/openstack-firstapp/doc/source/index.rst b/openstack-firstapp/doc/source/index.rst new file mode 100644 index 000000000..67620f0f4 --- /dev/null +++ b/openstack-firstapp/doc/source/index.rst @@ -0,0 +1,31 @@ +.. FirstApp documentation master file, created by + sphinx-quickstart on Wed Feb 11 12:27:57 2015. + You can adapt this file completely to your liking, but it should at least + contain the root `toctree` directive. + +Welcome to FirstApp's documentation! +==================================== + +Contents: + +.. toctree:: + :maxdepth: 2 + + section1 + section2 + section3 + section4 + section5 + section6 + section7 + section8 + section9 + appendix + +Indices and tables +================== + +* :ref:`genindex` +* :ref:`modindex` +* :ref:`search` + diff --git a/openstack-firstapp/doc/source/section1.rst b/openstack-firstapp/doc/source/section1.rst new file mode 100644 index 000000000..4ee2c3d68 --- /dev/null +++ b/openstack-firstapp/doc/source/section1.rst @@ -0,0 +1,618 @@ +============================ +Section One: Getting Started +============================ + +Who should read this book +------------------------- + +This book has been written for software developers who wish to deploy +applications to OpenStack clouds. + +We've assumed that you're an experienced programmer, but that you haven't +necessarily created an application for cloud in general, or for OpenStack in +particular. + +If you're already familiar with OpenStack, you'll save time learning about the +general concepts, and you'll still find value in learning how to work +programmatically with it's components. + +What you will learn +------------------- + +Deploying applications in a cloud environment can be very different from the +traditional siloed approachyou see in traditional IT, so in addition to learning +to deploy applications on OpenStack, you will also learn some best practices for +cloud application development. Overall, this guide covers the following: + +* :doc:`/section1` - The most basic cloud application -- creating and destroying virtual resources +* :doc:`/section2` - The architecture of a sample cloud-based application +* :doc:`/section3` - The importance of message queues +* :doc:`/section4` - Scaling up and down in response to changes in application load +* :doc:`/section5` - Using object or block storage to create persistance +* :doc:`/section6` - Orchestrating your cloud for better control of the environment +* :doc:`/section7` - Networking choices and actions to help relieve potential congestion +* :doc:`/section8` - Advice for developers who may not have been exposed to operations tasks before +* :doc:`/section9` - Taking your application to the next level by spreading it across multiple regions or clouds + +A general overview +------------------ + +This tutorial actually involves two applications; the first, a fractal +generator, simply uses mathematical equations to generate images. We'll provide +that application to you in its entirety, because really, it's just an excuse; +the real application we will be showing you is the code that enables you to make +use of OpenStack to run it. That application includes: + +* Creating and destroying compute resources. (Those are the virtual machine instances on which the Fractals app runs.) +* Cloud-related architecture decisions, such as breaking individual functions out into microservices and modularizing them. +* Scaling up and down to customize the amount of available resources. +* Object and block storage for persistance of files and databases. +* Orchestration services to automatically adjust to the environment. +* Networking customization for better performance and segregation. +* A few other crazy things we think ordinary folks won't want to do ;). + + +Choosing your OpenStack SDK +--------------------------- + +Future versions of this book will cover completing these tasks with various +toolkits, such as the OpenStack SDK, and using various languages, such as Java +or Ruby. For now, however, this initial incarnation focuses on using Python with +Apache Libcloud. That said, if you're not a master Python programmer, +don't despair; the code is fairly straightforward, and should be readable to +anyone with a programming background. + +If you're a developer for an alternate toolkit and would like to see this book +support it, great! Please feel free to submit alternate code snippets, or to +contact any of the authors or members of the Documentation team to coordinate. + +Although this guide (initially) covers only Libcloud, you actually have several +choices when it comes to building an application for an OpenStack cloud. +These choices include: + +============= ============= ================================================================= ==================================================== +Language Name Description URL +============= ============= ================================================================= ==================================================== +Python Libcloud A Python-based library managed by the Apache Foundation. + This library enables you to work with multiple types of clouds. https://libcloud.apache.org +Python OpenStack SDK A python-based libary specifically developed for OpenStack. https://github.com/stackforge/python-openstacksdk +Java jClouds A Java-based library. Like libcloud, it's also managed by the https://jclouds.apache.org + Apache Foundation and works with multiple types of clouds. +Ruby fog A Ruby-based SDK for multiple clouds. http://www.fogproject.org +node.js pkgcloud A Node.js-based SDK for multiple clouds. https://github.com/pkgcloud/pkgcloud +PHP php-opencloud A library for developers using PHP to work with OpenStack clouds. http://php-opencloud.com/ +NET Framework OpenStack SDK A .NET based library that can be used to write C++ applications. https://www.nuget.org/packages/OpenStack-SDK-DotNet + for Microsoft + .NET +============= ============= ================================================================= ==================================================== + +A list of all available SDKs is available on the +`OpenStack wiki `_. + + +What you need +------------- + +We assume you already have access to an OpenStack cloud. +You should have a project (tenant) with a quota of at least +6 instances. The Fractals application itself runs in Ubuntu, Debian, and Fedora-based and +openSUSE-based distributions, so you'll need to be creating instances using one +of these operating systems. + +Interact with the cloud itself, you will also need to have + +.. only:: dotnet + + `OpenStack SDK for Microsoft .NET 0.9.1 or better installed `_. + .. warning:: This document has not yet been completed for the .NET SDK + +.. only:: fog + + `fog 1.19 or better installed `_ and working + with ruby gems 1.9 + .. warning:: This document has not yet been completed for the fog SDK + +.. only:: jclouds + + `jClouds 1.8 or better installed `_. + .. warning:: This document has not yet been completed for the jclouds SDK + +.. only:: libcloud + + `libcloud 0.15.1 or better installed `_. + +.. only:: node + + `a recent version of pkgcloud installed `_. + .. warning:: This document has not yet been completed for the pkgcloud SDK + +.. only:: openstacksdk + + the OpenStack SDK installed. + .. warning:: This document has not yet been completed for the OpenStack SDK + +.. only:: phpopencloud + + `a recent version of php-opencloud installed `_. + .. warning:: This document has not yet been completed for the php-opencloud SDK + + +You will need the following 5 pieces of information, which you can obtain from +your cloud provider: + +* auth URL +* username +* password +* project id or name (Projects are also known as tenants.) +* cloud region + +You can also get this information by downloading the OpenStack RC file from the +OpenStack Dashboard. To download this file, log into the Horizon dashboard and +click Project->Access & Security->API Access->Download OpenStack RC file. +If you choose this route, be aware that the "auth URL" doesn't include the path. +In other words, if your openrc.sh file shows: + +.. code-block:: bash + + export OS_AUTH_URL=http://controller:5000/v2.0 + +the actual auth URL will be + +.. code-block:: python + + http://controller:5000 + + + +How you'll interact with OpenStack +---------------------------------- + +Throughout this tutorial, you'll be interacting with your OpenStack cloud +through code, using one of the SDKs listed in section "Choosing your OpenStack +SDK". In this initial version, the code snippets assume that you're using +libcloud. + +.. only:: fog + + .. literalinclude:: ../../samples/fog/section1.rb + :start-after: step-1 + :end-before: step-2 + +.. only:: libcloud + + To try it out, add the following code to a Python script (or use an + interactive Python shell) by calling :code:`python -i`. + + .. literalinclude:: ../../samples/libcloud/section1.py + :start-after: step-1 + :end-before: step-2 + +.. only:: openstacksdk + + .. code-block:: python + + from openstack import connection + conn = connection.Connection(auth_url="http://controller:5000/v3", + user_name="your_auth_username", password="your_auth_password", ...) + + +.. Note:: We'll use the :code:`conn` object throughout the tutorial, so ensure you always have one handy. + +.. only:: libcloud + + .. Note:: If you receive the exception :code:`libcloud.common.types.InvalidCredsError: 'Invalid credentials with the provider'` while + trying to run one of the following API calls please double-check your credentials. + + .. Note:: If your provider says they do not use regions, try a blank string ('') for the region_name. + +Flavors and Images +------------------ + +In order to run your application, the first thing you'll need to do is create a +virtual machine, or launch an instance. This instance behaves (for all intents +and purposes) as a normal server. + +In order to launch an instance, you will need to choose a flavor and an image. +The flavor is essentially the size of the instance, such as its number of CPUs, +amount of RAM and disk. An image is a prepared OS instalation from which your +instance is cloned. Keep in mind when booting instances that larger flavors can +be more expensive (in terms of resources, and therefore monetary cost, if you're +working in a public cloud) than smaller ones. + +You can easily find out the images available in your cloud by +running some API calls: + +.. only:: fog + + .. literalinclude:: ../../samples/fog/section1.rb + :start-after: step-2 + :end-before: step-3 + +.. only:: libcloud + + .. literalinclude:: ../../samples/libcloud/section1.py + :start-after: step-2 + :end-before: step-3 + + You should see a result something like: + + .. code-block:: python + + + + +You can also get information on the various flavors: + +.. only:: fog + + .. literalinclude:: ../../samples/fog/section1.rb + :start-after: step-3 + :end-before: step-4 + +.. only:: libcloud + + .. literalinclude:: ../../samples/libcloud/section1.py + :start-after: step-3 + :end-before: step-4 + + This code should produce output something like: + + .. code-block:: python + + + + + + + + +Your images and flavors will be different, of course. + +Choose an image and flavor to use for your first instance. To start with, we +only need about 1GB of RAM, 1 CPU and a GB of disk, so in this example, the +:code:`m1.small` flavor, which exceeds these requirements, in conjuction with +the Ubuntu image, is a safe choice. +The flavor and image you choose here will be used throughout this guide, so you +will need to change the IDs in the following tutorial sections to correspond to +your desired flavor and image. + +If you don't see the image you want available in your cloud, you can usually +upload a new one - depending on your cloud's policy settings. There is a guide +on how to aquire images +`available here `_. + +Set the image and size variables to appropriate values for your cloud. We'll use +these in later sections. + +First tell the connection to retrieve a specific image, using the ID of the +image you have chosen to work with in the previous section: + + +.. only:: fog + + .. literalinclude:: ../../samples/fog/section1.rb + :start-after: step-4 + :end-before: step-5 + +.. only:: libcloud + + .. literalinclude:: ../../samples/libcloud/section1.py + :start-after: step-4 + :end-before: step-5 + + You should see output something like this: + + .. code-block:: python + + + +Next tell the script what flavor you want to use: + +.. only:: fog + + .. literalinclude:: ../../samples/fog/section1.rb + :start-after: step-5 + :end-before: step-6 + + +.. only:: libcloud + + .. literalinclude:: ../../samples/libcloud/section1.py + :start-after: step-5 + :end-before: step-6 + + You should see output something like this: + + .. code-block:: python + + + +Now you're ready to actually launch the instance. + +Booting an instance +------------------- + +Now that you have selected an image and flavor, use it to create an instance. + +.. only:: libcloud + + .. note:: The following instance creation assumes that you only have one + tenant network. If you have multiple tenant networks defined, you will + need to add a networks parameter to the create_node call. You'll know + this is the case if you see an error stating 'Exception: 400 Bad Request + Multiple possible networks found, use a Network ID to be more specific.' + See :doc:`/appendix` for details. + +Start by creating the instance. + +.. note:: An instance may be called a 'node' or 'server' by your SDK. + +.. only:: fog + + .. literalinclude:: ../../samples/fog/section1.rb + :start-after: step-6 + :end-before: step-7 + +.. only:: libcloud + + .. literalinclude:: ../../samples/libcloud/section1.py + :start-after: step-6 + :end-before: step-7 + + You should see output something like: + + .. code-block:: python + + + +.. only:: openstacksdk + + .. code-block:: python + + args = { + "name": "testing", + "flavorRef": flavor, + "imageRef": image, + } + instance = conn.compute.create_server(**args) + +If you then output a list of existing instances... + +.. only:: fog + + .. literalinclude:: ../../samples/fog/section1.rb + :start-after: step-7 + :end-before: step-8 + +.. only:: libcloud + + .. literalinclude:: ../../samples/libcloud/section1.py + :start-after: step-7 + :end-before: step-8 + +... you should see the new instance appear. + +.. only:: libcloud + + .. code-block:: python + + + +.. only:: openstacksdk + + .. code-block:: python + + instances = conn.compute.list_servers() + for instance in instances: + print(instance) + +Before we move on, there's one more thing you need to do. + +Destroying an instance +---------------------- + +It is important to keep in mind that cloud resources (including running +instances you are no longer using) can cost money. Learning to remove cloud +resources will help you avoid any unexpected costs incurred by unnecessary +cloud resources. + +.. only:: fog + + .. literalinclude:: ../../samples/fog/section1.rb + :start-after: step-8 + :end-before: step-9 + +.. only:: libcloud + + .. literalinclude:: ../../samples/libcloud/section1.py + :start-after: step-8 + :end-before: step-9 + + +If you then list the instances again, you'll see that the instance no longer appears. + +Leave your shell open, as you will use it for another instance deployment in this section. + +Deploy the application to a new instance +---------------------------------------- + +Now that you are familiar with how to create and destroy instances, it is time +to deploy the sample application. The instance you create for the app will be +similar to the first instance you created, but this time, we'll briefly +introduce a few extra concepts. + +.. note:: Internet connectivity from your cloud instance is required to download the application. + +When you create an instance for the application, you're going to want to give it +a bit more information than the bare instance we created and destroyed a little +while ago. We'll go into more detail in later sections, but for now, simply create +these resources so you can feed them to the instance: + +* A key pair. In order to access your instance, you will need to import an SSH + public key into OpenStack to create a key pair. This key pair will be installed + on the new instance by OpenStack. Typically, your public key is written to + :code:`.ssh/id_rsa.pub`. If you do not have an SSH public key file, follow + the instructions `here `_ + first. We'll cover this in depth in section 2. + +.. only:: fog + + .. warning:: This section has not been completed + +.. only:: libcloud + + In the following example, :code:`pub_key_file` should be set to the location + of your public SSH key file. + + .. literalinclude:: ../../samples/libcloud/section1.py + :start-after: step-9 + :end-before: step-10 + + :: + + + +* Network access. By default, OpenStack will filter all traffic. You'll need to + create a security group that will allow HTTP and SSH access and apply it to + your instance. We'll go into more detail in section 2. + +.. only:: fog + + .. literalinclude:: ../../samples/fog/section1.rb + :start-after: step-10 + :end-before: step-11 + +.. only:: libcloud + + .. literalinclude:: ../../samples/libcloud/section1.py + :start-after: step-10 + :end-before: step-11 + +* Userdata. During instance creation, userdata may be provided to OpenStack in + order to configure instances after they boot. The userdata is applied to an + instance by the cloud-init service. This service should be pre-installed on + the image you have chosen. We'll go into more detail in section 2. + +.. only:: fog + + .. warning:: This section has not been completed + +.. only:: libcloud + + .. literalinclude:: ../../samples/libcloud/section1.py + :start-after: step-11 + :end-before: step-12 + +Now you're ready to boot and configure the new instance. + +Booting and configuring an instance +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Use the image, flavor, key pair, and userdata to create a new instance. After +requesting the new instance, wait for it to finish. + +.. only:: fog + + .. warning:: This section has not been completed + +.. only:: libcloud + + .. literalinclude:: ../../samples/libcloud/section1.py + :start-after: step-12 + :end-before: step-13 + +When the instance boots up, the information in the ex_userdata variable tells it +to go ahead and deploy the Fractals app. + +Associating a Floating IP for external connectivity +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +We'll cover networking in greater detail in section 7, but in order to actually +see the application running, you'll need to know where to look for it. Your +instance will have outbound network access by default, but in order to provision +inbound network access (in other words, to make it reachable from the Internet) +you will need an IP address. In some cases, your instance may be provisioned +with a publicly routable IP by default. You'll be able to tell in this case +because when you list the instances you'll see an IP address listed under +public_ips or private_ips. + +If not, then you'll need to create a floating IP and attach it to your instance. + +.. only:: fog + + .. warning:: This section has not been completed + +.. only:: libcloud + + Use :code:`ex_list_floating_ip_pools()` and select the first pool of + Floating IP addresses. Allocate this to your project and attach it + to your instance. + + .. literalinclude:: ../../samples/libcloud/section1.py + :start-after: step-13 + :end-before: step-14 + +.. todo:: remove extra blank line after break + + You should see the Floating IP output to the command line: + + :: + + , driver=> + + You can then go ahead and attach it to the instance: + + .. literalinclude:: ../../samples/libcloud/section1.py + :start-after: step-14 + :end-before: step-15 + +Now go ahead and run the script to start the deployment. + +Accessing the application +~~~~~~~~~~~~~~~~~~~~~~~~~ + +Deploying application data and configuration to the instance can take some time. Consider +enjoying a cup of coffee while you wait. After the application has been deployed, you will be able to +visit the awesome graphic interface at the link provided below using your +preferred browser. + +.. only:: libcloud + + .. literalinclude:: ../../samples/libcloud/section1.py + :start-after: step-15 + +.. note:: If you are not using floating IPs, substitute another IP address as appropriate + +.. figure:: images/screenshot_webinterface.png + :width: 800px + :align: center + :height: 600px + :alt: screenshot of the webinterface + :figclass: align-center + +Next Steps +---------- + +Don't worry if you don't understand every part of what just happened. As we move +on to :doc:`/section2`, we'll go into these concepts in more detail. + +* :doc:`/section3` - to learn how to scale the application further +* :doc:`/section4` - to learn how to make your application more durable using Object Storage +* :doc:`/section5` - to migrate the database to block storage, or use the database-as-as-service component +* :doc:`/section6` - to automatically orchestrate the application +* :doc:`/section7` - to learn about more complex networking +* :doc:`/section8` - for advice for developers new to operations +* :doc:`/section9` - to see all the crazy things we think ordinary folks won't want to do ;) + +Full example code +----------------- + +Here's every code snippet into a single file, in case you want to run it all in one, or +you are so experienced you don't need instruction ;) If you are going to use this, +don't forget to set your authentication information and the flavor and image ID. + +.. only:: libcloud + + .. literalinclude:: ../../samples/libcloud/section1.py + :language: python + diff --git a/openstack-firstapp/doc/source/section2.rst b/openstack-firstapp/doc/source/section2.rst new file mode 100644 index 000000000..b5397180d --- /dev/null +++ b/openstack-firstapp/doc/source/section2.rst @@ -0,0 +1,511 @@ +================================================================== +Section Two: Introduction to the Fractals Application Architecture +================================================================== + +This tutorial works with a scalable cloud application that generates +`fractals `_ - beautiful images made +using only mathematics, like the image below. + +.. figure:: images/fractal-example.png + :scale: 50% + :align: left + +This section introduces the application architecture and explains how it was designed +to take advantage of cloud features in general, and OpenStack in particular. +It also provides explanations for some of the commands which were +referenced in the previous section. + +.. todo:: (for Nick) Improve the architecture discussion. + +.. only:: dotnet + + .. warning:: This section has not yet been completed for the .NET SDK + +.. only:: fog + + .. warning:: This section has not yet been completed for the fog SDK + +.. only:: jclouds + + .. warning:: This section has not yet been completed for the jclouds SDK + +.. only:: node + + .. warning:: This section has not yet been completed for the pkgcloud SDK + +.. only:: openstacksdk + + .. warning:: This section has not yet been completed for the OpenStack SDK + +.. only:: phpopencloud + + .. warning:: This section has not yet been completed for the PHP-OpenCloud SDK + + +Cloud application architecture principles +----------------------------------------- + +Cloud applications typically have several design principles in common. +Many of the Fractals application design decisions were motivated by these principles. + +Modularity and Microservices +~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +`Microservices `_ are an important design pattern used +to achieve application modularity. By separating logical application functions into separate services +, maintainance and re-use is more simple. Decoupling components from each other +also makes it easier to selectively scale individual components as required. Further, application modularity +is a required feature of applications which scale out well and are fault tolerant. + +Scalability +~~~~~~~~~~~ + +Cloud applications often make usage of a large number of small instances as opposed to a small number of +large instances. Provided that an application is sufficiently modular, microservices may be easily spread across +as many instances is required. This architecture enables an application to grow past the limit imposed by the maximum +size of an instance. It's like trying to move a large number of people from one place to another; there's only +so many people you can put on the largest bus, but you can use a virtually unlimited number of busses (or even small cars), +providing just as much capacity as you need - and no more. + +Fault Tolerance +~~~~~~~~~~~~~~~ + +In cloud programming, there's a well-known analogy known as "cattle vs pets". If you haven't heard it before, it goes +like this: + +When you're dealing with pets, you name them and care for them and if they get sick, you nurse them back to health. +Nursing pets back to health can be difficult and very time consuming. When you're dealing with cattle, you attach a +numbered tag to their ear and if they get sick you put them down and move on. + +That, as it happens, is the new reality of programming. Applications and systems used to be created on large, expensive +servers, cared for by operations staff dedicated to keeping them healthy. If something went wrong with one of those +servers, the staff's job was to do whatever it took to make it right again and save the server and the application. + +In cloud programming, it's very different. Rather than large, expensive servers, you're dealing with virtual +machines that are literally disposable; if something goes wrong, you shut it down and spin up a new one. There's +still operations staff, but rather than nursing individual servers back to health, their job is to monitor the +health of the overall system. + +There are definite advantages to this architecture. It's easy to get a "new" server, without any of the issues +that inevitably arise when a server has been up and running for months, or even years. + +As with classical infrastructure, failures of the underpinning cloud infrastructure (hardware, networks, and software) are unavoidable. When you're +designing for the cloud, it's crucial that your application is designed for an environment where failures +can happen at any moment. This may sound like a liability, but it's not; by designing your application with a high +degree of fault tolerance, you're also making it resilient in the face of change, and therefore more adaptable. + +Fault tolerance is essential to the cloud-based application. + +Automation +~~~~~~~~~~ + +If an application is meant to automatically scale up and down to meet demand, it is not feasible have any manual +steps in the process of deploying any component of the application. +Automation also decreases the time to recovery for your application in the event of component failures, increasing +fault tolerance and resilience. + +Programatic Interfaces (APIs) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Like many cloud applications, the Fractals app has a `RESTful API `_. +You can connect to it directly and generate fractals, or you can integrate it as a component of a larger app. +Any time a standard interface such as an API is available, automated testing becomes much more feasible, +increasing software quality. + +Fractals app architecture +------------------------- + +As you will see below, the Fractals app was designed with the principles of the previous subsection in mind. +You'll note that in :doc:`section1` we deployed the app in an all-in-one style, on a single virtual machine. +This isn't good practice, but as the app uses microservices to decouple logical application functions, we can +change this easily. + +.. graphviz:: images/architecture.dot + +Message queues are used to facilitate communication between the Fractal app +services. The Fractal app uses a so-called +`work queue `_ (or task queue) to distribute +tasks to the worker servies. + +Message queues work in a way similar to a queue (or a line, for those of us on the other side of the ocean) in a bank being +served by multiple clerks. The message queue in our application +provides a feed of work requests that can be taken one-at-a-time by worker services, +whether there is a single worker service or hundreds of them. + +This is a `useful pattern `_ for +many cloud applications that have long lists of requests coming in and a pool of resources +from which to service them. This also means that a worker may crash and the tasks will be +processed by other workers. + +.. note:: The `RabbitMQ getting started tutorial `_ provides a great introduction to message queues. + +.. graphviz:: images/work_queue.dot + +The worker service consumes messages from the work queue and then processes +them to create the corresponding fractal image file. + +Of course there's also a web interface which offers a more human friendly +way of accessing the API to view the created fractal images, and a simple command line interface. + +.. figure:: images/screenshot_webinterface.png + :width: 800px + :align: center + :height: 600px + :alt: screenshot of the webinterface + :figclass: align-center + + +There are also multiple storage backends (to store the generated fractal images) and a database +component (to store the state of tasks), but we'll talk about those in :doc:`/section4` and :doc:`/section5` respectively. + +How the Fractals app interacts with OpenStack +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. todo:: Description of the components of OpenStack and how they relate to the Fractals app and how it runs on the cloud. + TF notes this is already covered in the guide, just split across each section. Additing it here will force the + introduction of block storage, object storage, orchestration and neutron networking too early, + which could seriously confuse users that don't have these services in their cloud. Therefore, this should not b + done here. + + +The Magic Revisited +------------------- + +So what exactly was that request doing at the end of the previous section? +Let's look at it again. (Note that in this subsection, we're just explaining what +you've already done in the previous section; you don't need to execute these commands again.) + +.. only:: libcloud + + .. literalinclude:: ../../samples/libcloud/section2.py + :start-after: step-1 + :end-before: step-2 + +We explained image and flavor in :doc:`section1`, so in the following sections, +we will explain the other parameters in detail, including :code:`ex_userdata` (cloud-init) and +:code:`ex_keyname` (key pairs). + + +Introduction to cloud-init +~~~~~~~~~~~~~~~~~~~~~~~~~~ + +`cloud-init `_ is a tool that performs instance configuration tasks during the boot of a cloud instance, +and comes installed on most cloud images. :code:`ex_userdata`, which was passed to :code:`create_node`, is the configuration data passed to cloud-init. + +In this case, we are presenting a shell script as the `userdata `_. +When :code:`create_node` creates the instance, :code:`cloud-init` executes the shell script in the :code:`userdata` variable. + +When an SSH public key is provided during instance creation, cloud-init will install this key on a user account. (The username varies between +cloud images.) See the `Obtaining Images `_ section of the image guide +for some guidance on which username you should use when SSHing. If you still have problems logging in, ask your cloud provider to confirm the username. + +.. only:: libcloud + + .. literalinclude:: ../../samples/libcloud/section2.py + :start-after: step-2 + :end-before: step-3 + + +Once the instance is created, cloud-init downloads and executes a script called :code:`install.sh`. +This script installs the Fractals app. Cloud-init is capable +of consuming a number of different types of data, not just bash scripts. +You can even provide multiple types of data. You can find further information about +cloud-init in the +`official documentation `_. + +Introduction to key pairs +~~~~~~~~~~~~~~~~~~~~~~~~~ + +As you might imagine, security is important when it comes to your instances; you can't +have just anyone accessing them. In order to enable logging into an instance, you need to provide +the public key of an SSH key pair during instance creation. In section one, +you made sure that you had a key pair and uploaded it to OpenStack, and cloud-init installed +it for the user account. + +Even with a key in place, however, you'll need to have the appropriate security group rules in place to access your instance. + +Introduction to security groups +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Security groups are sets of network access rules that are applied to an instance's networking. +By default, only egress (outbound) traffic is allowed. You must explicitly enable ingress (inbound) network access by +creating a security group rule. + +.. warning:: Removing the egress rule created by OpenStack will cause your instance + networking to break. + +Start by creating a security group for the all-in-one instance and adding the appropriate rules, such as HTTP (TCP port 80) and SSH (TCP port 22): + +.. only:: libcloud + + .. literalinclude:: ../../samples/libcloud/section2.py + :start-after: step-3 + :end-before: step-4 + + +.. note:: :code:`ex_create_security_group_rule()` takes ranges of ports as input. This is why ports 80 and 22 are passed twice. + +You can list available security groups with: + +.. only:: libcloud + + .. literalinclude:: ../../samples/libcloud/section2.py + :start-after: step-4 + :end-before: step-5 + + +Once you've created a rule or group, you can also delete it: + +.. only:: libcloud + + .. literalinclude:: ../../samples/libcloud/section2.py + :start-after: step-5 + :end-before: step-6 + + +To see which security groups apply to an instance, you can: + +.. only:: libcloud + + .. literalinclude:: ../../samples/libcloud/section2.py + :start-after: step-6 + :end-before: step-7 + + +.. todo:: print() ? + +Once you've configured permissions, you'll need to know where to access the application. + +Introduction to Floating IPs +~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +As in traditional IT, cloud instances are accessed via IP addresses. Rather than static IPs, however, these IP addresses are +assigned programmatically by OpenStack. How this is actually done depends on the networking setup for your cloud. In +some cases, you will simply get an Internet routable IP address assigned directly to your instance. + +The most common way for OpenStack clouds to allocate Internet routable IP addresses to instances, however, is through the use of Floating IPs. +A Floating IP is an address that exists as an entity unto itself, and can be associated to a specific instance network interface. +When a Floating IP address is associated to an instance network interface, OpenStack re-directs traffic bound for that address to +the address of the instance's internal network interface address. Your cloud provider will generally offer pools of floating IPs for your use. + +To use a Floating IP, you must first allocate an IP to your project, then associate it to your instance's network interface. + +.. note:: + + Allocating a Floating IP address to an instance does not change the IP address of the instance, + it causes OpenStack to establish the network translation rules to allow an *additional* IP address. + +.. only:: libcloud + + .. literalinclude:: ../../samples/libcloud/section2.py + :start-after: step-7 + :end-before: step-8 + + +If you have no free Floating IPs that have been previously allocated for your project, first select a Floating IP pool offered by your provider. +In this example, we have selected the first one and assume that it has available IP addresses. + +.. only:: libcloud + + .. literalinclude:: ../../samples/libcloud/section2.py + :start-after: step-8 + :end-before: step-9 + +Now request that an address from this pool be allocated to your project. + +.. only:: libcloud + + .. literalinclude:: ../../samples/libcloud/section2.py + :start-after: step-9 + :end-before: step-10 + +Now that you have an unused floating IP address allocated to your project, attach it to an instance. + +.. only:: libcloud + + .. literalinclude:: ../../samples/libcloud/section2.py + :start-after: step-10 + :end-before: step-11 + +That brings us to where we ended up at the end of :doc:`/section1`. But where do we go from here? + +Splitting services across multiple instances +-------------------------------------------- + +We've talked about separating functions into different microservices, and how that +enables us to make use of the cloud architecture. Now let's see that in action. + +The rest of this tutorial won't reference the all-in-one instance you created in section one. +Take a moment to delete this instance. + +It's easy to split out services into multiple instances. We will create a controller instance called :code:`app-controller`, +which hosts the API, database, and messaging services. We'll also create a worker instance called :code:`app-worker-1`, which just generates fractals. + +The first step is to start the controller instance. The instance has the API service, the database, and the messaging service, +as you can see from the parameters passed to the installation script. + +========== ====================== ============================= +Parameter Description Values +========== ====================== ============================= +:code:`-i` Install a service :code:`messaging` (install RabbitMQ) and :code:`faafo` (install the Faafo app). +:code:`-r` Enable/start something :code:`api` (enable and start the API service), :code:`worker` (enable and start the worker service), and :code:`demo` (run the demo mode to request random fractals). +========== ====================== ============================= + +.. todo:: https://bugs.launchpad.net/openstack-manuals/+bug/1439918 + +.. only:: libcloud + + + .. literalinclude:: ../../samples/libcloud/section2.py + :start-after: step-11 + :end-before: step-12 + +Note that this time, when you create a security group, you're including a rule that only applies +for instances that are part of the worker_group. + +Next, start a second instance, which will be the worker instance: + +.. todo :: more text necessary here... + + +.. only:: libcloud + + .. literalinclude:: ../../samples/libcloud/section2.py + :start-after: step-12 + :end-before: step-13 + +Notice that you've added this instance to the worker_group, so it can access the controller. + +As you can see from the parameters passed to the installation script, you are specifying that this is the worker instance, but you're also passing the address of the API instance and the message +queue so the worker can pick up requests. The Fractals app installation script can take several parameters. + +========== ==================================================== ==================================== +Parameter Description Example +========== ==================================================== ==================================== +:code:`-e` The endpoint URL of the API service. http://localhost/ +:code:`-m` The transport URL of the messaging service. amqp://guest:guest@localhost:5672/ +:code:`-d` The connection URL for the database (not used here). sqlite:////tmp/sqlite.db +========== ==================================================== ==================================== + +Now if you make a request for a new fractal, you connect to the controller instance, :code:`app-controller`, but the +work will actually be performed by a separate worker instance - :code:`app-worker-1`. + +Login with SSH and use the Fractal app +-------------------------------------- + +Login to the worker instance, :code:`app-worker-1`, with SSH, using the previous added SSH key pair "demokey". Start +by getting the IP address of the worker: + +.. only:: libcloud + + .. literalinclude:: ../../samples/libcloud/section2.py + :start-after: step-13 + :end-before: step-14 + +Now you can SSH into the instance: + +:: + + $ ssh -i ~/.ssh/id_rsa USERNAME@IP_WORKER_1 + +.. note:: Replace :code:`IP_WORKER_1` with the IP address of the worker instance and USERNAME to the appropriate username. + +Once you've logged in, check to see whether the worker service process is running as expected. +You can find the logs of the worker service in the directory :code:`/var/log/supervisor/`. + +:: + + worker # ps ax | grep faafo-worker + 17210 ? R 7:09 /usr/bin/python /usr/local/bin/faafo-worker + +Open :code:`top` to monitor the CPU usage of the :code:`faafo-worker` process. + +Now log into the controller instance, :code:`app-controller`, also with SSH, using the previously added SSH key pair "demokey". + +:: + + $ ssh -i ~/.ssh/id_rsa USERNAME@IP_CONTROLLER + +.. note:: Replace :code:`IP_CONTROLLER` with the IP address of the controller instance and USERNAME to the appropriate username. + +Check to see whether the API service process is running like expected. You can find the logs for the API service +in the directory :code:`/var/log/supervisor/`. + +:: + + controller # ps ax | grep faafo-api + 17209 ? Sl 0:19 /usr/bin/python /usr/local/bin/faafo-api + +Now call the Fractal app's command line interface (:code:`faafo`) to request a few new fractals. +The following command will request a few fractals with random parameters: + +:: + + controller # faafo --endpoint-url http://localhost --verbose create + 2015-04-02 03:55:02.708 19029 INFO faafo.client [-] generating 6 task(s) + +Watch :code:`top` on the worker instance. Right after calling :code:`faafo` the :code:`faafo-worker` process should start consuming a lot of CPU cycles. + +:: + + PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND + 17210 root 20 0 157216 39312 5716 R 98.8 3.9 12:02.15 faafo-worker + +To show the details of a specific fractal use the subcommand :code:`show` of the Faafo CLI. + +:: + + controller # faafo show 154c7b41-108e-4696-a059-1bde9bf03d0a + +------------+------------------------------------------------------------------+ + | Parameter | Value | + +------------+------------------------------------------------------------------+ + | uuid | 154c7b41-108e-4696-a059-1bde9bf03d0a | + | duration | 4.163147 seconds | + | dimensions | 649 x 869 pixels | + | iterations | 362 | + | xa | -1.77488588389 | + | xb | 3.08249829401 | + | ya | -1.31213919301 | + | yb | 1.95281690897 | + | size | 71585 bytes | + | checksum | 103c056f709b86f5487a24dd977d3ab88fe093791f4f6b6d1c8924d122031902 | + +------------+------------------------------------------------------------------+ + +There are more commands available; find out more details about them with :code:`faafo get --help`, :code:`faafo list --help`, and :code:`faafo delete --help`. + +.. note:: The application stores the generated fractal images directly in the database used by the API service instance. + Storing image files in database is not good practice. We're doing it here as an example only as an easy + way to allow multiple instances to have access to the data. For best practice, we recommend storing + objects in Object Storage, which is covered in :doc:`section4`. + +Next Steps +---------- + +You should now have a basic understanding of the architecture of cloud-based applications. In addition, +you now have had practice starting new instances, automatically configuring them at boot, and +even modularizing an application so that you may use multiple instances to run it. These are the basic +steps for requesting and using compute resources in order to run your application on an OpenStack cloud. + +From here, you should go to :doc:`/section3` to learn how to scale the application further. Alternately, you may +jump to any of these sections: + +* :doc:`/section4` - to learn how to make your application more durable using Object Storage +* :doc:`/section5` - to migrate the database to block storage, or use the database-as-as-service component +* :doc:`/section6` - to automatically orchestrate the application +* :doc:`/section7` - to learn about more complex networking +* :doc:`/section8` - for advice for developers new to operations + + +Full example code +----------------- + +Here's every code snippet into a single file, in case you want to run it all in one, or +you are so experienced you don't need instruction ;) If you are going to use this, +don't forget to set your authentication information and the flavor and image ID. + +.. only:: libcloud + + .. literalinclude:: ../../samples/libcloud/section2.py + :language: python + + diff --git a/openstack-firstapp/doc/source/section3.rst b/openstack-firstapp/doc/source/section3.rst new file mode 100644 index 000000000..f763cd721 --- /dev/null +++ b/openstack-firstapp/doc/source/section3.rst @@ -0,0 +1,348 @@ +========================== +Section Three: Scaling Out +========================== + +.. todo:: For later versions of this guide: implement a service within the fractals app + that simply returns the CPU load on the local server. Then add to this section + a simple loop that checks to see if any servers are overloaded and adds a new + one if they are. (Or do this via SSH and w) + +One of the most-often cited reasons for designing applications using cloud patterns is +the ability to **scale out**. That is: to add additional resources as required. This is in +contrast to the previous mentality of increasing capacity by scaling the size of existing resources up. +In order for scale out to be feasible, you'll need to do two things: + +* Architect your application to make use of additional resources. +* Make it possible to add new resources to your application. + +.. todo:: nickchase needs to restate the second point + +In section 2, we talked about various aspects of the application architecture, such +as building in a modular fashion, creating an API, and so on. Now you'll see why +those are so important. By creating a modular application with decoupled services, +it is possible to identify components that cause application performance bottlenecks +and scale them out. + +Just as importantly, you can also remove resources when they are no longer necessary. +It is very difficult to overstate the cost savings that this feature can bring, as +compared to traditional infrastructure. + +Of course, just having access to additional resources is only part of the battle; +while it's certainly possible to manually add or destroy resources, you'll get more +value -- and more responsiveness -- if the application simply requests new resources +automatically when it needs them. + +This section continues to illustrate the separation of services onto multiple instances +and highlights some of the choices we've made that facilitate scalability in +the app's architecture. + +We'll progressively ramp up to use up to about 6 instances, so ensure +that your cloud account has appropriate quota to handle that many. + +In the previous section, we used two virtual machines - one 'control' service and one 'worker'. +In our application, the speed at which fractals can be generated depends on the number of workers. +With just one worker, we can only produce one fractal at a time. Before long, it will be clear +that we need more resources. + +.. note:: If you don't have a working application, follow the steps in :doc:`section2` to create one. + +.. todo:: ensure we have the controller_ip even if this is a new python session. + +Generate load +------------- + +You can test for yourself what happens when the Fractals app is under loaded by +* maxing out the CPU of the existing worker instances (loading the worker) +* generating a lot of API requests (load up the API) + +Generate a lot of worker load +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Use SSH to login to the controller instance, :code:`app-controller`, using the previous added SSH keypair. + +:: + + $ ssh -i ~/.ssh/id_rsa USERNAME@IP_CONTROLLER + +.. note:: Replace :code:`IP_CONTROLLER` with the IP address of the controller instance and USERNAME to the appropriate username. + +Call the Fractal app's command line interface (:code:`faafo`) to request the generation of 5 large fractals. + +:: + + $ faafo create --height 9999 --width 9999 --tasks 5 + +Now if you check the load on the worker, you can see that the instance is not doing well. +On our single CPU flavor instance, a load average of more than 1 means we are at capacity. + +:: + + $ ssh -i ~/.ssh/id_rsa USERNAME@IP_WORKER uptime + 10:37:39 up 1:44, 2 users, load average: 1.24, 1.40, 1.36 + +.. note:: Replace :code:`IP_WORKER` with the IP address of the worker instance and USERNAME to the appropriate username. + +Generate a lot of API load +~~~~~~~~~~~~~~~~~~~~~~~~~~ + +API load is a slightly different problem to the previous one regarding capacity to work. We can +simulate many requests to the API as follows: + +Use SSH to login to the controller instance, :code:`app-controller`, using the previous added SSH keypair. + +:: + + $ ssh -i ~/.ssh/id_rsa USERNAME@IP_CONTROLLER + +.. note:: Replace :code:`IP_CONTROLLER` with the IP address of the controller instance and USERNAME to the appropriate username. + +Call the Fractal app's command line interface (:code:`faafo`) in a for loop to +send many requests to the API. The following command will request a random set of fractals, +500 times: + +:: + + $ for i in $(seq 1 500); do faafo --endpoint-url http://IP_CONTROLLER create &; done + +.. note:: Replace :code:`IP_CONTROLLER` with the IP address of the controller instance. + +Now if you check the load on the API service instance, :code:`app-controller`, you can see that the instance is not doing well. +On our single CPU flavor instance, a load average of more than 1 means we are at capacity. + +:: + + $ uptime + 10:37:39 up 1:44, 2 users, load average: 1.24, 1.40, 1.36 + +The number of requests coming in means that some requests for fractals may not even get +onto the message queue to be processed. To ensure we can cope with demand, +we need to scale out our API services as well. + +As you can see, we need to scale out the Fractals application's API capability. + +Scaling out +----------- + +Remove the old App +~~~~~~~~~~~~~~~~~~ + +Go ahead and delete the existing instances and security groups you created in previous sections. +Remember; when components in the cloud aren't doing what you want them to do, just remove them and +re-create something new. + +.. only:: libcloud + + .. literalinclude:: ../../samples/libcloud/section3.py + :start-after: step-1 + :end-before: step-2 + + +Extra Security Groups +~~~~~~~~~~~~~~~~~~~~~ + +As you change the topology of your applications, you will need to update or create new security +groups. Here, we will re-create the required security groups. + +.. only:: libcloud + + .. literalinclude:: ../../samples/libcloud/section3.py + :start-after: step-2 + :end-before: step-3 + +A Floating IP Helper Function +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Define a short function to locate unused or allocate a new floating IP. This saves a few lines of boring code +and prevents you from reaching your Floating IP quota too quickly. + +.. only:: libcloud + + .. literalinclude:: ../../samples/libcloud/section3.py + :start-after: step-3 + :end-before: step-4 + +Splitting off the Database and Message Queue +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Prior to scaling out our application services like the API service or the workers +we have to add a central database and messaging instance, called :code:`app-services`, +that will be used to track the state of the fractals and to coordinate the communication between the services. + +.. only:: libcloud + + .. literalinclude:: ../../samples/libcloud/section3.py + :start-after: step-4 + :end-before: step-5 + +Scaling the API Service +~~~~~~~~~~~~~~~~~~~~~~~ + +With multiple workers producing fractals as fast as they can, we also need to make sure we +can receive the requests for fractals as quickly as possible. If our application +becomes popular, we may have many thousands of users trying to connect to our API to generate fractals. + +Armed with our security group, image and flavor size we can now add multiple API services: + +.. only:: libcloud + + .. literalinclude:: ../../samples/libcloud/section3.py + :start-after: step-5 + :end-before: step-6 + +These are client-facing services, so unlike the workers they do not use a message queue +to distribute tasks. Instead, we'll need to introduce some kind of load balancing mechanism +to share incoming requests between the different API services. + +One simple way might be to give half of our friends one address and half the other, but that's certainly +not a sustainable solution. Instead, we can do that automatically using a `DNS round robin `_. +However, OpenStack networking can provide Load Balancing as a Service, which we'll explain in :doc:`/section7`. + +.. todo:: Add a note that we demonstrate this by using the first API instance for the workers and the second API instance for the load simulation. + + + +Scaling the workers +~~~~~~~~~~~~~~~~~~~ + +To increase the overall capacity, we will now add 3 workers: + +.. only:: libcloud + + .. literalinclude:: ../../samples/libcloud/section3.py + :start-after: step-6 + :end-before: step-7 + + +Adding this capacity enables you to deal with a higher number of requests for fractals. +As soon as these worker instances come up, they'll start checking the message queue looking +for requests, reducing the overall backlog like a new register opening in the supermarket. + +This was obviously a very manual process - figuring out we needed more workers and then +starting new ones required some effort. Ideally the system would do this itself. If your +application has been built to detect these situations, you can have it automatically request +and remove resources, but you don't actually need to do this work yourself. Instead, the +OpenStack Orchestration service can monitor load and start instances as appropriate. +See :doc:`section6` to find out how to set that up. + +Verifying we've had an impact +----------------------------- + +In the steps above, we've split out several services and expanded capacity. SSH to one of the +app instances and create a few fractals. You will see that the Fractals app has a few new features. + +:: + + $ ssh -i ~/.ssh/id_rsa USERNAME@IP_API_1 + +.. note:: Replace :code:`IP_API_1` with the IP address of the first API instance and USERNAME to the appropriate username. + +Use the Fractal app's command line interface to generate fractals :code:`faafo create`. +Watch the progress of fractal generation with the :code:`faafo list`. Use :code:`faafo UUID` +to examine some of the fractals. The generated_by field will show which worker +created the fractal. The fact that multiple worker instances are sharing the work means +that fractals will be generated more quickly and the death of a worker probably won't even +be noticed. + +:: + + root@app-api-1:/var/log/supervisor# faafo list + +--------------------------------------+------------------+-------------+ + | UUID | Dimensions | Filesize | + +--------------------------------------+------------------+-------------+ + | 410bca6e-baa7-4d82-9ec0-78e409db7ade | 295 x 738 pixels | 26283 bytes | + | 66054419-f721-492f-8964-a5c9291d0524 | 904 x 860 pixels | 78666 bytes | + | d123e9c1-3934-4ffd-8b09-0032ca2b6564 | 952 x 382 pixels | 34239 bytes | + | f51af10a-084d-4314-876a-6d0b9ea9e735 | 877 x 708 pixels | 93679 bytes | + +--------------------------------------+------------------+-------------+ + + root@app-api-1:# faafo show d123e9c1-3934-4ffd-8b09-0032ca2b6564 + +--------------+------------------------------------------------------------------+ + | Parameter | Value | + +--------------+------------------------------------------------------------------+ + | uuid | d123e9c1-3934-4ffd-8b09-0032ca2b6564 | + | duration | 1.671410 seconds | + | dimensions | 952 x 382 pixels | + | iterations | 168 | + | xa | -2.61217 | + | xb | 3.98459 | + | ya | -1.89725 | + | yb | 2.36849 | + | size | 34239 bytes | + | checksum | d2025a9cf60faca1aada854d4cac900041c6fa762460f86ab39f42ccfe305ffe | + | generated_by | app-worker-2 | + +--------------+------------------------------------------------------------------+ + root@app-api-1:# faafo show 66054419-f721-492f-8964-a5c9291d0524 + +--------------+------------------------------------------------------------------+ + | Parameter | Value | + +--------------+------------------------------------------------------------------+ + | uuid | 66054419-f721-492f-8964-a5c9291d0524 | + | duration | 5.293870 seconds | + | dimensions | 904 x 860 pixels | + | iterations | 348 | + | xa | -2.74108 | + | xb | 1.85912 | + | ya | -2.36827 | + | yb | 2.7832 | + | size | 78666 bytes | + | checksum | 1f313aaa36b0f616b5c91bdf5a9dc54f81ff32488ce3999f87a39a3b23cf1b14 | + | generated_by | app-worker-1 | + +--------------+------------------------------------------------------------------+ + +The fractals are now available from any of the app-api hosts. Visit +http://IP_API_1/fractal/FRACTAL_UUID and http://IP_API_2/fractal/FRACTAL_UUID to verify. Now you have multiple +redundant web services. If one dies, the others can be used. + +.. note:: Replace :code:`IP_API_1` and :code:`IP_API_2` with the corresponding Floating IPs. Replace FRACTAL_UUID + the UUID of an existing fractal. + +Go ahead and test the fault tolerance. Start killing workers and API instances. As long as you have one of each, your application +should be fine. There is one weak point though. The database contains the fractals and fractal metadata. If you lose that instance, +the application will stop. Future sections will work to address this weak point. + +If we had a load balancer, we could distribute this load between the two different API +services. As mentioned previously, there are several options. We will show one in :doc:`section7`. + +You could in theory use a simple script to monitor the load +on your workers and API services and trigger the creation of new instances, which +you already know how to do. If you can see how to do that - congratulations, you're ready +to create scalable cloud applications. + +Of course, creating a monitoring system just for one application may not always be +the best way. We recommend you look at :doc:`section6` to find out about how you +can use OpenStack Orchestration's monitoring and autoscaling capabilities to do +steps like this automatically. + + +Next Steps +---------- + +You should now be fairly confident about starting new instance, and about segregating services of an application between them. + +As mentioned in :doc:`/section2` the generated fractals images will be saved on the local filesystem of the API service instances. Because we now have multiple API +instances up and running the generated fractal images will be spreaded accross multiple API services, stored on local instance filesystems. This ends in a lot of +:code:`IOError: [Errno 2] No such file or directory` exceptions when trying to download a fractal image from an API service instance not holding the fractal +image on its local filesystem. + +From here, you should go to :doc:`/section4` to learn how to use Object Storage to solve this problem in a elegant way. Alternately, you may jump to any of these sections: + +* :doc:`/section5` - to migrate the database to block storage, or use the database-as-as-service component +* :doc:`/section6` - to automatically orchestrate the application +* :doc:`/section7` - to learn about more complex networking +* :doc:`/section8` - for advice for developers new to operations + + +Full example code +----------------- + +Here's every code snippet into a single file, in case you want to run it all in one, or +you are so experienced you don't need instruction ;) If you are going to use this, +don't forget to set your authentication information and the flavor and image ID. + +.. only:: libcloud + + .. literalinclude:: ../../samples/libcloud/section3.py + :language: python + + + + diff --git a/openstack-firstapp/doc/source/section4.rst b/openstack-firstapp/doc/source/section4.rst new file mode 100644 index 000000000..412ebccc8 --- /dev/null +++ b/openstack-firstapp/doc/source/section4.rst @@ -0,0 +1,303 @@ +=============================== +Section Four: Making it Durable +=============================== + +.. todo:: https://github.com/apache/libcloud/pull/492 + +.. todo:: For later versions of the guide: Extend the Fractals app to use Swift directly, and show the actual code from there. + +.. todo:: Explain how to get objects back out again. + +.. todo:: Large object support in Swift http://docs.openstack.org/developer/swift/overview_large_objects.html + +This section introduces object storage. +`OpenStack Object Storage `_ +(code-named Swift) is open source software for creating redundant, scalable data storage +using clusters of standardized servers to store petabytes of accessible data. +It is a long-term storage system for large amounts of static data that can be +retrieved, leveraged, and updated. Access is via an API, not through a file-system +like more traditional storage. + +There are a two key concepts to understand in the Object Storage API. The Object +Storage API is organized around two types of entities: + +* Objects +* Containers + +Similar to the Unix programming model, an Object is a "bag of bytes" that contains data, +such as documents and images. Containers are used to group objects. +You can make many objects inside a container, and have many containers inside your account. + +If you think about how you traditionally make what you store durable, very quickly you should come +to the conclusion that keeping multiple copies of your objects on separate systems is a good way +to do that. However, keeping track of multiple copies of objects is a pain, and building that +into an app requires a lot of logic. OpenStack Object Storage does this automatically for you +behind-the-scenes - replicating each object at least twice before returning 'write success' to your +API call. It will always work to ensure that there are three copies of your objects (by default) +at all times - replicating them around the system in case of hardware failure, maintanance, network +outage or any other kind of breakage. This is very convenient for app creation - you can just dump +objects into object storage and not have to care about any of this additional work to keep them safe. + + +Using Object Storage to store fractals +-------------------------------------- + +The Fractals app currently uses the local filesystem on the instance to store the images it +generates. This is not scalable or durable, for a number of reasons. + +Because the local filesystem is ephemeral storage, if the instance is terminated, the fractal +images will be lost along with the instance. Block based storage, which we'll discuss in :doc:`/section5`, +avoids that problem, but like local filesystems, it +requires administration to ensure that it does not fill up, and immediate attention if disks fail. + +The Object Storage service manages many of these tasks that normally would require the application owner +to manage them, and presents a scalable and durable API that you can use for the fractals app, without +having to be concerened with the low level details of how the objects are stored and replicated, +and growing the storage pool. In fact, Object Storage handles replication intrinsicly, storing multiple +copies of each object and returning one of them on demand using the API. + +First, let's learn how to connect to the Object Storage Endpoint: + +.. only:: dotnet + + .. warning:: This section has not yet been completed for the .NET SDK + +.. only:: fog + + .. warning:: This section has not yet been completed for the fog SDK + +.. only:: jclouds + + .. warning:: This section has not yet been completed for the jclouds SDK + +.. only:: libcloud + + .. literalinclude:: ../../samples/libcloud/section4.py + :start-after: step-1 + :end-before: step-2 + + + .. warning:: + + Libcloud 0.16 and 0.17 are afflicted with a bug that means authentication to + a swift endpoint can fail with `a Python exception `_. + If you encounter this, you can upgrade your libcloud version, or apply a simple + `2-line patch `_. + + .. note:: Libcloud uses a different connector for Object Storage to all other OpenStack services, + so a conn object from previous sections won't work here and we have to create a new one named :code:`swift`. + +.. only:: node + + .. warning:: This section has not yet been completed for the pkgcloud SDK + +.. only:: openstacksdk + + .. warning:: This section has not yet been completed for the OpenStack SDK + +.. only:: phpopencloud + + .. warning:: This section has not yet been completed for the PHP-OpenCloud SDK + + +To begin to store objects, we must first make a container. +Call yours :code:`fractals`: + +.. only:: libcloud + + .. literalinclude:: ../../samples/libcloud/section4.py + :start-after: step-2 + :end-before: step-3 + + You should see output such as: + + .. code-block:: python + + + +You should now be able to see this container appear in a listing of +all containers in your account: + +.. only:: libcloud + + .. literalinclude:: ../../samples/libcloud/section4.py + :start-after: step-3 + :end-before: step-4 + + You should see output such as: + + .. code-block:: python + + [] + +The next logical step is to upload an object. Find a photo of a goat +online, name it :code:`goat.jpg` and upload it to your container :code:`fractals`: + +.. only:: libcloud + + .. literalinclude:: ../../samples/libcloud/section4.py + :start-after: step-4 + :end-before: step-5 + +List objects in your container :code:`fractals` to see if the upload was successful, then download +the file to verify the md5sum is the same: + +.. only:: libcloud + + .. literalinclude:: ../../samples/libcloud/section4.py + :start-after: step-5 + :end-before: step-6 + + :: + + [] + + + .. literalinclude:: ../../samples/libcloud/section4.py + :start-after: step-6 + :end-before: step-7 + + :: + + + + .. literalinclude:: ../../samples/libcloud/section4.py + :start-after: step-7 + :end-before: step-8 + + :: + + 7513986d3aeb22659079d1bf3dc2468b + + + +Finally, let's clean up by deleting our test object: + +.. only:: libcloud + + .. literalinclude:: ../../samples/libcloud/section4.py + :start-after: step-8 + :end-before: step-9 + + .. note:: You need to pass in objects to the delete commands, not object names. + + Now there should be no more objects be available in the container :code:`fractals`. + + .. literalinclude:: ../../samples/libcloud/section4.py + :start-after: step-9 + :end-before: step-10 + + :: + + [] + +Backup the Fractals from the database on the Object Storage +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +So let's now use the knowledge from above to backup the images of the Fractals app, stored inside the database right now, on the Object Storage. + +Use the :code:`fractals`' container from above to put the images in: + +.. only:: libcloud + + .. literalinclude:: ../../samples/libcloud/section4.py + :start-after: step-10 + :end-before: step-11 + +Next, we backup all of our existing fractals from the database to our swift container. A simple for loop takes care of that: + +.. only:: libcloud + + .. literalinclude:: ../../samples/libcloud/section4.py + :start-after: step-11 + :end-before: step-12 + + :: + + + + + + .. note:: Replace :code:`IP_API_1` with the IP address of the API instance. + + .. note:: The example code uses the awesome `Requests library `_. Ensure that it is installed on your system before trying to run the script above. + + +Configure the Fractals app to use Object Storage +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. warning:: Currenctly it is not possible to directly store generated images on the OpenStack Object Storage. Please revisit this section again in the future. + +Extra Features +-------------- + +Delete containers +~~~~~~~~~~~~~~~~~ + +One call we didn't cover above that you probably need to know is how to delete a container. +Ensure that you have removed all objects from the container before running this, otherwise +it will fail: + +.. only:: libcloud + + .. literalinclude:: ../../samples/libcloud/section4.py + :start-after: step-12 + :end-before: step-13 + +.. warning:: It is not possible to restore deleted objects. Be careful. + +Add metadata to objects +~~~~~~~~~~~~~~~~~~~~~~~ + +You can also do advanced things like uploading an object with metadata, such +as in this below example, but for further information we'll refer you to the +documentation for your SDK. This option also uses a bit stream to upload the +file - iterating bit by bit over the file and passing those bits to swift as +they come, compared to loading the entire file in memory and then sending it. +This is more efficient, especially for larger files. + + +.. only:: libcloud + + .. literalinclude:: ../../samples/libcloud/section4.py + :start-after: step-13 + :end-before: step-14 + +.. todo:: It would be nice to have a pointer here to section 9. + +Large objects +~~~~~~~~~~~~~ + +For efficiency, most Object Storage installations treat large objects (say, :code:`> 5GB`) +differently than smaller objects. + +.. only:: libcloud + + If you are working with large objects, use the :code:`ex_multipart_upload_object` + call instead of the simpler :code:`upload_object` call. How the upload works behind-the-scenes + is by splitting the large object into chunks, and creating a special manifest so + they can be recombined on download. Alter the :code:`chunk_size` parameter (in bytes) according to + what your cloud can accept. + + .. literalinclude:: ../../samples/libcloud/section4.py + :start-after: step-14 + :end-before: step-15 + + +Next Steps +---------- + +You should now be fairly confident working with Object Storage. +You can find more about the Object Storage SDK calls at: + +.. only:: libcloud + + https://libcloud.readthedocs.org/en/latest/storage/api.html + +Or try a different step in the tutorial, including: + +* :doc:`/section5` - to migrate the database to block storage, or use the database-as-as-service component +* :doc:`/section6` - to automatically orchestrate the application +* :doc:`/section7` - to learn about more complex networking +* :doc:`/section8` - for advice for developers new to operations + diff --git a/openstack-firstapp/doc/source/section5.rst b/openstack-firstapp/doc/source/section5.rst new file mode 100644 index 000000000..0416ed01a --- /dev/null +++ b/openstack-firstapp/doc/source/section5.rst @@ -0,0 +1,275 @@ +=========================== +Section Five: Block Storage +=========================== + +.. todo:: (For nick: Restructure the introduction to this chapter to provide context of what we're actually + going to do.) + +By default, data in OpenStack instances is stored on 'ephemeral' disks. These stay with the instance throughout its lifetime, but when the +instance is terminated, that storage disappears -- along with all the data stored on it. Ephemeral storage is allocated to a +single instance and cannot be moved to another instance. + +In this section, we will introduce block storage. Block storage (sometimes referred to as volume storage) provides you +with access to persistent storage devices. You interact with block storage by attaching volumes +to running instances, just as you might attach a USB drive to a physical server. Volumes can be detached from one instance and re-attached to another, and the data remains intact. +Block storage is implemented in OpenStack by the OpenStack Block Storage (cinder) project. + +One component of the Fractal app that cannot be allowed to fail is the database server, which is used to keep track +of all of the data about fractals that have been created, including their storage location. So while you may have +configured the images to be stored in Object Storage in the previous section, without the database we lose track of +where in Object Storage they are, and the parameters that were used to create them. + +Advanced users should consider how to remove the database from the architecture altogether and replace it +with metadata in the Object Storage (then contribute these steps to :doc:`section9`). Others should read +on to learn about how to work with block storage and move the Fractal app database server to use it. + +Basics +------ + +Later on, we'll use a volume from the block storage service +to provide persistent storage for the Fractal app's database server, +but first - let's cover the basics, such as creating and attaching a block storage device. + +.. only:: dotnet + + .. warning:: This section has not yet been completed for the .NET SDK + +.. only:: fog + + .. warning:: This section has not yet been completed for the fog SDK + +.. only:: jclouds + + .. warning:: This section has not yet been completed for the jclouds SDK + +.. only:: node + + .. warning:: This section has not yet been completed for the pkgcloud SDK + +.. only:: openstacksdk + + .. warning:: This section has not yet been completed for the OpenStack SDK + +.. only:: phpopencloud + + .. warning:: This section has not yet been completed for the PHP-OpenCloud SDK + + +As always, connect to the API endpoint: + +.. only:: libcloud + + .. code-block:: python + + from libcloud.compute.types import Provider + from libcloud.compute.providers import get_driver + + auth_username = 'your_auth_username' + auth_password = 'your_auth_password' + auth_url = 'http://controller:5000' + project_name = 'your_project_name_or_id' + region_name = 'your_region_name' + + provider = get_driver(Provider.OPENSTACK) + connection = provider(auth_username, + auth_password, + ex_force_auth_url=auth_url, + ex_force_auth_version='2.0_password', + ex_tenant_name=project_name, + ex_force_service_region=region_name) + + +To try it out, make a 1GB volume called :test'. + +.. only:: libcloud + + .. code-block:: python + + volume = connection.create_volume(1, 'test') + print(volume) + + :: + + + +.. note:: The parameter :code:`size` is in GigaBytes. + +List all volumes to see if it was successful: + +.. only:: libcloud + + .. code-block:: python + + volumes = connection.list_volumes() + print(volumes) + + :: + + [] + +Now that you have created a storage volume, let's attach it to an already running instance. + + +Using Block Storage for the Fractal Database Server +--------------------------------------------------- + +Firstly, we're going to need a new server for our dedicated database. +Start a new instance called :code:`app-database` using the image, flavor +and keypair you have been using since :doc:`/section1`. +We will also need a new security group to allow access to the database server +(for mysql, port 3306) from the network: + +.. only:: libcloud + + .. code-block:: python + + db_group = connection.ex_create_security_group('database', 'for database service') + connection.ex_create_security_group_rule(db_group, 'TCP', 3306, 3306) + instance = connection.create_node(name='app-database', + image=image, + size=flavor, + ex_keyname=keypair_name, + ex_security_groups=[db_group]) + +Using the unique identifier (UUID) for the volume, make a new volume object, then +use the server object from the previous snippet and attach the volume to it at :code:`/dev/vdb`: + +.. only:: libcloud + + .. code-block:: python + + volume = connection.ex_get_volume('755ab026-b5f2-4f53-b34a-6d082fb36689') + connection.attach_volume(instance, volume, '/dev/vdb') + +Log in to the server to be able to run the following steps. + +.. note:: Replace :code:`IP_SERVICES` with the IP address of the services instance and USERNAME to the appropriate username. + +Now prepare the empty block device. + +:: + + $ ssh -i ~/.ssh/id_rsa USERNAME@IP_SERVICES + # fdisk -l + # mke2fs /dev/vdb + # mkdir /mnt/database + # mount /dev/vdb /mnt/database + +.. todo:: Outputs missing, add attaching log from dmesg. + +Stop the running MySQL database service and move the database files from :code:`/var/lib/mysql` onto the new volume (temporary mounted at :code:`/mnt/database`). + +:: + + # systemctl stop mariadb + # mv /var/lib/mysql/* /mnt/database + +Sync the filesystems and mount the new blockdevice now containing the database files to :code:`/var/lib/mysql`. + +:: + + # sync + # umount /mnt/database + # rm -rf /mnt/database + # echo "/dev/vdb /var/lib/mysql ext4 defaults 1 2" >> /etc/fstab + # mount /var/lib/mysql + +Finally start the previously stopped MySQL database service and check if everything is working like expected. + +:: + + # systemctl start mariadb + # mysql -ufaafo -ppassword -h localhost faafo -e 'show tables;' + +Extras +------ + +You can detach the volume and re-attach it elsewhere, or destroy the volume with the below steps. + +.. warning:: + The following operations are destructive and will result in data loss. + +To detach and destroy a volume: + +.. only:: libcloud + + .. code-block:: python + + connection.detach_volume(volume) + + :: + + True + + .. code-block:: python + + connection.destroy_volume(volume) + +.. note:: :code:`detach_volume` and :code:`destroy_volume` take a volume object, not a name. + +There are also many other useful features, such as the ability to create snapshots of volumes (handy for backups): + +.. only:: libcloud + + .. code-block:: python + +* snapshot_name = 'test_backup_1' + connnection.create_volume_snapshot('test', name='test backup 1') + + .. todo:: Do we need a note here to mention that 'test' is the volume name and not the volume object? + + You can find information about these calls and more in the `libcloud documentation `_. + + +Working with the OpenStack Database service +------------------------------------------- + +You created the database manually above, which is fine for a case with a single +database you won't touch often like this. However, OpenStack also has a component +code-named :code:`trove` that provides Database as a Service (DBaaS). + +.. note:: This OpenStack Database service is not installed in many clouds right now, but if your cloud does + support it, it can make your life a lot easier when working with databases. + +SDKs don't generally support the service yet, but you can use the 'trove' commandline client +to work with it instead. + +Install the trove commandline client by following this guide: +http://docs.openstack.org/cli-reference/content/install_clients.html + +Then set up the necessary variables for your cloud in an 'openrc' file using this guide: +http://docs.openstack.org/cli-reference/content/cli_openrc.html + +Ensure you have an openrc.sh file, source it and then check your trove client works: +:: + + $ cat openrc.sh + export OS_USERNAME=your_auth_username + export OS_PASSWORD=your_auth_password + export OS_TENANT_NAME=your_project_name + export OS_AUTH_URL=http://controller:5000/v2.0 + export OS_REGION_NAME=your_region_name + + $ source openrc.sh + + $ trove --version + 1.0.9 + +From there, you can find a good resource on what is supported and how +to use in `these slides `_. Steps to work with an existing database +service installation start on slide 28. + + + +Next Steps +---------- + +You should now be fairly confident working with Block Storage volumes. +There are several calls we did not cover. To see these and more, +refer to the volume documentation of your SDK, or try a different step in the tutorial, including: + +* :doc:`/section6` - to automatically orchestrate the application +* :doc:`/section7` - to learn about more complex networking +* :doc:`/section8` - for advice for developers new to operations + + diff --git a/openstack-firstapp/doc/source/section6.rst b/openstack-firstapp/doc/source/section6.rst new file mode 100644 index 000000000..5f83a56aa --- /dev/null +++ b/openstack-firstapp/doc/source/section6.rst @@ -0,0 +1,199 @@ +========================== +Section Six: Orchestration +========================== + +.. todo:: Needs to be restructured so that the fractals app is used as the example for the explanatory material. + +.. note:: Sorry! We're not quite happy with this chapter. It will give you an introduction to heat, + but it's a little dry at the moment. We'd like to write a template for the Fractals app instead + of using the "hello world" style ones, so stay tuned! + +Throughout this guide, we've talked about the importance of durability and scalability +for your cloud-based applications. In most cases, really achieving these qualities means +automating tasks such as scaling and other operational tasks. + +The Orchestration module provides a template-based way to describe a cloud +application, then coordinates running the needed OpenStack API calls to run +cloud applications. The templates allow you to create most OpenStack resource +types, such as instances, networking information, volumes, security groups +and even users. It also provides more advanced functionality, such as +instance high availability, instance auto-scaling, and nested stacks. + +The OpenStack Orchestration API contains the following constructs: + +* Stacks +* Resources +* Templates + +Stacks are created from Templates, which contain Resources. Resources +are an abstraction in the HOT (Heat Orchestration Template) template language, which enables you to define different +cloud resources by setting the `type` attibute. + +For example, you might use the Orchestration API to create two compute +instances by creating a Stack and by passing a Template to the Orchestration API. +That Template would contain two Resources with the `type` attribute set to `OS::Nova::Server`. + +That's a simplistic example, of course, but the flexibility of the Resource object +enables the creation of Templates that contain all the required cloud +infrastructure to run an application, such as load balancers, block storage volumes, +compute instances, networking topology, and security policies. + +.. note:: The Orchestration module isn't deployed by default in every cloud. If these commands don't work, it means the Orchestration API isn't available; ask your support team for assistance. + +This section introduces the `HOT templating language `_, +and takes you throughsome of the common calls you will make when working with OpenStack Orchestration. + +Unlike previous sections of this guide, in which you used your SDK to programmatically interact with +OpenStack, in this section you'll be using the Orchestration API directly through Template files, +so we'll work from the command line. + +Install the 'heat' commandline client by following this guide: +http://docs.openstack.org/cli-reference/content/install_clients.html + +then set up the necessary variables for your cloud in an 'openrc' file using this guide: +http://docs.openstack.org/cli-reference/content/cli_openrc.html + +.. only:: dotnet + + .. warning:: the .NET SDK does not currently support OpenStack Orchestration + +.. only:: fog + + .. note:: fog `does support OpenStack Orchestration `_. + +.. only:: jclouds + + .. warning:: Jclouds does not currently support OpenStack Orchestration. See this `bug report `_. + +.. only:: libcloud + + .. warning:: libcloud does not currently support OpenStack Orchestration. + +.. only:: node + + .. note:: Pkgcloud supports OpenStack Orchestration :D:D:D but this section is `not written yet `_ + +.. only:: openstacksdk + + .. warning:: OpenStack SDK does not currently support OpenStack Orchestration. + +.. only:: phpopencloud + + .. note:: PHP-opencloud supports orchestration :D:D:D but this section is not written yet. + +HOT Templating Language +----------------------- + +The best place to learn about the template syntax for OpenStack Orchestration is the +`Heat Orchestration Template (HOT) Guide `_ +You should read the HOT Guide first to learn how to create basic templates, their inputs and outputs. + +Working with Stacks: Basics +--------------------------- + +.. todo:: + + This section needs to have a HOT template written for deploying the Fractal Application + +.. todo:: + + Replace the hello_world.yaml templte with the Fractal template + +* Stack create + +In the following example, we use the `hello_world `_ Hot template to demonstrate creating +a Nova compute instance, with a few configuration settings passed in, such as an administrative password and the unique identifier (UUID) +of an image: + +:: + + $ wget https://raw.githubusercontent.com/openstack/heat-templates/master/hot/hello_world.yaml + $ heat stack-create --template-file hello_world.yaml \ + --parameters admin_pass=Test123\;key_name=test\;image=5bbe4073-90c0-4ec9-833c-092459cc4539 hello_world + +--------------------------------------+-------------+--------------------+----------------------+ + | id | stack_name | stack_status | creation_time | + +--------------------------------------+-------------+--------------------+----------------------+ + | 0db2c026-fb9a-4849-b51d-b1df244096cd | hello_world | CREATE_IN_PROGRESS | 2015-04-01T03:20:25Z | + +--------------------------------------+-------------+--------------------+----------------------+ + +The resulting stack creates a Nova instance automatically, which you can see here: + +:: + + $ nova list + +--------------------------------------+---------------------------------+--------+------------+-------------+------------------+ + | ID | Name | Status | Task State | Power State | Networks | + +--------------------------------------+---------------------------------+--------+------------+-------------+------------------+ + | 9bdf0e2f-415e-43a0-90ea-63a5faf86cf9 | hello_world-server-dwmwhzfxgoor | ACTIVE | - | Running | private=10.0.0.3 | + +--------------------------------------+---------------------------------+--------+------------+-------------+------------------+ + +Verify that the stack was successfully created using the following command: + +:: + + $ heat stack-list + +--------------------------------------+-------------+-----------------+----------------------+ + | id | stack_name | stack_status | creation_time | + +--------------------------------------+-------------+-----------------+----------------------+ + | 0db2c026-fb9a-4849-b51d-b1df244096cd | hello_world | CREATE_COMPLETE | 2015-04-01T03:20:25Z | + +--------------------------------------+-------------+-----------------+----------------------+ + +Remove the stack: + +:: + + $ heat stack-delete hello_world + +--------------------------------------+-------------+--------------------+----------------------+ + | id | stack_name | stack_status | creation_time | + +--------------------------------------+-------------+--------------------+----------------------+ + | 0db2c026-fb9a-4849-b51d-b1df244096cd | hello_world | DELETE_IN_PROGRESS | 2015-04-01T03:20:25Z | + +--------------------------------------+-------------+--------------------+----------------------+ + +Verify that the removal of the stack has deleted the nova instance: + +:: + + $ nova list + +----+------+--------+------------+-------------+----------+ + | ID | Name | Status | Task State | Power State | Networks | + +----+------+--------+------------+-------------+----------+ + +----+------+--------+------------+-------------+----------+ + +While this stack is not very interesting - it just starts a single instance - it +is possible to make very complicated templates that involve dozens of instances +or adds and removes instances based on demand. Continue to the next section to +learn more. + +Working with Stacks: Advanced +----------------------------- + +.. todo:: needs more explanatory material + +.. todo:: needs a heat template that uses fractal app + +With the use of the Orchestration API, the Fractal app can create an autoscaling +group for all parts of the application, in order to dynamically provision more +compute resources during periods of heavy utilization, and also terminate compute +instances to scale down, as demand decreases. + +There are two helpful articles available to learn about autoscaling with the +Orchestration API: + +* http://superuser.openstack.org/articles/simple-auto-scaling-environment-with-heat +* http://superuser.openstack.org/articles/understanding-openstack-heat-auto-scaling + +An example template that creates an auto-scaling wordpress instance can be found in +`the heat template repository `_ + + +Next Steps +---------- + +You should now be fairly confident working with the Orchestration service. +There are several calls we did not cover. To see these and more, +refer to the volume documentation of your SDK, or try a different step in the tutorial, including: + +* :doc:`/section7` - to learn about more complex networking +* :doc:`/section8` - for advice for developers new to operations +* :doc:`/section9` - to see all the crazy things we think ordinary folks won't want to do ;) + diff --git a/openstack-firstapp/doc/source/section7.rst b/openstack-firstapp/doc/source/section7.rst new file mode 100644 index 000000000..e682b0be2 --- /dev/null +++ b/openstack-firstapp/doc/source/section7.rst @@ -0,0 +1,797 @@ +========================= +Section Seven: Networking +========================= + +.. todo:: Latter part of the chapter (LBaaS) needs to use Fractals app entities for the examples. + +Prior to this chapter, all of the nodes that comprise the fractal application +were attached to the same network. + +In this section of the tutorial, we introduce the Networking API, +which will enable us to build networking topologies that separate +public traffic accessing the application from traffic between the API +instances and the worker components, introduce load balancing for +resilience, and create a secure backend network for communication between the +database, webserver, file storage, and worker components. + +.. only:: dotnet + + .. warning:: This section has not yet been completed for the .NET SDK + +.. only:: fog + + .. warning:: fog `supports `_ the OpenStack Networking API, but this section has not yet been completed. + +.. only:: jclouds + + .. warning:: jClouds supports the OpenStack Networking API, but section has not yet been completed. Please see `this `_ in the meantime. + +.. only:: libcloud + + .. warning:: Libcloud does not support the OpenStack Networking API + +.. only:: node + + .. warning:: Pkgcloud supports the OpenStack Networking API, but this section has not been completed + +.. only:: openstacksdk + + .. warning:: This section has not yet been completed for the OpenStack SDK + +.. only:: phpopencloud + + .. warning:: PHP-OpenCloud supports the OpenStack Networking API, but this section has not been completed + +Working with the CLI +-------------------- + +As SDKs don't currently support the OpenStack Networking API this section uses +the commandline. + +Install the 'neutron' commandline client by following this guide: +http://docs.openstack.org/cli-reference/content/install_clients.html + +Then set up the necessary variables for your cloud in an 'openrc' file using this guide: +http://docs.openstack.org/cli-reference/content/cli_openrc.html + +Ensure you have an openrc.sh file, source it and then check your neutron client works: +:: + + $ cat openrc.sh + export OS_USERNAME=your_auth_username + export OS_PASSWORD=your_auth_password + export OS_TENANT_NAME=your_project_name + export OS_AUTH_URL=http://controller:5000/v2.0 + export OS_REGION_NAME=your_region_name + + $ source openrc.sh + + $ neutron --version + 2.3.11 + +Networking Segmentation +----------------------- + +In traditional datacenters, multiple network segments are +dedicated to specific types of network traffic. + +The fractal application we are building contains three types of network traffic: + +* public-facing wev traffic +* API traffic +* internal worker traffic + +For performance reasons, it makes sense to have a network for each tier, +so that traffic from one tier does not "crowd out" other types of traffic +and cause the application to fail. In addition, having separate networks makes +controlling access to parts of the application easier to manage, improving the overall +security of the application. + +Prior to this section, the network layout for the Fractal application would be similar to the following diagram: + +.. nwdiag:: + + nwdiag { + + network public { + address = "203.0.113.0/24" + tenant_router [ address = "203.0.113.20" ]; + } + + network tenant_network { + address = "10.0.0.0/24" + tenant_router [ address = "10.0.0.1" ]; + api [ address = "203.0.113.20, 10.0.0.3" ]; + webserver1 [ address = "203.0.113.21, 10.0.0.4" ]; + webserver2 [ address = "203.0.113.22, 10.0.0.5" ]; + worker1 [ address = "203.0.113.23, 10.0.0.6" ]; + worker2 [ address = "203.0.113.24, 10.0.0.7" ]; + } + } + +In this network layout, we are assuming that the OpenStack cloud in which +you have been building your application has a public +network and tenant router that was already created in advance, either by the +administrators of the cloud you are running the Fractal application on, +or by you, following the instructions in the appendix. + +Many of the network concepts that are discussed in this section are +already present in the diagram above. A tenant router provides +routing and external access for the worker nodes, and floating IP addresses +are already associated with each node in the Fractal application cluster +to facilitate external access. + +At the end of this section, we will be making some slight changes to the networking topology +by using the OpenStack Networking API to create a new network to which the worker nodes will attach +(10.0.1.0/24). We will use the API network (10.0.3.0/24) to attach the Fractal API servers. Webserver instances have their own network (10.0.2.0/24), and +will be accessible by fractal aficionados worldwide, by allocating floating IPs from the public network. + +.. nwdiag:: + + nwdiag { + + network public { + address = "203.0.113.0/24" + tenant_router [ address = "203.0.113.60"]; + } + + network webserver_network{ + address = "10.0.2.0/24" + tenant_router [ address = "10.0.2.1"]; + webserver1 [ address = "203.0.113.21, 10.0.2.3"]; + webserver2 [ address = "203.0.113.22, 10.0.2.4"]; + } + network api_network { + address = "10.0.3.0/24" + tenant_router [ address = "10.0.3.1" ]; + api1 [ address = "10.0.3.3" ]; + api2 [ address = "10.0.3.4" ]; + } + + network worker_network { + address = "10.0.1.0/24" + tenant_router [ address = "10.0.1.1" ]; + worker1 [ address = "10.0.1.5" ]; + worker2 [ address = "10.0.1.6" ]; + } + } + +Introduction to Tenant Networking +--------------------------------- + +With the OpenStack Networking API, the workflow for creating a network topology that separates the public-facing +Fractals app API from the worker backend is as follows: + +* Create a network for the web server nodes. + +* Create a network for the worker nodes. This is the private data network. + +* Create a subnet for the private data network to use for addressing. In other words, when worker instances are created, their IP addresses will come from this subnet. + +* Create a subnet for the web server network to use for addressing. In other words, when web server instances are created, their IP addresses will come from this subnet. + +* Create a router for the private data network. + +* Allocate floating ips and assign them to the web server nodes. + +Creating Networks +----------------- + +We assume that the public network, with the subnet that floating IPs can be allocated from, was provisioned +for you by your cloud operator. This is due to the nature of L3 routing, where the IP address range that +is used for floating IPs is configured in other parts of the operator's network, so that traffic is properly routed. + +.. todo:: Rework the console outputs in these sections to be more comprehensive, based on the outline above + +Next, create a private data network, worker_network: + +:: + + $ neutron net-create worker_network + Created a new network: + +-----------------+--------------------------------------+ + | Field | Value | + +-----------------+--------------------------------------+ + | admin_state_up | True | + | id | 953224c6-c510-45c5-8a29-37deffd3d78e | + | name | worker_network | + | router:external | False | + | shared | False | + | status | ACTIVE | + | subnets | | + | tenant_id | f77bf3369741408e89d8f6fe090d29d2 | + +-----------------+--------------------------------------+ + +Now let's just confirm that we have both the worker network, and a public +network by getting a list of all networks in the cloud. The public network +doesn't have to be named public - it could be 'external', 'net04_ext' or +something else - the important thing is it exists and can be used to reach +the internet. + +:: + + $ neutron net-list + +--------------------------------------+------------------+--------------------------------------------------+ + | id | name | subnets | + +--------------------------------------+------------------+--------------------------------------------------+ + | 29349515-98c1-4f59-922e-3809d1b9707c | public | 7203dd35-7d17-4f37-81a1-9554b3316ddb | + | 953224c6-c510-45c5-8a29-37deffd3d78e | worker_network | | + +--------------------------------------+------------------+--------------------------------------------------+ + +Next create the subnet from which addresses will be allocated for instances on the worker network: + +:: + + $ neutron subnet-create --name worker_cidr worker_network 10.0.1.0/24 + Created a new subnet: + +-------------------+--------------------------------------------+ + | Field | Value | + +-------------------+--------------------------------------------+ + | allocation_pools | {"start": "10.0.1.2", "end": "10.0.1.254"} | + | cidr | 10.0.1.0/24 | + | dns_nameservers | | + | enable_dhcp | True | + | gateway_ip | 10.0.1.1 | + | host_routes | | + | id | a0e2ebe4-5d4e-46b3-82b5-4179d778e615 | + | ip_version | 4 | + | ipv6_address_mode | | + | ipv6_ra_mode | | + | name | worker_cidr | + | network_id | 953224c6-c510-45c5-8a29-37deffd3d78e | + | tenant_id | f77bf3369741408e89d8f6fe090d29d2 | + +-------------------+--------------------------------------------+ + +Now create a network for the webservers ... + +:: + + $ neutron net-create webserver_network + Created a new network: + +-----------------+--------------------------------------+ + | Field | Value | + +-----------------+--------------------------------------+ + | admin_state_up | True | + | id | 28cf9704-2b43-4925-b23e-22a892e354f2 | + | mtu | 0 | + | name | webserver_network | + | router:external | False | + | shared | False | + | status | ACTIVE | + | subnets | | + | tenant_id | 0cb06b70ef67424b8add447415449722 | + +-----------------+--------------------------------------+ + +... and a subnet from which they can pull IP addresses: + +:: + + $ neutron subnet-create webserver_network 10.0.2.0/24 + Created a new subnet: + +-------------------+--------------------------------------------+ + | Field | Value | + +-------------------+--------------------------------------------+ + | allocation_pools | {"start": "10.0.2.2", "end": "10.0.2.254"} | + | cidr | 10.0.2.0/24 | + | dns_nameservers | | + | enable_dhcp | True | + | gateway_ip | 10.0.2.1 | + | host_routes | | + | id | 1e0d6a75-c40e-4be5-8e13-b2226fc8444a | + | ip_version | 4 | + | ipv6_address_mode | | + | ipv6_ra_mode | | + | name | | + | network_id | 28cf9704-2b43-4925-b23e-22a892e354f2 | + | tenant_id | 0cb06b70ef67424b8add447415449722 | + +-------------------+--------------------------------------------+ + +Next, create the network for the API servers: + +:: + + $ neutron net-create api_network + Created a new network: + +-----------------+--------------------------------------+ + | Field | Value | + +-----------------+--------------------------------------+ + | admin_state_up | True | + | id | 5fe4045a-65dc-4672-b44e-1f14a496a71a | + | mtu | 0 | + | name | api_network | + | router:external | False | + | shared | False | + | status | ACTIVE | + | subnets | | + | tenant_id | 0cb06b70ef67424b8add447415449722 | + +-----------------+--------------------------------------+ + +Finally, create the subnet for the API network: + +:: + + $ neutron subnet-create api_network 10.0.3.0/24 + Created a new subnet: + +-------------------+--------------------------------------------+ + | Field | Value | + +-------------------+--------------------------------------------+ + | allocation_pools | {"start": "10.0.3.2", "end": "10.0.3.254"} | + | cidr | 10.0.3.0/24 | + | dns_nameservers | | + | enable_dhcp | True | + | gateway_ip | 10.0.3.1 | + | host_routes | | + | id | 6ce4b60d-a940-4369-b8f0-2e9c196e4f20 | + | ip_version | 4 | + | ipv6_address_mode | | + | ipv6_ra_mode | | + | name | | + | network_id | 5fe4045a-65dc-4672-b44e-1f14a496a71a | + | tenant_id | 0cb06b70ef67424b8add447415449722 | + +-------------------+--------------------------------------------+ + +Now that you've got the networks created, go ahead and create two Floating IPs, for web servers. +Ensure that you replace 'public' with the name of the public/external network set up +by your cloud administrator. + +:: + + $ neutron floatingip-create public + Created a new floatingip: + +---------------------+--------------------------------------+ + | Field | Value | + +---------------------+--------------------------------------+ + | fixed_ip_address | | + | floating_ip_address | 203.0.113.21 | + | floating_network_id | 7ad1ce2b-4b8c-4036-a77b-90332d7f4dbe | + | id | 185df49f-7890-4c59-a66a-2456b6a87422 | + | port_id | | + | router_id | | + | status | DOWN | + | tenant_id | 0cb06b70ef67424b8add447415449722 | + +---------------------+--------------------------------------+ + + $ neutron floatingip-create public + Created a new floatingip: + +---------------------+--------------------------------------+ + | Field | Value | + +---------------------+--------------------------------------+ + | fixed_ip_address | | + | floating_ip_address | 203.0.113.22 | + | floating_network_id | 7ad1ce2b-4b8c-4036-a77b-90332d7f4dbe | + | id | 185df49f-7890-4c59-a66a-2456b6a87422 | + | port_id | | + | router_id | | + | status | DOWN | + | tenant_id | 0cb06b70ef67424b8add447415449722 | + +---------------------+--------------------------------------+ + +.. note:: The world is running out of IPv4 addresses. If you get an error like + "No more IP addresses available on network", contact your cloud + administrator. You may also want to ask about IPv6 :) + +Next we'll need to enable OpenStack to route traffic appropriately. + +Creating the SNAT gateway +------------------------- + +Because we are using cloud-init and other tools to deploy and bootstrap the application, +the Fractal app worker instances require Source Network Address Translation (SNAT). +If the Fractal app worker nodes were deployed from a "golden image" +that had all the software components already installed, there would be no need to create a +Neutron router to provide SNAT functionality. + +.. todo :: nickchase doesn't understand the above paragraph. Why wouldn't it be required? + +:: + + $ neutron router-create tenant_router + Created a new router: + +-----------------------+--------------------------------------+ + | Field | Value | + +-----------------------+--------------------------------------+ + | admin_state_up | True | + | external_gateway_info | | + | id | d380b29f-ca65-4718-9735-196cbed10fce | + | name | tenant_router | + | routes | | + | status | ACTIVE | + | tenant_id | f77bf3369741408e89d8f6fe090d29d2 | + +-----------------------+--------------------------------------+ + +After creating the router, you need to set up the gateway for the router. For outbound access +we will set the router's gateway as the public network. + +:: + + $ neutron router-gateway-set worker_router public + Set gateway for router tenant_router + + $ neutron router-show tenant_router + + +-----------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ + | Field | Value | + +-----------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ + | admin_state_up | True | + | external_gateway_info | {"network_id": "29349515-98c1-4f59-922e-3809d1b9707c", "enable_snat": true, "external_fixed_ips": [{"subnet_id": "7203dd35-7d17-4f37-81a1-9554b3316ddb", "ip_address": "203.0.113.50"}]} | + | id | d380b29f-ca65-4718-9735-196cbed10fce | + | name | tenant_router | + | routes | | + | status | ACTIVE | + | tenant_id | f77bf3369741408e89d8f6fe090d29d2 | + +-----------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ + + +The final, most important step is to create an interface on the worker network and attach it to the router you just created. + +:: + + $ neutron router-interface-add tenant_router worker_cidr + Added interface 0d8bd523-06c2-4ddd-8b33-8726af2daa0a to router worker_router. + + +:: + + $ neutron net-list + +--------------------------------------+----------------+--------------------------------------------------+ + | id | name | subnets | + +--------------------------------------+----------------+--------------------------------------------------+ + | 29349515-98c1-4f59-922e-3809d1b9707c | public | 7203dd35-7d17-4f37-81a1-9554b3316ddb | + | 953224c6-c510-45c5-8a29-37deffd3d78e | worker_network | a0e2ebe4-5d4e-46b3-82b5-4179d778e615 10.0.1.0/24 | + +--------------------------------------+----------------+--------------------------------------------------+ + +.. todo: + Wire up the tenant router to the api_network and webserver_network + +Booting a worker +~~~~~~~~~~~~~~~~ + +Now that you've prepared the networking infrastructure, you can go ahead and boot an instance on it. +Ensure you use appropriate flavor and image values for your cloud - see :doc:`section1` if you've not already. + +.. todo:: Show how to create an instance in libcloud using the network we just created. - libcloud does not yet support this. + +:: + + $ nova boot --flavor m1.tiny --image cirros-0.3.3-x86_64-disk --nic net-id=953224c6-c510-45c5-8a29-37deffd3d78e worker1 + +--------------------------------------+-----------------------------------------------------------------+ + | Property | Value | + +--------------------------------------+-----------------------------------------------------------------+ + | OS-DCF:diskConfig | MANUAL | + | OS-EXT-AZ:availability_zone | nova | + | OS-EXT-STS:power_state | 0 | + | OS-EXT-STS:task_state | scheduling | + | OS-EXT-STS:vm_state | building | + | OS-SRV-USG:launched_at | - | + | OS-SRV-USG:terminated_at | - | + | accessIPv4 | | + | accessIPv6 | | + | adminPass | 9vU8KSY4oDht | + | config_drive | | + | created | 2015-03-30T05:26:04Z | + | flavor | m1.tiny (1) | + | hostId | | + | id | 9e188a47-a246-463e-b445-027d6e2966e0 | + | image | cirros-0.3.3-x86_64-disk (ad605ff9-4593-4048-900b-846d6401c193) | + | key_name | - | + | metadata | {} | + | name | worker1 | + | os-extended-volumes:volumes_attached | [] | + | progress | 0 | + | security_groups | default | + | status | BUILD | + | tenant_id | f77bf3369741408e89d8f6fe090d29d2 | + | updated | 2015-03-30T05:26:04Z | + | user_id | a61292a5691d4c6c831b7a8f07921261 | + +--------------------------------------+-----------------------------------------------------------------+ + +Load Balancing +-------------- + +After separating the Fractal worker nodes into their own network, +the next logical step is to move the Fractal API service onto a load balancer, +so that multiple API workers can handle requests. By using a load balancer, the API +service can be scaled out in a similar fashion to the worker nodes. + +Neutron LbaaS API +~~~~~~~~~~~~~~~~~ + +.. note:: This section is based on the Neutron LBaaS API version 1.0 http://docs.openstack.org/admin-guide-cloud/content/lbaas_workflow.html + +.. todo:: libcloud support added 0.14: https://developer.rackspace.com/blog/libcloud-0-dot-14-released/ - this section needs rewriting to use the libcloud API + +The OpenStack Networking API provides support for creating loadbalancers, which can be used to +scale the Fractal app web service. In the following example, we create two compute instances via the Compute +API, then instantiate a loadbalancer that will use a virtual IP (VIP) for accessing the web service offered by +the two compute nodes. The end result will be the following network topology: + +.. nwdiag:: + + nwdiag { + + network public { + address = "203.0.113.0/24" + tenant_router [ address = "203.0.113.60" ]; + loadbalancer [ address = "203.0.113.63" ]; + } + + network webserver_network { + address = "10.0.2.0/24" + tenant_router [ address = "10.0.2.1"]; + webserver1 [ address = "203.0.113.21, 10.0.2.3"]; + webserver2 [ address = "203.0.113.22, 10.0.2.4"]; + } + } + +libcloud support added 0.14: https://developer.rackspace.com/blog/libcloud-0-dot-14-released/ + +Let's start by looking at what's already in place. + +:: + + $ neutron net-list + +--------------------------------------+-------------------+-----------------------------------------------------+ + | id | name | subnets | + +--------------------------------------+-------------------+-----------------------------------------------------+ + | 3c826379-e896-45a9-bfe1-8d84e68e9c63 | webserver_network | 3eada497-36dd-485b-9ba4-90c5e3340a53 10.0.2.0/24 | + | 7ad1ce2b-4b8c-4036-a77b-90332d7f4dbe | public | 47fd3ff1-ead6-4d23-9ce6-2e66a3dae425 203.0.113.0/24 | + +--------------------------------------+-------------------+-----------------------------------------------------+ + +Now let's go ahead and create 2 instances. + +:: + + $ nova boot --flavor 1 --image 53ff0943-99ba-42d2-a10d-f66656372f87 --min-count 2 test + +--------------------------------------+-----------------------------------------------------------------+ + | Property | Value | + +--------------------------------------+-----------------------------------------------------------------+ + | OS-DCF:diskConfig | MANUAL | + | OS-EXT-AZ:availability_zone | nova | + | OS-EXT-STS:power_state | 0 | + | OS-EXT-STS:task_state | scheduling | + | OS-EXT-STS:vm_state | building | + | OS-SRV-USG:launched_at | - | + | OS-SRV-USG:terminated_at | - | + | accessIPv4 | | + | accessIPv6 | | + | adminPass | z84zWFCcpppH | + | config_drive | | + | created | 2015-04-02T02:45:09Z | + | flavor | m1.tiny (1) | + | hostId | | + | id | 8d579f4a-116d-46b9-8db3-aa55b76f76d8 | + | image | cirros-0.3.3-x86_64-disk (53ff0943-99ba-42d2-a10d-f66656372f87) | + | key_name | - | + | metadata | {} | + | name | test-1 | + | os-extended-volumes:volumes_attached | [] | + | progress | 0 | + | security_groups | default | + | status | BUILD | + | tenant_id | 0cb06b70ef67424b8add447415449722 | + | updated | 2015-04-02T02:45:09Z | + | user_id | d95381d331034e049727e2413efde39f | + +--------------------------------------+-----------------------------------------------------------------+ + +Confirm that they were added: + +:: + + $ nova list + +--------------------------------------+--------+--------+------------+-------------+------------------+ + | ID | Name | Status | Task State | Power State | Networks | + +--------------------------------------+--------+--------+------------+-------------+------------------+ + | 8d579f4a-116d-46b9-8db3-aa55b76f76d8 | test-1 | ACTIVE | - | Running | private=10.0.2.4 | + | 8fadf892-b6e9-44f4-b132-47c6762ffa2c | test-2 | ACTIVE | - | Running | private=10.0.2.3 | + +--------------------------------------+--------+--------+------------+-------------+------------------+ + +Now let's look at what ports are available: + +:: + + $ neutron port-list + +--------------------------------------+------+-------------------+---------------------------------------------------------------------------------+ + | id | name | mac_address | fixed_ips | + +--------------------------------------+------+-------------------+---------------------------------------------------------------------------------+ + | 1d9a0f79-bf05-443e-b65d-a05b0c635936 | | fa:16:3e:10:f8:f0 | {"subnet_id": "3eada497-36dd-485b-9ba4-90c5e3340a53", "ip_address": "10.0.2.2"} | + | 3f40c866-169b-48ec-8e0a-d9f1e70e5756 | | fa:16:3e:8c:6f:25 | {"subnet_id": "3eada497-36dd-485b-9ba4-90c5e3340a53", "ip_address": "10.0.2.1"} | + | 462c92c6-941c-48ab-8cca-3c7a7308f580 | | fa:16:3e:d7:7d:56 | {"subnet_id": "3eada497-36dd-485b-9ba4-90c5e3340a53", "ip_address": "10.0.2.4"} | + | 7451d01f-bc3b-46a6-9ae3-af260d678a63 | | fa:16:3e:c6:d4:9c | {"subnet_id": "3eada497-36dd-485b-9ba4-90c5e3340a53", "ip_address": "10.0.2.3"} | + +--------------------------------------+------+-------------------+---------------------------------------------------------------------------------+ + +Next create additional floating IPs by specifying the fixed IP addresses they should point to and the ports they should use: + +:: + + $ neutron floatingip-create public --fixed-ip-address 10.0.2.3 --port-id 7451d01f-bc3b-46a6-9ae3-af260d678a63 + Created a new floatingip: + +---------------------+--------------------------------------+ + | Field | Value | + +---------------------+--------------------------------------+ + | fixed_ip_address | 10.0.2.3 | + | floating_ip_address | 203.0.113.21 | + | floating_network_id | 7ad1ce2b-4b8c-4036-a77b-90332d7f4dbe | + | id | dd2c838e-7c1b-480c-a18c-17f1526c96ea | + | port_id | 7451d01f-bc3b-46a6-9ae3-af260d678a63 | + | router_id | 7f8ee1f6-7211-40e8-b9a8-17582ecfe50b | + | status | DOWN | + | tenant_id | 0cb06b70ef67424b8add447415449722 | + +---------------------+--------------------------------------+ + $ neutron floatingip-create public --fixed-ip-address 10.0.2.4 --port-id 462c92c6-941c-48ab-8cca-3c7a7308f580 + Created a new floatingip: + +---------------------+--------------------------------------+ + | Field | Value | + +---------------------+--------------------------------------+ + | fixed_ip_address | 10.0.2.4 | + | floating_ip_address | 203.0.113.22 | + | floating_network_id | 7ad1ce2b-4b8c-4036-a77b-90332d7f4dbe | + | id | 6eb510bf-c18f-4c6f-bb35-e21938ca8bd4 | + | port_id | 462c92c6-941c-48ab-8cca-3c7a7308f580 | + | router_id | 7f8ee1f6-7211-40e8-b9a8-17582ecfe50b | + | status | DOWN | + | tenant_id | 0cb06b70ef67424b8add447415449722 | + +---------------------+--------------------------------------+ + +All right, now you're ready to go ahead and create members for the load balancer pool, referencing the floating IPs: + +:: + + $ neutron lb-member-create --address 203.0.113.21 --protocol-port 80 mypool + Created a new member: + +--------------------+--------------------------------------+ + | Field | Value | + +--------------------+--------------------------------------+ + | address | 203.0.113.21 | + | admin_state_up | True | + | id | 679966a9-f719-4df0-86cf-3a24d0433b38 | + | pool_id | 600496f0-196c-431c-ae35-a0af9bb01d32 | + | protocol_port | 80 | + | status | PENDING_CREATE | + | status_description | | + | tenant_id | 0cb06b70ef67424b8add447415449722 | + | weight | 1 | + +--------------------+--------------------------------------+ + + $ neutron lb-member-create --address 203.0.113.22 --protocol-port 80 mypool + Created a new member: + +--------------------+--------------------------------------+ + | Field | Value | + +--------------------+--------------------------------------+ + | address | 203.0.113.22 | + | admin_state_up | True | + | id | f3ba0605-4926-4498-b86d-51002892e93a | + | pool_id | 600496f0-196c-431c-ae35-a0af9bb01d32 | + | protocol_port | 80 | + | status | PENDING_CREATE | + | status_description | | + | tenant_id | 0cb06b70ef67424b8add447415449722 | + | weight | 1 | + +--------------------+--------------------------------------+ + +You should be able to see them in the member list: + +:: + + $ neutron lb-member-list + +--------------------------------------+--------------+---------------+--------+----------------+--------+ + | id | address | protocol_port | weight | admin_state_up | status | + +--------------------------------------+--------------+---------------+--------+----------------+--------+ + | 679966a9-f719-4df0-86cf-3a24d0433b38 | 203.0.113.21 | 80 | 1 | True | ACTIVE | + | f3ba0605-4926-4498-b86d-51002892e93a | 203.0.113.22 | 80 | 1 | True | ACTIVE | + +--------------------------------------+--------------+---------------+--------+----------------+--------+ + +Now let's create a healthmonitor that will ensure that members of the loadbalancer pool are active and able +to respond to requests. If a member in the pool dies or is unresponsive, the member is removed from the pool +so that client requests are routed to another active member. + +:: + + $ neutron lb-healthmonitor-create --delay 3 --type HTTP --max-retries 3 --timeout 3 + Created a new health_monitor: + +----------------+--------------------------------------+ + | Field | Value | + +----------------+--------------------------------------+ + | admin_state_up | True | + | delay | 3 | + | expected_codes | 200 | + | http_method | GET | + | id | 663345e6-2853-43b2-9ccb-a623d5912345 | + | max_retries | 3 | + | pools | | + | tenant_id | 0cb06b70ef67424b8add447415449722 | + | timeout | 3 | + | type | HTTP | + | url_path | / | + +----------------+--------------------------------------+ + $ neutron lb-healthmonitor-associate 663345e6-2853-43b2-9ccb-a623d5912345 mypool + Associated health monitor 663345e6-2853-43b2-9ccb-a623d5912345 + +Now create a virtual IP that will be used to direct traffic between the various members of the pool: + +:: + + $ neutron lb-vip-create --name myvip --protocol-port 80 --protocol HTTP --subnet-id 47fd3ff1-ead6-4d23-9ce6-2e66a3dae425 mypool + Created a new vip: + +---------------------+--------------------------------------+ + | Field | Value | + +---------------------+--------------------------------------+ + | address | 203.0.113.63 | + | admin_state_up | True | + | connection_limit | -1 | + | description | | + | id | f0bcb66e-5eeb-447b-985e-faeb67540c2f | + | name | myvip | + | pool_id | 600496f0-196c-431c-ae35-a0af9bb01d32 | + | port_id | bc732f81-2640-4622-b624-993a5ae185c5 | + | protocol | HTTP | + | protocol_port | 80 | + | session_persistence | | + | status | PENDING_CREATE | + | status_description | | + | subnet_id | 47fd3ff1-ead6-4d23-9ce6-2e66a3dae425 | + | tenant_id | 0cb06b70ef67424b8add447415449722 | + +---------------------+--------------------------------------+ + +And confirm it's in place: + +:: + + $ neutron lb-vip-list + +--------------------------------------+-------+--------------+----------+----------------+--------+ + | id | name | address | protocol | admin_state_up | status | + +--------------------------------------+-------+--------------+----------+----------------+--------+ + | f0bcb66e-5eeb-447b-985e-faeb67540c2f | myvip | 203.0.113.63 | HTTP | True | ACTIVE | + +--------------------------------------+-------+--------------+----------+----------------+--------+ + +Now let's look at the big picture. + +Final Result +------------ + +With the addition of the loadbalancer, the Fractal app's networking topology now reflects the modular +nature of the application itself. + + +.. nwdiag:: + + nwdiag { + + network public { + address = "203.0.113.0/24" + tenant_router [ address = "203.0.113.60"]; + loadbalancer [ address = "203.0.113.63" ]; + } + + network webserver_network{ + address = "10.0.2.0/24" + tenant_router [ address = "10.0.2.1"]; + webserver1 [ address = "203.0.113.21, 10.0.2.3"]; + webserver2 [ address = "203.0.113.22, 10.0.2.4"]; + } + network api_network { + address = "10.0.3.0/24" + tenant_router [ address = "10.0.3.1" ]; + api1 [ address = "10.0.3.3" ]; + api2 [ address = "10.0.3.4" ]; + } + + network worker_network { + address = "10.0.1.0/24" + tenant_router [ address = "10.0.1.1" ]; + worker1 [ address = "10.0.1.5" ]; + worker2 [ address = "10.0.1.6" ]; + } + } + + +Next Steps +---------- + +You should now be fairly confident working with Network API. +There are several calls we did not cover. To see these and more, +refer to the volume documentation of your SDK, or try a different step in the tutorial, including: + +* :doc:`/section8` - for advice for developers new to operations +* :doc:`/section9` - to see all the crazy things we think ordinary folks won't want to do ;) + + diff --git a/openstack-firstapp/doc/source/section8.rst b/openstack-firstapp/doc/source/section8.rst new file mode 100644 index 000000000..b750c6882 --- /dev/null +++ b/openstack-firstapp/doc/source/section8.rst @@ -0,0 +1,119 @@ +====================================================== +Section Eight: Advice for Developers new to Operations +====================================================== + +In this section, we will introduce some operational concepts and tasks which may +be new to developers who have not written cloud applications before. + +Monitoring +---------- + +Monitoring is essential for cloud applications, especially if the application is +to be 'scalable'. You must know how many requests are coming in, and what impact +that has on the various services -- in other words, enough information to determine whether you +should start another worker or API service as we did in :doc:`/section3`. + +.. todo:: explain how to achieve this kind of monitoring. Ceilometer? (STOP LAUGHING.) + +Aside from this kind of monitoring, you should consider availability monitoring. +Does your application care about a worker going down? Maybe not. Does it care +about a failed database server? Probably yes. + +One great pattern to add this to your application is the +`Health Endpoint Monitoring Pattern `, +where a special API endpoint is introduced to your application for a basic +health check. + +Backups +------- + +Where instances store information that is not reproducable (such as a database +server, a file server, or even log files for an application), it is important to +back up this information as you would a normal non-cloud server. It sounds +simple, but just because it is 'in the cloud' does not mean it has any additional +robustness or resilience when it comes to failure of the underlying hardware or systems. + +OpenStack provides a couple of tools that make it easier to perform backups. If +your provider runs OpenStack Object Storage, this is normally extremely robust +and has several handy API calls and CLI tools for working with archive files. + +It is also possible to create snapshots of running instances and persistent +volumes using the OpenStack API. Refer to the documentation of your SDK for +more. + +.. todo:: link to appropriate documentation, or better yet, link and also include the commands here + +While the technical action to perform backups can be straightforward, you should +also think about your policies regarding what is backed up and how long each item +should be retained. + +Phoenix Servers +--------------- + +Application developers and operators who employ +`Phoenix Servers `_ +have built systems that start from a known baseline (sometimes just a specific +version of an operating system) and have built tooling that will automatically +build, install, and configure a system with no manual intervention. + +Phoenix Servers, named for the mythological bird that would live its life, +be consumed by fire, then rise from the ashes to live again, make it possible +to easily "start over" with new instances. + +If your application is automatically deployed on a regular basis, resolving outages and +security updates are not special operations that require manual intervention. +If you suffer an outage, provision more resources in another region. If you have +to patch security holes, provision more compute nodes that will be built with +the updated/patched software, then terminate vulnerable nodes, with traffic +automatically failing over to the new instances. + +Security +-------- + +Security-wise, one thing to keep in mind is that if one instance of an application +is compromised, all instances with the same image and configuration are likely +to suffer the same vulnerability. In this case, it is safer to rebuild all of your +instances (a task made easier by configuration management - see below). + +Configuration Management +------------------------ + +Tools such as Ansible, Chef, and Puppet allow you to describe exactly what should +be installed on an instance and how it should be configured. Using these +descriptions, the tool implements any changes required to get to the desired state. + +These tools vastly reduce the amount of effort it takes to work with large numbers of servers, +and also improves the ability to recreate, update, move, or distribute applications. + +Application Deployment +---------------------- + +Related to configuration management is the question of how you deploy your application. + +For example, do you: +* pull the latest code from a source control repository? +* make packaged releases that update infrequently? +* big-bang test in a development environment and deploy only after major changes? + +One of the latest trends in deploying scalable cloud applications is +`continuous integration `_ / +`continuous deployment `_ (CI/CD). +Working in a CI/CD fashion means +you are always testing your application and making frequent deployments to +production. + +In this tutorial, we have downloaded the latest version of our application +from source and installed it on a standard image. Our magic install script also +updates the standard image to have the latest dependencies we need to run the +application. + +Another approach to this is to create a 'gold' image - one that has your +application and dependencies pre-installed. This means faster boot times and +a higher degree of control over what is on the instance, however a process is +needed to ensure that 'gold' images do not fall behind on security updates. + +Fail Fast +--------- + + + diff --git a/openstack-firstapp/doc/source/section9.rst b/openstack-firstapp/doc/source/section9.rst new file mode 100644 index 000000000..02e62e5dc --- /dev/null +++ b/openstack-firstapp/doc/source/section9.rst @@ -0,0 +1,60 @@ +========================= +Section Nine: Going Crazy +========================= + +In this section, we will look at further options for expanding the sample application. + +Regions and geographic diversity +-------------------------------- + +.. note:: For more information on multi-site clouds, check out the `Multi-Site chapter `_ of the Architecture Design Guide. + +OpenStack supports the concepts of 'Regions' - ususally geographicaly separated installations that are +all connected to the one service catalogue. This section explains how to expand the Fractal app to +to use multiple regions for high availability. + +.. note:: This section is incomplete. Please help us finish it! + +Multiple clouds +--------------- + +.. note:: For more information on hybrid-clouds, check out the `Hybrid Cloud chapter `_ of the Architecture Design Guide + +Sometimes, you want to use multiple clouds, such as a private cloud inside your organisation +and a public cloud. This section attempts to do exactly that. + +.. note:: This section is incomplete. Please help us finish it! + +High Availability +----------------- +Using Pacemaker to look at the API. + +.. note:: This section is incomplete. Please help us finish it! + +conf.d, etc.d +------------- +Use conf.d and etc.d. + +In earlier sections, the Fractal Application uses an install script, with parameters passed in from the metadata API, +in order to bootstrap the cluster. `Etcd `_ is a "a distributed, consistent key value store for shared configuration and service discovery" +that can be used for storing configuration. Updated versions of the Fractal worker +component could be writted to connect to Etcd, or use `Confd `_ which will +poll for changes from Etcd and write changes to a configuration file on the local filesystem, which the Fractal worker +could use for configuration. + +Using Swift instead of a database +--------------------------------- + +We haven't quite figured out how to do this yet, but the general steps involve changing the fractal upload +code to store metadata with the object in swift, then changing the API code such as "list fractals" to +query swift to retrieve the metadata. If you do this, you should be able to stop using a database. + +.. note:: This section is incomplete. Please help us finish it! + +Next Steps +---------- +Wow, if you've made it through this section, you know more about +working with OpenStack clouds than the authors of this guide. + +Perhaps you can `contribute `_? + diff --git a/openstack-firstapp/samples/fog/section1.rb b/openstack-firstapp/samples/fog/section1.rb new file mode 100644 index 000000000..d21bc843c --- /dev/null +++ b/openstack-firstapp/samples/fog/section1.rb @@ -0,0 +1,55 @@ +# step-1 +require 'fog' + +auth_username = 'your_auth_username' +auth_password = 'your_auth_password' +auth_url = 'http://controller:5000' +project_name = 'your_project_name_or_id' +region_name = 'your_region_name' + +conn = Fog::Compute.new({ + :provider => 'openstack', + :openstack_auth_url => auth_url + '/v2.0/tokens', + :openstack_username => auth_username + :openstack_tenant => project_name + :openstack_api_key => auth_password +}) + +# step-2 +images = conn.list_images +print images.body + +# step-3 +flavors = conn.list_flavors +print flavors.body + +# step-4 +image_id = '2cccbea0-cea9-4f86-a3ed-065c652adda5' +image = conn.images.get image_id +print image + +# step-5 +flavor_id = '3' +image = conn.flavor.get flavor_id +print flavor + +# step-6 +instance_name = 'testing' +testing_instance = conn.servers.create(:name => instance_name, :flavor_ref => flavor.id, :image_ref => image.id) + +# step-7 +conn.servers + +# step-8 +testing_instance.destroy + +# step-9 + +# step-10 +all_in_one_security_group = conn.create_security_group 'all-in-one' 'network access for all-in-one application.' +conn.create_security_group_rule all_in_one_security_group 'TCP' 80 80 +conn.create_security_group_rule all_in_one_security_group 'TCP' 22 22 + +# step-11 +# step-12 +# step-13 diff --git a/openstack-firstapp/samples/libcloud/section1.py b/openstack-firstapp/samples/libcloud/section1.py new file mode 100644 index 000000000..9a2a56bf8 --- /dev/null +++ b/openstack-firstapp/samples/libcloud/section1.py @@ -0,0 +1,119 @@ +# step-1 +from libcloud.compute.types import Provider +from libcloud.compute.providers import get_driver + +auth_username = 'your_auth_username' +auth_password = 'your_auth_password' +auth_url = 'http://controller:5000' +project_name = 'your_project_name_or_id' +region_name = 'your_region_name' + +provider = get_driver(Provider.OPENSTACK) +conn = provider(auth_username, + auth_password, + ex_force_auth_url=auth_url, + ex_force_auth_version='2.0_password', + ex_tenant_name=project_name, + ex_force_service_region=region_name) + +# step-2 +images = conn.list_images() +for image in images: + print(image) + +# step-3 +flavors = conn.list_sizes() +for flavor in flavors: + print(flavor) + +# step-4 +image_id = '2cccbea0-cea9-4f86-a3ed-065c652adda5' +image = conn.get_image(image_id) +print(image) + +# step-5 +flavor_id = '3' +flavor = conn.ex_get_size(flavor_id) +print(flavor) + +# step-6 +instance_name = 'testing' +testing_instance = conn.create_node(name=instance_name, image=image, size=flavor) +print(testing_instance) + +# step-7 +instances = conn.list_nodes() +for instance in instances: + print(instance) + +# step-8 +conn.destroy_node(testing_instance) + +# step-9 +print('Checking for existing SSH key pair...') +keypair_name = 'demokey' +pub_key_file = '~/.ssh/id_rsa.pub' +keypair_exists = False +for keypair in conn.list_key_pairs(): + if keypair.name == keypair_name: + keypair_exists = True + +if keypair_exists: + print('Keypair already exists. Skipping import.') +else: + print('adding keypair...') + conn.import_key_pair_from_file(keypair_name, pub_key_file) + +for keypair in conn.list_key_pairs(): + print(keypair) + + +# step-10 +security_group_exists = False +for security_group in conn.ex_list_security_groups(): + if security_group.name =='all-in-one': + all_in_one_security_group = security_group + security_group_exists = True + +if security_group_exists: + print('Security Group already exists. Skipping creation.') +else: + all_in_one_security_group = conn.ex_create_security_group('all-in-one', 'network access for all-in-one application.') + conn.ex_create_security_group_rule(all_in_one_security_group, 'TCP', 80, 80) + conn.ex_create_security_group_rule(all_in_one_security_group, 'TCP', 22, 22) + +# step-11 +userdata = '''#!/usr/bin/env bash +curl -L -s https://git.openstack.org/cgit/stackforge/faafo/plain/contrib/install.sh | bash -s -- \ + -i faafo -i messaging -r api -r worker -r demo +''' + +# step-12 +instance_name = 'all-in-one' +testing_instance = conn.create_node(name=instance_name, + image=image, + size=flavor, + ex_keyname=keypair_name, + ex_userdata=userdata, + ex_security_groups=[all_in_one_security_group]) +conn.wait_until_running([testing_instance]) + +# step-13 +print('Checking for unused Floating IP...') +unused_floating_ip = None +for floating_ip in conn.ex_list_floating_ips(): + if floating_ip.node_id: + unused_floating_ip = floating_ip + break + + +if not unused_floating_ip: + pool = conn.ex_list_floating_ip_pools()[0] + print('Allocating new Floating IP from pool: {}'.format(pool)) + unused_floating_ip = pool.create_floating_ip() + +# step-14 +conn.ex_attach_floating_ip_to_node(testing_instance, unused_floating_ip) + +# step-15 +print('The Fractals app will be deployed to http://%s' % unused_floating_ip.ip_address) diff --git a/openstack-firstapp/samples/libcloud/section2.py b/openstack-firstapp/samples/libcloud/section2.py new file mode 100644 index 000000000..8e80d528b --- /dev/null +++ b/openstack-firstapp/samples/libcloud/section2.py @@ -0,0 +1,133 @@ +# step-1 +userdata = '''#!/usr/bin/env bash +curl -L -s https://git.openstack.org/cgit/stackforge/faafo/plain/contrib/install.sh | bash -s -- \ + -i faafo -i messaging -r api -r worker -r demo +''' + +instance_name = 'all-in-one' +testing_instance = conn.create_node(name=instance_name, + image=image, + size=flavor, + ex_keyname=keypair_name, + ex_userdata=userdata, + ex_security_groups=[all_in_one_security_group]) + +# step-2 +userdata = '''#!/usr/bin/env bash +curl -L -s https://git.openstack.org/cgit/stackforge/faafo/plain/contrib/install.sh | bash -s -- \ + -i messaging -i faafo -r api -r worker -r demo +''' + +# step-3 +all_in_one_security_group = conn.ex_create_security_group('all-in-one', 'network access for all-in-one application.') +conn.ex_create_security_group_rule(all_in_one_security_group, 'TCP', 80, 80) +conn.ex_create_security_group_rule(all_in_one_security_group, 'TCP', 22, 22) + +# step-4 +conn.ex_list_security_groups() + +# step-5 +conn.ex_delete_security_group_rule(rule) +conn.ex_delete_security_group(security_group) + +# step-6 +conn.ex_get_node_security_groups(testing_instance) + +# step-7 +unused_floating_ip = None +for floating_ip in conn.ex_list_floating_ips(): + if not floating_ip.node_id: + unused_floating_ip = floating_ip + print("Found an unused Floating IP: %s" % floating_ip) + break + +# step-8 +pool = conn.ex_list_floating_ip_pools()[0] + +# step-9 +unused_floating_ip = pool.create_floating_ip() + +# step-10 +conn.ex_attach_floating_ip_to_node(instance, unused_floating_ip) + +# step-11 +worker_group = conn.ex_create_security_group('worker', 'for services that run on a worker note') +conn.ex_create_security_group_rule(worker_group, 'TCP', 22, 22) + +controller_group = conn.ex_create_security_group('control', 'for services that run on a control note') +conn.ex_create_security_group_rule(controller_group, 'TCP', 22, 22) +conn.ex_create_security_group_rule(controller_group, 'TCP', 80, 80) +conn.ex_create_security_group_rule(controller_group, 'TCP', 5672, 5672, source_security_group=worker_group) + +userdata = '''#!/usr/bin/env bash +curl -L -s http://git.openstack.org/cgit/stackforge/faafo/plain/contrib/install.sh | bash -s -- \ + -i messaging -i faafo -r api +''' + +instance_controller_1 = conn.create_node(name='app-controller', + image=image, + size=flavor, + ex_keyname='demokey', + ex_userdata=userdata, + ex_security_groups=[controller_group]) + +conn.wait_until_running([instance_controller_1]) +print('Checking for unused Floating IP...') +unused_floating_ip = None +for floating_ip in conn.ex_list_floating_ips(): + if not floating_ip.node_id: + unused_floating_ip = floating_ip + break + + +if not unused_floating_ip: + pool = conn.ex_list_floating_ip_pools()[0] + print('Allocating new Floating IP from pool: {}'.format(pool)) + unused_floating_ip = pool.create_floating_ip() + + +conn.ex_attach_floating_ip_to_node(instance_controller_1, unused_floating_ip) +print('Application will be deployed to http://%s' % unused_floating_ip.ip_address) + +# step-12 +instance_controller_1 = conn.ex_get_node_details(instance_controller_1.id) +if instance_controller_1.public_ips: + ip_controller = instance_controller_1.private_ips[0] +else: + ip_controller = instance_controller_1.public_ips[0] + +userdata = '''#!/usr/bin/env bash +curl -L -s http://git.openstack.org/cgit/stackforge/faafo/plain/contrib/install.sh | bash -s -- \ + -i faafo -r worker -e 'http://%(ip_controller)s' -m 'amqp://guest:guest@%(ip_controller)s:5672/' +''' % {'ip_controller': ip_controller} +instance_worker_1 = conn.create_node(name='app-worker-1', + image=image, + size=flavor, + ex_keyname='demokey', + ex_userdata=userdata, + ex_security_groups=[worker_group]) + +conn.wait_until_running([instance_worker_1]) +print('Checking for unused Floating IP...') +unused_floating_ip = None +for floating_ip in conn.ex_list_floating_ips(): + if not floating_ip.node_id: + unused_floating_ip = floating_ip + break + + +if not unused_floating_ip: + pool = conn.ex_list_floating_ip_pools()[0] + print('Allocating new Floating IP from pool: {}'.format(pool)) + unused_floating_ip = pool.create_floating_ip() + + +conn.ex_attach_floating_ip_to_node(instance_worker_1, unused_floating_ip) +print('The worker will be available for SSH at %s' % unused_floating_ip.ip_address) + + +# step-13 +ip_instance_worker_1 = instance_worker_1.private_ips[0] +print(ip_instance_worker_1) + +# step-14 diff --git a/openstack-firstapp/samples/libcloud/section3.py b/openstack-firstapp/samples/libcloud/section3.py new file mode 100644 index 000000000..7e2958dae --- /dev/null +++ b/openstack-firstapp/samples/libcloud/section3.py @@ -0,0 +1,110 @@ +# step-1 +for instance in conn.list_nodes(): + if instance.name in ['all-in-one','app-worker-1', 'app-worker-2', 'app-controller']: + print('Destroying Instance: %s' % instance.name) + conn.destroy_node(instance) + + +for group in conn.ex_list_security_groups(): + if group.name in ['control', 'worker', 'api', 'services']: + print('Deleting security group: %s' % group.name) + conn.ex_delete_security_group(group) + +# step-2 +api_group = conn.ex_create_security_group('api', 'for API services only') +conn.ex_create_security_group_rule(api_group, 'TCP', 80, 80) +conn.ex_create_security_group_rule(api_group, 'TCP', 22, 22) + +worker_group = conn.ex_create_security_group('worker', 'for services that run on a worker note') +conn.ex_create_security_group_rule(worker_group, 'TCP', 22, 22) + +controller_group = conn.ex_create_security_group('control', 'for services that run on a control note') +conn.ex_create_security_group_rule(controller_group, 'TCP', 22, 22) +conn.ex_create_security_group_rule(controller_group, 'TCP', 80, 80) +conn.ex_create_security_group_rule(controller_group, 'TCP', 5672, 5672, source_security_group=worker_group) + +services_group = conn.ex_create_security_group('services', 'for DB and AMQP services only') +conn.ex_create_security_group_rule(services_group, 'TCP', 22, 22) +conn.ex_create_security_group_rule(services_group, 'TCP', 3306, 3306, source_security_group=api_group) +conn.ex_create_security_group_rule(services_group, 'TCP', 5672, 5672, source_security_group=worker_group) +conn.ex_create_security_group_rule(services_group, 'TCP', 5672, 5672, source_security_group=api_group) + +# step-3 +def get_floating_ip(conn): + '''A helper function to re-use available Floating IPs''' + unused_floating_ip = None + for floating_ip in conn.ex_list_floating_ips(): + if not floating_ip.node_id: + unused_floating_ip = floating_ip + break + if not unused_floating_ip: + pool = conn.ex_list_floating_ip_pools()[0] + unused_floating_ip = pool.create_floating_ip() + return unused_floating_ip + +# step-4 +userdata = '''#!/usr/bin/env bash +curl -L -s http://git.openstack.org/cgit/stackforge/faafo/plain/contrib/install.sh | bash -s -- \ + -i database -i messaging +''' + +instance_services = conn.create_node(name='app-services', + image=image, + size=flavor, + ex_keyname='demokey', + ex_userdata=userdata, + ex_security_groups=[services_group]) +instance_services = conn.wait_until_running([instance_services])[0][0] +services_ip = instance_services.private_ips[0] + + +# step-5 +userdata = '''#!/usr/bin/env bash +curl -L -s http://git.openstack.org/cgit/stackforge/faafo/plain/contrib/install.sh | bash -s -- \ + -i faafo -r api -m 'amqp://guest:guest@%(services_ip)s:5672/' \ + -d 'mysql://faafo:password@%(services_ip)s:3306/faafo' +''' % { 'services_ip': services_ip } +instance_api_1 = conn.create_node(name='app-api-1', + image=image, + size=flavor, + ex_keyname='demokey', + ex_userdata=userdata, + ex_security_groups=[api_group]) +instance_api_2 = conn.create_node(name='app-api-2', + image=image, + size=flavor, + ex_keyname='demokey', + ex_userdata=userdata, + ex_security_groups=[api_group]) +instance_api_1 = conn.wait_until_running([instance_api_1])[0][0] +api_1_ip = instance_api_1.private_ips[0] +instance_api_2 = conn.wait_until_running([instance_api_2])[0][0] +api_2_ip = instance_api_2.private_ips[0] + +for instance in [instance_api_1, instance_api_2]: + floating_ip = get_floating_ip(conn) + conn.ex_attach_floating_ip_to_node(instance, floating_ip) + print('allocated %(ip)s to %(host)s' % {'ip': floating_ip.ip_address, 'host': instance.name}) + +# step-6 +userdata = '''#!/usr/bin/env bash +curl -L -s http://git.openstack.org/cgit/stackforge/faafo/plain/contrib/install.sh | bash -s -- \ + -i faafo -r worker -e 'http://%(api_1_ip)s' -m 'amqp://guest:guest@%(services_ip)s:5672/' +''' % {'api_1_ip': api_1_ip, 'services_ip': services_ip} +instance_worker_1 = conn.create_node(name='app-worker-1', + image=image, size=flavor, + ex_keyname='demokey', + ex_userdata=userdata, + ex_security_groups=[worker_group]) +instance_worker_2 = conn.create_node(name='app-worker-2', + image=image, size=flavor, + ex_keyname='demokey', + ex_userdata=userdata, + ex_security_groups=[worker_group]) +instance_worker_3 = conn.create_node(name='app-worker-3', + image=image, size=flavor, + ex_keyname='demokey', + ex_userdata=userdata, + ex_security_groups=[worker_group]) + +# step-7 diff --git a/openstack-firstapp/samples/libcloud/section4.py b/openstack-firstapp/samples/libcloud/section4.py new file mode 100644 index 000000000..ed2e9b3d3 --- /dev/null +++ b/openstack-firstapp/samples/libcloud/section4.py @@ -0,0 +1,93 @@ +# step-1 +from libcloud.storage.types import Provider +from libcloud.storage.providers import get_driver + +auth_username = 'your_auth_username' +auth_password = 'your_auth_password' +auth_url = 'http://controller:5000' +project_name = 'your_project_name_or_id' +region_name = 'your_region_name' + +provider = get_driver(Provider.OPENSTACK_SWIFT) +swift = provider(auth_username, + auth_password, + ex_force_auth_url=auth_url, + ex_force_auth_version='2.0_password', + ex_tenant_name=project_name, + ex_force_service_region=region_name) + +# step-2 +container_name = 'fractals' +container = swift.create_container(container_name=container_name) +print(container) + +# step-3 +print(swift.list_containers()) + +# step-4 +file_path = 'goat.jpg' +object_name = 'an amazing goat' +container = swift.get_container(container_name=container_name) +object = container.upload_object(file_path=file_path, object_name=object_name) + +# step-5 +objects = container.list_objects() +print(objects) + +# step-6 +object = swift.get_object(container_name, object_name) +print object + +# step-7 +import hashlib +print(hashlib.md5(open('goat.jpg', 'rb').read()).hexdigest()) + +# step-8 +swift.delete_object(object) + +# step-9 +objects = container.list_objects() +print(objects) + +# step-10 +container_name = 'fractals' +container = swift.get_container(container_name) + +# step-11 +import base64 +import cStringIO +import json + +import requests + +endpoint = 'http://IP_API_1' +params = { 'results_per_page': '-1' } +response = requests.get('%s/v1/fractal' % endpoint, params=params) +data = json.loads(response.text) +for fractal in data['objects']: + response = requests.get('%s/fractal/%s' % (endpoint, fractal['uuid']), stream=True) + container.upload_object_via_stream(response.iter_content(), object_name=fractal['uuid']) + +for object in container.list_objects(): + print(object) + +# step-12 +for object in container.list_objects(): + container.delete_object(object) +swift.delete_container(container) + +# step-13 +file_path = 'goat.jpg' +object_name = 'backup_goat.jpg' +extra = {'meta_data': {'description': 'a funny goat', 'created': '2015-06-02'}} +with open('goat.jpg', 'rb') as iterator: + object = swift.upload_object_via_stream(iterator=iterator, + container=container, + object_name=object_name, + extra=extra) + +# step-14 +swift.ex_multipart_upload_object(file_path, container, object_name, + chunk_size=33554432) + +# step-15 diff --git a/openstack-firstapp/setup.cfg b/openstack-firstapp/setup.cfg new file mode 100644 index 000000000..3e9bacaa8 --- /dev/null +++ b/openstack-firstapp/setup.cfg @@ -0,0 +1,23 @@ +[metadata] +name = OpenStack First Application +summary = OpenStack First Application +description-file = + README.rst +author = OpenStack Documentation +author-email = openstack-docs@lists.openstack.org +home-page = http://docs.openstack.org/ +classifier = + Intended Audience :: Developers + License :: OSI Approved :: Apache Software License + Operating System :: POSIX :: Linux + +[build_sphinx] +all_files = 1 +build-dir = doc/build +source-dir = doc/source + +[pbr] +warnerrors = True + +[wheel] +universal = 1 diff --git a/openstack-firstapp/setup.py b/openstack-firstapp/setup.py new file mode 100755 index 000000000..ed58d0f26 --- /dev/null +++ b/openstack-firstapp/setup.py @@ -0,0 +1,6 @@ +#!/usr/bin/env python +import setuptools + +setuptools.setup( + setup_requires=['pbr'], + pbr=True) diff --git a/test-requirements.txt b/test-requirements.txt index 03c204a80..ecfd8c96f 100644 --- a/test-requirements.txt +++ b/test-requirements.txt @@ -2,3 +2,13 @@ # of appearance. Changing the order has an impact on the overall integration # process, which may cause wedges in the gate later. openstack-doc-tools>=0.23 +Pygments +docutils<=0.9.1 +sphinx>=1.1.2,<1.2 +pbr>=0.6,!=0.7,<1.0 +oslosphinx +openstackdocstheme +nwdiag +blockdiag +sphinxcontrib-blockdiag +sphinxcontrib-nwdiag diff --git a/tox.ini b/tox.ini index b48e5493f..27e303315 100644 --- a/tox.ini +++ b/tox.ini @@ -69,3 +69,23 @@ commands = doc-tools-check-languages doc-tools-check-languages.conf test {posarg sitepackages=True whitelist_externals = doc-tools-check-languages commands = doc-tools-check-languages doc-tools-check-languages.conf publish all + +[testenv:openstack-firstapp-libcloud] +commands = sphinx-build -E -W -t libcloud openstack-firstapp/doc/source openstack-firstapp/build/html +[testenv:openstack-firstapp-jclouds] +commands = sphinx-build -E -W -t jclouds openstack-firstapp/doc/source openstack-firstapp/build/html + +[testenv:openstack-firstapp-fog] +commands = sphinx-build -E -W -t fog openstack-firstapp/doc/source openstack-firstapp/build/html + +[testenv:openstack-firstapp-dotnet] +commands = sphinx-build -E -W -t dotnet openstack-firstapp/doc/source openstack-firstapp/build/html + +[testenv:openstack-firstapp-node] +commands = sphinx-build -E -W -t node openstack-firstapp/doc/source openstack-firstapp/build/html + +[testenv:openstack-firstapp-openstacksdk] +commands = sphinx-build -E -W -t openstacksdk openstack-firstapp/doc/source openstack-firstapp/build/html + +[testenv:openstack-firstapp-todos] +commands = sphinx-build -E -W -t libcloud openstack-firstapp/doc/source openstack-firstapp/build/html