Commit 4bb6e3fd authored by Kazuhiko Shiozaki's avatar Kazuhiko Shiozaki

Merge branch 'master' into erp5-component

parents 0c1d06b5 2c739e76
Changes Changes
======= =======
0.75.0 (2013-03-26)
-------------------
* Add backward compatibility about Partition.getInstanceGuid() in request.py. [Cedric de Saint Martin]
* request.py: Don't crash if resource is not ready. [Cedric de Saint Martin]
* Use memory-based kumofs instead of memcached to have no limitation for key length and data size. [Kazuhiko Shiozaki]
* Postgres: allow slapuser# to connect as postgres user. [Marco Mariani]
* apache_frontend: Sanitize inputs, disable Varnish cache, don't touch to custom file if already present. [Cedric de Saint Martin]
* Resiliency: simpler, more robust PBS recipe and promise. [Marco Mariani]
* Add helper method to set "location" parameter in librecipe. [Cedric de Saint Martin]
* Add download helper function in librecipe. [Cedric de Saint Martin]
* Update wrapper recipe to make it simpler and more dev-friendly. [Cedric de Saint Martin]
* Add configurationfile recipe. [Cedric de Saint Martin]
* Add request-edge recipe. [Cedric de Saint Martin]
* Add publishsection recipe. [Cedric de Saint Martin]
* Add match support for promise check_page_content. [Cedric de Saint Martin]
0.74.0 (2013-03-05) 0.74.0 (2013-03-05)
------------------- -------------------
......
...@@ -4,14 +4,41 @@ extends = ...@@ -4,14 +4,41 @@ extends =
../zlib/buildout.cfg ../zlib/buildout.cfg
../openssl/buildout.cfg ../openssl/buildout.cfg
parts = nginx
[nginx] [nginx]
recipe = hexagonit.recipe.cmmi recipe = hexagonit.recipe.cmmi
url = http://nginx.org/download/nginx-1.0.14.tar.gz url = http://nginx.org/download/nginx-1.2.7.tar.gz
md5sum = d252f5c689a14a668e241c744ccf5f06
configure-options=
--with-ipv6
--with-http_ssl_module
--with-ld-opt="-L ${zlib:location}/lib -L ${openssl:location}/lib -L ${pcre:location}/lib -Wl,-rpath=${pcre:location}/lib -Wl,-rpath=${zlib:location}/lib -Wl,-rpath=${openssl:location}/lib"
--with-cc-opt="-I ${pcre:location}/include -I ${openssl:location}/include -I ${zlib:location}/include"
[nginx-unstable]
recipe = hexagonit.recipe.cmmi
url = http://nginx.org/download/nginx-1.3.14.tar.gz
md5sum = 9b13753c88ea682fddd1495cb36e5d39
configure-options= configure-options=
--with-ipv6 --with-ipv6
--with-http_ssl_module --with-http_ssl_module
--with-ld-opt="-L ${zlib:location}/lib -L ${openssl:location}/lib -L ${pcre:location}/lib -Wl,-rpath=${pcre:location}/lib -Wl,-rpath=${zlib:location}/lib -Wl,-rpath=${openssl:location}/lib" --with-ld-opt="-L ${zlib:location}/lib -L ${openssl:location}/lib -L ${pcre:location}/lib -Wl,-rpath=${pcre:location}/lib -Wl,-rpath=${zlib:location}/lib -Wl,-rpath=${openssl:location}/lib"
--with-cc-opt="-I ${pcre:location}/include -I ${openssl:location}/include -I ${zlib:location}/include" --with-cc-opt="-I ${pcre:location}/include -I ${openssl:location}/include -I ${zlib:location}/include"
[hexaglobe-nginx-module]
recipe = hexagonit.recipe.download
url = http://easicloud-p.cdn.hexaglobe.net/nginx-easicloud.tar.gz
md5sum = 57fe2ceb09740f22b5b1023f29889e0e
strip-top-level-dir = true
[nginx-enable-sub]
# Used by Hexaglobe for watermarking
<= nginx
configure-options=
--with-ipv6
--with-http_ssl_module
--with-ld-opt="-L ${zlib:location}/lib -L ${openssl:location}/lib -L ${pcre:location}/lib -Wl,-rpath=${pcre:location}/lib -Wl,-rpath=${zlib:location}/lib -Wl,-rpath=${openssl:location}/lib"
--with-cc-opt="-I ${pcre:location}/include -I ${openssl:location}/include -I ${zlib:location}/include"
--add-module=${hexaglobe-nginx-module:location}/sub_module
# --add-module=${hexaglobe-nginx-module:location}/nginx-upstream-fair
...@@ -28,7 +28,7 @@ from setuptools import setup, find_packages ...@@ -28,7 +28,7 @@ from setuptools import setup, find_packages
import glob import glob
import os import os
version = '0.74.1-dev' version = '0.75.1.dev'
name = 'slapos.cookbook' name = 'slapos.cookbook'
long_description = open("README.txt").read() + "\n" + \ long_description = open("README.txt").read() + "\n" + \
open("CHANGES.txt").read() + "\n" open("CHANGES.txt").read() + "\n"
...@@ -52,6 +52,7 @@ setup(name=name, ...@@ -52,6 +52,7 @@ setup(name=name,
packages=find_packages(), packages=find_packages(),
include_package_data=True, include_package_data=True,
install_requires=[ install_requires=[
'hexagonit.recipe.download',
'lxml', # for full blown python interpreter 'lxml', # for full blown python interpreter
'netaddr', # to manipulate on IP addresses 'netaddr', # to manipulate on IP addresses
'setuptools', # namespaces 'setuptools', # namespaces
...@@ -80,6 +81,7 @@ setup(name=name, ...@@ -80,6 +81,7 @@ setup(name=name,
'check_url_available = slapos.recipe.check_url_available:Recipe', 'check_url_available = slapos.recipe.check_url_available:Recipe',
'cloud9 = slapos.recipe.cloud9:Recipe', 'cloud9 = slapos.recipe.cloud9:Recipe',
'cloudooo.test = slapos.recipe.erp5_test:CloudoooRecipe', 'cloudooo.test = slapos.recipe.erp5_test:CloudoooRecipe',
'configurationfile = slapos.recipe.configurationfile:Recipe',
'cron = slapos.recipe.dcron:Recipe', 'cron = slapos.recipe.dcron:Recipe',
'cron.d = slapos.recipe.dcron:Part', 'cron.d = slapos.recipe.dcron:Part',
'davstorage = slapos.recipe.davstorage:Recipe', 'davstorage = slapos.recipe.davstorage:Recipe',
...@@ -121,6 +123,7 @@ setup(name=name, ...@@ -121,6 +123,7 @@ setup(name=name,
'kvm = slapos.recipe.kvm:Recipe', 'kvm = slapos.recipe.kvm:Recipe',
'kvm.frontend = slapos.recipe.kvm_frontend:Recipe', 'kvm.frontend = slapos.recipe.kvm_frontend:Recipe',
'lamp = slapos.recipe.lamp:Request', 'lamp = slapos.recipe.lamp:Request',
'lamp.generic = slapos.recipe.lampgeneric:Recipe',
'lamp.request = slapos.recipe.lamp:Request', 'lamp.request = slapos.recipe.lamp:Request',
'lamp.simple = slapos.recipe.lamp:Simple', 'lamp.simple = slapos.recipe.lamp:Simple',
'lamp.static = slapos.recipe.lamp:Static', 'lamp.static = slapos.recipe.lamp:Static',
...@@ -151,11 +154,13 @@ setup(name=name, ...@@ -151,11 +154,13 @@ setup(name=name,
'proactive = slapos.recipe.proactive:Recipe', 'proactive = slapos.recipe.proactive:Recipe',
'publish = slapos.recipe.publish:Recipe', 'publish = slapos.recipe.publish:Recipe',
'publish.serialised = slapos.recipe.publish:Serialised', 'publish.serialised = slapos.recipe.publish:Serialised',
'publishsection = slapos.recipe.publish:PublishSection',
'publishurl = slapos.recipe.publishurl:Recipe', 'publishurl = slapos.recipe.publishurl:Recipe',
'pwgen = slapos.recipe.pwgen:Recipe', 'pwgen = slapos.recipe.pwgen:Recipe',
'pwgen.stable = slapos.recipe.pwgen:StablePasswordGeneratorRecipe', 'pwgen.stable = slapos.recipe.pwgen:StablePasswordGeneratorRecipe',
'request = slapos.recipe.request:Recipe', 'request = slapos.recipe.request:Recipe',
'request.serialised = slapos.recipe.request:Serialised', 'request.serialised = slapos.recipe.request:Serialised',
'request.edge = slapos.recipe.request:RequestEdge',
'requestoptional = slapos.recipe.request:RequestOptional', 'requestoptional = slapos.recipe.request:RequestOptional',
'seleniumrunner = slapos.recipe.seleniumrunner:Recipe', 'seleniumrunner = slapos.recipe.seleniumrunner:Recipe',
'sheepdogtestbed = slapos.recipe.sheepdogtestbed:SheepDogTestBed', 'sheepdogtestbed = slapos.recipe.sheepdogtestbed:SheepDogTestBed',
...@@ -188,6 +193,7 @@ setup(name=name, ...@@ -188,6 +193,7 @@ setup(name=name,
'xvfb = slapos.recipe.xvfb:Recipe', 'xvfb = slapos.recipe.xvfb:Recipe',
'xwiki = slapos.recipe.xwiki:Recipe', 'xwiki = slapos.recipe.xwiki:Recipe',
'zabbixagent = slapos.recipe.zabbixagent:Recipe', 'zabbixagent = slapos.recipe.zabbixagent:Recipe',
'zimbra.kvm = slapos.recipe.zimbra_kvm:Recipe',
'zeo = slapos.recipe.zeo:Recipe', 'zeo = slapos.recipe.zeo:Recipe',
], ],
......
...@@ -38,6 +38,7 @@ class Recipe(GenericBaseRecipe): ...@@ -38,6 +38,7 @@ class Recipe(GenericBaseRecipe):
'url': self.options['url'], 'url': self.options['url'],
'shell_path': self.options['dash_path'], 'shell_path': self.options['dash_path'],
'curl_path': self.options['curl_path'], 'curl_path': self.options['curl_path'],
'match': self.options.get('match', self.options['url'])
} }
# XXX-Cedric in this script, curl won't check certificate # XXX-Cedric in this script, curl won't check certificate
......
...@@ -3,13 +3,14 @@ ...@@ -3,13 +3,14 @@
# BEWARE: It will be overwritten automatically # BEWARE: It will be overwritten automatically
URL="%(url)s" URL="%(url)s"
MATCH='%(match)s"
if [ -z $URL ]; then if [ -z $URL ]; then
echo "No URL specified." >&2 echo "No URL specified." >&2
exit 3 exit 3
fi fi
%(curl_path)s -k -sL $URL | grep "$URL" > /dev/null %(curl_path)s -k -sL $URL | grep "$MATCH" > /dev/null
if [ $? != 0 ]; then if [ $? != 0 ]; then
echo "Content at $URL seems to be corrupted" >&2 echo "Content at $URL seems to be corrupted" >&2
......
##############################################################################
#
# 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 GenericBaseRecipe
class Recipe(GenericBaseRecipe):
def install(self):
configuration_file = self.createFile(
self.options['configuration-file-path'],
self.substituteTemplate(
self.options['configuration-template-path'],
self.options
)
)
return configuration_file
...@@ -36,6 +36,11 @@ from slapos.recipe.librecipe import GenericBaseRecipe ...@@ -36,6 +36,11 @@ from slapos.recipe.librecipe import GenericBaseRecipe
BUFFER_SIZE = 1024 BUFFER_SIZE = 1024
# XXX-Cedric: For god's sake, why do we always reinvent the wheel???
# DON'T use this and use h.r.download, except if you need the "confirm" feature.
# XXX-Cedric: implement "confirm" feature in h.r.download
def service(args): def service(args):
environ = os.environ.copy() environ = os.environ.copy()
environ.update(PATH=args['path']) environ.update(PATH=args['path'])
......
##############################################################################
#
# Copyright (c) 2013 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 shutil
import os
import zc.buildout
from slapos.recipe.librecipe import GenericBaseRecipe
class Recipe(GenericBaseRecipe):
# XXX-Cedric: write docstring
def install(self):
path_list = []
# Download and unpack application if not already existing
htdocs_location = self.options['htdocs']
if not (os.path.exists(htdocs_location) and os.listdir(htdocs_location)):
try:
os.rmdir(htdocs_location)
except:
pass
self.download(htdocs_location)
# Install php.ini
php_ini = self.createFile(os.path.join(self.options['php-ini-dir'],
'php.ini'),
self.substituteTemplate(self.getTemplateFilename('php.ini.in'),
dict(tmp_directory=self.options['tmp-dir']))
)
path_list.append(php_ini)
# Install apache
apache_config = dict(
pid_file=self.options['pid-file'],
lock_file=self.options['lock-file'],
ip=self.options['ip'],
port=self.options['port'],
error_log=self.options['error-log'],
access_log=self.options['access-log'],
document_root=self.options['htdocs'],
php_ini_dir=self.options['php-ini-dir'],
)
httpd_conf = self.createFile(self.options['httpd-conf'],
self.substituteTemplate(self.getTemplateFilename('apache.in'),
apache_config)
)
path_list.append(httpd_conf)
wrapper = self.createWrapper(name=self.options['wrapper'],
command=self.options['httpd-binary'],
parameters=[
'-f',
self.options['httpd-conf'],
'-DFOREGROUND'
])
path_list.append(wrapper)
return path_list
# Apache static configuration
# Automatically generated
# Basic server configuration
PidFile "%(pid_file)s"
Listen %(ip)s:%(port)s
PHPINIDir %(php_ini_dir)s
ServerAdmin someone@email
DefaultType text/plain
TypesConfig conf/mime.types
AddType application/x-compress .Z
AddType application/x-gzip .gz .tgz
AddType application/x-httpd-php .php .phtml .php5 .php4
AddType application/x-httpd-php-source .phps
# 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
# Directory protection
<Directory />
Options FollowSymLinks
AllowOverride None
Require all denied
</Directory>
<Directory %(document_root)s>
Options FollowSymLinks
AllowOverride All
Require all granted
</Directory>
DocumentRoot %(document_root)s
DirectoryIndex index.html index.php
# List of modules
LoadModule unixd_module modules/mod_unixd.so
LoadModule access_compat_module modules/mod_access_compat.so
LoadModule authz_core_module modules/mod_authz_core.so
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 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 dir_module modules/mod_dir.so
LoadModule php5_module modules/libphp5.so
LoadModule alias_module modules/mod_alias.so
[PHP]
engine = On
safe_mode = Off
expose_php = Off
error_reporting = E_ALL & ~(E_DEPRECATED|E_NOTICE|E_WARNING)
display_errors = On
display_startup_errors = Off
log_errors = On
log_errors_max_len = 1024
ignore_repeated_errors = Off
ignore_repeated_source = Off
session.save_path = "%(tmp_directory)s"
session.auto_start = 0
date.timezone = Europe/Paris
file_uploads = On
upload_max_filesize = 8M
post_max_size = 8M
magic_quotes_gpc=Off
...@@ -32,6 +32,7 @@ import os ...@@ -32,6 +32,7 @@ import os
import sys import sys
import inspect import inspect
import re import re
import shutil
import urllib import urllib
import urlparse import urlparse
...@@ -226,3 +227,30 @@ class GenericBaseRecipe(object): ...@@ -226,3 +227,30 @@ class GenericBaseRecipe(object):
url = urlparse.urlunparse((scheme, netloc, path, params, query, fragment)) url = urlparse.urlunparse((scheme, netloc, path, params, query, fragment))
return url return url
def setLocationOption(self):
if not self.options.get('location'):
self.options['location'] = os.path.join(
self.buildout['buildout']['parts-directory'], self.name)
def download(self, destination=None):
""" A simple wrapper around h.r.download, downloading to self.location"""
self.setLocationOption()
import hexagonit.recipe.download
if not destination:
destination = self.location
if os.path.exists(destination):
# leftovers from a previous failed attempt, removing it.
log.warning('Removing already existing directory %s' % destination)
shutil.rmtree(destination)
os.mkdir(destination)
try:
options = self.options.copy()
options['destination'] = destination
hexagonit.recipe.download.Recipe(
self.buildout, self.name, options).install()
except:
shutil.rmtree(destination)
raise
...@@ -28,6 +28,8 @@ import zc.buildout ...@@ -28,6 +28,8 @@ import zc.buildout
from slapos.recipe.librecipe import wrap from slapos.recipe.librecipe import wrap
from slapos.recipe.librecipe import GenericSlapRecipe from slapos.recipe.librecipe import GenericSlapRecipe
CONNECTION_PARAMETER_STRING = 'connection-'
class Recipe(GenericSlapRecipe): class Recipe(GenericSlapRecipe):
def _install(self): def _install(self):
publish_dict = dict() publish_dict = dict()
...@@ -47,3 +49,26 @@ SERIALISED_MAGIC_KEY = '_' ...@@ -47,3 +49,26 @@ SERIALISED_MAGIC_KEY = '_'
class Serialised(Recipe): class Serialised(Recipe):
def _setConnectionDict(self, publish_dict): def _setConnectionDict(self, publish_dict):
return super(Serialised, self)._setConnectionDict(wrap(publish_dict)) return super(Serialised, self)._setConnectionDict(wrap(publish_dict))
class PublishSection(GenericSlapRecipe):
"""
Take a list of "request" sections, and publish every connection parameter.
Input:
section-list: String, representing the list of sections to fetch
parameters to publish, in order, separated by a space.
"""
def _install(self):
publish_dict = dict()
for section in self.options['section-list'].strip().split():
section = section.strip()
options = self.buildout[section].copy()
for k, v in options.iteritems():
if k.startswith(CONNECTION_PARAMETER_STRING):
print k, v
publish_dict[k.lstrip(CONNECTION_PARAMETER_STRING)] = v
self.setConnectionDict(publish_dict)
return []
...@@ -215,7 +215,6 @@ class RequestOptional(Recipe): ...@@ -215,7 +215,6 @@ class RequestOptional(Recipe):
update = install update = install
class Serialised(Recipe): class Serialised(Recipe):
def _filterForStorage(self, partition_parameter_kw): def _filterForStorage(self, partition_parameter_kw):
return wrap(partition_parameter_kw) return wrap(partition_parameter_kw)
...@@ -225,3 +224,39 @@ class Serialised(Recipe): ...@@ -225,3 +224,39 @@ class Serialised(Recipe):
return json.loads(instance.getConnectionParameter(JSON_SERIALISED_MAGIC_KEY)) return json.loads(instance.getConnectionParameter(JSON_SERIALISED_MAGIC_KEY))
except slapmodule.NotFoundError: except slapmodule.NotFoundError:
return {} return {}
CONNECTION_PARAMETER_STRING = 'connection-'
class RequestEdge(Recipe):
"""
For each country in country-list, do a request.
"""
def __init__(self, buildout, name, options):
self.logger = logging.getLogger(name)
self.options = options
self.request_dict = {}
# Keep a copy of original options dict
original_options = options.copy()
for country in options['country-list'].split(','):
# Request will have its own copy of options dict
local_options = original_options.copy()
local_options['name'] = '%s-%s' % (country, name)
local_options['sla'] = "region"
local_options['sla-region'] = country
self.request_dict[country] = Recipe(buildout, name, local_options)
# "Bubble" all connection parameters
for option, value in local_options.iteritems():
if option.startswith(CONNECTION_PARAMETER_STRING):
self.options['%s-%s' % (option, country)] = value
def install(self):
for country, request in self.request_dict.iteritems():
request.install()
return []
update = install
...@@ -116,7 +116,7 @@ class Recipe: ...@@ -116,7 +116,7 @@ class Recipe:
for parameter, value in self.parameter_dict.items(): for parameter, value in self.parameter_dict.items():
# All parameters evaluating to False are... False, and shouldn't # All parameters evaluating to False are... False, and shouldn't
# convey any information. # convey any information.
# Here, all those parameters are set to empty string. # Here, all those parameters are simply ignored.
if value: if value:
if isinstance(value, str): if isinstance(value, str):
buildout.set('slap-parameter', parameter, value) buildout.set('slap-parameter', parameter, value)
......
...@@ -30,25 +30,32 @@ import shlex ...@@ -30,25 +30,32 @@ import shlex
from slapos.recipe.librecipe import GenericBaseRecipe from slapos.recipe.librecipe import GenericBaseRecipe
class Recipe(GenericBaseRecipe): class Recipe(GenericBaseRecipe):
def install(self): def install(self):
command_line = shlex.split(self.options['command-line']) command_line = shlex.split(self.options['command-line'])
wrapper_path = self.options['wrapper-path']
wait_files = self.options.get('wait-for-files') wait_files = self.options.get('wait-for-files')
environment = self.options.get('environment')
if not wait_files and not environment:
# Create a simple wrapper as shell script
return [self.createWrapper(
name=wrapper_path,
command=command_line[0],
parameters=command_line[1:],
)]
# More complex needs: create a Python script as wrapper
if wait_files is not None: if wait_files is not None:
wait_files = [filename.strip() for filename in wait_files.split() wait_files = [filename.strip() for filename in wait_files.split()
if filename.strip()] if filename.strip()]
environment = self.options.get('environment')
if environment is not None: if environment is not None:
environment = dict((k.strip(), v.strip()) for k, v in [ environment = dict((k.strip(), v.strip()) for k, v in [
line.split('=') line.split('=')
for line in environment.split('\n') for line in environment.split('\n')
]) ])
return [self.createPythonScript( return [self.createPythonScript(
self.options['output'], wrapper_path,
'slapos.recipe.librecipe.execute.generic_exec', 'slapos.recipe.librecipe.execute.generic_exec',
(command_line, wait_files, environment,), (command_line, wait_files, environment,),
)] )]
##############################################################################
#
# 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 GenericBaseRecipe
import sys
class Recipe(GenericBaseRecipe):
"""
kvm instance configuration.
"""
def install(self):
config = dict(
vnc_ip=self.options['vnc-ip'],
vnc_port=self.options['vnc-port'],
boot_disk_path=self.options['boot-disk-path'],
disk_path=self.options['data-disk-path'],
disk_size=self.options['data-disk-size'],
disk_type=self.options['data-disk-type'],
mac_address=self.options['mac-address'],
smp_count=self.options['smp-count'],
ram_size=self.options['ram-size'],
socket_path=self.options['socket-path'],
pid_file_path=self.options['pid-path'],
python_path=sys.executable,
shell_path=self.options['shell-path'],
qemu_path=self.options['qemu-path'],
qemu_img_path=self.options['qemu-img-path'],
vnc_passwd=self.options['passwd']
)
# Runners
runner_path = self.createExecutable(
self.options['runner-path'],
self.substituteTemplate(self.getTemplateFilename('kvm_run.in'), config))
controller_path = self.createExecutable(
self.options['controller-path'],
self.substituteTemplate(self.getTemplateFilename('kvm_controller_run.in'),
config))
return [runner_path, controller_path]
#!%(python_path)s
# BEWARE: This file is operated by slapgrid
# BEWARE: It will be overwritten automatically
# Echo client program
import socket
import time
# Connect to KVM qmp socket
so = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
connected = False
while not connected:
try:
so.connect('%(socket_path)s')
except socket.error:
time.sleep(1)
else:
connected = True
data = so.recv(1024)
# Enable qmp
so.send('{ "execute": "qmp_capabilities" }')
data = so.recv(1024)
# Set VNC password
so.send('{ "execute": "change", ' \
'"arguments": { "device": "vnc", "target": "password", ' \
' "arg": "%(vnc_passwd)s" } }')
data = so.recv(1024)
# Finish
so.close()
#!%(python_path)s
# BEWARE: This file is operated by slapgrid
# BEWARE: It will be overwritten automatically
# Echo client program
import os
import socket
import subprocess
def getSocketStatus(host, port):
s = None
for res in socket.getaddrinfo(host, port,
socket.AF_UNSPEC, socket.SOCK_STREAM):
af, socktype, proto, canonname, sa = res
try:
s = socket.socket(af, socktype, proto)
except socket.error, msg:
s = None
continue
try:
s.connect(sa)
except socket.error, msg:
s.close()
s = None
continue
break
return s
# create disk if doesn't exist
disk_path = '%(disk_path)s'
if not os.path.exists(disk_path):
subprocess.Popen(['%(qemu_img_path)s', 'create' ,'-f', 'qcow2',
disk_path, '%(disk_size)sG'])
# Generate NAT rules
nat_rules = ",".join("hostfwd=tcp:%(vnc_ip)s:%%s-:%%s" %% (port, port) for port in [25, 80, 110, 143, 443, 465, 587, 993, 995, 7071])
kvm_argument_list = ['%(qemu_path)s',
'-enable-kvm', '-net', 'nic,macaddr=%(mac_address)s',
'-net', 'user,hostfwd=tcp:%(vnc_ip)s:2222-:22,%%s' %% nat_rules,
'-smp', '%(smp_count)s',
'-m', '%(ram_size)s',
'-drive', 'file=%(disk_path)s,if=%(disk_type)s',
#'-drive', 'file=%(boot_disk_path)s,if=%(disk_type)s',
'-vnc', '%(vnc_ip)s:1,ipv4,password',
'-boot', 'menu=on',
'-qmp', 'unix:%(socket_path)s,server',
'-pidfile', '%(pid_file_path)s',
]
os.execv('%(qemu_path)s', kvm_argument_list)
...@@ -83,6 +83,7 @@ port ...@@ -83,6 +83,7 @@ port
Port used by Apache. Optional parameter, defaults to 4443. Port used by Apache. Optional parameter, defaults to 4443.
plain_http_port plain_http_port
~~~~~~~~~~~~~~~
Port used by apache to serve plain http (only used to redirect to https). Port used by apache to serve plain http (only used to redirect to https).
Optional parameter, defaults to 8080. Optional parameter, defaults to 8080.
...@@ -192,7 +193,12 @@ Notes ...@@ -192,7 +193,12 @@ Notes
===== =====
It is not possible with slapos to listen to port <= 1024, because process are It is not possible with slapos to listen to port <= 1024, because process are
not run as root. It is a good idea then to go on the node where the instance is not run as root.
Solution 1
----------
It is a good idea then to go on the node where the instance is
and set some iptables rules like (if using default ports):: and set some iptables rules like (if using default ports)::
iptables -t nat -A PREROUTING -p tcp -d {public_ipv4} --dport 443 -j DNAT --to-destination {listening_ipv4}:4443 iptables -t nat -A PREROUTING -p tcp -d {public_ipv4} --dport 443 -j DNAT --to-destination {listening_ipv4}:4443
...@@ -200,3 +206,12 @@ and set some iptables rules like (if using default ports):: ...@@ -200,3 +206,12 @@ and set some iptables rules like (if using default ports)::
Where {public ip} is the public IP of your server, or at least the LAN IP to where your NAT will forward to. Where {public ip} is the public IP of your server, or at least the LAN IP to where your NAT will forward to.
{listening ip} is the private ipv4 (like 10.0.34.123) that the instance is using and sending as connection parameter. {listening ip} is the private ipv4 (like 10.0.34.123) that the instance is using and sending as connection parameter.
Solution 2
----------
It is also possible to directly allow the service to listen on 80 and 443 ports using the following command:
setcap 'cap_net_bind_service=+ep' /opt/slapgrid/$APACHE_FRONTEND_SOFTWARE_RELEASE_MD5/parts/apache-2.2/bin/httpd
Then specify in the instance parameters "port" and "plain_http_port" to be 443 and 80, respectively.
#############################
#
# Deploy hello-world instance
#
#############################
[buildout]
parts =
directory
hello-world
publish-connection-parameter
# Define egg directories to be the one from Software Release
# (/opt/slapgrid/...)
# Always the same.
eggs-directory = ${buildout:eggs-directory}
develop-eggs-directory = ${buildout:develop-eggs-directory}
offline = true
[instance-parameter]
# Fetches parameters defined in SlapOS Master for this instance.
# Always the same.
recipe = slapos.cookbook:slapconfiguration
computer = $${slap_connection:computer_id}
partition = $${slap_connection:partition_id}
url = $${slap_connection:server_url}
key = $${slap_connection:key_file}
cert = $${slap_connection:cert_file}
# Define default parameter(s) that will be used later, in case user didn't
# specify it
name = anonymous
# Create all needed directories, depending on your needs
[directory]
recipe = slapos.cookbook:mkdirectory
etc = $${buildout:directory}/etc
# Executables put here will be started but not monitored (for startup scripts)
script = $${:etc}/run/
# Executables put here will be started and monitored (for daemons)
service = $${:etc}/service
# Executables put here will be launched after buildout has completed to see
# if instance is running
promise = $${:etc}/promise/
# Create a simple shell script that will only output your name if you
# specified it as instance parameter.
# Usually, of course, we use more useful commands, like web servers.
[hello-world]
# This recipe will try to "exec" the command-line after separating parameters.
recipe = slapos.cookbook:wrapper
# Notice that there is only one $ at ${dash:location}, it is because it comes from the Software Release buildout profile.
command-line = ${dash:location}/bin/dash -c 'echo "Hello $${instance-parameter:name}!"; sleep 100000;'
# Put this shell script in the "etc/service" directory. Every executable of this
# repository will be started and monitored by supervisord
wrapper-path = $${directory:service}/hello-world
# Publish all the parameters needed for the user to connect to the instance.
# It can be anything: URL(s), password(s), or arbitrary parameters.
# Here we'll just echo back the entered name as instance parameter
[publish-connection-parameter]
recipe = slapos.cookbook:publish
name = Hello $${instance-parameter:name}!
[buildout]
extends =
# "slapos" stack describes basic things needed for 99.9% of SlapOS Software
# Releases
../../stack/slapos.cfg
# Extend here component profiles, like openssl, apache, mariadb, curl...
# Or/and extend a stack (lamp, tomcat) that does most of the work for you
# In this example we only need the dash binary to run a simple "hello world"
# shell script.
../../component/dash/buildout.cfg
parts =
# Call installation of slapos.cookbook egg defined in stack/slapos.cfg (needed
# in 99,9% of Slapos Software Releases)
slapos-cookbook
# Call creation of instance.cfg file that will be called for deployment of
# instance
template
# Download instance.cfg.in (buildout profile used to deployment of instance),
# replace all ${foo:bar} parameters by real values, and change $${foo:bar} to
# ${foo:bar}
[template]
recipe = slapos.recipe.template
url = ${:_profile_base_location_}/instance.cfg.in
output = ${buildout:directory}/instance.cfg
# MD5 checksum can be skipped for development, but must be filled for production
#md5sum =
mode = 0644
This Software Release represents a generic LAMP service.
The PHP application is given to the instance by parameter as URL of application archive.
XXX-Cedric: what about application configuration?
\ No newline at end of file
# Exactly the same as software.cfg, but fetch the slapos.cookbook and
# slapos.toolbox from git repository instead of fetching stable version,
# allowing to play with bleeding edge environment.
# You'll need to run buildout twice for this profile.
[buildout]
extends =
../../component/git/buildout.cfg
software.cfg
parts +=
# Development parts
slapos.cookbook-repository
slapos.core-repository
slapos.toolbox-repository
check-recipe
develop =
${:parts-directory}/slapos.cookbook-repository
${:parts-directory}/slapos.core-repository
${:parts-directory}/slapos.toolbox-repository
[slapos.toolbox-repository]
recipe = slapos.recipe.build:gitclone
repository = http://git.erp5.org/repos/slapos.toolbox.git
branch = master
git-executable = ${git:location}/bin/git
[slapos.cookbook-repository]
recipe = slapos.recipe.build:gitclone
repository = http://git.erp5.org/repos/slapos.git
branch = lamp-edge
git-executable = ${git:location}/bin/git
[slapos.core-repository]
recipe = slapos.recipe.build:gitclone
repository = http://git.erp5.org/repos/slapos.core.git
branch = master
git-executable = ${git:location}/bin/git
[check-recipe]
recipe = plone.recipe.command
stop-on-error = true
update-command = ${:command}
command =
grep parts ${buildout:develop-eggs-directory}/slapos.cookbook.egg-link &&
grep parts ${buildout:develop-eggs-directory}/slapos.core.egg-link &&
grep parts ${buildout:develop-eggs-directory}/slapos.toolbox.egg-link
[versions]
slapos.cookbook =
slapos.toolbox =
slapos.core =
[buildout]
parts =
logrotate
logrotate-entry-apache
cron
cron-entry-logrotate
promise
frontend-promise
publish-connection-informations
eggs-directory = ${buildout:eggs-directory}
develop-eggs-directory = ${buildout:develop-eggs-directory}
newest = false
#----------------
#--
#-- Creation of all needed directories.
[rootdirectory]
recipe = slapos.cookbook:mkdirectory
etc = $${buildout:directory}/etc
var = $${buildout:directory}/var
srv = $${buildout:directory}/srv
bin = $${buildout:directory}/bin
tmp = $${buildout:directory}/tmp
[basedirectory]
recipe = slapos.cookbook:mkdirectory
log = $${rootdirectory:var}/log
services = $${rootdirectory:etc}/service
run = $${rootdirectory:var}/run
backup = $${rootdirectory:srv}/backup
promises = $${rootdirectory:etc}/promise
[directory]
recipe = slapos.cookbook:mkdirectory
cron-entries = $${rootdirectory:etc}/cron.d
crontabs = $${rootdirectory:etc}/crontabs
cronstamps = $${rootdirectory:etc}/cronstamps
ca-dir = $${rootdirectory:srv}/ssl
httpd-log = $${basedirectory:log}/apache
php-ini-dir = $${rootdirectory:etc}/php
tmp-php = $${rootdirectory:tmp}/php
logrotate-entries = $${rootdirectory:etc}/logrotate.d
logrotate-backup = $${basedirectory:backup}/logrotate
report = $${rootdirectory:etc}/report
stunnel-conf = $${rootdirectory:etc}/stunnel
xml-report = $${rootdirectory:var}/xml_report
www = $${rootdirectory:srv}/www/
[cadirectory]
recipe = slapos.cookbook:mkdirectory
requests = $${directory:ca-dir}/requests
private = $${directory:ca-dir}/private
certs = $${directory:ca-dir}/certs
newcerts = $${directory:ca-dir}/newcerts
crl = $${directory:ca-dir}/crl
#----------------
#--
#-- Deploy cron.
[cron]
recipe = slapos.cookbook:cron
dcrond-binary = ${dcron:location}/sbin/crond
cron-entries = $${directory:cron-entries}
crontabs = $${directory:crontabs}
cronstamps = $${directory:cronstamps}
catcher = $${cron-simplelogger:wrapper}
binary = $${basedirectory:services}/crond
[cron-simplelogger]
recipe = slapos.cookbook:simplelogger
wrapper = $${rootdirectory:bin}/cron_simplelogger
log = $${basedirectory:log}/crond.log
#----------------
#--
#-- Deploy logrotate.
[cron-entry-logrotate]
<= cron
recipe = slapos.cookbook:cron.d
name = logrotate
frequency = 0 0 * * *
command = $${logrotate:wrapper}
[logrotate]
recipe = slapos.cookbook:logrotate
# Binaries
logrotate-binary = ${logrotate:location}/usr/sbin/logrotate
gzip-binary = ${gzip:location}/bin/gzip
gunzip-binary = ${gzip:location}/bin/gunzip
# Directories
wrapper = $${rootdirectory:bin}/logrotate
conf = $${rootdirectory:etc}/logrotate.conf
logrotate-entries = $${directory:logrotate-entries}
backup = $${directory:logrotate-backup}
state-file = $${rootdirectory:srv}/logrotate.status
#----------------
#--
#-- Deploy Apache + PHP application.
[apache-php]
recipe = slapos.cookbook:lamp.generic
url = $${slap-parameter:application-location}
strip-top-level-dir = true
# md5sum =
# XXX-Cedric: add some "template" configuration
htdocs = $${directory:www}
pid-file = $${basedirectory:run}/apache.pid
lock-file = $${basedirectory:run}/apache.lock
ip = $${slap-network-information:global-ipv6}
port = 8080
error-log = $${directory:httpd-log}/error.log
access-log = $${directory:httpd-log}/access.log
php-ini-dir = $${directory:php-ini-dir}
tmp-dir = $${directory:tmp-php}
httpd-conf = $${rootdirectory:etc}/apache.conf
wrapper = $${basedirectory:services}/apache
httpd-binary = ${apache:location}/bin/httpd
[logrotate-entry-apache]
<= logrotate
recipe = slapos.cookbook:logrotate.d
name = apache
log = $${apache-php:error-log} $${apache-php:access-log}
frequency = daily
rotate-num = 30
sharedscripts = true
notifempty = true
create = true
#----------------
#--
#-- Request frontend.
[request-frontend]
<= slap-connection
recipe = slapos.cookbook:requestoptional
name = Frontend
# XXX We have hardcoded SR URL here.
software-url = http://git.erp5.org/gitweb/slapos.git/blob_plain/HEAD:/software/apache-frontend/software.cfg
slave = true
config = url custom_domain
config-url = http://[$${apache-php:ip}]:$${apache-php:port}/
return = site_url
config-custom_domain = $${slap-parameter:domain}
#----------------
#--
#-- Publish instance parameters.
[publish-connection-informations]
recipe = slapos.cookbook:publish
backend-url = http://[$${apache-php:ip}]:$${apache-php:port}/
url = $${request-frontend:connection-site_url}
#----------------
#--
#-- Deploy promises scripts.
[promise]
recipe = slapos.cookbook:check_port_listening
path = $${basedirectory:promises}/apache
hostname = $${apache-php:ip}
port = $${apache-php:port}
[frontend-promise]
recipe = slapos.cookbook:check_url_available
path = $${basedirectory:promises}/frontend
url = $${request-frontend:connection-site_url}
dash_path = ${dash:location}/bin/dash
curl_path = ${curl:location}/bin/curl
[slap-parameter]
# Default value if no domain is specified
domain =
# Default value if no ssh parameter is specified
logbox-ip =
logbox-port =
logbox-user =
logbox-passwd =
# This instance will request other instances of lamp-generic depending on a
# list of countries.
[buildout]
parts =
request-edge
publish-connection-parameter
eggs-directory = ${buildout:eggs-directory}
develop-eggs-directory = ${buildout:develop-eggs-directory}
offline = true
[request-edge]
<= slap-connection
recipe = slapos.cookbook:request.edge
# This magic parameter triggers several requests, one request per country.
name = lamp
return = url backend-url
country-list = $${slap-parameter:country-list}
software-url = $${slap-connection:software-release-url}
software-type = default
config = application-location
config-application-location = $${slap-parameter:application-location}
return = backend-url
[publish-connection-parameter]
recipe = slapos.cookbook:publishsection
section-list = request-edge
[buildout]
parts =
switch_softwaretype
eggs-directory = ${buildout:eggs-directory}
develop-eggs-directory = ${buildout:develop-eggs-directory}
offline = true
[switch_softwaretype]
recipe = slapos.cookbook:softwaretype
default = ${instance-apache-php:output}
edge = ${instance-edge:output}
[buildout]
extends =
../../stack/lamp/buildout.cfg
parts +=
instance-edge
# XXX: switch to ngnix
[instance]
url = ${:_profile_base_location_}/instance.cfg.in
md5sum = 26ac6629a83869140189a85e581e822f
[instance-apache-php]
url = ${:_profile_base_location_}/instance-apache-php.cfg.in
md5sum = fdc849c9f49b9d2fb043bf229d24076b
[instance-edge]
recipe = slapos.recipe.template
url = ${:_profile_base_location_}/instance-edge.cfg.in
output = ${buildout:directory}/instance-edge.cfg
#md5sum = 6b7a6caf44e3a94bed7f89c04003a171
mode = 0644
zimbra-kvm
==========
Introduction
------------
Zimbra single-machine deployment inside of a virtual machine.
Internals
---------
The following ports are reachable from the outside world:
22 -> 2222
443 -> 4443
Others?
For each port, KVM does a NAT redirection from the VM to the local ipv4. Then, 6tunnel is called to redirect it to the outside world using ipv6.
Deployment
----------
To deploy a new Zimbra service, you just need to request a new instance of it,
then connect the the machine using ssh with root:zimbra credentials, reconfigure
Zimbra to use another domain name, and change root password.
Disk Image content
------------------
Ubuntu 12.04, Zimbra install from official packages, 8.0.3
admin password: Cedric de Saint Martin has it.
bind9: http://wiki.zimbra.com/index.php?title=Split_dns
resolv.conf: http://askubuntu.com/questions/30942/why-does-my-resolv-conf-file-get-regenerated-every-time
Todo
----
* SMTP master/slave design implemented
* Reverse proxy for web works
* Automatically download the proper boot disk image.
* Have two virtual disks: one for system/zimbra, one for data.
* Unify smtp frontend and web frontend
[buildout]
extends =
../../component/6tunnel/buildout.cfg
../../component/curl/buildout.cfg
../../component/dash/buildout.cfg
../../component/dcron/buildout.cfg
../../component/gzip/buildout.cfg
../../component/qemu-kvm/buildout.cfg
../../component/logrotate/buildout.cfg
../../component/noVNC/buildout.cfg
../../component/openssl/buildout.cfg
../../stack/slapos.cfg
parts =
template
eggs
[eggs]
recipe = z3c.recipe.scripts
eggs =
${lxml-python:egg}
websockify
slapos.cookbook
slapos.toolbox
[template-kvm]
recipe = slapos.recipe.template
url = ${:_profile_base_location_}/instance-kvm.cfg.in
#md5sum = d4f7203365bacd70ad62f6b6de9f74d4
output = ${buildout:directory}/template-kvm.cfg
mode = 0644
[template]
recipe = slapos.recipe.template
url = ${:_profile_base_location_}/instance.cfg.in
#md5sum = 68788763d23f70f24b9e575871c903a8
output = ${buildout:directory}/template.cfg
mode = 0644
[versions]
# Numpy 1.7.0 doesn't install well
numpy = 1.6.2
[buildout]
extends =
../../component/git/buildout.cfg
common.cfg
parts +=
slapos.cookbook-repository
slapos.toolbox-repository
check-recipe
develop =
${:parts-directory}/slapos.cookbook-repository
${:parts-directory}/slapos.toolbox-repository
[slapos.cookbook-repository]
recipe = slapos.recipe.build:gitclone
repository = http://git.erp5.org/repos/slapos.git
branch = zimbra-kvm
git-executable = ${git:location}/bin/git
[slapos.toolbox-repository]
recipe = slapos.recipe.build:gitclone
repository = http://git.erp5.org/repos/slapos.toolbox.git
branch = master
git-executable = ${git:location}/bin/git
[check-recipe]
recipe = plone.recipe.command
stop-on-error = true
update-command = ${:command}
command =
grep parts ${buildout:develop-eggs-directory}/slapos.cookbook.egg-link &&
grep parts ${buildout:develop-eggs-directory}/slapos.toolbox.egg-link
#############################
#
# Instanciate kvm
#
#############################
[buildout]
parts =
certificate-authority
request-web-frontend
kvm-promise
tunnel-ipv6-kvm-https
tunnel-ipv6-kvm-ssh
tunnel-ipv6-kvm-zimbra-admin
tunnel-ipv6-kvm-smtp
tunnel-ipv6-kvm-smtp-submission
websockify-sighandler
novnc-promise
publish-kvm-connection-information
eggs-directory = ${buildout:eggs-directory}
develop-eggs-directory = ${buildout:develop-eggs-directory}
offline = true
[directory]
recipe = slapos.cookbook:mkdirectory
etc = $${buildout:directory}/etc
bin = $${buildout:directory}/bin
srv = $${buildout:directory}/srv
var = $${buildout:directory}/var
scripts = $${:etc}/run
services = $${:etc}/service
promises = $${:etc}/promise
novnc-conf = $${:etc}/novnc
run = $${:var}/run
ca-dir = $${:srv}/ssl
[create-mac]
recipe = slapos.cookbook:generate.mac
storage-path = $${directory:srv}/mac
[gen-passwd]
recipe = slapos.cookbook:generate.password
storage-path = $${directory:srv}/passwd
bytes = 4
[kvm-instance]
# XXX-Cedric: change "KVM" recipe to simple "create wrappers". No need for this
# Specific code
recipe = slapos.cookbook:zimbra.kvm
vnc-ip = $${slap-network-information:local-ipv4}
vnc-port = 5901
boot-disk-path = $${directory:srv}/boot.qcow2
data-disk-path = $${directory:srv}/virtual.qcow2
data-disk-size = $${slap-parameter:disk-size}
data-disk-type = $${slap-parameter:disk-type}
socket-path = $${directory:var}/qmp_socket
pid-path = $${directory:run}/pid_file
smp-count = $${slap-parameter:cpu-count}
ram-size = $${slap-parameter:ram-size}
disk-type = virtio
mac-address = $${create-mac:mac-address}
runner-path = $${directory:services}/kvm
controller-path = $${directory:scripts}/kvm_controller
shell-path = ${dash:location}/bin/dash
qemu-path = ${kvm:location}/bin/qemu-system-x86_64
qemu-img-path = ${kvm:location}/bin/qemu-img
passwd = $${gen-passwd:passwd}
[kvm-promise]
recipe = slapos.cookbook:check_port_listening
path = $${directory:promises}/vnc_promise
hostname = $${kvm-instance:vnc-ip}
port = $${kvm-instance:vnc-port}
# 6tunnel
# Refers to http://wiki.zimbra.com/wiki/Ports#External_Access
[tunnel-ipv6-kvm-https]
recipe = slapos.cookbook:ipv6toipv4
ipv6 = $${slap-network-information:global-ipv6}
ipv6-port = 443
ipv4 = $${slap-network-information:local-ipv4}
ipv4-port = 443
shell-path = ${dash:location}/bin/dash
6tunnel-path = ${6tunnel:location}/bin/6tunnel
runner-path = $${directory:services}/6tunnel-https
[tunnel-ipv6-kvm-zimbra-admin]
recipe = slapos.cookbook:ipv6toipv4
ipv6 = $${slap-network-information:global-ipv6}
ipv6-port = 7071
ipv4 = $${slap-network-information:local-ipv4}
ipv4-port = 7071
shell-path = ${dash:location}/bin/dash
6tunnel-path = ${6tunnel:location}/bin/6tunnel
runner-path = $${directory:services}/6tunnel-zimbra_admin
[tunnel-ipv6-kvm-ssh]
recipe = slapos.cookbook:ipv6toipv4
ipv6 = $${slap-network-information:global-ipv6}
ipv6-port = 2222
ipv4 = $${slap-network-information:local-ipv4}
ipv4-port = 2222
shell-path = ${dash:location}/bin/dash
6tunnel-path = ${6tunnel:location}/bin/6tunnel
runner-path = $${directory:services}/6tunnel-ssh
[tunnel-ipv6-kvm-smtp]
recipe = slapos.cookbook:ipv6toipv4
ipv6 = $${slap-network-information:global-ipv6}
ipv6-port = 25
ipv4 = $${slap-network-information:local-ipv4}
ipv4-port = 25
shell-path = ${dash:location}/bin/dash
6tunnel-path = ${6tunnel:location}/bin/6tunnel
runner-path = $${directory:services}/6tunnel-smtp
[tunnel-ipv6-kvm-smtp-submission]
recipe = slapos.cookbook:ipv6toipv4
ipv6 = $${slap-network-information:global-ipv6}
ipv6-port = 587
ipv4 = $${slap-network-information:local-ipv4}
ipv4-port = 587
shell-path = ${dash:location}/bin/dash
6tunnel-path = ${6tunnel:location}/bin/6tunnel
runner-path = $${directory:services}/6tunnel-smtp-submission
[novnc-instance]
recipe = slapos.cookbook:novnc
path = $${ca-novnc:executable}
ip = $${slap-network-information:global-ipv6}
port = 6080
vnc-ip = $${kvm-instance:vnc-ip}
vnc-port = $${kvm-instance:vnc-port}
novnc-location = ${noVNC:location}
websockify-path = ${buildout:directory}/bin/websockify
ssl-key-path = $${ca-novnc:key-file}
ssl-cert-path = $${ca-novnc:cert-file}
[websockify-sighandler]
recipe = slapos.cookbook:signalwrapper
wrapper-path = $${directory:services}/websockify
wrapped-path = $${novnc-instance:path}
[certificate-authority]
recipe = slapos.cookbook:certificate_authority
openssl-binary = ${openssl:location}/bin/openssl
ca-dir = $${directory:ca-dir}
requests-directory = $${cadirectory:requests}
wrapper = $${directory:services}/certificate_authority
ca-private = $${cadirectory:private}
ca-certs = $${cadirectory:certs}
ca-newcerts = $${cadirectory:newcerts}
ca-crl = $${cadirectory:crl}
[cadirectory]
recipe = slapos.cookbook:mkdirectory
requests = $${directory:ca-dir}/requests/
private = $${directory:ca-dir}/private/
certs = $${directory:ca-dir}/certs/
newcerts = $${directory:ca-dir}/newcerts/
crl = $${directory:ca-dir}/crl/
[ca-novnc]
<= certificate-authority
recipe = slapos.cookbook:certificate_authority.request
key-file = $${directory:novnc-conf}/novnc.key
cert-file = $${directory:novnc-conf}/novnc.crt
executable = $${directory:bin}/novnc
wrapper = $${directory:bin}/websockify
[novnc-promise]
recipe = slapos.cookbook:check_port_listening
path = $${directory:promises}/novnc_promise
hostname = $${novnc-instance:ip}
port = $${novnc-instance:port}
[kvm-monitor]
recipe = slapos.cookbook:generic.slapmonitor
db-path = $${directory:srv}/slapmonitor_database
[request-slave-frontend]
recipe = slapos.cookbook:requestoptional
software-url = $${slap-parameter:frontend-software-url}
server-url = $${slap-connection:server-url}
key-file = $${slap-connection:key-file}
cert-file = $${slap-connection:cert-file}
computer-id = $${slap-connection:computer-id}
partition-id = $${slap-connection:partition-id}
name = VNC Frontend
software-type = $${slap-parameter:frontend-software-type}
slave = true
config = host port
config-host = $${novnc-instance:ip}
config-port = $${novnc-instance:port}
return = url resource port domainname
sla = instance_guid
sla-instance_guid = $${slap-parameter:frontend-instance-guid}
[request-web-frontend]
<= slap-connection
recipe = slapos.cookbook:requestoptional
name = Web Frontend
# XXX We have hardcoded SR URL here.
software-url = http://git.erp5.org/gitweb/slapos.git/blob_plain/HEAD:/software/apache-frontend/software.cfg
slave = true
config = url custom_domain
config-url = https://[$${tunnel-ipv6-kvm-https:ipv6}]:$${tunnel-ipv6-kvm-https:ipv6-port}/
return = site_url
config-custom_domain = $${slap-parameter:domain}
[publish-kvm-connection-information]
recipe = slapos.cookbook:publish
web-backend-url = https://[$${tunnel-ipv6-kvm-https:ipv6}]:$${tunnel-ipv6-kvm-https:ipv6-port}/
web-url = $${request-web-frontend:connection-site_url}
vnc-backend-url = https://[$${novnc-instance:ip}]:$${novnc-instance:port}/vnc_auto.html?host=[$${novnc-instance:ip}]&port=$${novnc-instance:port}&encrypt=1
vnc-password = $${kvm-instance:passwd}
vnc-url = $${request-slave-frontend:connection-url}/vnc_auto.html?host=$${request-slave-frontend:connection-domainname}&port=$${request-slave-frontend:connection-port}&encrypt=1&path=$${request-slave-frontend:connection-resource}
ssh = ssh root@$${tunnel-ipv6-kvm-ssh:ipv6} -p $${tunnel-ipv6-kvm-ssh:ipv6-port}
[slap-parameter]
# Default values if not specified
frontend-instance-guid =
frontend-software-type = frontend
frontend-software-url = http://git.erp5.org/gitweb/slapos.git/blob_plain/refs/tags/slapos-0.92:/software/kvm/software.cfg
ram-size = 4096
disk-size = 50
disk-type = virtio
cpu-count = 4
domain =
[buildout]
parts =
switch-softwaretype
eggs-directory = ${buildout:eggs-directory}
develop-eggs-directory = ${buildout:develop-eggs-directory}
offline = true
[switch-softwaretype]
recipe = slapos.cookbook:softwaretype
default = ${template-kvm:output}
[slap-connection]
# part to migrate to new - separated words
computer-id = $${slap_connection:computer_id}
partition-id = $${slap_connection:partition_id}
server-url = $${slap_connection:server_url}
software-release-url = $${slap_connection:software_release_url}
key-file = $${slap_connection:key_file}
cert-file = $${slap_connection:cert_file}
[buildout]
extends = common.cfg
[networkcache]
# signature certificates of the following uploaders.
# Romain Courteaud
# Cedric de Saint Martin
# Test Agent
signature-certificate-list =
-----BEGIN CERTIFICATE-----
MIIB4DCCAUkCADANBgkqhkiG9w0BAQsFADA5MQswCQYDVQQGEwJGUjEZMBcGA1UE
CBMQRGVmYXVsdCBQcm92aW5jZTEPMA0GA1UEChMGTmV4ZWRpMB4XDTExMDkxNTA5
MDAwMloXDTEyMDkxNTA5MDAwMlowOTELMAkGA1UEBhMCRlIxGTAXBgNVBAgTEERl
ZmF1bHQgUHJvdmluY2UxDzANBgNVBAoTBk5leGVkaTCBnzANBgkqhkiG9w0BAQEF
AAOBjQAwgYkCgYEApYZv6OstoqNzxG1KI6iE5U4Ts2Xx9lgLeUGAMyfJLyMmRLhw
boKOyJ9Xke4dncoBAyNPokUR6iWOcnPHtMvNOsBFZ2f7VA28em3+E1JRYdeNUEtX
Z0s3HjcouaNAnPfjFTXHYj4um1wOw2cURSPuU5dpzKBbV+/QCb5DLheynisCAwEA
ATANBgkqhkiG9w0BAQsFAAOBgQBCZLbTVdrw3RZlVVMFezSHrhBYKAukTwZrNmJX
mHqi2tN8tNo6FX+wmxUUAf3e8R2Ymbdbn2bfbPpcKQ2fG7PuKGvhwMG3BlF9paEC
q7jdfWO18Zp/BG7tagz0jmmC4y/8akzHsVlruo2+2du2freE8dK746uoMlXlP93g
QUUGLQ==
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIIB9jCCAV+gAwIBAgIJAO4V/jiMoICoMA0GCSqGSIb3DQEBBQUAMBMxETAPBgNV
BAMMCENPTVAtMjMyMCAXDTEyMDIxNjExMTAyM1oYDzIxMTIwMTIzMTExMDIzWjAT
MREwDwYDVQQDDAhDT01QLTIzMjCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA
wi/3Z8W9pUiegUXIk/AiFDQ0UJ4JFAwjqr+HSRUirlUsHHT+8DzH/hfcTDX1I5BB
D1ADk+ydXjMm3OZrQcXjn29OUfM5C+g+oqeMnYQImN0DDQIOcUyr7AJc4xhvuXQ1
P2pJ5NOd3tbd0kexETa1LVhR6EgBC25LyRBRae76qosCAwEAAaNQME4wHQYDVR0O
BBYEFMDmW9aFy1sKTfCpcRkYnP6zUd1cMB8GA1UdIwQYMBaAFMDmW9aFy1sKTfCp
cRkYnP6zUd1cMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEFBQADgYEAskbFizHr
b6d3iIyN+wffxz/V9epbKIZVEGJd/6LrTdLiUfJPec7FaxVCWNyKBlCpINBM7cEV
Gn9t8mdVQflNqOlAMkOlUv1ZugCt9rXYQOV7rrEYJBWirn43BOMn9Flp2nibblby
If1a2ZoqHRxoNo2yTmm7TSYRORWVS+vvfjY=
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIIB9jCCAV+gAwIBAgIJAKRvzcy7OH0UMA0GCSqGSIb3DQEBBQUAMBMxETAPBgNV
BAMMCENPTVAtNzcyMCAXDTEyMDgxMDE1NDI1MVoYDzIxMTIwNzE3MTU0MjUxWjAT
MREwDwYDVQQDDAhDT01QLTc3MjCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA
o7aipd6MbnuGDeR1UJUjuMLQUariAyQ2l2ZDS6TfOwjHiPw/mhzkielgk73kqN7A
sUREx41eTcYCXzTq3WP3xCLE4LxLg1eIhd4nwNHj8H18xR9aP0AGjo4UFl5BOMa1
mwoyBt3VtfGtUmb8whpeJgHhqrPPxLoON+i6fIbXDaUCAwEAAaNQME4wHQYDVR0O
BBYEFEfjy3OopT2lOksKmKBNHTJE2hFlMB8GA1UdIwQYMBaAFEfjy3OopT2lOksK
mKBNHTJE2hFlMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEFBQADgYEAaNRx6YN2
M/p3R8/xS6zvH1EqJ3FFD7XeAQ52WuQnKSREzuw0dsw12ClxjcHiQEFioyTiTtjs
5pW18Ry5Ie7iFK4cQMerZwWPxBodEbAteYlRsI6kePV7Gf735Y1RpuN8qZ2sYL6e
x2IMeSwJ82BpdEI5niXxB+iT0HxhmR+XaMI=
-----END CERTIFICATE-----
[versions]
numpy = 1.6.2
Jinja2 = 2.6
Werkzeug = 0.8.3
apache-libcloud = 0.12.1
async = 0.6.1
buildout-versions = 1.7
gitdb = 0.5.4
hexagonit.recipe.cmmi = 1.6
lxml = 3.1.0
meld3 = 0.6.10
plone.recipe.command = 1.1
pycrypto = 2.6
slapos.cookbook = 0.73.1
slapos.recipe.template = 2.4.2
slapos.toolbox = 0.33.1
smmap = 0.8.2
websockify = 0.3.0
z3c.recipe.scripts = 1.0.1
# Required by:
# slapos.core==0.35.1
# slapos.toolbox==0.33.1
Flask = 0.9
# Required by:
# slapos.toolbox==0.33.1
GitPython = 0.3.2.RC1
# Required by:
# slapos.toolbox==0.33.1
atomize = 0.1.1
# Required by:
# slapos.toolbox==0.33.1
feedparser = 5.1.3
# Required by:
# hexagonit.recipe.cmmi==1.6
hexagonit.recipe.download = 1.6nxd002
# Required by:
# slapos.cookbook==0.73.1
inotifyx = 0.2.0
# Required by:
# slapos.cookbook==0.73.1
netaddr = 0.7.10
# Required by:
# slapos.core==0.35.1
netifaces = 0.8
# Required by:
# slapos.toolbox==0.33.1
paramiko = 1.10.0
# Required by:
# slapos.toolbox==0.33.1
psutil = 0.6.1
# Required by:
# slapos.core==0.35.1
pyflakes = 0.6.1
# Required by:
# slapos.cookbook==0.73.1
pytz = 2012j
# Required by:
# slapos.cookbook==0.73.1
# slapos.core==0.35.1
# slapos.toolbox==0.33.1
setuptools = 0.6c12dev-r88846
# Required by:
# slapos.cookbook==0.73.1
# slapos.toolbox==0.33.1
slapos.core = 0.35.1
# Required by:
# slapos.core==0.35.1
supervisor = 3.0b1
# Required by:
# slapos.core==0.35.1
unittest2 = 0.5.1
# Required by:
# slapos.cookbook==0.73.1
# slapos.toolbox==0.33.1
xml-marshaller = 0.9.7
# Required by:
# slapos.core==0.35.1
zope.interface = 4.0.5
\ No newline at end of file
...@@ -297,6 +297,7 @@ inotifyx = 0.2.0 ...@@ -297,6 +297,7 @@ inotifyx = 0.2.0
lxml = 3.1.0 lxml = 3.1.0
meld3 = 0.6.10 meld3 = 0.6.10
netaddr = 0.7.10 netaddr = 0.7.10
plone.recipe.command = 1.1
pycrypto = 2.6 pycrypto = 2.6
pytz = 2012j pytz = 2012j
rdiff-backup = 1.0.5 rdiff-backup = 1.0.5
......
...@@ -60,6 +60,7 @@ recipe = zc.recipe.egg ...@@ -60,6 +60,7 @@ recipe = zc.recipe.egg
eggs = eggs =
${lxml-python:egg} ${lxml-python:egg}
slapos.cookbook slapos.cookbook
hexagonit.recipe.download
inotifyx inotifyx
netaddr netaddr
slapos.core slapos.core
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment