Commit 6f913a29 authored by Marco Mariani's avatar Marco Mariani

Merge branch 'master' into zimbra

parents ad1362d8 5ca33bc8
Changes
=======
0.76.0 (2013-04-03)
-------------------
* Add 'generic' phpconfigure recipe, allowing to configure any PHP-based app. [Cedric de Saint Martin]
* apache_frontend: Have more useful access_log in apache frontend. [Cedric de Saint Martin]
* apache_frontend: Add "SSLProxyEngine On" to http apache frontend vhost to be able to proxy https -> http. [Cedric de Saint Martin]
* Add first preliminary version of nginx-based reverse proxy. [Cedric de Saint Martin]
* Request-optional is not verbose anymore (again) if it failed. [Cedric de Saint Martin]
* Add possibility to fetch web ip and port from apache recipe. [Cedric de Saint Martin]
0.75.0 (2013-03-26)
-------------------
* Add backward compatibility about Partition.getInstanceGuid() in request.py. [Cedric de Saint Martin]
* request.py: Don't crash if resource is not ready. [Cedric de Saint Martin]
* Use memory-based kumofs instead of memcached to have no limitation for key length and data size. [Kazuhiko Shiozaki]
* Postgres: allow slapuser# to connect as postgres user. [Marco Mariani]
* apache_frontend: Sanitize inputs, disable Varnish cache, don't touch to custom file if already present. [Cedric de Saint Martin]
* Resiliency: simpler, more robust PBS recipe and promise. [Marco Mariani]
* Add helper method to set "location" parameter in librecipe. [Cedric de Saint Martin]
* Add download helper function in librecipe. [Cedric de Saint Martin]
* Update wrapper recipe to make it simpler and more dev-friendly. [Cedric de Saint Martin]
* Add configurationfile recipe. [Cedric de Saint Martin]
* Add request-edge recipe. [Cedric de Saint Martin]
* Add publishsection recipe. [Cedric de Saint Martin]
* Add match support for promise check_page_content. [Cedric de Saint Martin]
0.74.0 (2013-03-05)
-------------------
......
......@@ -51,7 +51,7 @@ md5sum = 5dc8cc28447ed3747b8a53c768d872aa
# NODE_PATH=${:destination}/node_modules ${nodejs:node_location} ${:cloud9_js_location}
recipe = plone.recipe.command
stop-on-error = true
commit = 9158bbf9e886e3b96e91239249aca66e420aa8d1
commit = f7d102bc225c922f116d2cea52a746d64343ea59
repository = https://github.com/ajaxorg/cloud9.git
location = ${buildout:parts-directory}/${:_buildout_section_name_}
environment = export GIT_SSL_NO_VERIFY=true; export PATH=${git:location}/bin:${nodejs:location}/bin:${node-sm:location}/node_modules/sm/bin:$PATH; export CPPFLAGS="-I${libxml2:location}/include -I${nodejs:location}/include"; export LDFLAGS="-L${libxml2:location}/lib -Wl,-rpath=${libxml2:location}/lib"; export HOME=${:location};
......
......@@ -6,8 +6,8 @@ parts =
[coreutils]
recipe = hexagonit.recipe.cmmi
url = http://ftp.gnu.org/gnu/coreutils/coreutils-8.20.tar.xz
md5sum = 3d69af8f561fce512538a9fe85f147ff
url = http://ftp.gnu.org/gnu/coreutils/coreutils-8.21.tar.xz
md5sum = 065ba41828644eca5dd8163446de5d64
configure-options =
--prefix=${buildout:parts-directory}/${:_buildout_section_name_} --enable-install-program=tr,basename,uname,cat,cp,ls
environment =
......
......@@ -8,8 +8,8 @@ extends =
[gettext]
recipe = hexagonit.recipe.cmmi
url = http://ftp.gnu.org/pub/gnu/gettext/gettext-0.18.2.tar.gz
md5sum = 0c86e5af70c195ab8bd651d17d783928
url = http://ftp.gnu.org/pub/gnu/gettext/gettext-0.18.2.1.tar.gz
md5sum = 034c8103b14654ebd300fadac44d6f14
configure-options =
--disable-static
......
......@@ -11,9 +11,9 @@ extends =
[groonga]
recipe = hexagonit.recipe.cmmi
version = 3.0.1
version = 3.0.2
url = http://packages.groonga.org/source/groonga/groonga-${:version}.tar.gz
md5sum = fd03bb14a04e7c696151b5673e408701
md5sum = b17934ef2589a4e261ed0d99aec713eb
configure-options =
--disable-static
--disable-glibtest
......@@ -27,9 +27,9 @@ environment =
[groonga-normalizer-mysql]
recipe = hexagonit.recipe.cmmi
version = 1.0.1
version = 1.0.2
url = http://packages.groonga.org/source/groonga-normalizer-mysql/groonga-normalizer-mysql-${:version}.tar.gz
md5sum = 93239c856f2e4768562506d440cb4c7d
md5sum = 782111599dcba5023beb698dc5ea514a
location = ${groonga:location}
depends =
${groonga:version}
......
......@@ -9,8 +9,8 @@ parts = haproxy
[haproxy]
recipe = hexagonit.recipe.cmmi
url = http://haproxy.1wt.eu/download/1.4/src/haproxy-1.4.22.tar.gz
md5sum = a0b007c76f6a78524f3b3dd5e704979c
url = http://haproxy.1wt.eu/download/1.4/src/haproxy-1.4.23.tar.gz
md5sum = 6535d5e58037ada4b58b439cebe03c79
configure-command = true
# If the system is running on Linux 2.6, we use "linux26" as the TARGET,
# otherwise use "generic".
......
......@@ -30,6 +30,7 @@ md5sum = 46148e9536222d0ad2ef36777c55714d
patches = ${kumo-ipv6-multiip-patch-download:location}/${kumo-ipv6-multiip-patch-download:filename}
patch-options = -p1
configure-options =
--enable-tcadb
--with-tokyocabinet=${tokyocabinet:location}
--with-msgpack=${messagepack:location}
......
......@@ -62,8 +62,8 @@ environment =
# mroonga - a storage engine for MySQL. It provides fast fulltext search feature to all MySQL users.
# http://mroonga.github.com/
recipe = hexagonit.recipe.cmmi
url = http://packages.groonga.org/source/mroonga/mroonga-3.01.tar.gz
md5sum = 45c302ca45ae0eb4bbc6f3ec5f7f1072
url = http://packages.groonga.org/source/mroonga/mroonga-3.02.tar.gz
md5sum = b2d1a4abc12030fdbd9064bbb6175366
configure-options =
--with-mysql-source=${mariadb:location}__compile__/mariadb-${mariadb:version}
--with-mysql-config=${mariadb:location}/bin/mysql_config
......
......@@ -4,14 +4,36 @@ extends =
../zlib/buildout.cfg
../openssl/buildout.cfg
parts = nginx
[nginx]
recipe = hexagonit.recipe.cmmi
url = http://nginx.org/download/nginx-1.0.14.tar.gz
url = http://nginx.org/download/nginx-1.2.7.tar.gz
md5sum = d252f5c689a14a668e241c744ccf5f06
configure-options=
--with-ipv6
--with-http_ssl_module
--with-mail
--with-mail_ssl_module
--with-ld-opt="-L ${zlib:location}/lib -L ${openssl:location}/lib -L ${pcre:location}/lib -Wl,-rpath=${pcre:location}/lib -Wl,-rpath=${zlib:location}/lib -Wl,-rpath=${openssl:location}/lib"
--with-cc-opt="-I ${pcre:location}/include -I ${openssl:location}/include -I ${zlib:location}/include"
[nginx-unstable]
<= nginx
url = http://nginx.org/download/nginx-1.3.15.tar.gz
md5sum = ded252047393c79a31b0862e9166a065
[hexaglobe-nginx-module]
recipe = hexagonit.recipe.download
url = http://easicloud-p.cdn.hexaglobe.net/nginx-easicloud.tar.gz
md5sum = 57fe2ceb09740f22b5b1023f29889e0e
strip-top-level-dir = true
[nginx-enable-sub]
# Used by Hexaglobe for watermarking
<= nginx
configure-options=
--with-ipv6
--with-http_ssl_module
--with-ld-opt="-L ${zlib:location}/lib -L ${openssl:location}/lib -L ${pcre:location}/lib -Wl,-rpath=${pcre:location}/lib -Wl,-rpath=${zlib:location}/lib -Wl,-rpath=${openssl:location}/lib"
--with-cc-opt="-I ${pcre:location}/include -I ${openssl:location}/include -I ${zlib:location}/include"
--add-module=${hexaglobe-nginx-module:location}/sub_module
# --add-module=${hexaglobe-nginx-module:location}/nginx-upstream-fair
......@@ -45,6 +45,7 @@ configure-options =
--libdir=lib
shared no-idea no-mdc2 no-rc5 zlib
-Wl,-rpath=${zlib:location}/lib -Wl,-rpath=${buildout:parts-directory}/${:_buildout_section_name_}/lib
&& make depend
# it seems that parallel build sometimes fails for openssl.
make-options =
......
......@@ -23,11 +23,11 @@ filename = create-libs-symlink.py
recipe = hexagonit.recipe.cmmi
depends =
${gdbm:version}
version = 5.16.2
version = 5.16.3
# increase revision when we need to rebuild binary libraries.
revision = 1
url = http://www.cpan.org/src/5.0/perl-${:version}.tar.bz2
md5sum = 2818ab01672f005a4e552a713aa27b08
md5sum = 025102de0e4a597cf541e57da80c6aa3
siteprefix = ${buildout:parts-directory}/site_${:_buildout_section_name_}
patch-options = -p1
patches =
......
......@@ -14,8 +14,8 @@ parts = postgresql
[postgresql91]
recipe = hexagonit.recipe.cmmi
url = http://ftp.postgresql.org/pub/source/v9.1.7/postgresql-9.1.7.tar.bz2
md5sum = eaf7b67493d59d1a60767ffdfbd65ce9
url = http://ftp.postgresql.org/pub/source/v9.1.9/postgresql-9.1.9.tar.bz2
md5sum = 6b5ea53dde48fcd79acfc8c196b83535
configure-options = --with-openssl --with-perl
environment =
CPPFLAGS=-I${zlib:location}/include -I${readline:location}/include -I${openssl:location}/include -I${ncurses:location}/lib
......@@ -24,8 +24,8 @@ environment =
[postgresql92]
recipe = hexagonit.recipe.cmmi
url = http://ftp.postgresql.org/pub/source/v9.2.2/postgresql-9.2.2.tar.bz2
md5sum = 1cc388988e69bf75c6b55d59070100f6
url = http://ftp.postgresql.org/pub/source/v9.2.4/postgresql-9.2.4.tar.bz2
md5sum = 6ee5bb53b97da7c6ad9cb0825d3300dd
configure-options = --with-openssl
environment =
CPPFLAGS=-I${zlib:location}/include -I${readline:location}/include -I${openssl:location}/include -I${ncurses:location}/lib
......
[buildout]
extends =
../gdbm/buildout.cfg
../openssl/buildout.cfg
../zlib/buildout.cfg
../readline/buildout.cfg
../ncurses/buildout.cfg
../libyaml/buildout.cfg
parts = ruby
......@@ -12,8 +17,8 @@ md5sum = bc0c715c69da4d1d8bd57069c19f6c0e
configure-options =
--enable-shared --enable-rpath
environment =
CFLAGS=-I${libyaml:location}/include
LDFLAGS=-L${libyaml:location}/lib -Wl,-rpath=${libyaml:location}/lib
CPPFLAGS=-I${zlib:location}/include -I${readline:location}/include -I${libyaml:location}/include -I${ncurses:location}/include -I${ncurses:location}/include/ncursesw -I${gdbm:location}/include -I${openssl:location}/include
LDFLAGS=-L${zlib:location}/lib -L${libyaml:location}/lib -L${readline:location}/lib -L${ncurses:location}/lib -L${gdbm:location}/lib -L${openssl:location}/lib -Wl,-rpath=${zlib:location}/lib -Wl,-rpath=${libyaml:location}/lib -Wl,-rpath=${ncurses:location}/lib -Wl,-rpath=${readline:location}/lib -Wl,-rpath=${gdbm:location}/lib -Wl,-rpath=${openssl:location}/lib
[ruby-1.9]
<= ruby-1.9.3
......
......@@ -5,8 +5,8 @@ parts =
[sqlite3]
recipe = hexagonit.recipe.cmmi
url = http://www.sqlite.org/sqlite-autoconf-3071502.tar.gz
md5sum = bcb0ab0b5b30116b2531cfeef3c861b4
url = http://www.sqlite.org/2013/sqlite-autoconf-3071601.tar.gz
md5sum = 8860d1a1ed26d40f07e3c7ae035b644a
configure-options =
--disable-static
--enable-readline
......
......@@ -28,7 +28,7 @@ from setuptools import setup, find_packages
import glob
import os
version = '0.74.1-dev'
version = '0.76.1.dev'
name = 'slapos.cookbook'
long_description = open("README.txt").read() + "\n" + \
open("CHANGES.txt").read() + "\n"
......@@ -52,6 +52,7 @@ setup(name=name,
packages=find_packages(),
include_package_data=True,
install_requires=[
'hexagonit.recipe.download',
'lxml', # for full blown python interpreter
'netaddr', # to manipulate on IP addresses
'setuptools', # namespaces
......@@ -72,6 +73,7 @@ setup(name=name,
'apache.zope.backend = slapos.recipe.apache_zope_backend:Recipe',
'apacheperl = slapos.recipe.apacheperl:Recipe',
'apachephp = slapos.recipe.apachephp:Recipe',
'apachephpconfigure = slapos.recipe.apachephpconfigure:Recipe',
'apacheproxy = slapos.recipe.apacheproxy:Recipe',
'certificate_authority = slapos.recipe.certificate_authority:Recipe',
'certificate_authority.request = slapos.recipe.certificate_authority:Request',
......@@ -80,6 +82,7 @@ setup(name=name,
'check_url_available = slapos.recipe.check_url_available:Recipe',
'cloud9 = slapos.recipe.cloud9:Recipe',
'cloudooo.test = slapos.recipe.erp5_test:CloudoooRecipe',
'configurationfile = slapos.recipe.configurationfile:Recipe',
'cron = slapos.recipe.dcron:Recipe',
'cron.d = slapos.recipe.dcron:Part',
'davstorage = slapos.recipe.davstorage:Recipe',
......@@ -121,6 +124,7 @@ setup(name=name,
'kvm = slapos.recipe.kvm:Recipe',
'kvm.frontend = slapos.recipe.kvm_frontend:Recipe',
'lamp = slapos.recipe.lamp:Request',
'lamp.generic = slapos.recipe.lampgeneric:Recipe',
'lamp.request = slapos.recipe.lamp:Request',
'lamp.simple = slapos.recipe.lamp:Simple',
'lamp.static = slapos.recipe.lamp:Static',
......@@ -151,12 +155,15 @@ setup(name=name,
'proactive = slapos.recipe.proactive:Recipe',
'publish = slapos.recipe.publish:Recipe',
'publish.serialised = slapos.recipe.publish:Serialised',
'publishsection = slapos.recipe.publish:PublishSection',
'publishurl = slapos.recipe.publishurl:Recipe',
'pwgen = slapos.recipe.pwgen:Recipe',
'pwgen.stable = slapos.recipe.pwgen:StablePasswordGeneratorRecipe',
'request = slapos.recipe.request:Recipe',
'request.serialised = slapos.recipe.request:Serialised',
'request.edge = slapos.recipe.request:RequestEdge',
'requestoptional = slapos.recipe.request:RequestOptional',
'reverseproxy.nginx = slapos.recipe.reverse_proxy_nginx:Recipe',
'seleniumrunner = slapos.recipe.seleniumrunner:Recipe',
'sheepdogtestbed = slapos.recipe.sheepdogtestbed:SheepDogTestBed',
'shell = slapos.recipe.shell:Recipe',
......@@ -188,8 +195,8 @@ setup(name=name,
'xvfb = slapos.recipe.xvfb:Recipe',
'xwiki = slapos.recipe.xwiki:Recipe',
'zabbixagent = slapos.recipe.zabbixagent:Recipe',
'zimbra.kvm = slapos.recipe.zimbra_kvm:Recipe',
'zeo = slapos.recipe.zeo:Recipe',
],
'slapos.recipe.nosqltestbed.plugin': [
'kumo = slapos.recipe.nosqltestbed.kumo:KumoTestBed',
......
......@@ -22,7 +22,7 @@ ServerTokens Prod
# Log configuration
ErrorLog "%(error_log)s"
LogLevel warn
LogLevel info
LogFormat "%%h %%{REMOTE_USER}i %%{Host}i %%l %%u %%t \"%%r\" %%>s %%b \"%%{Referer}i\" \"%%{User-Agent}i\"" combined
LogFormat "%%h %%{REMOTE_USER}i %%{Host}i %%l %%u %%t \"%%r\" %%>s %%b" common
CustomLog "%(access_log)s" common
......@@ -130,6 +130,7 @@ Header append Vary User-Agent
<VirtualHost *:%(plain_http_port)s>
RewriteEngine On
SSLProxyEngine on
ProxyPreserveHost On
# Include configuration file not operated by slapos. This file won't be erased
......
......@@ -101,6 +101,9 @@ class Recipe(GenericBaseRecipe):
mysql_ip=self.options['mysql-host'],
mysql_port=self.options['mysql-port'],
secret_key=secret_key,
ip='[%s]' % self.options['ip'],
port=self.options['port'],
# XXX-Cedric: add frontend url.
)
directory, file_ = os.path.split(self.options['configuration'])
......
##############################################################################
#
# Copyright (c) 2012 Vifib SARL and Contributors. All Rights Reserved.
#
# WARNING: This program as such is intended to be used by professional
# programmers who take the whole responsibility of assessing all potential
# consequences resulting from its eventual inadequacies and bugs
# End users who are looking for a ready-to-use solution with commercial
# guarantees and support are strongly adviced to contract a Free Software
# Service Company
#
# This program is Free Software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 3
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#
##############################################################################
from slapos.recipe.librecipe import GenericBaseRecipe
import zc.buildout
import sys
import zc.recipe.egg
class Recipe(GenericBaseRecipe):
def install(self):
"""
Taken out from the old "lamp" recipe. Allows do configure a LAMP instance.
"""
self.path_list = []
document_root = self.options['htdocs']
url = self.options.get('url', '')
mysql_conf = {'mysql_host': self.options['mysql-host'],
'mysql_port': self.options['mysql-port'],
'mysql_user': self.options['mysql-username'],
'mysql_password': self.options['mysql-password'],
'mysql_database': self.options['mysql-database'],
}
self.configureInstallation(document_root, url, mysql_conf)
return self.path_list
def configureInstallation(self, document_root, url, mysql_conf):
"""Start process which can launch python scripts, move or remove files or
directories when installing software.
"""
if not self.options.has_key('delete') and not self.options.has_key('rename') and not\
self.options.has_key('chmod') and not self.options.has_key('script') and not self.options.has_key('sql-script'):
return ""
delete = []
chmod = []
data = []
rename = []
rename_list = ""
argument = [self.options['lampconfigure'], "-H", mysql_conf['mysql_host'], "-P", mysql_conf['mysql_port'],
"-p", mysql_conf['mysql_password'], "-u", mysql_conf['mysql_user']]
if not self.options.has_key('file_token'):
argument = argument + ["-d", mysql_conf['mysql_database'],
"--table", self.options['table_name'].strip(), "--cond",
self.options.get('constraint', '1').strip()]
else:
argument = argument + ["-f", self.options['file_token'].strip()]
argument += ["-t", document_root]
if self.options.has_key('delete'):
delete = ["delete"]
for fname in self.options['delete'].split(','):
delete.append(fname.strip())
if self.options.has_key('rename'):
for fname in self.options['rename'].split(','):
if fname.find("=>") < 0:
old_name = fname
fname = []
fname.append(old_name)
fname.append(old_name + '-' + mysql_conf['mysql_user'])
else:
fname = fname.split("=>")
cmd = ["rename"]
if self.options.has_key('rename_chmod'):
cmd += ["--chmod", self.options['rename_chmod'].strip()]
rename.append(cmd + [fname[0].strip(), fname[1].strip()])
rename_list += fname[0] + " to " + fname[1] + " "
if self.options.has_key('chmod'):
chmod = ["chmod", self.options['mode'].strip()]
for fname in self.options['chmod'].split(','):
chmod.append(fname.strip())
if self.options.has_key('script') and \
self.options['script'].strip().endswith(".py"):
data = ["run", self.options['script'].strip(), "-v", mysql_conf['mysql_database'], url, document_root]
if self.options.has_key('sql-script'):
data = ["sql", self.options['sql-script'].strip(), "-v", mysql_conf['mysql_database'], url, document_root]
# TODO factor
if delete != []:
print "Creating lampconfigure with 'delete' arguments"
command = argument + delete
if rename != []:
for parameters in rename:
print "Creating lampconfigure with 'rename' arguments"
command = argument + rename
if chmod != []:
print "Creating lampconfigure with 'chmod' arguments"
command = argument + chmod
if data != []:
print "Creating lampconfigure with 'run' arguments"
command = argument + data
configureinstall_wrapper_path = self.createPythonScript(
self.options['configureinstall-location'],
__name__ + '.runner.executeRunner',
[argument, delete, rename, chmod, data]
)
#TODO finish to port this and remove upper one
#configureinstall_wrapper_path = self.createPythonScript(
# self.options['configureinstall-location'],
# 'slapos.lamp.run',
# [command]
#)
self.path_list.append(configureinstall_wrapper_path)
return rename_list
import subprocess
def executeRunner(args):
"""Start the instance configure. this may run a python script, move or/and rename
file or directory when dondition is filled. the condition may be when file exist or when an entry
exist into database.
"""
arguments, delete, rename, chmod, data = args
if delete != []:
print "Calling lampconfigure with 'delete' arguments"
result = subprocess.Popen(arguments + delete)
result.wait()
if rename != []:
for parameters in rename:
print "Calling lampconfigure with 'rename' arguments"
result = subprocess.Popen(arguments + parameters)
result.wait()
if chmod != []:
print "Calling lampconfigure with 'chmod' arguments"
result = subprocess.Popen(arguments + chmod)
result.wait()
if data != []:
print "Calling lampconfigure with 'run' arguments"
print arguments + data
result = subprocess.Popen(arguments + data)
result.wait()
return
......@@ -38,6 +38,7 @@ class Recipe(GenericBaseRecipe):
'url': self.options['url'],
'shell_path': self.options['dash_path'],
'curl_path': self.options['curl_path'],
'match': self.options.get('match', self.options['url'])
}
# XXX-Cedric in this script, curl won't check certificate
......
......@@ -3,13 +3,14 @@
# BEWARE: It will be overwritten automatically
URL="%(url)s"
MATCH='%(match)s"
if [ -z $URL ]; then
echo "No URL specified." >&2
exit 3
fi
%(curl_path)s -k -sL $URL | grep "$URL" > /dev/null
%(curl_path)s -k -sL $URL | grep "$MATCH" > /dev/null
if [ $? != 0 ]; then
echo "Content at $URL seems to be corrupted" >&2
......
##############################################################################
#
# Copyright (c) 2010 Vifib SARL and Contributors. All Rights Reserved.
#
# WARNING: This program as such is intended to be used by professional
# programmers who take the whole responsibility of assessing all potential
# consequences resulting from its eventual inadequacies and bugs
# End users who are looking for a ready-to-use solution with commercial
# guarantees and support are strongly adviced to contract a Free Software
# Service Company
#
# This program is Free Software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 3
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#
##############################################################################
from slapos.recipe.librecipe import GenericBaseRecipe
class Recipe(GenericBaseRecipe):
def install(self):
configuration_file = self.createFile(
self.options['configuration-file-path'],
self.substituteTemplate(
self.options['configuration-template-path'],
self.options
)
)
return configuration_file
......@@ -36,6 +36,11 @@ from slapos.recipe.librecipe import GenericBaseRecipe
BUFFER_SIZE = 1024
# XXX-Cedric: For god's sake, why do we always reinvent the wheel???
# DON'T use this and use h.r.download, except if you need the "confirm" feature.
# XXX-Cedric: implement "confirm" feature in h.r.download
def service(args):
environ = os.environ.copy()
environ.update(PATH=args['path'])
......
##############################################################################
#
# Copyright (c) 2013 Vifib SARL and Contributors. All Rights Reserved.
#
# WARNING: This program as such is intended to be used by professional
# programmers who take the whole responsibility of assessing all potential
# consequences resulting from its eventual inadequacies and bugs
# End users who are looking for a ready-to-use solution with commercial
# guarantees and support are strongly adviced to contract a Free Software
# Service Company
#
# This program is Free Software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 3
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#
##############################################################################
import shutil
import os
import zc.buildout
from slapos.recipe.librecipe import GenericBaseRecipe
class Recipe(GenericBaseRecipe):
# XXX-Cedric: write docstring
def install(self):
path_list = []
# Download and unpack application if not already existing
htdocs_location = self.options['htdocs']
if not (os.path.exists(htdocs_location) and os.listdir(htdocs_location)):
try:
os.rmdir(htdocs_location)
except:
pass
self.download(htdocs_location)
# Install php.ini
php_ini = self.createFile(os.path.join(self.options['php-ini-dir'],
'php.ini'),
self.substituteTemplate(self.getTemplateFilename('php.ini.in'),
dict(tmp_directory=self.options['tmp-dir']))
)
path_list.append(php_ini)
# Install apache
apache_config = dict(
pid_file=self.options['pid-file'],
lock_file=self.options['lock-file'],
ip=self.options['ip'],
port=self.options['port'],
error_log=self.options['error-log'],
access_log=self.options['access-log'],
document_root=self.options['htdocs'],
php_ini_dir=self.options['php-ini-dir'],
)
httpd_conf = self.createFile(self.options['httpd-conf'],
self.substituteTemplate(self.getTemplateFilename('apache.in'),
apache_config)
)
path_list.append(httpd_conf)
wrapper = self.createWrapper(name=self.options['wrapper'],
command=self.options['httpd-binary'],
parameters=[
'-f',
self.options['httpd-conf'],
'-DFOREGROUND'
])
path_list.append(wrapper)
return path_list
# Apache static configuration
# Automatically generated
# Basic server configuration
PidFile "%(pid_file)s"
Listen %(ip)s:%(port)s
PHPINIDir %(php_ini_dir)s
ServerAdmin someone@email
DefaultType text/plain
TypesConfig conf/mime.types
AddType application/x-compress .Z
AddType application/x-gzip .gz .tgz
AddType application/x-httpd-php .php .phtml .php5 .php4
AddType application/x-httpd-php-source .phps
# Log configuration
ErrorLog "%(error_log)s"
LogLevel warn
LogFormat "%%h %%{REMOTE_USER}i %%l %%u %%t \"%%r\" %%>s %%b \"%%{Referer}i\" \"%%{User-Agent}i\"" combined
LogFormat "%%h %%{REMOTE_USER}i %%l %%u %%t \"%%r\" %%>s %%b" common
CustomLog "%(access_log)s" common
# Directory protection
<Directory />
Options FollowSymLinks
AllowOverride None
Require all denied
</Directory>
<Directory %(document_root)s>
Options FollowSymLinks
AllowOverride All
Require all granted
</Directory>
DocumentRoot %(document_root)s
DirectoryIndex index.html index.php
# List of modules
LoadModule unixd_module modules/mod_unixd.so
LoadModule access_compat_module modules/mod_access_compat.so
LoadModule authz_core_module modules/mod_authz_core.so
LoadModule authz_host_module modules/mod_authz_host.so
LoadModule log_config_module modules/mod_log_config.so
LoadModule setenvif_module modules/mod_setenvif.so
LoadModule version_module modules/mod_version.so
LoadModule proxy_module modules/mod_proxy.so
LoadModule proxy_http_module modules/mod_proxy_http.so
LoadModule mime_module modules/mod_mime.so
LoadModule dav_module modules/mod_dav.so
LoadModule dav_fs_module modules/mod_dav_fs.so
LoadModule negotiation_module modules/mod_negotiation.so
LoadModule rewrite_module modules/mod_rewrite.so
LoadModule headers_module modules/mod_headers.so
LoadModule dir_module modules/mod_dir.so
LoadModule php5_module modules/libphp5.so
LoadModule alias_module modules/mod_alias.so
[PHP]
engine = On
safe_mode = Off
expose_php = Off
error_reporting = E_ALL & ~(E_DEPRECATED|E_NOTICE|E_WARNING)
display_errors = On
display_startup_errors = Off
log_errors = On
log_errors_max_len = 1024
ignore_repeated_errors = Off
ignore_repeated_source = Off
session.save_path = "%(tmp_directory)s"
session.auto_start = 0
date.timezone = Europe/Paris
file_uploads = On
upload_max_filesize = 8M
post_max_size = 8M
magic_quotes_gpc=Off
......@@ -32,6 +32,7 @@ import os
import sys
import inspect
import re
import shutil
import urllib
import urlparse
......@@ -226,3 +227,30 @@ class GenericBaseRecipe(object):
url = urlparse.urlunparse((scheme, netloc, path, params, query, fragment))
return url
def setLocationOption(self):
if not self.options.get('location'):
self.options['location'] = os.path.join(
self.buildout['buildout']['parts-directory'], self.name)
def download(self, destination=None):
""" A simple wrapper around h.r.download, downloading to self.location"""
self.setLocationOption()
import hexagonit.recipe.download
if not destination:
destination = self.location
if os.path.exists(destination):
# leftovers from a previous failed attempt, removing it.
log.warning('Removing already existing directory %s' % destination)
shutil.rmtree(destination)
os.mkdir(destination)
try:
options = self.options.copy()
options['destination'] = destination
hexagonit.recipe.download.Recipe(
self.buildout, self.name, options).install()
except:
shutil.rmtree(destination)
raise
......@@ -28,6 +28,8 @@ import zc.buildout
from slapos.recipe.librecipe import wrap
from slapos.recipe.librecipe import GenericSlapRecipe
CONNECTION_PARAMETER_STRING = 'connection-'
class Recipe(GenericSlapRecipe):
def _install(self):
publish_dict = dict()
......@@ -47,3 +49,26 @@ SERIALISED_MAGIC_KEY = '_'
class Serialised(Recipe):
def _setConnectionDict(self, publish_dict):
return super(Serialised, self)._setConnectionDict(wrap(publish_dict))
class PublishSection(GenericSlapRecipe):
"""
Take a list of "request" sections, and publish every connection parameter.
Input:
section-list: String, representing the list of sections to fetch
parameters to publish, in order, separated by a space.
"""
def _install(self):
publish_dict = dict()
for section in self.options['section-list'].strip().split():
section = section.strip()
options = self.buildout[section].copy()
for k, v in options.iteritems():
if k.startswith(CONNECTION_PARAMETER_STRING):
print k, v
publish_dict[k.lstrip(CONNECTION_PARAMETER_STRING)] = v
self.setConnectionDict(publish_dict)
return []
......@@ -195,7 +195,7 @@ class RequestOptional(Recipe):
self.logger.warning('Optional request failed.')
if not isinstance(self._raise_request_exception, slapmodule.NotFoundError):
# full traceback for optional 'not found' is too verbose and confusing
self.logger.warning(self._raise_request_exception_formatted)
self.logger.debug(self._raise_request_exception_formatted)
elif self.failed is not None:
# Check instance status to know if instance has been deployed
try:
......@@ -203,7 +203,7 @@ class RequestOptional(Recipe):
status = self.instance.getState()
else:
status = 'not ready yet'
except (slapmodule.NotFoundError, slapmodule.ServerError):
except (slapmodule.NotFoundError, slapmodule.ServerError, slapmodule.ResourceNotReady):
status = 'not ready yet'
except AttributeError:
status = 'unknown'
......@@ -215,7 +215,6 @@ class RequestOptional(Recipe):
update = install
class Serialised(Recipe):
def _filterForStorage(self, partition_parameter_kw):
return wrap(partition_parameter_kw)
......@@ -225,3 +224,39 @@ class Serialised(Recipe):
return json.loads(instance.getConnectionParameter(JSON_SERIALISED_MAGIC_KEY))
except slapmodule.NotFoundError:
return {}
CONNECTION_PARAMETER_STRING = 'connection-'
class RequestEdge(Recipe):
"""
For each country in country-list, do a request.
"""
def __init__(self, buildout, name, options):
self.logger = logging.getLogger(name)
self.options = options
self.request_dict = {}
# Keep a copy of original options dict
original_options = options.copy()
for country in options['country-list'].split(','):
# Request will have its own copy of options dict
local_options = original_options.copy()
local_options['name'] = '%s-%s' % (country, name)
local_options['sla'] = "region"
local_options['sla-region'] = country
self.request_dict[country] = Recipe(buildout, name, local_options)
# "Bubble" all connection parameters
for option, value in local_options.iteritems():
if option.startswith(CONNECTION_PARAMETER_STRING):
self.options['%s-%s' % (option, country)] = value
def install(self):
for country, request in self.request_dict.iteritems():
request.install()
return []
update = install
##############################################################################
#
# Copyright (c) 2010 Vifib SARL and Contributors. All Rights Reserved.
#
# WARNING: This program as such is intended to be used by professional
# programmers who take the whole responsibility of assessing all potential
# consequences resulting from its eventual inadequacies and bugs
# End users who are looking for a ready-to-use solution with commercial
# guarantees and support are strongly adviced to contract a Free Software
# Service Company
#
# This program is Free Software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 3
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#
##############################################################################
import operator
from slapos.recipe.librecipe import GenericSlapRecipe
import zc.buildout
class Recipe(GenericSlapRecipe):
def _install(self):
path_list = []
# Check for mandatory arguments
domain_name = self.options['domain']
if not domain_name:
raise zc.buildout.UserError('No domain name specified. Please define '
'the "domain" instance parameter.')
# XXX: add HTTP support
#https_port_number = self.options['https-port']
#http_port_number = self.options['http-port']
# Parse list of slaves
slave_instance_list = sorted(self.options['slave-instance-list'],
key=operator.itemgetter('slave_reference'))
# Now, we only take first instance and only use this one.
# XXX: TODO real implementation of slaves
zimbra_slave_instance = slave_instance_list[0]
# Generate Nginx configuration
nginx_configuration_dict = {
'listen-local-ipv4': self.options['ipv4'],
'listen-global-ipv6': '[%s]' % self.options['ipv6'],
'domain-name': domain_name,
'smtp-port-number': self.options['smtp-port'],
'error-log': self.options['error-log'],
'access-log': self.options['access-log'],
'htdocs': self.options['htdocs'],
'smtp-upstream-host': zimbra_slave_instance['smtp-upstream-host'],
'smtp-upstream-port': zimbra_slave_instance['smtp-upstream-port'],
}
nginx_configuration_file = self.createFile(
self.options['configuration-file'],
self.substituteTemplate(self.getTemplateFilename('nginx.conf.in'),
nginx_configuration_dict)
)
path_list.append(nginx_configuration_file)
# Generate Nginx wrapper
wrapper = self.createWrapper(
name=self.options['wrapper'],
command=self.options['nginx-executable'],
parameters=[
'-c', self.options['configuration-file'],
'-p', self.options['home-directory']
]
)
# TODO: reload configuration or have feature like apache_map
# Send connection informations about each slave
for slave_instance in slave_instance_list:
reference = slave_instance.get("slave_reference")
self.logger.debug('Sending connection parameters of slave '
'instance: %s' % reference)
try:
connection_dict = {
'listening-ipv6': self.options['ipv6'],
# Arbitrary, as the instance doesn't know its public IP.
'listening-ipv4': self.options['public-ipv4'],
# XXX-TODO
#'site_url': url,
}
self.setConnectionDict(connection_dict, reference)
except:
self.logger.fatal("Error while sending slave %s informations: %s",
reference, traceback.format_exc())
return path_list
daemon off;
worker_processes 1;
#XXX-Cedric: TODO separate the different logs
error_log %(error-log)s info;
events {
worker_connections 1024;
use epoll;
}
http {
log_format main
'$remote_addr - $remote_user [$time_local] '
'"$request" $status $bytes_sent '
'"$http_referer" "$http_user_agent" '
'"$gzip_ratio"';
server {
listen %(listen-local-ipv4)s:8008;
server_name localhost;
access_log %(access-log)s main;
error_log %(error-log)s info;
root %(htdocs)s;
location ~ $ {
add_header Auth-Server %(smtp-upstream-host)s;
add_header Auth-Port %(smtp-upstream-port)s;
return 200;
}
}
}
mail {
server_name %(domain-name)s;
auth_http %(listen-local-ipv4)s:8008;
server {
listen %(listen-local-ipv4)s:%(smtp-port-number)s;
listen %(listen-global-ipv6)s:%(smtp-port-number)s;
protocol smtp;
timeout 5s;
proxy on;
xclient off;
smtp_auth none;
}
}
......@@ -116,7 +116,7 @@ class Recipe:
for parameter, value in self.parameter_dict.items():
# All parameters evaluating to False are... False, and shouldn't
# convey any information.
# Here, all those parameters are set to empty string.
# Here, all those parameters are simply ignored.
if value:
if isinstance(value, str):
buildout.set('slap-parameter', parameter, value)
......
......@@ -30,25 +30,32 @@ import shlex
from slapos.recipe.librecipe import GenericBaseRecipe
class Recipe(GenericBaseRecipe):
def install(self):
command_line = shlex.split(self.options['command-line'])
wrapper_path = self.options['wrapper-path']
wait_files = self.options.get('wait-for-files')
environment = self.options.get('environment')
if not wait_files and not environment:
# Create a simple wrapper as shell script
return [self.createWrapper(
name=wrapper_path,
command=command_line[0],
parameters=command_line[1:],
)]
# More complex needs: create a Python script as wrapper
if wait_files is not None:
wait_files = [filename.strip() for filename in wait_files.split()
if filename.strip()]
environment = self.options.get('environment')
if environment is not None:
environment = dict((k.strip(), v.strip()) for k, v in [
line.split('=')
for line in environment.split('\n')
])
return [self.createPythonScript(
self.options['output'],
wrapper_path,
'slapos.recipe.librecipe.execute.generic_exec',
(command_line, wait_files, environment,),
)]
##############################################################################
#
# Copyright (c) 2011 Vifib SARL and Contributors. All Rights Reserved.
#
# WARNING: This program as such is intended to be used by professional
# programmers who take the whole responsibility of assessing all potential
# consequences resulting from its eventual inadequacies and bugs
# End users who are looking for a ready-to-use solution with commercial
# guarantees and support are strongly adviced to contract a Free Software
# Service Company
#
# This program is Free Software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 3
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#
##############################################################################
from slapos.recipe.librecipe import GenericBaseRecipe
import sys
class Recipe(GenericBaseRecipe):
"""
kvm instance configuration.
"""
def install(self):
config = dict(
vnc_ip=self.options['vnc-ip'],
vnc_port=self.options['vnc-port'],
boot_disk_path=self.options['boot-disk-path'],
disk_path=self.options['data-disk-path'],
disk_size=self.options['data-disk-size'],
disk_type=self.options['data-disk-type'],
mac_address=self.options['mac-address'],
smp_count=self.options['smp-count'],
ram_size=self.options['ram-size'],
socket_path=self.options['socket-path'],
pid_file_path=self.options['pid-path'],
python_path=sys.executable,
shell_path=self.options['shell-path'],
qemu_path=self.options['qemu-path'],
qemu_img_path=self.options['qemu-img-path'],
vnc_passwd=self.options['passwd']
)
# Runners
runner_path = self.createExecutable(
self.options['runner-path'],
self.substituteTemplate(self.getTemplateFilename('kvm_run.in'), config))
controller_path = self.createExecutable(
self.options['controller-path'],
self.substituteTemplate(self.getTemplateFilename('kvm_controller_run.in'),
config))
return [runner_path, controller_path]
#!%(python_path)s
# BEWARE: This file is operated by slapgrid
# BEWARE: It will be overwritten automatically
# Echo client program
import socket
import time
# Connect to KVM qmp socket
so = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
connected = False
while not connected:
try:
so.connect('%(socket_path)s')
except socket.error:
time.sleep(1)
else:
connected = True
data = so.recv(1024)
# Enable qmp
so.send('{ "execute": "qmp_capabilities" }')
data = so.recv(1024)
# Set VNC password
so.send('{ "execute": "change", ' \
'"arguments": { "device": "vnc", "target": "password", ' \
' "arg": "%(vnc_passwd)s" } }')
data = so.recv(1024)
# Finish
so.close()
#!%(python_path)s
# BEWARE: This file is operated by slapgrid
# BEWARE: It will be overwritten automatically
# Echo client program
import os
import socket
import subprocess
def getSocketStatus(host, port):
s = None
for res in socket.getaddrinfo(host, port,
socket.AF_UNSPEC, socket.SOCK_STREAM):
af, socktype, proto, canonname, sa = res
try:
s = socket.socket(af, socktype, proto)
except socket.error, msg:
s = None
continue
try:
s.connect(sa)
except socket.error, msg:
s.close()
s = None
continue
break
return s
# create disk if doesn't exist
disk_path = '%(disk_path)s'
if not os.path.exists(disk_path):
subprocess.Popen(['%(qemu_img_path)s', 'create' ,'-f', 'qcow2',
disk_path, '%(disk_size)sG'])
# Generate NAT rules
nat_rules = ",".join("hostfwd=tcp:%(vnc_ip)s:%%s-:%%s" %% (port, port) for port in [25, 80, 110, 143, 443, 465, 587, 993, 995, 7071])
kvm_argument_list = ['%(qemu_path)s',
'-enable-kvm', '-net', 'nic,macaddr=%(mac_address)s',
'-net', 'user,hostfwd=tcp:%(vnc_ip)s:2222-:22,%%s' %% nat_rules,
'-smp', '%(smp_count)s',
'-m', '%(ram_size)s',
'-drive', 'file=%(disk_path)s,if=%(disk_type)s',
#'-drive', 'file=%(boot_disk_path)s,if=%(disk_type)s',
'-vnc', '%(vnc_ip)s:1,ipv4,password',
'-boot', 'menu=on',
'-qmp', 'unix:%(socket_path)s,server',
'-pidfile', '%(pid_file_path)s',
]
os.execv('%(qemu_path)s', kvm_argument_list)
......@@ -83,6 +83,7 @@ port
Port used by Apache. Optional parameter, defaults to 4443.
plain_http_port
~~~~~~~~~~~~~~~
Port used by apache to serve plain http (only used to redirect to https).
Optional parameter, defaults to 8080.
......@@ -192,7 +193,12 @@ Notes
=====
It is not possible with slapos to listen to port <= 1024, because process are
not run as root. It is a good idea then to go on the node where the instance is
not run as root.
Solution 1 (IPv4 only)
----------------------
It is a good idea then to go on the node where the instance is
and set some iptables rules like (if using default ports)::
iptables -t nat -A PREROUTING -p tcp -d {public_ipv4} --dport 443 -j DNAT --to-destination {listening_ipv4}:4443
......@@ -200,3 +206,12 @@ and set some iptables rules like (if using default ports)::
Where {public ip} is the public IP of your server, or at least the LAN IP to where your NAT will forward to.
{listening ip} is the private ipv4 (like 10.0.34.123) that the instance is using and sending as connection parameter.
Solution 2 (IPv6 only)
----------------------
It is also possible to directly allow the service to listen on 80 and 443 ports using the following command:
setcap 'cap_net_bind_service=+ep' /opt/slapgrid/$APACHE_FRONTEND_SOFTWARE_RELEASE_MD5/parts/apache-2.2/bin/httpd
Then specify in the instance parameters "port" and "plain_http_port" to be 443 and 80, respectively.
#############################
#
# Deploy hello-world instance
#
#############################
[buildout]
parts =
directory
hello-world
publish-connection-parameter
# Define egg directories to be the one from Software Release
# (/opt/slapgrid/...)
# Always the same.
eggs-directory = ${buildout:eggs-directory}
develop-eggs-directory = ${buildout:develop-eggs-directory}
offline = true
[instance-parameter]
# Fetches parameters defined in SlapOS Master for this instance.
# Always the same.
recipe = slapos.cookbook:slapconfiguration
computer = $${slap_connection:computer_id}
partition = $${slap_connection:partition_id}
url = $${slap_connection:server_url}
key = $${slap_connection:key_file}
cert = $${slap_connection:cert_file}
# Define default parameter(s) that will be used later, in case user didn't
# specify it
# All parameters are available through the configuration.XX syntax.
# All possible parameters should have a default.
configuration.name = anonymous
# Create all needed directories, depending on your needs
[directory]
recipe = slapos.cookbook:mkdirectory
etc = $${buildout:directory}/etc
# Executables put here will be started but not monitored (for startup scripts)
script = $${:etc}/run/
# Executables put here will be started and monitored (for daemons)
service = $${:etc}/service
# Executables put here will be launched after buildout has completed to see
# if instance is running
promise = $${:etc}/promise/
# Create a simple shell script that will only output your name if you
# specified it as instance parameter.
# Usually, of course, we use more useful commands, like web servers.
[hello-world]
# This recipe will try to "exec" the command-line after separating parameters.
recipe = slapos.cookbook:wrapper
# Notice that there is only one $ at ${dash:location}, it is because it comes from the Software Release buildout profile.
command-line = ${dash:location}/bin/dash -c 'echo "Hello $${instance-parameter:configuration.name}!"; sleep 100000;'
# Put this shell script in the "etc/service" directory. Every executable of this
# repository will be started and monitored by supervisord
wrapper-path = $${directory:service}/hello-world
# Publish all the parameters needed for the user to connect to the instance.
# It can be anything: URL(s), password(s), or arbitrary parameters.
# Here we'll just echo back the entered name as instance parameter
[publish-connection-parameter]
recipe = slapos.cookbook:publish
name = Hello $${instance-parameter:configuration.name}!
[buildout]
extends =
# "slapos" stack describes basic things needed for 99.9% of SlapOS Software
# Releases
../../stack/slapos.cfg
# Extend here component profiles, like openssl, apache, mariadb, curl...
# Or/and extend a stack (lamp, tomcat) that does most of the work for you
# In this example we only need the dash binary to run a simple "hello world"
# shell script.
../../component/dash/buildout.cfg
parts =
# Call installation of slapos.cookbook egg defined in stack/slapos.cfg (needed
# in 99,9% of Slapos Software Releases)
slapos-cookbook
# Call creation of instance.cfg file that will be called for deployment of
# instance
template
# Download instance.cfg.in (buildout profile used to deployment of instance),
# replace all ${foo:bar} parameters by real values, and change $${foo:bar} to
# ${foo:bar}
[template]
recipe = slapos.recipe.template
url = ${:_profile_base_location_}/instance.cfg.in
output = ${buildout:directory}/instance.cfg
# MD5 checksum can be skipped for development, but must be filled for production
#md5sum =
mode = 0644
[buildout]
extends =
../../component/dash/buildout.cfg
../../component/dcron/buildout.cfg
../../component/gzip/buildout.cfg
../../component/logrotate/buildout.cfg
../../component/nginx/buildout.cfg
../../component/openssl/buildout.cfg
../../stack/slapos.cfg
parts =
slapos-cookbook
watermarkingadmin
eggs
instance-profile
develop =
${buildout:directory}/parts/watermarkingadmin
[watermarkingadmin]
recipe = hexagonit.recipe.download
url = http://easicloud-p.cdn.hexaglobe.net/api10.tar.gz
#md5sum =
[eggs]
recipe = zc.recipe.egg
eggs =
watermarkingadmin
slapos.toolbox
[watermarkadmin.ini.in]
recipe = slapos.recipe.download
url = ${:_profile_base_location_}/template/${:_buildout_section_name_}
md5sum = 2edc2acd102a465a0f21d8cd982ba4bf
download-only = true
#filename = template.in
mode = 0644
location = ${buildout:parts-directory}/${:_buildout_section_name_}
[nginx.conf.in]
recipe = slapos.recipe.download
url = ${:_profile_base_location_}/template/${:_buildout_section_name_}
md5sum = 7e41dfcb633ce52be42457ffd5b123d8
download-only = true
#filename = template.in
mode = 0644
location = ${buildout:parts-directory}/${:_buildout_section_name_}
[instance-profile]
recipe = slapos.recipe.template
url = ${:_profile_base_location_}/instance.cfg.in
output = ${buildout:directory}/instance.cfg
#md5sum = 650cd2527158734fd6ccd9ec374b5e69
mode = 0644
[watermarking-instance-profile]
recipe = slapos.recipe.template
url = ${:_profile_base_location_}/instance-watermarking.cfg.in
output = ${buildout:directory}/instance-watermarking.cfg
#md5sum = 76c88bfc59bc9c2d05fa13cc960349c7
mode = 0644
[edge-instance-profile]
recipe = slapos.recipe.template
url = ${:_profile_base_location_}/instance-edge.cfg.in
output = ${buildout:directory}/instance-edge.cfg
#md5sum = 650cd2527158734fd6ccd9ec374b5e69
mode = 0644
[buildout]
extends =
../../component/git/buildout.cfg
common.cfg
parts +=
slapos.cookbook-repository
check-recipe
develop +=
${:parts-directory}/slapos.cookbook-repository
[slapos.cookbook-repository]
recipe = slapos.recipe.build:gitclone
repository = http://git.erp5.org/repos/slapos.git
branch = hexaglobe-watermarking
git-executable = ${git:location}/bin/git
[check-recipe]
recipe = plone.recipe.command
stop-on-error = true
update-command = ${:command}
command =
grep parts ${buildout:develop-eggs-directory}/slapos.cookbook.egg-link
# This instance will request other instances of lamp-generic depending on a
# list of countries.
[buildout]
parts =
request-edge
publish-connection-parameter
eggs-directory = ${buildout:eggs-directory}
develop-eggs-directory = ${buildout:develop-eggs-directory}
offline = true
[request-edge]
<= slap-connection
recipe = slapos.cookbook:request.edge
# This magic parameter triggers several requests, one request per country.
name = watermark
country-list = $${slap-parameter:country-list}
software-url = $${slap-connection:software-release-url}
software-type = default
return = url admin-url admin-url-ipv6
[publish-connection-parameter]
recipe = slapos.cookbook:publishsection
section-list = request-edge
[buildout]
parts =
directory
nginx
watermarkadmin
logrotate
logrotate-entry-nginx
cron
cron-entry-logrotate
watermarkadmin-promise
publish-connection-parameter
# Define egg directories to be the one from Software Release
# (/opt/slapgrid/...)
eggs-directory = ${buildout:eggs-directory}
develop-eggs-directory = ${buildout:develop-eggs-directory}
offline = true
# Fetch parameters defined in SlapOS Master for this instance
[instance-parameter]
recipe = slapos.cookbook:slapconfiguration
computer = $${slap-connection:computer-id}
partition = $${slap-connection:partition-id}
url = $${slap-connection:server-url}
key = $${slap-connection:key-file}
cert = $${slap-connection:cert-file}
# Set default parameters
http-port = 8080
administration-port = 5000
# Create needed directories
[directory]
recipe = slapos.cookbook:mkdirectory
home = $${buildout:directory}
bin = $${:home}/bin
etc = $${:home}/etc
srv = $${:home}/srv
service = $${:etc}/service
promise = $${:etc}/promise
var = $${:home}/var
backup = $${:srv}/backup
log = $${:var}/log
run = $${:var}/run
nginx-configuration = $${:etc}/nginx
nginx-vhost-configuration = $${:nginx-configuration}/vhost
nginx-log = $${:home}/logs
nginx-cache = $${:var}/cache
nginx-temp-path = $${:srv}/nginx-proxy
cron-entries = $${:etc}/cron.d
crontabs = $${:etc}/crontabs
cronstamps = $${:etc}/cronstamps
logrotate-entries = $${:etc}/logrotate.d
logrotate-backup = $${:backup}/logrotate
# Deploy nginx
[nginx-configuration]
recipe = slapos.cookbook:configurationfile
configuration-template-path = ${nginx.conf.in:location}/nginx.conf.in
configuration-file-path = $${directory:nginx-configuration}/nginx.conf
vhost-configuration-directory-location = $${directory:nginx-vhost-configuration}
nginx-prefix = ${nginx-enable-sub:location}
nginx-temp-path = $${directory:nginx-temp-path}
pid-file = $${directory:run}/nginx.pid
home-directory = $${directory:home}
[nginx]
recipe = slapos.cookbook:wrapper
nginx-executable = $${:nginx-prefix}/sbin/nginx
nginx-prefix = ${nginx-enable-sub:location}
command-line = $${:nginx-executable} -c $${nginx-configuration:configuration-file-path} -p $${directory:home}
wrapper-path = $${directory:service}/nginx
# Deploy administration API server
[watermarkadmin-configuration]
recipe = slapos.cookbook:configurationfile
configuration-template-path = ${watermarkadmin.ini.in:location}/watermarkadmin.ini.in
configuration-file-path = $${directory:etc}/watermarkadmin.ini
flask-database-location = $${directory:srv}/flask.db
nginx-prefix = $${directory:home}
nginx-port = $${instance-parameter:http-port}
nginx-configuration-file-location = $${nginx-configuration:configuration-file-path}
nginx-executable-location = $${nginx:nginx-executable}
nginx-pidfile-location = $${nginx-configuration:pid-file}
nginx-vhost-configuration-directory-location = $${directory:nginx-vhost-configuration}
nginx-log-directory-location = $${directory:nginx-log}
nginx-cache-directory-location = $${directory:nginx-cache}
global-ip = $${instance-parameter:ipv6-random}
[watermarkadmin]
recipe = slapos.cookbook:wrapper
command-line =
${buildout:directory}/bin/api $${watermarkadmin-configuration:configuration-file-path}
wrapper-path = $${directory:service}/watermarkingadmin
# Deploy logrotate
[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 = $${directory:bin}/logrotate
conf = $${directory:etc}/logrotate.conf
logrotate-entries = $${directory:logrotate-entries}
backup = $${directory:logrotate-backup}
state-file = $${directory:srv}/logrotate.status
[logrotate-entry-nginx]
<= logrotate
recipe = slapos.cookbook:logrotate.d
name = nginx
log = $${watermarkadmin-configuration:nginx-log-directory-location}/*.log
frequency = daily
rotate-num = 30
post = ${buildout:bin-directory}/killpidfromfile $${nginx-configuration:pid-file} SIGUSR1
sharedscripts = true
notifempty = true
create = true
# Deploy cron and configure it
[cron-simplelogger]
recipe = slapos.cookbook:simplelogger
wrapper = $${directory:bin}/cron_simplelogger
log = $${directory:log}/crond.log
[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 = $${directory:service}/crond
[cron-entry-logrotate]
<= cron
recipe = slapos.cookbook:cron.d
name = logrotate
frequency = 0 0 * * *
command = $${logrotate:wrapper}
# Request frontend
[request-frontend]
<= slap-connection
recipe = slapos.cookbook:requestoptional
name = Frontend for $${slap-connection:computer-id} $${slap-connection:partition-id}
# XXX We have hardcoded SR URL here.
software-url = http://git.erp5.org/gitweb/slapos.git/blob_plain/HEAD:/software/apache-frontend/software.cfg
slave = true
config = url
config-url = http://[$${instance-parameter:ipv6-random}]:5000
return = site_url
# Check promises
[watermarkadmin-promise]
recipe = slapos.cookbook:check_port_listening
path = $${directory:promise}/watermarkadmin-promise
hostname = $${instance-parameter:ipv6-random}
port = $${instance-parameter:administration-port}
[watermarkadmin-promise-frontend]
recipe = slapos.cookbook:check_page_content
path = $${directory:promises}/watermarkadmin-frontend-promise
url = $${request-frontend:connection-site_url}
dash_path = ${dash:location}/bin/dash
curl_path = ${curl:location}/bin/curl
match = If you entered the URL manually please check your spelling and try again.
# Publish instance connection parameters
[publish-connection-parameter]
recipe = slapos.cookbook:publish
url = http://[$${instance-parameter:ipv6-random}]:$${instance-parameter:http-port}
# XXX-Cedric: hardcoded
admin-url-ipv6 = http://[$${instance-parameter:ipv6-random}]:5000
admin-url = $${request-frontend:connection-site_url}
[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 = ${watermarking-instance-profile:output}
watermarking = ${watermarking-instance-profile:output}
edge = ${edge-instance-profile:output}
daemon off;
worker_processes 1;
pid %(pid-file)s;
events {
worker_connections 1024;
}
http {
log_format up_log '$remote_addr - $remote_user [$time_local] $request '
'upstream_response_time $upstream_response_time '
'msec $msec request_time $request_time'
'cache_status $upstream_cache_status';
log_format sysl '"$time_local", "$http_referer", "$host", "$request", '
'"$status", "$http_user_agent", "$remote_addr", '
'"$bytes_sent", "$request_time"';
proxy_temp_path %(nginx-temp-path)s;
include %(nginx-prefix)s/conf/mime.types;
default_type application/octet-stream;
sendfile on;
keepalive_timeout 65;
include %(vhost-configuration-directory-location)s/*.conf;
}
[nginx]
vhosts = %(nginx-vhost-configuration-directory-location)s
log = %(nginx-log-directory-location)s
data = %(nginx-cache-directory-location)s
max_size = 1024m
inactive = 120m
port = %(nginx-port)s
pidfile = %(nginx-pidfile-location)s
nginx_bin = %(nginx-executable-location)s
conf = %(nginx-configuration-file-location)s
prefix = %(nginx-prefix)s
[flask]
DATABASE = %(flask-database-location)s
MAX_CONTENT_LENGTH = 4096
[api]
user = admin
pass = 276eeed9056ac2486f9c0237bb0be227
ip = %(global-ip)s
This Software Release represents a generic LAMP service.
The PHP application is given to the instance by parameter as URL of application archive.
XXX-Cedric: what about application configuration?
\ No newline at end of file
# Exactly the same as software.cfg, but fetch the slapos.cookbook and
# slapos.toolbox from git repository instead of fetching stable version,
# allowing to play with bleeding edge environment.
# You'll need to run buildout twice for this profile.
[buildout]
extends =
../../component/git/buildout.cfg
software.cfg
parts +=
# Development parts
slapos.cookbook-repository
slapos.core-repository
slapos.toolbox-repository
check-recipe
develop =
${:parts-directory}/slapos.cookbook-repository
${:parts-directory}/slapos.core-repository
${:parts-directory}/slapos.toolbox-repository
[slapos.toolbox-repository]
recipe = slapos.recipe.build:gitclone
repository = http://git.erp5.org/repos/slapos.toolbox.git
branch = master
git-executable = ${git:location}/bin/git
[slapos.cookbook-repository]
recipe = slapos.recipe.build:gitclone
repository = http://git.erp5.org/repos/slapos.git
branch = lamp-edge
git-executable = ${git:location}/bin/git
[slapos.core-repository]
recipe = slapos.recipe.build:gitclone
repository = http://git.erp5.org/repos/slapos.core.git
branch = master
git-executable = ${git:location}/bin/git
[check-recipe]
recipe = plone.recipe.command
stop-on-error = true
update-command = ${:command}
command =
grep parts ${buildout:develop-eggs-directory}/slapos.cookbook.egg-link &&
grep parts ${buildout:develop-eggs-directory}/slapos.core.egg-link &&
grep parts ${buildout:develop-eggs-directory}/slapos.toolbox.egg-link
[versions]
slapos.cookbook =
slapos.toolbox =
slapos.core =
[buildout]
parts =
logrotate
logrotate-entry-apache
cron
cron-entry-logrotate
promise
frontend-promise
publish-connection-informations
eggs-directory = ${buildout:eggs-directory}
develop-eggs-directory = ${buildout:develop-eggs-directory}
newest = false
#----------------
#--
#-- Creation of all needed directories.
[rootdirectory]
recipe = slapos.cookbook:mkdirectory
etc = $${buildout:directory}/etc
var = $${buildout:directory}/var
srv = $${buildout:directory}/srv
bin = $${buildout:directory}/bin
tmp = $${buildout:directory}/tmp
[basedirectory]
recipe = slapos.cookbook:mkdirectory
log = $${rootdirectory:var}/log
services = $${rootdirectory:etc}/service
run = $${rootdirectory:var}/run
backup = $${rootdirectory:srv}/backup
promises = $${rootdirectory:etc}/promise
[directory]
recipe = slapos.cookbook:mkdirectory
cron-entries = $${rootdirectory:etc}/cron.d
crontabs = $${rootdirectory:etc}/crontabs
cronstamps = $${rootdirectory:etc}/cronstamps
ca-dir = $${rootdirectory:srv}/ssl
httpd-log = $${basedirectory:log}/apache
php-ini-dir = $${rootdirectory:etc}/php
tmp-php = $${rootdirectory:tmp}/php
logrotate-entries = $${rootdirectory:etc}/logrotate.d
logrotate-backup = $${basedirectory:backup}/logrotate
report = $${rootdirectory:etc}/report
stunnel-conf = $${rootdirectory:etc}/stunnel
xml-report = $${rootdirectory:var}/xml_report
www = $${rootdirectory:srv}/www/
[cadirectory]
recipe = slapos.cookbook:mkdirectory
requests = $${directory:ca-dir}/requests
private = $${directory:ca-dir}/private
certs = $${directory:ca-dir}/certs
newcerts = $${directory:ca-dir}/newcerts
crl = $${directory:ca-dir}/crl
#----------------
#--
#-- Deploy cron.
[cron]
recipe = slapos.cookbook:cron
dcrond-binary = ${dcron:location}/sbin/crond
cron-entries = $${directory:cron-entries}
crontabs = $${directory:crontabs}
cronstamps = $${directory:cronstamps}
catcher = $${cron-simplelogger:wrapper}
binary = $${basedirectory:services}/crond
[cron-simplelogger]
recipe = slapos.cookbook:simplelogger
wrapper = $${rootdirectory:bin}/cron_simplelogger
log = $${basedirectory:log}/crond.log
#----------------
#--
#-- Deploy logrotate.
[cron-entry-logrotate]
<= cron
recipe = slapos.cookbook:cron.d
name = logrotate
frequency = 0 0 * * *
command = $${logrotate:wrapper}
[logrotate]
recipe = slapos.cookbook:logrotate
# Binaries
logrotate-binary = ${logrotate:location}/usr/sbin/logrotate
gzip-binary = ${gzip:location}/bin/gzip
gunzip-binary = ${gzip:location}/bin/gunzip
# Directories
wrapper = $${rootdirectory:bin}/logrotate
conf = $${rootdirectory:etc}/logrotate.conf
logrotate-entries = $${directory:logrotate-entries}
backup = $${directory:logrotate-backup}
state-file = $${rootdirectory:srv}/logrotate.status
#----------------
#--
#-- Deploy Apache + PHP application.
[apache-php]
recipe = slapos.cookbook:lamp.generic
url = $${slap-parameter:application-location}
strip-top-level-dir = true
# md5sum =
# XXX-Cedric: add some "template" configuration
htdocs = $${directory:www}
pid-file = $${basedirectory:run}/apache.pid
lock-file = $${basedirectory:run}/apache.lock
ip = $${slap-network-information:global-ipv6}
port = 8080
error-log = $${directory:httpd-log}/error.log
access-log = $${directory:httpd-log}/access.log
php-ini-dir = $${directory:php-ini-dir}
tmp-dir = $${directory:tmp-php}
httpd-conf = $${rootdirectory:etc}/apache.conf
wrapper = $${basedirectory:services}/apache
httpd-binary = ${apache:location}/bin/httpd
[logrotate-entry-apache]
<= logrotate
recipe = slapos.cookbook:logrotate.d
name = apache
log = $${apache-php:error-log} $${apache-php:access-log}
frequency = daily
rotate-num = 30
sharedscripts = true
notifempty = true
create = true
#----------------
#--
#-- Request frontend.
[request-frontend]
<= slap-connection
recipe = slapos.cookbook:requestoptional
name = Frontend
# XXX We have hardcoded SR URL here.
software-url = http://git.erp5.org/gitweb/slapos.git/blob_plain/HEAD:/software/apache-frontend/software.cfg
slave = true
config = url custom_domain
config-url = http://[$${apache-php:ip}]:$${apache-php:port}/
return = site_url
config-custom_domain = $${slap-parameter:domain}
#----------------
#--
#-- Publish instance parameters.
[publish-connection-informations]
recipe = slapos.cookbook:publish
backend-url = http://[$${apache-php:ip}]:$${apache-php:port}/
url = $${request-frontend:connection-site_url}
#----------------
#--
#-- Deploy promises scripts.
[promise]
recipe = slapos.cookbook:check_port_listening
path = $${basedirectory:promises}/apache
hostname = $${apache-php:ip}
port = $${apache-php:port}
[frontend-promise]
recipe = slapos.cookbook:check_url_available
path = $${basedirectory:promises}/frontend
url = $${request-frontend:connection-site_url}
dash_path = ${dash:location}/bin/dash
curl_path = ${curl:location}/bin/curl
[slap-parameter]
# Default value if no domain is specified
domain =
# Default value if no ssh parameter is specified
logbox-ip =
logbox-port =
logbox-user =
logbox-passwd =
# This instance will request other instances of lamp-generic depending on a
# list of countries.
[buildout]
parts =
request-edge
publish-connection-parameter
eggs-directory = ${buildout:eggs-directory}
develop-eggs-directory = ${buildout:develop-eggs-directory}
offline = true
[request-edge]
<= slap-connection
recipe = slapos.cookbook:request.edge
# This magic parameter triggers several requests, one request per country.
name = lamp
return = url backend-url
country-list = $${slap-parameter:country-list}
software-url = $${slap-connection:software-release-url}
software-type = default
config = application-location
config-application-location = $${slap-parameter:application-location}
return = backend-url
[publish-connection-parameter]
recipe = slapos.cookbook:publishsection
section-list = request-edge
[buildout]
parts =
switch_softwaretype
eggs-directory = ${buildout:eggs-directory}
develop-eggs-directory = ${buildout:develop-eggs-directory}
offline = true
[switch_softwaretype]
recipe = slapos.cookbook:softwaretype
default = ${instance-apache-php:output}
edge = ${instance-edge:output}
[buildout]
extends =
../../stack/lamp/buildout.cfg
parts +=
instance-edge
# XXX: switch to ngnix
[instance]
url = ${:_profile_base_location_}/instance.cfg.in
md5sum = 26ac6629a83869140189a85e581e822f
[instance-apache-php]
url = ${:_profile_base_location_}/instance-apache-php.cfg.in
md5sum = fdc849c9f49b9d2fb043bf229d24076b
[instance-edge]
recipe = slapos.recipe.template
url = ${:_profile_base_location_}/instance-edge.cfg.in
output = ${buildout:directory}/instance-edge.cfg
#md5sum = 6b7a6caf44e3a94bed7f89c04003a171
mode = 0644
**************************************************************************
This howto is for private networks only, in case the customer is migrating
from a previously installed Maarch.
**************************************************************************
Hot to install Maarch with SlapOS
=================================
1) Require the right Software Release ({insert SR number/URL here})
2) Request an instance of that Software Release.
Since we need to provide a parameter (type=resilient) that is not available through
the SlapOS web site, it must be done at command line.
If you are migrating data from an existing Maarch installation:
2.1) copy a 'data only' SQL dump - no schema - to the server that contains
the instance. Let's say it is /tmp/data.sql
The file must be readable by world, because we don't know yet the number
of the partition that will need to access it.
Remember to remove it afterwards.
The command line to request a partition is:
slapos request /etc/opt/slapos/slapos-client.cfg maarch-instance-name \
http://git.erp5.org/gitweb/slapos.git/blob_plain/refs/tags/slapos-0.159:/software/maarch/software.cfg \
--type=resilient --configuration maarch-sql-data-file=/tmp/data.sql
If you are not migrating data, don't provide the maarch-sql-data-file parameter.
A minimal working database will be created.
3) deploy the instance.
You should be able to connect to both Maarch (user 'superadmin')
and Postgres (user 'postgres') with the (very long)
passport reported in the connection parameters of the partition 'apache0'.
NB: even if you copied the SQL data from a previous installation, the 'superadmin' password
is set from the published connection parameter. If there are other admin accounts,
their password is not changed.
4) Again, only if you are migrating:
connect to the server, inside the partition of type apache-export
copy the docservers data inside the folders:
srv/docservers/ai
srv/docservers/manual
srv/docservers/OAIS_main
srv/docservers/OAIS_safe
srv/docservers/offline
srv/docservers/templates
also, change the owner and group of the copied files to the user that owns the partition.
......@@ -27,7 +27,7 @@ extensions = buildout-versions
[slapos.cookbook-repository]
recipe = slapos.recipe.build:gitclone
repository = http://git.erp5.org/repos/slapos.git
revision = 7dce435eca6fe2eeff60c865d41ee40db59257fa
revision = 7285bc913e6ea46a36ad2a887af6e9fab010ca74
git-executable = ${git:location}/bin/git
......
[buildout]
# XXX-Cedric: cahnge name to reverse-proxy-nginx
extends =
../../component/dcron/buildout.cfg
../../component/gzip/buildout.cfg
../../component/logrotate/buildout.cfg
../../component/nginx/buildout.cfg
../../component/openssl/buildout.cfg
../../stack/slapos.cfg
parts =
slapos-cookbook
eggs
instance-profile
[eggs]
recipe = zc.recipe.egg
eggs =
slapos.toolbox
[instance-profile]
recipe = slapos.recipe.template
url = ${:_profile_base_location_}/instance.cfg.in
output = ${buildout:directory}/instance.cfg
#md5sum = 650cd2527158734fd6ccd9ec374b5e69
mode = 0644
[buildout]
extends =
../../component/git/buildout.cfg
common.cfg
parts +=
slapos.cookbook-repository
check-recipe
develop =
${:parts-directory}/slapos.cookbook-repository
[slapos.cookbook-repository]
recipe = slapos.recipe.build:gitclone
repository = http://git.erp5.org/repos/slapos.git
branch = slaprunner
git-executable = ${git:location}/bin/git
[check-recipe]
recipe = plone.recipe.command
stop-on-error = true
update-command = ${:command}
command =
grep parts ${buildout:develop-eggs-directory}/slapos.cookbook.egg-link
[buildout]
parts =
directory
reverse-proxy
certificate-authority
ca-nginx
logrotate
logrotate-entry-nginx
cron
cron-entry-logrotate
smtp-port-promise
publish-connection-parameter
# Define egg directories to be the one from Software Release
# (/opt/slapgrid/...)
eggs-directory = ${buildout:eggs-directory}
develop-eggs-directory = ${buildout:develop-eggs-directory}
offline = true
# Fetch parameters defined in SlapOS Master for this instance
[instance-parameter]
recipe = slapos.cookbook:slapconfiguration
computer = $${slap-connection:computer-id}
partition = $${slap-connection:partition-id}
url = $${slap-connection:server-url}
key = $${slap-connection:key-file}
cert = $${slap-connection:cert-file}
# Set default parameters
configuration.slave-instance-list =
configuration.domain = un-hardcode-me
#configuration.http-port = 80
#configuration.https-port = 443
configuration.smtp-port = 25
configuration.public-ipv4 =
# Create needed directories
[directory]
recipe = slapos.cookbook:mkdirectory
home = $${buildout:directory}
bin = $${:home}/bin
etc = $${:home}/etc
srv = $${:home}/srv
var = $${:home}/var
service = $${:etc}/service
promise = $${:etc}/promise
backup = $${:srv}/backup
log = $${:var}/log
run = $${:var}/run
ca-dir = $${:srv}/ssl
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
nginx-configuration = $${:etc}/nginx
nginx-ssl = $${:ca-dir}/nginx
nginx-log = $${:home}/logs
nginx-htdocs = $${:srv}/www
cron-entries = $${:etc}/cron.d
crontabs = $${:etc}/crontabs
cronstamps = $${:etc}/cronstamps
logrotate-entries = $${:etc}/logrotate.d
logrotate-backup = $${:backup}/logrotate
# Deploy nginx and publish connection parameters inside of the recipe
[reverse-proxy]
recipe = slapos.cookbook:reverseproxy.nginx
nginx-executable = ${nginx-unstable:location}/sbin/nginx
wrapper = $${directory:bin}/nginx
configuration-file = $${directory:nginx-configuration}/nginx.conf
ipv6 = $${instance-parameter:ipv6-random}
ipv4 = $${instance-parameter:ipv4-random}
slave-instance-list = $${instance-parameter:slave-instance-list}
#http-port = $${instance-parameter:http-port}
#https-port = $${instance-parameter:https-port}
smtp-port = $${instance-parameter:configuration.smtp-port}
domain = $${instance-parameter:configuration.domain}
access-log = $${directory:nginx-log}/access.log
error-log = $${directory:nginx-log}/error.log
key-file = $${directory:nginx-configuration}/nginx.key
cert-file = $${directory:nginx-configuration}/nginx.crt
pid-file = $${directory:run}/nginx
htdocs = $${directory:nginx-htdocs}
home-directory = $${directory:home}
# Set the public IPs (if possible) as slave connection parameter so that user knows what IP
# to bind to its domain name
public-ipv4 = $${instance-parameter:configuration.public-ipv4}
# Create and handle certificate related stuffs, including encapsulating run of nginx executable
[certificate-authority]
recipe = slapos.cookbook:certificate_authority
openssl-binary = ${openssl:location}/bin/openssl
ca-dir = $${directory:ca-dir}
requests-directory = $${directory:ca-requests}
wrapper = $${directory:service}/ca
ca-private = $${directory:ca-private}
ca-certs = $${directory:ca-certs}
ca-newcerts = $${directory:ca-newcerts}
ca-crl = $${directory:ca-crl}
[ca-nginx]
<= certificate-authority
recipe = slapos.cookbook:certificate_authority.request
executable = $${reverse-proxy:wrapper}
wrapper = $${directory:service}/nginx
key-file = $${reverse-proxy:key-file}
cert-file = $${reverse-proxy:cert-file}
# Deploy logrotate
[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 = $${directory:bin}/logrotate
conf = $${directory:etc}/logrotate.conf
logrotate-entries = $${directory:logrotate-entries}
backup = $${directory:logrotate-backup}
state-file = $${directory:srv}/logrotate.status
[logrotate-entry-nginx]
<= logrotate
recipe = slapos.cookbook:logrotate.d
name = nginx
log = $${reverse-proxy:access-log} $${reverse-proxy:error-log}
frequency = daily
rotate-num = 30
post = ${buildout:bin-directory}/killpidfromfile $${reverse-proxy:pid-file} SIGUSR1
sharedscripts = true
notifempty = true
create = true
# Deploy cron and configure it
[cron-simplelogger]
recipe = slapos.cookbook:simplelogger
wrapper = $${directory:bin}/cron_simplelogger
log = $${directory:log}/crond.log
[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 = $${directory:service}/crond
[cron-entry-logrotate]
<= cron
recipe = slapos.cookbook:cron.d
name = logrotate
frequency = 0 0 * * *
command = $${logrotate:wrapper}
# Check promises
[smtp-port-promise]
recipe = slapos.cookbook:check_port_listening
path = $${directory:promise}/smtp-port-promise
hostname = $${instance-parameter:ipv6-random}
port = $${instance-parameter:configuration.smtp-port}
# Publish instance connection parameters
# Note: Parameters of slaves are published in the reverse-proxy recipe
[publish-connection-parameter]
recipe = slapos.cookbook:publish
ipv4 = $${instance-parameter:ipv4-random}
ipv6 = $${instance-parameter:ipv6-random}
......@@ -61,26 +61,26 @@ slapos.core = 0.34
slapos.libnetworkcache = 0.13.3
slapos.recipe.build = 0.11.5
slapos.recipe.template = 2.4.2
slapos.toolbox = 0.33.1
slapos.toolbox = 0.34.0
smmap = 0.8.2
xml-marshaller = 0.9.7
z3c.recipe.scripts = 1.0.1
# Required by:
# slapos.core==0.34
# slapos.toolbox==0.33.1
# slapos.toolbox==0.34.0
Flask = 0.9
# Required by:
# slapos.toolbox==0.33.1
# slapos.toolbox==0.34.0
GitPython = 0.3.2.RC1
# Required by:
# slapos.toolbox==0.33.1
# slapos.toolbox==0.34.0
atomize = 0.1.1
# Required by:
# slapos.toolbox==0.33.1
# slapos.toolbox==0.34.0
feedparser = 5.1.3
# Required by:
......@@ -92,11 +92,11 @@ hexagonit.recipe.download = 1.6nxd002
netifaces = 0.8
# Required by:
# slapos.toolbox==0.33.1
# slapos.toolbox==0.34.0
paramiko = 1.9.0
# Required by:
# slapos.toolbox==0.33.1
# slapos.toolbox==0.34.0
psutil = 0.6.1
# Required by:
......@@ -108,7 +108,7 @@ pyflakes = 0.5.0
# slapos.cookbook==0.71.1
# slapos.core==0.34
# slapos.libnetworkcache==0.13.3
# slapos.toolbox==0.33.1
# slapos.toolbox==0.34.0
# supervisor==3.0b1
# zc.buildout==1.6.0-dev-SlapOS-010
# zope.interface==4.0.3
......
[buildout]
# Run a SQL script to populate DB at first run
[tt-rss-init]
recipe = slapos.cookbook:apachephpconfigure
table_name = db.ttrss_users
#constraint = `pn_id`>0
lampconfigure = ${buildout:bin-directory}/lampconfigure
htdocs = $${apache-php:htdocs}
mysql-username = $${apache-php:mysql-username}
mysql-password = $${apache-php:mysql-password}
mysql-database = $${apache-php:mysql-database}
mysql-host = $${apache-php:mysql-host}
mysql-port = $${apache-php:mysql-port}
configureinstall-location = $${basedirectory:scripts}/configureInstall
sql-script = ${sql-script:location}/${sql-script:filename}
\ No newline at end of file
SET NAMES utf8;
SET CHARACTER SET utf8;
begin;
create table ttrss_users (id integer primary key not null auto_increment,
login varchar(120) not null unique,
pwd_hash varchar(250) not null,
last_login datetime default null,
access_level integer not null default 0,
theme_id integer default null,
email varchar(250) not null default '',
full_name varchar(250) not null default '',
email_digest bool not null default false,
last_digest_sent datetime default null,
salt varchar(250) not null default '',
created datetime default null,
twitter_oauth longtext default null,
otp_enabled boolean not null default false,
index (theme_id)) ENGINE=InnoDB DEFAULT CHARSET=UTF8;
insert into ttrss_users (login,pwd_hash,access_level) values ('admin',
'SHA1:5baa61e4c9b93f3f0682250b6cf8331b7ee68fd8', 10);
create table ttrss_feed_categories(id integer not null primary key auto_increment,
owner_uid integer not null,
title varchar(200) not null,
collapsed bool not null default false,
order_id integer not null default 0,
parent_cat integer,
index(parent_cat),
foreign key (parent_cat) references ttrss_feed_categories(id) ON DELETE SET NULL,
index(owner_uid),
foreign key (owner_uid) references ttrss_users(id) ON DELETE CASCADE) ENGINE=InnoDB DEFAULT CHARSET=UTF8;
create table ttrss_archived_feeds (id integer not null primary key,
owner_uid integer not null,
title varchar(200) not null,
feed_url text not null,
site_url varchar(250) not null default '',
index(owner_uid),
foreign key (owner_uid) references ttrss_users(id) ON DELETE CASCADE) ENGINE=InnoDB DEFAULT CHARSET=UTF8;
create table ttrss_counters_cache (
feed_id integer not null,
owner_uid integer not null,
value integer not null default 0,
updated datetime not null,
foreign key (owner_uid) references ttrss_users(id) ON DELETE CASCADE
);
create index ttrss_counters_cache_feed_id_idx on ttrss_counters_cache(feed_id);
create index ttrss_counters_cache_owner_uid_idx on ttrss_counters_cache(owner_uid);
create index ttrss_counters_cache_value_idx on ttrss_counters_cache(value);
create table ttrss_cat_counters_cache (
feed_id integer not null,
owner_uid integer not null,
value integer not null default 0,
updated datetime not null,
foreign key (owner_uid) references ttrss_users(id) ON DELETE CASCADE
);
create index ttrss_cat_counters_cache_owner_uid_idx on ttrss_cat_counters_cache(owner_uid);
create table ttrss_feeds (id integer not null auto_increment primary key,
owner_uid integer not null,
title varchar(200) not null,
cat_id integer default null,
feed_url text not null,
icon_url varchar(250) not null default '',
update_interval integer not null default 0,
purge_interval integer not null default 0,
last_updated datetime default 0,
last_error varchar(250) not null default '',
site_url varchar(250) not null default '',
auth_login varchar(250) not null default '',
auth_pass varchar(250) not null default '',
parent_feed integer default null,
private bool not null default false,
rtl_content bool not null default false,
hidden bool not null default false,
include_in_digest boolean not null default true,
cache_images boolean not null default false,
hide_images boolean not null default false,
cache_content boolean not null default false,
auth_pass_encrypted boolean not null default false,
last_viewed datetime default null,
last_update_started datetime default null,
always_display_enclosures boolean not null default false,
update_method integer not null default 0,
order_id integer not null default 0,
mark_unread_on_update boolean not null default false,
update_on_checksum_change boolean not null default false,
strip_images boolean not null default false,
pubsub_state integer not null default 0,
favicon_last_checked datetime default null,
index(owner_uid),
foreign key (owner_uid) references ttrss_users(id) ON DELETE CASCADE,
index(cat_id),
foreign key (cat_id) references ttrss_feed_categories(id) ON DELETE SET NULL,
index(parent_feed),
foreign key (parent_feed) references ttrss_feeds(id) ON DELETE SET NULL) ENGINE=InnoDB DEFAULT CHARSET=UTF8;
create index ttrss_feeds_owner_uid_index on ttrss_feeds(owner_uid);
create index ttrss_feeds_cat_id_idx on ttrss_feeds(cat_id);
insert into ttrss_feeds (owner_uid, title, feed_url) values
(1, 'Tiny Tiny RSS: New Releases', 'http://tt-rss.org/releases.rss');
insert into ttrss_feeds (owner_uid, title, feed_url) values
(1, 'Tiny Tiny RSS: Forum', 'http://tt-rss.org/forum/rss.php');
create table ttrss_entries (id integer not null primary key auto_increment,
title text not null,
guid varchar(255) not null unique,
link text not null,
updated datetime not null,
content longtext not null,
content_hash varchar(250) not null,
cached_content longtext,
no_orig_date bool not null default 0,
date_entered datetime not null,
date_updated datetime not null,
num_comments integer not null default 0,
plugin_data longtext,
comments varchar(250) not null default '',
author varchar(250) not null default '') ENGINE=InnoDB DEFAULT CHARSET=UTF8;
create index ttrss_entries_date_entered_index on ttrss_entries(date_entered);
create index ttrss_entries_guid_index on ttrss_entries(guid);
create index ttrss_entries_updated_idx on ttrss_entries(updated);
create table ttrss_user_entries (
int_id integer not null primary key auto_increment,
ref_id integer not null,
uuid varchar(200) not null,
feed_id int,
orig_feed_id int,
owner_uid integer not null,
marked bool not null default 0,
published bool not null default 0,
tag_cache text not null,
label_cache text not null,
last_read datetime,
score int not null default 0,
note longtext,
last_marked datetime,
last_published datetime,
unread bool not null default 1,
index (ref_id),
foreign key (ref_id) references ttrss_entries(id) ON DELETE CASCADE,
index (feed_id),
foreign key (feed_id) references ttrss_feeds(id) ON DELETE CASCADE,
index (orig_feed_id),
foreign key (orig_feed_id) references ttrss_archived_feeds(id) ON DELETE SET NULL,
index (owner_uid),
foreign key (owner_uid) references ttrss_users(id) ON DELETE CASCADE) ENGINE=InnoDB DEFAULT CHARSET=UTF8;
create index ttrss_user_entries_owner_uid_index on ttrss_user_entries(owner_uid);
create index ttrss_user_entries_ref_id_index on ttrss_user_entries(ref_id);
create index ttrss_user_entries_feed_id on ttrss_user_entries(feed_id);
create index ttrss_user_entries_unread_idx on ttrss_user_entries(unread);
create table ttrss_entry_comments (id integer not null primary key,
ref_id integer not null,
owner_uid integer not null,
private bool not null default 0,
date_entered datetime not null,
index (ref_id),
foreign key (ref_id) references ttrss_entries(id) ON DELETE CASCADE,
index (owner_uid),
foreign key (owner_uid) references ttrss_users(id) ON DELETE CASCADE) ENGINE=InnoDB DEFAULT CHARSET=UTF8;
create table ttrss_filter_types (id integer primary key,
name varchar(120) unique not null,
description varchar(250) not null unique) ENGINE=InnoDB DEFAULT CHARSET=UTF8;
insert into ttrss_filter_types (id,name,description) values (1, 'title', 'Title');
insert into ttrss_filter_types (id,name,description) values (2, 'content', 'Content');
insert into ttrss_filter_types (id,name,description) values (3, 'both',
'Title or Content');
insert into ttrss_filter_types (id,name,description) values (4, 'link',
'Link');
insert into ttrss_filter_types (id,name,description) values (5, 'date',
'Article Date');
insert into ttrss_filter_types (id,name,description) values (6, 'author', 'Author');
insert into ttrss_filter_types (id,name,description) values (7, 'tag', 'Article Tags');
create table ttrss_filter_actions (id integer not null primary key,
name varchar(120) unique not null,
description varchar(250) not null unique) ENGINE=InnoDB DEFAULT CHARSET=UTF8;
insert into ttrss_filter_actions (id,name,description) values (1, 'filter',
'Delete article');
insert into ttrss_filter_actions (id,name,description) values (2, 'catchup',
'Mark as read');
insert into ttrss_filter_actions (id,name,description) values (3, 'mark',
'Set starred');
insert into ttrss_filter_actions (id,name,description) values (4, 'tag',
'Assign tags');
insert into ttrss_filter_actions (id,name,description) values (5, 'publish',
'Publish article');
insert into ttrss_filter_actions (id,name,description) values (6, 'score',
'Modify score');
insert into ttrss_filter_actions (id,name,description) values (7, 'label',
'Assign label');
create table ttrss_filters (id integer not null primary key auto_increment,
owner_uid integer not null,
feed_id integer default null,
filter_type integer not null,
reg_exp varchar(250) not null,
filter_param varchar(250) not null default '',
inverse bool not null default false,
enabled bool not null default true,
cat_filter bool not null default false,
cat_id integer default null,
action_id integer not null default 1,
action_param varchar(250) not null default '',
index (filter_type),
foreign key (filter_type) references ttrss_filter_types(id) ON DELETE CASCADE,
index (owner_uid),
foreign key (owner_uid) references ttrss_users(id) ON DELETE CASCADE,
index (feed_id),
foreign key (feed_id) references ttrss_feeds(id) ON DELETE CASCADE,
index (cat_id),
foreign key (cat_id) references ttrss_feed_categories(id) ON DELETE CASCADE,
index (action_id),
foreign key (action_id) references ttrss_filter_actions(id) ON DELETE CASCADE) ENGINE=InnoDB DEFAULT CHARSET=UTF8;
create table ttrss_filters2(id integer primary key auto_increment,
owner_uid integer not null,
match_any_rule boolean not null default false,
enabled boolean not null default true,
index(owner_uid),
foreign key (owner_uid) references ttrss_users(id) ON DELETE CASCADE) ENGINE=InnoDB DEFAULT CHARSET=UTF8;
create table ttrss_filters2_rules(id integer primary key auto_increment,
filter_id integer not null references ttrss_filters2(id) on delete cascade,
reg_exp varchar(250) not null,
filter_type integer not null,
feed_id integer default null,
cat_id integer default null,
cat_filter boolean not null default false,
index (filter_id),
foreign key (filter_id) references ttrss_filters2(id) on delete cascade,
index (filter_type),
foreign key (filter_type) references ttrss_filter_types(id) ON DELETE CASCADE,
index (feed_id),
foreign key (feed_id) references ttrss_feeds(id) ON DELETE CASCADE,
index (cat_id),
foreign key (cat_id) references ttrss_feed_categories(id) ON DELETE CASCADE) ENGINE=InnoDB DEFAULT CHARSET=UTF8;
create table ttrss_filters2_actions(id integer primary key auto_increment,
filter_id integer not null,
action_id integer not null default 1 references ttrss_filter_actions(id) on delete cascade,
action_param varchar(250) not null default '',
index (filter_id),
foreign key (filter_id) references ttrss_filters2(id) on delete cascade,
index (action_id),
foreign key (action_id) references ttrss_filter_actions(id) ON DELETE CASCADE) ENGINE=InnoDB DEFAULT CHARSET=UTF8;
create table ttrss_tags (id integer primary key auto_increment,
owner_uid integer not null,
tag_name varchar(250) not null,
post_int_id integer not null,
index (post_int_id),
foreign key (post_int_id) references ttrss_user_entries(int_id) ON DELETE CASCADE,
index (owner_uid),
foreign key (owner_uid) references ttrss_users(id) ON DELETE CASCADE) ENGINE=InnoDB DEFAULT CHARSET=UTF8;
create table ttrss_version (schema_version int not null) ENGINE=InnoDB DEFAULT CHARSET=UTF8;
insert into ttrss_version values (106);
create table ttrss_enclosures (id integer primary key auto_increment,
content_url text not null,
content_type varchar(250) not null,
post_id integer not null,
title text not null,
duration text not null,
index (post_id),
foreign key (post_id) references ttrss_entries(id) ON DELETE cascade) ENGINE=InnoDB DEFAULT CHARSET=UTF8;
create index ttrss_enclosures_post_id_idx on ttrss_enclosures(post_id);
create table ttrss_settings_profiles(id integer primary key auto_increment,
title varchar(250) not null,
owner_uid integer not null,
index (owner_uid),
foreign key (owner_uid) references ttrss_users(id) ON DELETE CASCADE) ENGINE=InnoDB DEFAULT CHARSET=UTF8;
create table ttrss_prefs_types (id integer not null primary key,
type_name varchar(100) not null) ENGINE=InnoDB DEFAULT CHARSET=UTF8;
insert into ttrss_prefs_types (id, type_name) values (1, 'bool');
insert into ttrss_prefs_types (id, type_name) values (2, 'string');
insert into ttrss_prefs_types (id, type_name) values (3, 'integer');
create table ttrss_prefs_sections (id integer not null primary key,
order_id integer not null,
section_name varchar(100) not null) ENGINE=InnoDB DEFAULT CHARSET=UTF8;
insert into ttrss_prefs_sections (id, section_name, order_id) values (1, 'General', 0);
insert into ttrss_prefs_sections (id, section_name, order_id) values (2, 'Interface', 1);
insert into ttrss_prefs_sections (id, section_name, order_id) values (3, 'Advanced', 3);
insert into ttrss_prefs_sections (id, section_name, order_id) values (4, 'Digest', 2);
create table ttrss_prefs (pref_name varchar(250) not null primary key,
type_id integer not null,
section_id integer not null default 1,
short_desc text not null,
help_text varchar(250) not null default '',
access_level integer not null default 0,
def_value text not null,
index(type_id),
foreign key (type_id) references ttrss_prefs_types(id),
index(section_id),
foreign key (section_id) references ttrss_prefs_sections(id)) ENGINE=InnoDB DEFAULT CHARSET=UTF8;
create index ttrss_prefs_pref_name_idx on ttrss_prefs(pref_name);
insert into ttrss_prefs (pref_name,type_id,def_value,short_desc,section_id) values('PURGE_OLD_DAYS', 3, '60', 'Purge articles after this number of days (0 - disables)',1);
insert into ttrss_prefs (pref_name,type_id,def_value,short_desc,section_id) values('DEFAULT_UPDATE_INTERVAL', 3, '30', 'Default interval between feed updates',1);
insert into ttrss_prefs (pref_name,type_id,def_value,short_desc,section_id) values('DEFAULT_ARTICLE_LIMIT', 3, '30', 'Amount of articles to display at once',2);
insert into ttrss_prefs (pref_name,type_id,def_value,short_desc,section_id,help_text) values('ALLOW_DUPLICATE_POSTS', 1, 'true', 'Allow duplicate posts',1, 'This option is useful when you are reading several planet-type aggregators with partially colliding userbase. When disabled, it forces same posts from different feeds to appear only once.');
insert into ttrss_prefs (pref_name,type_id,def_value,short_desc,section_id) values('ENABLE_FEED_CATS', 1, 'true', 'Enable feed categories',2);
insert into ttrss_prefs (pref_name,type_id,def_value,short_desc,section_id) values('SHOW_CONTENT_PREVIEW', 1, 'true', 'Show content preview in headlines list',2);
insert into ttrss_prefs (pref_name,type_id,def_value,short_desc,section_id) values('SHORT_DATE_FORMAT', 2, 'M d, G:i', 'Short date format',3);
insert into ttrss_prefs (pref_name,type_id,def_value,short_desc,section_id) values('LONG_DATE_FORMAT', 2, 'D, M d Y - G:i', 'Long date format',3);
insert into ttrss_prefs (pref_name,type_id,def_value,short_desc,section_id,help_text) values('COMBINED_DISPLAY_MODE', 1, 'false', 'Combined feed display',2, 'Display expanded list of feed articles, instead of separate displays for headlines and article content');
insert into ttrss_prefs (pref_name,type_id,def_value,short_desc,section_id) values('HIDE_READ_FEEDS', 1, 'false', 'Hide feeds with no unread messages',2);
insert into ttrss_prefs (pref_name,type_id,def_value,short_desc,section_id,help_text) values('ON_CATCHUP_SHOW_NEXT_FEED', 1, 'false', 'On catchup show next feed',2, 'Automatically open next feed with unread articles after marking one as read');
insert into ttrss_prefs (pref_name,type_id,def_value,short_desc,section_id) values('FEEDS_SORT_BY_UNREAD', 1, 'false', 'Sort feeds by unread articles count',2);
insert into ttrss_prefs (pref_name,type_id,def_value,short_desc,section_id) values('REVERSE_HEADLINES', 1, 'false', 'Reverse headline order (oldest first)',2);
insert into ttrss_prefs (pref_name,type_id,def_value,short_desc,section_id,help_text) values('DIGEST_ENABLE', 1, 'false', 'Enable e-mail digest',4, 'This option enables sending daily digest of new (and unread) headlines on your configured e-mail address');
insert into ttrss_prefs (pref_name,type_id,def_value,short_desc,section_id) values('CONFIRM_FEED_CATCHUP', 1, 'true', 'Confirm marking feed as read',2);
insert into ttrss_prefs (pref_name,type_id,def_value,short_desc,section_id,help_text) values('CDM_AUTO_CATCHUP', 1, 'false', 'Automatically mark articles as read',2, 'This option enables marking articles as read automatically while you scroll article list.');
insert into ttrss_prefs (pref_name,type_id,def_value,short_desc,section_id) values('_DEFAULT_VIEW_MODE', 2, 'adaptive', '', 1);
insert into ttrss_prefs (pref_name,type_id,def_value,short_desc,section_id) values('_DEFAULT_VIEW_LIMIT', 3, '30', '', 1);
insert into ttrss_prefs (pref_name,type_id,def_value,short_desc,section_id) values('_PREFS_ACTIVE_TAB', 2, '', '', 1);
insert into ttrss_prefs (pref_name,type_id,def_value,short_desc,section_id,help_text) values('STRIP_UNSAFE_TAGS', 1, 'true', 'Strip unsafe tags from articles', 3, 'Strip all but most common HTML tags when reading articles.');
insert into ttrss_prefs (pref_name,type_id,def_value,short_desc,section_id,help_text) values('BLACKLISTED_TAGS', 2, 'main, generic, misc, uncategorized, blog, blogroll, general, news', 'Blacklisted tags', 3, 'When auto-detecting tags in articles these tags will not be applied (comma-separated list).');
insert into ttrss_prefs (pref_name,type_id,def_value,short_desc,section_id) values('FRESH_ARTICLE_MAX_AGE', 3, '24', 'Maximum age of fresh articles (in hours)',2);
insert into ttrss_prefs (pref_name,type_id,def_value,short_desc,section_id) values('DIGEST_CATCHUP', 1, 'false', 'Mark articles in e-mail digest as read',4);
insert into ttrss_prefs (pref_name,type_id,def_value,short_desc,section_id) values('CDM_EXPANDED', 1, 'true', 'Automatically expand articles in combined mode',2);
insert into ttrss_prefs (pref_name,type_id,def_value,short_desc,section_id) values('PURGE_UNREAD_ARTICLES', 1, 'true', 'Purge unread articles',3);
insert into ttrss_prefs (pref_name,type_id,def_value,short_desc,section_id) values('HIDE_READ_SHOWS_SPECIAL', 1, 'true', 'Show special feeds when hiding read feeds',2);
insert into ttrss_prefs (pref_name,type_id,def_value,short_desc,section_id,help_text) values('VFEED_GROUP_BY_FEED', 1, 'false', 'Group headlines in virtual feeds',2, 'When this option is enabled, headlines in Special feeds and Labels are grouped by feeds');
insert into ttrss_prefs (pref_name,type_id,def_value,short_desc,section_id) values('STRIP_IMAGES', 1, 'false', 'Do not embed images in articles', 2);
insert into ttrss_prefs (pref_name,type_id,def_value,short_desc,section_id) values('_DEFAULT_VIEW_ORDER_BY', 2, 'default', '', 1);
insert into ttrss_prefs (pref_name,type_id,def_value,short_desc,section_id) values('ENABLE_API_ACCESS', 1, 'false', 'Enable external API', 1);
insert into ttrss_prefs (pref_name,type_id,def_value,short_desc,section_id) values('_COLLAPSED_SPECIAL', 1, 'false', '', 1);
insert into ttrss_prefs (pref_name,type_id,def_value,short_desc,section_id) values('_COLLAPSED_LABELS', 1, 'false', '', 1);
insert into ttrss_prefs (pref_name,type_id,def_value,short_desc,section_id) values('_COLLAPSED_UNCAT', 1, 'false', '', 1);
insert into ttrss_prefs (pref_name,type_id,def_value,short_desc,section_id) values('_COLLAPSED_FEEDLIST', 1, 'false', '', 1);
insert into ttrss_prefs (pref_name,type_id,def_value,short_desc,section_id) values('_MOBILE_ENABLE_CATS', 1, 'false', '', 1);
insert into ttrss_prefs (pref_name,type_id,def_value,short_desc,section_id) values('_MOBILE_SHOW_IMAGES', 1, 'false', '', 1);
insert into ttrss_prefs (pref_name,type_id,def_value,short_desc,section_id) values('_MOBILE_HIDE_READ', 1, 'false', '', 1);
insert into ttrss_prefs (pref_name,type_id,def_value,short_desc,section_id) values('_MOBILE_SORT_FEEDS_UNREAD', 1, 'false', '', 1);
insert into ttrss_prefs (pref_name,type_id,def_value,short_desc,section_id) values('_THEME_ID', 2, '0', '', 1);
insert into ttrss_prefs (pref_name,type_id,def_value,short_desc,section_id) values('USER_TIMEZONE', 2, 'UTC', 'User timezone', 1);
insert into ttrss_prefs (pref_name,type_id,def_value,short_desc,section_id,help_text) values('USER_STYLESHEET', 2, '', 'Customize stylesheet', 2, 'Customize CSS stylesheet to your liking');
insert into ttrss_prefs (pref_name,type_id,def_value,short_desc,section_id,help_text) values('SORT_HEADLINES_BY_FEED_DATE', 1, 'true', 'Sort headlines by feed date',2, 'Use feed-specified date to sort headlines instead of local import date.');
insert into ttrss_prefs (pref_name,type_id,def_value,short_desc,section_id) values('_MOBILE_BROWSE_CATS', 1, 'true', '', 1);
insert into ttrss_prefs (pref_name,type_id,def_value,short_desc,section_id,help_text) values('SSL_CERT_SERIAL', 2, '', 'Login with an SSL certificate',3, 'Click to register your SSL client certificate with tt-rss');
insert into ttrss_prefs (pref_name,type_id,def_value,short_desc,section_id,help_text) values('DIGEST_PREFERRED_TIME', 2, '00:00', 'Try to send digests around specified time', 4, 'Uses UTC timezone');
insert into ttrss_prefs (pref_name,type_id,def_value,short_desc,section_id) values('_PREFS_SHOW_EMPTY_CATS', 1, 'false', '', 1);
insert into ttrss_prefs (pref_name,type_id,def_value,short_desc,section_id) values('_DEFAULT_INCLUDE_CHILDREN', 1, 'false', '', 1);
insert into ttrss_prefs (pref_name,type_id,def_value,short_desc,section_id) values('AUTO_ASSIGN_LABELS', 1, 'true', 'Assign articles to labels automatically', 3);
insert into ttrss_prefs (pref_name,type_id,def_value,short_desc,section_id) values('_ENABLED_PLUGINS', 2, '', '', 1);
insert into ttrss_prefs (pref_name,type_id,def_value,short_desc,section_id) values('_MOBILE_REVERSE_HEADLINES', 1, 'false', '', 1);
update ttrss_prefs set access_level = 1 where pref_name in ('ON_CATCHUP_SHOW_NEXT_FEED',
'SORT_HEADLINES_BY_FEED_DATE',
'VFEED_GROUP_BY_FEED',
'FRESH_ARTICLE_MAX_AGE',
'CDM_EXPANDED',
'SHOW_CONTENT_PREVIEW',
'AUTO_ASSIGN_LABELS',
'HIDE_READ_SHOWS_SPECIAL');
create table ttrss_user_prefs (
owner_uid integer not null,
pref_name varchar(250),
value longtext not null,
profile integer,
index (profile),
foreign key (profile) references ttrss_settings_profiles(id) ON DELETE CASCADE,
index (owner_uid),
foreign key (owner_uid) references ttrss_users(id) ON DELETE CASCADE,
index (pref_name),
foreign key (pref_name) references ttrss_prefs(pref_name) ON DELETE CASCADE) ENGINE=InnoDB DEFAULT CHARSET=UTF8;
create index ttrss_user_prefs_owner_uid_index on ttrss_user_prefs(owner_uid);
create index ttrss_user_prefs_pref_name_idx on ttrss_user_prefs(pref_name);
create table ttrss_sessions (id varchar(250) unique not null primary key,
data text,
expire integer not null,
index (id),
index (expire)) ENGINE=InnoDB DEFAULT CHARSET=UTF8;
create table ttrss_feedbrowser_cache (
feed_url text not null,
site_url text not null,
title text not null,
subscribers integer not null) DEFAULT CHARSET=UTF8;
create table ttrss_labels2 (id integer not null primary key auto_increment,
owner_uid integer not null,
caption varchar(250) not null,
fg_color varchar(15) not null default '',
bg_color varchar(15) not null default '',
foreign key (owner_uid) references ttrss_users(id) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=UTF8;
create table ttrss_user_labels2 (label_id integer not null,
article_id integer not null,
foreign key (label_id) references ttrss_labels2(id) ON DELETE CASCADE,
foreign key (article_id) references ttrss_entries(id) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=UTF8;
create table ttrss_access_keys (id integer not null primary key auto_increment,
access_key varchar(250) not null,
feed_id varchar(250) not null,
is_cat bool not null default false,
owner_uid integer not null,
foreign key (owner_uid) references ttrss_users(id) ON DELETE CASCADE) ENGINE=InnoDB DEFAULT CHARSET=UTF8;
create table ttrss_linked_instances (id integer not null primary key auto_increment,
last_connected datetime not null,
last_status_in integer not null,
last_status_out integer not null,
access_key varchar(250) not null unique,
access_url text not null) ENGINE=InnoDB DEFAULT CHARSET=UTF8;
create table ttrss_linked_feeds (
feed_url text not null,
site_url text not null,
title text not null,
created datetime not null,
updated datetime not null,
instance_id integer not null,
subscribers integer not null,
foreign key (instance_id) references ttrss_linked_instances(id) ON DELETE CASCADE) ENGINE=InnoDB DEFAULT CHARSET=UTF8;
create table ttrss_plugin_storage (
id integer not null auto_increment primary key,
name varchar(100) not null,
owner_uid integer not null,
content longtext not null,
foreign key (owner_uid) references ttrss_users(id) ON DELETE CASCADE) ENGINE=InnoDB DEFAULT CHARSET=UTF8;
commit;
[buildout]
extends =
../../stack/lamp/buildout.cfg
[application]
recipe = slapos.recipe.build:download-unpacked
url = https://github.com/gothfox/Tiny-Tiny-RSS/archive/1.7.5.tar.gz
#md5sum = a81cea71701404cebf64c07b7ac6c948
strip-top-level-dir = true
[application-template]
recipe = slapos.recipe.download
url = ${:_profile_base_location_}/template/config.php.in
#md5sum = Student may put here md5sum of this file, this is good idea
filename = template.in
mode = 0644
location = ${buildout:parts-directory}/${:_buildout_section_name_}
[application-configuration]
location = config.php
[sql-script]
recipe = slapos.recipe.download
location = ${buildout:parts-directory}/${:_buildout_section_name_}
url = ${:_profile_base_location_}/script/tt-rss.sql
#md5sum = c4d5f87d8f02cad3f20e679160195f48
filename = tt-rss.sql
mode = 0744
# XXX Should disappear and be integrated into apachephpconfigure
[configure-script]
recipe = slapos.recipe.download
location = ${buildout:parts-directory}/${:_buildout_section_name_}
url = ${:_profile_base_location_}/configure-tt-rss.py
#md5sum = c4d5f87d8f02cad3f20e679160195f48
filename = configure-tt-rss.py
mode = 0744
[custom-application-deployment-template]
recipe = slapos.recipe.template
url = ${:_profile_base_location_}/instance-custom.cfg.in
output = ${buildout:directory}/instance-custom.cfg
#md5sum = 283cb53ff8cd34635703e771062db919
mode = 0644
[custom-application-deployment]
path = ${custom-application-deployment-template:output}
part-list = tt-rss-init
<?php
// *******************************************
// *** Database configuration (important!) ***
// *******************************************
define('DB_TYPE', "mysql"); // or mysql
define('DB_HOST', "%(mysql_host)s");
define('DB_USER', "%(mysql_user)s");
define('DB_NAME', "%(mysql_database)s");
define('DB_PASS', "%(mysql_password)s");
define('MYSQL_CHARSET', 'UTF8');
// Connection charset for MySQL. If you have a legacy database and/or experience
// garbage unicode characters with this option, try setting it to a blank string.
// ***********************************
// *** Basic settings (important!) ***
// ***********************************
//FIXME set frontend URL
define('SELF_URL_PATH', 'http://%(ip)s:%(port)s');
// Full URL of your tt-rss installation. This should be set to the
// location of tt-rss directory, e.g. http://yourserver/tt-rss/
// You need to set this option correctly otherwise several features
// including PUSH, bookmarklets and browser integration will not work properly.
define('SINGLE_USER_MODE', true);
// Operate in single user mode, disables all functionality related to
// multiple users.
define('SIMPLE_UPDATE_MODE', false);
// Enables fallback update mode where tt-rss tries to update feeds in
// background while tt-rss is open in your browser.
// If you don't have a lot of feeds and don't want to or can't run
// background processes while not running tt-rss, this method is generally
// viable to keep your feeds up to date.
// Still, there are more robust (and recommended) updating methods
// available, you can read about them here: http://tt-rss.org/wiki/UpdatingFeeds
// *****************************
// *** Files and directories ***
// *****************************
//FIXME
define('PHP_EXECUTABLE', '/usr/bin/php');
// Path to PHP executable, used for various command-line tt-rss programs
define('LOCK_DIRECTORY', 'lock');
// Directory for lockfiles, must be writable to the user you run
// daemon process or cronjobs under.
define('CACHE_DIR', 'cache');
// Local cache directory for RSS feed content.
define('ICONS_DIR', "feed-icons");
define('ICONS_URL', "feed-icons");
// Local and URL path to the directory, where feed favicons are stored.
// Unless you really know what you're doing, please keep those relative
// to tt-rss main directory.
// **********************
// *** Authentication ***
// **********************
// Please see PLUGINS below to configure various authentication modules.
define('AUTH_AUTO_CREATE', true);
// Allow authentication modules to auto-create users in tt-rss internal
// database when authenticated successfully.
define('AUTH_AUTO_LOGIN', true);
// Automatically login user on remote or other kind of externally supplied
// authentication, otherwise redirect to login form as normal.
// If set to true, users won't be able to set application language
// and settings profile.
// *********************
// *** Feed settings ***
// *********************
define('FORCE_ARTICLE_PURGE', 0);
// When this option is not 0, users ability to control feed purging
// intervals is disabled and all articles (which are not starred)
// older than this amount of days are purged.
// *** PubSubHubbub settings ***
define('PUBSUBHUBBUB_HUB', '');
// URL to a PubSubHubbub-compatible hub server. If defined, "Published
// articles" generated feed would automatically become PUSH-enabled.
define('PUBSUBHUBBUB_ENABLED', false);
// Enable client PubSubHubbub support in tt-rss. When disabled, tt-rss
// won't try to subscribe to PUSH feed updates.
// *********************
// *** Sphinx search ***
// *********************
define('SPHINX_ENABLED', false);
// Enable fulltext search using Sphinx (http://www.sphinxsearch.com)
// Please see http://tt-rss.org/wiki/SphinxSearch for more information.
define('SPHINX_INDEX', 'ttrss');
// Index name in Sphinx configuration. You can specify multiple indexes
// as a comma-separated string.
// ***********************************
// *** Self-registrations by users ***
// ***********************************
define('ENABLE_REGISTRATION', false);
// Allow users to register themselves. Please be vary that allowing
// random people to access your tt-rss installation is a security risk
// and potentially might lead to data loss or server exploit. Disabled
// by default.
define('REG_NOTIFY_ADDRESS', 'user@your.domain.dom');
// Email address to send new user notifications to.
define('REG_MAX_USERS', 10);
// Maximum amount of users which will be allowed to register on this
// system. 0 - no limit.
// **********************************
// *** Cookies and login sessions ***
// **********************************
define('SESSION_COOKIE_LIFETIME', 86400*30);
// Default lifetime of a session (e.g. login) cookie. In seconds,
// 0 means cookie will be deleted when browser closes.
// Setting this to zero will affect several user preferences
// like widescreen mode not saving.
define('SESSION_EXPIRE_TIME', 86400*30);
// Hard expiration limit for sessions. Should be
// greater or equal to SESSION_COOKIE_LIFETIME
define('SESSION_CHECK_ADDRESS', 1);
// Check client IP address when validating session:
// 0 - disable checking
// 1 - check first 3 octets of an address (recommended)
// 2 - check first 2 octets of an address
// 3 - check entire address
// *********************************
// *** Email and digest settings ***
// *********************************
define('SMTP_FROM_NAME', 'Tiny Tiny RSS');
define('SMTP_FROM_ADDRESS', 'noreply@your.domain.dom');
// Name, address and subject for sending outgoing mail. This applies
// to password reset notifications, digest emails and any other mail.
define('DIGEST_SUBJECT', '[tt-rss] New headlines for last 24 hours');
// Subject line for email digests
define('SMTP_HOST', '');
// SMTP Host to send outgoing mail. Blank - use system MTA.
define('SMTP_PORT','');
// SMTP port to sent outgoing mail. Default is 25.
define('SMTP_LOGIN', '');
define('SMTP_PASSWORD', '');
// These two options enable SMTP authentication when sending
// outgoing mail. Only used with SMTP_HOST
// ***************************************
// *** Other settings (less important) ***
// ***************************************
define('CHECK_FOR_NEW_VERSION', false);
// Check for new versions of tt-rss automatically.
define('ENABLE_GZIP_OUTPUT', false);
// Selectively gzip output to improve wire performance. This requires
// PHP Zlib extension on the server.
// Enabling this can break tt-rss in several httpd/php configurations,
// if you experience weird errors and tt-rss failing to start, blank pages
// after login, or content encoding errors, disable it.
define('PLUGINS', 'auth_remote, auth_internal, note');
// Comma-separated list of plugins to load automatically for all users.
// System plugins have to be specified here. Please enable at least one
// authentication plugin here (auth_*).
// Users may enable other user plugins from Preferences/Plugins but may not
// disable plugins specified in this list.
define('CONFIG_VERSION', 26);
// Expected config version. Please update this option in config.php
// if necessary (after migrating all new options from this file).
// vim:ft=php
?>
zimbra-kvm
==========
Introduction
------------
Zimbra single-machine deployment inside of a virtual machine.
Internals
---------
The following ports are reachable from the outside world:
22 -> 2222
443 -> 4443
Others?
For each port, KVM does a NAT redirection from the VM to the local ipv4. Then, 6tunnel is called to redirect it to the outside world using ipv6.
Deployment
----------
To deploy a new Zimbra service, you just need to request a new instance of it,
then connect the the machine using ssh with root:zimbra credentials, reconfigure
Zimbra to use another domain name, and change root password.
Disk Image content
------------------
Ubuntu 12.04, Zimbra install from official packages, 8.0.3
admin password: Cedric de Saint Martin has it.
bind9: http://wiki.zimbra.com/index.php?title=Split_dns
resolv.conf: http://askubuntu.com/questions/30942/why-does-my-resolv-conf-file-get-regenerated-every-time
Todo
----
* SMTP master/slave design implemented
* Reverse proxy for web works
* Automatically download the proper boot disk image.
* Have two virtual disks: one for system/zimbra, one for data.
* Unify smtp frontend and web frontend
[buildout]
extends =
../../component/6tunnel/buildout.cfg
../../component/curl/buildout.cfg
../../component/dash/buildout.cfg
../../component/dcron/buildout.cfg
../../component/gzip/buildout.cfg
../../component/qemu-kvm/buildout.cfg
../../component/logrotate/buildout.cfg
../../component/noVNC/buildout.cfg
../../component/openssl/buildout.cfg
../../stack/slapos.cfg
parts =
template
eggs
[eggs]
recipe = z3c.recipe.scripts
eggs =
${lxml-python:egg}
websockify
slapos.cookbook
slapos.toolbox
[template-kvm]
recipe = slapos.recipe.template
url = ${:_profile_base_location_}/instance-kvm.cfg.in
#md5sum = d4f7203365bacd70ad62f6b6de9f74d4
output = ${buildout:directory}/template-kvm.cfg
mode = 0644
[template]
recipe = slapos.recipe.template
url = ${:_profile_base_location_}/instance.cfg.in
#md5sum = 68788763d23f70f24b9e575871c903a8
output = ${buildout:directory}/template.cfg
mode = 0644
[versions]
# Numpy 1.7.0 doesn't install well
numpy = 1.6.2
[buildout]
extends =
../../component/git/buildout.cfg
common.cfg
parts +=
slapos.cookbook-repository
slapos.toolbox-repository
check-recipe
develop =
${:parts-directory}/slapos.cookbook-repository
${:parts-directory}/slapos.toolbox-repository
[slapos.cookbook-repository]
recipe = slapos.recipe.build:gitclone
repository = http://git.erp5.org/repos/slapos.git
branch = zimbra-kvm
git-executable = ${git:location}/bin/git
[slapos.toolbox-repository]
recipe = slapos.recipe.build:gitclone
repository = http://git.erp5.org/repos/slapos.toolbox.git
branch = master
git-executable = ${git:location}/bin/git
[check-recipe]
recipe = plone.recipe.command
stop-on-error = true
update-command = ${:command}
command =
grep parts ${buildout:develop-eggs-directory}/slapos.cookbook.egg-link &&
grep parts ${buildout:develop-eggs-directory}/slapos.toolbox.egg-link
#############################
#
# Instanciate kvm
#
#############################
[buildout]
parts =
certificate-authority
request-web-frontend
kvm-promise
tunnel-ipv6-kvm-https
tunnel-ipv6-kvm-ssh
tunnel-ipv6-kvm-zimbra-admin
tunnel-ipv6-kvm-smtp
tunnel-ipv6-kvm-smtp-submission
websockify-sighandler
novnc-promise
publish-kvm-connection-information
eggs-directory = ${buildout:eggs-directory}
develop-eggs-directory = ${buildout:develop-eggs-directory}
offline = true
[directory]
recipe = slapos.cookbook:mkdirectory
etc = $${buildout:directory}/etc
bin = $${buildout:directory}/bin
srv = $${buildout:directory}/srv
var = $${buildout:directory}/var
scripts = $${:etc}/run
services = $${:etc}/service
promises = $${:etc}/promise
novnc-conf = $${:etc}/novnc
run = $${:var}/run
ca-dir = $${:srv}/ssl
[create-mac]
recipe = slapos.cookbook:generate.mac
storage-path = $${directory:srv}/mac
[gen-passwd]
recipe = slapos.cookbook:generate.password
storage-path = $${directory:srv}/passwd
bytes = 4
[kvm-instance]
# XXX-Cedric: change "KVM" recipe to simple "create wrappers". No need for this
# Specific code
recipe = slapos.cookbook:zimbra.kvm
vnc-ip = $${slap-network-information:local-ipv4}
vnc-port = 5901
boot-disk-path = $${directory:srv}/boot.qcow2
data-disk-path = $${directory:srv}/virtual.qcow2
data-disk-size = $${slap-parameter:disk-size}
data-disk-type = $${slap-parameter:disk-type}
socket-path = $${directory:var}/qmp_socket
pid-path = $${directory:run}/pid_file
smp-count = $${slap-parameter:cpu-count}
ram-size = $${slap-parameter:ram-size}
disk-type = virtio
mac-address = $${create-mac:mac-address}
runner-path = $${directory:services}/kvm
controller-path = $${directory:scripts}/kvm_controller
shell-path = ${dash:location}/bin/dash
qemu-path = ${kvm:location}/bin/qemu-system-x86_64
qemu-img-path = ${kvm:location}/bin/qemu-img
passwd = $${gen-passwd:passwd}
[kvm-promise]
recipe = slapos.cookbook:check_port_listening
path = $${directory:promises}/vnc_promise
hostname = $${kvm-instance:vnc-ip}
port = $${kvm-instance:vnc-port}
# 6tunnel
# Refers to http://wiki.zimbra.com/wiki/Ports#External_Access
[tunnel-ipv6-kvm-https]
recipe = slapos.cookbook:ipv6toipv4
ipv6 = $${slap-network-information:global-ipv6}
ipv6-port = 443
ipv4 = $${slap-network-information:local-ipv4}
ipv4-port = 443
shell-path = ${dash:location}/bin/dash
6tunnel-path = ${6tunnel:location}/bin/6tunnel
runner-path = $${directory:services}/6tunnel-https
[tunnel-ipv6-kvm-zimbra-admin]
recipe = slapos.cookbook:ipv6toipv4
ipv6 = $${slap-network-information:global-ipv6}
ipv6-port = 7071
ipv4 = $${slap-network-information:local-ipv4}
ipv4-port = 7071
shell-path = ${dash:location}/bin/dash
6tunnel-path = ${6tunnel:location}/bin/6tunnel
runner-path = $${directory:services}/6tunnel-zimbra_admin
[tunnel-ipv6-kvm-ssh]
recipe = slapos.cookbook:ipv6toipv4
ipv6 = $${slap-network-information:global-ipv6}
ipv6-port = 2222
ipv4 = $${slap-network-information:local-ipv4}
ipv4-port = 2222
shell-path = ${dash:location}/bin/dash
6tunnel-path = ${6tunnel:location}/bin/6tunnel
runner-path = $${directory:services}/6tunnel-ssh
[tunnel-ipv6-kvm-smtp]
recipe = slapos.cookbook:ipv6toipv4
ipv6 = $${slap-network-information:global-ipv6}
ipv6-port = 25
ipv4 = $${slap-network-information:local-ipv4}
ipv4-port = 25
shell-path = ${dash:location}/bin/dash
6tunnel-path = ${6tunnel:location}/bin/6tunnel
runner-path = $${directory:services}/6tunnel-smtp
[tunnel-ipv6-kvm-smtp-submission]
recipe = slapos.cookbook:ipv6toipv4
ipv6 = $${slap-network-information:global-ipv6}
ipv6-port = 587
ipv4 = $${slap-network-information:local-ipv4}
ipv4-port = 587
shell-path = ${dash:location}/bin/dash
6tunnel-path = ${6tunnel:location}/bin/6tunnel
runner-path = $${directory:services}/6tunnel-smtp-submission
[novnc-instance]
recipe = slapos.cookbook:novnc
path = $${ca-novnc:executable}
ip = $${slap-network-information:global-ipv6}
port = 6080
vnc-ip = $${kvm-instance:vnc-ip}
vnc-port = $${kvm-instance:vnc-port}
novnc-location = ${noVNC:location}
websockify-path = ${buildout:directory}/bin/websockify
ssl-key-path = $${ca-novnc:key-file}
ssl-cert-path = $${ca-novnc:cert-file}
[websockify-sighandler]
recipe = slapos.cookbook:signalwrapper
wrapper-path = $${directory:services}/websockify
wrapped-path = $${novnc-instance:path}
[certificate-authority]
recipe = slapos.cookbook:certificate_authority
openssl-binary = ${openssl:location}/bin/openssl
ca-dir = $${directory:ca-dir}
requests-directory = $${cadirectory:requests}
wrapper = $${directory:services}/certificate_authority
ca-private = $${cadirectory:private}
ca-certs = $${cadirectory:certs}
ca-newcerts = $${cadirectory:newcerts}
ca-crl = $${cadirectory:crl}
[cadirectory]
recipe = slapos.cookbook:mkdirectory
requests = $${directory:ca-dir}/requests/
private = $${directory:ca-dir}/private/
certs = $${directory:ca-dir}/certs/
newcerts = $${directory:ca-dir}/newcerts/
crl = $${directory:ca-dir}/crl/
[ca-novnc]
<= certificate-authority
recipe = slapos.cookbook:certificate_authority.request
key-file = $${directory:novnc-conf}/novnc.key
cert-file = $${directory:novnc-conf}/novnc.crt
executable = $${directory:bin}/novnc
wrapper = $${directory:bin}/websockify
[novnc-promise]
recipe = slapos.cookbook:check_port_listening
path = $${directory:promises}/novnc_promise
hostname = $${novnc-instance:ip}
port = $${novnc-instance:port}
[kvm-monitor]
recipe = slapos.cookbook:generic.slapmonitor
db-path = $${directory:srv}/slapmonitor_database
[request-slave-frontend]
recipe = slapos.cookbook:requestoptional
software-url = $${slap-parameter:frontend-software-url}
server-url = $${slap-connection:server-url}
key-file = $${slap-connection:key-file}
cert-file = $${slap-connection:cert-file}
computer-id = $${slap-connection:computer-id}
partition-id = $${slap-connection:partition-id}
name = VNC Frontend
software-type = $${slap-parameter:frontend-software-type}
slave = true
config = host port
config-host = $${novnc-instance:ip}
config-port = $${novnc-instance:port}
return = url resource port domainname
sla = instance_guid
sla-instance_guid = $${slap-parameter:frontend-instance-guid}
[request-web-frontend]
<= slap-connection
recipe = slapos.cookbook:requestoptional
name = Web Frontend
# XXX We have hardcoded SR URL here.
software-url = http://git.erp5.org/gitweb/slapos.git/blob_plain/HEAD:/software/apache-frontend/software.cfg
slave = true
config = url custom_domain
config-url = https://[$${tunnel-ipv6-kvm-https:ipv6}]:$${tunnel-ipv6-kvm-https:ipv6-port}/
return = site_url
config-custom_domain = $${slap-parameter:domain}
[request-smtp-frontend]
<= slap-connection
recipe = slapos.cookbook:requestoptional
name = SMTP Frontend
# XXX We have hardcoded SR URL here.
#software-url = http://git.erp5.org/gitweb/slapos.git/blob_plain/zimbra-kvm:/software/reverse-proxy-nginx/development.cfg
software-url = /opt/slapdev/software/reverse-proxy-nginx/development.cfg
slave = true
config = smtp-upstream-host smtp-upstream-port
config-smtp-upstream-host = $${tunnel-ipv6-kvm-smtp:ipv6}
config-smtp-upstream-port = $${tunnel-ipv6-kvm-smtp:port}
return = listening-ipv4
[publish-kvm-connection-information]
recipe = slapos.cookbook:publish
web-backend-url = https://[$${tunnel-ipv6-kvm-https:ipv6}]:$${tunnel-ipv6-kvm-https:ipv6-port}/
web-url = $${request-web-frontend:connection-site_url}
vnc-backend-url = https://[$${novnc-instance:ip}]:$${novnc-instance:port}/vnc_auto.html?host=[$${novnc-instance:ip}]&port=$${novnc-instance:port}&encrypt=1
vnc-password = $${kvm-instance:passwd}
vnc-url = $${request-slave-frontend:connection-url}/vnc_auto.html?host=$${request-slave-frontend:connection-domainname}&port=$${request-slave-frontend:connection-port}&encrypt=1&path=$${request-slave-frontend:connection-resource}
ssh = ssh root@$${tunnel-ipv6-kvm-ssh:ipv6} -p $${tunnel-ipv6-kvm-ssh:ipv6-port}
smtp-listening-ipv4 = $${request-smtp-frontend:connection-listening-ipv4}
[slap-parameter]
# Default values if not specified
frontend-instance-guid =
frontend-software-type = frontend
frontend-software-url = http://git.erp5.org/gitweb/slapos.git/blob_plain/refs/tags/slapos-0.92:/software/kvm/software.cfg
ram-size = 4096
disk-size = 50
disk-type = virtio
cpu-count = 4
domain =
[buildout]
parts =
switch-softwaretype
eggs-directory = ${buildout:eggs-directory}
develop-eggs-directory = ${buildout:develop-eggs-directory}
offline = true
[switch-softwaretype]
recipe = slapos.cookbook:softwaretype
default = ${template-kvm:output}
[slap-connection]
# part to migrate to new - separated words
computer-id = $${slap_connection:computer_id}
partition-id = $${slap_connection:partition_id}
server-url = $${slap_connection:server_url}
software-release-url = $${slap_connection:software_release_url}
key-file = $${slap_connection:key_file}
cert-file = $${slap_connection:cert_file}
[buildout]
extends = common.cfg
[networkcache]
# signature certificates of the following uploaders.
# Romain Courteaud
# Cedric de Saint Martin
# Test Agent
signature-certificate-list =
-----BEGIN CERTIFICATE-----
MIIB4DCCAUkCADANBgkqhkiG9w0BAQsFADA5MQswCQYDVQQGEwJGUjEZMBcGA1UE
CBMQRGVmYXVsdCBQcm92aW5jZTEPMA0GA1UEChMGTmV4ZWRpMB4XDTExMDkxNTA5
MDAwMloXDTEyMDkxNTA5MDAwMlowOTELMAkGA1UEBhMCRlIxGTAXBgNVBAgTEERl
ZmF1bHQgUHJvdmluY2UxDzANBgNVBAoTBk5leGVkaTCBnzANBgkqhkiG9w0BAQEF
AAOBjQAwgYkCgYEApYZv6OstoqNzxG1KI6iE5U4Ts2Xx9lgLeUGAMyfJLyMmRLhw
boKOyJ9Xke4dncoBAyNPokUR6iWOcnPHtMvNOsBFZ2f7VA28em3+E1JRYdeNUEtX
Z0s3HjcouaNAnPfjFTXHYj4um1wOw2cURSPuU5dpzKBbV+/QCb5DLheynisCAwEA
ATANBgkqhkiG9w0BAQsFAAOBgQBCZLbTVdrw3RZlVVMFezSHrhBYKAukTwZrNmJX
mHqi2tN8tNo6FX+wmxUUAf3e8R2Ymbdbn2bfbPpcKQ2fG7PuKGvhwMG3BlF9paEC
q7jdfWO18Zp/BG7tagz0jmmC4y/8akzHsVlruo2+2du2freE8dK746uoMlXlP93g
QUUGLQ==
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIIB9jCCAV+gAwIBAgIJAO4V/jiMoICoMA0GCSqGSIb3DQEBBQUAMBMxETAPBgNV
BAMMCENPTVAtMjMyMCAXDTEyMDIxNjExMTAyM1oYDzIxMTIwMTIzMTExMDIzWjAT
MREwDwYDVQQDDAhDT01QLTIzMjCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA
wi/3Z8W9pUiegUXIk/AiFDQ0UJ4JFAwjqr+HSRUirlUsHHT+8DzH/hfcTDX1I5BB
D1ADk+ydXjMm3OZrQcXjn29OUfM5C+g+oqeMnYQImN0DDQIOcUyr7AJc4xhvuXQ1
P2pJ5NOd3tbd0kexETa1LVhR6EgBC25LyRBRae76qosCAwEAAaNQME4wHQYDVR0O
BBYEFMDmW9aFy1sKTfCpcRkYnP6zUd1cMB8GA1UdIwQYMBaAFMDmW9aFy1sKTfCp
cRkYnP6zUd1cMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEFBQADgYEAskbFizHr
b6d3iIyN+wffxz/V9epbKIZVEGJd/6LrTdLiUfJPec7FaxVCWNyKBlCpINBM7cEV
Gn9t8mdVQflNqOlAMkOlUv1ZugCt9rXYQOV7rrEYJBWirn43BOMn9Flp2nibblby
If1a2ZoqHRxoNo2yTmm7TSYRORWVS+vvfjY=
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIIB9jCCAV+gAwIBAgIJAKRvzcy7OH0UMA0GCSqGSIb3DQEBBQUAMBMxETAPBgNV
BAMMCENPTVAtNzcyMCAXDTEyMDgxMDE1NDI1MVoYDzIxMTIwNzE3MTU0MjUxWjAT
MREwDwYDVQQDDAhDT01QLTc3MjCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA
o7aipd6MbnuGDeR1UJUjuMLQUariAyQ2l2ZDS6TfOwjHiPw/mhzkielgk73kqN7A
sUREx41eTcYCXzTq3WP3xCLE4LxLg1eIhd4nwNHj8H18xR9aP0AGjo4UFl5BOMa1
mwoyBt3VtfGtUmb8whpeJgHhqrPPxLoON+i6fIbXDaUCAwEAAaNQME4wHQYDVR0O
BBYEFEfjy3OopT2lOksKmKBNHTJE2hFlMB8GA1UdIwQYMBaAFEfjy3OopT2lOksK
mKBNHTJE2hFlMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEFBQADgYEAaNRx6YN2
M/p3R8/xS6zvH1EqJ3FFD7XeAQ52WuQnKSREzuw0dsw12ClxjcHiQEFioyTiTtjs
5pW18Ry5Ie7iFK4cQMerZwWPxBodEbAteYlRsI6kePV7Gf735Y1RpuN8qZ2sYL6e
x2IMeSwJ82BpdEI5niXxB+iT0HxhmR+XaMI=
-----END CERTIFICATE-----
[versions]
numpy = 1.6.2
Jinja2 = 2.6
Werkzeug = 0.8.3
apache-libcloud = 0.12.1
async = 0.6.1
buildout-versions = 1.7
gitdb = 0.5.4
hexagonit.recipe.cmmi = 1.6
lxml = 3.1.0
meld3 = 0.6.10
plone.recipe.command = 1.1
pycrypto = 2.6
slapos.cookbook = 0.73.1
slapos.recipe.template = 2.4.2
slapos.toolbox = 0.33.1
smmap = 0.8.2
websockify = 0.3.0
z3c.recipe.scripts = 1.0.1
# Required by:
# slapos.core==0.35.1
# slapos.toolbox==0.33.1
Flask = 0.9
# Required by:
# slapos.toolbox==0.33.1
GitPython = 0.3.2.RC1
# Required by:
# slapos.toolbox==0.33.1
atomize = 0.1.1
# Required by:
# slapos.toolbox==0.33.1
feedparser = 5.1.3
# Required by:
# hexagonit.recipe.cmmi==1.6
hexagonit.recipe.download = 1.6nxd002
# Required by:
# slapos.cookbook==0.73.1
inotifyx = 0.2.0
# Required by:
# slapos.cookbook==0.73.1
netaddr = 0.7.10
# Required by:
# slapos.core==0.35.1
netifaces = 0.8
# Required by:
# slapos.toolbox==0.33.1
paramiko = 1.10.0
# Required by:
# slapos.toolbox==0.33.1
psutil = 0.6.1
# Required by:
# slapos.core==0.35.1
pyflakes = 0.6.1
# Required by:
# slapos.cookbook==0.73.1
pytz = 2012j
# Required by:
# slapos.cookbook==0.73.1
# slapos.core==0.35.1
# slapos.toolbox==0.33.1
setuptools = 0.6c12dev-r88846
# Required by:
# slapos.cookbook==0.73.1
# slapos.toolbox==0.33.1
slapos.core = 0.35.1
# Required by:
# slapos.core==0.35.1
supervisor = 3.0b1
# Required by:
# slapos.core==0.35.1
unittest2 = 0.5.1
# Required by:
# slapos.cookbook==0.73.1
# slapos.toolbox==0.33.1
xml-marshaller = 0.9.7
# Required by:
# slapos.core==0.35.1
zope.interface = 4.0.5
\ No newline at end of file
......@@ -290,7 +290,7 @@ extra-context =
[template-memcached]
< = template-jinja2-base
filename = instance-memcached.cfg
md5sum = 2de1801236eb78651ecfd50ada46dd3b
md5sum = 346c864c1f119360eddb5e163f16d4f3
extra-context =
key dash_location dash:location
key dcron_location dcron:location
......@@ -438,6 +438,7 @@ eggs =
ordereddict
paramiko
ply
pyflakes
pyPdf # should be replaced by PyPDF2, but it is not installable
python-magic
python-memcached
......@@ -520,7 +521,7 @@ scripts = zodbanalyze
[cloudooo-repository]
branch = master
revision = 6629837c96ae58e96cac019044ce95d19cb7a659
revision = 168786a4c747d4dc4578a6428d39b3b2b3e1eb10
[mysql-python]
python = python2.6
......@@ -645,7 +646,7 @@ inotifyx = 0.2.0
ipdb = 0.7
ipython = 0.13.1
meld3 = 0.6.10
mr.developer = 1.24
mr.developer = 1.25
netaddr = 0.7.10
netifaces = 0.8
ordereddict = 1.1
......@@ -658,7 +659,7 @@ pyPdf = 1.13
pyflakes = 0.6.1
python-ldap = 2.4.10
python-magic = 0.4.3
qrcode = 2.4.2
qrcode = 2.5.1
requests = 1.1.0
restkit = 4.2.1
rtjp-eventlet = 0.3.2
......
......@@ -27,9 +27,9 @@ recipe = slapos.cookbook:generic.kumofs
# Network options
ip = ${slap-network-information:local-ipv4}
manager-port = 13101
server-port = 13201
server-listen-port = 13202
manager-port = 13401
server-port = 13501
server-listen-port = 13502
# previous memcached configuration
gateway-port = 11000
# previous memcached configuration
......
[buildout]
extends = ${custom-application-deployment:path}
parts =
certificate-authority
......@@ -13,6 +14,8 @@ parts =
frontend-promise
content-promise
publish-connection-informations
${custom-application-deployment:part-list}
eggs-directory = ${buildout:eggs-directory}
develop-eggs-directory = ${buildout:develop-eggs-directory}
......@@ -35,6 +38,7 @@ tmp = $${buildout:directory}/tmp
recipe = slapos.cookbook:mkdirectory
log = $${rootdirectory:var}/log
services = $${rootdirectory:etc}/service
scripts = $${rootdirectory:etc}/run
run = $${rootdirectory:var}/run
backup = $${rootdirectory:srv}/backup
promises = $${rootdirectory:etc}/promise
......
......@@ -74,7 +74,7 @@ mode = 0644
recipe = slapos.recipe.template
url = ${:_profile_base_location_}/apache/instance-apache-php.cfg.in
output = ${buildout:directory}/instance-apache-php.cfg
md5sum = af0d52de4c10d5a3a64f7c92283ad959
md5sum = 296ba845c8ffe75fbc6352dd0e8ce836
mode = 0644
[instance-apache-import]
......@@ -95,7 +95,7 @@ context = key templateapache instance-apache-php:output
import-list = file parts template-parts:destination
file replicated template-replicated:destination
md5sum = 4704f2788f096c7494694db72a9f6193
md5sum = 24c5d0db063e5343a3cb0db9d5fbc738
mode = 0644
[instance-resilient]
......@@ -135,6 +135,19 @@ md5sum = 0352896921ca1766b64f0b54f0f8c27e
mode = 0644
#----------------
#--
#-- Optional part allowing applications using this stack to run a custom
#-- instance.cfg at the end of Apache/PHP instance deployment.
#-- To use it in your application, just override those two parameters, like:
[custom-application-deployment]
# path = /path/to/instance-custom.cfg
# part-list = part1 part2
# See software/maarch/software.cfg for an example.
path =
part-list =
#----------------
#-- Dummy parts in case no application configuration file is needed
......@@ -145,13 +158,25 @@ location =
[application-configuration]
location =
#----------------
[custom-application-deployment]
# Optional part allowing applications using this stack to run a custom
# instance.cfg at the end of Apache/PHP instance deployment.
# To use it in your application, just override those two parameters, like:
# path = /path/to/instance-custom.cfg
# part-list =
# part1
# part2
# See software/tt-rss/software.cfg for an example.
path =
part-list =
[eggs]
recipe = zc.recipe.egg
eggs =
${lxml-python:egg}
slapos.toolbox
slapos.toolbox[lampconfigure]
[networkcache]
# Romain Courteaud + Sebastien Robin + Alain Takoudjou
......@@ -287,41 +312,42 @@ signature-certificate-list =
[versions]
Jinja2 = 2.6
MySQL-python = 1.2.4
Werkzeug = 0.8.3
apache-libcloud = 0.12.1
apache-libcloud = 0.12.3
async = 0.6.1
buildout-versions = 1.7
gitdb = 0.5.4
hexagonit.recipe.cmmi = 1.6
inotifyx = 0.2.0
lxml = 3.1.0
lxml = 3.1.1
meld3 = 0.6.10
netaddr = 0.7.10
pycrypto = 2.6
pytz = 2012j
pytz = 2013b
rdiff-backup = 1.0.5
slapos.cookbook = 0.74.0
slapos.cookbook = 0.76.0
slapos.recipe.build = 0.11.6
slapos.recipe.download = 1.0.dev-r4053
slapos.recipe.template = 2.4.2
slapos.toolbox = 0.33.1
slapos.toolbox = 0.34.0
smmap = 0.8.2
# Required by:
# slapos.core==0.35.1
# slapos.toolbox==0.33.1
# slapos.toolbox==0.34.0
Flask = 0.9
# Required by:
# slapos.toolbox==0.33.1
# slapos.toolbox==0.34.0
GitPython = 0.3.2.RC1
# Required by:
# slapos.toolbox==0.33.1
# slapos.toolbox==0.34.0
atomize = 0.1.1
# Required by:
# slapos.toolbox==0.33.1
# slapos.toolbox==0.34.0
feedparser = 5.1.3
# Required by:
......@@ -329,11 +355,11 @@ feedparser = 5.1.3
netifaces = 0.8
# Required by:
# slapos.toolbox==0.33.1
# slapos.toolbox==0.34.0
paramiko = 1.10.0
# Required by:
# slapos.toolbox==0.33.1
# slapos.toolbox==0.34.0
psutil = 0.6.1
# Required by:
......@@ -341,16 +367,17 @@ psutil = 0.6.1
pyflakes = 0.6.1
# Required by:
# slapos.cookbook==0.74.0
# hexagonit.recipe.download==1.6nxd002
# slapos.cookbook==0.76.0
# slapos.core==0.35.1
# slapos.toolbox==0.33.1
# slapos.toolbox==0.34.0
# supervisor==3.0b1
# zc.buildout==1.6.0-dev-SlapOS-010
# zope.interface==4.0.5
setuptools = 0.6c12dev-r88846
# Required by:
# slapos.toolbox==0.33.1
# slapos.toolbox==0.34.0
slapos.core = 0.35.1
# Required by:
......@@ -362,9 +389,10 @@ supervisor = 3.0b1
unittest2 = 0.5.1
# Required by:
# slapos.toolbox==0.33.1
# slapos.toolbox==0.34.0
xml-marshaller = 0.9.7
# Required by:
# slapos.core==0.35.1
zope.interface = 4.0.5
\ No newline at end of file
zope.interface = 4.0.5
......@@ -60,6 +60,7 @@ recipe = zc.recipe.egg
eggs =
${lxml-python:egg}
slapos.cookbook
hexagonit.recipe.download
inotifyx
netaddr
slapos.core
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment