Skip to content

Commit 7555767

Browse files
committed
Updated with Chef , Buildout , Blueprint
1 parent beaae53 commit 7555767

1 file changed

Lines changed: 162 additions & 6 deletions

File tree

docs/scenarios/admin.rst

Lines changed: 162 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -236,10 +236,25 @@ about Ansible, read the `Ansible Docs <http://docs.ansible.com/>`_.
236236
Chef
237237
----
238238

239-
.. todo:: Write about Chef
239+
Chef is a systems and cloud infrastructure automation framework that makes it easy to deploy servers and applications to any physical, virtual, or cloud location, no matter the size of the infrastructure. Each organization is comprised of one (or more) workstations, a single server, and every node that will be configured and maintained by the chef-client. Cookbooks (and recipes) are used to tell the chef-client how each node in your organization should be configured. The chef-client (which is installed on every node) does the actual configuration.
240240

241-
`Chef Documentation
242-
<http://wiki.opscode.com/display/chef/Documentation>`_
241+
The Chef Server
242+
---------------
243+
244+
The Chef server acts as a hub for configuration data. The Chef server stores cookbooks, the policies that are applied to nodes, and metadata that describes each registered node that is being managed by the chef-client. Nodes use the chef-client to ask the Chef server for configuration details, such as recipes, templates, and file distributions. The chef-client then does as much of the configuration work as possible on the nodes themselves (and not on the Chef server). This scalable approach distributes the configuration effort throughout the organization.
245+
246+
Server Essentials
247+
-----------------
248+
249+
The server acts as a repository for all of the data that may be needed by the chef-client while it configures a node:
250+
251+
* A node object exists for each node that is being managed by the chef-client
252+
* Each node object consists of a run-list and a collection of attributes
253+
* All data that is stored on the Chef server—including everything uploaded to the server from the chef-repo and by the chef-client—is searchable from both recipes (using the search method in the Recipe DSL) and the workstation (using the knife search subcommand)
254+
* The Chef server can apply global policy settings to all nodes across the organization, including for data bags, environments, and roles
255+
* The authentication process ensures that requests can only be made to the Chef server by authorized users
256+
* Users, once authorized can only perform certain actions
257+
* The Chef server provides powerful search functionality
243258

244259
Puppet
245260
------
@@ -340,12 +355,153 @@ For more information, refer to the `Puppet Labs Documentation <http://docs.puppe
340355
Blueprint
341356
---------
342357

343-
.. todo:: Write about Blueprint
358+
Flask uses a concept of blueprints for making application components and supporting common patterns within an application or across applications. Blueprints can greatly simplify how large applications work and provide a central means for Flask extensions to register operations on applications. A Blueprint object works similarly to a Flask application object, but it is not actually an application. Rather it is a blueprint of how to construct or extend an application.
359+
360+
Why Blueprints?
361+
Blueprints in Flask are intended for these cases:
362+
363+
Factor an application into a set of blueprints. This is ideal for larger applications; a project could instantiate an application object, initialize several extensions, and register a collection of blueprints.
364+
Register a blueprint on an application at a URL prefix and/or subdomain. Parameters in the URL prefix/subdomain become common view arguments (with defaults) across all view functions in the blueprint.
365+
Register a blueprint multiple times on an application with different URL rules.
366+
Provide template filters, static files, templates, and other utilities through blueprints. A blueprint does not have to implement applications or view functions.
367+
Register a blueprint on an application for any of these cases when initializing a Flask extension.
368+
A blueprint in Flask is not a pluggable app because it is not actually an application – it’s a set of operations which can be registered on an application, even multiple times. Why not have multiple application objects? You can do that (see Application Dispatching), but your applications will have separate configs and will be managed at the WSGI layer.
369+
370+
Blueprints instead provide separation at the Flask level, share application config, and can change an application object as necessary with being registered. The downside is that you cannot unregister a blueprint once an application was created without having to destroy the whole application object.
371+
372+
The Concept of Blueprints
373+
-------------------------
374+
The basic concept of blueprints is that they record operations to execute when registered on an application. Flask associates view functions with blueprints when dispatching requests and generating URLs from one endpoint to another.
375+
376+
My First Blueprint
377+
------------------
378+
This is what a very basic blueprint looks like. In this case we want to implement a blueprint that does simple rendering of static templates:
379+
from flask import Blueprint, render_template, abort
380+
from jinja2 import TemplateNotFound
381+
382+
simple_page = Blueprint('simple_page', __name__,
383+
template_folder='templates')
384+
385+
@simple_page.route('/', defaults={'page': 'index'})
386+
@simple_page.route('/<page>')
387+
def show(page):
388+
try:
389+
return render_template('pages/%s.html' % page)
390+
except TemplateNotFound:
391+
abort(404)
392+
When you bind a function with the help of the @simple_page.route decorator the blueprint will record the intention of registering the function show on the application when it’s later registered. Additionally it will prefix the endpoint of the function with the name of the blueprint which was given to the Blueprint constructor (in this case also simple_page).
393+
394+
Registering Blueprints
395+
----------------------
396+
So how do you register that blueprint? Like this:
397+
398+
from flask import Flask
399+
from yourapplication.simple_page import simple_page
400+
401+
app = Flask(__name__)
402+
app.register_blueprint(simple_page)
403+
If you check the rules registered on the application, you will find these:
404+
405+
[<Rule '/static/<filename>' (HEAD, OPTIONS, GET) -> static>,
406+
<Rule '/<page>' (HEAD, OPTIONS, GET) -> simple_page.show>,
407+
<Rule '/' (HEAD, OPTIONS, GET) -> simple_page.show>]
408+
The first one is obviously from the application ifself for the static files. The other two are for the show function of the simple_page blueprint. As you can see, they are also prefixed with the name of the blueprint and separated by a dot (.).
409+
410+
Blueprints however can also be mounted at different locations:
411+
412+
app.register_blueprint(simple_page, url_prefix='/pages')
413+
And sure enough, these are the generated rules:
414+
415+
[<Rule '/static/<filename>' (HEAD, OPTIONS, GET) -> static>,
416+
<Rule '/pages/<page>' (HEAD, OPTIONS, GET) -> simple_page.show>,
417+
<Rule '/pages/' (HEAD, OPTIONS, GET) -> simple_page.show>]
418+
On top of that you can register blueprints multiple times though not every blueprint might respond properly to that. In fact it depends on how the blueprint is implemented if it can be mounted more than once.
419+
420+
more on blueprint @http://flask.pocoo.org/docs/0.10/blueprints/
421+
422+
423+
424+
344425

345426
Buildout
346427
--------
428+
Q: Where can I get a copy of the example module that you used in your PyAtl talk?
429+
430+
A: You can download the source code for the lunar module that I use as my central example in the talk right here:
431+
432+
http://rhodesmill.org/brandon/static/2008/lunar.tar.gz
433+
434+
Q: How can I start developing my Python package with buildout?
435+
436+
A: Move into the top-level directory of your package — the directory that has your setup.py file inside — and place two files there: bootstrap.py, which you can get in its most recent official version from this link, and a buildout.cfg that describes the development tools you want available. To gain the three tools I discuss in my presentations — a Python interpreter, access to the command-line scripts defined in your package, and a way to invoke your test suite — try out this sample buildout.cfg:
437+
438+
[config]
439+
mypkgs = lunar
440+
441+
[buildout]
442+
develop = .
443+
parts = python scripts test
444+
445+
[python]
446+
recipe = zc.recipe.egg
447+
interpreter = python
448+
eggs = {config:mypkgs}
449+
450+
[scripts]
451+
recipe = zc.recipe.egg:scripts
452+
eggs = {config:mypkgs}
453+
454+
[test]
455+
recipe = zc.recipe.testrunner
456+
eggs = {config:mypkgs}
457+
458+
Edit the first section of the file (whose name is arbitrary, by the way; config just made it easy for me to remember why I put it there) and change the package name lunar to the name you gave your package in the name option of its setup.py. Then, run:
459+
$ python bootstrap.py
460+
$ ./bin/buildout
461+
462+
And you should find that a ./bin/ directory appears with a python interpreter, a test runner, and any command-line scripts your module defines as console entry-points in its setup.py.
463+
464+
Q: Does the buildout system destroy anything?
465+
466+
A: Yes; buildout will consider itself the owner of these three directories at the top level of your project, so make sure that you are not using directories with these names if you do not want them overwritten:
467+
468+
develop-eggs/
469+
eggs/
470+
parts/
471+
472+
Q: What if I need a buildout that pulls eggs from other locations than the main Python Package Index?
473+
474+
A: Add some URLs to your buildout.cfg — they can point to any package index pages that the easy_install command would normally be able to digest — by adding this parameter (you can list several URLs if you want; the following URL is simply for illustration):
475+
find-links = http://download.zope.org/distribution/
476+
477+
Q: How can I avoid having every buildout on my system download a separate copy of each egg it needs?
478+
479+
A: You should tell your buildouts to download eggs into a single cache somewhere under your home directory. The buildouts will still be safely isolated from each other, since each version of an egg has its own filename! But instead of modifying every single buildout.cfg file to accomplish this, just create a ~/.buildout/ directory inside of your home directory, and place the following inside of a file named default.cfg:
480+
[buildout]
481+
eggs-directory = /home/brandon/eggs
482+
483+
484+
Q: How can I develop against another package's source code, before it gets packaged up as an egg?
485+
486+
A: Download or checkout the other package's source code into either a sub-directory of your project, or another directory under your account. Then, mention that directory's name in the develop declaration in the main section of your buildout. For example, in my presentation above I check out the SQLAlchemy trunk into the directory sqlalchemy, and then adjust my develop line to look like:
487+
[buildout]
488+
develop = . sqlalchemy
489+
But sometimes putting other projects in a sub-directory of your own project can be annoying. Your version control system might then start trying to include the other project in your commits, and if you have several projects that need access to the development version of a particular library, it might be annoying to have to check it out several times. So I often check out several projects, both my own and some others, into a single top-level directory, and then have their develop lines look something like:
490+
[buildout]
491+
develop = . ../sqlalchemy ../gatech.identity
492+
This way, a small cluster of applications and libraries that I will be releasing as a set of eggs can all get developed together. But it does have the disadvantage that if I actually check in my buildout.cfg while it looks this way, then other developers will have to mimic my directory structure (or re-edit the buildout.cfg) before they too can work on the project.
493+
494+
Q: Buildout keeps disrupting my development by downloading newer versions of dependency packages when they appear, which often have slight changes that break my application.
495+
496+
A: A quick fix is to add this line to the buildout section of your buildout.cfg file:
497+
498+
[buildout]
499+
newest = false
500+
But I argue that this is inadequate protection, because if you move to another machine and re-create the buildout, then you are still vulnerable to getting newer versions of dependencies than the ones you were already working with. And specifying newer = false provides no protection for co-workers on other machines, or for your customers who might later be installing your product as an egg using easy_install!
347501

348-
.. todo:: Write about Buildout
502+
That's why the real solution is to always specify absolute version numbers in your project's setup.py. Instead of just requiring 'pyephem', require something specific like:
349503

350-
`Buildout Website <http://www.buildout.org>`_
504+
install_requires=['pyephem==3.7.2.3'],
505+
If you are afraid that you or your customers might miss out on critical security updates to a package by being stuck on a single version, then leave the lowest version number unspecified by saying something like:
506+
install_requires=['sqlalchmey >= 0.4, < 0.5'], _
351507

0 commit comments

Comments
 (0)