...
 
Commits (1)
......@@ -2,6 +2,8 @@
================
* No changes yet.
* Added fragment variant recipe. Which allow to use “extends” option
in the template [Antoine Catton]
1.1 (2011-05-30)
================
......
======================
slapos.recipe.template
======================
......@@ -5,7 +6,10 @@ Fully networked template recipe, reusing collective.recipe.template with
ability to download template over the network
Usage
-----
=====
Default recipe
--------------
::
......@@ -13,12 +17,61 @@ Usage
parts = template
[template]
recipe = slapos.cookbook:template
recipe = slapos.recipe.template
url = http://server/with/template
# optional md5sum
md5sum = 1234567890
output = ${buildout:directory}/result
Fragment variant recipe
-----------------------
* buildout.cfg
::
[buildout]
parts = template
[template]
recipe = slapos.recipe.template:fragments
url = http:://server/recipes/main.cfg
md5sum = 1234567890
output = ${buildout:directory}/output.cfg
value = foobar
* http://server/recipe/main.cfg
::
[buildout]
extends =
# buildout:extends lines should look like that :
# file (relative or absolute path), space, md5sum
../fragments/parent.cfg
* http://server/fragments/parent.cfg
::
[example]
recipe = example.recipe
option = ${:value}
output.cfg of this example should be :
::
[buildout]
[example]
recipe = example.recipe
option = foobar
Note
----
All parameters except url and md5sum will be passed to
collective.recipe.template, so please visit
http://pypi.python.org/pypi/collective.recipe.template for full information.
......@@ -29,5 +29,6 @@ setup(name=name,
entry_points={
'zc.buildout': [
'default = slapos.recipe.template:Recipe',
'fragments = slapos.recipe.template.fragments:Recipe',
]},
)
##############################################################################
#
# Copyright (c) 2010 Vifib SARL and Contributors. All Rights Reserved.
#
# WARNING: This program as such is intended to be used by professional
# programmers who take the whole responsibility of assessing all potential
# consequences resulting from its eventual inadequacies and bugs
# End users who are looking for a ready-to-use solution with commercial
# guarantees and support are strongly adviced to contract a Free Software
# Service Company
#
# This program is Free Software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 3
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#
##############################################################################
import ConfigParser
import re
import urlparse
import collective.recipe.template
import zc.buildout
class Recipe(collective.recipe.template.Recipe):
def __init__(self, buildout, name, options):
self._download = zc.buildout.download.Download(buildout['buildout'],
hash_name=True)
url = '%s %s' % (options.pop('url').strip(), options.get('md5sum'))
if 'input' not in options:
options['input'] = '%s.in' % options['output']
with open(options['input'], 'w'):
pass
# Prepare the file for collective recipe
buildout = ConfigParser.RawConfigParser()
buildout.add_section('buildout')
buildout.set('buildout', 'extends', url)
self.extend_buildout(buildout)
with open(options['input'], 'w') as file_:
buildout.write(file_)
# else collective recipe will take care to yell at the user :)
collective.recipe.template.Recipe.__init__(self, buildout, name, options)
def install(self):
return collective.recipe.template.Recipe.install(self) + [self.input]
def extend_buildout(self, buildout, parent_url=None):
extendsline_re = re.compile(r'^.* [0-9a-fA-F]{32}$')
extends = [tuple(line.strip().rsplit(' ', 1))
for line in buildout.get('buildout', 'extends').splitlines()
if extendsline_re.match(line.strip())]
buildout.remove_option('buildout', 'extends')
for url, md5sum in extends:
if parent_url is not None:
url = urlparse.urljoin(parent_url, url)
path, is_temp = self._download(url, md5sum=md5sum)
config_parent = ConfigParser.ConfigParser()
with open(path, 'r')as file_:
config_parent.readfp(file_)
if config_parent.has_option('buildout', 'extends'):
self.extend_buildout(config_parent, url)
for section in config_parent.sections():
if buildout.has_section(section):
for option in config_parent.options(section):
if not buildout.has_option(section, option):
buildout.set(section, option,
config_parent.get(section, option))
else:
buildout.add_section(section)
# Dumb copy of section
for option in config_parent.options(section):
buildout.set(section, option,
config_parent.get(section, option))