Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
slapos-caddy
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Guillaume Hervier
slapos-caddy
Commits
816550d8
Commit
816550d8
authored
Mar 29, 2012
by
Vincent Pelletier
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Jinja2-ify instance.cfg, tidstorage and cloudooo.
parent
9a54dee8
Changes
14
Hide whitespace changes
Inline
Side-by-side
Showing
14 changed files
with
750 additions
and
817 deletions
+750
-817
setup.py
setup.py
+0
-2
slapos/recipe/generate_cloudooo.py
slapos/recipe/generate_cloudooo.py
+0
-60
slapos/recipe/generate_erp5_tidstorage.py
slapos/recipe/generate_erp5_tidstorage.py
+0
-242
software/erp5/instance-cloudoo.cfg.in
software/erp5/instance-cloudoo.cfg.in
+64
-0
software/erp5/instance-cloudooo.cfg
software/erp5/instance-cloudooo.cfg
+0
-61
software/erp5/instance-tidstorage.cfg.in
software/erp5/instance-tidstorage.cfg.in
+518
-0
software/erp5/instance.cfg
software/erp5/instance.cfg
+0
-45
software/erp5/instance.cfg.in
software/erp5/instance.cfg.in
+112
-0
software/erp5/snippet-backend.cfg
software/erp5/snippet-backend.cfg
+0
-71
software/erp5/snippet-fontconfig.cfg
software/erp5/snippet-fontconfig.cfg
+0
-2
software/erp5/snippet-master.cfg
software/erp5/snippet-master.cfg
+0
-214
software/erp5/snippet-zeo.cfg
software/erp5/snippet-zeo.cfg
+0
-16
software/erp5/snippet-zope.cfg
software/erp5/snippet-zope.cfg
+0
-57
software/erp5/software.cfg
software/erp5/software.cfg
+56
-47
No files found.
setup.py
View file @
816550d8
...
...
@@ -111,8 +111,6 @@ setup(name=name,
'zabbixagent = slapos.recipe.zabbixagent:Recipe'
,
'generic.zope = slapos.recipe.generic_zope:Recipe'
,
'generic.zope.zeo.client = slapos.recipe.generic_zope_zeo_client:Recipe'
,
'generate.erp5.tidstorage = slapos.recipe.generate_erp5_tidstorage:Recipe'
,
'generate.cloudooo = slapos.recipe.generate_cloudooo:Recipe'
,
'zeo = slapos.recipe.zeo:Recipe'
,
'tidstorage = slapos.recipe.tidstorage:Recipe'
,
'erp5.bootstrap = slapos.recipe.erp5_bootstrap:Recipe'
,
...
...
slapos/recipe/generate_cloudooo.py
deleted
100644 → 0
View file @
9a54dee8
##############################################################################
#
# Copyright (c) 2011 Vifib SARL and Contributors. All Rights Reserved.
#
# WARNING: This program as such is intended to be used by professional
# programmers who take the whole responsibility of assessing all potential
# consequences resulting from its eventual inadequacies and bugs
# End users who are looking for a ready-to-use solution with commercial
# guarantees and support are strongly adviced to contract a Free Software
# Service Company
#
# This program is Free Software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 3
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#
##############################################################################
from
slapos.recipe.librecipe
import
GenericSlapRecipe
import
os
import
json
import
traceback
class
Recipe
(
GenericSlapRecipe
):
def
_options
(
self
,
options
):
self
.
dirname
=
os
.
path
.
join
(
self
.
buildout
[
'buildout'
][
'parts-directory'
],
self
.
name
)
options
[
'output'
]
=
os
.
path
.
join
(
self
.
dirname
,
self
.
name
+
'.cfg'
)
def
_generateRealTemplate
(
self
):
# TODO check json against schema
json_data
=
{}
if
self
.
parameter_dict
.
get
(
'cloudooo-json'
,
None
):
json_data
=
json
.
loads
(
self
.
parameter_dict
[
'cloudooo-json'
])
# dymanic fonts
font_url_list
=
json_data
.
get
(
'font_url_list'
,
[])
fontconfig_template
=
open
(
self
.
options
[
'template'
]).
read
()
fontconfig
=
open
(
self
.
options
[
'snippet-fontconfig'
]).
read
()
fontconfig_extension
=
fontconfig
%
dict
(
font_url_list
=
' '
.
join
(
font_url_list
))
with
open
(
self
.
options
[
'output'
],
'w'
)
as
f
:
f
.
write
(
fontconfig_template
+
fontconfig_extension
)
def
_install
(
self
):
if
not
os
.
path
.
exists
(
self
.
dirname
):
os
.
mkdir
(
self
.
dirname
)
try
:
self
.
_generateRealTemplate
()
except
Exception
:
print
'Ignored issue during template generation:
\
n
%s'
%
\
traceback
.
format_exc
()
return
[
self
.
dirname
]
slapos/recipe/generate_erp5_tidstorage.py
deleted
100644 → 0
View file @
9a54dee8
##############################################################################
#
# Copyright (c) 2011 Vifib SARL and Contributors. All Rights Reserved.
#
# WARNING: This program as such is intended to be used by professional
# programmers who take the whole responsibility of assessing all potential
# consequences resulting from its eventual inadequacies and bugs
# End users who are looking for a ready-to-use solution with commercial
# guarantees and support are strongly adviced to contract a Free Software
# Service Company
#
# This program is Free Software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 3
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#
##############################################################################
from
slapos.recipe.librecipe
import
GenericSlapRecipe
import
os
import
json
import
traceback
SECTION_BACKEND_PUBLISHER
=
"""[publish-apache-backend-list]
recipe = slapos.cookbook:publish"""
ZOPE_PORT_BASE
=
12000
ZEO_PORT_BASE
=
15000
HAPROXY_PORT_BASE
=
11000
APACHE_PORT_BASE
=
10000
class
Recipe
(
GenericSlapRecipe
):
def
_options
(
self
,
options
):
self
.
dirname
=
os
.
path
.
join
(
self
.
buildout
[
'buildout'
][
'parts-directory'
],
self
.
name
)
options
[
'output'
]
=
os
.
path
.
join
(
self
.
dirname
,
self
.
name
+
'.cfg'
)
def
_generateRealTemplate
(
self
):
current_zeo_port
=
ZEO_PORT_BASE
current_zope_port
=
ZOPE_PORT_BASE
current_apache_port
=
APACHE_PORT_BASE
current_haproxy_port
=
HAPROXY_PORT_BASE
json_data
=
json
.
loads
(
self
.
parameter_dict
[
'json'
])
site_id
=
str
(
json_data
[
'site-id'
])
# prepare zeo
output
=
''
part_list
=
[]
zope_dict
=
{}
zope_connection_dict
=
{}
known_tid_storage_identifier_dict
=
{}
snippet_zeo
=
open
(
self
.
options
[
'snippet-zeo'
]).
read
()
for
zeo_id
,
zeo_configuration_list
in
json_data
[
'zeo'
].
iteritems
():
if
not
type
(
zeo_configuration_list
)
in
(
type
([]),
type
(
set
()),
type
(())):
raise
ValueError
(
'%s passed in json is not a list, json: %s.'
%
(
zeo_configuration_list
,
json_data
))
storage_list
=
[]
a
=
storage_list
.
append
for
zeo_slave
in
zeo_configuration_list
:
zope_connection_dict
[
zeo_slave
[
'storage-name'
]]
=
{
'zope-cache-size'
:
zeo_slave
[
'zope-cache-size'
],
'zeo-cache-size'
:
zeo_slave
[
'zeo-cache-size'
],
'mount-point'
:
zeo_slave
[
'mount-point'
]
%
{
'site-id'
:
site_id
},
'storage-name'
:
zeo_slave
[
'storage-name'
],
'server'
:
'${zeo-instance-%(zeo-id)s:ip}:${zeo-instance-%(zeo-id)s:port}'
%
{
'zeo-id'
:
zeo_id
}
}
zodb_path
=
os
.
path
.
join
(
'${directory:zodb}'
,
zeo_slave
[
'storage-name'
]
+
'.fs'
)
a
(
' storage-name=%(storage-name)s zodb-path=%(zodb-path)s'
%
{
'zodb-path'
:
zodb_path
,
'storage-name'
:
zeo_slave
[
'storage-name'
]})
known_tid_storage_identifier_dict
[
"((('%(ip)s', %(port)s),), '%(storage_name)s')"
%
dict
(
ip
=
'${zeo-instance-%s:ip}'
%
zeo_id
,
port
=
'${zeo-instance-%s:port}'
%
zeo_id
,
storage_name
=
zeo_slave
[
'storage-name'
])]
=
(
zodb_path
,
'${directory:zodb-backup}/%s/'
%
zeo_slave
[
'storage-name'
],
zeo_slave
[
'serialize-path'
]
%
{
'site-id'
:
site_id
})
current_zeo_port
+=
1
output
+=
snippet_zeo
%
dict
(
zeo_id
=
zeo_id
,
zeo_port
=
current_zeo_port
,
storage_list
=
'
\
n
'
.
join
(
storage_list
)
)
part_list
.
extend
([
"zeo-instance-%s"
%
zeo_id
,
"logrotate-entry-zeo-%s"
%
zeo_id
])
zeo_connection_list
=
[]
a
=
zeo_connection_list
.
append
for
k
,
v
in
zope_connection_dict
.
iteritems
():
a
(
' zeo-cache-size=%(zeo-cache-size)s zope-cache-size=%(zope-cache-size)s server=%(server)s mount-point=%(mount-point)s storage-name=%(storage-name)s'
%
v
)
zeo_connection_string
=
'
\
n
'
.
join
(
zeo_connection_list
)
zope_dict
.
update
(
timezone
=
json_data
[
'timezone'
],
zeo_connection_string
=
zeo_connection_string
,
site_id
=
site_id
,
)
# always one distribution node
current_zope_port
+=
1
snippet_zope
=
open
(
self
.
options
[
'snippet-zope'
]).
read
()
zope_id
=
'zope-distribution'
part_list
.
append
(
zope_id
)
part_list
.
append
(
'logrotate-entry-%s'
%
zope_id
)
output
+=
snippet_zope
%
dict
(
zope_thread_amount
=
1
,
zope_id
=
zope_id
,
zope_port
=
current_zope_port
,
zope_timeserver
=
True
,
longrequest_logger_file
=
''
,
longrequest_logger_timeout
=
''
,
longrequest_logger_interval
=
''
,
**
zope_dict
)
# always one admin node
current_zope_port
+=
1
zope_id
=
'zope-admin'
part_list
.
append
(
zope_id
)
part_list
.
append
(
'logrotate-entry-%s'
%
zope_id
)
output
+=
snippet_zope
%
dict
(
zope_thread_amount
=
1
,
zope_id
=
zope_id
,
zope_port
=
current_zope_port
,
zope_timeserver
=
False
,
longrequest_logger_file
=
''
,
longrequest_logger_timeout
=
''
,
longrequest_logger_interval
=
''
,
**
zope_dict
)
# handle activity key
for
q
in
range
(
1
,
json_data
[
'activity'
][
'zopecount'
]
+
1
):
current_zope_port
+=
1
part_name
=
'zope-activity-%s'
%
q
part_list
.
append
(
part_name
)
part_list
.
append
(
'logrotate-entry-%s'
%
part_name
)
output
+=
snippet_zope
%
dict
(
zope_thread_amount
=
1
,
zope_id
=
part_name
,
zope_port
=
current_zope_port
,
zope_timeserver
=
True
,
longrequest_logger_file
=
''
,
longrequest_logger_timeout
=
''
,
longrequest_logger_interval
=
''
,
**
zope_dict
)
# handle backend key
snippet_backend
=
open
(
self
.
options
[
'snippet-backend'
]).
read
()
publish_url_list
=
[]
for
backend_name
,
backend_configuration
in
json_data
[
'backend'
].
iteritems
():
haproxy_backend_list
=
[]
for
q
in
range
(
1
,
backend_configuration
[
'zopecount'
]
+
1
):
current_zope_port
+=
1
part_name
=
'zope-%s-%s'
%
(
backend_name
,
q
)
part_list
.
append
(
part_name
)
part_list
.
append
(
'logrotate-entry-%s'
%
part_name
)
longrequest_logger
=
backend_configuration
.
get
(
"longrequest-logger"
,
None
)
if
longrequest_logger
is
not
None
:
longrequest_part_name
=
'%s-longrequest'
%
part_name
longrequest_logger_file
=
'${basedirectory:log}/%s.log'
\
%
longrequest_part_name
longrequest_logger_timeout
=
longrequest_logger
.
get
(
'timeout'
,
'4'
)
longrequest_logger_interval
=
longrequest_logger
.
get
(
'interval'
,
'2'
)
else
:
longrequest_logger_file
=
longrequest_logger_timeout
=
\
longrequest_logger_interval
=
''
output
+=
snippet_zope
%
dict
(
zope_thread_amount
=
backend_configuration
[
'thread-amount'
],
zope_id
=
part_name
,
zope_port
=
current_zope_port
,
zope_timeserver
=
False
,
longrequest_logger_file
=
longrequest_logger_file
,
longrequest_logger_timeout
=
longrequest_logger_timeout
,
longrequest_logger_interval
=
longrequest_logger_interval
,
**
zope_dict
)
haproxy_backend_list
.
append
(
'${%(part_name)s:ip}:${%(part_name)s:port}'
%
dict
(
part_name
=
part_name
))
scheme
=
backend_configuration
.
get
(
'scheme'
,
[
'https'
])
# now generate backend access
current_apache_port
+=
1
current_haproxy_port
+=
1
backend_dict
=
dict
(
backend_name
=
backend_name
,
apache_port
=
current_apache_port
,
apache_public_port
=
current_apache_port
+
1
,
haproxy_port
=
current_haproxy_port
,
access_control_string
=
backend_configuration
[
'access-control-string'
],
maxconn
=
backend_configuration
[
'maxconn'
],
server_check_path
=
'/%s/getId'
%
site_id
,
haproxy_backend_list
=
' '
.
join
(
haproxy_backend_list
),
ssl_authentication
=
backend_configuration
.
get
(
'ssl-authentication'
,
False
),
backend_path
=
backend_configuration
.
get
(
'backend-path'
,
'/'
)
%
{
'site-id'
:
site_id
}
)
current_apache_port
+=
1
output
+=
snippet_backend
%
backend_dict
if
'http'
in
scheme
:
part_list
.
append
(
'apache-public-%(backend_name)s logrotate-entry-apache-public-%(backend_name)s'
%
dict
(
backend_name
=
backend_name
))
publish_url_list
.
append
(
'url-public-%(backend_name)s = http://[${apache-public-%(backend_name)s:ip}]:${apache-public-%(backend_name)s:port}'
%
dict
(
backend_name
=
backend_name
))
if
'https'
in
scheme
:
part_list
.
append
(
'apache-%(backend_name)s ca-apache-%(backend_name)s logrotate-entry-apache-%(backend_name)s haproxy-%(backend_name)s'
%
dict
(
backend_name
=
backend_name
))
publish_url_list
.
append
(
'url-%(backend_name)s = https://[${apache-%(backend_name)s:ip}]:${apache-%(backend_name)s:port}'
%
dict
(
backend_name
=
backend_name
))
output
+=
SECTION_BACKEND_PUBLISHER
+
'
\
n
'
output
+=
'
\
n
'
.
join
(
publish_url_list
)
part_list
.
append
(
'publish-apache-backend-list'
)
master_dict
=
self
.
parameter_dict
.
copy
()
if
'erp5-ca'
in
json_data
:
erp5_ca
=
json_data
[
'erp5-ca'
]
# Fetching exactly named parameters from json in order to raise proper
# error if required
master_dict
.
update
(
erp5_ca_country_code
=
erp5_ca
[
'country-code'
],
erp5_ca_email
=
erp5_ca
[
'email'
],
erp5_ca_state
=
erp5_ca
[
'state'
],
erp5_ca_city
=
erp5_ca
[
'city'
],
erp5_ca_company
=
erp5_ca
[
'company'
]
)
else
:
master_dict
.
update
(
dict
(
erp5_ca_country_code
=
'XX'
,
erp5_ca_email
=
'xx@example.com'
,
# XXX-BBB: State by mistake has been configured as string "('State',)"
# string, so keep this for backward compatibility of existing
# automatically setup CAs
erp5_ca_state
=
"('State',)"
,
erp5_ca_city
=
'City'
,
erp5_ca_company
=
'Company'
))
prepend
=
open
(
self
.
options
[
'snippet-master'
]).
read
()
%
dict
(
part_list
=
'
\
n
'
.
join
([
' '
+
q
for
q
in
part_list
]),
known_tid_storage_identifier_dict
=
known_tid_storage_identifier_dict
,
haproxy_section
=
"haproxy-%s"
%
backend_name
,
zope_section
=
zope_id
,
site_id
=
site_id
,
**
master_dict
)
output
=
prepend
+
output
with
open
(
self
.
options
[
'output'
],
'w'
)
as
f
:
f
.
write
(
output
)
def
_install
(
self
):
if
not
os
.
path
.
exists
(
self
.
dirname
):
os
.
mkdir
(
self
.
dirname
)
if
not
"json"
in
self
.
parameter_dict
:
# no json transimtted, nothing to do
with
open
(
self
.
options
[
'output'
],
'w'
)
as
f
:
f
.
write
(
"[buildout]
\
n
parts =
\
n
"
)
else
:
try
:
self
.
_generateRealTemplate
()
except
Exception
:
print
'Ignored issue during template generation:
\
n
%s'
%
\
traceback
.
format_exc
()
return
[
self
.
dirname
]
software/erp5/instance-cloudoo.cfg.in
0 → 100644
View file @
816550d8
{% if software_type == slapparameter_dict['slap_software_type'] -%}
{% set json = json_module.loads(parameter_dict.get('cloudooo-json', '{}')) -%}
{% set bin_directory = parameter_dict['buildout-bin-directory'] -%}
[buildout]
parts =
publish-cloudooo-connection-information
cloudooo-instance
eggs-directory = {{ eggs_directory }}
develop-eggs-directory = {{ develop_eggs_directory }}
offline = true
[publish-cloudooo-connection-information]
recipe = slapos.cookbook:publishurl
url = cloudooo://${cloudooo-instance:ip}:${cloudooo-instance:port}/
[cloudooo-instance]
recipe = slapos.cookbook:generic.cloudooo
# Network options
ip = ${slap-network-information:local-ipv4}
port = 23000
openoffice-port = 23060
# Paths
configuration-file = ${rootdirectory:etc}/cloudooo.cfg
wrapper = ${basedirectory:services}/cloudooo
# Paths: Data
data-directory = ${directory:cloudooo-data}
environment =
LD_LIBRARY_PATH = {{ parameter_dict['file'] }}/lib:{{ parameter_dict['fontconfig'] }}/lib:{{ parameter_dict['freetype'] }}/lib:{{ parameter_dict['libICE'] }}/lib:{{ parameter_dict['libpng12'] }}/lib:{{ parameter_dict['libSM'] }}/lib:{{ parameter_dict['libX11'] }}/lib:{{ parameter_dict['libXau'] }}/lib:{{ parameter_dict['libXdmcp'] }}/lib:{{ parameter_dict['libXext'] }}/lib:{{ parameter_dict['libxcb'] }}/lib:{{ parameter_dict['libXrender'] }}/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 = ${rootdirectory:etc}/font.conf
font-system-folder = {{ parameter_dict['fonts'] }}
font-folder = ${directory:font}
url-list = {{ json.get('font_url_list', []) | join(' ') }}
service-folder = ${basedirectory:services}
onetimedownload_path = {{ bin_directory }}/onetimedownload
# rest of parts are candidates for some generic stuff
[basedirectory]
recipe = slapos.cookbook:mkdirectory
services = ${rootdirectory:etc}/run
[directory]
recipe = slapos.cookbook:mkdirectory
cloudooo-data = ${rootdirectory:srv}/cloudooo
font = ${rootdirectory:srv}/font
[rootdirectory]
recipe = slapos.cookbook:mkdirectory
etc = ${buildout:directory}/etc
srv = ${buildout:directory}/srv
{% endif %}
software/erp5/instance-cloudooo.cfg
deleted
100644 → 0
View file @
9a54dee8
[buildout]
parts =
publish-cloudooo-connection-information
cloudooo-instance
eggs-directory = ${buildout:eggs-directory}
develop-eggs-directory = ${buildout:develop-eggs-directory}
offline = true
[publish-cloudooo-connection-information]
recipe = slapos.cookbook:publishurl
url = cloudooo://$${cloudooo-instance:ip}:$${cloudooo-instance:port}/
[cloudooo-instance]
recipe = slapos.cookbook:generic.cloudooo
# Network options
ip = $${slap-network-information:local-ipv4}
port = 23000
openoffice-port = 23060
# Paths
configuration-file = $${rootdirectory:etc}/cloudooo.cfg
wrapper = $${basedirectory:services}/cloudooo
# Paths: Data
data-directory = $${directory:cloudooo-data}
environment =
LD_LIBRARY_PATH = ${file:location}/lib:${fontconfig:location}/lib:${freetype:location}/lib:${libICE:location}/lib:${libpng12:location}/lib:${libSM:location}/lib:${libX11:location}/lib:${libXau:location}/lib:${libXdmcp:location}/lib:${libXext:location}/lib:${libxcb:location}/lib:${libXrender:location}/lib:${zlib:location}/lib
FONTCONFIG_FILE = $${fontconfig-instance:conf-path}
# Binary information
# cloudooo specific configuration
ooo-binary-path = ${libreoffice-bin:location}/program
ooo-paster = ${buildout:bin-directory}/cloudooo_paster
ooo-uno-path = ${libreoffice-bin:location}/basis-link/program
[fontconfig-instance]
recipe = slapos.cookbook:fontconfig
conf-path = $${rootdirectory:etc}/font.conf
font-system-folder = ${fonts:location}
font-folder = $${directory:font}
url-list = $${dynamic-fontconfig-instance:url-list}
service-folder = $${basedirectory:services}
onetimedownload_path = ${buildout:bin-directory}/onetimedownload
# rest of parts are candidates for some generic stuff
[basedirectory]
recipe = slapos.cookbook:mkdirectory
services = $${rootdirectory:etc}/run
[directory]
recipe = slapos.cookbook:mkdirectory
cloudooo-data = $${rootdirectory:srv}/cloudooo
font = $${rootdirectory:srv}/font
[rootdirectory]
recipe = slapos.cookbook:mkdirectory
etc = $${buildout:directory}/etc
srv = $${buildout:directory}/srv
software/erp5/instance-tidstorage.cfg.in
0 → 100644
View file @
816550d8
{% if software_type == slapparameter_dict['slap_software_type'] -%}
{#
Note: all port counters are pre-incremented. No idea why base port is skipped.
-#}
{% set current_zeo_port = zeo_port_base | int -%}
{% set zope_port_base = zope_port_base | int -%}
{% set zope_dummy_list = [] %}
{% set current_apache_port = apache_port_base | int -%}
{% set current_haproxy_port = haproxy_port_base | int -%}
{% set json = json_module.loads(slapparameter_dict['json']) -%}
{% set bin_directory = parameter_dict['buildout-bin-directory'] -%}
{#
BBB: erp5-ca['state'] has been configured as string by mistake. Keep this for
backward compatibility with existing automatically setup CAs.
-#}
{% set erp5_ca = json.get('erp5-ca', {
'country-code': 'ZZ',
'email': 'nobody@example.com',
'state': "('State',)",
'city': 'City',
'company': 'Company',
}) -%}
{% set site_id = json['site-id'] -%}
{% set part_list = [] -%}
{% set known_tid_storage_identifier_dict = {} -%}
{% set zodb_connection_list = [] -%}
{% macro section(name) %}{% do part_list.append(name) %}{{ name }}{% endmacro -%}
{% macro zope(
name,
thread_amount=1,
timeserver=False,
longrequest_logger_file='',
longrequest_logger_timeout='',
longrequest_logger_interval=''
) -%}
[{{ section(name) }}]
recipe = slapos.cookbook:generic.zope.zeo.client
# XXX: products won't be needed as soon as all ERP5 (and products-deps)
# products will be eggified so then it will be possible to use them thanks to
# availability in software's eggs
products = {{ parameter_dict['products'] }}
# Options
user = zope
{% do zope_dummy_list.append(None) %}
{% set offset = zope_dummy_list | length %}
port = {{ zope_port_base + offset }}
ip = ${slap-network-information:local-ipv4}
thread-amount = {{ thread_amount }}
deadlock-path = /manage_debug_threads
timezone = {{ json['timezone'] }}
zeo-connection-string =
{{ zodb_connection_string }}
timeserver = {{ timeserver }}
tidstorage-ip = ${tidstorage:ip}
tidstorage-port = ${tidstorage:port}
# long request
longrequest-logger-file = {{ longrequest_logger_file }}
longrequest-logger-timeout = {{ longrequest_logger_timeout }}
longrequest-logger-interval = {{ longrequest_logger_interval }}
# Paths
wrapper = ${basedirectory:services}/{{ name }}
instance-path = ${directory:instance}
instance-etc = ${directory:instance-etc}
instance-products = ${directory:instance-products}
bt5-repository = ${rootdirectory:var}/bt5_repository
tmp-path = ${rootdirectory:tmp}
bin-path = ${rootdirectory:bin}
site-zcml = ${:instance-etc}/site.zcml
pid-file = ${basedirectory:run}/{{ name }}.pid
lock-file = ${basedirectory:run}/{{ name }}.lock
event-log = ${basedirectory:log}/{{ name }}-event.log
z2-log = ${basedirectory:log}/{{ name }}-Z2.log
configuration-file = ${rootdirectory:etc}/{{ name }}.conf
inituser = ${:instance-path}/inituser
# Binary information
runzope-binary = {{ bin_directory }}/runzope
# BT5 Configuration
bt5-repository-list =
promise-path = ${erp5-promise:promise-path}
site-id = {{ site_id }}
[{{ section('logrotate-entry-' + name) }}]
< = logrotate-base
recipe = slapos.cookbook:logrotate.d
name = {{ name }}
log = {{ '${' + name + ':event-log}' }} {{ '${' + name + ':z2-log}' }}
post = {{ bin_directory }}/killpidfromfile {{ '${' + name + ':pid-file}' }} SIGUSR2
{% endmacro -%}
#############################
# Directory creation
#############################
[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}/run
run = ${rootdirectory:var}/run
backup = ${rootdirectory:srv}/backup
[directory]
recipe = slapos.cookbook:mkdirectory
tidstorage = ${rootdirectory:srv}/tidstorage
zodb = ${rootdirectory:srv}/zodb
zodb-backup = ${basedirectory:backup}/zodb
instance = ${rootdirectory:srv}/erp5shared
instance-etc = ${:instance}/etc
apache-conf = ${rootdirectory:etc}/apache
instance-etc-package-include = ${:instance}/etc/package-include
instance-document = ${:instance}/Document
instance-propertysheet = ${:instance}/PropertySheet
instance-products = ${:instance}/Products
instance-extensions = ${:instance}/Extensions
instance-constraint = ${:instance}/Constraint
instance-import = ${:instance}/import
instance-lib = ${:instance}/lib
instance-tests = ${:instance}/tests
erp5-ca-dir = ${rootdirectory:srv}/erp5-ssl
ca-dir = ${rootdirectory:srv}/ssl
cron-entries = ${rootdirectory:etc}/cron.d
crontabs = ${rootdirectory:etc}/crontabs
cronstamps = ${rootdirectory:etc}/cronstamps
logrotate-backup = ${basedirectory:backup}/logrotate
logrotate-entries = ${rootdirectory:etc}/logrotate.d
#############################
# Binary symlinking
#############################
[binary-link]
recipe = slapos.cookbook:symbolic.link
target-directory = ${rootdirectory:bin}
link-binary =
{{ parameter_dict['coreutils'] }}/bin/basename
{{ parameter_dict['coreutils'] }}/bin/cat
{{ parameter_dict['coreutils'] }}/bin/cp
{{ parameter_dict['coreutils'] }}/bin/ls
{{ parameter_dict['coreutils'] }}/bin/tr
{{ parameter_dict['coreutils'] }}/bin/uname
{{ parameter_dict['git'] }}/bin/git
{{ parameter_dict['graphviz'] }}/bin/dot
{{ parameter_dict['grep'] }}/bin/grep
{{ parameter_dict['imagemagick'] }}/bin/convert
{{ parameter_dict['imagemagick'] }}/bin/identify
{{ parameter_dict['mariadb'] }}/bin/mysql
{{ parameter_dict['mariadb'] }}/bin/mysqldump
{{ parameter_dict['pdftk'] }}/bin/pdftk
{{ parameter_dict['sed'] }}/bin/sed
{{ parameter_dict['tesseract'] }}/bin/tesseract
{{ parameter_dict['w3m'] }}/bin/w3m
{{ parameter_dict['poppler'] }}/bin/pdfinfo
{{ parameter_dict['poppler'] }}/bin/pdftotext
{{ parameter_dict['poppler'] }}/bin/pdftohtml
#############################
# CA
#############################
[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
[certificate-authority]
recipe = slapos.cookbook:certificate_authority
openssl-binary = {{ parameter_dict['openssl'] }}/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}
#############################
# ERP5 CA
#############################
[erp5-cadirectory]
recipe = slapos.cookbook:mkdirectory
requests = ${directory:erp5-ca-dir}/requests
private = ${directory:erp5-ca-dir}/private
certs = ${directory:erp5-ca-dir}/certs
newcerts = ${directory:erp5-ca-dir}/newcerts
crl = ${directory:erp5-ca-dir}/crl
[erp5-certificate-authority]
recipe = slapos.cookbook:certificate_authority
openssl-binary = {{ parameter_dict['openssl'] }}/bin/openssl
ca-dir = ${directory:erp5-ca-dir}
requests-directory = ${erp5-cadirectory:requests}
wrapper = ${basedirectory:services}/erp5-ca
ca-private = ${erp5-cadirectory:private}
ca-certs = ${erp5-cadirectory:certs}
ca-newcerts = ${erp5-cadirectory:newcerts}
ca-crl = ${erp5-cadirectory:crl}
country-code = {{ erp5_ca['country-code'] }}
email = {{ erp5_ca['email'] }}
state = {{ erp5_ca['state'] }}
city = {{ erp5_ca['city'] }}
company = {{ erp5_ca['company'] }}
#############################
# CRON
#############################
[cron-base]
cron-entries = ${directory:cron-entries}
[cron]
< = cron-base
recipe = slapos.cookbook:cron
dcrond-binary = {{ parameter_dict['dcron'] }}/sbin/crond
crontabs = ${directory:crontabs}
cronstamps = ${directory:cronstamps}
catcher = ${cron-simplelogger:wrapper}
binary = ${basedirectory:services}/crond
[cron-simplelogger]
recipe = slapos.cookbook:simplelogger
wrapper = ${rootdirectory:bin}/cron_simplelogger
log = ${basedirectory:log}/cron.log
#############################
# Logrotate
#############################
[logrotate-base]
logrotate-entries = ${directory:logrotate-entries}
backup = ${directory:logrotate-backup}
[logrotate]
< = logrotate-base
recipe = slapos.cookbook:logrotate
# Binaries
logrotate-binary = {{ parameter_dict['logrotate'] }}/usr/sbin/logrotate
gzip-binary = {{ parameter_dict['gzip'] }}/bin/gzip
gunzip-binary = {{ parameter_dict['gzip'] }}/bin/gunzip
# Directories
wrapper = ${rootdirectory:bin}/logrotate
conf = ${rootdirectory:etc}/logrotate.conf
state-file = ${rootdirectory:srv}/logrotate.status
[cron-entry-logrotate]
< = cron-base
recipe = slapos.cookbook:cron.d
name = logrotate
frequency = 0 0 * * *
command = ${logrotate:wrapper}
#############################
# ERP5 bootstrap
#############################
[erp5-bootstrap]
recipe = slapos.cookbook:erp5.bootstrap
runner-path = ${basedirectory:services}/erp5-bootstrap
mysql-url = {{ slapparameter_dict['mysql-url'] }}
zope-url = http://${zope-admin:user}:${zope-admin:password}@${zope-admin:ip}:${zope-admin:port}/{{ site_id }}
#############################
# ERP5 promise
#############################
[erp5-promise]
recipe = slapos.cookbook:erp5.promise
promise-path = ${rootdirectory:etc}/erp5promise.cfg
kumofs-url = {{ slapparameter_dict['kumofs-url'] }}
memcached-url = {{ slapparameter_dict['memcached-url'] }}
cloudooo-url = {{ slapparameter_dict['cloudooo-url'] }}
smtp-url = ${slap-parameter:smtp-url}
bt5 = ${slap-parameter:bt5}
bt5-repository-url = ${slap-parameter:bt5-repository-url}
#############################
# ZEO
#############################
[zeo-instance-entry-common]
recipe = slapos.cookbook:zeo
ip = ${slap-network-information:local-ipv4}
binary-path = {{ bin_directory }}/runzeo
{% for zeo_id, zeo_configuration_list in json['zeo'].iteritems() -%}
{% set storage_list = [] -%}
{% for zeo_slave in zeo_configuration_list -%}
{% do zodb_connection_list.append(
'zeo-cache-size=%(zeo-cache-size)s zope-cache-size=%(zope-cache-size)s '
'server=%(server)s mount-point=%(mount-point)s storage-name=%(storage-name)s' % {
'zope-cache-size': zeo_slave['zope-cache-size'],
'zeo-cache-size': zeo_slave['zeo-cache-size'],
'mount-point': zeo_slave['mount-point'] % {'site-id': site_id},
'storage-name': zeo_slave['storage-name'],
'server': '${zeo-instance-%(zeo-id)s:ip}:${zeo-instance-%(zeo-id)s:port}' % {'zeo-id': zeo_id},
}) -%}
{% set zodb_path = '${directory:zodb}/' + zeo_slave['storage-name'] + '.fs' -%}
{% do storage_list.append('storage-name=%(storage-name)s zodb-path=%(zodb-path)s' % {'zodb-path': zodb_path, 'storage-name': zeo_slave['storage-name']}) -%}
{% do known_tid_storage_identifier_dict.__setitem__("((('%(ip)s', %(port)s),), '%(storage_name)s')" % {
'ip': '${zeo-instance-%s:ip}' % zeo_id,
'port': '${zeo-instance-%s:port}' % zeo_id,
'storage_name': zeo_slave['storage-name']
}, (zodb_path, '${directory:zodb-backup}/%s/' % zeo_slave['storage-name'], zeo_slave['serialize-path'] % {'site-id': site_id})) -%}
{% endfor -%}
{% set current_zeo_port = current_zeo_port + 1 -%}
[{{ section('zeo-instance-%s' % zeo_id) }}]
< = zeo-instance-entry-common
log-path = ${basedirectory:log}/zeo-{{ zeo_id }}.log
pid-path = ${basedirectory:run}/zeo-{{ zeo_id }}.pid
conf-path = ${rootdirectory:etc}/zeo-{{ zeo_id }}.conf
port = {{ current_zeo_port }}
storage =
{{ storage_list | join('\n ') }}
wrapper-path = ${basedirectory:services}/zeo-{{ zeo_id }}
[{{ section('logrotate-entry-zeo-%s' % zeo_id) }}]
< = logrotate-base
recipe = slapos.cookbook:logrotate.d
name = zeo-{{ zeo_id }}
log = ${zeo-instance-{{ zeo_id }}:log-path}
post = {{ bin_directory }}/killpidfromfile ${zeo-instance-{{ zeo_id }}:pid-path} SIGUSR2
{% endfor %}
{% set zodb_connection_string = zodb_connection_list | join('\n ') -%}
#############################
# Zope
#############################
# Distribution node
{{ zope('zope-distribution', timeserver=True) }}
# Admin node
{{ zope('zope-admin') }}
# Activity nodes
{% for q in range(1, json['activity']['zopecount'] + 1) -%}
{{ zope('zope-activity-%s' % q, timeserver=True) }}
{% endfor %}
# Other zopes, apaches and haproxies
{% set publish_url_list = [] -%}
{% for backend_name, backend_configuration in json['backend'].iteritems() -%}
{% set haproxy_backend_list = [] -%}
{% set longrequest_logger = backend_configuration.get('longrequest-logger') -%}
{% for q in range(1, backend_configuration['zopecount'] + 1) -%}
{% set part_name = 'zope-%s-%s' % (backend_name, q) -%}
{% if longrequest_logger != None -%}
{% set longrequest_logger_file = '${basedirectory:log}/%s-longrequest.log' % (part_name, ) -%}
{% set longrequest_logger_timeout = longrequest_logger.get('timeout', '4') -%}
{% set longrequest_logger_interval = longrequest_logger.get('interval', '2') -%}
{% else -%}
{% set longrequest_logger_file = '' -%}
{% set longrequest_logger_timeout = '' -%}
{% set longrequest_logger_interval = '' -%}
{% endif -%}
{{ zope(
part_name,
thread_amount=backend_configuration['thread-amount'],
longrequest_logger_file=longrequest_logger_file,
longrequest_logger_timeout=longrequest_logger_timeout,
longrequest_logger_interval=longrequest_logger_interval,
) }}
{% do haproxy_backend_list.append('${%(part_name)s:ip}:${%(part_name)s:port}' % {'part_name': part_name}) -%}
{% endfor %}
{% set scheme = backend_configuration.get('scheme', ['https']) -%}
{% set current_apache_port = current_apache_port + 2 -%}
{% set current_haproxy_port = current_haproxy_port + 1 -%}
{% if 'http' in scheme -%}
{% set section_name = 'apache-public-' ~ backend_name -%}
{% do publish_url_list.append(
'url-public-%(backend_name)s = http://[${%(section_name)s:ip}]:${%(section_name)s:port}' % {
'backend_name': backend_name,
'section_name': section_name,
}) -%}
[{{ section(section_name) }}]
recipe = slapos.cookbook:apache.zope.backend
backend = http://${haproxy-{{ backend_name }}:ip}:${haproxy-{{ backend_name }}:port}
ip = ${slap-network-information:global-ipv6}
port = {{ current_apache_port }}
scheme = http
wrapper = ${basedirectory:services}/apache-public-{{ backend_name }}
configuration-file = ${directory:apache-conf}/apache-public-{{ backend_name }}.conf
access-control-string = {{ backend_configuration['access-control-string'] }}
pid-file = ${basedirectory:run}/apache-public-{{ backend_name }}.pid
lock-file = ${basedirectory:run}/apache-public-{{ backend_name }}.lock
error-log = ${basedirectory:log}/apache-public-{{ backend_name }}-error.log
access-log = ${basedirectory:log}/apache-public-{{ backend_name }}-access.log
apache-binary = {{ parameter_dict['apache'] }}/bin/httpd
[{{ section('logrotate-entry-apache-public-' ~ backend_name) }}]
< = logrotate-base
recipe = slapos.cookbook:logrotate.d
name = apache-public-{{ backend_name }}
log = ${apache-public-{{ backend_name }}:error-log} ${apache-public-{{ backend_name }}:access-log}
post = {{ bin_directory }}/killpidfromfile ${apache-public-{{ backend_name }}:pid-file} SIGUSR1
{% endif %}
{% if 'https' in scheme -%}
{% set section_name = 'apache-' ~ backend_name -%}
{% do publish_url_list.append(
'url-%(backend_name)s = https://[${%(section_name)s:ip}]:${%(section_name)s:port}' % {
'backend_name': backend_name,
'section_name': section_name,
}) -%}
[{{ section(section_name) }}]
recipe = slapos.cookbook:apache.zope.backend
backend = http://${haproxy-{{ backend_name }}:ip}:${haproxy-{{ backend_name }}:port}
ip = ${slap-network-information:global-ipv6}
port = {{ current_apache_port - 1 }}
wrapper = ${rootdirectory:bin}/apache-{{ backend_name }}
scheme = https
key-file = ${directory:apache-conf}/apache-{{ backend_name }}.key
cert-file = ${directory:apache-conf}/apache-{{ backend_name }}.crt
configuration-file = ${directory:apache-conf}/apache-{{ backend_name }}.conf
access-control-string = {{ backend_configuration['access-control-string'] }}
pid-file = ${basedirectory:run}/apache-{{ backend_name }}.pid
lock-file = ${basedirectory:run}/apache-{{ backend_name }}.lock
ssl-session-cache = $${basedirectory:log}/apache-ssl-session-cache
error-log = ${basedirectory:log}/apache-{{ backend_name }}-error.log
access-log = ${basedirectory:log}/apache-{{ backend_name }}-access.log
apache-binary = {{ parameter_dict['apache'] }}/bin/httpd
ssl-authentication = {{ backend_configuration.get('ssl-authentication', False) }}
backend-path = {{ backend_configuration.get('backend-path', '/') % {'site-id': site_id} }}
# Note: Without erp5-certificate-authority main certificate have to be hardcoded
ssl-authentication-certificate = ${erp5-certificate-authority:ca-dir}/cacert.pem
ssl-authentication-crl = ${erp5-certificate-authority:ca-crl}
[{{ section('ca-apache-' ~ backend_name) }}]
< = certificate-authority
recipe = slapos.cookbook:certificate_authority.request
key-file = ${apache-{{ backend_name }}:key-file}
cert-file = ${apache-{{ backend_name }}:cert-file}
executable = ${apache-{{ backend_name }}:wrapper}
wrapper = ${basedirectory:services}/apache-{{ backend_name }}
[{{ section('logrotate-entry-apache-' ~ backend_name) }}]
< = logrotate-base
recipe = slapos.cookbook:logrotate.d
name = apache-{{ backend_name }}
log = ${apache-{{ backend_name }}:error-log} ${apache-{{ backend_name }}:access-log}
post = {{ bin_directory }}/killpidfromfile ${apache-{{ backend_name }}:pid-file} SIGUSR1
[{{ section('haproxy-' ~ backend_name) }}]
recipe = slapos.cookbook:haproxy
name = {{ backend_name }}
conf-path = ${rootdirectory:etc}/haproxy-{{ backend_name }}.cfg
ip = ${slap-network-information:local-ipv4}
port = {{ current_haproxy_port }}
maxconn = {{ backend_configuration['maxconn'] }}
server-check-path = /{{ site_id }}/getId
wrapper-path = ${basedirectory:services}/haproxy-{{ backend_name }}
binary-path = {{ parameter_dict['haproxy'] }}/sbin/haproxy
backend-list = {{ haproxy_backend_list | join(' ')}}
{% endif -%}
{% endfor %}
[{{ section('publish-apache-backend-list') }}]
recipe = slapos.cookbook:publish
{{ publish_url_list | join('\n') }}
#############################
# tidstorage
#############################
[tidstorage]
recipe = slapos.cookbook:tidstorage
known-tid-storage-identifier-dict = {{ known_tid_storage_identifier_dict }}
base-url = http://${zope-admin:ip}:${zope-admin:port}/%s/serialize
configuration-path = ${rootdirectory:etc}/tidstorage.py
ip = ${slap-network-information:local-ipv4}
port = 6001
timestamp-file-path = ${directory:tidstorage}/repozo_tidstorage_timestamp.log
logfile-name = ${basedirectory:log}/tidstorage.log
pidfile-name = ${basedirectory:run}/tidstorage.pid
status-file = ${directory:tidstorage}/tidstorage.tid
tidstorage-repozo-binary = {{ bin_directory }}/tidstorage_repozo
tidstoraged-binary = {{ bin_directory }}/tidstoraged
repozo-binary = {{ bin_directory }}/repozo
tidstorage-wrapper = ${basedirectory:services}/tidstoraged
repozo-wrapper = ${buildout:bin-directory}/tidstorage-repozo
[cron-entry-tidstorage-backup]
< = cron-base
recipe = slapos.cookbook:cron.d
name = tidstorage
frequency = 0 0 * * *
command = ${tidstorage:repozo-wrapper}
[logrotate-entry-tidstorage]
< = logrotate-base
recipe = slapos.cookbook:logrotate.d
name = tidstorage
log = ${tidstorage:logfile-name}
post = {{ bin_directory }}/killpidfromfile ${tidstorage:pidfile-name} SIGHUP
#############################
# buildout main section
#############################
[buildout]
parts =
logrotate
cron
cron-entry-logrotate
certificate-authority
erp5-certificate-authority
tidstorage
cron-entry-tidstorage-backup
logrotate-entry-tidstorage
binary-link
erp5-promise
erp5-bootstrap
{{ part_list | join('\n ') }}
eggs-directory = {{ eggs_directory }}
develop-eggs-directory = {{ develop_eggs_directory }}
offline = true
{% endif %}
software/erp5/instance.cfg
deleted
100644 → 0
View file @
9a54dee8
[instance]
rdiff_backup_binary = ${buildout:bin-directory}/rdiff-backup
[buildout]
parts =
switch-softwaretype
eggs-directory = ${buildout:eggs-directory}
develop-eggs-directory = ${buildout:develop-eggs-directory}
offline = true
[dynamic-template-tidstorage]
recipe = slapos.cookbook:generate.erp5.tidstorage
snippet-zeo = ${template-snippet-zeo:output}
snippet-zope = ${template-snippet-zope:output}
snippet-master = ${template-snippet-master:output}
snippet-backend = ${template-snippet-backend:output}
[dynamic-template-cloudooo]
recipe = slapos.cookbook:generate.cloudooo
template = ${template-cloudooo:output}
snippet-fontconfig = ${template-snippet-fontconfig:output}
[switch-softwaretype]
recipe = slapos.cookbook:softwaretype
default = ${template-erp5-development:rendered}
production = ${template-erp5-production:rendered}
kumofs = ${template-kumofs:rendered}
memcached = ${template-memcached:rendered}
cloudooo = $${dynamic-template-cloudooo:output}
zope = ${template-zope:rendered}
mariadb = ${template-mariadb:rendered}
sphinx = ${template-sphinx:rendered}
tidstorage = $${dynamic-template-tidstorage:output}
varnish = ${template-varnish:rendered}
[slap-connection]
# part to migrate to new - separated words
computer-id = $${slap_connection:computer_id}
partition-id = $${slap_connection:partition_id}
server-url = $${slap_connection:server_url}
software-release-url = $${slap_connection:software_release_url}
key-file = $${slap_connection:key_file}
cert-file = $${slap_connection:cert_file}
software/erp5/instance.cfg.in
0 → 100644
View file @
816550d8
[buildout]
parts =
switch-softwaretype
eggs-directory = {{ eggs_directory }}
develop-eggs-directory = {{ develop_eggs_directory }}
offline = true
[slap-parameters]
recipe = slapos.cookbook:slapparameters
computer = ${slap-connection:computer-id}
partition = ${slap-connection:partition-id}
url = ${slap-connection:server-url}
key = ${slap-connection:key-file}
cert = ${slap-connection:cert-file}
[jinja2-template-base]
recipe = slapos.recipe.template:jinja2
template = {{ profile_base_location }}/${:filename}.in
rendered = ${buildout:parts-directory}/${:_buildout_section_name_}/${:filename}
extra-context =
context =
key eggs_directory buildout:eggs-directory
key develop_eggs_directory buildout:develop-eggs-directory
jsonkey slapparameter_dict slap-parameters:json
${:extra-context}
[dynamic-template-tidstorage-parameters]
products = {{ product_list }}
apache = {{ apache_location }}
haproxy = {{ haproxy_location }}
dcron = {{ dcron_location }}
logrotate = {{ logrotate_location }}
gzip = {{ gzip_location }}
openssl = {{ openssl_location }}
coreutils = {{ coreutils_location }}
git = {{ git_location }}
graphviz = {{ graphviz_location }}
grep = {{ grep_location }}
imagemagick = {{ imagemagick_location }}
mariadb = {{ mariadb_location }}
pdftk = {{ pdftk_location }}
sed = {{ sed_location }}
tesseract = {{ tesseract_location }}
w3m = {{ w3m_location }}
poppler = {{ poppler_location }}
buildout-bin-directory = {{ buildout_bin_directory }}
[dynamic-template-tidstorage]
< = jinja2-template-base
filename = instance-tidstorage.cfg
md5sum = 5c3e834bf60819cf52995630e563227c
extensions = jinja2.ext.do
extra-context =
section parameter_dict dynamic-template-tidstorage-parameters
import json_module json
raw zope_port_base 12000
raw zeo_port_base 15000
raw haproxy_port_base 11000
raw apache_port_base 10000
# Must match the key id in [switch-softwaretype] which uses this section.
raw software_type tidstorage
[dynamic-template-cloudooo-parameters]
file = {{ file_location }}
fontconfig = {{ fontconfig_location }}
freetype = {{ freetype_location }}
libICE = {{ libICE_location }}
libpng12 = {{ libpng12_location }}
libSM = {{ libSM_location }}
libX11 = {{ libX11_location }}
libXau = {{ libXau_location }}
libXdmcp = {{ libXdmcp_location }}
libXext = {{ libXext_location }}
libxcb = {{ libxcb_location }}
libXrender = {{ libXrender_location }}
zlib = {{ zlib_location }}
libreoffice-bin = {{ libreoffice_bin_location }}
fonts = {{ fonts_location }}
buildout-bin-directory = {{ buildout_bin_directory }}
[dynamic-template-cloudooo]
< = jinja2-template-base
filename = instance-cloudoo.cfg
md5sum = aea927d5d3363177fd1017c4b89838d7
extra-context =
section parameter_dict dynamic-template-cloudooo-parameters
import json_module json
# Must match the key id in [switch-softwaretype] which uses this section.
raw software_type cloudooo
[switch-softwaretype]
recipe = slapos.cookbook:softwaretype
default = {{ template_erp5_development }}
production = {{ template_erp5_production }}
kumofs = {{ template_kumofs }}
memcached = {{ template_memcached }}
cloudooo = ${dynamic-template-cloudooo:rendered}
zope = {{ template_zope }}
mariadb = {{ template_mariadb }}
sphinx = {{ template_sphinx }}
tidstorage = ${dynamic-template-tidstorage:rendered}
varnish = {{ template_varnish }}
[slap-connection]
# part to migrate to new - separated words
computer-id = ${slap_connection:computer_id}
partition-id = ${slap_connection:partition_id}
server-url = ${slap_connection:server_url}
software-release-url = ${slap_connection:software_release_url}
key-file = ${slap_connection:key_file}
cert-file = ${slap_connection:cert_file}
software/erp5/snippet-backend.cfg
deleted
100644 → 0
View file @
9a54dee8
[apache-public-%(backend_name)s]
recipe = slapos.cookbook:apache.zope.backend
backend = http://$${haproxy-%(backend_name)s:ip}:$${haproxy-%(backend_name)s:port}/
ip = $${slap-network-information:global-ipv6}
port = %(apache_public_port)s
scheme = http
wrapper = $${basedirectory:services}/apache-public-%(backend_name)s
configuration-file = $${directory:apache-conf}/apache-public-%(backend_name)s.conf
access-control-string = %(access_control_string)s
pid-file = $${basedirectory:run}/apache-public-%(backend_name)s.pid
lock-file = $${basedirectory:run}/apache-public-%(backend_name)s.lock
error-log = $${basedirectory:log}/apache-public-%(backend_name)s-error.log
access-log = $${basedirectory:log}/apache-public-%(backend_name)s-access.log
apache-binary = ${apache:location}/bin/httpd
[apache-%(backend_name)s]
recipe = slapos.cookbook:apache.zope.backend
backend = http://$${haproxy-%(backend_name)s:ip}:$${haproxy-%(backend_name)s:port}
ip = $${slap-network-information:global-ipv6}
port = %(apache_port)s
wrapper = $${rootdirectory:bin}/apache-%(backend_name)s
scheme = https
key-file = $${directory:apache-conf}/apache-%(backend_name)s.key
cert-file = $${directory:apache-conf}/apache-%(backend_name)s.crt
configuration-file = $${directory:apache-conf}/apache-%(backend_name)s.conf
access-control-string = %(access_control_string)s
pid-file = $${basedirectory:run}/apache-%(backend_name)s.pid
lock-file = $${basedirectory:run}/apache-%(backend_name)s.lock
ssl-session-cache = $${basedirectory:log}/apache-ssl-session-cache
error-log = $${basedirectory:log}/apache-%(backend_name)s-error.log
access-log = $${basedirectory:log}/apache-%(backend_name)s-access.log
apache-binary = ${apache:location}/bin/httpd
ssl-authentication = %(ssl_authentication)s
backend-path = %(backend_path)s
# Note: Without erp5-certificate-authority main certificate have to be hardcoded
ssl-authentication-certificate = $${erp5-certificate-authority:ca-dir}/cacert.pem
ssl-authentication-crl = $${erp5-certificate-authority:ca-crl}
[ca-apache-%(backend_name)s]
<= certificate-authority
recipe = slapos.cookbook:certificate_authority.request
key-file = $${apache-%(backend_name)s:key-file}
cert-file = $${apache-%(backend_name)s:cert-file}
executable = $${apache-%(backend_name)s:wrapper}
wrapper = $${basedirectory:services}/apache-%(backend_name)s
[logrotate-entry-apache-public-%(backend_name)s]
<= logrotate
recipe = slapos.cookbook:logrotate.d
name = apache-public-%(backend_name)s
log = $${apache-public-%(backend_name)s:error-log} $${apache-public-%(backend_name)s:access-log}
post = ${buildout:bin-directory}/killpidfromfile $${apache-public-%(backend_name)s:pid-file} SIGUSR1
[logrotate-entry-apache-%(backend_name)s]
<= logrotate
recipe = slapos.cookbook:logrotate.d
name = apache-%(backend_name)s
log = $${apache-%(backend_name)s:error-log} $${apache-%(backend_name)s:access-log}
post = ${buildout:bin-directory}/killpidfromfile $${apache-%(backend_name)s:pid-file} SIGUSR1
[haproxy-%(backend_name)s]
recipe = slapos.cookbook:haproxy
name = %(backend_name)s
conf-path = $${rootdirectory:etc}/haproxy-%(backend_name)s.cfg
ip = $${slap-network-information:local-ipv4}
port = %(haproxy_port)s
maxconn = %(maxconn)s
server-check-path = %(server_check_path)s
wrapper-path = $${basedirectory:services}/haproxy-%(backend_name)s
binary-path = ${haproxy:location}/sbin/haproxy
backend-list = %(haproxy_backend_list)s
software/erp5/snippet-fontconfig.cfg
deleted
100644 → 0
View file @
9a54dee8
[dynamic-fontconfig-instance]
url-list = %(font_url_list)s
software/erp5/snippet-master.cfg
deleted
100644 → 0
View file @
9a54dee8
[buildout]
parts =
logrotate
cron
cron-entry-logrotate
certificate-authority
erp5-certificate-authority
tidstorage
cron-entry-tidstorage-backup
logrotate-entry-tidstorage
binary-link
erp5-promise
erp5-bootstrap
%(part_list)s
eggs-directory = ${buildout:eggs-directory}
develop-eggs-directory = ${buildout:develop-eggs-directory}
offline = true
[tidstorage]
recipe = slapos.cookbook:tidstorage
known-tid-storage-identifier-dict = %(known_tid_storage_identifier_dict)s
base-url = http://$${%(haproxy_section)s:ip}:$${%(haproxy_section)s:port}/%%s/serialize
configuration-path = $${rootdirectory:etc}/tidstorage.py
ip = $${slap-network-information:local-ipv4}
port = 6001
timestamp-file-path = $${directory:tidstorage}/repozo_tidstorage_timestamp.log
logfile-name = $${basedirectory:log}/tidstorage.log
pidfile-name = $${basedirectory:run}/tidstorage.pid
status-file = $${directory:tidstorage}/tidstorage.tid
tidstorage-repozo-binary = ${buildout:bin-directory}/tidstorage_repozo
tidstoraged-binary = ${buildout:bin-directory}/tidstoraged
repozo-binary = ${buildout:bin-directory}/repozo
tidstorage-wrapper = $${basedirectory:services}/tidstoraged
repozo-wrapper = $${buildout:bin-directory}/tidstorage-repozo
[cron-entry-tidstorage-backup]
<= cron
recipe = slapos.cookbook:cron.d
name = tidstorage
frequency = 0 0 * * *
command = $${tidstorage:repozo-wrapper}
[logrotate-entry-tidstorage]
<= logrotate
recipe = slapos.cookbook:logrotate.d
name = tidstorage
log = $${tidstorage:logfile-name}
post = ${buildout:bin-directory}/killpidfromfile $${tidstorage:pidfile-name} SIGHUP
[cron]
recipe = slapos.cookbook:cron
dcrond-binary = ${dcron:location}/sbin/crond
cron-entries = $${directory:cron-entries}
crontabs = $${directory:crontabs}
cronstamps = $${directory:cronstamps}
catcher = $${cron-simplelogger:wrapper}
binary = $${basedirectory:services}/crond
[cron-simplelogger]
recipe = slapos.cookbook:simplelogger
wrapper = $${rootdirectory:bin}/cron_simplelogger
log = $${basedirectory:log}/cron.log
[cron-entry-logrotate]
<= cron
recipe = slapos.cookbook:cron.d
name = logrotate
frequency = 0 0 * * *
command = $${logrotate:wrapper}
[logrotate]
recipe = slapos.cookbook:logrotate
# Binaries
logrotate-binary = ${logrotate:location}/usr/sbin/logrotate
gzip-binary = ${gzip:location}/bin/gzip
gunzip-binary = ${gzip:location}/bin/gunzip
# Directories
wrapper = $${rootdirectory:bin}/logrotate
conf = $${rootdirectory:etc}/logrotate.conf
logrotate-entries = $${directory:logrotate-entries}
backup = $${directory:logrotate-backup}
state-file = $${rootdirectory:srv}/logrotate.status
[zeo-instance-entry-common]
recipe = slapos.cookbook:zeo
ip = $${slap-network-information:local-ipv4}
binary-path = ${buildout:bin-directory}/runzeo
[erp5-certificate-authority]
recipe = slapos.cookbook:certificate_authority
openssl-binary = ${openssl:location}/bin/openssl
ca-dir = $${directory:erp5-ca-dir}
requests-directory = $${erp5-cadirectory:requests}
wrapper = $${basedirectory:services}/erp5-ca
ca-private = $${erp5-cadirectory:private}
ca-certs = $${erp5-cadirectory:certs}
ca-newcerts = $${erp5-cadirectory:newcerts}
ca-crl = $${erp5-cadirectory:crl}
country-code = %(erp5_ca_country_code)s
email = %(erp5_ca_email)s
state = %(erp5_ca_state)s
city = %(erp5_ca_city)s
company = %(erp5_ca_company)s
[erp5-cadirectory]
recipe = slapos.cookbook:mkdirectory
requests = $${directory:erp5-ca-dir}/requests
private = $${directory:erp5-ca-dir}/private
certs = $${directory:erp5-ca-dir}/certs
newcerts = $${directory:erp5-ca-dir}/newcerts
crl = $${directory:erp5-ca-dir}/crl
[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
[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}/run
run = $${rootdirectory:var}/run
backup = $${rootdirectory:srv}/backup
[directory]
recipe = slapos.cookbook:mkdirectory
tidstorage = $${rootdirectory:srv}/tidstorage
zodb = $${rootdirectory:srv}/zodb
zodb-backup = $${basedirectory:backup}/zodb
instance = $${rootdirectory:srv}/erp5shared
instance-etc = $${:instance}/etc
apache-conf = $${rootdirectory:etc}/apache
instance-etc-package-include = $${:instance}/etc/package-include
# because of bug in slapos.recipe.template keys are lowercased
instance-document = $${:instance}/Document
instance-propertysheet = $${:instance}/PropertySheet
instance-products = $${:instance}/Products
instance-extensions = $${:instance}/Extensions
instance-constraint = $${:instance}/Constraint
instance-import = $${:instance}/import
instance-lib = $${:instance}/lib
instance-tests = $${:instance}/tests
erp5-ca-dir = $${rootdirectory:srv}/erp5-ssl
ca-dir = $${rootdirectory:srv}/ssl
cron-entries = $${rootdirectory:etc}/cron.d
crontabs = $${rootdirectory:etc}/crontabs
cronstamps = $${rootdirectory:etc}/cronstamps
logrotate-backup = $${basedirectory:backup}/logrotate
logrotate-entries = $${rootdirectory:etc}/logrotate.d
[binary-link]
recipe = slapos.cookbook:symbolic.link
target-directory = $${rootdirectory:bin}
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
${git:location}/bin/git
${graphviz:location}/bin/dot
${grep:location}/bin/grep
${imagemagick:location}/bin/convert
${imagemagick:location}/bin/identify
${mariadb:location}/bin/mysql
${mariadb:location}/bin/mysqldump
${pdftk:location}/bin/pdftk
${sed:location}/bin/sed
${tesseract:location}/bin/tesseract
${w3m:location}/bin/w3m
${poppler:location}/bin/pdfinfo
${poppler:location}/bin/pdftotext
${poppler:location}/bin/pdftohtml
[erp5-bootstrap]
recipe = slapos.cookbook:erp5.bootstrap
runner-path = $${basedirectory:services}/erp5-bootstrap
mysql-url = %(mysql-url)s
zope-url = http://$${%(zope_section)s:user}:$${%(zope_section)s:password}@$${%(zope_section)s:ip}:$${%(zope_section)s:port}/%(site_id)s
[erp5-promise]
recipe = slapos.cookbook:erp5.promise
promise-path = $${rootdirectory:etc}/erp5promise.cfg
kumofs-url = %(kumofs-url)s
memcached-url = %(memcached-url)s
cloudooo-url = %(cloudooo-url)s
smtp-url = $${slap-parameter:smtp-url}
bt5 = $${slap-parameter:bt5}
bt5-repository-url = $${slap-parameter:bt5-repository-url}
software/erp5/snippet-zeo.cfg
deleted
100644 → 0
View file @
9a54dee8
[zeo-instance-%(zeo_id)s]
<= zeo-instance-entry-common
log-path = $${basedirectory:log}/zeo-%(zeo_id)s.log
pid-path = $${basedirectory:run}/zeo-%(zeo_id)s.pid
conf-path = $${rootdirectory:etc}/zeo-%(zeo_id)s.conf
port = %(zeo_port)s
storage =
%(storage_list)s
wrapper-path = $${basedirectory:services}/zeo-%(zeo_id)s
[logrotate-entry-zeo-%(zeo_id)s]
<= logrotate
recipe = slapos.cookbook:logrotate.d
name = zeo-%(zeo_id)s
log = $${zeo-instance-%(zeo_id)s:log-path}
post = ${buildout:bin-directory}/killpidfromfile $${zeo-instance-%(zeo_id)s:pid-path} SIGUSR2
software/erp5/snippet-zope.cfg
deleted
100644 → 0
View file @
9a54dee8
[%(zope_id)s]
recipe = slapos.cookbook:generic.zope.zeo.client
# XXX: products won't be needed as soon as all ERP5 (and products-deps)
# products will be eggified so then it will be possible to use them thanks to
# availability in software's eggs
products = ${products:list}
# Options
user = zope
port = %(zope_port)s
ip = $${slap-network-information:local-ipv4}
thread-amount = %(zope_thread_amount)s
deadlock-path = /manage_debug_threads
timezone = %(timezone)s
zeo-connection-string =
%(zeo_connection_string)s
timeserver = %(zope_timeserver)s
tidstorage-ip = $${tidstorage:ip}
tidstorage-port = $${tidstorage:port}
# long request
longrequest-logger-file = %(longrequest_logger_file)s
longrequest-logger-timeout = %(longrequest_logger_timeout)s
longrequest-logger-interval = %(longrequest_logger_interval)s
# Paths
wrapper = $${basedirectory:services}/%(zope_id)s
instance-path = $${directory:instance}
instance-etc = $${directory:instance-etc}
instance-products = $${directory:instance-products}
bt5-repository = $${rootdirectory:var}/bt5_repository
tmp-path = $${rootdirectory:tmp}
bin-path = $${rootdirectory:bin}
site-zcml = $${:instance-etc}/site.zcml
pid-file = $${basedirectory:run}/%(zope_id)s.pid
lock-file = $${basedirectory:run}/%(zope_id)s.lock
event-log = $${basedirectory:log}/%(zope_id)s-event.log
z2-log = $${basedirectory:log}/%(zope_id)s-Z2.log
configuration-file = $${rootdirectory:etc}/%(zope_id)s.conf
inituser = $${:instance-path}/inituser
# Binary information
runzope-binary = ${buildout:bin-directory}/runzope
# BT5 Configuration
bt5-repository-list =
promise-path = $${erp5-promise:promise-path}
site-id = %(site_id)s
[logrotate-entry-%(zope_id)s]
<= logrotate
recipe = slapos.cookbook:logrotate.d
name = %(zope_id)s
log = $${%(zope_id)s:event-log} $${%(zope_id)s:z2-log}
post = ${buildout:bin-directory}/killpidfromfile $${%(zope_id)s:pid-file} SIGUSR2
software/erp5/software.cfg
View file @
816550d8
...
...
@@ -13,6 +13,7 @@ parts +=
slapos.cookbook-repository
check-recipe
slapos.cookbook-python2.6
slapos.recipe.template-python2.6
# Create instance template
template
...
...
@@ -42,6 +43,12 @@ scripts =
python = python2.6
ugly-depend-on = ${slapos.cookbook-repository:command} ${slapos.cookbook-repository:update-command}
[slapos.recipe.template-python2.6]
recipe = zc.recipe.egg
eggs = slapos.recipe.template
scripts =
python = python2.6
[template-jinja2-base]
recipe = slapos.recipe.template:jinja2
template = ${:_profile_base_location_}/${:filename}.in
...
...
@@ -103,20 +110,6 @@ extra-context =
key tesseract_location tesseract:location
key w3m_location w3m:location
[template-cloudooo]
recipe = slapos.recipe.template
url = ${:_profile_base_location_}/instance-cloudooo.cfg
md5sum = e7698a0537785339e249bdc57f369e93
output = ${buildout:directory}/template-cloudooo.cfg
mode = 0644
[template-snippet-fontconfig]
recipe = slapos.recipe.template
url = ${:_profile_base_location_}/snippet-fontconfig.cfg
md5sum = 76c5d4cd1c8d48648684d9873f1ffed3
output = ${buildout:directory}/template-snippet-fontconfig.cfg
mode = 0644
[template-kumofs]
< = template-jinja2-base
filename = instance-kumofs.cfg
...
...
@@ -129,11 +122,55 @@ extra-context =
key logrotate_location logrotate:location
[template]
recipe = slapos.recipe.template
url = ${:_profile_base_location_}/instance.cfg
md5sum = f3443d071d8d7330b3453583e096fef0
output = ${buildout:directory}/template.cfg
mode = 0644
< = template-jinja2-base
# XXX: "template.cfg" is hardcoded in instanciation recipe
filename = template.cfg
template = ${:_profile_base_location_}/instance.cfg.in
md5sum = 29e6514746ec06708d1dd9fe600f653b
extra-context =
key apache_location apache:location
key buildout_bin_directory buildout:bin-directory
key coreutils_location coreutils:location
key dcron_location dcron:location
key file_location file:location
key fontconfig_location fontconfig:location
key fonts_location fonts:location
key freetype_location freetype:location
key git_location git:location
key graphviz_location graphviz:location
key grep_location grep:location
key gzip_location gzip:location
key haproxy_location haproxy:location
key imagemagick_location imagemagick: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 libpng12_location libpng12:location
key libreoffice_bin_location libreoffice-bin:location
key libxcb_location libxcb:location
key logrotate_location logrotate:location
key mariadb_location mariadb:location
key openssl_location openssl:location
key pdftk_location pdftk:location
key poppler_location poppler:location
key product_list products:list
key profile_base_location :_profile_base_location_
key sed_location sed:location
key template_erp5_development template-erp5-development:rendered
key template_erp5_production template-erp5-production:rendered
key template_kumofs template-kumofs:rendered
key template_mariadb template-mariadb:rendered
key template_memcached template-memcached:rendered
key template_sphinx template-sphinx:rendered
key template_varnish template-varnish:rendered
key template_zope template-zope:rendered
key tesseract_location tesseract:location
key w3m_location w3m:location
key zlib_location zlib:location
[template-memcached]
< = template-jinja2-base
...
...
@@ -158,34 +195,6 @@ md5sum = 1b458ff6a9b82f24f29f71b58f559186
extra-context =
key local_bt5_repository local-bt5-repository:list
[template-snippet-zeo]
recipe = slapos.recipe.template
url = ${:_profile_base_location_}/snippet-zeo.cfg
md5sum = ca9ee3825ff90c5c894ff1da8c601552
output = ${buildout:directory}/template-snippet-zeo.cfg
mode = 0644
[template-snippet-master]
recipe = slapos.recipe.template
url = ${:_profile_base_location_}/snippet-master.cfg
md5sum = 14ffe48453a74190bdd289169220739f
output = ${buildout:directory}/template-snippet-master.cfg
mode = 0644
[template-snippet-zope]
recipe = slapos.recipe.template
url = ${:_profile_base_location_}/snippet-zope.cfg
md5sum = bcc68c31a16b35bee7111f9c6e02b781
output = ${buildout:directory}/template-snippet-zope.cfg
mode = 0644
[template-snippet-backend]
recipe = slapos.recipe.template
url = ${:_profile_base_location_}/snippet-backend.cfg
md5sum = 3a1b359b57bf21a226bb96c0c18f1924
output = ${buildout:directory}/template-snippet-backend.cfg
mode = 0644
[template-varnish]
< = template-jinja2-base
filename = instance-varnish.cfg
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment