[Checkins] SVN: Sandbox/J1m/metarecipe/ meta-recipe helper
jim
cvs-admin at zope.org
Thu May 31 16:30:39 UTC 2012
Log message for revision 126538:
meta-recipe helper
Changed:
U Sandbox/J1m/metarecipe/buildout.cfg
U Sandbox/J1m/metarecipe/setup.py
A Sandbox/J1m/metarecipe/src/zc/metarecipe/
A Sandbox/J1m/metarecipe/src/zc/metarecipe/README.txt
A Sandbox/J1m/metarecipe/src/zc/metarecipe/__init__.py
A Sandbox/J1m/metarecipe/src/zc/metarecipe/testing.py
A Sandbox/J1m/metarecipe/src/zc/metarecipe/tests.py
-=-
Modified: Sandbox/J1m/metarecipe/buildout.cfg
===================================================================
--- Sandbox/J1m/metarecipe/buildout.cfg 2012-05-31 16:28:38 UTC (rev 126537)
+++ Sandbox/J1m/metarecipe/buildout.cfg 2012-05-31 16:30:35 UTC (rev 126538)
@@ -4,7 +4,7 @@
[test]
recipe = zc.recipe.testrunner
-eggs =
+eggs = zc.metarecipe [test]
[py]
recipe = zc.recipe.egg
Modified: Sandbox/J1m/metarecipe/setup.py
===================================================================
--- Sandbox/J1m/metarecipe/setup.py 2012-05-31 16:28:38 UTC (rev 126537)
+++ Sandbox/J1m/metarecipe/setup.py 2012-05-31 16:30:35 UTC (rev 126538)
@@ -11,10 +11,10 @@
# FOR A PARTICULAR PURPOSE.
#
##############################################################################
-name, version = 'zc.', '0'
+name, version = 'zc.metarecipe', '0'
install_requires = ['setuptools']
-extras_require = dict(test=['zope.testing'])
+extras_require = dict(test=['zope.testing', 'manuel'])
entry_points = """
"""
Added: Sandbox/J1m/metarecipe/src/zc/metarecipe/README.txt
===================================================================
--- Sandbox/J1m/metarecipe/src/zc/metarecipe/README.txt (rev 0)
+++ Sandbox/J1m/metarecipe/src/zc/metarecipe/README.txt 2012-05-31 16:30:35 UTC (rev 126538)
@@ -0,0 +1,200 @@
+============
+Meta-recipes
+============
+
+Buildout recipes provide resuable Python modukes for common
+configuration tasks. The most widely used recipes tend to provide
+low-level functions, like installing eggs or softwarte distributions,
+creating configuration files, and so on. The normal recipe framework
+is fairly well suited to building these general components.
+
+Full-blown applications may require many, often tens, of parts.
+Defining the many parts that make up an application can be tedious and
+often entails a lot of repetition. Buildout provides a number of
+mechanisms to avoid repetition, including merging of configuration
+files and macros, but these, while useful to an extent, don't scale
+very will. Buildout isn't and shouldn't be a programming language.
+
+Meta-recipes allow us to bring Python to bear to provide higher-level
+abstractions for buildouts.
+
+A meta-recipe is a regular Python recipe that primarily operates by
+creating parts. A meta recipe isn't merely a high level recipe. It's
+a recipe that defers most of it's work to lower-level recipe by
+manipulating the buildout database.
+
+Unfortunatly, buildout doesn't yet provide a high-level API for
+creating parts. It has a private low-level API which has been
+promoted to public (meaning it won't be broken by future release), and
+it's straightforward to write the needed high-level API, but it's
+annoying to repeat the high-level API in each meta recipe.
+
+This small package provides the high-lebel API needed for meta recipes
+and a simple testing framework. It will be merged into a future
+buildout release.
+
+A `presentation at PyCon 2011
+<http://blip.tv/pycon-us-videos-2009-2010-2011/pycon-2011-deploying-applications-with-zc-buildout-4897770>`_
+described early work with meta recipes.
+
+A simple meta-recipe example
+============================
+
+Let's look at a fairly simple meta-recipe example. First, consider a
+buildout configuration that builds a database deployment::
+
+ [buildout]
+ parts = ctl pack
+
+ [deployment]
+ recipe = zc.recipe.deployment
+ name = ample
+ user = zope
+
+ [ctl]
+ recipe = zc.recipe.rhrc
+ deployment = deployment
+ chkconfig = 345 99 10
+ parts = main index
+
+ [main]
+ recipe = zc.zodbrecipes:server
+ deployment = deployment
+ address = :8100
+ path = /var/databases/ample/main.fs
+ zeo.conf =
+ <zeo>
+ address ${:address}
+ </zeo>
+ %import zc.zlibstorage
+ <zlibstorage>
+ <filestorage>
+ path ${:path}
+ </filestorage>
+ </zlibstorage>
+
+ [pack]
+ recipe = zc.recipe.deployment:crontab
+ deployment = deployment
+ times = 1 2 * * 6
+ command = ${buildout:bin-directory}/zeopack -d3 -t00 ${main:address}
+
+.. -> low_level
+
+This buildout doesn't build software. Rather it builds configuration
+for deploying a database configuration using already-deployed
+software. For the purpose of this document, however, the details are
+totally unimportant.
+
+Rather than crafting the configuration above every time, we can write
+a meta-recipe that crafts it for us. We'll use our meta-recipe as
+follows::
+
+ [buildout]
+ parts = ample
+
+ [ample]
+ recipe = com.example.ample:db
+ path = /var/databases/ample/main.fs
+
+The idea here is that the meta recipe allows us to specify the minimal
+information necessary. A meta-recipe often automates policies and
+assumptions that are application and organization dependent. The
+example above assumes, for exampe, that we want to pack on Saturdays
+to to 3 days in the past.
+
+So now, let's see the meta recipe that automates this::
+
+ import zc.metarecipe
+
+ class Recipe(zc.metarecipe.Recipe):
+
+ def __init__(self, buildout, name, options):
+ super(Recipe, self).__init__(buildout, name, options)
+
+ self.parse('''
+ [deployment]
+ recipe = zc.recipe.deployment
+ name = %s
+ user = zope
+ ''' % name)
+
+ self['main'] = dict(
+ recipe = 'zc.zodbrecipes:server',
+ deployment = 'deployment',
+ address = ':8100',
+ path = options['path'],
+ **{
+ 'zeo.conf': '''
+ <zeo>
+ address ${:address}
+ </zeo>
+
+ %import zc.zlibstorage
+
+ <zlibstorage>
+ <filestorage>
+ path ${:path}
+ </filestorage>
+ </zlibstorage>
+ '''}
+ )
+
+ self.parse('''
+ [pack]
+ recipe = zc.recipe.deployment:crontab
+ deployment = deployment
+ times = 1 2 * * 6
+ command =
+ ${buildout:bin-directory}/zeopack -d3 -t00 ${main:address}
+
+ [ctl]
+ recipe = zc.recipe.rhrc
+ deployment = deployment
+ chkconfig = 345 99 10
+ parts = main index
+ ''')
+
+.. -> source
+
+ >>> exec source
+
+Now, let's test it. We'll test it without actually running
+buildout. Rather, we'll use a faux buildout provided by the
+zc.metarecipe.testing module.
+
+ >>> import zc.metarecipe.testing
+ >>> buildout = zc.metarecipe.testing.Buildout()
+
+ >>> _ = Recipe(buildout, 'ample', dict(path='/var/databases/ample/main.fs'))
+ [deployment]
+ name = ample
+ recipe = zc.recipe.deployment
+ user = zope
+ [main]
+ address = :8100
+ deployment = deployment
+ path = /var/databases/ample/main.fs
+ recipe = zc.zodbrecipes:server
+ zeo.conf = <zeo>
+ address ${:address}
+ </zeo>
+ <BLANKLINE>
+ %import zc.zlibstorage
+ <BLANKLINE>
+ <zlibstorage>
+ <filestorage>
+ path ${:path}
+ </filestorage>
+ </zlibstorage>
+ [ctl]
+ chkconfig = 345 99 10
+ deployment = deployment
+ parts = main index
+ recipe = zc.recipe.rhrc
+ [pack]
+ command = ${buildout:bin-directory}/zeopack -d3 -t00 ${main:address}
+ deployment = deployment
+ recipe = zc.recipe.deployment:crontab
+ times = 1 2 * * 6
+
Property changes on: Sandbox/J1m/metarecipe/src/zc/metarecipe/README.txt
___________________________________________________________________
Added: svn:eol-style
+ native
Added: Sandbox/J1m/metarecipe/src/zc/metarecipe/__init__.py
===================================================================
--- Sandbox/J1m/metarecipe/src/zc/metarecipe/__init__.py (rev 0)
+++ Sandbox/J1m/metarecipe/src/zc/metarecipe/__init__.py 2012-05-31 16:30:35 UTC (rev 126538)
@@ -0,0 +1,24 @@
+import ConfigParser, cStringIO, textwrap
+
+class Recipe(object):
+
+ def __init__(self, buildout, name, options):
+ self.buildout = buildout
+ self.name = name
+ self.options = options
+
+ def install(self):
+ return ()
+
+ update = install
+
+ def __setitem__(self, name, data):
+ self.buildout._raw[name] = data
+ self.buildout[name]
+
+ def parse(self, data):
+ parser = ConfigParser.RawConfigParser()
+ parser.readfp(cStringIO.StringIO(textwrap.dedent(data)))
+
+ for section in parser.sections():
+ self[section] = dict(parser.items(section))
Property changes on: Sandbox/J1m/metarecipe/src/zc/metarecipe/__init__.py
___________________________________________________________________
Added: svn:keywords
+ Id
Added: svn:eol-style
+ native
Added: Sandbox/J1m/metarecipe/src/zc/metarecipe/testing.py
===================================================================
--- Sandbox/J1m/metarecipe/src/zc/metarecipe/testing.py (rev 0)
+++ Sandbox/J1m/metarecipe/src/zc/metarecipe/testing.py 2012-05-31 16:30:35 UTC (rev 126538)
@@ -0,0 +1,11 @@
+
+
+class Buildout:
+
+ def __init__(self):
+ self._raw = {}
+
+ def __getitem__(self, name):
+ print "[%s]" % name
+ for k, v in sorted(self._raw[name].items()):
+ print "%s = %s" % (k, v.replace("\n", "\n ").strip())
Property changes on: Sandbox/J1m/metarecipe/src/zc/metarecipe/testing.py
___________________________________________________________________
Added: svn:keywords
+ Id
Added: svn:eol-style
+ native
Added: Sandbox/J1m/metarecipe/src/zc/metarecipe/tests.py
===================================================================
--- Sandbox/J1m/metarecipe/src/zc/metarecipe/tests.py (rev 0)
+++ Sandbox/J1m/metarecipe/src/zc/metarecipe/tests.py 2012-05-31 16:30:35 UTC (rev 126538)
@@ -0,0 +1,28 @@
+##############################################################################
+#
+# Copyright (c) 2010 Zope Foundation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+from zope.testing import setupstack
+import manuel.capture
+import manuel.doctest
+import manuel.testing
+import unittest
+
+def test_suite():
+ return unittest.TestSuite((
+ manuel.testing.TestSuite(
+ manuel.doctest.Manuel() + manuel.capture.Manuel(),
+ 'README.txt',
+ setUp=setupstack.setUpDirectory, tearDown=setupstack.tearDown,
+ ),
+ ))
+
Property changes on: Sandbox/J1m/metarecipe/src/zc/metarecipe/tests.py
___________________________________________________________________
Added: svn:keywords
+ Id
Added: svn:eol-style
+ native
More information about the checkins
mailing list