Commit fa940d0e authored by Boxiang Sun's avatar Boxiang Sun

misc things

parent ee0352eb
......@@ -7,8 +7,8 @@ parts =
[cmake]
recipe = slapos.recipe.cmmi
url = http://www.cmake.org/files/v2.8/cmake-2.8.12.1.tar.gz
md5sum = 9d38cd4e2c94c3cea97d0e2924814acc
url = https://cmake.org/files/v3.6/cmake-3.6.2.tar.gz
md5sum = 139d7affdd4e8ab1edfc9f4322d69e43
environment =
CMAKE_INCLUDE_PATH=${ncurses:location}/include
CMAKE_LIBRARY_PATH=${ncurses:location}/lib
# GNU C Compiler
# Mostly required to support languages different than C or C++
[buildout]
extends =
../gmp/buildout.cfg
../mpc/buildout.cfg
../mpfr/buildout.cfg
../perl/buildout.cfg
../tar/buildout.cfg
../xz-utils/buildout.cfg
parts =
gcc-4.9
[isl-0.14]
recipe = slapos.recipe.cmmi
url = ftp://gcc.gnu.org/pub/gcc/infrastructure/isl-0.14.tar.bz2
md5sum = acd347243fca5609e3df37dba47fd0bb
configure-options =
--with-gmp-prefix=${gmp:location}
--disable-static
environment =
LDFLAGS=-Wl,-rpath=${gmp:location}/lib
[gcc-common-4.9]
recipe = slapos.recipe.cmmi
url = http://ftp.gnu.org/gnu/gcc/gcc-4.9.4/gcc-4.9.4.tar.bz2
md5sum = 87c24a4090c1577ba817ec6882602491
# make install does not work when several core are used
make-targets = install -j1
[gcc-4.9]
<= gcc-common-4.9
configure-options =
--disable-bootstrap
--disable-multilib
--with-gmp=${gmp:location}
--with-mpfr=${mpfr:location}
--with-mpc=${mpc:location}
--enable-languages="c,c++"
--with-isl=${isl-0.14:location}
environment =
LDFLAGS=-Wl,-rpath=${gmp:location}/lib -Wl,-rpath=${isl-0.14:location}/lib -Wl,-rpath=${mpc:location}/lib -Wl,-rpath=${mpfr:location}/lib
PATH=${perl:location}/bin:${tar:location}/bin:%(PATH)s
[gcc-minimal-4.9]
<= gcc-common-4.9
configure-options =
--disable-bootstrap
--disable-multilib
--with-gmp=${gmp:location}
--with-mpfr=${mpfr:location}
--with-mpc=${mpc:location}
--enable-languages=c
--without-isl
--without-cloog
environment =
LDFLAGS=-Wl,-rpath=${gmp:location}/lib -Wl,-rpath=${mpc:location}/lib -Wl,-rpath=${mpfr:location}/lib
PATH=${perl:location}/bin:${tar:location}/bin:%(PATH)s
[gcc-fortran-4.9]
<= gcc-common-4.9
configure-options =
--disable-bootstrap
--disable-multilib
--with-gmp=${gmp:location}
--with-mpfr=${mpfr:location}
--with-mpc=${mpc:location}
--enable-languages="c,c++,fortran"
--with-isl=${isl-0.14:location}
environment =
LDFLAGS=-Wl,-rpath=${gmp:location}/lib -Wl,-rpath=${isl-0.14:location}/lib -Wl,-rpath=${mpc:location}/lib -Wl,-rpath=${mpfr:location}/lib
PATH=${perl:location}/bin:${tar:location}/bin:%(PATH)s
......@@ -3,6 +3,8 @@
[buildout]
extends =
../gmp/buildout.cfg
../mpc/buildout.cfg
../mpfr/buildout.cfg
../perl/buildout.cfg
../tar/buildout.cfg
../xz-utils/buildout.cfg
......@@ -10,28 +12,6 @@ extends =
parts =
gcc
[mpfr]
recipe = slapos.recipe.cmmi
url = http://ftp.gnu.org/gnu/mpfr/mpfr-3.1.3.tar.xz
md5sum = 6969398cd2fbc56a6af570b5273c56a9
configure-options =
--with-gmp=${gmp:location}
--disable-static
environment =
PATH=${xz-utils:location}/bin:%(PATH)s
LDFLAGS=-Wl,-rpath=${gmp:location}/lib
[mpc]
recipe = slapos.recipe.cmmi
url = http://ftp.gnu.org/gnu/mpc/mpc-1.0.3.tar.gz
md5sum = d6a1d5f8ddea3abd2cc3e98f58352d26
configure-options =
--with-gmp=${gmp:location}
--with-mpfr=${mpfr:location}
--disable-static
environment =
LDFLAGS=-Wl,-rpath=${gmp:location}/lib -Wl,-rpath=${mpfr:location}/lib
[isl]
recipe = slapos.recipe.cmmi
url = ftp://gcc.gnu.org/pub/gcc/infrastructure/isl-0.16.1.tar.bz2
......
[buildout]
# Note: here are just part of gdb dependencies. For the dependencies which
# debian used to build gdb, please refer:
# ftp://ftp.fr.debian.org/debian/pool/main/g/gdb/gdb_7.11.1-2.dsc
extends =
../bzip2/buildout.cfg
../autoconf/buildout.cfg
../libtool/buildout.cfg
../gettext/buildout.cfg
../bison/buildout.cfg
../flex/buildout.cfg
../libexpat/buildout.cfg
../ncurses/buildout.cfg
../readline/buildout.cfg
../zlib/buildout.cfg
../xz-utils/buildout.cfg
../gmp/buildout.cfg
../mpfr/buildout.cfg
../mpc/buildout.cfg
../python-2.7/buildout.cfg
parts =
gdb
[isl]
recipe = slapos.recipe.cmmi
url = ftp://gcc.gnu.org/pub/gcc/infrastructure/isl-0.15.tar.bz2
md5sum = 8428efbbc6f6e2810ce5c1ba73ecf98c
configure-options =
--with-gmp-prefix=${gmp:location}
--disable-static
environment =
LDFLAGS=-Wl,-rpath=${gmp:location}/lib
[gdb]
recipe = slapos.recipe.cmmi
url = ftp://ftp.gnu.org/gnu/gdb/gdb-7.11.1.tar.xz
md5sum = 5aa71522e488e358243917967db87476
configure-options =
--with-python=${python2.7:location}/bin/python2.7
environment =
PATH = ${libtool:location}/bin:${xz-utils:location}/bin:%(PATH)s
CPPFLAGS = -I${python2.7:location}/include/python2.7 -I${bzip2:location}/include -I${gmp:location}/include -I${mpc:location}/include -I${mpfr:location}/include -I${isl:location}/include -I{zlib:location}/include -I${readline:location}/include -I${libexpat:location}/include -I${libffi:location}/include -I${ncurses:location}/include -I${ncurses:location}/include/ncursesw -I${bzip2:location}/include -I${gettext:location}/include
LDFLAGS = -L${python2.7:location}/lib -L${bzip2:location}/lib -L${gettext:location}/lib -L${gmp:location}/lib -L${mpfr:location}/lib -L${isl:location}/lib -L${mpc:location}/lib -L${zlib:location}/lib -L${readline:location}/lib -L${libexpat:location}/lib -L${libffi:location}/lib -L${ncurses:location}/lib
LD_LIBRARY_PATH=${ncurses:location}/lib:$LD_LIBRARY_PATH
\ No newline at end of file
......@@ -3,7 +3,7 @@ parts = libevent
[libevent]
recipe = slapos.recipe.cmmi
url = http://www.monkey.org/~provos/libevent-1.4.13-stable.tar.gz
md5sum = 0b3ea18c634072d12b3c1ee734263664
url = https://github.com/downloads/libevent/libevent/libevent-2.0.21-stable.tar.gz
# md5sum = 0b3ea18c634072d12b3c1ee734263664
configure-options =
--disable-static
[buildout]
extends =
../cmake/buildout.cfg
parts =
llvm-make
[llvm]
recipe = hexagonit.recipe.download
url = http://llvm.org/releases/3.5.2/llvm-3.5.2.src.tar.xz
md5sum = f5a4dc595f7e8bd23397684d0906d014
destination = ${buildout:parts-directory}
path = ${buildout:parts-directory}/llvm-3.5.2.src
[clang]
recipe = hexagonit.recipe.download
url = http://llvm.org/releases/3.5.2/cfe-3.5.2.src.tar.xz
filename = cfe-3.5.2.src.tar.xz
md5sum = aba5d02251bf7845a2013d6bb0702ac7
destination = ${llvm:path}/tools
path = ${llvm:path}/tools/cfe-3.5.2.src
[llvm-cmake]
recipe = slapos.recipe.cmmi
# clang have to put in llvm/tools/clang dir
# and cannot build in place. So use cmake undocumented feature(-B, -H)
# to specify the source code path and build path
configure-command = $ [ -d ${:tools-clang} ] && rm -R ${:tools-clang} ||
mv ${clang:path} ${:tools-clang} && \
${cmake:location}/bin/cmake \
-B${buildout:parts-directory}/llvm-cmake \
-H${llvm:path} \
-DCMAKE_INSTALL_PREFIX=${:location}
tools-clang = ${llvm:path}/tools/clang
path = ${buildout:parts-directory}/llvm-cmake
location = ${buildout:parts-directory}/llvm
[llvm-make]
recipe = slapos.recipe.cmmi
path = ${llvm-cmake:path}
\ No newline at end of file
[buildout]
extends =
../gmp/buildout.cfg
../mpfr/buildout.cfg
parts =
mpc
[mpc]
recipe = slapos.recipe.cmmi
url = http://ftp.gnu.org/gnu/mpc/mpc-1.0.3.tar.gz
md5sum = d6a1d5f8ddea3abd2cc3e98f58352d26
configure-options =
--with-gmp=${gmp:location}
--with-mpfr=${mpfr:location}
--disable-static
environment =
LDFLAGS=-Wl,-rpath=${gmp:location}/lib -Wl,-rpath=${mpfr:location}/lib
\ No newline at end of file
[buildout]
extends =
../gmp/buildout.cfg
../xz-utils/buildout.cfg
[mpfr]
recipe = slapos.recipe.cmmi
url = http://ftp.gnu.org/gnu/mpfr/mpfr-3.1.3.tar.xz
md5sum = 6969398cd2fbc56a6af570b5273c56a9
configure-options =
--with-gmp=${gmp:location}
--disable-static
environment =
PATH=${xz-utils:location}/bin:%(PATH)s
LDFLAGS=-Wl,-rpath=${gmp:location}/lib
\ No newline at end of file
[buildout]
parts +=
ninja
[ninja-download]
recipe = hexagonit.recipe.download
ignore-existing = true
version = v1.7.1
url = https://github.com/ninja-build/ninja/archive/${:version}.tar.gz
destination = ${buildout:parts-directory}
path = ${buildout:parts-directory}/ninja-1.7.1
[ninja]
recipe = plone.recipe.command
path = ${ninja-download:path}
command = (cd ${:path} && ./configure.py --bootstrap)
update-command = command
\ No newline at end of file
[buildout]
extends =
../cmake/buildout.cfg
../ninja/buildout.cfg
../git/buildout.cfg
../freetype/buildout.cfg
parts +=
depot_tools
[depot_tools]
recipe = plone.recipe.command
location = ${buildout:directory}/parts/depot_tools
depot_tools-repository = https://chromium.googlesource.com/chromium/tools/depot_tools.git
git-binary = ${git:location}/bin/git
command = ([ -d ${:location} ] && ls || ${:git-binary} clone ${:depot-repository} ${:location})
update-command = command
\ No newline at end of file
[buildout]
extends =
../libevent/buildout.cfg
../ncurses/buildout.cfg
parts =
tmux
[tmux]
recipe = slapos.recipe.cmmi
url = https://github.com/tmux/tmux/releases/download/2.0/tmux-2.0.tar.gz
md5sum = 9fb6b443392c3978da5d599f1e814eaa
environment =
CFLAGS=-I${ncurses:location}/include -I${libevent:location}/include/
LDFLAGS=-L${ncurses:location}/lib/ -L${libevent:location}/lib/ -Wl,-rpath=${ncurses:location}/lib/ -Wl,-rpath=${libevent:location}/lib/
configure-options =
--prefix=${buildout:parts-directory}/${:_buildout_section_name_}
Available ``software-type`` values
==================================
- ``default``
Recommended for production use.
- ``create-erp5-site``
Automated creation of ERP5Site instance, for easy deployment.
Usage in production discouraged due to the increased risk of data loss.
Notes
=====
This software release is not intended to be accessed directly, but through a
front-end instance which is expected to contains the RewriteRules_ (or
equivalent) needed to relocate Zope's urls via its VirtualHostMonster_. See the
``frontend`` erp5 instance parameter.
Included cloudooo partition is **deprecated**. It is not recommended for
intensive usage. See the ``cloudooo`` Software Release to setup a cloudooo
cluster, more suitable for intensive usage.
Port ranges
===========
This software release assigns the following port ranges by default:
==================== ==========
Partition type Port range
==================== ==========
memcached-persistent 2000-2009
memcached-volatile 2010-2019
cloudooo 2020-2024
smtp 2025-2029
neo (admin & master) 2050-2051
mariadb 2099
zeo 2100-2149
balancer 2150-2199
zope 2200-*
jupyter 8888
==================== ==========
Non-zope partitions are unique in an ERP5 cluster, so you shouldn't have to
care about them as a user (but a Software Release developer needs to know
them).
Zope partitions should be assigned port ranges starting at 2200, incrementing
by some value which depends on how many zope process you want per partition
(see the ``port-base`` parameter in ``zope-partition-dict``).
Notes to the Software Release developper: These ranges are not strictly
defined. Not each port is actually used so one may reduce alread-assigned
ranges if needed (ex: memcached partitions use actually fewer ports). There
should be enough room for evolution (as between smtp and mariadb types). It is
important to not allocate any port after 2200 as user may have assigned ports
to his zope processes.
.. _RewriteRules: http://httpd.apache.org/docs/current/en/mod/mod_rewrite.html#rewriterule
.. _VirtualHostMonster: http://docs.zope.org/zope2/zope2book/VirtualHosting.html
{
"$schema": "http://json-schema.org/draft-04/schema#",
"required": ["tcpv4-port"],
"properties": {
"tcpv4-port": {
"allOf": [{
"$ref": "#/definitions/tcpv4port"
}, {
"description": "Start allocating ports at this value, going upward"
}]
}
}
}
{
"$schema": "http://json-schema.org/draft-04/schema#",
"description": "Parameters to instantiate ERP5",
"additionalProperties": false,
"properties": {
"sla-dict": {
"description": "Where to request instances. Each key is a query string for criterions (e.g. \"computer_guid=foo\"), and each value is a list of partition references (note: Zope partitions reference must be prefixed with \"zope-\").",
"additionalProperties": {
"type": "array",
"items": { "type": "string" },
"uniqueItems": true
},
"type": "object"
},
"site-id": {
"description": "ERP5Site object's id",
"default": "erp5",
"type": "string"
},
"timezone": {
"description": "Zope's timezone. Possible values are determined by host's libc, and typically come from a separate package (tzdata, ...)",
"default": "UTC",
"type": "string"
},
"deadlock-debugger-password": {
"description": "Password for /manage_debug_threads",
"type": "string"
},
"inituser-login": {
"description": "Login of the initial/rescue user",
"default": "zope",
"type": "string"
},
"inituser-password": {
"description": "Password of the initial/rescue user",
"type": "string"
},
"developer-list": {
"description": "List of logins which should get the Developper role (required to modify portal_components' content), defaulting to inituser-login's value",
"items": {
"pattern": "^\\S+$",
"type": "string"
},
"uniqueItems": true,
"type": "array"
},
"hostalias-dict": {
"description": "Hostname-to-hostname mapping",
"default": {},
"additionalProperties": {
"description": "A hostname to which current entry will resolve",
"type": "string"
},
"type": "object"
},
"hosts-dict": {
"description": "Host entries to be used in addition to and/or overriding auto-generated ones (erp5-catalog-0, erp5-cloudooo, erp5-memcached-persistent, erp5-memcached-volatile and erp5-smtp)",
"patternProperties": {
".*": {
"description": "An IP or domain name to which current entry will resolve",
"type": "string"
}
},
"type": "object"
},
"frontend": {
"description": "Front-end slave instance request parameters",
"properties": {
"software-url": {
"description": "Front-end's software type. If this parameter is empty, no front-end instance is requested. Else, sla-dict must specify 'frontend' which is a special value matching all frontends (e.g. {\"instance_guid=bar\": [\"frontend\"]}).",
"default": "",
"type": "string"
},
"domain": {
"description": "The domain name to request front-end to respond as.",
"default": "",
"type": "string"
},
"software-type": {
"description": "Request a front-end slave instance of this software type.",
"default": "RootSoftwareInstance",
"type": "object"
}
},
"type": "object"
},
"zope-partition-dict": {
"description": "Zope layout definition",
"default": {"1": {}},
"patternProperties": {
".*": {
"additionalProperties": false,
"properties": {
"family": {
"description": "The family this partition is part of. For example: 'public', 'admin', 'backoffice', 'web-service'... Each family gets its own balancer entry. It has no special meaning for the system.",
"default": "default",
"type": "string"
},
"instance-count": {
"description": "Number of Zopes to setup on this partition",
"default": 1,
"type": "integer"
},
"thread-amount": {
"description": "Number of worker threads for each created Zope process",
"default": 4,
"type": "integer"
},
"timerserver-interval": {
"description": "Timerserver tick perdiod, in seconds, or 0 to disable",
"default": 5,
"type": "integer"
},
"webdav": {
"description": "Serve webdav queries, implies timerserver-interval=0 (disabled). Mixing webdav and non-webdav nodes in a single family will give unspecified results.",
"default": false,
"type": "boolean"
},
"longrequest-logger-interval": {
"description": "Period, in seconds, with which LongRequestLogger polls worker thread stack traces, or -1 to disable",
"default": -1,
"type": "integer"
},
"longrequest-logger-timeout": {
"description": "Transaction duration after which LongRequestLogger will start logging its stack trace, in seconds",
"default": 1,
"type": "integer"
},
"port-base": {
"allOf": [{
"$ref": "#/definitions/tcpv4port"
}, {
"description": "Start allocating ports at this value. Useful if one needs to make several partitions share the same port range (ie, several partitions bound to a single address)",
"default": 2200
}]
}
},
"type": "object"
}
},
"type": "object"
},
"kumofs": {
"description": "Persistent memcached service",
"additionalProperties": {
"$ref": "./instance-kumofs-schema.json#/properties"
},
"type": "object"
},
"memcached": {
"description": "Volatile memcached service",
"additionalProperties": {
"$ref": "./instance-kumofs-schema.json#/properties"
},
"type": "object"
},
"cloudooo": {
"description": "Format conversion service",
"additionalProperties": {
"$ref": "./instance-cloudooo-schema.json#/properties"
},
"type": "object"
},
"mariadb": {
"description": "Relational database service",
"additionalProperties": {
"$ref": "./instance-mariadb-schema.json#/properties"
},
"type": "object"
},
"zodb-zeo": {
"description": "Common settings ZEO servers",
"properties": {
"tcpv4-port": {
"allOf": [{
"$ref": "#/definitions/tcpv4port"
}, {
"description": "Start allocating ports at this value, going upward"
}]
},
"backup-periodicity": {
"description": "When to backup, specified in the same format as for systemd.time(7) calendar events (years & seconds not supported, DoW & DoM can not be combined). Enter 'never' to disable backups.",
"default": "daily",
"type": "string"
},
"tidstorage-repozo-path": {
"description": "Directory for backup timestamp and tidstorage status files.",
"default": "~/srv/backup/tidstorage",
"type": "string"
}
},
"type": "object"
},
"zodb": {
"description": "Zope Object DataBase mountpoints. See https://github.com/zopefoundation/ZODB/blob/3.10/src/ZODB/component.xml for extra options.",
"items": {
"required": ["type"],
"properties": {
"name": {
"description": "Database name",
"default": "main",
"type": "string"
},
"mount-point": {
"description": "Mount point",
"default": "/",
"type": "string"
},
"type": {
"description": "Storage type",
"enum": ["zeo", "neo"],
"type": "string"
},
"server": {
"description": "Instantiate a server. If missing, 'storage-dict' must contain the necessary properties to mount the ZODB. For ZEO, the partition reference is 'zodb'. For NEO, they are 'neo-0', 'neo-1', ...",
"anyOf": [
{"$ref": "./instance-zeo-schema.json"},
{"$ref": "../neoppod/instance-neo-input-schema.json"}
]
},
"storage-dict": {
"description": "Storage configuration. For NEO, 'logfile' is automatically set (see https://lab.nexedi.com/nexedi/neoppod/blob/master/neo/client/component.xml for other settings).",
"properties": {
"ssl": {
"description": "For external NEO. Pass false if you want to disable SSL or pass custom values for ca/cert/key.",
"default": true,
"type": "boolean"
}
},
"additionalProperties": {"type": "string"},
"type": "object"
}
},
"additionalProperties": {"type": "string"},
"type": "object"
},
"type": "array"
},
"jupyter": {
"description": "Jupyter slave instance parameters",
"properties": {
"enable": {
"description": "Whether to enable creation of associated slave Jupyter instance",
"default": false,
"type": "boolean"
},
"zope-family": {
"description": "Zope family to connect Jupyter to by default",
"default": "<first instantiated Zope family>",
"type": "string"
}
},
"type": "object"
}
}
}
{
"$schema": "http://json-schema.org/draft-04/schema#",
"description": "Values returned by ERP5 instantiation",
"additionalProperties": false,
"properties": {
"hosts-dict": {
"description": "Hosts mapping, including auto-generated entries",
"patternProperties": {
".*": {
"description": "IP current entry resolves to",
"type": "string"
}
},
"type": "object"
},
"site-id": {
"description": "Chosen ERP5Site object identifier",
"type": "string"
},
"inituser-login": {
"description": "Initial user login",
"type": "string"
},
"inituser-password": {
"description": "Initial user password",
"type": "string"
},
"deadlock-debugger-password": {
"description": "Deadlock debugger password",
"type": "string"
},
"memcached-persistent-url": {
"description": "Persistent memcached access information",
"pattern": "^memcached://",
"type": "string"
},
"memcached-volatile-url": {
"description": "Volatile memcached access information",
"pattern": "^memcached://",
"type": "string"
},
"cloudooo-url": {
"description": "Conversion service access information - DEPRECATED",
"pattern": "^cloudooo://",
"type": "string"
},
"mariadb-database-list": {
"description": "Relational database access information",
"items": {
"pattern": "^mysql://",
"type": "string"
},
"uniqueItems": true,
"type": "array"
},
"mariadb-test-database-list": {
"description": "Relational database access information",
"items": {
"pattern": "^mysql://",
"type": "string"
},
"uniqueItems": true,
"type": "array"
},
"neo-masters": {
"$ref": "../neoppod/instance-neo-output-schema.json#/properties/masters"
},
"neo-admins": {
"$ref": "../neoppod/instance-neo-output-schema.json#/properties/admins"
},
"jupyter-url": {
"description": "Jupyter notebook web UI access information",
"pattern": "^https://",
"type": "string"
}
},
"patternProperties": {
"family-.*": {
"description": "Zope family access information",
"pattern": "^https://",
"type": "string"
}
},
"type": "object"
}
{
"$schema": "http://json-schema.org/draft-04/schema#",
"required": ["tcpv4-port"],
"properties": {
"tcpv4-port": {
"allOf": [{
"$ref": "#/definitions/tcpv4port"
}, {
"description": "Start allocating ports at this value, going upward"
}]
},
"ram-storage-size": {
"description": "If 0 use disk storage, otherwise use ram and limit data size to this many megabytes",
"default": 0,
"type": "integer"
}
}
}
{
"$schema": "http://json-schema.org/draft-04/schema#",
"required": ["tcpv4-port"],
"properties": {
"tcpv4-port": {
"allOf": [{
"$ref": "#/definitions/tcpv4port"
}, {
"description": "Start allocating ports at this value, going downward"
}]
},
"database-list": {
"description": "Databases to create and respective user credentials getting all privileges on it",
"default": [{
"name": "erp5",
"user": "user",
"password": "insecure"
}],
"minItems": 1,
"items": {
"required": ["name", "user", "password"],
"properties": {
"name": {
"description": "Database name",
"type": "string"
},
"user": {
"description": "User name",
"type": "string"
},
"password": {
"description": "User password",
"type": "string"
}
},
"type": "object"
},
"type": "array"
},
"test-database-amount": {
"description": "The number of test databases to create, adding auto-generated entries to database-list",
"default": 1,
"minimum": 0,
"type": "integer"
},
"catalog-backup": {
"description": "Backup control knobs",
"properties": {
"full-retention-days": {
"description": "How many days full backups must be retained, -1 meaning full backups are disabled and 0 meaning no expiration",
"default": 7,
"minimum": -1,
"type": "integer"
},
"incremental-retention-days": {
"description": "How many days incremental backups (binlogs) must be retained, -1 meaning incremental backups are disabled and 0 meaning no expiration, defaulting to full-retention-days' value",
"minimum": -1,
"type": "integer"
}
},
"type": "object"
},
"backup-periodicity": {
"description": "When to backup, specified in the same format as for systemd.time(7) calendar events (years & seconds not supported, DoW & DoM can not be combined).",
"default": "daily",
"type": "string"
},
"innodb-buffer-pool-size": {
"description": "See MariaDB documentation on innodb_buffer_pool_size",
"minimum": 0,
"type": "integer"
},
"innodb-log-file-size": {
"description": "See MariaDB documentation on innodb_log_file_size",
"minimum": 0,
"type": "integer"
},
"innodb-log-buffer-size": {
"description": "See MariaDB documentation on innodb_log_buffer_size",
"minimum": 0,
"type": "integer"
},
"long-query-time": {
"description": "Number of seconds above which long queries are logged",
"minimum": 0,
"default": 1,
"type": "number"
},
"relaxed-writes": {
"description": "When enabled, sets innodb_flush_log_at_trx_commit = 0, innodb_flush_method = nosync, innodb_doublewrite = 0 and sync_frm = 0 - RTFM, those options are dangerous",
"default": false,
"type": "boolean"
},
"ssl": {
"description": "Enable and define SSL support for network connections",
"default": {},
"properties": {
"ca-crt": {
"description": "Certificate Authority's certificate, in PEM format",
"type": "string"
},
"crt": {
"description": "Server's certificate, in PEM format (mandatory to enable SSL support)",
"type": "string"
},
"key": {
"description": "Server's key, in PEM format (mandatory to enable SSL support)",
"type": "string"
},
"crl": {
"description": "Server's certificate revocation list, in PEM format",
"type": "string"
},
"cipher": {
"description": "Permissible cipher specifications, separated by colons",
"type": "string"
}
},
"type": "object"
}
}
}
{
"$schema": "http://json-schema.org/draft-04/schema#",
"extends": "./schema-definitions.json#",
"required": ["tcpv4-port"],
"properties": {
"tcpv4-port": {
"allOf": [{
"$ref": "#/definitions/tcpv4port"
}, {
"description": "Start allocating ports at this value, going upward"
}]
},
"postmaster": {
"description": "Mail address to send technical mails to. Non-empty value required for smptd relay service to be deployed. Values will be put in alias-dict as 'postmaster' key (alias-dict takes precedence)",
"default": "",
"type": "string"
},
"alias-dict": {
"description": "Mail alias support",
"default": {},
"patternProperties": {
".*": {
"description": "List of addresses alias expands to",
"type": "array"
}
},
"type": "object"
},
"relay": {
"description": "Forward outgoing mails to a specific relay. If enabled, relay must support TLS-encrypted SASL authentication.",
"dependencies": {
"host": ["sasl-credential"]
},
"properties": {
"host": {
"description": "Host name or address of relay, with optional port (ex: '[example.com]:submissionu'). Enclosing hostname with [] prevents MX lookup.",
"type": "string"
},
"sasl-credential": {
"description": "SASL credential, in the login:password form",
"type": "string"
}
},
"default": {},
"type": "object"
},
"divert": {
"description": "Intercept all mails and send them to given addresses instead of original recipient",
"type": "array",
"items": {
"type": "string"
},
"uniqueItems": true
}
}
}
{
"$schema": "http://json-schema.org/draft-04/schema#",
"additionalProperties": false,
"properties": {
"backup": {
"description": "'%(backup)s' is expanded to partition's ZODB backup path (typically 'srv/backup/zodb'), and %(name)s with the export id",
"default": "%(backup)s/%(name)s",
"type": "string"
},
"family": {
"description": "Opaque name used to regroup/separate mountpoints under different ZEO processes (must be valid as a file name and as a ConfigParser section name)",
"default": "default",
"pattern": "^[^<>:\"/\\|?*\\]\\[ ]*$",
"type": "string"
},
"path": {
"description": "FileStorage file path, '%(zodb)s' occurrences are replaced with the path to partition's srv/zodb directory, and %(name)s with the export id",
"default": "%(zodb)s/%(name)s.fs",
"type": "string"
}
},
"type": "object"
}
# This file is for building ERP5 software release using erp5-component
# branch.
[buildout]
extends =
software.cfg
[slapos.cookbook-repository]
branch = erp5-component
[erp5]
branch = erp5-component
[buildout]
extends =
../../stack/erp5/buildout.cfg
{
"name": "ERP5",
"description": "ERP5, Open-Source ERP",
"serialisation": "json-in-xml",
"software-type": {
"default": {
"title": "Default",
"description": "No automated database modification (ERP5Site is not automatically created).",
"request": "instance-erp5-input-schema.json",
"response": "instance-erp5-output-schema.json",
"index": 0
},
"create-erp5-site": {
"title": "Create ERP5 Site",
"description": "Automated ERP5Site creation on instanciation when ZODB is found empty.",
"request": "instance-erp5-input-schema.json",
"response": "instance-erp5-output-schema.json",
"index": 1
}
}
}
[buildout]
eggs-directory = ${buildout:eggs-directory}
develop-eggs-directory = ${buildout:develop-eggs-directory}
offline = true
extends = ${monitor2-template:rendered}
parts =
testnode
shell
shellinabox
certificate-authority
ca-shellinabox
ca-httpd
monitor-base
monitor-publish
[monitor-publish]
recipe = slapos.cookbook:publish
url = http://[$${shellinabox:ipv6}]:$${shellinabox:port}/
password = $${pwgen:passwd}
[pwgen]
recipe = slapos.cookbook:generate.password
storage-path = $${buildout:directory}/.password
[testnode]
recipe = slapos.cookbook:erp5testnode
slapos-directory = $${directory:slapos}
working-directory = $${directory:testnode}
test-suite-directory = $${directory:test-suite}
proxy-host = $${slap-network-information:local-ipv4}
proxy-port = 5000
log-directory = $${directory:log}
srv-directory = $${rootdirectory:srv}
software-directory = $${directory:software}
run-directory = $${directory:run}
test-node-title = $${slap-parameter:test-node-title}
node-quantity = $${slap-parameter:node-quantity}
ipv4-address = $${slap-network-information:local-ipv4}
ipv6-address = $${slap-network-information:global-ipv6}
test-suite-master-url = $${slap-parameter:test-suite-master-url}
instance-dict = $${slap-parameter:instance-dict}
software-path-list = $${slap-parameter:software-path-list}
git-binary = ${git:location}/bin/git
slapos-binary = ${buildout:bin-directory}/slapos
testnode = ${buildout:bin-directory}/testnode
zip-binary = ${zip:location}/bin/zip
httpd-pid-file = $${basedirectory:run}/httpd.pid
httpd-lock-file = $${basedirectory:run}/httpd.lock
httpd-conf-file = $${rootdirectory:etc}/httpd.conf
httpd-wrapper = $${rootdirectory:bin}/httpd
httpd-port = 9080
httpd-software-access-port = 9081
httpd-ip = $${slap-network-information:global-ipv6}
httpd-log-directory = $${basedirectory:log}
httpd-software-directory = $${directory:software}
httpd-cert-file = $${rootdirectory:etc}/httpd-public.crt
httpd-key-file = $${rootdirectory:etc}/httpd-private.key
configuration-file = $${rootdirectory:etc}/erp5testnode.cfg
log-file = $${basedirectory:log}/erp5testnode.log
wrapper = $${basedirectory:services}/erp5testnode
# Binaries
apache-binary = ${apache:location}/bin/httpd
apache-modules-dir = ${apache:location}/modules
apache-mime-file = ${apache:location}/conf/mime.types
apache-htpasswd = ${apache:location}/bin/htpasswd
[shell]
recipe = slapos.cookbook:shell
wrapper = $${rootdirectory:bin}/sh
shell = ${busybox:location}/bin/sh
home = $${buildout:directory}
ps1 = "\\w> "
path =
${busybox:location}/bin/
${busybox:location}/usr/bin/
${git:location}/bin/
${python2.7:location}/bin/
${buildout:bin-directory}/
${busybox:location}/sbin/
${busybox:location}/usr/sbin/
[shellinabox]
recipe = slapos.cookbook:shellinabox
ipv6 = $${slap-network-information:global-ipv6}
port = 8080
shell = $${shell:wrapper}
wrapper = $${rootdirectory:bin}/shellinaboxd
shellinabox-binary = ${shellinabox:location}/bin/shellinaboxd
password = $${pwgen:passwd}
directory = $${buildout:directory}/
login-shell = $${rootdirectory:bin}/login
certificate-directory = $${directory:shellinabox}
cert-file = $${directory:shellinabox}/public.crt
key-file = $${directory:shellinabox}/private.key
[certificate-authority]
recipe = slapos.cookbook:certificate_authority
openssl-binary = ${openssl:location}/bin/openssl
ca-dir = $${directory:ca-dir}
requests-directory = $${cadirectory:requests}
wrapper = $${basedirectory:services}/ca
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-shellinabox]
<= certificate-authority
recipe = slapos.cookbook:certificate_authority.request
executable = $${shellinabox:wrapper}
wrapper = $${basedirectory:services}/shellinaboxd
key-file = $${shellinabox:key-file}
cert-file = $${shellinabox:cert-file}
[ca-httpd]
<= certificate-authority
recipe = slapos.cookbook:certificate_authority.request
executable = $${testnode:httpd-wrapper}
wrapper = $${basedirectory:services}/httpd
key-file = $${testnode:httpd-key-file}
cert-file = $${testnode:httpd-cert-file}
[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
promises = $${rootdirectory:etc}/promise
[directory]
recipe = slapos.cookbook:mkdirectory
slapos = $${rootdirectory:srv}/slapos
testnode = $${rootdirectory:srv}/testnode
test-suite = $${rootdirectory:srv}/test_suite
log = $${basedirectory:log}/testnode
run = $${basedirectory:run}/testnode
software = $${rootdirectory:srv}/software
shellinabox = $${rootdirectory:srv}/shellinabox
ca-dir = $${rootdirectory:srv}/ca
[slap-parameter]
node-quantity = 1
test-suite-master-url =
instance-dict =
software-path-list = ["https://lab.nexedi.com/nexedi/slapos/raw/master/software/seleniumrunner/software.cfg"]
{
"type": "object",
"$schema": "http://json-schema.org/draft-04/schema",
"title": "Input Parameters",
"properties": {
"test-node-title": {
"title": "Test Node Title",
"description": "Name for the Test Node which will be used at ERP5.",
"type": "string"
},
"node-quantity": {
"title": "Quantity of Parallel runs",
"description": "QUantity of Parallel tests will be executed on this Node.",
"type": "integer"
},
"test-suite-master-url": {
"title": "Task Distribution URL",
"description": "Url for the task distributor master on portal_task_distribution",
"type": "string"
}
}
}
{
"$schema": "http://json-schema.org/draft-04/schema#",
"description": "Values returned by Apache Frontend instanciation",
"properties": {
"password": {
"description": "Password to access shellinabox.",
"type": "string"
},
"url": {
"description": "IPv6 URL to access the shell in a box.",
"type": "string"
}
},
"type": "object"
}
[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-default:output}
[buildout]
extends =
../../stack/slapos.cfg
../../component/git/buildout.cfg
../../component/lxml-python/buildout.cfg
../../component/zip/buildout.cfg
../../component/busybox/buildout.cfg
../../component/shellinabox/buildout.cfg
../../component/pwgen/buildout.cfg
../../component/apache/buildout.cfg
../../stack/monitor/buildout.cfg
parts =
slapos-cookbook
template
lxml-python
eggs
zip
git
apache
[eggs]
recipe = zc.recipe.egg
eggs =
${lxml-python:egg}
zc.buildout
slapos.libnetworkcache
slapos.core
jsonschema
hexagonit.recipe.download
netaddr
inotifyx
lock_file
pytz
erp5.util
PyXML
[testnode]
scripts =
testnode = erp5.util.testnode:main
slapgrid-cp = slapos.grid.slapgrid:runComputerPartition
slapgrid-sr = slapos.grid.slapgrid:runSoftwareRelease
slapproxy = slapos.proxy:main
[template]
recipe = slapos.recipe.template
url = ${:_profile_base_location_}/instance.cfg
output = ${buildout:directory}/template.cfg
mode = 0644
md5sum = 307663d73ef3ef94b02567ecd322252e
[template-default]
recipe = slapos.recipe.template
url = ${:_profile_base_location_}/instance-default.cfg
output = ${buildout:directory}/template-default.cfg
mode = 0644
md5sum = 621c84f7adcba394686acbaf44cc1d7d
[versions]
PyXML = 0.8.5
erp5.util = 0.4.45
slapos.recipe.template = 2.7
{
"name": "ERP5 Test Node",
"description": "ERP5 Test Node Runner",
"serialisation": "xml",
"software-type": {
"default": {
"title": "Default",
"description": "Default setup for ERP5TestNode Instance.",
"request": "instance-erp5testnode-input-schema.json",
"response": "instance-output-schema.json"
}
}
}
[buildout]
extends =
../../stack/slapos.cfg
../../component/bash/buildout.cfg
../../component/pyston/buildout.cfg
../../component/tmux/buildout.cfg
../../component/gdb/buildout.cfg
parts +=
gdb
tmux
eggs
bash
depot_tools
[eggs]
recipe = zc.recipe.egg
eggs =
${lxml-python:egg}
${slapos-cookbook:eggs}
slapos.recipe.template
erp5.util
interpreter = pythonwitheggs
(in no special order)
General:
- ipv6 support (besides frontend-backend apache connection)
requires important changes at ERP5 level
- resilience
- make mariadb user accounts accept connections only from relevant IPs
or make x509 mandatory (needs ZMySQLD*A support)
- make postfix log inside partition
- document postfix parameters (only once it actually works)
Monitoring:
- daily slow-query digest
make percona toolkit available in mysql instance and decide how to send digest
- daily apachedex
Backups:
- flush binlogs independently from full backups (in addition to anyway flushing them on full backup creation)
- rotate tidstorage consistency points
- make mysql backup path an instance parameter
- make srv/backup/zodb the default value for a parameter (zodb{ 'backup_root': ...} or so) to have a single value to modify to relocate zodb backups of a partition
- make srv/backup/logrotate customisable (per partition, otherwise files will overwrite each other)
[buildout]
extends =
# Exact version of Zope
ztk-versions.cfg
zope-versions.cfg
../../component/cups/buildout.cfg
../../component/dbus/buildout.cfg
../../component/file/buildout.cfg
../../component/fonts/buildout.cfg
../../component/ghostscript/buildout.cfg
../../component/git/buildout.cfg
../../component/graphviz/buildout.cfg
../../component/gzip/buildout.cfg
../../component/haproxy/buildout.cfg
../../component/hookbox/buildout.cfg
../../component/findutils/buildout.cfg
../../component/librsvg/buildout.cfg
../../component/imagemagick/buildout.cfg
../../component/inkscape/buildout.cfg
../../component/kumo/buildout.cfg
../../component/libdmtx/buildout.cfg
../../component/libffi/buildout.cfg
../../component/libpng/buildout.cfg
../../component/libreoffice-bin/buildout.cfg
../../component/matplotlib/buildout.cfg
../../component/mesa/buildout.cfg
../../component/numpy/buildout.cfg
../../component/pandas/buildout.cfg
../../component/percona-toolkit/buildout.cfg
../../component/patch/buildout.cfg
../../component/pillow/buildout.cfg
../../component/pycrypto-python/buildout.cfg
../../component/pysvn-python/buildout.cfg
../../component/python-ldap-python/buildout.cfg
../../component/rdiff-backup/buildout.cfg
../../component/scikit-learn/buildout.cfg
../../component/stunnel/buildout.cfg
../../component/subversion/buildout.cfg
../../component/tesseract/buildout.cfg
../../component/w3-validator/buildout.cfg
../../component/w3m/buildout.cfg
../../component/xorg/buildout.cfg
../../component/poppler/buildout.cfg
../../component/zabbix/buildout.cfg
../../component/sed/buildout.cfg
../../component/coreutils/buildout.cfg
../../component/grep/buildout.cfg
../../component/dash/buildout.cfg
../../component/wget/buildout.cfg
../../component/aspell/buildout.cfg
../../component/cloudooo/buildout.cfg
../../component/jsl/buildout.cfg
../../component/6tunnel/buildout.cfg
../../component/findutils/buildout.cfg
../../component/userhosts/buildout.cfg
../../component/postfix/buildout.cfg
../../software/ipython_notebook/software.cfg
../../software/neoppod/software-common.cfg
# keep neoppod extends last
parts +=
erp5-util-develop
slapos-cookbook-develop
slapos-cookbook
rdiff-backup
aspell
aspell-en-dictionary
apache
apache-antiloris
file
findutils
graphviz
haproxy
jsl
stunnel
w3m
poppler
libpng
ghostscript
mroonga-mariadb
imagemagick
inkscape
libdmtx
dmtx-utils
kumo
libreoffice-bin
w3-validator
tesseract
hookbox
perl-DBD-mariadb
perl-DBI
percona-toolkit
zabbix-agent
dash
wget
userhosts
postfix
# Buildoutish
eggs
testrunner
test_suite_runner
# basic Xorg
libXdmcp
libXext
libXau
libSM
libXrender
# fonts
liberation-fonts
ipaex-fonts
ipa-fonts
ocrb-fonts
android-fonts
# Cloudooo specific part
cloudooo-develop
cloudooo
# get git repositories
erp5
genbt5list
# some additional utils
zodbanalyze
# Create instance template
template
# jupyter
ipython-notebook
instance-jupyter
# override instance-jupyter not to render into default template.cfg
[instance-jupyter]
rendered = ${buildout:directory}/template-jupyter.cfg
[download-base]
<= download-base-neo
url = ${:_profile_base_location_}/${:filename}
[check-recipe]
recipe = plone.recipe.command
stop-on-error = true
update-command = ${:command}
command = grep parts ${buildout:develop-eggs-directory}/slapos.cookbook.egg-link
[mariadb-resiliency-after-import-script]
recipe = slapos.recipe.build:download
url = ${:_profile_base_location_}/template/instance-mariadb-resiliency-after-import-script.sh.in
md5sum = b32d9ee1cb85f85d8d2f2b58f58459f1
mode = 755
[template-mariadb]
<= download-base
filename = instance-mariadb.cfg.in
md5sum = 9312af2f9d9faf06d2f26f073ad60180
link-binary =
${coreutils:location}/bin/basename
${coreutils:location}/bin/cat
${coreutils:location}/bin/cp
${coreutils:location}/bin/ls
${coreutils:location}/bin/tr
${coreutils:location}/bin/uname
${gettext:location}/lib/gettext/hostname
${grep:location}/bin/grep
${sed:location}/bin/sed
${mariadb:location}/bin/mysqlbinlog
[template-kumofs]
<= download-base
filename = instance-kumofs.cfg.in
md5sum = 763db0c4a94649296e74fe1f53c03940
[template-cloudooo]
<= download-base
filename = instance-cloudoo.cfg.in
md5sum = 1eedc7ee93ac7c95e1c7d50a36ef2b01
[template-zope-conf]
<= download-base
filename = zope.conf.in
md5sum = 77ab4f229a92e02603028a0bd3772edd
[template-runzope-userhosts-preloaded]
<= download-base
filename = runzope_userhosts_preloaded.in
md5sum = bc6048b85b410693e60e5a77399dd1b7
[template-my-cnf]
<= download-base
filename = my.cnf.in
md5sum = d50920c942b8ee98402f8551fef38383
[template-mariadb-initial-setup]
<= download-base
filename = mariadb_initial_setup.sql.in
md5sum = 6465212fdc7fe9076a0c929d9f14da14
[template-create-erp5-site]
<= download-base
filename = instance-create-erp5-site.cfg.in
md5sum = 71cef1d06065951ab4cf43eb13f311a3
[template-create-erp5-site-real]
<= download-base
filename = instance-create-erp5-site-real.cfg.in
md5sum = 79f789360e71146486c82a7a10834bae
[template-postfix]
< = download-base
filename = instance-postfix.cfg.in
md5sum = 90a017581116f14014a039d38ef36ffd
[template-postfix-master-cf]
< = download-base
filename = postfix_master.cf.in
md5sum = 9ac81647368068a1a98a785d08074b43
[template-postfix-main-cf]
< = download-base
filename = postfix_main.cf.in
md5sum = d51897728755e14d8005344608098009
[template-postfix-aliases]
< = download-base
filename = postfix_aliases.in
md5sum = 0969fbb25b05c02ef3c2d437b2f4e1a0
[template]
recipe = slapos.recipe.template:jinja2
# XXX: "template.cfg" is hardcoded in instanciation recipe
rendered = ${buildout:directory}/template.cfg
template = ${:_profile_base_location_}/instance.cfg.in
md5sum = 10d02ec69c875e6a55afe3bf79db7bba
mode = 640
context =
key mariadb_link_binary template-mariadb:link-binary
key zope_link_binary template-zope:link-binary
key apache_location apache:location
key aspell_location aspell:location
key bin_directory buildout:bin-directory
key buildout_bin_directory buildout:bin-directory
key cairo_location cairo:location
key coreutils_location coreutils:location
key cups_location cups:location
key curl_location curl:location
key cyrus_sasl_location cyrus-sasl:location
key dash_location dash:location
key dbus_glib_location dbus-glib:location
key dbus_location dbus:location
key dcron_location dcron:location
key erp5_location erp5:location
key file_location file:location
key findutils_location findutils:location
key fontconfig_location fontconfig:location
key fonts_location fonts:location
key freetype_location freetype:location
key glib_location glib:location
key glu_location glu:location
key gzip_location gzip:location
key haproxy_location haproxy:location
key instance_common_cfg instance-common:rendered
key jsl_location jsl:location
key jupyter_enable_default erp5-defaults:jupyter-enable-default
key kumo_location kumo:location
key libICE_location libICE:location
key libSM_location libSM:location
key libX11_location libX11:location
key libXau_location libXau:location
key libXdmcp_location libXdmcp:location
key libXext_location libXext:location
key libXrender_location libXrender:location
key libexpat_location libexpat:location
key libffi_location libffi:location
key libpng12_location libpng12:location
key libreoffice_bin_location libreoffice-bin:location
key librsvg_location librsvg:location
key libxcb_location libxcb:location
key local_bt5_repository local-bt5-repository:list
key logrotate_location logrotate:location
key mariadb_location mariadb:location
key mariadb_resiliency_after_import_script mariadb-resiliency-after-import-script:target
key mesa_location mesa:location
key openssl_location openssl:location
key pixman_location pixman:location
key postfix_location postfix:location
key root_common root-common:target
key sixtunnel_location 6tunnel:location
key slapos_core_version versions:slapos.core
key stunnel_location stunnel:location
key template_apache_conf template-apache-backend-conf:target
key template_balancer template-balancer:target
key template_cloudooo template-cloudooo:target
key template_create_erp5_site template-create-erp5-site:target
key template_create_erp5_site_real template-create-erp5-site-real:target
key template_erp5 template-erp5:target
key template_haproxy_cfg template-haproxy-cfg:target
key template_jupyter_cfg instance-jupyter:rendered
key template_kumofs template-kumofs:target
key template_mariadb template-mariadb:target
key template_mariadb_initial_setup template-mariadb-initial-setup:target
key template_monitor monitor-template:rendered
key template_my_cnf template-my-cnf:target
key template_postfix template-postfix:target
key template_postfix_aliases template-postfix-aliases:target
key template_postfix_main_cf template-postfix-main-cf:target
key template_postfix_master_cf template-postfix-master-cf:target
key template_runzope_userhosts_preloaded template-runzope-userhosts-preloaded:target
key template_zeo template-zeo:target
key template_zope template-zope:target
key template_zope_conf template-zope-conf:target
key userhosts_location userhosts:location
key wget_location wget:location
key xdamage_location xdamage:location
key xfixes_location xfixes:location
key zlib_location zlib:location
key extra_path_list eggs:extra-paths
[monitor-template-dummy]
<= download-base
# This is a placeholder, to be overriden by extending monitor SR
filename = dummy.cfg
md5sum = d41d8cd98f00b204e9800998ecf8427e
[monitor-template]
rendered = ${monitor-template-dummy:target}
[template-erp5]
<= download-base
filename = instance-erp5.cfg.in
md5sum = 66edf64eeaecded8977459acb26f4424
[template-zeo]
<= download-base
filename = instance-zeo.cfg.in
md5sum = b0cb0ee97cddc79112a718e065806037
[template-zope]
<= download-base
filename = instance-zope.cfg.in
md5sum = 83304f1940e0d7555bd678e2cea4c738
link-binary =
${aspell:location}/bin/aspell
${dmtx-utils:location}/bin/dmtxwrite
${git:location}/bin/git
${graphviz:location}/bin/dot
${grep:location}/bin/grep
${imagemagick:location}/bin/convert
${imagemagick:location}/bin/identify
${jsl:location}/bin/jsl
${librsvg:location}/bin/rsvg-convert
${mariadb:location}/bin/mysql
${mariadb:location}/bin/mysqldump
${openssl:location}/bin/openssl
${poppler:location}/bin/pdfinfo
${poppler:location}/bin/pdftohtml
${poppler:location}/bin/pdftotext
${sed:location}/bin/sed
${tesseract:location}/bin/tesseract
${w3m:location}/bin/w3m
[template-balancer]
<= download-base
filename = instance-balancer.cfg.in
md5sum = ec9321514674c084e509ca070763b4a1
[template-haproxy-cfg]
<= download-base
filename = haproxy.cfg.in
md5sum = 3defd473e2cea17ae36bba7752494858
[bt5-repository]
# Format:
# <url or path> [...]
#
# Use absolute paths for local repositories, and URLs for non-local otherwise.
#
list = ${local-bt5-repository:list}
[local-bt5-repository]
# Same as bt5-repository, but only local repository.
# Used to generate bt5lists.
list = ${erp5:location}/bt5 ${erp5:location}/product/ERP5/bootstrap
[genbt5list]
recipe = plone.recipe.command
stop-on-error = true
genbt5list = ${erp5:location}/product/ERP5/bin/genbt5list
command =
${buildout:executable} ${:genbt5list} ${local-bt5-repository:list}
update-command = ${:command}
[erp5_repository_list]
repository_id_list = erp5
# ERP5 defaults, which can be overridden in inheriting recipes (e.g. wendelin)
[erp5-defaults]
# Jupyter is by default disabled in ERP5
jupyter-enable-default = false
[erp5]
recipe = slapos.recipe.build:gitclone
repository = https://lab.nexedi.com/nexedi/erp5.git
branch = master
git-executable = ${git:location}/bin/git
[testrunner]
# XXX: Workaround for fact ERP5Type is not an distribution and does not
# expose entry point for test runner
recipe = zc.recipe.egg
eggs = ${eggs:eggs}
extra-paths = ${eggs:extra-paths}
entry-points =
runUnitTest=runUnitTest:main
scripts = runUnitTest
initialization =
import glob, imp, os, sys
import App # prevent Testing from importing Zope2.App instead of App
import Products
Products.__path__[:0] = filter(None,
os.getenv('INSERT_PRODUCTS_PATH', '').split(os.pathsep))
os.environ['SOFTWARE_HOME'] = os.path.abspath(imp.find_module('Zope2')[1])
os.environ['ZOPE_SCRIPTS'] = ''
parts_directory = '''${buildout:parts-directory}'''
repository_id_list = \
'''${erp5_repository_list:repository_id_list}'''.split()[::-1]
os.environ['erp5_tests_bt5_path'] = ','.join(sum((
[bt5_path, os.path.join(bt5_path, '*')]
for bt5_path in (os.path.join(parts_directory, x, 'bt5')
for x in repository_id_list)), []))
extra_path_list = '''${:extra-paths}'''.split()
sys.path[:0] = sum((
glob.glob(os.path.join(x, 'tests'))
for x in extra_path_list), [])
sys.path[:0] = sum((
glob.glob(os.path.join(x, 'Products', '*', 'tests'))
for x in extra_path_list), [])
sys.path[:0] = sum((
glob.glob(os.path.join(x, 'Products', '*', 'tests'))
for x in os.getenv('INSERT_PRODUCTS_PATH', '').split(os.pathsep)), [])
os.environ['PATH'] = '${jsl:location}/bin:%s' % os.environ['PATH']
os.environ['CGI_PATH'] = '${w3-validator:location}/httpd/cgi-bin'
[test_suite_runner]
# XXX: Workaround for fact ERP5Type is not an distribution and does not
# expose entry point for test runner
recipe = zc.recipe.egg
eggs = ${eggs:eggs}
extra-paths = ${eggs:extra-paths}
entry-points =
runTestSuite=Products.ERP5Type.tests.runTestSuite:main
scripts = runTestSuite
initialization =
import os
import sys
import Products
[Products.__path__.insert(0, p) for p in reversed(os.environ.get('INSERT_PRODUCTS_PATH', '').split(':')) if p]
import Zope2
os.environ['SOFTWARE_HOME'] = os.path.abspath(os.path.dirname(os.path.dirname(Zope2.__file__)))
os.environ['ZOPE_SCRIPTS'] = ''
repository_id_list = list(reversed('''${erp5_repository_list:repository_id_list}'''.split()))
sys.path[0:0] = ['/'.join(['''${buildout:parts-directory}''', x]) for x in repository_id_list]
[eggs]
<= neoppod
eggs =
${numpy:egg}
${matplotlib:egg}
${python-mysqlclient:egg}
${lxml-python:egg}
${pandas:egg}
${pillow-python:egg}
${python-ldap-python:egg}
${pysvn-python:egg}
${pycrypto-python:egg}
${scikit-learn:egg}
lock_file
astor
PyStemmer
PyXML
Pympler
SOAPpy
chardet
collective.recipe.template
coverage
erp5diff
inotifyx
interval
ipdb
Jinja2
jsonschema
mechanize
objgraph
paramiko
ply
pyflakes
pypdf2
python-magic
python-memcached
pytz
requests
threadframe
timerserver
urlnorm
uuid
xml_marshaller
xupdate_processor
feedparser
validictory
erp5.util
huBarcode
qrcode
spyne
httplib2
suds
pprofile
pycountry
xfw
jsonschema
# Needed for checking ZODB Components source code
pylint
pytracemalloc
neoppod[client]
# Zope
ZODB3
Zope2
# Zope acquisition patch
Acquisition
# Other Zope 2 packages
Products.PluggableAuthService
Products.PluginRegistry
# CMF 2.2
Products.CMFActionIcons
Products.CMFCalendar
Products.CMFCore
Products.CMFDefault
Products.CMFTopic
Products.CMFUid
Products.DCWorkflow
Products.GenericSetup
five.localsitemanager
# Other products
Products.DCWorkflowGraph
Products.MimetypesRegistry
Products.ExternalEditor
Products.TIDStorage
Products.LongRequestLogger
Products.PloneHotfix20160830
# BBB: Temporarily keep zope.app.testing awaiting we use newer version of CMF
# (for tests like testCookieCrumbler).
zope.app.testing
# Currently forked in our repository
# Products.PortalTransforms
# Dependency for our fork of PortalTransforms
StructuredText
# Needed for parsing .po files from our Localizer subset
polib
# parameterizing the version of the generated python interpreter name by the
# python section version causes dependency between this egg section and the
# installation of python, which we don't want on an instance
interpreter = ${buildout:python}
scripts =
repozo
runzope
runzeo
tidstoraged
tidstorage_repozo
web_checker_utility = erp5.util.webchecker:web_checker_utility
extra-paths =
${erp5:location}
# patches for eggs
patch-binary = ${patch:location}/bin/patch
Acquisition-patches = ${:_profile_base_location_}/../../component/egg-patch/Acquisition/aq_dynamic.patch#e8029103350dad364d25747514a20327
Acquisition-patch-options = -p1
Products.DCWorkflow-patches = ${:_profile_base_location_}/../../component/egg-patch/Products.DCWorkflow/workflow_method.patch#975b49e96bae33ac8563454fe5fa9899
Products.DCWorkflow-patch-options = -p1
python-magic-patches = ${:_profile_base_location_}/../../component/egg-patch/python_magic/magic.patch#de0839bffac17801e39b60873a6c2068
python-magic-patch-options = -p1
[zodbanalyze]
recipe = zc.recipe.egg
eggs = erp5.util
entry-points =
zodbanalyze=erp5.util.zodbanalyze:main
scripts = zodbanalyze
# develop erp5.util from parts/erp5/
[erp5-util-develop]
recipe = zc.recipe.egg:develop
setup = ${erp5:location}
[cloudooo-repository]
branch =
revision = 9d3317fc1efaee317af95443121ae30a0596b35c
[slapos-deps-eggs]
recipe = zc.recipe.egg
eggs +=
slapos.toolbox[zodbpack]
scripts +=
is-local-tcp-port-opened
is-process-older-than-dependency-set
zodbpack
[versions]
# See ../../software/neoppod/software-common.cfg for versions common with NEO:
# neoppod, mysqlclient, slapos.recipe.template & [slapos-deps-eggs]
# patched eggs
Acquisition = 2.13.9+SlapOSPatched001
Products.DCWorkflow = 2.2.4+SlapOSPatched001
pysvn = 1.7.10+SlapOSPatched002
python-ldap = 2.4.27+SlapOSPatched001
python-magic = 0.4.12+SlapOSPatched001
# specify dev version to be sure that an old released version is not used
cloudooo = 1.2.5-dev
# use newer version than specified in ZTK
PasteDeploy = 1.5.2
Pygments = 2.1.3
argparse = 1.4.0
coverage = 4.2
zope.dottedname = 4.1.0
# test_UserManagerInterfaces in testERP5Security fails with 1.10.0.
Products.PluggableAuthService = 1.9.0
# we are still using this old stable version.
rdiff-backup = 1.0.5
# use newest version of slapos.cookbook
slapos.cookbook =
# modified version that works fine for buildout installation
SOAPpy = 0.12.0nxd001
# CMF 2.3 is not yet supported.
Products.CMFCalendar = 2.2.3
Products.CMFCore = 2.2.10
Products.CMFDefault = 2.2.4
Products.CMFTopic = 2.2.1
Products.CMFUid = 2.2.1
# newer version requires zope.traversing>=4.0.0a2.
zope.app.appsetup = 3.16.0
# newer version requires zope.i18n>=4.0.0a3
zope.app.publication = 3.14.0
# newer version requires zope.testbrowser>=4
zope.app.testing = 3.8.1
# Pinned versions
Pillow = 3.3.1
Products.CMFActionIcons = 2.1.3
Products.DCWorkflowGraph = 0.4.1
# Products.ExternalEditor 2.0.0's dtml is not based on Zope2 OFS's one.
Products.ExternalEditor = 1.1.1
Products.GenericSetup = 1.8.3
Products.LongRequestLogger = 2.0.0
Products.MimetypesRegistry = 2.0.10
Products.PloneHotfix20160830 = 1.3
Products.PluginRegistry = 1.4
Products.TIDStorage = 5.4.9
PyPDF2 = 1.26.0
PyStemmer = 1.3.0
PyXML = 0.8.5
Pympler = 0.4.3
StructuredText = 2.11.1
WSGIUtils = 0.7
Zope2 = 2.13.24
astor = 0.5
# astroid 1.4.1 breaks testDynamicClassGeneration
astroid = 1.3.8
backports-abc = 0.4
chardet = 2.3.0
csp-eventlet = 0.7.0
erp5diff = 0.8.1.7
eventlet = 0.19.0
five.formlib = 1.0.4
five.localsitemanager = 2.0.5
greenlet = 0.4.10
http-parser = 0.8.3
httplib2 = 0.9.2
huBarcode = 1.0.0
interval = 1.0.0
ipdb = 0.10.1
ipykernel = 4.5.0
ipython = 5.1.0
ipywidgets = 5.2.2
logilab-common = 1.2.2
matplotlib = 1.5.3
mistune = 0.7.3
notebook = 4.2.2
numpy = 1.11.1
objgraph = 3.0.0
pandas = 0.18.1
ply = 3.9
polib = 1.0.7
pprofile = 1.9.2
prompt-toolkit = 1.0.7
ptyprocess = 0.5.1
pycountry = 1.20
pyflakes = 1.3.0
# pylint 1.5.1 breaks testDynamicClassGeneration
pylint = 1.4.4
python-memcached = 1.58
pytracemalloc = 1.2
pyzmq = 15.4.0
qrcode = 5.3
restkit = 4.2.2
rtjp-eventlet = 0.3.2
scikit-learn = 0.17.1
scipy = 0.18.0
simplegeneric = 0.8.1
socketpool = 0.5.3
spyne = 2.12.13
suds = 0.4
terminado = 0.6
threadframe = 0.2
timerserver = 2.0.2
tornado = 4.4.1
traitlets = 4.3.0
urlnorm = 1.1.4
uuid = 1.30
validictory = 1.0.2
widgetsnbextension = 1.2.6
xfw = 0.10
xupdate-processor = 0.4
# Required by:
# Products.CMFCore==2.2.10
Products.ZSQLMethods = 2.13.4
# Required by:
# ipython==5.1.0
backports.shutil-get-terminal-size = 1.0.0
# Required by:
# tornado==4.4.1
backports.ssl-match-hostname = 3.5.0.1
# Required by:
# tornado==4.4.1
certifi = 2016.8.31
# Required by:
# matplotlib==1.5.3
cycler = 0.10.0
# Required by:
# ipython==5.1.0
# traitlets==4.3.0
decorator = 4.0.10
# Required by:
# SOAPpy===0.12.0nxd001
fpconst = 0.7.2
# Required by:
# nbformat==4.1.0
# notebook==4.2.2
# traitlets==4.3.0
ipython-genutils = 0.1.0
# Required by:
# notebook==4.2.2
# nbconvert 4.2.0 depends on entrypoints egg that is not available as tar/zip source.
nbconvert = 4.1.0
# Required by:
# nbconvert==4.1.0
# notebook==4.2.2
nbformat = 4.1.0
# Required by:
# ipython==5.1.0
pathlib2 = 2.1.0
# Required by:
# ipython==5.1.0
pexpect = 4.2.1
# Required by:
# ipython==5.1.0
pickleshare = 0.7.4
# Required by:
# matplotlib==1.5.3
# pandas==0.18.1
python-dateutil = 2.5.3
# Required by:
# tornado==4.4.1
singledispatch = 3.4.0.3
# Required by:
# prompt-toolkit==1.0.3
wcwidth = 0.1.7
# Required by:
# zope.app.testing==3.8.1
zope.app.debug = 3.4.1
# Required by:
# zope.app.testing==3.8.1
zope.app.dependable = 3.5.1
# Required by:
# Products.CMFCalendar==2.2.3
# five.formlib==1.0.4
zope.app.form = 4.0.2
{% set server_check_path = parameter_dict['server-check-path'] -%}
global
maxconn 4096
stats socket {{ parameter_dict['socket-path'] }} level admin
defaults
log global
mode http
option httplog
option dontlognull
retries 1
option redispatch
maxconn 2000
cookie SERVERID rewrite
http-send-name-header X-Balancer-Current-Server
balance roundrobin
stats uri /haproxy
stats realm Global\ statistics
# it is useless to have timeout much bigger than the one of apache.
# By default apache use 300s, so we set slightly more in order to
# make sure that apache will first stop the connection.
timeout server 305s
# Stop waiting in queue for a zope to become available.
# If no zope can be reached after one minute, consider the request will
# never succeed.
timeout queue 60s
# The connection should be immediate on LAN,
# so we should not set more than 5 seconds, and it could be already too much
timeout connect 5s
# As requested in haproxy doc, make this "at least equal to timeout server".
timeout client 305s
# Use "option forceclose" to not preserve client & server persistent connections
# while handling every incoming request individually, dispatching them one after
# another to servers, in HTTP close mode. This is really needed when haproxy
# is configured with maxconn to 1, without this option browsers are unable
# to render a page
option forceclose
{% for name, (port, backend_list) in sorted(parameter_dict['backend-dict'].iteritems()) -%}
listen {{ name }}
bind {{ parameter_dict['ip'] }}:{{ port }}
http-request set-header X-Balancer-Current-Cookie SERVERID
{% set has_webdav = [] -%}
{% for address, connection_count, webdav in backend_list -%}
{% if webdav %}{% do has_webdav.append(None) %}{% endif -%}
{% set server_name = name ~ '-' ~ loop.index0 -%}
server {{ server_name }} {{ address }} cookie {{ server_name }} check inter 3s rise 1 fall 2 maxqueue 5 maxconn {{ connection_count }}
{% endfor -%}
{%- if not has_webdav and server_check_path %}
option httpchk GET {{ server_check_path }}
{% endif -%}
{% endfor %}
{% set part_list = [] -%}
{% set ssl_parameter_dict = slapparameter_dict.get('ssl', {}) %}
{% macro section(name) %}{% do part_list.append(name) %}{{ name }}{% endmacro -%}
{% set use_ipv6 = slapparameter_dict.get('use-ipv6', False) -%}
{#
XXX: This template only supports exactly one IPv4 and (if ipv6 is used) one IPv6
per partition. No more (undefined result), no less (IndexError).
-#}
# TODO: insert varnish between apache & haproxy.
# And think of a way to specify which urls goe through varnish, which go
# directly to haproxy. (maybe just passing literal configuration file chunk)
{% set ipv4 = (ipv4_set | list)[0] -%}
{% set apache_ip_list = [ipv4] -%}
{% if ipv6_set -%}
{% set ipv6 = (ipv6_set | list)[0] -%}
{% do apache_ip_list.append('[' ~ ipv6 ~ ']') -%}
{% endif -%}
[simplefile]
recipe = slapos.recipe.template:jinja2
template = inline:{{ '{{ content }}' }}
{% macro simplefile(section_name, file_path, content, mode='') -%}
{% set content_section_name = section_name ~ '-content' -%}
[{{ content_section_name }}]
content = {{ dumps(content) }}
[{{ section(section_name) }}]
< = simplefile
rendered = {{ file_path }}
context = key content {{content_section_name}}:content
mode = {{ mode }}
{%- endmacro %}
{% if use_ipv6 -%}
[zope-tunnel-base]
recipe = slapos.cookbook:ipv4toipv6
runner-path = ${directory:services}/${:base-name}
6tunnel-path = {{ parameter_dict['6tunnel'] }}/bin/6tunnel
shell-path = {{ parameter_dict['dash'] }}/bin/dash
ipv4 = {{ ipv4 }}
{% endif -%}
{% set haproxy_dict = {} -%}
{% set apache_dict = {} -%}
{% set next_port = slapparameter_dict['tcpv4-port'] -%}
{% for family_name, parameter_id_list in sorted(
slapparameter_dict['zope-family-dict'].iteritems()) -%}
{% set zope_family_address_list = [] -%}
{% set has_webdav = [] -%}
{% for parameter_id in parameter_id_list -%}
{% set zope_address_list = slapparameter_dict[parameter_id] -%}
{% for zope_address, maxconn, webdav in zope_address_list -%}
{% if webdav -%}
{% do has_webdav.append(None) %}
{% endif -%}
{% if use_ipv6 -%}
[{{ section('zope-tunnel-' ~ next_port) }}]
< = zope-tunnel-base
base-name = {{ 'zeo-tunnel-' ~ next_port }}
ipv4-port = {{ next_port }}
ipv6-port = {{ zope_address.split(']:')[1] }}
ipv6 = {{ zope_address.split(']:')[0][1:] }}
{% set zope_effective_address = ipv4 ~ ":" ~ next_port -%}
{% set next_port = next_port + 1 -%}
{% else -%}
{% set zope_effective_address = zope_address -%}
{% endif -%}
{% do zope_family_address_list.append((zope_effective_address, maxconn, webdav)) -%}
{% endfor -%}
{% endfor -%}
{# Make rendering fail artificially if any family has no known backend.
# This is useful as haproxy's hot-reconfiguration mechanism is
# supervisord-incompatible.
# As jinja2 postpones KeyError until place-holder value is actually used,
# do a no-op getitem.
-#}
{% do zope_family_address_list[0][0] -%}
{% set haproxy_port = next_port -%}
{% set next_port = next_port + 1 -%}
{% do haproxy_dict.__setitem__(family_name, (haproxy_port, zope_family_address_list)) -%}
{% if has_webdav -%}
{% set internal_scheme = 'http' -%}{# mod_rewrite does not recognise webdav scheme -#}
{% set external_scheme = 'webdavs' -%}
{% else %}
{% set internal_scheme = 'http' -%}
{% set external_scheme = 'https' -%}
{% endif -%}
{% do apache_dict.__setitem__(family_name, (next_port, external_scheme, internal_scheme ~ '://' ~ ipv4 ~ ':' ~ haproxy_port ~ slapparameter_dict['backend-path'])) -%}
{% set next_port = next_port + 1 -%}
{% endfor -%}
[haproxy-cfg-parameter-dict]
socket-path = ${directory:run}/haproxy.sock
server-check-path = {{ dumps(slapparameter_dict['haproxy-server-check-path']) }}
backend-dict = {{ dumps(haproxy_dict) }}
ip = {{ ipv4 }}
[haproxy-cfg]
recipe = slapos.recipe.template:jinja2
template = {{ parameter_dict['template-haproxy-cfg'] }}
rendered = ${directory:etc}/haproxy.cfg
context = section parameter_dict haproxy-cfg-parameter-dict
extensions = jinja2.ext.do
[{{ section('haproxy') }}]
recipe = slapos.cookbook:wrapper
wrapper-path = ${directory:services}/haproxy
command-line = "{{ parameter_dict['haproxy'] }}/sbin/haproxy" -f "${haproxy-cfg:rendered}"
{# TODO: build socat and wrap it as "${directory:bin}/haproxy-ctl" to connect to "${haproxy-cfg-parameter-dict:socket-path}" #}
[apache-conf-ssl]
cert = ${directory:apache-conf}/apache.crt
key = ${directory:apache-conf}/apache.pem
ca-cert = ${directory:apache-conf}/ca.crt
crl = ${directory:apache-conf}/crl.pem
[apache-conf-parameter-dict]
backend-list = {{ dumps(apache_dict.values()) }}
ip-list = {{ dumps(apache_ip_list) }}
pid-file = ${directory:run}/apache.pid
error-log = ${directory:log}/apache-error.log
access-log = ${directory:log}/apache-access.log
# Apache 2.4's default value (60 seconds) can be a bit too short
timeout = 300
# Basic SSL server configuration
cert = ${apache-ssl:cert}
key = ${apache-ssl:key}
cipher =
ssl-session-cache = ${directory:log}/apache-ssl-session-cache
# Client x509 auth
ca-cert = ${apache-ssl-client:cert}
crl = ${apache-ssl-client:crl}
[apache-conf]
recipe = slapos.recipe.template:jinja2
template = {{ parameter_dict['template-apache-conf'] }}
rendered = ${directory:apache-conf}/apache.conf
context = section parameter_dict apache-conf-parameter-dict
[{{ section('apache') }}]
recipe = slapos.cookbook:wrapper
wrapper-path = ${directory:services}/apache
command-line = "{{ parameter_dict['apache'] }}/bin/httpd" -f "${apache-conf:rendered}" -DFOREGROUND
[{{ section('apache-promise') }}]
# Check any apache port in ipv4, expect other ports and ipv6 to behave consistently
recipe = slapos.cookbook:check_port_listening
path = ${directory:promise}/apache
hostname = {{ ipv4 }}
port = {{ apache_dict.values()[0][0] }}
[publish]
recipe = slapos.cookbook:publish.serialised
{% for family_name, (apache_port, scheme, _) in apache_dict.items() -%}
{{ family_name ~ '-v6' }} = {% if ipv6_set %}{{ scheme ~ '://[' ~ ipv6 ~ ']:' ~ apache_port }}{% endif %}
{{ family_name }} = {{ scheme ~ '://' ~ ipv4 ~ ':' ~ apache_port }}
{% endfor -%}
[apache-ssl]
{% if ssl_parameter_dict.get('key') -%}
key = ${apache-ssl-key:rendered}
cert = ${apache-ssl-cert:rendered}
{{ simplefile('apache-ssl-key', '${apache-conf-ssl:key}', ssl_parameter_dict['key']) }}
{{ simplefile('apache-ssl-cert', '${apache-conf-ssl:cert}', ssl_parameter_dict['cert']) }}
{% else %}
recipe = plone.recipe.command
command = "{{ parameter_dict['openssl'] }}/bin/openssl" req -newkey rsa -batch -new -x509 -days 3650 -nodes -keyout "${:key}" -out "${:cert}"
key = ${apache-conf-ssl:key}
cert = ${apache-conf-ssl:cert}
{%- endif %}
[apache-ssl-client]
{% if ssl_parameter_dict.get('ca-cert') -%}
cert = ${apache-ssl-ca:rendered}
crl = ${apache-ssl-crl:rendered}
{{ simplefile('apache-ssl-ca', '${apache-conf-ssl:ca-cert}', ssl_parameter_dict['ca-cert']) }}
{{ simplefile('apache-ssl-crl', '${apache-conf-ssl:crl}', ssl_parameter_dict['crl']) }}
{% else %}
cert =
crl =
{%- endif %}
[logrotate-apache]
recipe = slapos.cookbook:logrotate.d
logrotate-entries = ${logrotate:logrotate-entries}
backup = ${logrotate:backup}
name = apache
log = ${apache-conf-parameter-dict:error-log} ${apache-conf-parameter-dict:access-log}
post = {{ parameter_dict['bin-directory'] }}/slapos-kill --pidfile ${apache-conf-parameter-dict:pid-file} -s USR1
[directory]
recipe = slapos.cookbook:mkdirectory
apache-conf = ${:etc}/apache
bin = ${buildout:directory}/bin
etc = ${buildout:directory}/etc
promise = ${directory:etc}/promise
services = ${:etc}/run
var = ${buildout:directory}/var
run = ${:var}/run
log = ${:var}/log
ca-dir = ${buildout:directory}/srv/ssl
requests = ${:ca-dir}/requests
private = ${:ca-dir}/private
certs = ${:ca-dir}/certs
newcerts = ${:ca-dir}/newcerts
crl = ${:ca-dir}/crl
[monitor-instance-parameter]
monitor-httpd-ipv6 = {{ (ipv6_set | list)[0] }}
monitor-httpd-port = {{ next_port }}
monitor-title = Balancer monitor
[buildout]
extends =
{{ logrotate_cfg }}
{{ parameter_dict['template-monitor'] }}
parts +=
publish
logrotate-apache
{{ part_list | join('\n ') }}
{% set bin_directory = parameter_dict['buildout-bin-directory'] -%}
{% set use_ipv6 = slapparameter_dict.get('use-ipv6', False) -%}
[buildout]
extends =
{{ parameter_dict['template-monitor'] }}
parts +=
publish
cloudooo-instance
resiliency-exclude-file
promise
promise-openoffice
{% if use_ipv6 %}promise-tunnel{% endif %}
[publish]
recipe = slapos.cookbook:publish.serialised
{% if use_ipv6 -%}
url = cloudooo://[${ipv6toipv4:ipv6}]:${ipv6toipv4:ipv6-port}/
{% else -%}
url = cloudooo://${cloudooo-instance:ip}:${cloudooo-instance:port}/
{% endif -%}
[cloudooo-instance]
recipe = slapos.cookbook:generic.cloudooo
# Network options
ip = {{ (ipv4_set | list)[0] }}
{% set tcpv4_port = slapparameter_dict['tcpv4-port'] -%}
port = {{ tcpv4_port }}
openoffice-port = {{ tcpv4_port + 1 }}
# Paths
configuration-file = ${directory:etc}/cloudooo.cfg
wrapper = ${directory:service}/cloudooo
# Paths: Data
data-directory = ${directory:cloudooo-data}
environment =
LD_LIBRARY_PATH = {{ parameter_dict['cairo'] }}/lib:{{ parameter_dict['cups'] }}/lib:{{ parameter_dict['cups'] }}/lib64:{{ parameter_dict['dbus'] }}/lib:{{ parameter_dict['dbus-glib'] }}/lib:{{ parameter_dict['file'] }}/lib:{{ parameter_dict['fontconfig'] }}/lib:{{ parameter_dict['freetype'] }}/lib:{{ parameter_dict['glib'] }}/lib:{{ parameter_dict['glu'] }}/lib:{{ parameter_dict['libICE'] }}/lib:{{ parameter_dict['libSM'] }}/lib:{{ parameter_dict['libX11'] }}/lib:{{ parameter_dict['libXau'] }}/lib:{{ parameter_dict['libXdmcp'] }}/lib:{{ parameter_dict['libXext'] }}/lib:{{ parameter_dict['libXrender'] }}/lib:{{ parameter_dict['libexpat'] }}/lib:{{ parameter_dict['libffi'] }}/lib:{{ parameter_dict['libffi'] }}/lib64:{{ parameter_dict['libpng12'] }}/lib:{{ parameter_dict['libxcb'] }}/lib:{{ parameter_dict['mesa'] }}/lib:{{ parameter_dict['pixman'] }}/lib:{{ parameter_dict['xdamage'] }}/lib:{{ parameter_dict['xfixes'] }}/lib:{{ parameter_dict['zlib'] }}/lib
FONTCONFIG_FILE = ${fontconfig-instance:conf-path}
# Binary information
# cloudooo specific configuration
ooo-binary-path = {{ parameter_dict['libreoffice-bin'] }}/program
ooo-paster = {{ bin_directory }}/cloudooo_paster
ooo-uno-path = {{ parameter_dict['libreoffice-bin'] }}/basis-link/program
[fontconfig-instance]
recipe = slapos.cookbook:fontconfig
conf-path = ${directory:etc}/font.conf
font-system-folder = {{ parameter_dict['fonts'] }}
font-folder = ${directory:font}
service-folder = ${directory:service}
[resiliency-exclude-file]
# Generate rdiff exclude file in case of resiliency
recipe = collective.recipe.template
input = inline: **
output = ${directory:srv}/exporter.exclude
[promise]
recipe = slapos.cookbook:check_port_listening
path = ${directory:promise}/cloudooo
hostname = ${cloudooo-instance:ip}
port = ${cloudooo-instance:port}
[promise-openoffice]
recipe = slapos.cookbook:check_port_listening
path = ${directory:promise}/openoffice
hostname = ${cloudooo-instance:ip}
port = ${cloudooo-instance:openoffice-port}
{% if use_ipv6 -%}
[promise-tunnel]
recipe = slapos.cookbook:check_port_listening
path = ${directory:promise}/tunnel
hostname = ${ipv6toipv4:ipv6}
port = ${ipv6toipv4:ipv6-port}
[ipv6toipv4]
recipe = slapos.cookbook:ipv6toipv4
runner-path = ${directory:service}/${:base-name}
6tunnel-path = {{ parameter_dict['6tunnel'] }}/bin/6tunnel
shell-path = {{ parameter_dict['dash'] }}/bin/dash
ipv4 = ${cloudooo-instance:ip}
ipv6 = {{ (ipv6_set | list)[0] }}
ipv6-port = ${cloudooo-instance:port}
ipv4-port = ${cloudooo-instance:port}
base-name = cloudooo-tunnel
{% endif -%}
# rest of parts are candidates for some generic stuff
[directory]
recipe = slapos.cookbook:mkdirectory
etc = ${buildout:directory}/etc
srv = ${buildout:directory}/srv
service = ${:etc}/run
promise = ${:etc}/promise
cloudooo-data = ${:srv}/cloudooo
font = ${:srv}/font
[monitor-instance-parameter]
monitor-httpd-ipv6 = {{ (ipv6_set | list)[0] }}
monitor-httpd-port = {{ tcpv4_port + 2 }}
monitor-title = Cloudooo monitor
[directory]
recipe = slapos.cookbook:mkdirectory
etc = ${buildout:directory}/etc
services = ${:etc}/run
promise = ${:etc}/promise
[erp5-bootstrap]
recipe = slapos.cookbook:erp5.bootstrap
runner-path = ${directory:services}/erp5-bootstrap
{# Note: a random domain name will be picked if several point to the same IP -#}
{% set reverse_hosts = {} -%}
{% for x, y in publish['hosts-dict'].iteritems() -%}
{% do reverse_hosts.__setitem__(y, x) -%}
{% endfor -%}
{# XXX: Expect the first database to be the one to use for catalog. -#}
{% set mysql_parsed = urlparse.urlparse(publish['mariadb-database-list'][0]) -%}
mysql-url = {{ dumps(urlparse.urlunparse(mysql_parsed[:1] + (mysql_parsed.username + ":" + mysql_parsed.password + "@" + reverse_hosts.get(mysql_parsed.hostname, mysql_parsed.hostname) + ':' ~ mysql_parsed.port, ) + mysql_parsed[2:])) }}
{# Pick the first http[s] family found, they should be all equivalent anyway. -#}
{% set family_list = [] -%}
{% for key, value in publish.items() -%}
{% if key.startswith('family-') and value.startswith('http') -%}
{% do family_list.append(value.split('://', 1)) -%}
{% endif -%}
{% endfor -%}
zope-url = {{ dumps(family_list[0][0] + '://' + publish['inituser-login'] + ':' + publish_early['inituser-password'] + '@' + family_list[0][1] + '/' + publish['site-id']) }}
[promise-erp5-site]
recipe = slapos.cookbook:check_url_available
url = ${erp5-bootstrap:zope-url}
path = ${directory:promise}/erp5-site
dash_path = {{ parameter_dict['dash-location'] }}/bin/dash
curl_path = {{ parameter_dict['curl-location'] }}/bin/curl
[buildout]
parts = promise-erp5-site
eggs-directory = {{ eggs_directory }}
develop-eggs-directory = {{ develop_eggs_directory }}
{# To create the script (wrapper) which creates the ERP5Site object, pieces
# of what is published by extended file are required. Because they are not
# available at the time the file you are reading is rendered, and because
# those values are composed (lists, dicts...) of which items are needed,
# they cannot be accessed. Instead, make buildout provide these values to
# a second template, rendered at a convenient time.
-#}
[instance-create-erp5-site-real-parameters]
dash-location = {{ parameter_dict['dash-location'] }}
curl-location = {{ parameter_dict['curl-location'] }}
[instance-create-erp5-site-real]
recipe = slapos.recipe.template:jinja2
template = {{ parameter_dict['template-create-erp5-site-real'] }}
rendered = ${buildout:directory}/instance-create-erp5-site-real.cfg
extensions = jinja2.ext.do
context =
import urlparse urlparse
section publish publish
section publish_early publish-early
section parameter_dict instance-create-erp5-site-real-parameters
key eggs_directory buildout:eggs-directory
key develop_eggs_directory buildout:develop-eggs-directory
[instance-create-erp5-site-real-run]
recipe = slapos.recipe.build
script =
import subprocess, sys
subprocess.check_call([
sys.argv[0],
"buildout:directory=${buildout:directory}",
"buildout:installed=.installed-${:_buildout_section_name_}.cfg",
"-Uoc", self.options['run'],
])
run = ${instance-create-erp5-site-real:rendered}
slapos_promise =
[buildout]
extends = {{ parameter_dict['instance-erp5'] }}
parts +=
instance-create-erp5-site-real-run
{% import "root_common" as root_common with context %}
{% set frontend_dict = slapparameter_dict.get('frontend', {}) -%}
{% set has_frontend = frontend_dict.get('software-url', '') != '' -%}
{% set site_id = slapparameter_dict.get('site-id', 'erp5') -%}
{% set inituser_login = slapparameter_dict.get('inituser-login', 'zope') -%}
{% set publish_dict = {'site-id': site_id, 'inituser-login': inituser_login} -%}
{% set has_posftix = slapparameter_dict.get('smtp', {}).get('postmaster') -%}
{% set jupyter_dict = slapparameter_dict.get('jupyter', {}) -%}
{% set has_jupyter = jupyter_dict.get('enable', jupyter_enable_default).lower() in ('true', 'yes') -%}
{% set jupyter_zope_family = jupyter_dict.get('zope-family', '') -%}
[request-common]
<= request-common-base
config-use-ipv6 = {{ dumps(slapparameter_dict.get('use-ipv6', False)) }}
{% macro request(name, software_type, config_key, config, ret={'url': True}, key_config={}) -%}
{% do config.update(slapparameter_dict.get(config_key, {})) -%}
{% set section = 'request-' ~ name -%}
[{{ section }}]
<= request-common
name = {{ name }}
software-type = {{ software_type }}
return = {{ ' '.join(ret) }}
{% for ret, publish in ret.iteritems() -%}
{% if publish -%}
{% do publish_dict.__setitem__(name ~ '-' ~ ret, '${' ~ section ~ ':connection-' ~ ret ~ '}')%}
{% endif -%}
{% endfor -%}
{{ root_common.sla(name) }}
{% for k, v in config.iteritems() -%}
config-{{ k }} = {{ dumps(v) }}
{% endfor -%}
{% for k, v in key_config.iteritems() -%}
config-{{ k }} = {{ '${' ~ v ~ '}' }}
{% endfor -%}
{% endmacro -%}
{{ request('memcached-persistent', 'kumofs', 'kumofs', {'tcpv4-port': 2000}) }}
{{ request('memcached-volatile', 'kumofs', 'memcached', {'tcpv4-port': 2010, 'ram-storage-size': 64}) }}
{{ request('cloudooo', 'cloudooo', 'cloudooo', {'tcpv4-port': 2020}) }}
{{ request('mariadb', 'mariadb', 'mariadb', {'tcpv4-port': 2099}, {'database-list': True, 'test-database-list': True}) }}
{% if has_posftix -%}
{{ request('smtp', 'postfix', 'smtp', {'tcpv4-port': 2025, 'smtpd-sasl-user': 'erp5@nowhere'}, key_config={'smtpd-sasl-password': 'publish-early:smtpd-sasl-password'}) }}
{%- else %}
[request-smtp]
# Placeholder smtp service URL
connection-url = smtp://127.0.0.2:0/
{%- endif %}
{# ZODB -#}
{% set zodb_dict = {} -%}
{% set storage_dict = {} -%}
{% set mountpoints = set() -%}
{% for zodb in slapparameter_dict.get('zodb') or ({'type': 'zeo', 'server': {}},) -%}
{% do mountpoints.add(zodb.setdefault('mount-point', '/')) -%}
{% set name = zodb.pop('name', 'root') -%}
{% do assert(name not in zodb_dict, name, zodb_dict) -%}
{% do zodb_dict.__setitem__(name, zodb) -%}
{% if 'server' in zodb -%}
{% do storage_dict.setdefault(zodb['type'], {}).__setitem__(name, zodb.pop('server')) -%}
{% endif -%}
{% endfor -%}
{% do assert(len(mountpoints) == len(zodb_dict)) -%}
{% set neo = [] -%}
{% for server_type, server_dict in storage_dict.iteritems() -%}
{% if server_type == 'neo' -%}
{% set ((name, server_dict),) = server_dict.items() -%}
{% do neo.append(server_dict.get('cluster')) -%}
{% do server_dict.update(cluster='${publish-early:neo-cluster}') -%}
{{ root_common.request_neo(server_dict, 'zodb-neo', 'neo-') }}
{% set client_dict = zodb_dict[name].setdefault('storage-dict', {}) -%}
{% for k in 'ssl', '_ca', '_cert', '_key' -%}
{% do k in server_dict and client_dict.setdefault(k, server_dict[k]) -%}
{% endfor -%}
{% else -%}
{{ assert(server_type == 'zeo', server_type) -}}
{# BBB: for compatibility, keep 'zodb' as partition_reference for ZEO -#}
{{ request('zodb', 'zodb-' ~ server_type, 'zodb-' ~ server_type, {'tcpv4-port': 2100, 'zodb-dict': server_dict}, dict.fromkeys(('storage-dict', 'tidstorage-ip', 'tidstorage-port'))) }}
{% endif -%}
{% endfor -%}
[publish-early]
recipe = slapos.cookbook:publish-early
-init =
inituser-password gen-password:passwd
deadlock-debugger-password gen-deadlock-debugger-password:passwd
{%- if has_posftix %}
smtpd-sasl-password gen-smtpd-sasl-password:passwd
{%- endif %}
{%- if neo %}
neo-cluster gen-neo-cluster:name
{%- if neo[0] %}
neo-cluster = {{ neo[0] }}
{%- endif %}
{%- endif %}
{%- set inituser_password = slapparameter_dict.get('inituser-password') %}
{%- if inituser_password %}
inituser-password = {{ inituser_password }}
{%- endif %}
{%- set deadlock_debugger_password = slapparameter_dict.get('deadlock-debugger-password') -%}
{%- if deadlock_debugger_password %}
deadlock-debugger-password = {{ deadlock_debugger_password }}
{%- endif %}
[gen-password]
recipe = slapos.cookbook:generate.password
storage-path =
[gen-deadlock-debugger-password]
<= gen-password
[gen-neo-cluster-base]
<= gen-password
[gen-neo-cluster]
name = neo-${gen-neo-cluster-base:passwd}
[gen-smtpd-sasl-password]
< = gen-password
[request-zope-base]
<= request-common
return =
zope-address-list
hosts-dict
{% set bt5_default_list = 'erp5_full_text_myisam_catalog erp5_configurator_standard erp5_configurator_maxma_demo erp5_configurator_ung erp5_configurator_run_my_doc' -%}
{% if has_jupyter -%}
{% set bt5_default_list = bt5_default_list + ' erp5_data_notebook' -%}
{% endif -%}
config-bt5 = {{ dumps(slapparameter_dict.get('bt5', bt5_default_list)) }}
config-bt5-repository-url = {{ dumps(slapparameter_dict.get('bt5-repository-url', local_bt5_repository)) }}
config-cloudooo-url = ${request-cloudooo:connection-url}
config-deadlock-debugger-password = ${publish-early:deadlock-debugger-password}
config-developer-list = {{ dumps(slapparameter_dict.get('developer-list', [inituser_login])) }}
config-hosts-dict = {{ dumps(slapparameter_dict.get('hosts-dict', {})) }}
config-hostalias-dict = {{ dumps(slapparameter_dict.get('hostalias-dict', {})) }}
config-inituser-login = {{ dumps(inituser_login) }}
config-inituser-password = ${publish-early:inituser-password}
config-kumofs-url = ${request-memcached-persistent:connection-url}
config-memcached-url = ${request-memcached-volatile:connection-url}
config-mysql-test-url-list = ${request-mariadb:connection-test-database-list}
config-mysql-url-list = ${request-mariadb:connection-database-list}
config-site-id = {{ dumps(site_id) }}
config-smtp-url = ${request-smtp:connection-url}
config-timezone = {{ dumps(slapparameter_dict.get('timezone', 'UTC')) }}
config-zodb-dict = {{ dumps(zodb_dict) }}
{% for server_type, server_dict in storage_dict.iteritems() -%}
{% if server_type == 'neo' -%}
config-neo-cluster = ${publish-early:neo-cluster}
config-neo-name = {{ server_dict.keys()[0] }}
config-neo-masters = ${neo-0-final:connection-masters}
{% else -%}
config-zodb-zeo = ${request-zodb:connection-storage-dict}
config-tidstorage-ip = ${request-zodb:connection-tidstorage-ip}
config-tidstorage-port = ${request-zodb:connection-tidstorage-port}
{% endif -%}
{% endfor -%}
software-type = zope
{% set zope_family_dict = {} -%}
{% set jupyter_zope_family_default = [] -%}
{% for custom_name, zope_parameter_dict in slapparameter_dict.get('zope-partition-dict', {'1': {}}).items() -%}
{% set partition_name = 'zope-' ~ custom_name -%}
{% set section_name = 'request-' ~ partition_name -%}
{% set zope_family = zope_parameter_dict.get('family', 'default') -%}
{# # default jupyter zope family is first zope family. -#}
{# # use list.append() to update it, because in jinja2 set changes only local scope. -#}
{% if not jupyter_zope_family_default -%}
{% do jupyter_zope_family_default.append(zope_family) -%}
{% endif -%}
{% do zope_family_dict.setdefault(zope_family, []).append(section_name) -%}
[{{ section_name }}]
<= request-zope-base
name = {{ partition_name }}
{{ root_common.sla(partition_name) }}
config-name = {{ dumps(custom_name) }}
config-instance-count = {{ dumps(zope_parameter_dict.get('instance-count', 1)) }}
config-thread-amount = {{ dumps(zope_parameter_dict.get('thread-amount', 4)) }}
config-timerserver-interval = {{ dumps(zope_parameter_dict.get('timerserver-interval', 5)) }}
config-longrequest-logger-interval = {{ dumps(zope_parameter_dict.get('longrequest-logger-interval', -1)) }}
config-longrequest-logger-timeout = {{ dumps(zope_parameter_dict.get('longrequest-logger-timeout', 1)) }}
config-port-base = {{ dumps(zope_parameter_dict.get('port-base', 2200)) }}
config-webdav = {{ dumps(zope_parameter_dict.get('webdav', False)) }}
{% endfor -%}
{# if not explicitly configured, connect jupyter to first zope family, which -#}
{# will be 'default' if zope families are not configured also -#}
{% if not jupyter_zope_family and jupyter_zope_family_default -%}
{% set jupyter_zope_family = jupyter_zope_family_default[0] -%}
{% endif -%}
{# We need to concatenate lists that we cannot read as lists, so this gets hairy. -#}
{% set zope_address_list_id_dict = {} -%}
{% set zope_family_parameter_dict = {} -%}
{% for family_name, zope_section_id_list in zope_family_dict.items() -%}
{% for zope_section_id in zope_section_id_list -%}
{% set parameter_name = 'zope-family-entry-' ~ zope_section_id -%}
{% do zope_address_list_id_dict.__setitem__(zope_section_id, parameter_name) -%}
{% do zope_family_parameter_dict.setdefault(family_name, []).append(parameter_name) -%}
{% endfor -%}
{% if has_frontend -%}
{% set frontend_name = 'frontend-' ~ family_name -%}
{% do publish_dict.__setitem__('family-' ~ family_name, '${' ~ frontend_name ~ ':connection-site_url}' ) -%}
[{{ frontend_name }}]
<= request-frontend-base
name = {{ frontend_name }}
config-url = ${request-balancer:connection-{{ family_name }}-v6}
{% else -%}
{% do publish_dict.__setitem__('family-' ~ family_name, '${request-balancer:connection-' ~ family_name ~ '}' ) -%}
{% do publish_dict.__setitem__('family-' ~ family_name ~ '-v6', '${request-balancer:connection-' ~ family_name ~ '-v6}' ) -%}
{% endif -%}
{% endfor -%}
{% if has_jupyter -%}
{# request jupyter connected to balancer of proper zope family -#}
{{ request('jupyter', 'jupyter', 'jupyter', {}, key_config={'erp5-url': 'request-balancer:connection-' ~ jupyter_zope_family}) }}
{% if has_frontend -%}
[frontend-jupyter]
<= request-frontend-base
name = frontend-jupyter
config-url = ${request-jupyter:connection-url}
{# # override jupyter-url in publish_dict with frontend address -#}
{% do publish_dict.__setitem__('jupyter-url', '${frontend-jupyter:connection-site_url}') -%}
{% endif -%}
{%- endif %}
{% set balancer_dict = slapparameter_dict.get('balancer', {}) -%}
[request-balancer]
<= request-common
name = balancer
software-type = balancer
{{ root_common.sla('balancer') }}
return =
{%- for family in zope_family_dict %}
{{ family }}
{{ family }}-v6
{% endfor -%}
config-zope-family-dict = {{ dumps(zope_family_parameter_dict) }}
config-tcpv4-port = {{ dumps(balancer_dict.get('tcpv4-port', 2150)) }}
{% for zope_section_id, name in zope_address_list_id_dict.items() -%}
config-{{ name }} = {{ ' ${' ~ zope_section_id ~ ':connection-zope-address-list}' }}
{% endfor -%}
# XXX: should those really be same for all families ?
config-haproxy-server-check-path = {{ dumps(balancer_dict.get('haproxy-server-check-path', '/') % {'site-id': site_id}) }}
config-backend-path = {{ dumps(balancer_dict.get('apache-backend-path', '/') % {'site-id': site_id}) }}
config-ssl = {{ dumps(balancer_dict.get('ssl', {})) }}
[request-frontend-base]
{% if has_frontend -%}
<= request-common
software-url = {{ dumps(frontend_dict['software-url']) }}
software-type = {{ dumps(frontend_dict.get('software-type', 'RootSoftwareInstance')) }}
{{ root_common.sla('frontend', True) }}
slave = true
{% set config_dict = {
'type': 'zope',
} -%}
{% if frontend_dict.get('domain') -%}
{% do config_dict.__setitem__('custom_domain', frontend_dict['domain']) -%}
{% endif -%}
{% for name, value in config_dict.items() -%}
config-{{ name }} = {{ value }}
{% endfor -%}
return = site_url
{% endif -%}
[publish]
recipe = slapos.cookbook:publish.serialised
-extends = publish-early
{% if 'neo' in storage_dict -%}
neo-masters = ${neo-0-final:connection-masters}
neo-admins = ${neo-0-final:connection-admins}
{% endif -%}
{#
Pick any published hosts-dict, they are expected to be identical - and there is
no way to check here.
-#}
hosts-dict = {{ '${' ~ zope_address_list_id_dict.keys()[0] ~ ':connection-hosts-dict}' }}
{% for name, value in publish_dict.items() -%}
{{ name }} = {{ value }}
{% endfor -%}
{{ root_common.common_section() }}
{% set use_ipv6 = slapparameter_dict.get('use-ipv6', False) -%}
[buildout]
extends =
{{ logrotate_cfg }}
{{ parameter_dict['template-monitor'] }}
parts +=
publish
kumofs-instance
logrotate-entry-kumofs
resiliency-exclude-file
promise-kumofs-server
promise-kumofs-server-listen
promise-kumofs-gateway
promise-kumofs-manager
[publish]
recipe = slapos.cookbook:publish.serialised
{% if use_ipv6 -%}
url = memcached://[${kumofs-instance:ip}]:${kumofs-instance:gateway-port}/
{% else -%}
url = memcached://${kumofs-instance:ip}:${kumofs-instance:gateway-port}/
{% endif -%}
[kumofs-instance]
recipe = slapos.cookbook:generic.kumofs
# Network options
{% if use_ipv6 -%}
ip = {{ (ipv6_set | list)[0] }}
address-family = inet6
{% else -%}
ip = {{ (ipv4_set | list)[0] }}
address-family = inet4
{% endif -%}
{% set tcpv4_port = slapparameter_dict['tcpv4-port'] -%}
manager-port = {{ tcpv4_port }}
server-port = {{ tcpv4_port + 1 }}
server-listen-port = {{ tcpv4_port + 2 }}
gateway-port = {{ tcpv4_port + 3 }}
# Paths: Data
{% set ram_storage_size = slapparameter_dict.get('ram-storage-size') -%}
{% if ram_storage_size -%}
data-path = *#capsiz={{ ram_storage_size }}m
{% else -%}
# (with 10M buckets and HDBTLARGE option)
data-path = ${directory:kumofs-data}/kumodb.tch#bnum=10485760#opts=l
{% endif -%}
# Paths: Running wrappers
gateway-wrapper = ${directory:services}/kumofs_gateway
manager-wrapper = ${directory:services}/kumofs_manager
server-wrapper = ${directory:services}/kumofs_server
# Paths: Logs
kumo-gateway-log = ${directory:log}/kumo-gateway.log
kumo-manager-log = ${directory:log}/kumo-manager.log
kumo-server-log = ${directory:log}/kumo-server.log
# Binary information
kumo-gateway-binary = {{ parameter_dict['kumo-location'] }}/bin/kumo-gateway
kumo-manager-binary = {{ parameter_dict['kumo-location'] }}/bin/kumo-manager
kumo-server-binary = {{ parameter_dict['kumo-location'] }}/bin/kumo-server
shell-path = {{ parameter_dict['dash-location'] }}/bin/dash
[logrotate-entry-kumofs]
recipe = slapos.cookbook:logrotate.d
logrotate-entries = ${logrotate:logrotate-entries}
backup = ${logrotate:backup}
name = kumofs
log = ${kumofs-instance:kumo-gateway-log} ${kumofs-instance:kumo-manager-log} ${kumofs-instance:kumo-server-log}
[directory]
recipe = slapos.cookbook:mkdirectory
log = ${buildout:directory}/var/log
services = ${buildout:directory}/etc/run
promise = ${buildout:directory}/etc/promise
srv = ${buildout:directory}/srv
kumofs-data = ${:srv}/kumofs
[resiliency-exclude-file]
# Generate rdiff exclude file in case of resiliency
recipe = collective.recipe.template
input = inline: **
output = ${directory:srv}/exporter.exclude
# Deploy zope promises scripts
[promise-template]
recipe = slapos.cookbook:check_port_listening
hostname = ${kumofs-instance:ip}
port = ${kumofs-instance:server-listen-port}
[promise-kumofs-server]
<= promise-template
path = ${directory:promise}/kumofs-server
port = ${kumofs-instance:server-port}
[promise-kumofs-server-listen]
<= promise-template
path = ${directory:promise}/kumofs-server-listen
port = ${kumofs-instance:server-listen-port}
[promise-kumofs-gateway]
<= promise-template
path = ${directory:promise}/kumofs-gateway
port = ${kumofs-instance:gateway-port}
[promise-kumofs-manager]
<= promise-template
path = ${directory:promise}/kumofs-manager
port = ${kumofs-instance:manager-port}
[monitor-instance-parameter]
monitor-httpd-ipv6 = {{ (ipv6_set | list)[0] }}
monitor-httpd-port = {{ tcpv4_port + 4 }}
monitor-title = Kumofs monitor
{% set part_list = [] -%}
{% macro section(name) %}{% do part_list.append(name) %}{{ name }}{% endmacro -%}
{% set use_ipv6 = slapparameter_dict.get('use-ipv6', False) -%}
{% set database_list = slapparameter_dict.get('database-list', [{'name': 'erp5', 'user': 'user', 'password': 'insecure'}]) -%}
{% set test_database_list = [] %}
{% for database_count in range(slapparameter_dict.get('test-database-amount', 1)) -%}
{% do test_database_list.append({'name': 'erp5_test_' ~ database_count, 'user': 'testuser_' ~ database_count, 'password': 'testpassword' ~ database_count}) -%}
{% endfor -%}
{% set catalog_backup = slapparameter_dict.get('catalog-backup', {}) -%}
{% set backup_periodicity = slapparameter_dict.get('backup-periodicity', 'daily') -%}
{% set full_backup_retention_days = catalog_backup.get('full-retention-days', 7) -%}
{% set incremental_backup_retention_days = catalog_backup.get('incremental-retention-days', full_backup_retention_days) -%}
{% set port = slapparameter_dict['tcpv4-port'] %}
{% if use_ipv6 -%}
{% set ip = (ipv6_set | list)[0] -%}
{% else -%}
{% set ip = (ipv4_set | list)[0] -%}
{% endif -%}
[publish]
recipe = slapos.cookbook:publish.serialised
{% macro render_database_list(database_list) -%}
{% set publish_database_list = [] -%}
{% for database in database_list -%}
{% if database.get('user') -%}
{% do publish_database_list.append("mysql://" ~ database['user'] ~ ":" ~ database['password'] ~ "@" ~ ip ~ ":" ~ port ~ "/" ~ database['name']) -%}
{% else -%}
{% do publish_database_list.append("mysql://" ~ ip ~ ":" ~ port ~ "/" ~ database['name']) -%}
{% endif -%}
{% endfor -%}
{{ dumps(publish_database_list) }}
{% endmacro -%}
database-list = {{ render_database_list(database_list) }}
test-database-list = {{ render_database_list(test_database_list) }}
[simplefile]
recipe = slapos.recipe.template:jinja2
template = inline:{{ '{{ content }}' }}
{% macro simplefile(section_name, file_path, content, mode='') -%}
{% set content_section_name = section_name ~ '-content' -%}
[{{ content_section_name }}]
content = {{ dumps(content) }}
[{{ section(section_name) }}]
< = simplefile
rendered = {{ file_path }}
context = key content {{content_section_name}}:content
mode = {{ mode }}
{%- endmacro %}
{% set ssl_dict = {} -%}
{% macro sslfile(key, content, mode='644') -%}
{% set path = '${directory:mariadb-ssl}/' ~ key ~ '.pem' -%}
{% do ssl_dict.__setitem__(key, path) -%}
{{ simplefile('ssl-file-' ~ key, path, content, mode) }}
{%- endmacro %}
{% set ssl_parameter_dict = slapparameter_dict.get('ssl') -%}
{% if ssl_parameter_dict -%}
{% set base_directory = '${directory:mariadb-ssl}/' -%}
{# Note: The key content will be stored in .installed.cfg, and this template's
rendering, so the only point of mode is to avoid risking mariadb complaining
about laxist file mode. -#}
{{ sslfile('key', ssl_parameter_dict['key'], mode='600') }}
{{ sslfile('crt', ssl_parameter_dict['crt']) }}
{% if 'ca-crt' in ssl_parameter_dict -%}
{{ sslfile('ca-crt', ssl_parameter_dict['ca-crt']) }}
{% endif -%}
{% if 'crl' in ssl_parameter_dict -%}
{{ sslfile('crl', ssl_parameter_dict['crl']) }}
{% endif -%}
{%- endif %}
{% if full_backup_retention_days > -1 -%}
[{{ section('cron-entry-mariadb-backup') }}]
recipe = slapos.cookbook:cron.d
cron-entries = ${cron:cron-entries}
name = mariadb-backup
time = {{ dumps(backup_periodicity) }}
{# When binlogs are enabled:
# flush-logs: used so no manipulation on binlogs is needed to restore from
# full + binlogs. The first binlog after a dump starts from dump snapshot and
# can be fully restored.
# master-data: use value "2" as we are not in a replication case
#}
command = "${binary-wrap-mysqldump:wrapper-path}" -u root --all-databases --single-transaction {% if incremental_backup_retention_days > -1 %}--flush-logs --master-data=2 {% endif %}| {{ parameter_dict['gzip-location'] }}/bin/gzip > "${directory:mariadb-backup-full}/$({{ parameter_dict['coreutils-location'] }}/bin/date "+%Y%m%d%H%M%S").sql.gz"
{# KEEP GLOB PATTERN IN SYNC with generated filenames above
# YYYYmmddHHMMSS -#}
file-glob = ??????????????.sql.gz
{% if full_backup_retention_days > 0 -%}
[{{ section("cron-entry-mariadb-backup-expire") }}]
recipe = slapos.cookbook:cron.d
cron-entries = ${cron:cron-entries}
name = mariadb-backup-expire
time = {{ dumps(backup_periodicity) }}
command = {{ parameter_dict['findutils-location'] }}/bin/find "${directory:mariadb-backup-full}" -maxdepth 1 -name "${cron-entry-mariadb-backup:file-glob}" -daystart -mtime +{{ full_backup_retention_days }} -delete
{%- endif %}
{%- endif %}
[my-cnf-parameters]
ip = {{ ip }}
port = {{ port }}
socket = ${directory:run}/mariadb.sock
data-directory = ${directory:mariadb-data}
tmp-directory = ${directory:tmp}
pid-file = ${directory:run}/mariadb.pid
error-log = ${directory:log}/mariadb_error.log
slow-query-log = ${directory:log}/mariadb_slowquery.log
long-query-time = {{ dumps(slapparameter_dict.get('long-query-time', 1)) }}
innodb-buffer-pool-size = {{ dumps(slapparameter_dict.get('innodb-buffer-pool-size', 0)) }}
innodb-log-file-size = {{ dumps(slapparameter_dict.get('innodb-log-file-size', 0)) }}
innodb-log-buffer-size = {{ dumps(slapparameter_dict.get('innodb-log-buffer-size', 0)) }}
relaxed-writes = {{ dumps(slapparameter_dict.get('relaxed-writes', False)) }}
{% if incremental_backup_retention_days > -1 -%}
binlog-path = ${directory:mariadb-backup-incremental}/binlog
# XXX: binlog rotation happens along with other log's rotation
binlog-expire-days = {{ dumps(incremental_backup_retention_days) }}
server-id = {{ dumps(slapparameter_dict.get('server-id', 1)) }}
{% else %}
binlog-path =
{%- endif %}
{%- for key, value in ssl_dict.items() -%}
ssl-{{ key }} = {{ value }}
{% endfor %}
[my-cnf]
recipe = slapos.recipe.template:jinja2
rendered = ${directory:etc}/mariadb.cnf
template = {{ parameter_dict['template-my-cnf'] }}
context = section parameter_dict my-cnf-parameters
[init-script-parameters]
database-list = {{ dumps(database_list + test_database_list) }}
[init-script]
recipe = slapos.recipe.template:jinja2
# XXX: is there a better location ?
rendered = ${directory:etc}/mariadb_initial_setup.sql
template = {{ parameter_dict['template-mariadb-initial-setup'] }}
context = section parameter_dict init-script-parameters
[update-mysql]
recipe = slapos.cookbook:generic.mysql.wrap_update_mysql
output = ${directory:services}/mariadb_update
binary = ${binary-wrap-mysql_upgrade:wrapper-path}
mysql = ${binary-wrap-mysql:wrapper-path}
init-script = ${init-script:rendered}
mysql_tzinfo_to_sql = ${binary-wrap-mysql_tzinfo_to_sql:wrapper-path}
[mysqld]
recipe = slapos.cookbook:generic.mysql.wrap_mysqld
output = ${directory:services}/mariadb
binary = {{ parameter_dict['mariadb-location'] }}/bin/mysqld
configuration-file = ${my-cnf:rendered}
data-directory = ${my-cnf-parameters:data-directory}
mysql-install-binary = {{ parameter_dict['mariadb-location'] }}/scripts/mysql_install_db
mysql-base-directory = {{ parameter_dict['mariadb-location'] }}
[logrotate-entry-mariadb]
recipe = slapos.cookbook:logrotate.d
logrotate-entries = ${logrotate:logrotate-entries}
backup = ${logrotate:backup}
name = mariadb
log = ${my-cnf-parameters:error-log} ${my-cnf-parameters:slow-query-log}
post = "${binary-wrap-mysql:wrapper-path}" -B -u root -e "FLUSH LOGS"
[binary-link]
recipe = slapos.cookbook:symbolic.link
target-directory = ${directory:bin}
link-binary = {{ dumps(parameter_dict['link-binary']) }}
[{{ section("binary-link-mysqlbinlog") }}]
< = binary-link
link-binary = {{ parameter_dict['mariadb-location'] }}/bin/mysqlbinlog
[binary-wrap-base]
recipe = slapos.cookbook:wrapper
# Note: --defaults-file must be the first argument, otherwise wrapped binary
# will reject it.
command-line = "{{ parameter_dict['mariadb-location'] }}/bin/${:command}" --defaults-file="${my-cnf:rendered}"
wrapper-path = ${directory:bin}/${:command}
parameters-extra = true
[binary-wrap-mysql]
< = binary-wrap-base
command = mysql
[binary-wrap-mysqldump]
< = binary-wrap-base
command = mysqldump
[binary-wrap-mysql_upgrade]
< = binary-wrap-base
command = mysql_upgrade
[binary-wrap-mysql_tzinfo_to_sql]
< = binary-wrap-base
command-line = "{{ parameter_dict['mariadb-location'] }}/bin/${:command}"
command = mysql_tzinfo_to_sql
[directory]
recipe = slapos.cookbook:mkdirectory
bin = ${buildout:directory}/bin
etc = ${buildout:directory}/etc
services = ${:etc}/run
promise = ${:etc}/promise
srv = ${buildout:directory}/srv
tmp = ${buildout:directory}/tmp
backup = ${:srv}/backup
mariadb-backup-full = ${:backup}/mariadb-full
mariadb-backup-incremental = ${:backup}/mariadb-incremental
mariadb-data = ${:srv}/mariadb
mariadb-ssl = ${:etc}/mariadb-ssl
var = ${buildout:directory}/var
log = ${:var}/log
run = ${:var}/run
[resiliency-exclude-file]
# Generate rdiff exclude file in case of resiliency
recipe = collective.recipe.template
input = inline: srv/mariadb/**
output = ${directory:srv}/exporter.exclude
[resiliency-after-import-script]
# Generate after import script used by importer instance of webrunner
recipe = collective.recipe.template
input = {{ parameter_dict['mariadb-resiliency-after-import-script'] }}
output = ${directory:srv}/runner-import-restore
mode = 755
dash = {{ parameter_dict['dash-location'] }}/bin/dash
[promise]
recipe = slapos.cookbook:wrapper
command-line = "{{ parameter_dict['bin-directory'] }}/is-local-tcp-port-opened" "${my-cnf-parameters:ip}" "${my-cnf-parameters:port}"
wrapper-path = ${directory:promise}/mariadb
parameters-extra = true
[monitor-instance-parameter]
monitor-httpd-ipv6 = {{ (ipv6_set | list)[0] }}
monitor-httpd-port = {{ port + 1 }}
monitor-title = Mariadb monitor
[buildout]
extends =
{{ logrotate_cfg }}
{{ parameter_dict['template-monitor'] }}
parts +=
publish
logrotate-entry-mariadb
binary-link
update-mysql
mysqld
resiliency-exclude-file
resiliency-after-import-script
promise
{{ part_list | join('\n ') }}
{% set part_list = [] -%}
{% macro section(name) %}{% do part_list.append(name) %}{{ name }}{% endmacro -%}
{% if slapparameter_dict['use-ipv6'] -%}
{% set ip = '[' ~ (ipv6_set | list)[0] ~ ']' -%}
{% else -%}
{% set ip = (ipv4_set | list)[0] -%}
{% endif -%}
{% set tcpv4_port = slapparameter_dict['tcpv4-port'] -%}
{% set relay = slapparameter_dict.get('relay', {}) -%}
{% set divert = slapparameter_dict.get('divert', []) -%}
{% set alias_dict = slapparameter_dict.get('alias-dict', {}) -%}
{% do alias_dict.setdefault('postmaster', [slapparameter_dict['postmaster']]) -%}
{% set smtpd_sasl_user = slapparameter_dict['smtpd-sasl-user'] -%}
{% set smtpd_sasl_password = slapparameter_dict['smtpd-sasl-password'] -%}
[smtpd-password]
recipe = slapos.cookbook:generate.password
storage-path =
[{{ section('publish') }}]
recipe = slapos.cookbook:publish.serialised
url = {{ dumps('smtp://' ~ urllib.quote_plus(smtpd_sasl_user) ~ ':' ~ urllib.quote_plus(smtpd_sasl_password) ~ '@' ~ ip ~ ':' ~ tcpv4_port) }}
[directory]
recipe = slapos.cookbook:mkdirectory
etc = ${buildout:directory}/etc
promise = ${:etc}/promise
etc-postfix = ${:etc}/postfix
etc-cyrus = ${:etc}/cyrus
run = ${:etc}/run
bin = ${buildout:directory}/bin
usr = ${buildout:directory}/usr
var = ${buildout:directory}/var
var-lib = ${:var}/lib
var-lib-postfix = ${:var-lib}/postfix
var-spool = ${:var}/spool
var-spool-postfix = ${:var-spool}/postfix
# Not used at buildout level, presence needed by postfix.
var-spool-postfix-active = ${:var-spool-postfix}/active
var-spool-postfix-bounce = ${:var-spool-postfix}/bounce
var-spool-postfix-corrupt = ${:var-spool-postfix}/corrupt
var-spool-postfix-defer = ${:var-spool-postfix}/defer
var-spool-postfix-deferred = ${:var-spool-postfix}/deferred
var-spool-postfix-flush = ${:var-spool-postfix}/flush
var-spool-postfix-hold = ${:var-spool-postfix}/hold
var-spool-postfix-incoming = ${:var-spool-postfix}/incoming
var-spool-postfix-maildrop = ${:var-spool-postfix}/maildrop
var-spool-postfix-pid = ${:var-spool-postfix}/pid
var-spool-postfix-private = ${:var-spool-postfix}/private
var-spool-postfix-public = ${:var-spool-postfix}/public
var-spool-postfix-saved = ${:var-spool-postfix}/saved
var-spool-postfix-trace = ${:var-spool-postfix}/trace
[configuration]
smtp = {{ dumps(tcpv4_port) }}
inet-interfaces = {{ dumps(ip) }}
alias-dict = {{ dumps(alias_dict) }}
relayhost = {{ dumps(relay.get('host')) }}
relay-sasl-credential = {{ dumps(relay.get('sasl-credential')) }}
divert = {{ dumps(divert) }}
cyrus-sasldb = ${directory:etc-cyrus}/postfix.gdbm
[userinfo]
recipe = slapos.cookbook:userinfo
[smtp-sasl-passwd]
recipe = slapos.recipe.template:jinja2
rendered = ${directory:etc-postfix}/sasl_passwd
{% if relay -%}
template = inline:{{ "{{ host }} {{ sasl_credential }}" }}
{%- else -%}
template = inline:
{%- endif %}
context =
key host configuration:relayhost
key sasl_credential configuration:relay-sasl-credential
mode = 600
[{{ section('cyrus-smtpd-conf') }}]
recipe = slapos.recipe.template:jinja2
rendered = ${directory:etc-cyrus}/smtpd.conf
template = inline:
pwcheck_method: auxprop
mech_list: PLAIN LOGIN
sasldb_path: {{ '{{ sasldb }}' }}
context =
key sasldb configuration:cyrus-sasldb
[{{ section('cyrus-smtpd-password') }}]
recipe = plone.recipe.command
stop-on-error = true
command =
rm -f '${configuration:cyrus-sasldb}' &&
echo '{{ smtpd_sasl_password }}' | '${wrapper-postfix-saslpasswd2:wrapper-path}' -pc '{{ smtpd_sasl_user }}'
update-command = ${:command}
[divert]
recipe = slapos.recipe.template:jinja2
rendered = ${directory:etc-postfix}/divert
{% if divert -%}
template = inline:{{ "/.*/ {{ ', '.join(divert) }}" }}
{%- else -%}
template = inline:
{%- endif %}
context =
key divert configuration:divert
[smtpd-ssl]
recipe = plone.recipe.command
stop-on-error = true
openssl = '{{ parameter_dict['openssl'] }}/bin/openssl'
cert = ${directory:etc-postfix}/smtpd.crt
key = ${directory:etc-postfix}/smtpd.pem
dh-512 = ${directory:etc-postfix}/dh512.pem
dh-2048 = ${directory:etc-postfix}/dh2048.pem
command =
${:openssl} dhparam -out '${:dh-512}' 512 &&
${:openssl} dhparam -out '${:dh-2048}' 2048 &&
${:update}
update =
${:openssl} req -newkey rsa -batch -new -x509 -days 3650 -nodes -keyout '${:key}' -out '${:cert}'
[{{ section('postfix-main-cf') }}]
recipe = slapos.recipe.template:jinja2
rendered = ${directory:etc-postfix}/main.cf
template = {{ parameter_dict['template-postfix-main-cf'] }}
context =
key bin_directory directory:bin
key usr_directory directory:usr
key queue_directory directory:var-spool-postfix
key data_directory directory:var-lib-postfix
key spool_directory directory:var-spool
key mail_owner userinfo:pw-name
key setgid_group userinfo:gr-name
key inet_interfaces configuration:inet-interfaces
key relayhost configuration:relayhost
key sasl_passwd typed-paths:smtp-sasl-passwd
key aliases typed-paths:aliases
key divert typed-paths:divert
key cyrus_directory directory:etc-cyrus
key cert smtpd-ssl:cert
key key smtpd-ssl:key
key dh_512 smtpd-ssl:dh-512
key dh_2048 smtpd-ssl:dh-2048
[{{ section('postfix-master-cf') }}]
recipe = slapos.recipe.template:jinja2
rendered = ${directory:etc-postfix}/master.cf
template = {{ parameter_dict['template-postfix-master-cf'] }}
context = key smtp configuration:smtp
[aliases]
recipe = slapos.recipe.template:jinja2
template = {{ parameter_dict['template-postfix-aliases'] }}
rendered = ${directory:etc-postfix}/aliases
context =
key alias_dict configuration:alias-dict
[typed-paths]
# Postfix-friendly rendering of file paths, prefixed with database type.
aliases = hash:${aliases:rendered}
smtp-sasl-passwd = hash:${smtp-sasl-passwd:rendered}
divert = pcre:${divert:rendered}
[{{ section('postalias-db') }}]
recipe = plone.recipe.command
stop-on-error = true
command = '${wrapper-postalias:wrapper-path}' '${typed-paths:aliases}' '${typed-paths:smtp-sasl-passwd}'
update-command = ${:command}
[wrapper-postfix-saslpasswd2]
recipe = slapos.cookbook:wrapper
parameters-extra = true
command-line = '{{ parameter_dict['cyrus-sasl-location'] }}/sbin/saslpasswd2' -f '${configuration:cyrus-sasldb}'
wrapper-path = ${directory:bin}/saslpasswd2
[base-wrapper]
recipe = slapos.cookbook:wrapper
environment =
MAIL_CONFIG=${directory:etc-postfix}
SASL_CONF_PATH=${directory:etc-cyrus}
parameters-extra = true
[base-bin-wrapper]
< = base-wrapper
command-line = ${:path}/${:basename}
wrapper-path = ${directory:bin}/${:basename}
[base-bin-bin-wrapper]
< = base-bin-wrapper
path = {{ parameter_dict['postfix-location'] }}/usr/bin
[base-sbin-bin-wrapper]
< = base-bin-wrapper
path = {{ parameter_dict['postfix-location'] }}/usr/sbin
{% for extend, basename_list in (
(
'base-bin-bin-wrapper',
(
'mailq',
'newaliases',
),
),
(
'base-sbin-bin-wrapper',
(
'postalias',
'postcat',
'postconf',
'postdrop',
'postfix',
'postkick',
'postlock',
'postlog',
'postmap',
'postmulti',
'postqueue',
'postsuper',
'sendmail',
),
),
) %}
{% for basename in basename_list -%}
[{{ section('wrapper-' ~ basename) }}]
< = {{ extend }}
basename = {{ basename }}
{% endfor %}
{% endfor %}
[{{ section('postfix-symlinks-libexec') }}]
recipe = slapos.cookbook:symbolic.link
target-directory = ${directory:usr}
link-binary =
{{ parameter_dict['postfix-location'] }}/usr/libexec
[{{ section('service-postfix-master') }}]
< = base-wrapper
command-line = ${directory:usr}/libexec/postfix/master
wrapper-path = ${directory:run}/postfix-master
[{{ section('postfix-promise') }}]
recipe = slapos.cookbook:check_port_listening
path = ${directory:promise}/postfix
hostname = {{ ip }}
port = {{ tcpv4_port }}
[buildout]
extends = {{ logrotate_cfg }}
parts =
{{ part_list | join('\n ') }}
{% set next_port = slapparameter_dict['tcpv4-port'] -%}
{% set ipv4 = (ipv4_set | list)[0] -%}
{% set backup_periodicity = slapparameter_dict.get('backup-periodicity', 'daily') -%}
{% set part_list = [] -%}
{% macro section(name) %}{% do part_list.append(name) %}{{ name }}{% endmacro -%}
{% set storage_dict = {} -%}
{% set default_zodb_path = buildout_directory ~ '/srv/zodb' -%}
{% set default_backup_path = buildout_directory ~ '/srv/backup/zodb' -%}
{% set bin_directory = parameter_dict['buildout-bin-directory'] -%}
[logrotate-base]
recipe = slapos.cookbook:logrotate.d
logrotate-entries = ${logrotate:logrotate-entries}
backup = ${logrotate:backup}
[zeo-base]
recipe = slapos.cookbook:zeo
log-path = ${directory:log}/${:base-name}.log
pid-path = ${directory:run}/${:base-name}.pid
conf-path = ${directory:etc}/${:base-name}.conf
wrapper-path = ${directory:services}/${:base-name}
binary-path = {{ bin_directory }}/runzeo
ip = {{ ipv4 }}
{% set known_tid_storage_identifier_dict = {} -%}
{% set zodb_dict = {} -%}
{% for name, zodb in slapparameter_dict['zodb-dict'].iteritems() -%}
{% do zodb_dict.setdefault(zodb.get('family', 'default').lower(), []).append((name, zodb)) -%}
{% endfor -%}
{% set tidstorage_port = next_port + len(zodb_dict) -%}
{% for family, zodb in zodb_dict.iteritems() -%}
{% set storage_list = [] -%}
{% set known_tid_storage_identifier_host = (ipv4, next_port), -%}
{% for name, zodb in zodb -%}
{% do storage_dict.__setitem__(name, {'server': ipv4 ~ ':' ~ next_port, 'storage': name}) %}
{% set path = zodb.get('path', '%(zodb)s/%(name)s.fs') % {'zodb': default_zodb_path, 'name': name} -%}
{% do storage_list.append((name, path)) -%}
{% set backup_directory = zodb.get('backup', '%(backup)s/%(name)s') % {'backup': default_backup_path, 'name': name} -%}
{# BBB: No mount-point specified because they're meaningless for ZEO and
TIDStorage. Pass '' for compatibility, and not None
because this would disable TIDStorage bootstrapping. -#}
{% do known_tid_storage_identifier_dict.__setitem__(json_module.dumps(
(known_tid_storage_identifier_host, name)),
(path, backup_directory, '')) -%}
{% endfor -%}
{% set zeo_section_name = 'zeo-' ~ family %}
[{{ zeo_section_name }}]
< = zeo-base
base-name = zeo-{{ family }}
port = {{ next_port }}
storage = {{ dumps(storage_list) }}
[{{ section("logrotate-" ~ zeo_section_name) }}]
< = logrotate-base
name = {{ "${" ~ zeo_section_name ~ ":base-name}" }}
log = {{ "${" ~ zeo_section_name ~ ":log-path}" }}
post = {{ bin_directory }}/slapos-kill --pidfile {{ "${" ~ zeo_section_name ~ ":pid-path}" }} -s USR2
[{{ section(zeo_section_name ~ "-promise") }}]
recipe = slapos.cookbook:check_port_listening
hostname = {{ "${" ~ zeo_section_name ~ ":ip}" }}
port = {{ "${" ~ zeo_section_name ~ ":port}" }}
path = ${directory:promises}/zeo-{{ family }}
{% set next_port = next_port + 1 -%}
{% endfor -%}
{% if backup_periodicity == 'never' -%}
{% set known_tid_storage_identifier_dict = () %}
{% set tidstorage_repozo_path = '' -%}
{% else -%}
[tidstorage]
recipe = slapos.cookbook:tidstorage
known-tid-storage-identifier-dict = {{ dumps(known_tid_storage_identifier_dict) }}
configuration-path = ${directory:etc}/tidstorage.py
ip = {{ ipv4 }}
port = {{ tidstorage_port }}
{% set tidstorage_repozo_path = slapparameter_dict.get('tidstorage-repozo-path', buildout_directory ~ '/srv/backup/tidstorage') -%}
timestamp-file-path = {{ tidstorage_repozo_path ~ '/repozo_tidstorage_timestamp.log' }}
{# BBB: recipe requires logfile-name for nothing because tidstorage runs in foreground mode -#}
logfile-name =
pidfile-name = ${directory:run}/tidstorage.pid
{# TODO: Add support for backup status file, so that the status file can be close to the ZODB (rather than close to the backup files). And do it efficiently, to not copy the whole status file every time. -#}
status-file = {{ tidstorage_repozo_path ~ '/tidstorage.tid' }}
tidstorage-repozo-binary = {{ bin_directory }}/tidstorage_repozo
tidstoraged-binary = {{ bin_directory }}/tidstoraged
repozo-binary = {{ bin_directory }}/repozo
repozo-wrapper = ${buildout:bin-directory}/tidstorage-repozo
{% if len(known_tid_storage_identifier_dict) > 1 -%}
tidstorage-wrapper = ${directory:services}/tidstoraged
[{{ section("promise-tidstorage") }}]
recipe = slapos.cookbook:check_port_listening
hostname = ${tidstorage:ip}
port = ${tidstorage:port}
path = ${directory:promises}/tidstorage
{% endif -%}
[{{ section("cron-entry-tidstorage-backup") }}]
# TODO:
# - configurable full/incremental
# - configurable retention
recipe = slapos.cookbook:cron.d
cron-entries = ${cron:cron-entries}
name = tidstorage
time = {{ dumps(backup_periodicity) }}
command = ${tidstorage:repozo-wrapper}
{% endif -%}
[publish]
recipe = slapos.cookbook:publish.serialised
storage-dict = {{ dumps(storage_dict) }}
{% if len(known_tid_storage_identifier_dict) > 1 -%}
tidstorage-ip = ${tidstorage:ip}
tidstorage-port = ${tidstorage:port}
{% else -%}
tidstorage-ip =
tidstorage-port =
{% endif -%}
# Used for ERP5 resiliency or (more probably)
# webrunner resiliency with erp5 inside.
[{{ section("resiliency-exclude-file") }}]
# Generate rdiff exclude file
recipe = collective.recipe.template
input = inline: srv/zodb/**
output = ${directory:srv}/exporter.exclude
[{{ section("resiliency-after-import-script") }}]
# Generate after import script used by importer instance of webrunner
recipe = collective.recipe.template
input = inline: #!/bin/sh
# DO NOT RUN THIS SCRIPT ON PRODUCTION INSTANCE
# OR ZODB DATA WILL BE ERASED.
# This script will restore the repozo backup to the real
# zodb location. It is launched by the clone (importer) instance of webrunner
# in the end of the import script.
# Depending on the output, it will create a file containing
# the status of the restoration (success or failure).
zodb_directory="${directory:zodb}"
zodb_backup_directory="{{ default_backup_path }}"
repozo="${tidstorage:repozo-binary}"
EXIT_CODE=0
{% for family, zodb in zodb_dict.iteritems() -%}
{% for name, zodb in zodb -%}
{% set zeo_section_name = 'zeo-' ~ family %}
storage_name="{{ name }}"
zodb_path="$storage_name.fs"
pid_file={{ "${" ~ zeo_section_name ~ ":pid-path}" }}
if [ -e "$pid_file" ]; then
pid=$(cat $pid_file) > /dev/null 2>&1
if kill -0 "$pid"; then
echo "Zeo is already running with pid $pid. Aborting."
exit 1
fi
fi
echo "Removing $zodb_path..."
echo "Restoring $storage_name into $zodb_path..."
$repozo --recover --output="$zodb_directory/$zodb_path" --repository="$zodb_backup_directory/$storage_name"
CURRENT_EXIT_CODE=$?
if [ ! "$CURRENT_EXIT_CODE"="0" ]; then
EXIT_CODE="$CURRENT_EXIT_CODE"
echo "$storage_name Backup restoration failed."
fi
{% endfor -%}
{% endfor -%}
exit $EXIT_CODE
output = ${directory:srv}/runner-import-restore
mode = 755
[directory]
recipe = slapos.cookbook:mkdirectory
bin = ${buildout:directory}/bin
etc = ${buildout:directory}/etc
services = ${:etc}/run
promises = ${:etc}/promise
srv = ${buildout:directory}/srv
var = ${buildout:directory}/var
log = ${:var}/log
run = ${:var}/run
backup-zodb = {{ default_backup_path }}
zodb = {{ default_zodb_path }}
tidstorage = {{ tidstorage_repozo_path }}
{% set next_port = next_port + 1 -%}
[monitor-instance-parameter]
monitor-httpd-ipv6 = {{ (ipv6_set | list)[0] }}
monitor-httpd-port = {{ next_port }}
monitor-title = ZODB monitor
[buildout]
extends =
{{ logrotate_cfg }}
{{ parameter_dict['template-monitor'] }}
parts +=
{{ part_list | join('\n ') }}
publish
{% set use_ipv6 = slapparameter_dict.get('use-ipv6', False) -%}
{% set next_port = slapparameter_dict['port-base'] -%}
{% set site_id = slapparameter_dict['site-id'] -%}
{% set zodb_dict = slapparameter_dict['zodb-dict'] -%}
{% set node_id_base = slapparameter_dict['name'] -%}
{% set part_list = [] -%}
{% set publish_list = [] -%}
{% set longrequest_logger_base_path = buildout_directory ~ '/var/log/longrequest_logger_' -%}
{% macro section(name) %}{% do part_list.append(name) %}{{ name }}{% endmacro -%}
{% set bin_directory = parameter_dict['buildout-bin-directory'] -%}
{#
XXX: This template only supports exactly one IPv4 and one IPv6 per
partition. No more (undefined result), no less (IndexError).
-#}
{% set ipv4 = (ipv4_set | list)[0] -%}
{% if slapparameter_dict['mysql-test-url-list'] -%}
[{{ section('test-runner') }}]
recipe = slapos.cookbook:erp5.test
certificate-authority-path = ${test-certificate-authority:ca-dir}
mysql-url-list = {{ dumps(slapparameter_dict['mysql-test-url-list']) }}
kumofs-url = {{ dumps(slapparameter_dict['kumofs-url']) }}
memcached-url = {{ dumps(slapparameter_dict['memcached-url']) }}
cloudooo-url = {{ dumps(slapparameter_dict['cloudooo-url']) }}
test-instance-path = ${directory:unit-test-path}
prepend-path = ${buildout:bin-directory}
run-unit-test = ${buildout:bin-directory}/runUnitTest
run-test-suite = ${buildout:bin-directory}/runTestSuite
openssl-binary = ${test-certificate-authority:openssl-binary}
run-unit-test-binary = {{ parameter_dict['bin-directory'] }}/runUnitTest
run-test-suite-binary = {{ parameter_dict['bin-directory'] }}/runTestSuite
[test-certificate-authority]
recipe = slapos.cookbook:certificate_authority
openssl-binary = ${binary-link:target-directory}/openssl
ca-dir = ${directory:test-ca-dir}
requests-directory = ${directory:test-ca-requests}
wrapper = ${directory:services}/test-ca
ca-private = ${directory:test-ca-private}
ca-certs = ${directory:test-ca-certs}
ca-newcerts = ${directory:test-ca-newcerts}
ca-crl = ${directory:test-ca-crl}
{%- endif %}
[directory]
recipe = slapos.cookbook:mkdirectory
bin = ${buildout:directory}/bin
etc = ${buildout:directory}/etc
instance = ${:srv}/erp5shared
instance-constraint = ${:instance}/Constraint
instance-document = ${:instance}/Document
instance-etc = ${:instance}/etc
instance-etc-package-include = ${:instance}/etc/package-include
instance-extensions = ${:instance}/Extensions
instance-import = ${:instance}/import
instance-lib = ${:instance}/lib
instance-products = ${:instance}/Products
instance-propertysheet = ${:instance}/PropertySheet
instance-tests = ${:instance}/tests
log = ${:var}/log
run = ${:var}/run
services = ${:etc}/run
service-on-watch = ${:etc}/service
srv = ${buildout:directory}/srv
tmp = ${buildout:directory}/tmp
var = ${buildout:directory}/var
promises = ${:etc}/promise
unit-test-path = ${:srv}/test-instance/unit_test
test-ca-dir = ${:srv}/test-ca
test-ca-requests = ${:test-ca-dir}/requests
test-ca-private = ${:test-ca-dir}/private
test-ca-certs = ${:test-ca-dir}/certs
test-ca-newcerts = ${:test-ca-dir}/newcerts
test-ca-crl = ${:test-ca-dir}/crl
ca-dir = ${:srv}/ca
ca-requests = ${:ca-dir}/requests
ca-private = ${:ca-dir}/private
ca-certs = ${:ca-dir}/certs
ca-newcerts = ${:ca-dir}/newcerts
ca-crl = ${:ca-dir}/crl
[binary-link]
recipe = slapos.cookbook:symbolic.link
target-directory = ${directory:bin}
link-binary = {{ dumps(parameter_dict['link-binary']) }}
[certificate-authority-common]
requests-directory = ${directory:ca-requests}
ca-dir = ${directory:ca-dir}
ca-private = ${directory:ca-private}
ca-certs = ${directory:ca-certs}
ca-newcerts = ${directory:ca-newcerts}
ca-crl = ${directory:ca-crl}
[{{ section('certificate-authority') }}]
< = certificate-authority-common
recipe = slapos.cookbook:certificate_authority
openssl-binary = ${binary-link:target-directory}/openssl
wrapper = ${directory:services}/ca
{% if use_ipv6 -%}
{% set ipv6 = (ipv6_set | list)[0] -%}
[ipv6toipv4-base]
recipe = slapos.cookbook:ipv6toipv4
runner-path = ${directory:services}/${:base-name}
6tunnel-path = {{ parameter_dict['6tunnel'] }}/bin/6tunnel
shell-path = {{ parameter_dict['dash'] }}/bin/dash
ipv4 = {{ ipv4 }}
ipv6 = {{ ipv6 }}
{% endif -%}
{% set hosts_dict = {} -%}
{% for alias, url in (
('erp5-memcached-volatile', slapparameter_dict['memcached-url']),
('erp5-memcached-persistent', slapparameter_dict['kumofs-url']),
('erp5-cloudooo', slapparameter_dict['cloudooo-url']),
('erp5-smtp', slapparameter_dict['smtp-url']),
) -%}
{% do hosts_dict.__setitem__(
alias,
urlparse.urlparse(url).hostname,
) -%}
{%- endfor %}
{% for i, url in enumerate(slapparameter_dict['mysql-url-list']) -%}
{% do hosts_dict.__setitem__(
'erp5-catalog-' ~ i,
urlparse.urlparse(url).hostname,
) -%}
{%- endfor %}
{% do hosts_dict.update(slapparameter_dict['hosts-dict']) -%}
[host-common]
[hosts-parameter]
# Used for both hosts and hostaliases sections.
host-dict = {{ dumps(hosts_dict) }}
hostalias-dict = {{ dumps(slapparameter_dict['hostalias-dict']) }}
# Note: there is a subtle difference between hosts and hostaliases files:
# - hosts files start with resolved, followed by alias(es) (only one alias per
# line in this case)
# - hostaliases start with alias, followed by resolved
# ...so it's not possible to merge these templates (not a big deal anyway).
[hostaliases]
recipe = slapos.recipe.template:jinja2
template = inline: {{ '
{% for alias, aliased in host_dict.items() -%}
{{ alias }} {{ aliased }}
{% endfor %}
' }}
rendered = ${directory:etc}/hostaliases
context = key host_dict hosts-parameter:hostalias-dict
[hosts]
recipe = slapos.recipe.template:jinja2
template = inline: {{ '
{% for alias, aliased in host_dict.items() -%}
{{ aliased }} {{ alias }}
{% endfor %}
' }}
rendered = ${directory:etc}/hosts
context = key host_dict hosts-parameter:host-dict
[preload-userhosts-runzope-parameter]
runzope-binary = {{ bin_directory }}/runzope
userhosts = {{ parameter_dict['userhosts'] }}
shell-path = {{ parameter_dict['dash'] }}/bin/dash
hosts = ${hosts:rendered}
hostaliases = ${hostaliases:rendered}
[preload-userhosts-runzope]
recipe = slapos.recipe.template:jinja2
rendered = ${directory:bin}/runzope_userhosts_preloaded
context = section parameter_dict preload-userhosts-runzope-parameter
template = {{ parameter_dict['runzope-userhosts-preloaded-template'] }}
mode = 755
{# Hack to deploy SSL certs via instance parameters -#}
{% for zodb in zodb_dict.itervalues() -%}
{% set storage_dict = zodb.setdefault('storage-dict', {}) -%}
{% if zodb['type'] == 'neo' and storage_dict.get('ssl', 1) -%}
{% for k, v in (('_ca', 'ca.crt'),
('_cert', 'neo.crt'),
('_key', 'neo.key')) -%}
{% if k in storage_dict -%}
[{{ section('neo-ssl-' + k[1:]) }}]
recipe = slapos.recipe.template:jinja2
rendered = ${directory:etc}/{{v}}
template = inline:{{'{{'}}pem}}
context = key pem :pem
pem = {{dumps(storage_dict.pop(k))}}
{% endif -%}
{% endfor -%}
{% endif -%}
{% endfor -%}
{# endhack -#}
[zope-base]
recipe = slapos.cookbook:generic.zope.zeo.client
inituser = ${directory:instance}/inituser
user = {{ dumps(slapparameter_dict['inituser-login']) }}
password = {{ dumps(slapparameter_dict['inituser-password']) }}
timezone = {{ dumps(slapparameter_dict['timezone']) }}
tmp-path = ${directory:tmp}
instancehome-path = ${directory:instance}
home-path = ${buildout:directory}
bin-path = ${directory:bin}:{{ parameter_dict['coreutils'] }}/bin
site-zcml = ${directory:instance-etc}/site.zcml
runzope-binary = ${preload-userhosts-runzope:rendered}
bt5-repository =
[zope-conf-parameter-base]
ip = {{ ipv4 }}
site-id = {{ site_id }}
{% set zeo_dict = slapparameter_dict.get('zodb-zeo', {}) -%}
{% for name, zodb in zodb_dict.iteritems() -%}
{% set storage_dict = zodb.setdefault('storage-dict', {}) -%}
{% if zodb['type'] == 'zeo' -%}
{% do storage_dict.update(zeo_dict.get(name, ())) -%}
{% else -%}
{% if name == slapparameter_dict.get('neo-name') -%}
{% do storage_dict.update(master_nodes=slapparameter_dict['neo-masters'],
name=slapparameter_dict['neo-cluster']) -%}
{% endif -%}
{{ assert(storage_dict['master_nodes'], name) }}
{% if storage_dict.pop('ssl', 1) -%}
{% do storage_dict.update(ca='~/etc/ca.crt',
cert='~/etc/neo.crt',
key='~/etc/neo.key') -%}
{% endif -%}
{% endif -%}
{% endfor -%}
developer-list = {{ dumps(slapparameter_dict['developer-list']) }}
instance = ${directory:instance}
instance-products = ${directory:instance-products}
deadlock-path = /manage_debug_threads
deadlock-debugger-password = {{ dumps(slapparameter_dict['deadlock-debugger-password']) }}
{% if slapparameter_dict.get('tidstorage-ip') -%}
tidstorage-ip = {{ dumps(slapparameter_dict['tidstorage-ip']) }}
tidstorage-port = {{ dumps(slapparameter_dict['tidstorage-port']) }}
{% endif -%}
promise-path = ${erp5-promise:promise-path}
{% set thread_amount = slapparameter_dict['thread-amount'] -%}
thread-amount = {{ thread_amount }}
{% set webdav = slapparameter_dict['webdav'] -%}
webdav = {{ dumps(webdav) }}
{% if webdav -%}
{% set timerserver_interval = 0 -%}
{% else -%}
{% set timerserver_interval = slapparameter_dict['timerserver-interval'] -%}
{%- endif %}
timerserver-interval = {{ dumps(timerserver_interval) }}
[zope-conf-base]
recipe = slapos.recipe.template:jinja2
template = {{ parameter_dict['zope-conf-template'] }}
[logrotate-entry-base]
recipe = slapos.cookbook:logrotate.d
logrotate-entries = ${logrotate:logrotate-entries}
backup = ${logrotate:backup}
{% macro zope(
index,
port,
longrequest_logger_timeout,
longrequest_logger_interval
) -%}
{% set name = 'zope-' ~ index -%}
{% set conf_name = name ~ '-conf' -%}
{% set conf_parameter_name = conf_name ~ '-param' -%}
{% set zope_tunnel_section_name = name ~ '-ipv6toipv4' -%}
{% set zope_tunnel_base_name = zope_tunnel_section_name -%}
[{{ conf_parameter_name }}]
< = zope-conf-parameter-base
pid-file = ${directory:run}/{{ name }}.pid
lock-file = ${directory:run}/{{ name }}.lock
port = {{ port }}
event-log = ${directory:log}/{{ name }}-event.log
z2-log = ${directory:log}/{{ name }}-Z2.log
node-id = {{ dumps(node_id_base ~ '-' ~ index) }}
{% set log_list = [] -%}
{% set import_set = set() -%}
{% for db_name, zodb in zodb_dict.iteritems() -%}
{% do zodb.setdefault('pool-size', thread_amount) -%}
{% if zodb['type'] == 'neo' -%}
{% do import_set.add('neo.client') -%}
{% set log = name ~ '-neo-' ~ db_name ~ '.log' -%}
{% do log_list.append('${directory:log}/' + log) -%}
{% do zodb['storage-dict'].update(logfile='~/var/log/'+log) -%}
{% endif -%}
{% endfor -%}
import-list = {{ dumps(list(import_set)) }}
zodb-dict = {{ dumps(zodb_dict) }}
{% if longrequest_logger_interval > 0 -%}
longrequest-logger-file = {{ longrequest_logger_base_path ~ name ~ ".log" }}
longrequest-logger-timeout = {{ longrequest_logger_timeout }}
longrequest-logger-interval = {{ longrequest_logger_interval }}
{% else -%}
longrequest-logger-file =
{% endif -%}
[{{ conf_name }}]
< = zope-conf-base
rendered = ${directory:etc}/{{ name }}.conf
context =
section parameter_dict {{ conf_parameter_name }}
[{{ section(name) }}]
< = zope-base
wrapper = ${directory:service-on-watch}/{{ name }}
configuration-file = {{ '${' ~ conf_name ~ ':rendered}' }}
[{{ section("promise-" ~ name) }}]
recipe = slapos.cookbook:check_port_listening
hostname = {{ ipv4 }}
port = {{ port }}
path = ${directory:promises}/{{ name }}
{% set extra_path_list = [] -%}
{% set shell_escaped_extra_path_list = [] -%}
{% for line in parameter_dict['extra-path-list'].splitlines() -%}
{% set line = line.strip() -%}
{% do extra_path_list.append(line) -%}
{% do shell_escaped_extra_path_list.append(line.replace("\x27", "\x27\\\x27\x27")) -%}
{% endfor -%}
[{{ section("promise-" ~ name ~ "-is-running-actual-product") }}]
recipe = slapos.cookbook:wrapper
command-line = '{{ parameter_dict['bin-directory'] }}/is-process-older-than-dependency-set' '{{ "${" ~ conf_parameter_name ~ ":pid-file}" }}' {{ " ".join(shell_escaped_extra_path_list) }}
wrapper-path = ${directory:promises}/{{ name }}-is-running-actual-product
parameters-extra = true
{% if use_ipv6 -%}
[{{ zope_tunnel_section_name }}]
< = ipv6toipv4-base
base-name = {{ zope_tunnel_base_name }}
ipv6-port = {{ port }}
ipv4-port = {{ port }}
{% do publish_list.append(("[" ~ ipv6 ~ "]:" ~ port, thread_amount, webdav)) -%}
[{{ section("promise-tunnel-" ~ name) }}]
recipe = slapos.cookbook:check_port_listening
hostname = {{ '${' ~ zope_tunnel_section_name ~ ':ipv6}' }}
port = {{ '${' ~ zope_tunnel_section_name ~ ':ipv6-port}' }}
path = ${directory:promises}/{{ zope_tunnel_base_name }}
{% else -%}
{% do publish_list.append((ipv4 ~ ":" ~ port, thread_amount, webdav)) -%}
{% endif -%}
[{{ section('logrotate-entry-' ~ name) }}]
< = logrotate-entry-base
name = {{ name }}
log = {{ '${' ~ conf_parameter_name ~ ':event-log}' }} {{ '${' ~ conf_parameter_name ~ ':z2-log}' }} {{ '${' ~ conf_parameter_name ~ ':longrequest-logger-file}' }} {{ ' '.join(log_list) }}
post = {{ bin_directory }}/slapos-kill --pidfile {{ '${' ~ conf_parameter_name ~ ':pid-file}' }} -s USR2
{% endmacro -%}
{% for i in range(slapparameter_dict['instance-count']) -%}
{{ zope(
i,
next_port,
slapparameter_dict['longrequest-logger-timeout'],
slapparameter_dict['longrequest-logger-interval'],
) }}
{% set next_port = next_port + 1 -%}
{% endfor -%}
[publish]
recipe = slapos.cookbook:publish.serialised
zope-address-list = {{ dumps(publish_list) }}
{#
Note: hosts_dist is generated at zope level rather than at erp5 (root partition)
level, as it is easier: we can access urls as python values trivially here.
This has the downside of making each zope partition publish the (hopefuly) same
dict toward erp5 partition, violating the DRY principle and making the intent
hard to guess.
-#}
hosts-dict = {{ dumps(hosts_dict) }}
[erp5-promise]
recipe = slapos.cookbook:erp5.promise
promise-path = ${directory:etc}/erp5promise.cfg
kumofs-url = {{ dumps(slapparameter_dict['kumofs-url']) }}
memcached-url = {{ dumps(slapparameter_dict['memcached-url']) }}
cloudooo-url = {{ dumps(slapparameter_dict['cloudooo-url']) }}
smtp-url = {{ dumps(slapparameter_dict['smtp-url']) }}
bt5 = {{ dumps(slapparameter_dict['bt5']) }}
bt5-repository-url = {{ dumps(slapparameter_dict['bt5-repository-url']) }}
[monitor-instance-parameter]
monitor-httpd-ipv6 = {{ (ipv6_set | list)[0] }}
monitor-httpd-port = {{ next_port }}
monitor-title = Zope monitor
[buildout]
extends =
{{ logrotate_cfg }}
{{ parameter_dict['template-monitor'] }}
parts +=
erp5-promise
{{ part_list | join('\n ') }}
publish
versions = versions
[versions]
slapos.core = {{ slapos_core_version }}
[buildout]
extends = {{ instance_common_cfg }}
[jinja2-template-base]
context +=
raw slapos_core_version {{ slapos_core_version }}
[dynamic-template-cloudooo-parameters]
cairo = {{ cairo_location }}
cups = {{ cups_location }}
dbus = {{ dbus_location }}
dbus-glib = {{ dbus_glib_location }}
file = {{ file_location }}
fontconfig = {{ fontconfig_location }}
freetype = {{ freetype_location }}
glib = {{ glib_location }}
glu = {{ glu_location }}
libICE = {{ libICE_location }}
libSM = {{ libSM_location }}
libX11 = {{ libX11_location }}
libXau = {{ libXau_location }}
libXdmcp = {{ libXdmcp_location }}
libXext = {{ libXext_location }}
libXrender = {{ libXrender_location }}
libexpat = {{ libexpat_location }}
libffi = {{ libffi_location }}
libpng12 = {{ libpng12_location }}
libxcb = {{ libxcb_location }}
mesa = {{ mesa_location }}
pixman = {{ pixman_location }}
xdamage = {{ xdamage_location }}
xfixes = {{ xfixes_location }}
zlib = {{ zlib_location }}
libreoffice-bin = {{ libreoffice_bin_location }}
fonts = {{ fonts_location }}
buildout-bin-directory = {{ buildout_bin_directory }}
6tunnel = {{ sixtunnel_location }}
dash = {{ dash_location }}
template-monitor = {{ dumps(template_monitor) }}
[dynamic-template-cloudooo]
<= jinja2-template-base
template = {{ template_cloudooo }}
filename = instance-cloudoo.cfg
extra-context =
section parameter_dict dynamic-template-cloudooo-parameters
[dynamic-template-postfix-parameters]
bin-directory = {{ bin_directory }}
cyrus-sasl-location = {{ cyrus_sasl_location }}
openssl = {{ openssl_location }}
postfix-location = {{ postfix_location }}
template-postfix-aliases = {{ template_postfix_aliases }}
template-postfix-main-cf = {{ template_postfix_main_cf }}
template-postfix-master-cf = {{ template_postfix_master_cf }}
[dynamic-template-postfix]
< = jinja2-template-base
template = {{ template_postfix }}
filename = instance-postfix.cfg
extensions = jinja2.ext.do
extra-context =
section parameter_dict dynamic-template-postfix-parameters
import urllib urllib
[dynamic-template-erp5-parameters]
jupyter-enable-default = {{ jupyter_enable_default }}
local-bt5-repository = {{ local_bt5_repository }}
[dynamic-template-erp5]
<= jinja2-template-base
template = {{ template_erp5 }}
filename = instance-erp5.cfg
extra-context =
key jupyter_enable_default dynamic-template-erp5-parameters:jupyter-enable-default
key local_bt5_repository dynamic-template-erp5-parameters:local-bt5-repository
key openssl_location :openssl-location
import urlparse urlparse
import-list =
rawfile root_common {{ root_common }}
openssl-location = {{ openssl_location }}
[dynamic-template-balancer-parameters]
apache = {{ apache_location }}
openssl = {{ openssl_location }}
haproxy = {{ haproxy_location }}
bin-directory = {{ bin_directory }}
6tunnel = {{ sixtunnel_location }}
dash = {{ dash_location }}
template-haproxy-cfg = {{ template_haproxy_cfg }}
template-apache-conf = {{ template_apache_conf }}
template-monitor = {{ dumps(template_monitor) }}
[dynamic-template-balancer]
<= jinja2-template-base
template = {{ template_balancer }}
filename = instance-balancer.cfg
extra-context =
section parameter_dict dynamic-template-balancer-parameters
[dynamic-template-zeo-parameters]
buildout-bin-directory = {{ buildout_bin_directory }}
template-monitor = {{ dumps(template_monitor) }}
[dynamic-template-zeo]
<= jinja2-template-base
template = {{ template_zeo }}
filename = instance-zeo.cfg
extra-context =
key buildout_directory buildout:directory
section parameter_dict dynamic-template-zeo-parameters
import json_module json
[dynamic-template-zope-parameters]
bin-directory = {{ bin_directory }}
zope-conf-template = {{ template_zope_conf }}
buildout-bin-directory = {{ buildout_bin_directory }}
6tunnel = {{ sixtunnel_location }}
coreutils = {{ coreutils_location }}
dash = {{ dash_location }}
jsl = {{ jsl_location }}
link-binary = {{ dumps(zope_link_binary) }}
userhosts = {{ userhosts_location }}
runzope-userhosts-preloaded-template = {{ template_runzope_userhosts_preloaded }}
template-monitor = {{ dumps(template_monitor) }}
extra-path-list = {{ dumps(extra_path_list) }}
[dynamic-template-zope]
<= jinja2-template-base
template = {{ template_zope }}
filename = instance-zope.cfg
extra-context =
key buildout_directory buildout:directory
section parameter_dict dynamic-template-zope-parameters
import urlparse urlparse
[dynamic-template-kumofs-parameters]
dash-location = {{ dash_location }}
dcron-location = {{ dcron_location }}
gzip-location = {{ gzip_location }}
kumo-location = {{ kumo_location }}
logrotate-location = {{ logrotate_location }}
template-monitor = {{ dumps(template_monitor) }}
[dynamic-template-kumofs]
<= jinja2-template-base
template = {{ template_kumofs }}
filename = instance-kumofs.cfg
extra-context =
section parameter_dict dynamic-template-kumofs-parameters
[dynamic-template-mariadb-parameters]
coreutils-location = {{ coreutils_location }}
dash-location = {{ dash_location }}
findutils-location = {{ findutils_location }}
gzip-location = {{ gzip_location }}
mariadb-location = {{ mariadb_location }}
template-my-cnf = {{ template_my_cnf }}
template-mariadb-initial-setup = {{ template_mariadb_initial_setup }}
link-binary = {{ dumps(mariadb_link_binary) }}
bin-directory = {{ bin_directory }}
mariadb-resiliency-after-import-script = {{ mariadb_resiliency_after_import_script }}
template-monitor = {{ template_monitor }}
[dynamic-template-mariadb]
<= jinja2-template-base
template = {{ template_mariadb }}
filename = instance-mariadb.cfg
extra-context =
section parameter_dict dynamic-template-mariadb-parameters
[dynamic-template-create-erp5-site-parameters]
instance-erp5 = ${dynamic-template-erp5:rendered}
template-create-erp5-site-real = {{ template_create_erp5_site_real }}
dash-location = {{ dash_location }}
curl-location = {{ curl_location }}
[dynamic-template-create-erp5-site]
<= jinja2-template-base
template = {{ template_create_erp5_site }}
filename = instance-create-erp5-site.cfg
extra-context =
section parameter_dict dynamic-template-create-erp5-site-parameters
# we need this value to be present in a section,
# for slapos.cookbook:switch-softwaretype to work
[dynamic-template-jupyter]
rendered = {{ template_jupyter_cfg }}
[switch-softwaretype]
recipe = slapos.cookbook:switch-softwaretype
override = {{ dumps(override_switch_softwaretype |default) }}
# Public software types
default = dynamic-template-erp5:rendered
create-erp5-site = dynamic-template-create-erp5-site:rendered
# BBB
RootSoftwareInstance = ${:default}
# Internal software types
kumofs = dynamic-template-kumofs:rendered
cloudooo = dynamic-template-cloudooo:rendered
mariadb = dynamic-template-mariadb:rendered
balancer = dynamic-template-balancer:rendered
postfix = dynamic-template-postfix:rendered
zodb-zeo = dynamic-template-zeo:rendered
zodb-neo = neo-storage-mysql:rendered
zope = dynamic-template-zope:rendered
jupyter = dynamic-template-jupyter:rendered
USE mysql;
DROP FUNCTION IF EXISTS last_insert_grn_id;
{% set mroonga = parameter_dict.get('mroonga', 'ha_mroonga.so') -%}
{% if mroonga %}CREATE FUNCTION last_insert_grn_id RETURNS INTEGER SONAME '{{ mroonga }}';{% endif %}
DROP FUNCTION IF EXISTS sphinx_snippets;
#CREATE FUNCTION sphinx_snippets RETURNS STRING SONAME 'ha_sphinx.so';
{% macro database(name, user, password) -%}
CREATE DATABASE IF NOT EXISTS `{{ name }}`;
{% if user -%}
GRANT ALL PRIVILEGES ON `{{ name }}`.* TO `{{ user }}`@`%` IDENTIFIED BY '{{ password }}';
GRANT ALL PRIVILEGES ON `{{ name }}`.* TO `{{ user }}`@localhost IDENTIFIED BY '{{ password }}';
{%- endif %}
{% endmacro -%}
{% for entry in parameter_dict['database-list'] -%}
{{ database(entry['name'], entry.get('user'), entry.get('password')) }}
{% endfor -%}
{% set socket = parameter_dict['socket'] -%}
# ERP5 buildout my.cnf template based on my-huge.cnf shipped with mysql
# The MySQL server
[mysqld]
# ERP5 by default requires InnoDB storage. MySQL by default fallbacks to using
# different engine, like MyISAM. Such behaviour generates problems only, when
# tables requested as InnoDB are silently created with MyISAM engine.
#
# Loud fail is really required in such case.
sql_mode="NO_ENGINE_SUBSTITUTION"
skip_show_database
{% set ip = parameter_dict.get('ip') -%}
{% if ip -%}
bind_address = {{ ip }}
port = {{ parameter_dict['port'] }}
{% else -%}
skip_networking
{% endif -%}
socket = {{ socket }}
datadir = {{ parameter_dict['data-directory'] }}
tmpdir = {{ parameter_dict['tmp-directory'] }}
pid_file = {{ parameter_dict['pid-file'] }}
log_error = {{ parameter_dict['error-log'] }}
slow_query_log
slow_query_log_file = {{ parameter_dict['slow-query-log'] }}
long_query_time = {{ parameter_dict['long-query-time'] }}
max_allowed_packet = 128M
query_cache_size = 32M
innodb_file_per_table = 0
plugin_load = ha_mroonga.so;handlersocket.so
# By default only 100 connections are allowed, when using zeo
# we may have much more connections
max_connections = 1000
{% set innodb_buffer_pool_size = parameter_dict['innodb-buffer-pool-size'] -%}
{% if innodb_buffer_pool_size %}innodb_buffer_pool_size = {{ innodb_buffer_pool_size }}{% endif %}
{% set innodb_log_file_size = parameter_dict['innodb-log-file-size'] -%}
{% if innodb_log_file_size %} innodb_log_file_size = {{ innodb_log_file_size }}{% endif %}
{% set innodb_log_buffer_size = parameter_dict['innodb-log-buffer-size'] -%}
{% if innodb_log_buffer_size %} innodb_log_buffer_size = {{ innodb_log_buffer_size }}{% endif %}
# very important to allow parallel indexing
# Note: this is compatible with binlog-based incremental backups, because ERP5
# doesn't use "insert ... select" (in any number of queries) pattern.
innodb_locks_unsafe_for_binlog = 1
{% set log_bin = parameter_dict['binlog-path'] -%}
{% if log_bin -%}
log_bin = {{ log_bin }}
{% set binlog_expire_days = parameter_dict['binlog-expire-days'] -%}
{% if binlog_expire_days > 0 %}expire_logs_days = {{ binlog_expire_days }}{% endif %}
server_id = {{ parameter_dict['server-id'] }}
{% endif %}
# Some dangerous settings you may want to uncomment temporarily
# if you only want performance or less disk access.
{% set x = '' if parameter_dict['relaxed-writes'] else '#' -%}
{{x}}innodb_flush_log_at_trx_commit = 0
{{x}}innodb_flush_method = nosync
{{x}}innodb_doublewrite = 0
{{x}}sync_frm = 0
# Force utf8 usage
collation_server = utf8_unicode_ci
character_set_server = utf8
skip_character_set_client_handshake
{% if 'ssl-key' in parameter_dict -%}
ssl_cert = {{ parameter_dict['ssl-crt'] }}
ssl_key = {{ parameter_dict['ssl-key'] }}
{% if 'ssl-ca-crt' in parameter_dict -%}
ssl_ca = {{ parameter_dict['ssl-ca-crt'] }}
{%- endif %}
{% if 'ssl-crl' in parameter_dict -%}
ssl_crl = {{ parameter_dict['ssl-crl'] }}
{%- endif %}
{% if 'ssl-cipher' in parameter_dict -%}
ssl_cipher = {{ parameter_dict['ssl-cipher'] }}
{%- endif %}
{%- endif %}
[client]
socket = {{ socket }}
user = root
[mysql]
no_auto_rehash
[mysqlhotcopy]
interactive_timeout
# See http://www.postfix.org/aliases.5.html for format
{% for name, alias_list in alias_dict.items() -%}
{{ name }}: {{ alias_list | join(', ') }}
{% endfor %}
# http://www.postfix.org/STANDARD_CONFIGURATION_README.html
# http://www.postfix.org/postconf.5.html
queue_directory = {{ queue_directory }}
command_directory = {{ bin_directory }}
daemon_directory = {{ usr_directory }}/libexec/postfix
data_directory = {{ data_directory }}
mail_owner = {{ mail_owner }}
alias_maps = {{ aliases }}
alias_database = {{ aliases }}
mail_spool_directory = {{ spool_directory }}
sendmail_path =
newaliases_path =
mailq_path =
setgid_group = {{ setgid_group }}
html_directory =
manpage_directory =
sample_directory =
readme_directory =
inet_interfaces = {{ inet_interfaces }}
virtual_alias_maps = {{ divert }}
# Compared to default:
# - remove X-related variables, irrelevant for slapos, to be concise
# - add SASL_CONF_PATH to have per-partition cyrus-sasl configuration
import_environment =
MAIL_CONFIG MAIL_DEBUG MAIL_LOGTAG TZ LANG=C
SASL_CONF_PATH
# Mandatory sasl auth over TLS
# XXX: no man-in-the-middle protection
smtpd_tls_cert_file = {{ cert }}
smtpd_tls_key_file = {{ key }}
smtpd_tls_dh512_param_file = {{ dh_512 }}
{#
Note: 1024 vs. 2048 is not a typo, but what is actually recommended in
postfix documentation
-#}
smtpd_tls_dh1024_param_file = {{ dh_2048 }}
smtpd_tls_security_level = encrypt
smtpd_sasl_auth_enable = yes
# Reject as many bogus cases as soon as possible, so errors are visible to ERP5
# developper rather than relying on bounces.
smtpd_recipient_restrictions =
reject_non_fqdn_recipient
reject_unknown_recipient_domain
permit_sasl_authenticated
reject
# Disable local delivery
local_transport = error
{% if relayhost -%}
relayhost = {{ relayhost }}
smtp_tls_security_level = encrypt
smtp_tls_session_cache_database = btree:{{ data_directory }}/smtp_scache
smtp_sasl_auth_enable = yes
smtp_sasl_password_maps = {{ sasl_passwd }}
smtp_sasl_tls_security_options = noanonymous
{%- endif %}
# http://www.postfix.org/master.5.html
# ==========================================================================
# service type private unpriv chroot wakeup maxproc command + args
# (yes) (yes) (yes) (never) (100)
# ==========================================================================
{{ smtp }} inet n - n - - smtpd
pickup unix n - n 60 1 pickup
cleanup unix n - n - 0 cleanup
qmgr unix n - n 300 1 qmgr
tlsmgr unix - - n 1000? 1 tlsmgr
rewrite unix - - n - - trivial-rewrite
bounce unix - - n - 0 bounce
defer unix - - n - 0 bounce
trace unix - - n - 0 bounce
verify unix - - n - 1 verify
flush unix n - n 1000? 0 flush
proxymap unix - - n - - proxymap
proxywrite unix - - n - 1 proxymap
smtp unix - - n - - smtp
relay unix - - n - - smtp
showq unix n - n - - showq
error unix - - n - - error
retry unix - - n - - error
discard unix - - n - - discard
local unix - n n - - local
virtual unix - n n - - virtual
lmtp unix - - n - - lmtp
anvil unix - - n - 1 anvil
scache unix - - n - 1 scache
#!{{ parameter_dict['shell-path'] }}
HOSTALIASES='{{ parameter_dict['hostaliases'] }}' HOSTS='{{ parameter_dict['hosts'] }}' exec '{{ parameter_dict['userhosts'] }}' '{{ parameter_dict['runzope-binary'] }}' "$@"
#!${:dash}
# DO NOT RUN THIS SCRIPT ON PRODUCTION INSTANCE
# OR MYSQL DATA WILL BE ERASED.
# This script will import the dump of the mysql database to the real
# database. It is launched by the clone (importer) instance of webrunner
# in the end of the import script.
# Depending on the output, it will create a file containing
# the status of the restoration (success or failure)
set -e
mysql_executable="${binary-wrap-mysql:wrapper-path}"
mysqldump_executable="${binary-wrap-mysqldump:wrapper-path}"
mariadb_data_directory="${directory:mariadb-data}"
mariadb_backup_directory="${directory:mariadb-backup-full}"
instance_directory="${buildout:directory}"
pid_file="${my-cnf-parameters:pid-file}"
binlog_path="${my-cnf-parameters:binlog-path}"
# Make sure mariadb is not already running
if [ -e "$pid_file" ]; then
pid=$(cat $pid_file) > /dev/null 2>&1
if kill -0 "$pid"; then
echo "Mariadb is already running with pid $pid. Aborting."
exit 1
fi
fi
echo "Deleting existing database..."
rm -r $mariadb_data_directory/* >/dev/null 2>&1 || true
echo "Adapting binlog database to new paths..."
new_binlog_directory="$(dirname $binlog_path)"
binlog_index_file="$new_binlog_directory/binlog.index"
old_binlog_directory="$(dirname $(head -n 1 $binlog_index_file))"
sed -e "s|$old_binlog_directory|$new_binlog_directory|g" $binlog_index_file > $binlog_index_file
echo "Starting mariadb..."
# XXX hardcoded
$instance_directory/etc/run/mariadb &
mysqld_pid=$!
trap "kill $mysqld_pid" EXIT TERM INT
sleep 30
# If mysql has stopped, abort
if ! [ -d /proc/$mysql_pid ]; then
echo "mysqld exited, aborting."
exit 1
fi
$instance_directory/etc/run/mariadb_update &
mariadb_update_pid=$!
sleep 60
# If mariadb_update is still running, abort
if [ -d /proc/$mariadb_update_pid ]; then
echo "mariadb_update still running after timeout, aborting."
kill $mariadb_update_pid
exit 1
fi
echo "Importing data..."
# Use latest dump XXX can contain funny characters
dump=$(ls -r $mariadb_backup_directory | head -1)
zcat "$mariadb_backup_directory/$dump" | $mysql_executable -u root --socket="$instance_directory/var/run/mariadb.sock"
RESTORE_EXIT_CODE=$?
if [ $RESTORE_EXIT_CODE -eq 0 ]; then
echo 'Backup restoration successfully completed.'
else
echo 'Backup restoration failed.'
fi
exit $RESTORE_EXIT_CODE
[versions]
AccessControl = 2.13.14
Acquisition = 2.13.9
DateTime = 2.12.8
DocumentTemplate = 2.13.2
ExtensionClass = 2.13.2
Jinja2 = 2.8
MarkupSafe = 0.23
Missing = 2.13.1
MultiMapping = 2.13.0
Paste = 1.7.5.1
PasteDeploy = 1.3.4
PasteScript = 1.7.5
Persistence = 2.13.2
Products.BTreeFolder2 = 2.13.5
Products.ExternalMethod = 2.13.1
Products.MIMETools = 2.13.0
Products.MailHost = 2.13.2
Products.OFSP = 2.13.2
Products.PythonScripts = 2.13.2
Products.StandardCacheManagers = 2.13.1
Products.ZCTextIndex = 2.13.5
Products.ZCatalog = 2.13.27
Pygments = 2.1.2
Record = 2.13.0
RestrictedPython = 3.6.0
Sphinx = 1.0.8
ZConfig = 2.9.3
ZODB3 = 3.10.5
ZopeUndo = 2.12.0
docutils = 0.12
initgroups = 2.13.0
mechanize = 0.2.5
mr.developer = 1.34
pytz = 2015.7
repoze.retry = 1.2
repoze.tm2 = 1.0
repoze.who = 2.0
setuptools = 20.2.2
tempstorage = 2.12.2
transaction = 1.1.1
z3c.checkversions = 0.5
zExceptions = 2.13.0
zLOG = 2.11.2
zc.buildout = 2.3.1
zc.lockfile = 1.0.2
zc.recipe.egg = 2.0.3
zc.recipe.testrunner = 1.2.1
zdaemon = 2.0.7
zope.annotation = 3.5.0
zope.broken = 3.6.0
zope.browser = 1.3
zope.browsermenu = 3.9.1
zope.browserpage = 3.12.2
zope.browserresource = 3.10.3
zope.component = 3.9.5
zope.configuration = 3.7.4
zope.container = 3.11.2
zope.contentprovider = 3.7.2
zope.contenttype = 3.5.5
zope.deferredimport = 3.5.3
zope.dottedname = 3.4.6
zope.event = 3.5.2
zope.exceptions = 3.6.2
zope.filerepresentation = 3.6.1
zope.i18n = 3.7.4
zope.i18nmessageid = 3.5.3
zope.interface = 3.6.7
zope.lifecycleevent = 3.6.2
zope.location = 3.9.1
zope.pagetemplate = 3.5.2
zope.processlifetime = 1.0
zope.proxy = 3.6.1
zope.ptresource = 3.9.0
zope.publisher = 3.12.6
zope.schema = 3.7.1
zope.security = 3.7.4
zope.sendmail = 3.7.5
zope.sequencesort = 3.4.0
zope.site = 3.9.2
zope.size = 3.4.1
zope.structuredtext = 3.5.1
zope.tal = 3.5.2
zope.tales = 3.5.3
zope.testbrowser = 3.11.1
zope.testing = 3.9.7
zope.traversing = 3.13.2
zope.viewlet = 3.7.2
# Note: Environment is setup in running wrapper script, as zope.conf is read
# too late for some components.
%define INSTANCE {{ parameter_dict['instance'] }}
instancehome $INSTANCE
zserver-threads {{ parameter_dict['thread-amount'] }}
# When ownership checking is enabled, the roles a script runs as are the
# intersection between user's roles and script owner's roles. This means
# that revoking a code author's access to the system prevent all scripts
# owned by that user from being of much use.
# This is not how ERP5 approaches development: Managers write code,
# Managers must be trustable and trusted, and their past work should not be
# revoked when their account is terminated.
skip-ownership-checking true
lock-filename {{ parameter_dict['lock-file'] }}
pid-filename {{ parameter_dict['pid-file'] }}
default-zpublisher-encoding utf-8
rest-input-encoding utf-8
rest-output-encoding utf-8
# XXX: isn't this entry implicit ?
products {{ parameter_dict['instance-products'] }}
{% if parameter_dict['webdav'] -%}
<webdav-source-server>
address {{ parameter_dict['ip'] }}:{{ parameter_dict['port'] }}
force-connection-close off
</webdav-source-server>
{% else %}
<http-server>
address {{ parameter_dict['ip'] }}:{{ parameter_dict['port'] }}
</http-server>
{%- endif %}
<zoperunner>
program $INSTANCE/bin/runzope
</zoperunner>
<product-config DeadlockDebugger>
dump_url {{ parameter_dict['deadlock-path'] }}
secret {{ parameter_dict['deadlock-debugger-password'] }}
</product-config>
{% if 'longrequest-logger-interval' in parameter_dict -%}
<product-config LongRequestLogger>
logfile {{ parameter_dict['longrequest-logger-file'] }}
timeout {{ parameter_dict['longrequest-logger-timeout'] }}
interval {{ parameter_dict['longrequest-logger-interval'] }}
</product-config>
{% endif -%}
{% if 'tidstorage-ip' in parameter_dict -%}
<product-config TIDStorage>
backend-ip {{ parameter_dict['tidstorage-ip'] }}
backend-port {{ parameter_dict['tidstorage-port'] }}
</product-config>
{% endif -%}
<product-config CMFActivity>
node-id {{ parameter_dict['node-id'] }}
</product-config>
{% set timerserver_interval = parameter_dict['timerserver-interval'] -%}
{% if timerserver_interval -%}
%import timerserver
<timer-server>
interval {{ timerserver_interval }}
</timer-server>
{% endif -%}
{% set promise_path = parameter_dict['promise-path'] -%}
{% if promise_path -%}
<product-config /{{ parameter_dict['site-id'] }}>
promise_path {{ promise_path }}
</product-config>
{% endif -%}
<eventlog>
level info
<logfile>
dateformat
path {{ parameter_dict['event-log'] }}
</logfile>
</eventlog>
<logger access>
level WARN
<logfile>
dateformat
format %(message)s
path {{ parameter_dict['z2-log'] }}
</logfile>
</logger>
<zodb_db temporary>
<temporarystorage>
name temporary storage for sessioning
</temporarystorage>
mount-point /temp_folder
container-class Products.TemporaryFolder.TemporaryContainer
</zodb_db>
{% set developer_list = parameter_dict['developer-list'] -%}
{% if developer_list -%}
%import Products.ERP5Type
<ERP5Type erp5>
developers {{ developer_list | join(' ') }}
</ERP5Type>
{% endif -%}
{% for m in parameter_dict['import-list'] -%}
%import {{ m }}
{% endfor -%}
{% set type_dict = {'neo': 'NEOStorage', 'zeo': 'zeoclient'} %}
{% for name, zodb_dict in parameter_dict['zodb-dict'].iteritems() %}
<zodb_db {{ name }}>
{%- set storage_type = type_dict[zodb_dict.pop('type')] %}
{%- set storage_dict = zodb_dict.pop('storage-dict') %}
{%- for key, value in zodb_dict.iteritems() %}
{{ key }} {{ value }}
{%- endfor %}
<{{ storage_type }}>
{%- for key, value in storage_dict.iteritems() %}
{{ key }} {{ value }}
{%- endfor %}
</{{ storage_type }}>
</zodb_db>
{% endfor -%}
[versions]
# ZTK
zope.annotation = 3.5.0
zope.applicationcontrol = 3.5.5
zope.authentication = 3.7.1
zope.broken = 3.6.0
zope.browser = 1.3
zope.browsermenu = 3.9.1
zope.browserpage = 3.12.2
zope.browserresource = 3.10.3
zope.cachedescriptors = 3.5.1
zope.catalog = 3.8.2
zope.component = 3.9.5
zope.componentvocabulary = 1.0.1
zope.configuration = 3.7.4
zope.container = 3.11.2
zope.contentprovider = 3.7.2
zope.contenttype = 3.5.5
zope.copy = 3.5.0
zope.copypastemove = 3.7.0
zope.datetime = 3.4.1
zope.deferredimport = 3.5.3
zope.deprecation = 3.4.1
zope.dottedname = 3.4.6
zope.dublincore = 3.7.1
zope.error = 3.7.4
zope.event = 3.5.2
zope.exceptions = 3.6.2
zope.filerepresentation = 3.6.1
zope.formlib = 4.0.6
zope.hookable = 3.4.1
zope.i18n = 3.7.4
zope.i18nmessageid = 3.5.3
zope.index = 3.6.4
zope.interface = 3.6.7
zope.intid = 3.7.2
zope.keyreference = 3.6.4
zope.lifecycleevent = 3.6.2
zope.location = 3.9.1
zope.login = 1.0.0
zope.mimetype = 1.3.1
zope.minmax = 1.1.2
zope.pagetemplate = 3.5.2
zope.password = 3.6.1
zope.pluggableauth = 1.0.3
zope.principalannotation = 3.6.1
zope.principalregistry = 3.7.1
zope.processlifetime = 1.0
zope.proxy = 3.6.1
zope.ptresource = 3.9.0
zope.publisher = 3.12.6
zope.ramcache = 1.0
zope.schema = 3.7.1
zope.security = 3.7.4
zope.securitypolicy = 3.7.0
zope.sendmail = 3.7.5
zope.sequencesort = 3.4.0
zope.server = 3.6.3
zope.session = 3.9.5
zope.site = 3.9.2
zope.size = 3.4.1
zope.structuredtext = 3.5.1
zope.tal = 3.5.2
zope.tales = 3.5.3
zope.testing = 3.9.7
zope.traversing = 3.13.2
zope.viewlet = 3.7.2
# Deprecating
zope.documenttemplate = 3.4.3
# Dependencies
# Needed for the mechanize 0.1.x.
ClientForm = 0.2.10
distribute = 0.6.49
docutils = 0.7
Jinja2 = 2.5.5
# Newer versions of mechanize are not fully py24 compatible.
mechanize = 0.1.11
Paste = 1.7.5.1
PasteDeploy = 1.3.4
PasteScript = 1.7.5
py = 1.3.4
Pygments = 1.3.1
python-gettext = 1.0
pytz = 2013b
RestrictedPython = 3.6.0
setuptools = 12.2
Sphinx = 1.0.8
transaction = 1.1.1
unittest2 = 0.5.1
z3c.recipe.sphinxdoc = 0.0.8
zc.buildout = 2.3.1
zc.lockfile = 1.0.2
ZConfig = 2.8.0
zc.recipe.egg = 1.3.2
zc.recipe.testrunner = 1.2.1
zc.resourcelibrary = 1.3.4
zdaemon = 2.0.7
ZODB3 = 3.9.7
zope.mkzeoinstance = 3.9.6
# toolchain
argparse = 1.1
coverage = 3.5.3
lxml = 2.2.8
mr.developer = 1.25
tl.eggdeps = 0.4
nose = 1.1.2
z3c.checkversions = 0.4.2
z3c.recipe.compattest = 0.12.2
z3c.recipe.depgraph = 0.5
zope.kgs = 1.2.0
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