diff --git a/CHANGES.txt b/CHANGES.txt index 136d8998f2e0b137b688eff51f52b777457845a7..aae2c58d3f05860619b92e1ccd46fe9b500e443e 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -1,3 +1,35 @@ +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) ================ diff --git a/component/python-2.6/buildout.cfg b/component/python-2.6/buildout.cfg index b77372774e12b06689cca936b904de310887a422..22a4bd307d0b59de56e6a05cd3fafe6c692063a4 100644 --- a/component/python-2.6/buildout.cfg +++ b/component/python-2.6/buildout.cfg @@ -1,3 +1,4 @@ + [buildout] # XXX: Extends shall not jump out of software extends = @@ -27,12 +28,12 @@ recipe = hexagonit.recipe.cmmi # other settings in this part if we don't set it explicitly here. prefix = ${buildout:parts-directory}/${:_buildout_section_name_} version = 2.6 -package_version = ${:version}.6 +package_version = ${:version}.7 executable = ${:prefix}/bin/python${:version} url = - http://python.org/ftp/python/${:package_version}/Python-${:package_version}.tgz -md5sum = b2f209df270a33315e62c1ffac1937f0 + http://python.org/ftp/python/${:package_version}/Python-${:package_version}.tar.bz2 +md5sum = d40ef58ed88438a870bbeb0ac5d4217b patch-options = -p1 patches = ${python-2.6.6-no_system_inc_dirs.patch:location}/${python-2.6.6-no_system_inc_dirs.patch:filename} diff --git a/component/zabbix/buildout.cfg b/component/zabbix/buildout.cfg index d4dbeb591c44aefeabd6d1b08ba7252b2d731e13..a18f88e7ae552ef39b7ef99ea835198071f5c7e3 100644 --- a/component/zabbix/buildout.cfg +++ b/component/zabbix/buildout.cfg @@ -4,8 +4,8 @@ parts = [zabbix-agent] recipe = hexagonit.recipe.cmmi -url = http://prdownloads.sourceforge.net/zabbix/zabbix-1.8.4.tar.gz?download -md5sum = 969ce09317c98b205bc96157e16f5c8c +url = http://prdownloads.sourceforge.net/zabbix/zabbix-1.8.5.tar.gz?download +md5sum = 58b9253fb0eace1e20b2fe5c1fce32a3 configure-options = --enable-agent --enable-ipv6 diff --git a/setup.py b/setup.py index a3895f5f9a9eb7cf746eb06d197083484810f234..8d49768d188791047f0731d07217177aabc99dc9 100644 --- a/setup.py +++ b/setup.py @@ -2,7 +2,7 @@ from setuptools import setup, find_packages import glob import os -version = '0.2-dev' +version = '0.7-dev' name = 'slapos.cookbook' long_description = open("README.txt").read() + "\n" + \ open("CHANGES.txt").read() + "\n" @@ -27,12 +27,10 @@ setup(name=name, include_package_data=True, install_requires=[ '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 'netaddr', # to manipulate on IP addresses 'setuptools', # namespaces - 'slapos.slap', # uses internally + 'slapos.core', # uses internally # 'slapos.toolbox', # needed for libcloud, cloudmgr, disabled for now 'xml_marshaller', # need to communication with slapgrid 'zc.buildout', # plays with buildout @@ -41,25 +39,25 @@ setup(name=name, zip_safe=True, entry_points={ 'zc.buildout': [ - 'build = slapos.recipe.build:Script', - 'buildcmmi = slapos.recipe.build:Cmmi', 'download = slapos.recipe.download:Recipe', 'erp5 = slapos.recipe.erp5:Recipe', 'erp5testnode = slapos.recipe.erp5testnode:Recipe', 'helloworld = slapos.recipe.helloworld:Recipe', 'java = slapos.recipe.java:Recipe', + 'kumofs = slapos.recipe.kumofs:Recipe', 'kvm = slapos.recipe.kvm:Recipe', 'libcloud = slapos.recipe.libcloud:Recipe', 'libcloudrequest = slapos.recipe.libcloudrequest:Recipe', + 'memcached = slapos.recipe.memcached:Recipe', 'nbdserver = slapos.recipe.nbdserver:Recipe', 'nosqltestbed = slapos.recipe.nosqltestbed:NoSQLTestBed', 'proactive = slapos.recipe.proactive:Recipe', 'sheepdogtestbed = slapos.recipe.sheepdogtestbed:SheepDogTestBed', 'siptester = slapos.recipe.siptester:SipTesterRecipe', 'slaprunner = slapos.recipe.slaprunner:Recipe', - 'template = slapos.recipe.template:Recipe', 'testnode = slapos.recipe.testnode:Recipe', 'vifib = slapos.recipe.vifib:Recipe', 'xwiki = slapos.recipe.xwiki:Recipe', + 'zabbixagent = slapos.recipe.zabbixagent:Recipe', ]}, ) diff --git a/slapos/recipe/README.build.txt b/slapos/recipe/README.build.txt deleted file mode 100644 index 9c33fe2e233667d55e0ec1be4a8c22460f34d09b..0000000000000000000000000000000000000000 --- a/slapos/recipe/README.build.txt +++ /dev/null @@ -1,91 +0,0 @@ -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 diff --git a/slapos/recipe/README.kumofs.txt b/slapos/recipe/README.kumofs.txt new file mode 100644 index 0000000000000000000000000000000000000000..4a611af0b56b5dae1b655dc81af8b11b1d08213e --- /dev/null +++ b/slapos/recipe/README.kumofs.txt @@ -0,0 +1,4 @@ +kumofs +========= + +Instantiates KumoFS instance. diff --git a/slapos/recipe/README.memcached.txt b/slapos/recipe/README.memcached.txt new file mode 100644 index 0000000000000000000000000000000000000000..ed148080001aea29a7b930ecde87a452601d9ff0 --- /dev/null +++ b/slapos/recipe/README.memcached.txt @@ -0,0 +1,4 @@ +memcached +========= + +Instantiates Memcached instance. diff --git a/slapos/recipe/README.template.txt b/slapos/recipe/README.template.txt deleted file mode 100644 index 2539cd862e753e758f875c337bbac1b6f114a188..0000000000000000000000000000000000000000 --- a/slapos/recipe/README.template.txt +++ /dev/null @@ -1,24 +0,0 @@ -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. diff --git a/slapos/recipe/README.zabbixagent.txt b/slapos/recipe/README.zabbixagent.txt new file mode 100644 index 0000000000000000000000000000000000000000..640198e6c9c246de039e232eb624ad38e54c9464 --- /dev/null +++ b/slapos/recipe/README.zabbixagent.txt @@ -0,0 +1,2 @@ +zabbixagent +=========== diff --git a/slapos/recipe/build.py b/slapos/recipe/build.py deleted file mode 100644 index dbda7d8bab1d8c67e0517e911440594f1db3e986..0000000000000000000000000000000000000000 --- a/slapos/recipe/build.py +++ /dev/null @@ -1,240 +0,0 @@ -############################################################################## -# -# 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) diff --git a/slapos/recipe/cloudooo/__init__.py b/slapos/recipe/cloudooo/__init__.py index 96cc8b720089d0c152d966b1716ac4898ab885a6..df8ec564ed7cdfa648dd32ac5d5c7b14642795e0 100644 --- a/slapos/recipe/cloudooo/__init__.py +++ b/slapos/recipe/cloudooo/__init__.py @@ -102,7 +102,7 @@ class Recipe(BaseSlapRecipe): self.path_list.append(config_file) # Use execute from erp5. 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, sys.executable, self.wrapper_directory, arguments=[self.options['ooo_paster'].strip(), 'serve', config_file])) diff --git a/slapos/recipe/erp5/__init__.py b/slapos/recipe/erp5/__init__.py index cffe579b44850bf34ce44e1efd21bb7da21eec7d..a3e212e4b9493d789f5c93c1d155e1bebadeb569 100644 --- a/slapos/recipe/erp5/__init__.py +++ b/slapos/recipe/erp5/__init__.py @@ -34,8 +34,13 @@ import sys import zc.buildout import zc.recipe.egg 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): def getTemplateFilename(self, template_name): @@ -307,7 +312,7 @@ class Recipe(BaseSlapRecipe): self._createDirectory(cron_d) self._createDirectory(crontabs) 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.options['dcrond_binary'].strip(), '-s', cron_d, '-c', crontabs, '-t', timestamps, '-f', '-l', '5', '-M', catcher] @@ -412,7 +417,7 @@ class Recipe(BaseSlapRecipe): conversion_server_dict)) self.path_list.append(config_file) 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, arguments=[self.options['ooo_paster'].strip(), 'serve', config_file])) return { @@ -436,7 +441,7 @@ class Recipe(BaseSlapRecipe): config)) self.path_list.append(haproxy_conf_path) 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.options['haproxy_binary'].strip(), '-f', haproxy_conf_path] )[0] @@ -455,7 +460,7 @@ class Recipe(BaseSlapRecipe): password = self.generatePassword() # XXX Unhardcoded me please user = 'zope' - write_inituser( + Zope2InitUser( os.path.join(self.erp5_directory, "inituser"), user, password) self._createDirectory(self.erp5_directory) @@ -542,7 +547,7 @@ class Recipe(BaseSlapRecipe): self.substituteTemplate(self.getTemplateFilename('zeo.conf.in'), config)) self.path_list.append(zeo_conf_path) 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.options['runzeo_binary'].strip(), '-C', zeo_conf_path] )[0] @@ -588,7 +593,7 @@ class Recipe(BaseSlapRecipe): ))) # TID server 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.options['tidstoraged_binary'], '--nofork', '--config', tidstorage_config])[0] @@ -599,7 +604,7 @@ class Recipe(BaseSlapRecipe): # repozo wrapper 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.options['tidstorage_repozo_binary'], '--config', tidstorage_config, '--repozo', self.options['repozo_binary'], '-z'])[0] @@ -617,7 +622,19 @@ class Recipe(BaseSlapRecipe): def installZope(self, ip, port, name, zodb_configuration_string, 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 zope_config = dict( products=self.options['products'], @@ -625,7 +642,7 @@ class Recipe(BaseSlapRecipe): ) # configure default Zope2 zcml 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['instance'] = self.erp5_directory zope_config['event_log'] = os.path.join(self.log_directory, @@ -649,8 +666,10 @@ class Recipe(BaseSlapRecipe): self.erp5_directory, 'Products')) zope_config['products'] = '\n'.join(prefixed_products) zope_config['address'] = '%s:%s' % (ip, port) - zope_config['tmp_directory'] = self.tmp_directory - zope_config['path'] = self.bin_directory + zope_environment_list = [] + 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_conf_content = self.substituteTemplate( @@ -673,7 +692,7 @@ class Recipe(BaseSlapRecipe): self.path_list.append(zope_conf_path) # Create init script 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.options['runzope_binary'].strip(), '-C', zope_conf_path] )[0] @@ -888,13 +907,13 @@ class Recipe(BaseSlapRecipe): '--socket=%s' %mysql_conf['socket'].strip(), '--user=root'] environment = dict(PATH='%s' % self.bin_directory) 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=[ innobackupex_argument_list + ['--incremental'], environment])[0] self.path_list.append(innobackupex_incremental) 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=[ innobackupex_argument_list, environment])[0] diff --git a/slapos/recipe/erp5/template/apache.zope.conf.in b/slapos/recipe/erp5/template/apache.zope.conf.in index 59007a36f0c8c0c733f93f48909f26c22c4d4472..131040d535278991f7d2f71b68c90c7224bf3953 100644 --- a/slapos/recipe/erp5/template/apache.zope.conf.in +++ b/slapos/recipe/erp5/template/apache.zope.conf.in @@ -1,12 +1,27 @@ # Apache configuration file for Zope # 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 PidFile "%(pid_file)s" LockFile "%(lock_file)s" Listen %(ip)s:%(port)s ServerAdmin %(server_admin)s -DefaultType text/plain TypesConfig conf/mime.types AddType application/x-compress .Z AddType application/x-gzip .gz .tgz @@ -19,7 +34,6 @@ RequestHeader unset REMOTE_USER # Log configuration 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" common CustomLog "%(access_log)s" common @@ -37,19 +51,3 @@ CustomLog "%(access_log)s" common # Magic of Zope related rewrite RewriteEngine On %(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 diff --git a/slapos/recipe/erp5/template/site.zcml b/slapos/recipe/erp5/template/site.zcml new file mode 100644 index 0000000000000000000000000000000000000000..47454428ef0282edeab26b4bb96edf57bce2f33c --- /dev/null +++ b/slapos/recipe/erp5/template/site.zcml @@ -0,0 +1,26 @@ +<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> diff --git a/slapos/recipe/erp5/template/zope.conf.in b/slapos/recipe/erp5/template/zope.conf.in index 6215910658752a3bfa33d2d4f603d0035e604c1a..90a1ac96b1f9d5e3f50c93ee149939b91b845d57 100644 --- a/slapos/recipe/erp5/template/zope.conf.in +++ b/slapos/recipe/erp5/template/zope.conf.in @@ -9,10 +9,7 @@ instancehome $INSTANCE # Environment override <environment> - TMP %(tmp_directory)s - TMPDIR %(tmp_directory)s - HOME %(tmp_directory)s - PATH %(path)s +%(environment)s </environment> # No need to debug diff --git a/slapos/recipe/erp5testnode/Updater.py b/slapos/recipe/erp5testnode/Updater.py index b8c1b7d714531d0e0c88b8cce396ac26a266b501..83ea60a1e7738bdd55316ce4bb7c5937f838203c 100644 --- a/slapos/recipe/erp5testnode/Updater.py +++ b/slapos/recipe/erp5testnode/Updater.py @@ -147,7 +147,7 @@ class Updater(object): # edit .git/info/sparse-checkout if you want sparse checkout if revision: if type(revision) is str: - h = self._git_find_rev('r' + revision) + h = revision else: h = revision[1] if h != self._git('rev-parse', 'HEAD'): diff --git a/slapos/recipe/erp5testnode/__init__.py b/slapos/recipe/erp5testnode/__init__.py index c48df631fc7af016b8e96a6277c056ea937f34b6..4d0b409adef5e084d4b2afe1209e573a9451826c 100644 --- a/slapos/recipe/erp5testnode/__init__.py +++ b/slapos/recipe/erp5testnode/__init__.py @@ -97,8 +97,8 @@ class Recipe(BaseSlapRecipe): bot_environment=self.parameter_dict.get('bot_environment', ''), partition_reference=CONFIG['partition_reference'], environment=dict(PATH=os.environ['PATH']), - vcs_authentication_list=self.parameter_dict.get( - 'vcs_authentication_list') + vcs_authentication_list=eval(self.parameter_dict.get( + 'vcs_authentication_list')), ) ])) @@ -112,8 +112,9 @@ class Recipe(BaseSlapRecipe): print "home_directory : %r" % home_directory git_dict.setdefault("git_server_name", "git.erp5.org") 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') - for vcs_authentication_dict in git_dict['vcs_authentication_list']: + for vcs_authentication_dict in vcs_authentication_list: netrc_file.write(""" machine %(host)s login %(user_name)s diff --git a/slapos/recipe/erp5testnode/testnode.py b/slapos/recipe/erp5testnode/testnode.py index 852e334d29b8dd15a989fea3dfde7b54ff96f37b..252745abfb1a98cc5b76576f8ec352208ec3085f 100644 --- a/slapos/recipe/erp5testnode/testnode.py +++ b/slapos/recipe/erp5testnode/testnode.py @@ -94,7 +94,7 @@ repository = %(repository_path)s branch = %(branch)s """ % {'buildout_section_id': buildout_section_id, 'repository_path' : repository_path, - 'branch' : vcs_repository.get('branch','')} + 'branch' : vcs_repository.get('branch','master')} custom_profile = open(custom_profile_path, 'w') custom_profile.write(profile_content) @@ -224,6 +224,7 @@ branch = %(branch)s invocation_list.extend([run_test_suite_path, '--test_suite', config['test_suite'], '--revision', revision, + '--test_suite_title', test_suite_title, '--node_quantity', config['node_quantity'], '--master_url', config['test_suite_master_url']]) run_test_suite = subprocess.Popen(invocation_list) diff --git a/slapos/recipe/kumofs/__init__.py b/slapos/recipe/kumofs/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..1b38aff6ed7bb24e9768531f8f0931bb68283679 --- /dev/null +++ b/slapos/recipe/kumofs/__init__.py @@ -0,0 +1,270 @@ +############################################################################## +# +# 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 diff --git a/slapos/recipe/kumofs/certificate_authority.py b/slapos/recipe/kumofs/certificate_authority.py new file mode 100644 index 0000000000000000000000000000000000000000..8caffc0c21b2852f259a9b6f85bda5e311965c47 --- /dev/null +++ b/slapos/recipe/kumofs/certificate_authority.py @@ -0,0 +1,112 @@ +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) diff --git a/slapos/recipe/kumofs/template/kumo_gateway.in b/slapos/recipe/kumofs/template/kumo_gateway.in new file mode 100644 index 0000000000000000000000000000000000000000..912f8f1007ad2cad325c56ce13a634375cee8ebc --- /dev/null +++ b/slapos/recipe/kumofs/template/kumo_gateway.in @@ -0,0 +1,2 @@ +#!/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 diff --git a/slapos/recipe/kumofs/template/kumo_manager.in b/slapos/recipe/kumofs/template/kumo_manager.in new file mode 100644 index 0000000000000000000000000000000000000000..e63e3c569de5f689176f19793706e49f90d3c95f --- /dev/null +++ b/slapos/recipe/kumofs/template/kumo_manager.in @@ -0,0 +1,2 @@ +#!/bin/sh +exec %(kumo_manager_binary)s -a -l %(kumo_manager_ip)s:%(kumo_manager_port)s -o %(kumo_manager_log)s diff --git a/slapos/recipe/kumofs/template/kumo_server.in b/slapos/recipe/kumofs/template/kumo_server.in new file mode 100644 index 0000000000000000000000000000000000000000..81aeabb323590320bc1be69b1854d50cdc3d9687 --- /dev/null +++ b/slapos/recipe/kumofs/template/kumo_server.in @@ -0,0 +1,2 @@ +#!/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 diff --git a/slapos/recipe/kumofs/template/openssl.cnf.ca.in b/slapos/recipe/kumofs/template/openssl.cnf.ca.in new file mode 100644 index 0000000000000000000000000000000000000000..8a450a68762145e72923635273e06a00e80d34ca --- /dev/null +++ b/slapos/recipe/kumofs/template/openssl.cnf.ca.in @@ -0,0 +1,350 @@ +# +# 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) diff --git a/slapos/recipe/kumofs/template/stunnel.conf.in b/slapos/recipe/kumofs/template/stunnel.conf.in new file mode 100644 index 0000000000000000000000000000000000000000..81aacdd78690b618ca64ae3a2bdba6108ff60934 --- /dev/null +++ b/slapos/recipe/kumofs/template/stunnel.conf.in @@ -0,0 +1,12 @@ +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 diff --git a/slapos/recipe/librecipe.py b/slapos/recipe/librecipe/__init__.py similarity index 100% rename from slapos/recipe/librecipe.py rename to slapos/recipe/librecipe/__init__.py diff --git a/slapos/recipe/erp5/execute.py b/slapos/recipe/librecipe/execute.py similarity index 100% rename from slapos/recipe/erp5/execute.py rename to slapos/recipe/librecipe/execute.py diff --git a/slapos/recipe/memcached/__init__.py b/slapos/recipe/memcached/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..03ebd049623c34d8751b1c493c194304e4bab1f6 --- /dev/null +++ b/slapos/recipe/memcached/__init__.py @@ -0,0 +1,242 @@ +############################################################################## +# +# 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']) diff --git a/slapos/recipe/memcached/certificate_authority.py b/slapos/recipe/memcached/certificate_authority.py new file mode 100644 index 0000000000000000000000000000000000000000..8caffc0c21b2852f259a9b6f85bda5e311965c47 --- /dev/null +++ b/slapos/recipe/memcached/certificate_authority.py @@ -0,0 +1,112 @@ +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) diff --git a/slapos/recipe/memcached/template/memcached.in b/slapos/recipe/memcached/template/memcached.in new file mode 100644 index 0000000000000000000000000000000000000000..92dae43a99feff580ac9ff3a6437c25a925f32e5 --- /dev/null +++ b/slapos/recipe/memcached/template/memcached.in @@ -0,0 +1,2 @@ +#!/bin/sh +exec %(memcached_binary)s -p %(memcached_port)s -U %(memcached_port)s -l %(memcached_ip)s diff --git a/slapos/recipe/memcached/template/openssl.cnf.ca.in b/slapos/recipe/memcached/template/openssl.cnf.ca.in new file mode 100644 index 0000000000000000000000000000000000000000..8a450a68762145e72923635273e06a00e80d34ca --- /dev/null +++ b/slapos/recipe/memcached/template/openssl.cnf.ca.in @@ -0,0 +1,350 @@ +# +# 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) diff --git a/slapos/recipe/memcached/template/stunnel.conf.in b/slapos/recipe/memcached/template/stunnel.conf.in new file mode 100644 index 0000000000000000000000000000000000000000..81aacdd78690b618ca64ae3a2bdba6108ff60934 --- /dev/null +++ b/slapos/recipe/memcached/template/stunnel.conf.in @@ -0,0 +1,12 @@ +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 diff --git a/slapos/recipe/template.py b/slapos/recipe/template.py deleted file mode 100644 index c8369e9a4e075fe519d03ea348c6a0b0ab444757..0000000000000000000000000000000000000000 --- a/slapos/recipe/template.py +++ /dev/null @@ -1,37 +0,0 @@ -############################################################################## -# -# 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) diff --git a/slapos/recipe/zabbixagent/__init__.py b/slapos/recipe/zabbixagent/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..ef587e32ae39bb410ddb7107283990a9c9c22540 --- /dev/null +++ b/slapos/recipe/zabbixagent/__init__.py @@ -0,0 +1,113 @@ +############################################################################## +# +# 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 diff --git a/slapos/recipe/zabbixagent/catdatefile.py b/slapos/recipe/zabbixagent/catdatefile.py new file mode 100644 index 0000000000000000000000000000000000000000..d3de298b272cce0eba88570aa6734ee74115e58e --- /dev/null +++ b/slapos/recipe/zabbixagent/catdatefile.py @@ -0,0 +1,14 @@ +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() diff --git a/slapos/recipe/zabbixagent/svcdaemon.py b/slapos/recipe/zabbixagent/svcdaemon.py new file mode 100644 index 0000000000000000000000000000000000000000..dcdead9ac154604fab43e4064d8ccc9351d8d4d4 --- /dev/null +++ b/slapos/recipe/zabbixagent/svcdaemon.py @@ -0,0 +1,60 @@ +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) diff --git a/slapos/recipe/zabbixagent/template/logrotate_entry.in b/slapos/recipe/zabbixagent/template/logrotate_entry.in new file mode 100644 index 0000000000000000000000000000000000000000..f20ce80b17a9f7ec33aee2ce72d69da19e55d896 --- /dev/null +++ b/slapos/recipe/zabbixagent/template/logrotate_entry.in @@ -0,0 +1,10 @@ +%(file_list)s { + daily + dateext + rotate 30 + compress + notifempty + sharedscripts + create + olddir %(olddir)s +} diff --git a/slapos/recipe/zabbixagent/template/zabbix_agentd.conf.in b/slapos/recipe/zabbixagent/template/zabbix_agentd.conf.in new file mode 100644 index 0000000000000000000000000000000000000000..9aef9930ca937ea7e1ef55a667676b2303b0d0c5 --- /dev/null +++ b/slapos/recipe/zabbixagent/template/zabbix_agentd.conf.in @@ -0,0 +1,231 @@ +# 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= diff --git a/software/erp5testnode/software.cfg b/software/erp5testnode/software.cfg index 42133f3a9cd6ddbe5796c13b90b4a921ed03d245..6126ff63275dd163a63b934adce861b9ac27f504 100644 --- a/software/erp5testnode/software.cfg +++ b/software/erp5testnode/software.cfg @@ -10,6 +10,7 @@ find-links = http://www.nexedi.org/static/packages/source/slapos.buildout/ versions = versions rebootstrap-section = python2.6 + extends = ../../component/python-2.6/buildout.cfg ../../component/subversion/buildout.cfg @@ -37,10 +38,6 @@ arguments = sys.argv[1:] + ["bootstrap"] section = python2.6 version = 1 -[versions] -# Use SlapOS patched zc.buildout -zc.buildout = 1.5.3-dev-SlapOS-001 - [eggs] recipe = zc.recipe.egg eggs = @@ -53,3 +50,429 @@ recipe = slapos.recipe.template url = ${:_profile_base_location_}/instance.cfg output = ${buildout:directory}/template.cfg 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 + diff --git a/software/kumofs/instance.cfg b/software/kumofs/instance.cfg new file mode 100644 index 0000000000000000000000000000000000000000..b2c8ab1fe7233968b75df396bf9fd05cac741bfb --- /dev/null +++ b/software/kumofs/instance.cfg @@ -0,0 +1,16 @@ +[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 diff --git a/software/kumofs/software.cfg b/software/kumofs/software.cfg new file mode 100644 index 0000000000000000000000000000000000000000..df4234c27e9d5a988a9ed2c1ed539fa673ad4bc1 --- /dev/null +++ b/software/kumofs/software.cfg @@ -0,0 +1,77 @@ +[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 diff --git a/software/memcached/instance.cfg b/software/memcached/instance.cfg new file mode 100644 index 0000000000000000000000000000000000000000..9b0c2276294533d3d5a3d613323b894284af9297 --- /dev/null +++ b/software/memcached/instance.cfg @@ -0,0 +1,14 @@ +[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 diff --git a/software/memcached/software.cfg b/software/memcached/software.cfg new file mode 100644 index 0000000000000000000000000000000000000000..f9c56de716d221f855a62e6f47ad67d78735c330 --- /dev/null +++ b/software/memcached/software.cfg @@ -0,0 +1,76 @@ +[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 diff --git a/software/zabbix-agent/instance.cfg b/software/zabbix-agent/instance.cfg new file mode 100644 index 0000000000000000000000000000000000000000..ab25b3ee9cf57763b7756983626b6943c439fcba --- /dev/null +++ b/software/zabbix-agent/instance.cfg @@ -0,0 +1,12 @@ +[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 diff --git a/software/zabbix-agent/software.cfg b/software/zabbix-agent/software.cfg new file mode 100644 index 0000000000000000000000000000000000000000..4df644300e348073d47d7bf12e9567c416c96de5 --- /dev/null +++ b/software/zabbix-agent/software.cfg @@ -0,0 +1,525 @@ +[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 +