Commit 70d78c20 authored by Sebastien Robin's avatar Sebastien Robin

Merge branch 'master' into erp5testnode

parents 8289bfb3 d2d28243
0.7 (unreleased)
================
* No changes yet.
0.6 (2011-06-13)
================
* Fixed slapos.recipe.erp5 instantiation. [Łukasz Nowak]
0.5 (2011-06-13)
================
* Implement zabbix agent instantiation. [Łukasz Nowak]
* Drop dependency on Zope2. [Łukasz Nowak]
* Share more in slapos.recipe.librecipe module. [Łukasz Nowak]
0.4 (2011-06-09)
================
* Remove reference to slapos.tool.networkcache as it was removed from pypi. [Łukasz Nowak]
* Add Kumofs standalone software release and recipe [Cedric de Saint Martin]
* Add Memcached standalone software release and recipe [Cedric de Saint Martin]
0.3 (2011-06-09)
================
* Moved out template and build to separate distributions [Łukasz Nowak]
* Depend on slapos.core instead of depracated slapos.slap [Romain Courteaud]
* Fix apache module configuration [Kazuhiko Shiozaki]
* Allow to control full environment in erp5 module [Łukasz Nowak]
0.2 (unreleased) 0.2 (unreleased)
================ ================
......
[buildout] [buildout]
# XXX: Extends shall not jump out of software # XXX: Extends shall not jump out of software
extends = extends =
...@@ -27,12 +28,12 @@ recipe = hexagonit.recipe.cmmi ...@@ -27,12 +28,12 @@ recipe = hexagonit.recipe.cmmi
# other settings in this part if we don't set it explicitly here. # other settings in this part if we don't set it explicitly here.
prefix = ${buildout:parts-directory}/${:_buildout_section_name_} prefix = ${buildout:parts-directory}/${:_buildout_section_name_}
version = 2.6 version = 2.6
package_version = ${:version}.6 package_version = ${:version}.7
executable = ${:prefix}/bin/python${:version} executable = ${:prefix}/bin/python${:version}
url = url =
http://python.org/ftp/python/${:package_version}/Python-${:package_version}.tgz http://python.org/ftp/python/${:package_version}/Python-${:package_version}.tar.bz2
md5sum = b2f209df270a33315e62c1ffac1937f0 md5sum = d40ef58ed88438a870bbeb0ac5d4217b
patch-options = -p1 patch-options = -p1
patches = patches =
${python-2.6.6-no_system_inc_dirs.patch:location}/${python-2.6.6-no_system_inc_dirs.patch:filename} ${python-2.6.6-no_system_inc_dirs.patch:location}/${python-2.6.6-no_system_inc_dirs.patch:filename}
......
...@@ -4,8 +4,8 @@ parts = ...@@ -4,8 +4,8 @@ parts =
[zabbix-agent] [zabbix-agent]
recipe = hexagonit.recipe.cmmi recipe = hexagonit.recipe.cmmi
url = http://prdownloads.sourceforge.net/zabbix/zabbix-1.8.4.tar.gz?download url = http://prdownloads.sourceforge.net/zabbix/zabbix-1.8.5.tar.gz?download
md5sum = 969ce09317c98b205bc96157e16f5c8c md5sum = 58b9253fb0eace1e20b2fe5c1fce32a3
configure-options = configure-options =
--enable-agent --enable-agent
--enable-ipv6 --enable-ipv6
...@@ -2,7 +2,7 @@ from setuptools import setup, find_packages ...@@ -2,7 +2,7 @@ from setuptools import setup, find_packages
import glob import glob
import os import os
version = '0.2-dev' version = '0.7-dev'
name = 'slapos.cookbook' name = 'slapos.cookbook'
long_description = open("README.txt").read() + "\n" + \ long_description = open("README.txt").read() + "\n" + \
open("CHANGES.txt").read() + "\n" open("CHANGES.txt").read() + "\n"
...@@ -27,12 +27,10 @@ setup(name=name, ...@@ -27,12 +27,10 @@ setup(name=name,
include_package_data=True, include_package_data=True,
install_requires=[ install_requires=[
'PyXML', # for full blown python interpreter 'PyXML', # for full blown python interpreter
'Zope2', # some recipes like to play with zope
'collective.recipe.template', # needed by template recipe
'lxml', # for full blown python interpreter 'lxml', # for full blown python interpreter
'netaddr', # to manipulate on IP addresses 'netaddr', # to manipulate on IP addresses
'setuptools', # namespaces 'setuptools', # namespaces
'slapos.slap', # uses internally 'slapos.core', # uses internally
# 'slapos.toolbox', # needed for libcloud, cloudmgr, disabled for now # 'slapos.toolbox', # needed for libcloud, cloudmgr, disabled for now
'xml_marshaller', # need to communication with slapgrid 'xml_marshaller', # need to communication with slapgrid
'zc.buildout', # plays with buildout 'zc.buildout', # plays with buildout
...@@ -41,25 +39,25 @@ setup(name=name, ...@@ -41,25 +39,25 @@ setup(name=name,
zip_safe=True, zip_safe=True,
entry_points={ entry_points={
'zc.buildout': [ 'zc.buildout': [
'build = slapos.recipe.build:Script',
'buildcmmi = slapos.recipe.build:Cmmi',
'download = slapos.recipe.download:Recipe', 'download = slapos.recipe.download:Recipe',
'erp5 = slapos.recipe.erp5:Recipe', 'erp5 = slapos.recipe.erp5:Recipe',
'erp5testnode = slapos.recipe.erp5testnode:Recipe', 'erp5testnode = slapos.recipe.erp5testnode:Recipe',
'helloworld = slapos.recipe.helloworld:Recipe', 'helloworld = slapos.recipe.helloworld:Recipe',
'java = slapos.recipe.java:Recipe', 'java = slapos.recipe.java:Recipe',
'kumofs = slapos.recipe.kumofs:Recipe',
'kvm = slapos.recipe.kvm:Recipe', 'kvm = slapos.recipe.kvm:Recipe',
'libcloud = slapos.recipe.libcloud:Recipe', 'libcloud = slapos.recipe.libcloud:Recipe',
'libcloudrequest = slapos.recipe.libcloudrequest:Recipe', 'libcloudrequest = slapos.recipe.libcloudrequest:Recipe',
'memcached = slapos.recipe.memcached:Recipe',
'nbdserver = slapos.recipe.nbdserver:Recipe', 'nbdserver = slapos.recipe.nbdserver:Recipe',
'nosqltestbed = slapos.recipe.nosqltestbed:NoSQLTestBed', 'nosqltestbed = slapos.recipe.nosqltestbed:NoSQLTestBed',
'proactive = slapos.recipe.proactive:Recipe', 'proactive = slapos.recipe.proactive:Recipe',
'sheepdogtestbed = slapos.recipe.sheepdogtestbed:SheepDogTestBed', 'sheepdogtestbed = slapos.recipe.sheepdogtestbed:SheepDogTestBed',
'siptester = slapos.recipe.siptester:SipTesterRecipe', 'siptester = slapos.recipe.siptester:SipTesterRecipe',
'slaprunner = slapos.recipe.slaprunner:Recipe', 'slaprunner = slapos.recipe.slaprunner:Recipe',
'template = slapos.recipe.template:Recipe',
'testnode = slapos.recipe.testnode:Recipe', 'testnode = slapos.recipe.testnode:Recipe',
'vifib = slapos.recipe.vifib:Recipe', 'vifib = slapos.recipe.vifib:Recipe',
'xwiki = slapos.recipe.xwiki:Recipe', 'xwiki = slapos.recipe.xwiki:Recipe',
'zabbixagent = slapos.recipe.zabbixagent:Recipe',
]}, ]},
) )
build
=====
Recipe to build the software.
Example buildout::
[buildout]
parts =
file
[zlib]
# Use standard configure, make, make install way
recipe = slapos.cookbook:build
url = http://prdownloads.sourceforge.net/libpng/zlib-1.2.5.tar.gz?download
md5sum = c735eab2d659a96e5a594c9e8541ad63
slapos_promisee =
directory:include
file:include/zconf.h
file:include/zlib.h
directory:lib
statlib:lib/libz.a
dynlib:lib/libz.so linked:libc.so.6 rpath:
dynlib:lib/libz.so.1 linked:libc.so.6 rpath:
dynlib:lib/libz.so.1.2.5 linked:libc.so.6
directory:lib/pkgconfig
file:lib/pkgconfig/zlib.pc
directory:share
directory:share/man
directory:share/man/man3
file:share/man/man3/zlib.3
[file]
recipe = slapos.cookbook:buildcmmi
url = ftp://ftp.astron.com/pub/file/file-5.04.tar.gz
md5sum = accade81ff1cc774904b47c72c8aeea0
environment =
CPPFLAGS=-I${zlib:location}/include
LDFLAGS=-L${zlib:location}/lib -Wl,-rpath -Wl,${zlib:location}/lib
slapos_promisee =
directory:bin
dynlib:bin/file linked:libz.so.1,libc.so.6,libmagic.so.1 rpath:${zlib:location}/lib,!/lib
directory:include
file:include/magic.h
directory:lib
statlib:lib/libmagic.a
statlib:lib/libmagic.la
dynlib:lib/libmagic.so linked:libz.so.1,libc.so.6 rpath:${zlib:location}/lib
dynlib:lib/libmagic.so.1 linked:libz.so.1,libc.so.6 rpath:${zlib:location}/lib
dynlib:lib/libmagic.so.1.0.0 linked:libz.so.1,libc.so.6 rpath:${zlib:location}/lib
directory:share
directory:share/man
directory:share/man/man1
file:share/man/man1/file.1
directory:share/man/man3
file:share/man/man3/libmagic.3
directory:share/man/man4
file:share/man/man4/magic.4
directory:share/man/man5
directory:share/misc
file:share/misc/magic.mgc
[somethingelse]
# default way with using script
recipe = slapos.cookbook:build
url_0 = http://host/path/file.tar.gz
md5sum = 9631070eac74f92a812d4785a84d1b4e
script =
import os
os.chdir(%(work_directory)s)
unpack(%(url_0), strip_path=True)
execute('make')
execute('make install DEST=%(location)s')
slapos_promisee =
...
TODO:
* add linking suport, buildout definition:
slapos_link = <relative/path> [optional-path
can be used as::
[file]
slapos_link =
bin/file
bin/file ${buildout:bin-directory}/bin/anotherfile
Which will link ${file:location}/bin/file to ${buildout:bin-directory}/bin/file
and ${file:location}/bin/file to ${buildout:bin-directory}/bin/anotherfile
kumofs
=========
Instantiates KumoFS instance.
memcached
=========
Instantiates Memcached instance.
template
========
Fully networked template recipe, reusing collective.recipe.template with
ability to download template over the network
Usage
-----
::
[buildout]
parts = template
[template]
recipe = slapos.cookbook:template
url = http://server/with/template
# optional md5sum
md5sum = 1234567890
output = ${buildout:directory}/result
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.
##############################################################################
#
# 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 logging
import os
import setuptools
import shutil
import subprocess
import tempfile
import zc.buildout
def readElfAsDict(f):
"""Reads ELF information from file"""
popen = subprocess.Popen(['readelf', '-d', f],
stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
result = popen.communicate()[0]
if popen.returncode != 0:
raise AssertionError(result)
library_list = []
rpath_list = []
runpath_list = []
for l in result.split('\n'):
if '(NEEDED)' in l:
library_list.append(l.split(':')[1].strip(' []'))
elif '(RPATH)' in l:
rpath_list = [q.rstrip('/') for q in l.split(':',1)[1].strip(' []').split(':')]
elif '(RUNPATH)' in l:
runpath_list = [q.rstrip('/') for q in l.split(':',1)[1].strip(' []').split(':')]
if len(runpath_list) == 0:
runpath_list = rpath_list
elif len(rpath_list) != 0 and runpath_list != rpath_list:
raise ValueError('RPATH and RUNPATH are different.')
return dict(
library_list=sorted(library_list),
runpath_list=sorted(runpath_list)
)
def call(*args, **kwargs):
"""Subprocess call with closed file descriptors and stdin"""
kwargs.update(
stdin=subprocess.PIPE,
close_fds=True)
popen = subprocess.Popen(*args, **kwargs)
popen.stdin.flush()
popen.stdin.close()
popen.stdin = None
popen.communicate()
if popen.returncode != 0:
raise subprocess.CalledProcessError(popen.returncode, ' '.join(args[0]))
def calls(call_string, **kwargs):
"""Subprocesser caller which allows to pass arguments as string"""
call(call_string.split(), **kwargs)
def guessworkdir(path):
if len(os.listdir(path)) == 1:
return os.path.join(path, os.listdir(path)[0])
return path
class Script:
"""Free script building system"""
def _checkPromisee(self, location):
promisee_problem_list = []
a = promisee_problem_list.append
for promisee in self.options['slapos_promisee'].split('\n'):
promisee = promisee.strip()
if not promisee:
continue
if promisee.startswith('file:') or promisee.startswith('statlib'):
s, path = promisee.split(':')
if not os.path.exists(os.path.join(location, path)):
a('File promisee not met for %r' % path)
elif promisee.startswith('directory'):
s, path = promisee.split(':')
if not os.path.isdir(os.path.join(location, path)):
a('Directory promisee not met for %r' %
path)
elif promisee.startswith('dynlib:'):
if 'linked:' not in promisee:
raise zc.buildout.UserError('dynlib promisee requires \'linked:\' '
'parameter.')
if 'rpath:' not in promisee:
rpath_list = []
for promisee_part in promisee.split():
if promisee_part.startswith('dynlib:'):
s, path = promisee_part.split(':')
elif promisee_part.startswith('linked:'):
s, link_list = promisee_part.split(':')
link_list = link_list.split(',')
elif promisee_part.startswith('rpath:'):
s, rpath_list = promisee_part.split(':')
if rpath_list:
r = rpath_list
rpath_list = []
for q in r.split(','):
if q.startswith('!'):
q = q.replace('!', location)
rpath_list.append(q)
else:
rpath_list = []
if not os.path.exists(os.path.join(location, path)):
a('Dynlib promisee file not met %r' % promisee)
else:
elf_dict = readElfAsDict(os.path.join(location, path))
if sorted(link_list) != sorted(elf_dict['library_list']):
a('Promisee library list not met (wanted: %r, found: %r)'%(
link_list, elf_dict['library_list']))
if sorted(rpath_list) != sorted(elf_dict['runpath_list']):
a('Promisee rpath list not met (wanted: %r, found: %r)'%(
rpath_list, elf_dict['runpath_list']))
else:
raise zc.buildout.UserError('Unknown promisee %r' % promisee)
if len(promisee_problem_list):
raise zc.buildout.UserError('Promisee not met, found issues:\n %s' %
' '.join([q+'\n' for q in promisee_problem_list]))
def download(self, url, md5sum):
download = zc.buildout.download.Download(self.buildout['buildout'],
hash_name=True)
path, is_temp = download(url, md5sum=self.options.get('md5sum'))
return path
def extract(self, path):
extract_dir = tempfile.mkdtemp(self.name)
self.logger.debug('Created working directory %r' % extract_dir)
setuptools.archive_util.unpack_archive(path, extract_dir)
self.cleanup_dir_list.append(extract_dir)
return extract_dir
script = 'raise NotImplementedError'
def __init__(self, buildout, name, options):
self.cleanup_dir_list = []
self.options = options
self.buildout = buildout
self.name = name
self.logger = logging.getLogger('SlapOS build of %s' % self.name)
self.options.setdefault('location',
os.path.join(buildout['buildout']['parts-directory'], self.name))
# cleanup some variables
for k in ['location', 'url', 'md5sum']:
self.options[k] = self.options.get(k, '').strip()
self.options['script'] = self.options.get('script', self.script) % self.options
def getEnvironment(self):
# prepare cool dictionary
wanted_env = {}
for line in self.options.get('environment', '').splitlines():
line = line.strip()
if not line:
continue
if not '=' in line:
raise zc.buildout.UserError('Line %r in environment is incorrect' % line)
key, value = line.split('=')
key = key.strip()
value = value.strip()
if key in wanted_env:
raise zc.buildout.UserError('Key %r is repeated' % key)
wanted_env[key] = value
env = {}
for k,v in os.environ.iteritems():
change = wanted_env.pop(k, None)
if change is not None:
env[k] = change % os.environ
self.logger.info('Environment %r setup to %r' % (k, env[k]))
else:
env[k] =v
for k,v in wanted_env.iteritems():
self.logger.info('Environment %r added with %r' % (k, v))
env[k] = v
return env
def install(self):
try:
env = self.getEnvironment()
exec self.options['script']
try:
self._checkPromisee(self.options['location'])
except Exception:
if os.path.exists(self.options['location']):
self.logger.info('Removing location %r because of error' % self.options['location'])
shutil.rmtree(self.options['location'])
raise
finally:
for d in self.cleanup_dir_list:
if os.path.exists(d):
self.logger.debug('Cleanup directory %r' % d)
shutil.rmtree(d)
return [self.options['location']]
def update(self):
pass
class Cmmi(Script):
"""Simple configure-make-make-insall compatible with hexagonit.recipe.cmmi
Compatibility on parameter level, without bug-to-bug, hack-to-hack"""
script = """
extract_dir = self.extract(self.download(self.options['url'], self.options.get('md5sum')))
workdir = guessworkdir(extract_dir)
configure_command = ["./configure", "--prefix=%(location)s"]
configure_command.extend(%(configure-options)r.split())
self.logger.info('Configuring with: %%s' %% configure_command)
call(configure_command, cwd=workdir, env=env)
self.logger.info('Building')
call("make", cwd=workdir, env=env)
self.logger.info('Installing')
call(["make", "install"], cwd=workdir, env=env)
"""
def __init__(self, buildout, name, options):
options['configure-options'] = ' '.join(options.get('configure-options', '').strip().splitlines())
Script.__init__(self, buildout, name, options)
...@@ -102,7 +102,7 @@ class Recipe(BaseSlapRecipe): ...@@ -102,7 +102,7 @@ class Recipe(BaseSlapRecipe):
self.path_list.append(config_file) self.path_list.append(config_file)
# Use execute from erp5. # Use execute from erp5.
self.path_list.extend(zc.buildout.easy_install.scripts([(name, self.path_list.extend(zc.buildout.easy_install.scripts([(name,
__name__ + 'slapos.recipe.erp5.execute', __name__ + 'slapos.recipe.librecipe.execute',
'execute_with_signal_translation')], self.ws, 'execute_with_signal_translation')], self.ws,
sys.executable, self.wrapper_directory, sys.executable, self.wrapper_directory,
arguments=[self.options['ooo_paster'].strip(), 'serve', config_file])) arguments=[self.options['ooo_paster'].strip(), 'serve', config_file]))
......
...@@ -34,8 +34,13 @@ import sys ...@@ -34,8 +34,13 @@ import sys
import zc.buildout import zc.buildout
import zc.recipe.egg import zc.recipe.egg
import ConfigParser import ConfigParser
from Zope2.utilities.mkzopeinstance import write_inituser
# based on Zope2.utilities.mkzopeinstance.write_inituser
def Zope2InitUser(path, username, password):
open(path, 'w').write('')
os.chmod(path, 0600)
open(path, "w").write('%s:{SHA}%s\n' % (
username,binascii.b2a_base64(hashlib.sha1(password).digest())[:-1]))
class Recipe(BaseSlapRecipe): class Recipe(BaseSlapRecipe):
def getTemplateFilename(self, template_name): def getTemplateFilename(self, template_name):
...@@ -307,7 +312,7 @@ class Recipe(BaseSlapRecipe): ...@@ -307,7 +312,7 @@ class Recipe(BaseSlapRecipe):
self._createDirectory(cron_d) self._createDirectory(cron_d)
self._createDirectory(crontabs) self._createDirectory(crontabs)
wrapper = zc.buildout.easy_install.scripts([('crond', wrapper = zc.buildout.easy_install.scripts([('crond',
__name__ + '.execute', 'execute')], self.ws, sys.executable, 'slapos.recipe.librecipe.execute', 'execute')], self.ws, sys.executable,
self.wrapper_directory, arguments=[ self.wrapper_directory, arguments=[
self.options['dcrond_binary'].strip(), '-s', cron_d, '-c', crontabs, self.options['dcrond_binary'].strip(), '-s', cron_d, '-c', crontabs,
'-t', timestamps, '-f', '-l', '5', '-M', catcher] '-t', timestamps, '-f', '-l', '5', '-M', catcher]
...@@ -412,7 +417,7 @@ class Recipe(BaseSlapRecipe): ...@@ -412,7 +417,7 @@ class Recipe(BaseSlapRecipe):
conversion_server_dict)) conversion_server_dict))
self.path_list.append(config_file) self.path_list.append(config_file)
self.path_list.extend(zc.buildout.easy_install.scripts([(name, self.path_list.extend(zc.buildout.easy_install.scripts([(name,
__name__ + '.execute', 'execute_with_signal_translation')], self.ws, 'slapos.recipe.librecipe.execute', 'execute_with_signal_translation')], self.ws,
sys.executable, self.wrapper_directory, sys.executable, self.wrapper_directory,
arguments=[self.options['ooo_paster'].strip(), 'serve', config_file])) arguments=[self.options['ooo_paster'].strip(), 'serve', config_file]))
return { return {
...@@ -436,7 +441,7 @@ class Recipe(BaseSlapRecipe): ...@@ -436,7 +441,7 @@ class Recipe(BaseSlapRecipe):
config)) config))
self.path_list.append(haproxy_conf_path) self.path_list.append(haproxy_conf_path)
wrapper = zc.buildout.easy_install.scripts([('haproxy_%s' % name, wrapper = zc.buildout.easy_install.scripts([('haproxy_%s' % name,
__name__ + '.execute', 'execute')], self.ws, sys.executable, 'slapos.recipe.librecipe.execute', 'execute')], self.ws, sys.executable,
self.wrapper_directory, arguments=[ self.wrapper_directory, arguments=[
self.options['haproxy_binary'].strip(), '-f', haproxy_conf_path] self.options['haproxy_binary'].strip(), '-f', haproxy_conf_path]
)[0] )[0]
...@@ -455,7 +460,7 @@ class Recipe(BaseSlapRecipe): ...@@ -455,7 +460,7 @@ class Recipe(BaseSlapRecipe):
password = self.generatePassword() password = self.generatePassword()
# XXX Unhardcoded me please # XXX Unhardcoded me please
user = 'zope' user = 'zope'
write_inituser( Zope2InitUser(
os.path.join(self.erp5_directory, "inituser"), user, password) os.path.join(self.erp5_directory, "inituser"), user, password)
self._createDirectory(self.erp5_directory) self._createDirectory(self.erp5_directory)
...@@ -542,7 +547,7 @@ class Recipe(BaseSlapRecipe): ...@@ -542,7 +547,7 @@ class Recipe(BaseSlapRecipe):
self.substituteTemplate(self.getTemplateFilename('zeo.conf.in'), config)) self.substituteTemplate(self.getTemplateFilename('zeo.conf.in'), config))
self.path_list.append(zeo_conf_path) self.path_list.append(zeo_conf_path)
wrapper = zc.buildout.easy_install.scripts([('zeo_%s' % zeo_number, wrapper = zc.buildout.easy_install.scripts([('zeo_%s' % zeo_number,
__name__ + '.execute', 'execute')], self.ws, sys.executable, 'slapos.recipe.librecipe.execute', 'execute')], self.ws, sys.executable,
self.wrapper_directory, arguments=[ self.wrapper_directory, arguments=[
self.options['runzeo_binary'].strip(), '-C', zeo_conf_path] self.options['runzeo_binary'].strip(), '-C', zeo_conf_path]
)[0] )[0]
...@@ -588,7 +593,7 @@ class Recipe(BaseSlapRecipe): ...@@ -588,7 +593,7 @@ class Recipe(BaseSlapRecipe):
))) )))
# TID server # TID server
tidstorage_server = zc.buildout.easy_install.scripts([('tidstoraged', tidstorage_server = zc.buildout.easy_install.scripts([('tidstoraged',
__name__ + '.execute', 'execute')], self.ws, sys.executable, 'slapos.recipe.librecipe.execute', 'execute')], self.ws, sys.executable,
self.wrapper_directory, arguments=[ self.wrapper_directory, arguments=[
self.options['tidstoraged_binary'], '--nofork', '--config', self.options['tidstoraged_binary'], '--nofork', '--config',
tidstorage_config])[0] tidstorage_config])[0]
...@@ -599,7 +604,7 @@ class Recipe(BaseSlapRecipe): ...@@ -599,7 +604,7 @@ class Recipe(BaseSlapRecipe):
# repozo wrapper # repozo wrapper
tidstorage_repozo = zc.buildout.easy_install.scripts([('tidstorage_repozo', tidstorage_repozo = zc.buildout.easy_install.scripts([('tidstorage_repozo',
__name__ + '.execute', 'execute')], self.ws, sys.executable, 'slapos.recipe.librecipe.execute', 'execute')], self.ws, sys.executable,
self.bin_directory, arguments=[ self.bin_directory, arguments=[
self.options['tidstorage_repozo_binary'], '--config', tidstorage_config, self.options['tidstorage_repozo_binary'], '--config', tidstorage_config,
'--repozo', self.options['repozo_binary'], '-z'])[0] '--repozo', self.options['repozo_binary'], '-z'])[0]
...@@ -617,7 +622,19 @@ class Recipe(BaseSlapRecipe): ...@@ -617,7 +622,19 @@ class Recipe(BaseSlapRecipe):
def installZope(self, ip, port, name, zodb_configuration_string, def installZope(self, ip, port, name, zodb_configuration_string,
with_timerservice=False, tidstorage_config=None, thread_amount=1, with_timerservice=False, tidstorage_config=None, thread_amount=1,
with_deadlockdebugger=True): with_deadlockdebugger=True, zope_environment=None):
default_zope_environment = dict(
TMP=self.tmp_directory,
TMPDIR=self.tmp_directory,
HOME=self.tmp_directory,
PATH=self.bin_directory
)
if zope_environment is None:
zope_environment = default_zope_environment.copy()
else:
for envk, envv in default_zope_environment.iteritems():
if envk not in zope_environment:
zope_environment[envk] = envv
# Create zope configuration file # Create zope configuration file
zope_config = dict( zope_config = dict(
products=self.options['products'], products=self.options['products'],
...@@ -625,7 +642,7 @@ class Recipe(BaseSlapRecipe): ...@@ -625,7 +642,7 @@ class Recipe(BaseSlapRecipe):
) )
# configure default Zope2 zcml # configure default Zope2 zcml
open(os.path.join(self.erp5_directory, 'etc', 'site.zcml'), 'w').write( open(os.path.join(self.erp5_directory, 'etc', 'site.zcml'), 'w').write(
pkg_resources.resource_string('Zope2', 'utilities/skel/etc/site.zcml')) pkg_resources.resource_string(__name__, 'template/site.zcml'))
zope_config['zodb_configuration_string'] = zodb_configuration_string zope_config['zodb_configuration_string'] = zodb_configuration_string
zope_config['instance'] = self.erp5_directory zope_config['instance'] = self.erp5_directory
zope_config['event_log'] = os.path.join(self.log_directory, zope_config['event_log'] = os.path.join(self.log_directory,
...@@ -649,8 +666,10 @@ class Recipe(BaseSlapRecipe): ...@@ -649,8 +666,10 @@ class Recipe(BaseSlapRecipe):
self.erp5_directory, 'Products')) self.erp5_directory, 'Products'))
zope_config['products'] = '\n'.join(prefixed_products) zope_config['products'] = '\n'.join(prefixed_products)
zope_config['address'] = '%s:%s' % (ip, port) zope_config['address'] = '%s:%s' % (ip, port)
zope_config['tmp_directory'] = self.tmp_directory zope_environment_list = []
zope_config['path'] = self.bin_directory for envk, envv in zope_environment.iteritems():
zope_environment_list.append('%s %s' % (envk, envv))
zope_config['environment'] = "\n".join(zope_environment_list)
zope_wrapper_template_location = self.getTemplateFilename('zope.conf.in') zope_wrapper_template_location = self.getTemplateFilename('zope.conf.in')
zope_conf_content = self.substituteTemplate( zope_conf_content = self.substituteTemplate(
...@@ -673,7 +692,7 @@ class Recipe(BaseSlapRecipe): ...@@ -673,7 +692,7 @@ class Recipe(BaseSlapRecipe):
self.path_list.append(zope_conf_path) self.path_list.append(zope_conf_path)
# Create init script # Create init script
wrapper = zc.buildout.easy_install.scripts([(name, wrapper = zc.buildout.easy_install.scripts([(name,
__name__ + '.execute', 'execute')], self.ws, sys.executable, 'slapos.recipe.librecipe.execute', 'execute')], self.ws, sys.executable,
self.wrapper_directory, arguments=[ self.wrapper_directory, arguments=[
self.options['runzope_binary'].strip(), '-C', zope_conf_path] self.options['runzope_binary'].strip(), '-C', zope_conf_path]
)[0] )[0]
...@@ -888,13 +907,13 @@ class Recipe(BaseSlapRecipe): ...@@ -888,13 +907,13 @@ class Recipe(BaseSlapRecipe):
'--socket=%s' %mysql_conf['socket'].strip(), '--user=root'] '--socket=%s' %mysql_conf['socket'].strip(), '--user=root']
environment = dict(PATH='%s' % self.bin_directory) environment = dict(PATH='%s' % self.bin_directory)
innobackupex_incremental = zc.buildout.easy_install.scripts([( innobackupex_incremental = zc.buildout.easy_install.scripts([(
'innobackupex_incremental', __name__ + '.execute', 'executee')], 'innobackupex_incremental','slapos.recipe.librecipe.execute', 'executee')],
self.ws, sys.executable, self.bin_directory, arguments=[ self.ws, sys.executable, self.bin_directory, arguments=[
innobackupex_argument_list + ['--incremental'], innobackupex_argument_list + ['--incremental'],
environment])[0] environment])[0]
self.path_list.append(innobackupex_incremental) self.path_list.append(innobackupex_incremental)
innobackupex_full = zc.buildout.easy_install.scripts([('innobackupex_full', innobackupex_full = zc.buildout.easy_install.scripts([('innobackupex_full',
__name__ + '.execute', 'executee')], self.ws, 'slapos.recipe.librecipe.execute', 'executee')], self.ws,
sys.executable, self.bin_directory, arguments=[ sys.executable, self.bin_directory, arguments=[
innobackupex_argument_list, innobackupex_argument_list,
environment])[0] environment])[0]
......
# Apache configuration file for Zope # Apache configuration file for Zope
# Automatically generated # Automatically generated
# List of modules
LoadModule authz_host_module modules/mod_authz_host.so
LoadModule log_config_module modules/mod_log_config.so
LoadModule setenvif_module modules/mod_setenvif.so
LoadModule version_module modules/mod_version.so
LoadModule proxy_module modules/mod_proxy.so
LoadModule proxy_http_module modules/mod_proxy_http.so
LoadModule ssl_module modules/mod_ssl.so
LoadModule mime_module modules/mod_mime.so
LoadModule dav_module modules/mod_dav.so
LoadModule dav_fs_module modules/mod_dav_fs.so
LoadModule negotiation_module modules/mod_negotiation.so
LoadModule rewrite_module modules/mod_rewrite.so
LoadModule headers_module modules/mod_headers.so
LoadModule antiloris_module modules/mod_antiloris.so
# Basic server configuration # Basic server configuration
PidFile "%(pid_file)s" PidFile "%(pid_file)s"
LockFile "%(lock_file)s" LockFile "%(lock_file)s"
Listen %(ip)s:%(port)s Listen %(ip)s:%(port)s
ServerAdmin %(server_admin)s ServerAdmin %(server_admin)s
DefaultType text/plain
TypesConfig conf/mime.types TypesConfig conf/mime.types
AddType application/x-compress .Z AddType application/x-compress .Z
AddType application/x-gzip .gz .tgz AddType application/x-gzip .gz .tgz
...@@ -19,7 +34,6 @@ RequestHeader unset REMOTE_USER ...@@ -19,7 +34,6 @@ RequestHeader unset REMOTE_USER
# Log configuration # Log configuration
ErrorLog "%(error_log)s" ErrorLog "%(error_log)s"
LogLevel warn
LogFormat "%%h %%{REMOTE_USER}i %%l %%u %%t \"%%r\" %%>s %%b \"%%{Referer}i\" \"%%{User-Agent}i\"" combined LogFormat "%%h %%{REMOTE_USER}i %%l %%u %%t \"%%r\" %%>s %%b \"%%{Referer}i\" \"%%{User-Agent}i\"" combined
LogFormat "%%h %%{REMOTE_USER}i %%l %%u %%t \"%%r\" %%>s %%b" common LogFormat "%%h %%{REMOTE_USER}i %%l %%u %%t \"%%r\" %%>s %%b" common
CustomLog "%(access_log)s" common CustomLog "%(access_log)s" common
...@@ -37,19 +51,3 @@ CustomLog "%(access_log)s" common ...@@ -37,19 +51,3 @@ CustomLog "%(access_log)s" common
# Magic of Zope related rewrite # Magic of Zope related rewrite
RewriteEngine On RewriteEngine On
%(rewrite_rule)s %(rewrite_rule)s
# List of modules
LoadModule authz_host_module modules/mod_authz_host.so
LoadModule log_config_module modules/mod_log_config.so
LoadModule setenvif_module modules/mod_setenvif.so
LoadModule version_module modules/mod_version.so
LoadModule proxy_module modules/mod_proxy.so
LoadModule proxy_http_module modules/mod_proxy_http.so
LoadModule ssl_module modules/mod_ssl.so
LoadModule mime_module modules/mod_mime.so
LoadModule dav_module modules/mod_dav.so
LoadModule dav_fs_module modules/mod_dav_fs.so
LoadModule negotiation_module modules/mod_negotiation.so
LoadModule rewrite_module modules/mod_rewrite.so
LoadModule headers_module modules/mod_headers.so
LoadModule antiloris_module modules/mod_antiloris.so
<configure
xmlns="http://namespaces.zope.org/zope"
xmlns:meta="http://namespaces.zope.org/meta"
xmlns:five="http://namespaces.zope.org/five">
<include package="Products.Five" />
<meta:redefinePermission from="zope2.Public" to="zope.Public" />
<!-- Load the meta -->
<include files="package-includes/*-meta.zcml" />
<five:loadProducts file="meta.zcml"/>
<!-- Load the configuration -->
<include files="package-includes/*-configure.zcml" />
<five:loadProducts />
<!-- Load the configuration overrides-->
<includeOverrides files="package-includes/*-overrides.zcml" />
<five:loadProductsOverrides />
<securityPolicy
component="Products.Five.security.FiveSecurityPolicy" />
</configure>
...@@ -9,10 +9,7 @@ instancehome $INSTANCE ...@@ -9,10 +9,7 @@ instancehome $INSTANCE
# Environment override # Environment override
<environment> <environment>
TMP %(tmp_directory)s %(environment)s
TMPDIR %(tmp_directory)s
HOME %(tmp_directory)s
PATH %(path)s
</environment> </environment>
# No need to debug # No need to debug
......
...@@ -147,7 +147,7 @@ class Updater(object): ...@@ -147,7 +147,7 @@ class Updater(object):
# edit .git/info/sparse-checkout if you want sparse checkout # edit .git/info/sparse-checkout if you want sparse checkout
if revision: if revision:
if type(revision) is str: if type(revision) is str:
h = self._git_find_rev('r' + revision) h = revision
else: else:
h = revision[1] h = revision[1]
if h != self._git('rev-parse', 'HEAD'): if h != self._git('rev-parse', 'HEAD'):
......
...@@ -97,8 +97,8 @@ class Recipe(BaseSlapRecipe): ...@@ -97,8 +97,8 @@ class Recipe(BaseSlapRecipe):
bot_environment=self.parameter_dict.get('bot_environment', ''), bot_environment=self.parameter_dict.get('bot_environment', ''),
partition_reference=CONFIG['partition_reference'], partition_reference=CONFIG['partition_reference'],
environment=dict(PATH=os.environ['PATH']), environment=dict(PATH=os.environ['PATH']),
vcs_authentication_list=self.parameter_dict.get( vcs_authentication_list=eval(self.parameter_dict.get(
'vcs_authentication_list') 'vcs_authentication_list')),
) )
])) ]))
...@@ -112,8 +112,9 @@ class Recipe(BaseSlapRecipe): ...@@ -112,8 +112,9 @@ class Recipe(BaseSlapRecipe):
print "home_directory : %r" % home_directory print "home_directory : %r" % home_directory
git_dict.setdefault("git_server_name", "git.erp5.org") git_dict.setdefault("git_server_name", "git.erp5.org")
if git_dict.get('vcs_authentication_list', None) is not None: if git_dict.get('vcs_authentication_list', None) is not None:
vcs_authentication_list = eval(git_dict['vcs_authentication_list'])
netrc_file = open(os.path.join(home_directory, '.netrc'), 'w') netrc_file = open(os.path.join(home_directory, '.netrc'), 'w')
for vcs_authentication_dict in git_dict['vcs_authentication_list']: for vcs_authentication_dict in vcs_authentication_list:
netrc_file.write(""" netrc_file.write("""
machine %(host)s machine %(host)s
login %(user_name)s login %(user_name)s
......
...@@ -94,7 +94,7 @@ repository = %(repository_path)s ...@@ -94,7 +94,7 @@ repository = %(repository_path)s
branch = %(branch)s branch = %(branch)s
""" % {'buildout_section_id': buildout_section_id, """ % {'buildout_section_id': buildout_section_id,
'repository_path' : repository_path, 'repository_path' : repository_path,
'branch' : vcs_repository.get('branch','')} 'branch' : vcs_repository.get('branch','master')}
custom_profile = open(custom_profile_path, 'w') custom_profile = open(custom_profile_path, 'w')
custom_profile.write(profile_content) custom_profile.write(profile_content)
...@@ -224,6 +224,7 @@ branch = %(branch)s ...@@ -224,6 +224,7 @@ branch = %(branch)s
invocation_list.extend([run_test_suite_path, invocation_list.extend([run_test_suite_path,
'--test_suite', config['test_suite'], '--test_suite', config['test_suite'],
'--revision', revision, '--revision', revision,
'--test_suite_title', test_suite_title,
'--node_quantity', config['node_quantity'], '--node_quantity', config['node_quantity'],
'--master_url', config['test_suite_master_url']]) '--master_url', config['test_suite_master_url']])
run_test_suite = subprocess.Popen(invocation_list) run_test_suite = subprocess.Popen(invocation_list)
......
##############################################################################
#
# 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.
#
##############################################################################
from slapos.recipe.librecipe import BaseSlapRecipe
import hashlib
import os
import pkg_resources
import sys
import zc.buildout
import ConfigParser
class Recipe(BaseSlapRecipe):
def getTemplateFilename(self, template_name):
return pkg_resources.resource_filename(__name__,
'template/%s' % template_name)
def _install(self):
self.path_list = []
self.requirements, self.ws = self.egg.working_set()
# XXX-Cedric : add logrotate?
self.cron_d = self.installCrond()
kumo_conf = self.installKumo(self.getLocalIPv4Address())
ca_conf = self.installCertificateAuthority()
key, certificate = self.requestCertificate('Login Based Access')
stunnel_conf = self.installStunnel(self.getGlobalIPv6Address(),
self.getLocalIPv4Address(), 12345, kumo_conf['kumo_gateway_port'],
certificate, key, ca_conf['ca_crl'],
ca_conf['certificate_authority_path'])
self.linkBinary()
self.setConnectionDict(dict(
stunnel_ip = stunnel_conf['public_ip'],
stunnel_port = stunnel_conf['public_port'],
))
return self.path_list
def linkBinary(self):
"""Links binaries to instance's bin directory for easier exposal"""
for linkline in self.options.get('link_binary_list', '').splitlines():
if not linkline:
continue
target = linkline.split()
if len(target) == 1:
target = target[0]
path, linkname = os.path.split(target)
else:
linkname = target[1]
target = target[0]
link = os.path.join(self.bin_directory, linkname)
if os.path.lexists(link):
if not os.path.islink(link):
raise zc.buildout.UserError(
'Target link already %r exists but it is not link' % link)
os.unlink(link)
os.symlink(target, link)
self.logger.debug('Created link %r -> %r' % (link, target))
self.path_list.append(link)
def installCrond(self):
timestamps = self.createDataDirectory('cronstamps')
cron_output = os.path.join(self.log_directory, 'cron-output')
self._createDirectory(cron_output)
catcher = zc.buildout.easy_install.scripts([('catchcron',
__name__ + '.catdatefile', 'catdatefile')], self.ws, sys.executable,
self.bin_directory, arguments=[cron_output])[0]
self.path_list.append(catcher)
cron_d = os.path.join(self.etc_directory, 'cron.d')
crontabs = os.path.join(self.etc_directory, 'crontabs')
self._createDirectory(cron_d)
self._createDirectory(crontabs)
# Use execute from erp5.
wrapper = zc.buildout.easy_install.scripts([('crond',
'slapos.recipe.librecipe.execute', 'execute')], self.ws, sys.executable,
self.wrapper_directory, arguments=[
self.options['dcrond_binary'].strip(), '-s', cron_d, '-c', crontabs,
'-t', timestamps, '-f', '-l', '5', '-M', catcher]
)[0]
self.path_list.append(wrapper)
return cron_d
def installLogrotate(self):
"""Installs logortate main configuration file and registers its to cron"""
logrotate_d = os.path.abspath(os.path.join(self.etc_directory,
'logrotate.d'))
self._createDirectory(logrotate_d)
logrotate_backup = self.createBackupDirectory('logrotate')
logrotate_conf = self.createConfigurationFile("logrotate.conf",
"include %s" % logrotate_d)
logrotate_cron = os.path.join(self.cron_d, 'logrotate')
state_file = os.path.join(self.data_root_directory, 'logrotate.status')
open(logrotate_cron, 'w').write('0 0 * * * %s -s %s %s' %
(self.options['logrotate_binary'], state_file, logrotate_conf))
self.path_list.extend([logrotate_d, logrotate_conf, logrotate_cron])
return logrotate_d, logrotate_backup
def registerLogRotation(self, name, log_file_list, postrotate_script):
"""Register new log rotation requirement"""
open(os.path.join(self.logrotate_d, name), 'w').write(
self.substituteTemplate(self.getTemplateFilename(
'logrotate_entry.in'),
dict(file_list=' '.join(['"'+q+'"' for q in log_file_list]),
postrotate=postrotate_script, olddir=self.logrotate_backup)))
def installCertificateAuthority(self, ca_country_code='XX',
ca_email='xx@example.com', ca_state='State', ca_city='City',
ca_company='Company'):
backup_path = self.createBackupDirectory('ca')
self.ca_dir = os.path.join(self.data_root_directory, 'ca')
self._createDirectory(self.ca_dir)
self.ca_request_dir = os.path.join(self.ca_dir, 'requests')
self._createDirectory(self.ca_request_dir)
config = dict(ca_dir=self.ca_dir, request_dir=self.ca_request_dir)
self.ca_private = os.path.join(self.ca_dir, 'private')
self.ca_certs = os.path.join(self.ca_dir, 'certs')
self.ca_crl = os.path.join(self.ca_dir, 'crl')
self.ca_newcerts = os.path.join(self.ca_dir, 'newcerts')
self.ca_key_ext = '.key'
self.ca_crt_ext = '.crt'
for d in [self.ca_private, self.ca_crl, self.ca_newcerts, self.ca_certs]:
self._createDirectory(d)
for f in ['crlnumber', 'serial']:
if not os.path.exists(os.path.join(self.ca_dir, f)):
open(os.path.join(self.ca_dir, f), 'w').write('01')
if not os.path.exists(os.path.join(self.ca_dir, 'index.txt')):
open(os.path.join(self.ca_dir, 'index.txt'), 'w').write('')
openssl_configuration = os.path.join(self.ca_dir, 'openssl.cnf')
config.update(
working_directory=self.ca_dir,
country_code=ca_country_code,
state=ca_state,
city=ca_city,
company=ca_company,
email_address=ca_email,
)
self._writeFile(openssl_configuration, pkg_resources.resource_string(
__name__, 'template/openssl.cnf.ca.in') % config)
self.path_list.extend(zc.buildout.easy_install.scripts([
('certificate_authority',
__name__ + '.certificate_authority', 'runCertificateAuthority')],
self.ws, sys.executable, self.wrapper_directory, arguments=[dict(
openssl_configuration=openssl_configuration,
openssl_binary=self.options['openssl_binary'],
certificate=os.path.join(self.ca_dir, 'cacert.pem'),
key=os.path.join(self.ca_private, 'cakey.pem'),
crl=os.path.join(self.ca_crl),
request_dir=self.ca_request_dir
)]))
# configure backup
backup_cron = os.path.join(self.cron_d, 'ca_rdiff_backup')
open(backup_cron, 'w').write(
'''0 0 * * * %(rdiff_backup)s %(source)s %(destination)s'''%dict(
rdiff_backup=self.options['rdiff_backup_binary'],
source=self.ca_dir,
destination=backup_path))
self.path_list.append(backup_cron)
return dict(
ca_certificate=os.path.join(config['ca_dir'], 'cacert.pem'),
ca_crl=os.path.join(config['ca_dir'], 'crl'),
certificate_authority_path=config['ca_dir']
)
def requestCertificate(self, name):
hash = hashlib.sha512(name).hexdigest()
key = os.path.join(self.ca_private, hash + self.ca_key_ext)
certificate = os.path.join(self.ca_certs, hash + self.ca_crt_ext)
parser = ConfigParser.RawConfigParser()
parser.add_section('certificate')
parser.set('certificate', 'name', name)
parser.set('certificate', 'key_file', key)
parser.set('certificate', 'certificate_file', certificate)
parser.write(open(os.path.join(self.ca_request_dir, hash), 'w'))
return key, certificate
def installStunnel(self, public_ip, private_ip, public_port, private_port,
ca_certificate, key, ca_crl, ca_path):
"""Installs stunnel"""
template_filename = self.getTemplateFilename('stunnel.conf.in')
log = os.path.join(self.log_directory, 'stunnel.log')
pid_file = os.path.join(self.run_directory, 'stunnel.pid')
stunnel_conf = dict(
public_ip=public_ip,
private_ip=private_ip,
public_port=public_port,
pid_file=pid_file,
log=log,
cert = ca_certificate,
key = key,
ca_crl = ca_crl,
ca_path = ca_path,
private_port = private_port,
)
stunnel_conf_path = self.createConfigurationFile("stunnel.conf",
self.substituteTemplate(template_filename,
stunnel_conf))
wrapper = zc.buildout.easy_install.scripts([('stunnel',
'slapos.recipe.librecipe.execute', 'execute')], self.ws, sys.executable,
self.wrapper_directory, arguments=[
self.options['stunnel_binary'].strip(), stunnel_conf_path]
)[0]
self.path_list.append(wrapper)
return stunnel_conf
def installKumo(self, ip, kumo_manager_port=13101, kumo_server_port=13201,
kumo_server_listen_port=13202, kumo_gateway_port=13301):
# XXX: kumo is not storing pid in file, unless it is not running as daemon
# but running daemons is incompatible with SlapOS, so there is currently
# no way to have Kumo's pid files to rotate logs and send signals to them
config = dict(
kumo_gateway_binary=self.options['kumo_gateway_binary'],
kumo_gateway_ip=ip,
kumo_gateway_log=os.path.join(self.log_directory, "kumo-gateway.log"),
kumo_manager_binary=self.options['kumo_manager_binary'],
kumo_manager_ip=ip,
kumo_manager_log=os.path.join(self.log_directory, "kumo-manager.log"),
kumo_server_binary=self.options['kumo_server_binary'],
kumo_server_ip=ip,
kumo_server_log=os.path.join(self.log_directory, "kumo-server.log"),
kumo_server_storage=os.path.join(self.data_root_directory, "kumodb.tch"),
kumo_manager_port=kumo_manager_port,
kumo_server_port=kumo_server_port,
kumo_server_listen_port=kumo_server_listen_port,
kumo_gateway_port=kumo_gateway_port
)
self.path_list.append(self.createRunningWrapper('kumo_gateway',
self.substituteTemplate(self.getTemplateFilename('kumo_gateway.in'),
config)))
self.path_list.append(self.createRunningWrapper('kumo_manager',
self.substituteTemplate(self.getTemplateFilename('kumo_manager.in'),
config)))
self.path_list.append(self.createRunningWrapper('kumo_server',
self.substituteTemplate(self.getTemplateFilename('kumo_server.in'),
config)))
return dict(
kumo_address = '%s:%s' % (config['kumo_gateway_ip'],
config['kumo_gateway_port']),
kumo_gateway_ip=config['kumo_gateway_ip'],
kumo_gateway_port=config['kumo_gateway_port'],
)
\ No newline at end of file
import os
import subprocess
import time
import ConfigParser
def popenCommunicate(command_list, input=None):
subprocess_kw = dict(stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
if input is not None:
subprocess_kw.update(stdin=subprocess.PIPE)
popen = subprocess.Popen(command_list, **subprocess_kw)
result = popen.communicate(input)[0]
if popen.returncode is None:
popen.kill()
if popen.returncode != 0:
raise ValueError('Issue during calling %r, result was:\n%s' % (
command_list, result))
return result
class CertificateAuthority:
def __init__(self, key, certificate, openssl_binary,
openssl_configuration, request_dir):
self.key = key
self.certificate = certificate
self.openssl_binary = openssl_binary
self.openssl_configuration = openssl_configuration
self.request_dir = request_dir
def checkAuthority(self):
file_list = [ self.key, self.certificate ]
ca_ready = True
for f in file_list:
if not os.path.exists(f):
ca_ready = False
break
if ca_ready:
return
for f in file_list:
if os.path.exists(f):
os.unlink(f)
try:
# no CA, let us create new one
popenCommunicate([self.openssl_binary, 'req', '-nodes', '-config',
self.openssl_configuration, '-new', '-x509', '-extensions',
'v3_ca', '-keyout', self.key, '-out', self.certificate,
'-days', '10950'], 'Automatic Certificate Authority\n')
except:
try:
for f in file_list:
if os.path.exists(f):
os.unlink(f)
except:
# do not raise during cleanup
pass
raise
def _checkCertificate(self, common_name, key, certificate):
file_list = [key, certificate]
ready = True
for f in file_list:
if not os.path.exists(f):
ready = False
break
if ready:
return False
for f in file_list:
if os.path.exists(f):
os.unlink(f)
csr = certificate + '.csr'
try:
popenCommunicate([self.openssl_binary, 'req', '-config',
self.openssl_configuration, '-nodes', '-new', '-keyout',
key, '-out', csr, '-days', '3650'],
common_name + '\n')
try:
popenCommunicate([self.openssl_binary, 'ca', '-batch', '-config',
self.openssl_configuration, '-out', certificate,
'-infiles', csr])
finally:
if os.path.exists(csr):
os.unlink(csr)
except:
try:
for f in file_list:
if os.path.exists(f):
os.unlink(f)
except:
# do not raise during cleanup
pass
raise
else:
return True
def checkRequestDir(self):
for request_file in os.listdir(self.request_dir):
parser = ConfigParser.RawConfigParser()
parser.readfp(open(os.path.join(self.request_dir, request_file), 'r'))
if self._checkCertificate(parser.get('certificate', 'name'),
parser.get('certificate', 'key_file'), parser.get('certificate',
'certificate_file')):
print 'Created certificate %r' % parser.get('certificate', 'name')
def runCertificateAuthority(args):
ca_conf = args[0]
ca = CertificateAuthority(ca_conf['key'], ca_conf['certificate'],
ca_conf['openssl_binary'], ca_conf['openssl_configuration'],
ca_conf['request_dir'])
while True:
ca.checkAuthority()
ca.checkRequestDir()
time.sleep(60)
#!/bin/sh
exec %(kumo_gateway_binary)s -F -E -m %(kumo_manager_ip)s:%(kumo_manager_port)s -t %(kumo_gateway_ip)s:%(kumo_gateway_port)s -o %(kumo_gateway_log)s
#!/bin/sh
exec %(kumo_manager_binary)s -a -l %(kumo_manager_ip)s:%(kumo_manager_port)s -o %(kumo_manager_log)s
#!/bin/sh
exec %(kumo_server_binary)s -l %(kumo_server_ip)s:%(kumo_server_port)s -L %(kumo_server_listen_port)s -m %(kumo_manager_ip)s:%(kumo_manager_port)s -s %(kumo_server_storage)s -o %(kumo_server_log)s
#
# OpenSSL example configuration file.
# This is mostly being used for generation of certificate requests.
#
# This definition stops the following lines choking if HOME isn't
# defined.
HOME = .
RANDFILE = $ENV::HOME/.rnd
# Extra OBJECT IDENTIFIER info:
#oid_file = $ENV::HOME/.oid
oid_section = new_oids
# To use this configuration file with the "-extfile" option of the
# "openssl x509" utility, name here the section containing the
# X.509v3 extensions to use:
# extensions =
# (Alternatively, use a configuration file that has only
# X.509v3 extensions in its main [= default] section.)
[ new_oids ]
# We can add new OIDs in here for use by 'ca', 'req' and 'ts'.
# Add a simple OID like this:
# testoid1=1.2.3.4
# Or use config file substitution like this:
# testoid2=${testoid1}.5.6
# Policies used by the TSA examples.
tsa_policy1 = 1.2.3.4.1
tsa_policy2 = 1.2.3.4.5.6
tsa_policy3 = 1.2.3.4.5.7
####################################################################
[ ca ]
default_ca = CA_default # The default ca section
####################################################################
[ CA_default ]
dir = %(working_directory)s # Where everything is kept
certs = $dir/certs # Where the issued certs are kept
crl_dir = $dir/crl # Where the issued crl are kept
database = $dir/index.txt # database index file.
#unique_subject = no # Set to 'no' to allow creation of
# several ctificates with same subject.
new_certs_dir = $dir/newcerts # default place for new certs.
certificate = $dir/cacert.pem # The CA certificate
serial = $dir/serial # The current serial number
crlnumber = $dir/crlnumber # the current crl number
# must be commented out to leave a V1 CRL
crl = $dir/crl.pem # The current CRL
private_key = $dir/private/cakey.pem # The private key
RANDFILE = $dir/private/.rand # private random number file
x509_extensions = usr_cert # The extentions to add to the cert
# Comment out the following two lines for the "traditional"
# (and highly broken) format.
name_opt = ca_default # Subject Name options
cert_opt = ca_default # Certificate field options
# Extension copying option: use with caution.
# copy_extensions = copy
# Extensions to add to a CRL. Note: Netscape communicator chokes on V2 CRLs
# so this is commented out by default to leave a V1 CRL.
# crlnumber must also be commented out to leave a V1 CRL.
# crl_extensions = crl_ext
default_days = 3650 # how long to certify for
default_crl_days= 30 # how long before next CRL
default_md = default # use public key default MD
preserve = no # keep passed DN ordering
# A few difference way of specifying how similar the request should look
# For type CA, the listed attributes must be the same, and the optional
# and supplied fields are just that :-)
policy = policy_match
# For the CA policy
[ policy_match ]
countryName = match
stateOrProvinceName = match
organizationName = match
organizationalUnitName = optional
commonName = supplied
emailAddress = optional
# For the 'anything' policy
# At this point in time, you must list all acceptable 'object'
# types.
[ policy_anything ]
countryName = optional
stateOrProvinceName = optional
localityName = optional
organizationName = optional
organizationalUnitName = optional
commonName = supplied
emailAddress = optional
####################################################################
[ req ]
default_bits = 2048
default_md = sha1
default_keyfile = privkey.pem
distinguished_name = req_distinguished_name
#attributes = req_attributes
x509_extensions = v3_ca # The extentions to add to the self signed cert
# Passwords for private keys if not present they will be prompted for
# input_password = secret
# output_password = secret
# This sets a mask for permitted string types. There are several options.
# default: PrintableString, T61String, BMPString.
# pkix : PrintableString, BMPString (PKIX recommendation before 2004)
# utf8only: only UTF8Strings (PKIX recommendation after 2004).
# nombstr : PrintableString, T61String (no BMPStrings or UTF8Strings).
# MASK:XXXX a literal mask value.
# WARNING: ancient versions of Netscape crash on BMPStrings or UTF8Strings.
string_mask = utf8only
# req_extensions = v3_req # The extensions to add to a certificate request
[ req_distinguished_name ]
countryName = Country Name (2 letter code)
countryName_value = %(country_code)s
countryName_min = 2
countryName_max = 2
stateOrProvinceName = State or Province Name (full name)
stateOrProvinceName_value = %(state)s
localityName = Locality Name (eg, city)
localityName_value = %(city)s
0.organizationName = Organization Name (eg, company)
0.organizationName_value = %(company)s
# we can do this but it is not needed normally :-)
#1.organizationName = Second Organization Name (eg, company)
#1.organizationName_default = World Wide Web Pty Ltd
commonName = Common Name (eg, your name or your server\'s hostname)
commonName_max = 64
emailAddress = Email Address
emailAddress_value = %(email_address)s
emailAddress_max = 64
# SET-ex3 = SET extension number 3
#[ req_attributes ]
#challengePassword = A challenge password
#challengePassword_min = 4
#challengePassword_max = 20
#
#unstructuredName = An optional company name
[ usr_cert ]
# These extensions are added when 'ca' signs a request.
# This goes against PKIX guidelines but some CAs do it and some software
# requires this to avoid interpreting an end user certificate as a CA.
basicConstraints=CA:FALSE
# Here are some examples of the usage of nsCertType. If it is omitted
# the certificate can be used for anything *except* object signing.
# This is OK for an SSL server.
# nsCertType = server
# For an object signing certificate this would be used.
# nsCertType = objsign
# For normal client use this is typical
# nsCertType = client, email
# and for everything including object signing:
# nsCertType = client, email, objsign
# This is typical in keyUsage for a client certificate.
# keyUsage = nonRepudiation, digitalSignature, keyEncipherment
# This will be displayed in Netscape's comment listbox.
nsComment = "OpenSSL Generated Certificate"
# PKIX recommendations harmless if included in all certificates.
subjectKeyIdentifier=hash
authorityKeyIdentifier=keyid,issuer
# This stuff is for subjectAltName and issuerAltname.
# Import the email address.
# subjectAltName=email:copy
# An alternative to produce certificates that aren't
# deprecated according to PKIX.
# subjectAltName=email:move
# Copy subject details
# issuerAltName=issuer:copy
#nsCaRevocationUrl = http://www.domain.dom/ca-crl.pem
#nsBaseUrl
#nsRevocationUrl
#nsRenewalUrl
#nsCaPolicyUrl
#nsSslServerName
# This is required for TSA certificates.
# extendedKeyUsage = critical,timeStamping
[ v3_req ]
# Extensions to add to a certificate request
basicConstraints = CA:FALSE
keyUsage = nonRepudiation, digitalSignature, keyEncipherment
[ v3_ca ]
# Extensions for a typical CA
# PKIX recommendation.
subjectKeyIdentifier=hash
authorityKeyIdentifier=keyid:always,issuer
# This is what PKIX recommends but some broken software chokes on critical
# extensions.
#basicConstraints = critical,CA:true
# So we do this instead.
basicConstraints = CA:true
# Key usage: this is typical for a CA certificate. However since it will
# prevent it being used as an test self-signed certificate it is best
# left out by default.
# keyUsage = cRLSign, keyCertSign
# Some might want this also
# nsCertType = sslCA, emailCA
# Include email address in subject alt name: another PKIX recommendation
# subjectAltName=email:copy
# Copy issuer details
# issuerAltName=issuer:copy
# DER hex encoding of an extension: beware experts only!
# obj=DER:02:03
# Where 'obj' is a standard or added object
# You can even override a supported extension:
# basicConstraints= critical, DER:30:03:01:01:FF
[ crl_ext ]
# CRL extensions.
# Only issuerAltName and authorityKeyIdentifier make any sense in a CRL.
# issuerAltName=issuer:copy
authorityKeyIdentifier=keyid:always
[ proxy_cert_ext ]
# These extensions should be added when creating a proxy certificate
# This goes against PKIX guidelines but some CAs do it and some software
# requires this to avoid interpreting an end user certificate as a CA.
basicConstraints=CA:FALSE
# Here are some examples of the usage of nsCertType. If it is omitted
# the certificate can be used for anything *except* object signing.
# This is OK for an SSL server.
# nsCertType = server
# For an object signing certificate this would be used.
# nsCertType = objsign
# For normal client use this is typical
# nsCertType = client, email
# and for everything including object signing:
# nsCertType = client, email, objsign
# This is typical in keyUsage for a client certificate.
# keyUsage = nonRepudiation, digitalSignature, keyEncipherment
# This will be displayed in Netscape's comment listbox.
nsComment = "OpenSSL Generated Certificate"
# PKIX recommendations harmless if included in all certificates.
subjectKeyIdentifier=hash
authorityKeyIdentifier=keyid,issuer
# This stuff is for subjectAltName and issuerAltname.
# Import the email address.
# subjectAltName=email:copy
# An alternative to produce certificates that aren't
# deprecated according to PKIX.
# subjectAltName=email:move
# Copy subject details
# issuerAltName=issuer:copy
#nsCaRevocationUrl = http://www.domain.dom/ca-crl.pem
#nsBaseUrl
#nsRevocationUrl
#nsRenewalUrl
#nsCaPolicyUrl
#nsSslServerName
# This really needs to be in place for it to be a proxy certificate.
proxyCertInfo=critical,language:id-ppl-anyLanguage,pathlen:3,policy:foo
####################################################################
[ tsa ]
default_tsa = tsa_config1 # the default TSA section
[ tsa_config1 ]
# These are used by the TSA reply generation only.
dir = /etc/pki/tls # TSA root directory
serial = $dir/tsaserial # The current serial number (mandatory)
crypto_device = builtin # OpenSSL engine to use for signing
signer_cert = $dir/tsacert.pem # The TSA signing certificate
# (optional)
certs = $dir/cacert.pem # Certificate chain to include in reply
# (optional)
signer_key = $dir/private/tsakey.pem # The TSA private key (optional)
default_policy = tsa_policy1 # Policy if request did not specify it
# (optional)
other_policies = tsa_policy2, tsa_policy3 # acceptable policies (optional)
digests = md5, sha1 # Acceptable message digests (mandatory)
accuracy = secs:1, millisecs:500, microsecs:100 # (optional)
clock_precision_digits = 0 # number of digits after dot. (optional)
ordering = yes # Is ordering defined for timestamps?
# (optional, default: no)
tsa_name = yes # Must the TSA name be included in the reply?
# (optional, default: no)
ess_cert_id_chain = no # Must the ESS cert id chain be included?
# (optional, default: no)
foreground = yes
output = %(log)s
pid = %(pid_file)s
syslog = no
CApath = %(ca_path)s
key = %(key)s
CRLpath = %(ca_crl)s
cert = %(cert)s
[service]
accept = %(public_ip)s:%(public_port)s
connect = %(private_ip)s:%(private_port)s
##############################################################################
#
# 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.
#
##############################################################################
from slapos.recipe.librecipe import BaseSlapRecipe
import hashlib
import os
import pkg_resources
import sys
import zc.buildout
import ConfigParser
class Recipe(BaseSlapRecipe):
def getTemplateFilename(self, template_name):
return pkg_resources.resource_filename(__name__,
'template/%s' % template_name)
def _install(self):
self.path_list = []
self.requirements, self.ws = self.egg.working_set()
# XXX-Cedric : add logrotate?
self.cron_d = self.installCrond()
memcached_conf = self.installMemcached(ip=self.getLocalIPv4Address(),
port=11000)
ca_conf = self.installCertificateAuthority()
key, certificate = self.requestCertificate('Memcached')
stunnel_conf = self.installStunnel(self.getGlobalIPv6Address(),
self.getLocalIPv4Address(), 12345, memcached_conf['memcached_port'],
certificate, key, ca_conf['ca_crl'],
ca_conf['certificate_authority_path'])
self.linkBinary()
self.setConnectionDict(dict(
stunnel_ip = stunnel_conf['public_ip'],
stunnel_port = stunnel_conf['public_port'],
))
return self.path_list
def linkBinary(self):
"""Links binaries to instance's bin directory for easier exposal"""
for linkline in self.options.get('link_binary_list', '').splitlines():
if not linkline:
continue
target = linkline.split()
if len(target) == 1:
target = target[0]
path, linkname = os.path.split(target)
else:
linkname = target[1]
target = target[0]
link = os.path.join(self.bin_directory, linkname)
if os.path.lexists(link):
if not os.path.islink(link):
raise zc.buildout.UserError(
'Target link already %r exists but it is not link' % link)
os.unlink(link)
os.symlink(target, link)
self.logger.debug('Created link %r -> %r' % (link, target))
self.path_list.append(link)
def installCrond(self):
timestamps = self.createDataDirectory('cronstamps')
cron_output = os.path.join(self.log_directory, 'cron-output')
self._createDirectory(cron_output)
catcher = zc.buildout.easy_install.scripts([('catchcron',
__name__ + '.catdatefile', 'catdatefile')], self.ws, sys.executable,
self.bin_directory, arguments=[cron_output])[0]
self.path_list.append(catcher)
cron_d = os.path.join(self.etc_directory, 'cron.d')
crontabs = os.path.join(self.etc_directory, 'crontabs')
self._createDirectory(cron_d)
self._createDirectory(crontabs)
# Use execute from erp5.
wrapper = zc.buildout.easy_install.scripts([('crond',
'slapos.recipe.librecipe.execute', 'execute')], self.ws, sys.executable,
self.wrapper_directory, arguments=[
self.options['dcrond_binary'].strip(), '-s', cron_d, '-c', crontabs,
'-t', timestamps, '-f', '-l', '5', '-M', catcher]
)[0]
self.path_list.append(wrapper)
return cron_d
def installLogrotate(self):
"""Installs logortate main configuration file and registers its to cron"""
logrotate_d = os.path.abspath(os.path.join(self.etc_directory,
'logrotate.d'))
self._createDirectory(logrotate_d)
logrotate_backup = self.createBackupDirectory('logrotate')
logrotate_conf = self.createConfigurationFile("logrotate.conf",
"include %s" % logrotate_d)
logrotate_cron = os.path.join(self.cron_d, 'logrotate')
state_file = os.path.join(self.data_root_directory, 'logrotate.status')
open(logrotate_cron, 'w').write('0 0 * * * %s -s %s %s' %
(self.options['logrotate_binary'], state_file, logrotate_conf))
self.path_list.extend([logrotate_d, logrotate_conf, logrotate_cron])
return logrotate_d, logrotate_backup
def registerLogRotation(self, name, log_file_list, postrotate_script):
"""Register new log rotation requirement"""
open(os.path.join(self.logrotate_d, name), 'w').write(
self.substituteTemplate(self.getTemplateFilename(
'logrotate_entry.in'),
dict(file_list=' '.join(['"'+q+'"' for q in log_file_list]),
postrotate=postrotate_script, olddir=self.logrotate_backup)))
def installCertificateAuthority(self, ca_country_code='XX',
ca_email='xx@example.com', ca_state='State', ca_city='City',
ca_company='Company'):
backup_path = self.createBackupDirectory('ca')
self.ca_dir = os.path.join(self.data_root_directory, 'ca')
self._createDirectory(self.ca_dir)
self.ca_request_dir = os.path.join(self.ca_dir, 'requests')
self._createDirectory(self.ca_request_dir)
config = dict(ca_dir=self.ca_dir, request_dir=self.ca_request_dir)
self.ca_private = os.path.join(self.ca_dir, 'private')
self.ca_certs = os.path.join(self.ca_dir, 'certs')
self.ca_crl = os.path.join(self.ca_dir, 'crl')
self.ca_newcerts = os.path.join(self.ca_dir, 'newcerts')
self.ca_key_ext = '.key'
self.ca_crt_ext = '.crt'
for d in [self.ca_private, self.ca_crl, self.ca_newcerts, self.ca_certs]:
self._createDirectory(d)
for f in ['crlnumber', 'serial']:
if not os.path.exists(os.path.join(self.ca_dir, f)):
open(os.path.join(self.ca_dir, f), 'w').write('01')
if not os.path.exists(os.path.join(self.ca_dir, 'index.txt')):
open(os.path.join(self.ca_dir, 'index.txt'), 'w').write('')
openssl_configuration = os.path.join(self.ca_dir, 'openssl.cnf')
config.update(
working_directory=self.ca_dir,
country_code=ca_country_code,
state=ca_state,
city=ca_city,
company=ca_company,
email_address=ca_email,
)
self._writeFile(openssl_configuration, pkg_resources.resource_string(
__name__, 'template/openssl.cnf.ca.in') % config)
self.path_list.extend(zc.buildout.easy_install.scripts([
('certificate_authority',
__name__ + '.certificate_authority', 'runCertificateAuthority')],
self.ws, sys.executable, self.wrapper_directory, arguments=[dict(
openssl_configuration=openssl_configuration,
openssl_binary=self.options['openssl_binary'],
certificate=os.path.join(self.ca_dir, 'cacert.pem'),
key=os.path.join(self.ca_private, 'cakey.pem'),
crl=os.path.join(self.ca_crl),
request_dir=self.ca_request_dir
)]))
# configure backup
backup_cron = os.path.join(self.cron_d, 'ca_rdiff_backup')
open(backup_cron, 'w').write(
'''0 0 * * * %(rdiff_backup)s %(source)s %(destination)s'''%dict(
rdiff_backup=self.options['rdiff_backup_binary'],
source=self.ca_dir,
destination=backup_path))
self.path_list.append(backup_cron)
return dict(
ca_certificate=os.path.join(config['ca_dir'], 'cacert.pem'),
ca_crl=os.path.join(config['ca_dir'], 'crl'),
certificate_authority_path=config['ca_dir']
)
def requestCertificate(self, name):
hash = hashlib.sha512(name).hexdigest()
key = os.path.join(self.ca_private, hash + self.ca_key_ext)
certificate = os.path.join(self.ca_certs, hash + self.ca_crt_ext)
parser = ConfigParser.RawConfigParser()
parser.add_section('certificate')
parser.set('certificate', 'name', name)
parser.set('certificate', 'key_file', key)
parser.set('certificate', 'certificate_file', certificate)
parser.write(open(os.path.join(self.ca_request_dir, hash), 'w'))
return key, certificate
def installStunnel(self, public_ip, private_ip, public_port, private_port,
ca_certificate, key, ca_crl, ca_path):
"""Installs stunnel"""
template_filename = self.getTemplateFilename('stunnel.conf.in')
log = os.path.join(self.log_directory, 'stunnel.log')
pid_file = os.path.join(self.run_directory, 'stunnel.pid')
stunnel_conf = dict(
public_ip=public_ip,
private_ip=private_ip,
public_port=public_port,
pid_file=pid_file,
log=log,
cert = ca_certificate,
key = key,
ca_crl = ca_crl,
ca_path = ca_path,
private_port = private_port,
)
stunnel_conf_path = self.createConfigurationFile("stunnel.conf",
self.substituteTemplate(template_filename,
stunnel_conf))
wrapper = zc.buildout.easy_install.scripts([('stunnel',
'slapos.recipe.librecipe.execute', 'execute')], self.ws, sys.executable,
self.wrapper_directory, arguments=[
self.options['stunnel_binary'].strip(), stunnel_conf_path]
)[0]
self.path_list.append(wrapper)
return stunnel_conf
def installMemcached(self, ip, port):
config = dict(
memcached_binary=self.options['memcached_binary'],
memcached_ip=ip,
memcached_port=port,
)
self.path_list.append(self.createRunningWrapper('memcached',
self.substituteTemplate(self.getTemplateFilename('memcached.in'),
config)))
return dict(memcached_url='%s:%s' %
(config['memcached_ip'], config['memcached_port']),
memcached_ip=config['memcached_ip'],
memcached_port=config['memcached_port'])
import os
import subprocess
import time
import ConfigParser
def popenCommunicate(command_list, input=None):
subprocess_kw = dict(stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
if input is not None:
subprocess_kw.update(stdin=subprocess.PIPE)
popen = subprocess.Popen(command_list, **subprocess_kw)
result = popen.communicate(input)[0]
if popen.returncode is None:
popen.kill()
if popen.returncode != 0:
raise ValueError('Issue during calling %r, result was:\n%s' % (
command_list, result))
return result
class CertificateAuthority:
def __init__(self, key, certificate, openssl_binary,
openssl_configuration, request_dir):
self.key = key
self.certificate = certificate
self.openssl_binary = openssl_binary
self.openssl_configuration = openssl_configuration
self.request_dir = request_dir
def checkAuthority(self):
file_list = [ self.key, self.certificate ]
ca_ready = True
for f in file_list:
if not os.path.exists(f):
ca_ready = False
break
if ca_ready:
return
for f in file_list:
if os.path.exists(f):
os.unlink(f)
try:
# no CA, let us create new one
popenCommunicate([self.openssl_binary, 'req', '-nodes', '-config',
self.openssl_configuration, '-new', '-x509', '-extensions',
'v3_ca', '-keyout', self.key, '-out', self.certificate,
'-days', '10950'], 'Automatic Certificate Authority\n')
except:
try:
for f in file_list:
if os.path.exists(f):
os.unlink(f)
except:
# do not raise during cleanup
pass
raise
def _checkCertificate(self, common_name, key, certificate):
file_list = [key, certificate]
ready = True
for f in file_list:
if not os.path.exists(f):
ready = False
break
if ready:
return False
for f in file_list:
if os.path.exists(f):
os.unlink(f)
csr = certificate + '.csr'
try:
popenCommunicate([self.openssl_binary, 'req', '-config',
self.openssl_configuration, '-nodes', '-new', '-keyout',
key, '-out', csr, '-days', '3650'],
common_name + '\n')
try:
popenCommunicate([self.openssl_binary, 'ca', '-batch', '-config',
self.openssl_configuration, '-out', certificate,
'-infiles', csr])
finally:
if os.path.exists(csr):
os.unlink(csr)
except:
try:
for f in file_list:
if os.path.exists(f):
os.unlink(f)
except:
# do not raise during cleanup
pass
raise
else:
return True
def checkRequestDir(self):
for request_file in os.listdir(self.request_dir):
parser = ConfigParser.RawConfigParser()
parser.readfp(open(os.path.join(self.request_dir, request_file), 'r'))
if self._checkCertificate(parser.get('certificate', 'name'),
parser.get('certificate', 'key_file'), parser.get('certificate',
'certificate_file')):
print 'Created certificate %r' % parser.get('certificate', 'name')
def runCertificateAuthority(args):
ca_conf = args[0]
ca = CertificateAuthority(ca_conf['key'], ca_conf['certificate'],
ca_conf['openssl_binary'], ca_conf['openssl_configuration'],
ca_conf['request_dir'])
while True:
ca.checkAuthority()
ca.checkRequestDir()
time.sleep(60)
#!/bin/sh
exec %(memcached_binary)s -p %(memcached_port)s -U %(memcached_port)s -l %(memcached_ip)s
#
# OpenSSL example configuration file.
# This is mostly being used for generation of certificate requests.
#
# This definition stops the following lines choking if HOME isn't
# defined.
HOME = .
RANDFILE = $ENV::HOME/.rnd
# Extra OBJECT IDENTIFIER info:
#oid_file = $ENV::HOME/.oid
oid_section = new_oids
# To use this configuration file with the "-extfile" option of the
# "openssl x509" utility, name here the section containing the
# X.509v3 extensions to use:
# extensions =
# (Alternatively, use a configuration file that has only
# X.509v3 extensions in its main [= default] section.)
[ new_oids ]
# We can add new OIDs in here for use by 'ca', 'req' and 'ts'.
# Add a simple OID like this:
# testoid1=1.2.3.4
# Or use config file substitution like this:
# testoid2=${testoid1}.5.6
# Policies used by the TSA examples.
tsa_policy1 = 1.2.3.4.1
tsa_policy2 = 1.2.3.4.5.6
tsa_policy3 = 1.2.3.4.5.7
####################################################################
[ ca ]
default_ca = CA_default # The default ca section
####################################################################
[ CA_default ]
dir = %(working_directory)s # Where everything is kept
certs = $dir/certs # Where the issued certs are kept
crl_dir = $dir/crl # Where the issued crl are kept
database = $dir/index.txt # database index file.
#unique_subject = no # Set to 'no' to allow creation of
# several ctificates with same subject.
new_certs_dir = $dir/newcerts # default place for new certs.
certificate = $dir/cacert.pem # The CA certificate
serial = $dir/serial # The current serial number
crlnumber = $dir/crlnumber # the current crl number
# must be commented out to leave a V1 CRL
crl = $dir/crl.pem # The current CRL
private_key = $dir/private/cakey.pem # The private key
RANDFILE = $dir/private/.rand # private random number file
x509_extensions = usr_cert # The extentions to add to the cert
# Comment out the following two lines for the "traditional"
# (and highly broken) format.
name_opt = ca_default # Subject Name options
cert_opt = ca_default # Certificate field options
# Extension copying option: use with caution.
# copy_extensions = copy
# Extensions to add to a CRL. Note: Netscape communicator chokes on V2 CRLs
# so this is commented out by default to leave a V1 CRL.
# crlnumber must also be commented out to leave a V1 CRL.
# crl_extensions = crl_ext
default_days = 3650 # how long to certify for
default_crl_days= 30 # how long before next CRL
default_md = default # use public key default MD
preserve = no # keep passed DN ordering
# A few difference way of specifying how similar the request should look
# For type CA, the listed attributes must be the same, and the optional
# and supplied fields are just that :-)
policy = policy_match
# For the CA policy
[ policy_match ]
countryName = match
stateOrProvinceName = match
organizationName = match
organizationalUnitName = optional
commonName = supplied
emailAddress = optional
# For the 'anything' policy
# At this point in time, you must list all acceptable 'object'
# types.
[ policy_anything ]
countryName = optional
stateOrProvinceName = optional
localityName = optional
organizationName = optional
organizationalUnitName = optional
commonName = supplied
emailAddress = optional
####################################################################
[ req ]
default_bits = 2048
default_md = sha1
default_keyfile = privkey.pem
distinguished_name = req_distinguished_name
#attributes = req_attributes
x509_extensions = v3_ca # The extentions to add to the self signed cert
# Passwords for private keys if not present they will be prompted for
# input_password = secret
# output_password = secret
# This sets a mask for permitted string types. There are several options.
# default: PrintableString, T61String, BMPString.
# pkix : PrintableString, BMPString (PKIX recommendation before 2004)
# utf8only: only UTF8Strings (PKIX recommendation after 2004).
# nombstr : PrintableString, T61String (no BMPStrings or UTF8Strings).
# MASK:XXXX a literal mask value.
# WARNING: ancient versions of Netscape crash on BMPStrings or UTF8Strings.
string_mask = utf8only
# req_extensions = v3_req # The extensions to add to a certificate request
[ req_distinguished_name ]
countryName = Country Name (2 letter code)
countryName_value = %(country_code)s
countryName_min = 2
countryName_max = 2
stateOrProvinceName = State or Province Name (full name)
stateOrProvinceName_value = %(state)s
localityName = Locality Name (eg, city)
localityName_value = %(city)s
0.organizationName = Organization Name (eg, company)
0.organizationName_value = %(company)s
# we can do this but it is not needed normally :-)
#1.organizationName = Second Organization Name (eg, company)
#1.organizationName_default = World Wide Web Pty Ltd
commonName = Common Name (eg, your name or your server\'s hostname)
commonName_max = 64
emailAddress = Email Address
emailAddress_value = %(email_address)s
emailAddress_max = 64
# SET-ex3 = SET extension number 3
#[ req_attributes ]
#challengePassword = A challenge password
#challengePassword_min = 4
#challengePassword_max = 20
#
#unstructuredName = An optional company name
[ usr_cert ]
# These extensions are added when 'ca' signs a request.
# This goes against PKIX guidelines but some CAs do it and some software
# requires this to avoid interpreting an end user certificate as a CA.
basicConstraints=CA:FALSE
# Here are some examples of the usage of nsCertType. If it is omitted
# the certificate can be used for anything *except* object signing.
# This is OK for an SSL server.
# nsCertType = server
# For an object signing certificate this would be used.
# nsCertType = objsign
# For normal client use this is typical
# nsCertType = client, email
# and for everything including object signing:
# nsCertType = client, email, objsign
# This is typical in keyUsage for a client certificate.
# keyUsage = nonRepudiation, digitalSignature, keyEncipherment
# This will be displayed in Netscape's comment listbox.
nsComment = "OpenSSL Generated Certificate"
# PKIX recommendations harmless if included in all certificates.
subjectKeyIdentifier=hash
authorityKeyIdentifier=keyid,issuer
# This stuff is for subjectAltName and issuerAltname.
# Import the email address.
# subjectAltName=email:copy
# An alternative to produce certificates that aren't
# deprecated according to PKIX.
# subjectAltName=email:move
# Copy subject details
# issuerAltName=issuer:copy
#nsCaRevocationUrl = http://www.domain.dom/ca-crl.pem
#nsBaseUrl
#nsRevocationUrl
#nsRenewalUrl
#nsCaPolicyUrl
#nsSslServerName
# This is required for TSA certificates.
# extendedKeyUsage = critical,timeStamping
[ v3_req ]
# Extensions to add to a certificate request
basicConstraints = CA:FALSE
keyUsage = nonRepudiation, digitalSignature, keyEncipherment
[ v3_ca ]
# Extensions for a typical CA
# PKIX recommendation.
subjectKeyIdentifier=hash
authorityKeyIdentifier=keyid:always,issuer
# This is what PKIX recommends but some broken software chokes on critical
# extensions.
#basicConstraints = critical,CA:true
# So we do this instead.
basicConstraints = CA:true
# Key usage: this is typical for a CA certificate. However since it will
# prevent it being used as an test self-signed certificate it is best
# left out by default.
# keyUsage = cRLSign, keyCertSign
# Some might want this also
# nsCertType = sslCA, emailCA
# Include email address in subject alt name: another PKIX recommendation
# subjectAltName=email:copy
# Copy issuer details
# issuerAltName=issuer:copy
# DER hex encoding of an extension: beware experts only!
# obj=DER:02:03
# Where 'obj' is a standard or added object
# You can even override a supported extension:
# basicConstraints= critical, DER:30:03:01:01:FF
[ crl_ext ]
# CRL extensions.
# Only issuerAltName and authorityKeyIdentifier make any sense in a CRL.
# issuerAltName=issuer:copy
authorityKeyIdentifier=keyid:always
[ proxy_cert_ext ]
# These extensions should be added when creating a proxy certificate
# This goes against PKIX guidelines but some CAs do it and some software
# requires this to avoid interpreting an end user certificate as a CA.
basicConstraints=CA:FALSE
# Here are some examples of the usage of nsCertType. If it is omitted
# the certificate can be used for anything *except* object signing.
# This is OK for an SSL server.
# nsCertType = server
# For an object signing certificate this would be used.
# nsCertType = objsign
# For normal client use this is typical
# nsCertType = client, email
# and for everything including object signing:
# nsCertType = client, email, objsign
# This is typical in keyUsage for a client certificate.
# keyUsage = nonRepudiation, digitalSignature, keyEncipherment
# This will be displayed in Netscape's comment listbox.
nsComment = "OpenSSL Generated Certificate"
# PKIX recommendations harmless if included in all certificates.
subjectKeyIdentifier=hash
authorityKeyIdentifier=keyid,issuer
# This stuff is for subjectAltName and issuerAltname.
# Import the email address.
# subjectAltName=email:copy
# An alternative to produce certificates that aren't
# deprecated according to PKIX.
# subjectAltName=email:move
# Copy subject details
# issuerAltName=issuer:copy
#nsCaRevocationUrl = http://www.domain.dom/ca-crl.pem
#nsBaseUrl
#nsRevocationUrl
#nsRenewalUrl
#nsCaPolicyUrl
#nsSslServerName
# This really needs to be in place for it to be a proxy certificate.
proxyCertInfo=critical,language:id-ppl-anyLanguage,pathlen:3,policy:foo
####################################################################
[ tsa ]
default_tsa = tsa_config1 # the default TSA section
[ tsa_config1 ]
# These are used by the TSA reply generation only.
dir = /etc/pki/tls # TSA root directory
serial = $dir/tsaserial # The current serial number (mandatory)
crypto_device = builtin # OpenSSL engine to use for signing
signer_cert = $dir/tsacert.pem # The TSA signing certificate
# (optional)
certs = $dir/cacert.pem # Certificate chain to include in reply
# (optional)
signer_key = $dir/private/tsakey.pem # The TSA private key (optional)
default_policy = tsa_policy1 # Policy if request did not specify it
# (optional)
other_policies = tsa_policy2, tsa_policy3 # acceptable policies (optional)
digests = md5, sha1 # Acceptable message digests (mandatory)
accuracy = secs:1, millisecs:500, microsecs:100 # (optional)
clock_precision_digits = 0 # number of digits after dot. (optional)
ordering = yes # Is ordering defined for timestamps?
# (optional, default: no)
tsa_name = yes # Must the TSA name be included in the reply?
# (optional, default: no)
ess_cert_id_chain = no # Must the ESS cert id chain be included?
# (optional, default: no)
foreground = yes
output = %(log)s
pid = %(pid_file)s
syslog = no
CApath = %(ca_path)s
key = %(key)s
CRLpath = %(ca_crl)s
cert = %(cert)s
[service]
accept = %(public_ip)s:%(public_port)s
connect = %(private_ip)s:%(private_port)s
##############################################################################
#
# 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 collective.recipe.template
import zc.buildout
class Recipe(collective.recipe.template.Recipe):
def __init__(self, buildout, name, options):
download = zc.buildout.download.Download(buildout['buildout'],
hash_name=True)
path, is_temp = download(options.pop('url'),
md5sum=options.get('md5sum'))
options['input'] = path
collective.recipe.template.Recipe.__init__(self, buildout, name, options)
##############################################################################
#
# Copyright (c) 2011 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.
#
##############################################################################
from slapos.recipe.librecipe import BaseSlapRecipe
import binascii
import os
import pkg_resources
import pprint
import hashlib
import sys
import zc.buildout
import zc.recipe.egg
import ConfigParser
class Recipe(BaseSlapRecipe):
def installLogrotate(self):
"""Installs logortate main configuration file and registers its to cron"""
logrotate_d = os.path.abspath(os.path.join(self.etc_directory,
'logrotate.d'))
self._createDirectory(logrotate_d)
logrotate_backup = self.createBackupDirectory('logrotate')
logrotate_conf = self.createConfigurationFile("logrotate.conf",
"include %s" % logrotate_d)
logrotate_cron = os.path.join(self.cron_d, 'logrotate')
state_file = os.path.join(self.data_root_directory, 'logrotate.status')
open(logrotate_cron, 'w').write('0 0 * * * %s -s %s %s' %
(self.options['logrotate_binary'], state_file, logrotate_conf))
self.path_list.extend([logrotate_d, logrotate_conf, logrotate_cron])
return logrotate_d, logrotate_backup
def registerLogRotation(self, name, log_file_list):
"""Register new log rotation requirement"""
open(os.path.join(self.logrotate_d, name), 'w').write(
pkg_resources.resource_string(__name__, 'template/logrotate_entry.in')%
dict(file_list=' '.join(['"'+q+'"' for q in log_file_list]),
olddir=self.logrotate_backup))
def installCrond(self):
timestamps = self.createDataDirectory('cronstamps')
cron_output = os.path.join(self.log_directory, 'cron-output')
self._createDirectory(cron_output)
catcher = zc.buildout.easy_install.scripts([('catchcron',
__name__ + '.catdatefile', 'catdatefile')], self.ws, sys.executable,
self.bin_directory, arguments=[cron_output])[0]
self.path_list.append(catcher)
cron_d = os.path.join(self.etc_directory, 'cron.d')
crontabs = os.path.join(self.etc_directory, 'crontabs')
self._createDirectory(cron_d)
self._createDirectory(crontabs)
wrapper = zc.buildout.easy_install.scripts([('crond',
'slapos.recipe.librecipe.execute', 'execute')], self.ws, sys.executable,
self.wrapper_directory, arguments=[
self.options['dcrond_binary'].strip(), '-s', cron_d, '-c', crontabs,
'-t', timestamps, '-f', '-l', '5', '-M', catcher]
)[0]
self.path_list.append(wrapper)
return cron_d
def _install(self):
self.path_list = []
self.requirements, self.ws = self.egg.working_set()
# self.cron_d is a directory, where cron jobs can be registered
self.cron_d = self.installCrond()
self.logrotate_d, self.logrotate_backup = self.installLogrotate()
zabbix_log_file = os.path.join(self.log_directory, 'zabbix_agentd.log')
self.registerLogRotation('zabbix_agentd', [zabbix_log_file])
zabbix_agentd = dict(
pid_file=os.path.join(self.run_directory, "zabbix_agentd.pid"),
log_file=zabbix_log_file,
ip=self.getGlobalIPv6Address(),
server=self.parameter_dict['server'],
hostname=self.parameter_dict['hostname'],
port='10050'
)
zabbix_agentd_conf = self.createConfigurationFile("zabbix_agentd.conf",
pkg_resources.resource_string(__name__,
'template/zabbix_agentd.conf.in') % zabbix_agentd)
self.path_list.append(zabbix_agentd_conf)
wrapper = zc.buildout.easy_install.scripts([('zabbixagentd',
'slapos.recipe.librecipe.execute', 'execute')], self.ws, sys.executable,
self.bin_directory, arguments=[
self.options['zabbix_agentd_binary'].strip(), '-c',
zabbix_agentd_conf])[0]
self.path_list.extend(zc.buildout.easy_install.scripts([
('zabbixagentd', __name__ + '.svcdaemon', 'svcdaemon')],
self.ws, sys.executable, self.wrapper_directory, arguments=[dict(
real_binary=wrapper, pid_file=zabbix_agentd['pid_file'])]))
self.setConnectionDict(dict(ip=zabbix_agentd['ip'],
name=zabbix_agentd['hostname'], port=zabbix_agentd['port']))
return self.path_list
import os
import sys
import time
def catdatefile(args):
directory = args[0]
try:
suffix = args[1]
except IndexError:
suffix = '.log'
f = open(os.path.join(directory,
time.strftime('%Y-%m-%d.%H:%M.%s') + suffix), 'aw')
for line in sys.stdin.read():
f.write(line)
f.close()
import os
import subprocess
import time
import signal
import sys
def get_pid(filename):
pid = None
if os.path.exists(filename):
data = open(pid_file).read()
try:
pid = int(data)
except ValueError:
pass
return pid
pid_file = None
def sig_handler(s, frame):
print "Killing on signal %s:" % s,
global pid_file
if pid_file is not None:
pid = get_pid(pid_file)
if pid is not None:
os.kill(pid, signal.SIGTERM)
try:
os.kill(pid, 0)
except Exception:
pass
else:
time.sleep(5)
try:
os.kill(pid, 0)
except Exception:
pass
else:
print 'with SIGKILL...',
os.kill(pid, signal.SIGKILL)
else:
raise ValueError('Pid is none.')
print 'done.'
sys.exit(0)
signal.signal(signal.SIGINT, sig_handler)
signal.signal(signal.SIGQUIT, sig_handler)
signal.signal(signal.SIGTERM, sig_handler)
def svcdaemon(args):
"""Utility script to run daemons in supervisord"""
real_binary = args[0]['real_binary']
global pid_file
pid_file = args[0]['pid_file']
subprocess.check_call(real_binary)
print 'Started %r' % real_binary
while True:
time.sleep(5)
pid = get_pid(pid_file)
if pid is None:
raise ValueError('Pid is none')
os.kill(pid, 0)
%(file_list)s {
daily
dateext
rotate 30
compress
notifempty
sharedscripts
create
olddir %(olddir)s
}
# This is a config file for Zabbix Agent (Unix)
# To get more information about Zabbix, visit http://www.zabbix.com
############ GENERAL PARAMETERS #################
### Option: PidFile
# Name of PID file.
#
# Mandatory: no
# Default:
# PidFile=/tmp/zabbix_agentd.pid
PidFile=%(pid_file)s
### Option: LogFile
# Name of log file.
# If not set, syslog is used.
#
# Mandatory: no
# Default:
# LogFile=
LogFile=%(log_file)s
### Option: LogFileSize
# Maximum size of log file in MB.
# 0 - disable automatic log rotation.
#
# Mandatory: no
# Range: 0-1024
# Default:
# LogFileSize=1
LogFileSize=0
### Option: DebugLevel
# Specifies debug level
# 0 - no debug
# 1 - critical information
# 2 - error information
# 3 - warnings
# 4 - for debugging (produces lots of information)
#
# Mandatory: no
# Range: 0-4
# Default:
# DebugLevel=3
### Option: SourceIP
# Source IP address for outgoing connections.
#
# Mandatory: no
# Default:
# SourceIP=
SourceIP=%(ip)s
### Option: EnableRemoteCommands
# Whether remote commands from Zabbix server are allowed.
# 0 - not allowed
# 1 - allowed
#
# Mandatory: no
# Default:
# EnableRemoteCommands=0
### Option: LogRemoteCommands
# Enable logging of executed shell commands as warnings.
# 0 - disabled
# 1 - enabled
#
# Mandatory: no
# Default:
# LogRemoteCommands=0
##### Passive checks related
### Option: Server
# List of comma delimited IP addresses (or hostnames) of Zabbix servers.
# No spaces allowed. First entry is used for receiving list of and sending active checks.
# If IPv6 support is enabled then '127.0.0.1', '::127.0.0.1', '::ffff:127.0.0.1' are treated equally.
#
# Mandatory: yes
# Default:
# Server=
Server=%(server)s
### Option: Hostname
# Unique, case sensitive hostname.
# Required for active checks and must match hostname as configured on the server.
# System hostname is used if undefined.
#
# Default:
# Hostname=system.hostname
Hostname=%(hostname)s
### Option: ListenPort
# Agent will listen on this port for connections from the server.
#
# Mandatory: no
# Range: 1024-32767
# Default:
# ListenPort=10050
ListenPort=%(port)s
### Option: ListenIP
# List of comma delimited IP addresses that the agent should listen on.
#
# Mandatory: no
# Default:
# ListenIP=0.0.0.0
ListenIP=%(ip)s
### Option: DisablePassive
# Disable passive checks. The agent will not listen on any TCP port.
# Only active checks will be processed.
# 0 - do not disable
# 1 - disable
#
# Mandatory: no
# Default:
# DisablePassive=0
##### Active checks related
### Option: DisableActive
# Disable active checks. The agent will work in passive mode listening for server.
#
# Mandatory: no
# Default:
# DisableActive=0
### Option: ServerPort
# Server port for retrieving list of and sending active checks.
#
# Mandatory: no
# Default:
# ServerPort=10051
### Option: RefreshActiveChecks
# How often list of active checks is refreshed, in seconds.
#
# Mandatory: no
# Range: 60-3600
# Default:
# RefreshActiveChecks=120
### Option: BufferSend
# Do not keep data longer than N seconds in buffer.
#
# Mandatory: no
# Range: 1-3600
# Default:
# BufferSend=5
### Option: BufferSize
# Maximum number of values in a memory buffer. The agent will send
# all collected data to Zabbix Server or Proxy if the buffer is full.
#
# Mandatory: no
# Range: 2-65535
# Default:
# BufferSize=100
### Option: MaxLinesPerSecond
# Maximum number of new lines the agent will send per second to Zabbix Server
# or Proxy processing 'log' and 'logrt' active checks.
# The provided value will be overridden by the parameter 'maxlines',
# provided in 'log' or 'logrt' item keys.
#
# Mandatory: no
# Range: 1-1000
# Default:
# MaxLinesPerSecond=100
### Option: AllowRoot
# Allow the agent to run as 'root'. If disabled and the agent is started by 'root', the agent
# will try to switch to user 'zabbix' instead. Has no effect if started under a regular user.
# 0 - do not allow
# 1 - allow
#
# Mandatory: no
# Default:
# AllowRoot=0
############ ADVANCED PARAMETERS #################
### Option: StartAgents
# Number of pre-forked instances of zabbix_agentd that process passive checks.
#
# Mandatory: no
# Range: 1-100
# Default:
# StartAgents=3
### Option: Timeout
# Spend no more than Timeout seconds on processing
#
# Mandatory: no
# Range: 1-30
# Default:
# Timeout=3
### Option: Include
# You may include individual files or all files in a directory in the configuration file.
#
# Mandatory: no
# Default:
# Include=
# Include=/etc/zabbix/zabbix_agentd.userparams.conf
# Include=/etc/zabbix/zabbix_agentd/
####### USER-DEFINED MONITORED PARAMETERS #######
### Option: UnsafeUserParameters
# Allow all characters to be passed in arguments to user-defined parameters.
# 0 - do not allow
# 1 - allow
#
# Mandatory: no
# Range: 0-1
# Default:
# UnsafeUserParameters=0
### Option: UserParameter
# User-defined parameter to monitor. There can be several user-defined parameters.
# Format: UserParameter=<key>,<shell command>
# Note that shell command must not return empty string or EOL only.
# See 'zabbix_agentd' directory for examples.
#
# Mandatory: no
# Default:
# UserParameter=
...@@ -10,6 +10,7 @@ find-links = http://www.nexedi.org/static/packages/source/slapos.buildout/ ...@@ -10,6 +10,7 @@ find-links = http://www.nexedi.org/static/packages/source/slapos.buildout/
versions = versions versions = versions
rebootstrap-section = python2.6 rebootstrap-section = python2.6
extends = extends =
../../component/python-2.6/buildout.cfg ../../component/python-2.6/buildout.cfg
../../component/subversion/buildout.cfg ../../component/subversion/buildout.cfg
...@@ -37,10 +38,6 @@ arguments = sys.argv[1:] + ["bootstrap"] ...@@ -37,10 +38,6 @@ arguments = sys.argv[1:] + ["bootstrap"]
section = python2.6 section = python2.6
version = 1 version = 1
[versions]
# Use SlapOS patched zc.buildout
zc.buildout = 1.5.3-dev-SlapOS-001
[eggs] [eggs]
recipe = zc.recipe.egg recipe = zc.recipe.egg
eggs = eggs =
...@@ -53,3 +50,429 @@ recipe = slapos.recipe.template ...@@ -53,3 +50,429 @@ recipe = slapos.recipe.template
url = ${:_profile_base_location_}/instance.cfg url = ${:_profile_base_location_}/instance.cfg
output = ${buildout:directory}/template.cfg output = ${buildout:directory}/template.cfg
mode = 0644 mode = 0644
[versions]
# Use SlapOS patched zc.buildout
zc.buildout = 1.5.3-dev-SlapOS-002
[versions]
AccessControl = 2.13.4
Jinja2 = 2.5.5
Products.OFSP = 2.13.2
Werkzeug = 0.6.2
hexagonit.recipe.cmmi = 1.5.0
lxml = 2.3
manuel = 1.5.0
mechanize = 0.2.5
meld3 = 0.6.7
mr.developer = 1.17
slapos.cookbook = 0.4
slapos.core = 0.2
slapos.recipe.template = 1.1
zope.i18n = 3.7.4
zope.tales = 3.5.1
#Required by:
#Products.ExternalMethod 2.13.0
#Products.PythonScripts 2.13.0
#DocumentTemplate 2.13.1
#Products.ZCTextIndex 2.13.2
#Products.BTreeFolder2 2.13.3
#Zope2 2.13.7
#Products.ZCatalog 2.13.14
Acquisition = 2.13.7nxd001
#Required by:
#Products.PythonScripts 2.13.0
#Zope2 2.13.7
#Products.ZCatalog 2.13.14
DateTime = 3.0b1
#Required by:
#Products.MIMETools 2.13.0
#Products.PythonScripts 2.13.0
#Zope2 2.13.7
#Products.ZCatalog 2.13.14
DocumentTemplate = 2.13.1
#Required by:
#MultiMapping 2.13.0
#Products.ExternalMethod 2.13.0
#Record 2.13.0
#Missing 2.13.1
#Persistence 2.13.2
#Zope2 2.13.7
#Products.ZCatalog 2.13.14
ExtensionClass = 2.13.2
#Required by:
#slapos.core 0.2
Flask = 0.6.1
#Required by:
#Zope2 2.13.7
#Products.ZCatalog 2.13.14
Missing = 2.13.1
#Required by:
#Zope2 2.13.7
MultiMapping = 2.13.0
#Required by:
#Products.ExternalMethod 2.13.0
#Products.OFSP 2.13.2
#Products.ZCTextIndex 2.13.2
#Products.BTreeFolder2 2.13.3
#Zope2 2.13.7
#Products.ZCatalog 2.13.14
Persistence = 2.13.2
#Required by:
#Zope2 2.13.7
Products.BTreeFolder2 = 2.13.3
#Required by:
#Zope2 2.13.7
Products.ExternalMethod = 2.13.0
#Required by:
#Zope2 2.13.7
Products.MIMETools = 2.13.0
#Required by:
#Zope2 2.13.7
Products.MailHost = 2.13.1
#Required by:
#Zope2 2.13.7
Products.PythonScripts = 2.13.0
#Required by:
#Zope2 2.13.7
Products.StandardCacheManagers = 2.13.0
#Required by:
#Zope2 2.13.7
Products.ZCTextIndex = 2.13.2
#Required by:
#Zope2 2.13.7
Products.ZCatalog = 2.13.14
#Required by:
#slapos.cookbook 0.4
PyXML = 0.8.5
#Required by:
#Zope2 2.13.7
Record = 2.13.0
#Required by:
#Products.PythonScripts 2.13.0
#Zope2 2.13.7
RestrictedPython = 3.6.0
#Required by:
#zdaemon 2.0.4
#zLOG 2.11.1
#Zope2 2.13.7
#ZODB3 3.10.3
ZConfig = 2.9.0
#Required by:
#Products.ExternalMethod 2.13.0
#Products.BTreeFolder2 2.13.3
#Zope2 2.13.7
#zope.container 3.12.0
ZODB3 = 3.10.3
#Required by:
#slapos.cookbook 0.4
Zope2 = 2.13.7
#Required by:
#Zope2 2.13.7
ZopeUndo = 2.12.0
#Required by:
#mr.developer 1.17
#slapos.core 0.2
argparse = 1.2.1
#Required by:
#slapos.recipe.template 1.1
collective.recipe.template = 1.8
#Required by:
#Zope2 2.13.7
docutils = 0.7
#Required by:
#hexagonit.recipe.cmmi 1.5.0
hexagonit.recipe.download = 1.5.0
#Required by:
#Zope2 2.13.7
initgroups = 2.13.0
#Required by:
#slapos.core 0.2
#slapos.cookbook 0.4
netaddr = 0.7.5
#Required by:
#slapos.core 0.2
netifaces = 0.5
#Required by:
#Zope2 2.13.7
#zope.i18n 3.7.4
#zope.testbrowser 4.0.2
pytz = 2011g
#Required by:
#zc.buildout 1.5.3-dev-SlapOS-001
setuptools = 0.6c12dev-r88846
#Required by:
#slapos.core 0.2
supervisor = 3.0a10
#Required by:
#Zope2 2.13.7
tempstorage = 2.12.1
#Required by:
#Products.StandardCacheManagers 2.13.0
#Zope2 2.13.7
#zope.sendmail 3.7.4
transaction = 1.1.1
#Required by:
#slapos.cookbook 0.4
xml-marshaller = 0.9.7
#Required by:
#Products.PythonScripts 2.13.0
#Zope2 2.13.7
zExceptions = 2.13.0
#Required by:
#Zope2 2.13.7
zLOG = 2.11.1
#Required by:
#ZODB3 3.10.3
zc.lockfile = 1.0.0
#Required by:
#slapos.cookbook 0.4
zc.recipe.egg = 1.3.2
#Required by:
#Zope2 2.13.7
zdaemon = 2.0.4
#Required by:
#zope.site 3.9.2
zope.annotation = 3.5.0
#Required by:
#zope.container 3.12.0
zope.broken = 3.6.0
#Required by:
#Zope2 2.13.7
#zope.browsermenu 3.9.1
#zope.publisher 3.12.6
zope.browser = 1.3
#Required by:
#Zope2 2.13.7
zope.browsermenu = 3.9.1
#Required by:
#Zope2 2.13.7
zope.browserpage = 3.12.2
#Required by:
#Zope2 2.13.7
#zope.ptresource 3.9.0
zope.browserresource = 3.12.0
#Required by:
#Products.StandardCacheManagers 2.13.0
#Zope2 2.13.7
#zope.pagetemplate 3.5.2
#zope.lifecycleevent 3.7.0
#zope.contentprovider 3.7.2
#zope.viewlet 3.7.2
#zope.i18n 3.7.4
#zope.security 3.8.2
#zope.container 3.12.0
#zope.publisher 3.12.6
#zope.traversing 3.14.0
zope.component = 3.10.0
#Required by:
#Zope2 2.13.7
#zope.viewlet 3.7.2
#zope.sendmail 3.7.4
#zope.publisher 3.12.6
zope.configuration = 3.7.4
#Required by:
#Products.BTreeFolder2 2.13.3
#Zope2 2.13.7
#zope.site 3.9.2
zope.container = 3.12.0
#Required by:
#Zope2 2.13.7
#zope.viewlet 3.7.2
zope.contentprovider = 3.7.2
#Required by:
#Zope2 2.13.7
zope.contenttype = 3.5.3
#Required by:
#Zope2 2.13.7
zope.deferredimport = 3.5.3
#Required by:
#Products.ZCatalog 2.13.14
#zope.container 3.12.0
zope.dottedname = 3.4.6
#Required by:
#Products.BTreeFolder2 2.13.3
#Zope2 2.13.7
#zope.lifecycleevent 3.7.0
#zope.viewlet 3.7.2
#zope.schema 3.8.0
#zope.site 3.9.2
#zope.publisher 3.12.6
zope.event = 3.5.0-1
#Required by:
#Zope2 2.13.7
#zope.testing 3.10.2
#zope.publisher 3.12.6
zope.exceptions = 3.6.1
#Required by:
#zope.container 3.12.0
zope.filerepresentation = 3.6.0
#Required by:
#Zope2 2.13.7
#zope.size 3.4.1
#zope.pagetemplate 3.5.2
#zope.tal 3.5.2
#zope.viewlet 3.7.2
#zope.sendmail 3.7.4
#zope.security 3.8.2
#zope.traversing 3.14.0
zope.i18nmessageid = 3.5.3
#Required by:
#slapos.core 0.2
#Zope2 2.13.7
zope.interface = 3.6.3
#Required by:
#Products.BTreeFolder2 2.13.3
#Zope2 2.13.7
#zope.site 3.9.2
zope.lifecycleevent = 3.7.0
#Required by:
#Zope2 2.13.7
#zope.viewlet 3.7.2
#zope.security 3.8.2
#zope.publisher 3.12.6
zope.location = 3.9.0
#Required by:
#Zope2 2.13.7
#zope.ptresource 3.9.0
zope.pagetemplate = 3.5.2
#Required by:
#Zope2 2.13.7
zope.processlifetime = 1.0
#Required by:
#Zope2 2.13.7
#zope.publisher 3.12.6
#zope.traversing 3.14.0
zope.proxy = 3.6.1
#Required by:
#Zope2 2.13.7
zope.ptresource = 3.9.0
#Required by:
#Zope2 2.13.7
#zope.viewlet 3.7.2
#zope.traversing 3.14.0
zope.publisher = 3.12.6
#Required by:
#Zope2 2.13.7
#zope.viewlet 3.7.2
#zope.sendmail 3.7.4
#zope.security 3.8.2
#zope.testbrowser 4.0.2
zope.schema = 3.8.0
#Required by:
#Zope2 2.13.7
#zope.viewlet 3.7.2
#zope.site 3.9.2
#zope.traversing 3.14.0
zope.security = 3.8.2
#Required by:
#Zope2 2.13.7
zope.sendmail = 3.7.4
#Required by:
#Zope2 2.13.7
zope.sequencesort = 3.4.0
#Required by:
#Zope2 2.13.7
zope.site = 3.9.2
#Required by:
#Zope2 2.13.7
zope.size = 3.4.1
#Required by:
#Zope2 2.13.7
zope.structuredtext = 3.5.1
#Required by:
#Zope2 2.13.7
#zope.tales 3.5.1
zope.tal = 3.5.2
#Required by:
#Zope2 2.13.7
zope.testbrowser = 4.0.2
#Required by:
#Zope2 2.13.7
zope.testing = 3.10.2
#Required by:
#Zope2 2.13.7
#zope.viewlet 3.7.2
zope.traversing = 3.14.0
#Required by:
#Zope2 2.13.7
zope.viewlet = 3.7.2
[buildout]
parts =
instance
eggs-directory = ${buildout:eggs-directory}
develop-eggs-directory = ${buildout:develop-eggs-directory}
[instance]
recipe = ${instance-recipe:egg}:${instance-recipe:module}
kumo_gateway_binary = ${kumo:location}/bin/kumo-gateway
kumo_manager_binary = ${kumo:location}/bin/kumo-manager
kumo_server_binary = ${kumo:location}/bin/kumo-server
dcrond_binary = ${dcron:location}/sbin/crond
openssl_binary = ${openssl:location}/bin/openssl
rdiff_backup_binary = ${buildout:bin-directory}/rdiff-backup
stunnel_binary = ${stunnel:location}/bin/stunnel
[buildout]
extensions =
slapos.zcbworkarounds
slapos.rebootstrap
find-links +=
http://www.nexedi.org/static/packages/source/slapos.buildout/
extends =
../../component/git/buildout.cfg
../../component/kumo/buildout.cfg
../../component/python-2.7/buildout.cfg
../../component/dcron/buildout.cfg
../../component/stunnel/buildout.cfg
../../component/rdiff-backup/buildout.cfg
../../component/lxml-python/buildout.cfg
versions = versions
parts +=
# Create instance template
#TODO : list here all parts.
template
libxslt
eggs
instance-recipe-egg
# XXX: Workaround of SlapOS limitation
# Unzippig of eggs is required, as SlapOS do not yet provide nicely working
# development / fast switching environment for whole software
unzip = true
[rebootstrap]
# Default first version of rebootstrapped python
version = 2
section = python2.7
[instance-recipe]
egg = slapos.cookbook
module = kumofs
[instance-recipe-egg]
recipe = zc.recipe.egg
python = python2.7
eggs = ${instance-recipe:egg}
[eggs]
recipe = zc.recipe.egg
python = python2.7
eggs =
${lxml-python:egg}
[template]
# Default template for the instance.
recipe = slapos.recipe.template
url = ${:_profile_base_location_}/instance.cfg
md5sum = 056a4af7128fd9e31da42c85cc039420
output = ${buildout:directory}/template.cfg
mode = 0644
[versions]
slapos.cookbook = 0.4
erp5.recipe.cmmiforcei686 = 0.1.1
hexagonit.recipe.cmmi = 1.5.0
hexagonit.recipe.download = 1.5.0
# Required by slapos.cookbook==0.4
slapos.core = 0.2
collective.recipe.template = 1.8
netaddr = 0.7.5
xml-marshaller = 0.9.7
setuptools = 0.6c12dev-r88795
# Use SlapOS patched zc.buildout
zc.buildout = 1.5.3-dev-SlapOS-001
[buildout]
parts =
instance
eggs-directory = ${buildout:eggs-directory}
develop-eggs-directory = ${buildout:develop-eggs-directory}
[instance]
recipe = ${instance-recipe:egg}:${instance-recipe:module}
dcrond_binary = ${dcron:location}/sbin/crond
memcached_binary = ${memcached:location}/bin/memcached
openssl_binary = ${openssl:location}/bin/openssl
rdiff_backup_binary = ${buildout:bin-directory}/rdiff-backup
stunnel_binary = ${stunnel:location}/bin/stunnel
[buildout]
extensions =
slapos.zcbworkarounds
slapos.rebootstrap
find-links +=
http://www.nexedi.org/static/packages/source/slapos.buildout/
extends =
../../component/memcached/buildout.cfg
../../component/python-2.7/buildout.cfg
../../component/dcron/buildout.cfg
../../component/stunnel/buildout.cfg
../../component/rdiff-backup/buildout.cfg
../../component/lxml-python/buildout.cfg
versions = versions
parts =
# Create instance template
#TODO : list here all parts.
template
libxslt
eggs
instance-recipe-egg
# XXX: Workaround of SlapOS limitation
# Unzippig of eggs is required, as SlapOS do not yet provide nicely working
# development / fast switching environment for whole software
unzip = true
[rebootstrap]
# Default first version of rebootstrapped python
version = 2
section = python2.7
[instance-recipe]
egg = slapos.cookbook
module = memcached
[instance-recipe-egg]
recipe = zc.recipe.egg
python = python2.7
eggs = ${instance-recipe:egg}
[eggs]
recipe = zc.recipe.egg
python = python2.7
eggs =
${lxml-python:egg}
[template]
# Default template for the instance.
recipe = slapos.recipe.template
url = ${:_profile_base_location_}/instance.cfg
md5sum = 837caf9897332a5f70c72438f1dc5bae
output = ${buildout:directory}/template.cfg
mode = 0644
[versions]
slapos.cookbook = 0.4
# Required by slapos.cookbook==0.4
slapos.core = 0.2
collective.recipe.template = 1.8
netaddr = 0.7.5
xml-marshaller = 0.9.7
setuptools = 0.6c12dev-r88795
hexagonit.recipe.cmmi = 1.5.0
hexagonit.recipe.download = 1.5.0
plone.recipe.command = 1.1
# Use SlapOS patched zc.buildout
zc.buildout = 1.5.3-dev-SlapOS-001
[buildout]
parts =
instance
eggs-directory = ${buildout:eggs-directory}
develop-eggs-directory = ${buildout:develop-eggs-directory}
[instance]
recipe = slapos.cookbook:zabbixagent
dcrond_binary = ${dcron:location}/sbin/crond
logrotate_binary = ${logrotate:location}/usr/sbin/logrotate
zabbix_agentd_binary = ${zabbix-agent:location}/sbin/zabbix_agentd
[buildout]
extends =
../../component/dcron/buildout.cfg
../../component/logrotate/buildout.cfg
../../component/zabbix/buildout.cfg
../../component/lxml-python/buildout.cfg
find-links = http://www.nexedi.org/static/packages/source/slapos.buildout/
versions = versions
parts =
eggs
template
# Use only quite well working sites.
allow-hosts =
*.nexedi.org
*.python.org
*.sourceforge.net
[eggs]
recipe = zc.recipe.egg
eggs =
${lxml-python:egg}
slapos.cookbook
[template]
# Default template for the instance.
recipe = slapos.recipe.template
url = ${:_profile_base_location_}/instance.cfg
md5sum = 98a680fe8fddce5dcee455e65c228fde
output = ${buildout:directory}/template.cfg
mode = 0644
[versions]
zc.buildout = 1.5.3-dev-SlapOS-001
Jinja2 = 2.5.5
Werkzeug = 0.6.2
buildout-versions = 1.6
hexagonit.recipe.cmmi = 1.5.0
lxml = 2.3
meld3 = 0.6.7
slapos.recipe.template = 1.1
# Required by:
# slapos.core==0.2
Flask = 0.6.1
# Required by:
# slapos.cookbook==0.4
PyXML = 0.8.4
# Required by:
# slapos.recipe.template==1.1
collective.recipe.template = 1.8
# Required by:
# hexagonit.recipe.cmmi==1.5.0
hexagonit.recipe.download = 1.5.0
# Required by:
# slapos.cookbook==0.4
# slapos.core==0.2
netaddr = 0.7.5
# Required by:
# slapos.core==0.2
netifaces = 0.5
# Required by:
# slapos.cookbook==0.4
# slapos.core==0.2
# zc.buildout==1.5.3-dev-SlapOS-001
# zc.recipe.egg==1.3.2
setuptools = 0.6c12dev-r88846
# Required by:
# slapos.cookbook==0.4
slapos.core = 0.2
# Required by:
# slapos.core==0.2
supervisor = 3.0a10
# Required by:
# slapos.cookbook==0.4
xml-marshaller = 0.9.7
# Required by:
# slapos.cookbook==0.4
zc.recipe.egg = 1.3.2
# Required by:
# slapos.core==0.2
zope.interface = 3.6.3
# Added by Buildout Versions at 2011-06-13 10:01:36.219846
Jinja2 = 2.5.5
Werkzeug = 0.6.2
buildout-versions = 1.6
hexagonit.recipe.cmmi = 1.5.0
lxml = 2.3
meld3 = 0.6.7
slapos.recipe.template = 1.1
# Required by:
# slapos.core==0.2
Flask = 0.6.1
# Required by:
# slapos.cookbook==0.4
PyXML = 0.8.4
# Required by:
# slapos.recipe.template==1.1
collective.recipe.template = 1.8
# Required by:
# hexagonit.recipe.cmmi==1.5.0
hexagonit.recipe.download = 1.5.0
# Required by:
# slapos.cookbook==0.4
# slapos.core==0.2
netaddr = 0.7.5
# Required by:
# slapos.core==0.2
netifaces = 0.5
# Required by:
# slapos.cookbook==0.4
# slapos.core==0.2
# zc.buildout==1.5.3-dev-SlapOS-001
# zc.recipe.egg==1.3.2
setuptools = 0.6c12dev-r88846
# Required by:
# slapos.cookbook==0.4
slapos.core = 0.2
# Required by:
# slapos.core==0.2
supervisor = 3.0a10
# Required by:
# slapos.cookbook==0.4
xml-marshaller = 0.9.7
# Required by:
# slapos.cookbook==0.4
zc.recipe.egg = 1.3.2
# Required by:
# slapos.core==0.2
zope.interface = 3.6.3
# Added by Buildout Versions at 2011-06-13 10:15:31.979623
Jinja2 = 2.5.5
Werkzeug = 0.6.2
buildout-versions = 1.6
hexagonit.recipe.cmmi = 1.5.0
lxml = 2.3
meld3 = 0.6.7
slapos.recipe.template = 1.1
# Required by:
# slapos.core==0.2
Flask = 0.6.1
# Required by:
# slapos.cookbook==0.4
PyXML = 0.8.4
# Required by:
# slapos.recipe.template==1.1
collective.recipe.template = 1.8
# Required by:
# hexagonit.recipe.cmmi==1.5.0
hexagonit.recipe.download = 1.5.0
# Required by:
# slapos.cookbook==0.4
# slapos.core==0.2
netaddr = 0.7.3
# Required by:
# slapos.core==0.2
netifaces = 0.5
# Required by:
# slapos.cookbook==0.4
# slapos.core==0.2
# zc.buildout==1.5.3-dev-SlapOS-001
# zc.recipe.egg==1.3.2
setuptools = 0.6c11
# Required by:
# slapos.cookbook==0.4
slapos.core = 0.2
# Required by:
# slapos.core==0.2
supervisor = 3.0a10
# Required by:
# slapos.cookbook==0.4
xml-marshaller = 0.9.7
# Required by:
# slapos.cookbook==0.4
zc.recipe.egg = 1.3.2
# Required by:
# slapos.core==0.2
zope.interface = 3.6.3
# Added by Buildout Versions at 2011-06-13 10:16:55.921352
Jinja2 = 2.5.5
Werkzeug = 0.6.2
buildout-versions = 1.6
hexagonit.recipe.cmmi = 1.5.0
lxml = 2.3
meld3 = 0.6.7
slapos.recipe.template = 1.1
# Required by:
# slapos.core==0.2
Flask = 0.6.1
# Required by:
# slapos.cookbook==0.4
PyXML = 0.8.4
# Required by:
# slapos.recipe.template==1.1
collective.recipe.template = 1.8
# Required by:
# hexagonit.recipe.cmmi==1.5.0
hexagonit.recipe.download = 1.5.0
# Required by:
# slapos.cookbook==0.4
# slapos.core==0.2
netaddr = 0.7.3
# Required by:
# slapos.core==0.2
netifaces = 0.5
# Required by:
# slapos.cookbook==0.4
# slapos.core==0.2
# zc.buildout==1.5.3-dev-SlapOS-001
# zc.recipe.egg==1.3.2
setuptools = 0.6c11
# Required by:
# slapos.cookbook==0.4
slapos.core = 0.2
# Required by:
# slapos.core==0.2
supervisor = 3.0a10
# Required by:
# slapos.cookbook==0.4
xml-marshaller = 0.9.7
# Required by:
# slapos.cookbook==0.4
zc.recipe.egg = 1.3.2
# Required by:
# slapos.core==0.2
zope.interface = 3.6.3
# Added by Buildout Versions at 2011-06-13 10:17:42.100375
Jinja2 = 2.5.5
Werkzeug = 0.6.2
buildout-versions = 1.6
hexagonit.recipe.cmmi = 1.5.0
lxml = 2.3
meld3 = 0.6.7
slapos.recipe.template = 1.1
# Required by:
# slapos.core==0.2
Flask = 0.6.1
# Required by:
# slapos.cookbook==0.4
PyXML = 0.8.4
# Required by:
# slapos.recipe.template==1.1
collective.recipe.template = 1.8
# Required by:
# hexagonit.recipe.cmmi==1.5.0
hexagonit.recipe.download = 1.5.0
# Required by:
# slapos.cookbook==0.4
# slapos.core==0.2
netaddr = 0.7.3
# Required by:
# slapos.core==0.2
netifaces = 0.5
# Required by:
# slapos.cookbook==0.4
# slapos.core==0.2
# zc.buildout==1.5.3-dev-SlapOS-001
# zc.recipe.egg==1.3.2
setuptools = 0.6c11
# Required by:
# slapos.cookbook==0.4
slapos.core = 0.2
# Required by:
# slapos.core==0.2
supervisor = 3.0a10
# Required by:
# slapos.cookbook==0.4
xml-marshaller = 0.9.7
# Required by:
# slapos.cookbook==0.4
zc.recipe.egg = 1.3.2
# Required by:
# slapos.core==0.2
zope.interface = 3.6.3
# Added by Buildout Versions at 2011-06-13 10:19:50.709164
Jinja2 = 2.5.5
Werkzeug = 0.6.2
buildout-versions = 1.6
hexagonit.recipe.cmmi = 1.5.0
lxml = 2.3
meld3 = 0.6.7
slapos.recipe.template = 1.1
# Required by:
# slapos.core==0.2
Flask = 0.6.1
# Required by:
# slapos.cookbook==0.4
PyXML = 0.8.4
# Required by:
# slapos.recipe.template==1.1
collective.recipe.template = 1.8
# Required by:
# hexagonit.recipe.cmmi==1.5.0
hexagonit.recipe.download = 1.5.0
# Required by:
# slapos.cookbook==0.4
# slapos.core==0.2
netaddr = 0.7.3
# Required by:
# slapos.core==0.2
netifaces = 0.5
# Required by:
# slapos.cookbook==0.4
# slapos.core==0.2
# zc.buildout==1.5.3-dev-SlapOS-001
# zc.recipe.egg==1.3.2
setuptools = 0.6c11
# Required by:
# slapos.cookbook==0.4
slapos.core = 0.2
# Required by:
# slapos.core==0.2
supervisor = 3.0a10
# Required by:
# slapos.cookbook==0.4
xml-marshaller = 0.9.7
# Required by:
# slapos.cookbook==0.4
zc.recipe.egg = 1.3.2
# Required by:
# slapos.core==0.2
zope.interface = 3.6.3
# Added by Buildout Versions at 2011-06-13 10:39:36.870559
Jinja2 = 2.5.5
Werkzeug = 0.6.2
buildout-versions = 1.6
hexagonit.recipe.cmmi = 1.5.0
lxml = 2.3
meld3 = 0.6.7
slapos.recipe.template = 1.1
# Required by:
# slapos.core==0.2
Flask = 0.6.1
# Required by:
# slapos.cookbook==0.4
PyXML = 0.8.4
# Required by:
# slapos.recipe.template==1.1
collective.recipe.template = 1.8
# Required by:
# hexagonit.recipe.cmmi==1.5.0
hexagonit.recipe.download = 1.5.0
# Required by:
# slapos.cookbook==0.4
# slapos.core==0.2
netaddr = 0.7.3
# Required by:
# slapos.core==0.2
netifaces = 0.5
# Required by:
# slapos.cookbook==0.4
# slapos.core==0.2
# zc.buildout==1.5.3-dev-SlapOS-001
# zc.recipe.egg==1.3.2
setuptools = 0.6c11
# Required by:
# slapos.cookbook==0.4
slapos.core = 0.2
# Required by:
# slapos.core==0.2
supervisor = 3.0a10
# Required by:
# slapos.cookbook==0.4
xml-marshaller = 0.9.7
# Required by:
# slapos.cookbook==0.4
zc.recipe.egg = 1.3.2
# Required by:
# slapos.core==0.2
zope.interface = 3.6.3
# Added by Buildout Versions at 2011-06-13 10:41:41.115948
Jinja2 = 2.5.5
Werkzeug = 0.6.2
buildout-versions = 1.6
hexagonit.recipe.cmmi = 1.5.0
lxml = 2.3
meld3 = 0.6.7
slapos.cookbook = 0.5
slapos.recipe.template = 1.1
# Required by:
# slapos.core==0.2
Flask = 0.6.1
# Required by:
# slapos.cookbook==0.5
PyXML = 0.8.4
# Required by:
# slapos.recipe.template==1.1
collective.recipe.template = 1.8
# Required by:
# hexagonit.recipe.cmmi==1.5.0
hexagonit.recipe.download = 1.5.0
# Required by:
# slapos.cookbook==0.5
# slapos.core==0.2
netaddr = 0.7.3
# Required by:
# slapos.core==0.2
netifaces = 0.5
# Required by:
# slapos.cookbook==0.5
# slapos.core==0.2
# zc.buildout==1.5.3-dev-SlapOS-001
# zc.recipe.egg==1.3.2
setuptools = 0.6c11
# Required by:
# slapos.cookbook==0.5
slapos.core = 0.2
# Required by:
# slapos.core==0.2
supervisor = 3.0a10
# Required by:
# slapos.cookbook==0.5
xml-marshaller = 0.9.7
# Required by:
# slapos.cookbook==0.5
zc.recipe.egg = 1.3.2
# Required by:
# slapos.core==0.2
zope.interface = 3.6.3
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment