Commit 2ee149d0 authored by Marco Mariani's avatar Marco Mariani

Merge remote-tracking branch 'origin/master' into cygwin-share-res

Conflicts:
	component/dash/buildout.cfg
	component/dcron/buildout.cfg
	component/dropbear/buildout.cfg
	component/glib/buildout.cfg
	component/openssl/buildout.cfg
	component/popt/buildout.cfg
	component/rdiff-backup/buildout.cfg
	software/apache-frontend/software.cfg
parents b2ab8ee3 c9e7414b
......@@ -9,3 +9,5 @@ eggs/
parts/
slapos.cookbook.egg-info
.*.swp
*~
\#*\#
\ No newline at end of file
Changes
=======
0.78.1 (2013-05-31)
0.83.1 (2013-09-10)
------------------
* slapconfiguration: fixes previous releasei (don't encode tap_set because it's not a string). [Cedric de Saint Martin]
0.83 (2013-09-10)
-----------------
* slaprunner recipe: remove trailing / from master_url. [Cedric de Saint Martin]
* librecipe: add pidfile option for singletons. [Cedric de Saint Martin]
* Resiliency: Use new pidfile option. [Cedric de Saint Martin]
* Fix request.py for slave instances. [Cedric de Saint Martin]
* slapconfiguration recipe: cast some parameters from unicode to str. [Cedric de Saint Martin]
0.82 (2013-08-30)
-----------------
* Certificate Authority: Can receice certificate to install. [Cedric Le Ninivin]
* Squid: Add squid recipe. [Romain Courteaud]
* Request: Trasmit instace state to requested instances. [Benjamin Blanc / Cédric Le Ninivin]
* Slapconfiguration: Now return instance state. [Cédric Le Ninivin]
* Apache Frontend: Remove recipe
0.81 (2013-08-12)
-----------------
* KVM SR: implement resiliency test. [Cedric de Saint Martin]
0.80 (2013-08-06)
----------------
* Add a simple readline recipe. [f4fce7e]
0.79 (2013-08-06)
-----------------
* KVM SR: Add support for NAT based networking (User Mode Network). [627895fe35]
* KVM SR: add virtual-hard-drive-url support. [aeb5df40cd, 8ce5a9aa1d0, a5034801aa9]
* Fix regression in GenericBaseRecipe.generatePassword. [3333b07d33c]
0.78.5 (2013-08-06)
-------------------
* check_url_available: add option to check secure links [6cbce4d8231]
0.78.4 (2013-08-06)
-------------------
* slapos.cookbook:slaprunner: Update to use https. [Cedric Le Ninivin]
0.78.3 (2013-07-18)
-------------------
* slapos.cookbook:publish: Add support to publish information for slaves. [Cedric Le Ninivin]
0.78.2 (2013-07-18)
-------------------
* Fix slapos.cookbook:request: Add backward compatiblity about getInstanceGuid(). [Cedric de Saint Martin]
* slapos.cookbook:check_* promises: Add timeout to curl that is not otherwise killed by slapos promise subsystem. [Cedric de Saint Martin]
* Cloudooo: Allow any environment variables. [Yusei Tahara]
* ERP5: disable MariaDB query cache completely by 'query_cache_type = 0' for ERP5. [Kazuhiko Shiozaki]
* ERP5: enable haproxy admin socket and install haproxyctl script. [Kazuhiko Shiozaki]
* ERP5: increase the maximum number of open file descriptors before starting mysqld. [Kazuhiko Shiozaki]
* python 2.7: updated to 2.7.5 [Cedric de Saint Martin]
0.78.1 (2013-05-31)
-------------------
* Add boinc recipe: Allow to deploy an empty BOINC project. [Alain Takoudjou]
* Add boinc.app recipe: Allow to deploy and update a BOINC application into existing BOINC server instance . [Alain Takoudjou]
* Add boinc.client recipe: Allow to deploy a BOINC Client instance on SlapOS. [Alain Takoudjou]
......@@ -15,10 +80,6 @@ Changes
* Add trac recipe: for deploying Trac and manage project with support of SVN and GIT. [Alain Takoudjou]
* Add bonjourgrid recipe: for deploying BonjourGrid Master and submit BOINC or Condor project. [Alain Takoudjou]
* Add bonjourgrid.client recipe: for deploying BonjourGrid Worker instance and execute BOINC or Condor Jobs. [Alain Takoudjou]
* Cloudooo: Allow any environment variables. [Yusei Tahara]
* ERP5: disable MariaDB query cache completely by 'query_cache_type = 0' for ERP5. [Kazuhiko Shiozaki]
* ERP5: enable haproxy admin socket and install haproxyctl script. [Kazuhiko Shiozaki]
* ERP5: increase the maximum number of open file descriptors before starting mysqld. [Kazuhiko Shiozaki]
0.78.0 (2013-04-28)
-------------------
......
......@@ -121,8 +121,9 @@ make-targets =
[apache-2.2]
# inspired on http://old.aclark.net/team/aclark/blog/a-lamp-buildout-for-wordpress-and-other-php-apps/
recipe = slapos.recipe.cmmi
url = http://mir2.ovh.net/ftp.apache.org/dist//httpd/httpd-2.2.24.tar.gz
md5sum = 64a3392018ad60583209a16d728180d3
version = 2.2.25
url = http://mir2.ovh.net/ftp.apache.org/dist/httpd/httpd-${:version}.tar.bz2
md5sum = 9ebe3070c0bb4311f21a0cd0e34f0045
patch-options = -p1
configure-options = --disable-static
--enable-authn-alias
......@@ -183,6 +184,8 @@ environment =
recipe = slapos.recipe.cmmi
url = http://sourceforge.net/projects/mod-antiloris/files/mod_antiloris-0.4.tar.bz2/download
md5sum = 66862bf10e9be3a023e475604a28a0b4
depends =
${apache-2.2:version}
configure-command = ${apache-2.2:location}/bin/apxs
configure-options = -c mod_antiloris.c
make-binary = ${:configure-command}
......
......@@ -44,6 +44,13 @@ filename = cloud9-session-directory.patch
download-only = true
md5sum = 5dc8cc28447ed3747b8a53c768d872aa
[cloud9-socket.patch]
recipe = hexagonit.recipe.download
url = ${:_profile_base_location_}/${:filename}
filename = cloud9-socket.patch
download-only = true
#md5sum = 5dc8cc28447ed3747b8a53c768d872aa
[cloud9-git]
# Online IDE written in javascript/node.js
# URL : c9.io
......@@ -55,7 +62,7 @@ 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};
command = ${:environment} (git clone --quiet ${:repository} ${:location} && cd ${:location} && git reset --hard ${:commit} && ${node-sm:location}/node_modules/.bin/sm install && patch -p1 < ${cloud9-session-directory.patch:location}/${cloud9-session-directory.patch:filename}) || (rm -fr ${:location}; exit 1)
command = ${:environment} (git clone --quiet ${:repository} ${:location} && cd ${:location} && git reset --hard ${:commit} && ${node-sm:location}/node_modules/.bin/sm install && patch -p1 < ${cloud9-session-directory.patch:location}/${cloud9-session-directory.patch:filename} && ${node-sm:location}/node_modules/.bin/sm install && patch -p1 < ${cloud9-socket.patch:location}/${cloud9-socket.patch:filename}) || (rm -fr ${:location}; exit 1)
update-command =
executable = ${:location}/server.js
......
diff --git a/node_modules/smith.io/node_modules/engine.io/node_modules/engine.io-client/dist/engine.io-dev.js b/node_modules/smith.io/node_modules/engine.io/node_modules/engine.io-client/dist/engine.io-dev.js
index fa7e54a..14b8e67 100644
--- a/node_modules/smith.io/node_modules/engine.io/node_modules/engine.io-client/dist/engine.io-dev.js
+++ b/node_modules/smith.io/node_modules/engine.io/node_modules/engine.io-client/dist/engine.io-dev.js
@@ -2126,7 +2126,7 @@ Polling.prototype.uri = function () {
query = '?' + query;
}
- return schema + '://' + this.host + port + this.path + query;
+ return this.path + query;
};
});require.register("transports/websocket.js", function(module, exports, require, global){
......@@ -22,7 +22,7 @@ git-executable = ${git:location}/bin/git
[cloudooo]
recipe = zc.recipe.egg
python = python2.6
python = python2.7
extra-paths = ${cloudooo-repository:location}
eggs =
${lxml-python:egg}
......
......@@ -2,7 +2,7 @@
extends =
../xz-utils/buildout.cfg
parts =
coreutils
coreutils-output
[coreutils]
recipe = slapos.recipe.cmmi
......@@ -13,3 +13,17 @@ configure-options =
environment =
PATH=${xz-utils:location}/bin:%(PATH)s
LDFLAGS =-Wl,--as-needed
[coreutils-output]
# Shared binary location to ease migration
recipe = plone.recipe.command
stop-on-error = true
update-command = ${:command}
command = ${:test} -x ${:test} -a -x ${:cat} -a -x ${:rm} -a -x ${:echo} -a -x ${:date} -a -x ${:md5sum} -a -x ${:basename}
test = ${coreutils:location}/bin/test
cat = ${coreutils:location}/bin/cat
rm = ${coreutils:location}/bin/rm
echo = ${coreutils:location}/bin/echo
date = ${coreutils:location}/bin/date
md5sum = ${coreutils:location}/bin/md5sum
basename = ${coreutils:location}/bin/basename
[buildout]
extends =
../coreutils/buildout.cfg
parts = dash
parts = dash-output
[dash]
recipe = slapos.recipe.cmmi
......@@ -15,3 +17,11 @@ configure-options =
share = /usr
promises =
/usr/bin/dash.exe
[dash-output]
# Shared binary location to ease migration
recipe = plone.recipe.command
stop-on-error = true
update-command = ${:command}
command = ${coreutils-output:test} -x ${:dash}
dash = ${dash:location}/bin/dash
[buildout]
parts = dcron
extends =
../coreutils/buildout.cfg
parts = dcron-output
[dcron-hooks-download]
recipe = hexagonit.recipe.download
url = ${:_profile_base_location_}/${:filename}
md5sum = 860e914dff4108b47565965fe5ebc7b5
download-only = true
filename = dcron-hooks.py
[dcron-patch-nonroot]
recipe = hexagonit.recipe.download
md5sum = 2f5b22dc1cbe81060a9c28e6f5c06e8b
md5sum = d5408ab682b65cc1eda40d588fcd7db8
url = ${:_profile_base_location_}/${:filename}
filename = dcron-4.4.noroot.no.globals.patch
download-only = true
......@@ -18,8 +28,18 @@ patches =
patch-options = -p1
make-options =
PREFIX=${buildout:parts-directory}/${:_buildout_section_name_}
post-make-hook = ${dcron-hooks-download:location}/${dcron-hooks-download:filename}:post_make_hook
[dcron:cygwin]
share = /usr
promises =
/usr/sbin/cron.exe
[dcron-output]
# Shared binary location to ease migration
recipe = plone.recipe.command
stop-on-error = true
update-command = ${:command}
command = ${coreutils-output:test} -x ${:crond} -a -x ${:crontab} -a ! -u ${:crontab}
crond = ${dcron:location}/sbin/crond
crontab = ${dcron:location}/bin/crontab
# Patch for making dcron usable without root user, as a local service
diff -ru dcron-4.4.org/chuser.c dcron-4.4/chuser.c
--- dcron-4.4.org/chuser.c 2010-01-18 16:27:31.000000000 +0100
+++ dcron-4.4/chuser.c 2011-04-01 11:19:19.000000000 +0200
+++ dcron-4.4/chuser.c 2013-07-18 18:17:16.342147418 +0200
@@ -14,47 +14,6 @@
int
ChangeUser(const char *user, char *dochdir)
......@@ -53,7 +52,16 @@ diff -ru dcron-4.4.org/chuser.c dcron-4.4/chuser.c
diff -ru dcron-4.4.org/crontab.c dcron-4.4/crontab.c
--- dcron-4.4.org/crontab.c 2010-01-18 16:27:31.000000000 +0100
+++ dcron-4.4/crontab.c 2011-04-01 11:19:19.000000000 +0200
+++ dcron-4.4/crontab.c 2013-07-18 18:18:07.768535485 +0200
@@ -88,7 +88,7 @@
break;
case 'c':
/* getopt guarantees optarg != 0 here */
- if (*optarg != 0 && getuid() == geteuid()) {
+ if (*optarg != 0) {
CDir = optarg;
} else {
printlogf(0, "-c option: superuser only");
@@ -316,9 +316,6 @@
close(filedes[0]);
......@@ -75,7 +83,7 @@ diff -ru dcron-4.4.org/crontab.c dcron-4.4/crontab.c
ptr = PATH_VI;
diff -ru dcron-4.4.org/job.c dcron-4.4/job.c
--- dcron-4.4.org/job.c 2010-01-18 16:27:31.000000000 +0100
+++ dcron-4.4/job.c 2011-04-01 11:19:19.000000000 +0200
+++ dcron-4.4/job.c 2013-07-18 18:17:16.342147418 +0200
@@ -62,14 +62,6 @@
* Change running state to the user in question
*/
......@@ -108,7 +116,7 @@ diff -ru dcron-4.4.org/job.c dcron-4.4/job.c
/*
diff -ru dcron-4.4.org/Makefile dcron-4.4/Makefile
--- dcron-4.4.org/Makefile 2010-01-18 16:27:31.000000000 +0100
+++ dcron-4.4/Makefile 2011-04-01 11:19:35.000000000 +0200
+++ dcron-4.4/Makefile 2013-07-18 18:17:16.342147418 +0200
@@ -3,7 +3,6 @@
# these variables can be configured by e.g. `make SCRONTABS=/different/path`
......
import os
import shutil
def post_make_hook(options, buildout):
crontab_path = os.path.join(options['location'], 'bin', 'crontab')
os.chmod(crontab_path, 0750)
......@@ -7,9 +7,10 @@
[buildout]
extends =
../zlib/buildout.cfg
../coreutils/buildout.cfg
parts =
dropbear
dropbear-output
[dropbear]
recipe = slapos.recipe.cmmi
......@@ -40,3 +41,12 @@ patch-options=
patches =
${dropbear:patches}
${:_profile_base_location_}/dropbear-0.53.1-cygwin.patch
[dropbear-output]
# Shared binary location to ease migration
recipe = plone.recipe.command
stop-on-error = true
update-command = ${:command}
command = ${coreutils-output:test} -x ${:ssh} -a -x ${:keygen}
ssh = ${dropbear:location}/bin/dbclient
keygen = ${dropbear:location}/bin/dropbearkey
# faketime - report faked system time to programs without having to change the system-wide time
# http://www.code-wizards.com/projects/libfaketime
[buildout]
parts = faketime
[faketime]
recipe = slapos.recipe.cmmi
url = http://www.code-wizards.com/projects/libfaketime/libfaketime-0.9.1.tar.gz
md5sum = ce3f996dfd5826b4ac62f1a7cc36ea27
configure-command = true
make-options =
PREFIX=${buildout:parts-directory}/${:_buildout_section_name_}
make-binary = make -e -C src
make-targets = install
post-install = sed -i -e "16c\FTPL_PATH=${buildout:parts-directory}/${:_buildout_section_name_}/lib/faketime" ${buildout:parts-directory}/${:_buildout_section_name_}/bin/faketime
......@@ -2,6 +2,7 @@
extends =
../bzip2/buildout.cfg
../libpng/buildout.cfg
../patch/buildout.cfg
../pkgconfig/buildout.cfg
../zlib/buildout.cfg
......@@ -28,16 +29,25 @@ environment =
PATH=${pkgconfig:location}/bin:%(PATH)s
PKG_CONFIG_PATH=${libogg:location}/lib/pkgconfig
[libtheora-png_sizeof.patch]
recipe = hexagonit.recipe.download
url = ${:_profile_base_location_}/${:filename}
filename = libtheora-png_sizeof.patch
md5sum = eaa1454081b50f05b59495a12f52b0d5
download-only = true
[libtheora]
recipe = slapos.recipe.cmmi
url = http://downloads.xiph.org/releases/theora/libtheora-1.1.1.tar.bz2
md5sum = 292ab65cedd5021d6b7ddd117e07cd8e
depends =
${libpng:so_version}
patches = ${libtheora-png_sizeof.patch:location}/${libtheora-png_sizeof.patch:filename}
patch-options = -p1
configure-options =
--disable-static
environment =
PATH=${pkgconfig:location}/bin:%(PATH)s
PATH=${patch:location}/bin:${pkgconfig:location}/bin:%(PATH)s
PKG_CONFIG_PATH=${libogg:location}/lib/pkgconfig:${libpng:location}/lib/pkgconfig:${libvorbis:location}/lib/pkgconfig
[yasm]
......
--- libtheora-1.1.1/examples/png2theora.c.orig 2009-08-23 03:14:04.000000000 +0900
+++ libtheora-1.1.1/examples/png2theora.c 2013-07-16 12:40:07.629087870 +0900
@@ -462,9 +462,9 @@
png_set_strip_alpha(png_ptr);
row_data = (png_bytep)png_malloc(png_ptr,
- 3*height*width*png_sizeof(*row_data));
+ 3*height*width*sizeof(*row_data));
row_pointers = (png_bytep *)png_malloc(png_ptr,
- height*png_sizeof(*row_pointers));
+ height*sizeof(*row_pointers));
for(y = 0; y < height; y++) {
row_pointers[y] = row_data + y*(3*width);
}
......@@ -33,7 +33,7 @@ environment =
[ppl]
recipe = slapos.recipe.cmmi
# we should use version 0.10.x for gcc-4.5
url = http://www.cs.unipr.it/ppl/Download/ftp/releases/0.10.2/ppl-0.10.2.tar.bz2
url = http://bugseng.com/products/ppl/download/ftp/releases/0.10.2/ppl-0.10.2.tar.bz2
md5sum = 5667111f53150618b0fa522ffc53fc3e
configure-options =
--with-libgmp-prefix=${gmp:location}
......@@ -85,9 +85,6 @@ patches =
${gcc-multiarch.patch:location}/${gcc-multiarch.patch:filename}
patch-options = -p2
configure-command = make clean \\; make distclean \\; ./configure
# GMP does not correctly detect achitecture so it have to be given
# as slapos.recipe.cmmi is using shell expansion in subproceses
# backticks are working
configure-options =
--disable-bootstrap
--enable-languages="c,c++"
......@@ -97,12 +94,30 @@ configure-options =
--with-mpc=${mpc:location}
--with-ppl=${ppl:location}
--with-cloog=${cloog-ppl:location}
--with-ecj-jar=${ecj:location}/${ecj:filename}
--prefix=${buildout:parts-directory}/${:_buildout_section_name_}
environment =
LDFLAGS=-Wl,-rpath=${mpfr:location}/lib -Wl,-rpath=${gmp:location}/lib -Wl,-rpath=${mpc:location}/lib -Wl,-rpath=${ppl:location}/lib -Wl,-rpath=${cloog-ppl:location}/lib
PATH=${zip:location}/bin:%(PATH)s
# make install does not work when several core are used
make-targets = install -j1
[gcc-minimal]
recipe = slapos.recipe.cmmi
url = http://ftp.gnu.org/gnu/gcc/gcc-4.5.4/gcc-core-4.5.4.tar.bz2
md5sum = ca62e442629a9a7710f5d797bf1b521c
patches =
${gcc-multiarch.patch:location}/${gcc-multiarch.patch:filename}
patch-options = -p2
configure-options =
--disable-bootstrap
--enable-languages=c
--disable-multilib
--with-gmp=${gmp:location}
--with-mpfr=${mpfr:location}
--with-mpc=${mpc:location}
--without-ppl
--without-cloog
environment =
LDFLAGS=-Wl,-rpath=${mpfr:location}/lib -Wl,-rpath=${gmp:location}/lib -Wl,-rpath=${mpc:location}/lib
# make install does not work when several core are used
make-targets = install -j1
......
......@@ -4,6 +4,7 @@
[buildout]
extends =
../curl/buildout.cfg
../gettext/buildout.cfg
../libexpat/buildout.cfg
../openssl/buildout.cfg
../zlib/buildout.cfg
......
--- glib/gstrfuncs.c~ 2012-12-30 14:51:30.000000000 +0800
+++ glib/gstrfuncs.c 2012-12-30 14:51:50.203125000 +0800
@@ -1423,7 +1423,7 @@
#ifdef HAVE_STRSIGNAL
const char *msg_locale;
-#if defined(G_OS_BEOS) || defined(G_WITH_CYGWIN)
+#if defined(G_OS_BEOS)
extern const char *strsignal(int);
#else
/* this is declared differently (const) in string.h on BeOS */
[buildout]
extends =
../readline/buildout.cfg
../gmp/buildout.cfg
../nettle/buildout.cfg
../ncurses/buildout.cfg
../readline/buildout.cfg
../zlib/buildout.cfg
parts = gnutls
......@@ -22,14 +24,13 @@ environment =
LDFLAGS=-lgpg-error -L${gpg-error:location}/lib -Wl,-rpath=${gpg-error:location}/lib
[gnutls]
# XXX-Cedric : update to latest gnutls
recipe = slapos.recipe.cmmi
url = ftp://ftp.gnutls.org/gcrypt/gnutls/v2.8/gnutls-2.8.6.tar.bz2
md5sum = eb0a6d7d3cb9ac684d971c14f9f6d3ba
url = ftp://ftp.gnutls.org/gcrypt/gnutls/v3.2/gnutls-3.2.0.tar.xz
md5sum = e0cba4ddd923420026ff9739b3bc069a
configure-options =
--with-libgcrypt-prefix=${gcrypt:location}
--disable-static
environment =
CPPFLAGS=-I${zlib:location}/include -I${readline:location}/include -I${ncurses:location}/include -I${ncurses:location}/include/ncursesw -I${gcrypt:location}/include -I${gpg-error:location}/include
LDFLAGS=-lgcrypt -L${readline:location}/lib -Wl,-rpath=${readline:location}/lib -L${ncurses:location}/lib -Wl,-rpath=${ncurses:location}/lib -L${gcrypt:location}/lib -Wl,-rpath=${gcrypt:location}/lib -L${zlib:location}/lib -Wl,-rpath=${zlib:location}/lib -L${gpg-error:location}/lib -Wl,-rpath=${gpg-error:location}/lib
PKG_CONFIG=${zlib:location}/lib/pkgconfig
CPPFLAGS=-I${zlib:location}/include -I${readline:location}/include -I${ncurses:location}/include -I${ncurses:location}/include/ncursesw -I${gmp:location}/include -I${gcrypt:location}/include -I${gpg-error:location}/include -I${nettle:location}/include
LDFLAGS=-lgcrypt -L${gmp:location}/lib -Wl,-rpath=${gmp:location}/lib -L${readline:location}/lib -Wl,-rpath=${readline:location}/lib -L${ncurses:location}/lib -Wl,-rpath=${ncurses:location}/lib -L${gcrypt:location}/lib -Wl,-rpath=${gcrypt:location}/lib -L${nettle:location}/lib -Wl,-rpath=${nettle:location}/lib -L${zlib:location}/lib -Wl,-rpath=${zlib:location}/lib -L${gpg-error:location}/lib -Wl,-rpath=${gpg-error:location}/lib
[buildout]
extends =
../pcre/buildout.cfg
../coreutils/buildout.cfg
../xz-utils/buildout.cfg
parts =
grep
grep-output
[grep]
recipe = slapos.recipe.cmmi
......@@ -13,3 +14,11 @@ environment =
PATH=${xz-utils:location}/bin:%(PATH)s
CPPFLAGS=-I${pcre:location}/include
LDFLAGS=-L${pcre:location}/lib -Wl,-rpath=${pcre:location}/lib
[grep-output]
# Shared binary location to ease migration
recipe = plone.recipe.command
stop-on-error = true
update-command = ${:command}
command = ${coreutils-output:test} -x ${:grep}
grep = ${grep:location}/bin/grep
[buildout]
extends =
../autoconf/buildout.cfg
../automake/buildout.cfg
[make]
# make 3.82 breaks too many things. Stick with 3.81.
# See http://lists.gnu.org/archive/html/make-alpha/2010-07/msg00025.html
# for all incompatible changes.
# Moreover, vanilla 3.81 does some seg faults, so use Debian patched version.
<= make3.81-debian
[make-dfsg_3.81-8.2.diff]
# Debian patch coming from:
# http://ftp.de.debian.org/debian/pool/main/m/make-dfsg/make-dfsg_3.81-8.2.diff.gz
recipe = hexagonit.recipe.download
url = ${:_profile_base_location_}/${:_buildout_section_name_}
md5sum = fa77bb989a096fafbe7c78582e9415e3
download-only = true
[make3.81-debian]
recipe = slapos.recipe.cmmi
url = http://ftp.de.debian.org/debian/pool/main/m/make-dfsg/make-dfsg_3.81.orig.tar.gz
md5sum = 7c93b1ab4680eb21c2c13f4f47741e2d
patches =
${make-dfsg_3.81-8.2.diff:location}/make-dfsg_3.81-8.2.diff
patch-options = -p1
This diff is collapsed.
......@@ -18,10 +18,10 @@ parts =
[mariadb]
recipe = slapos.recipe.cmmi
version = 5.5.31
version = 5.5.32
revision = 1
url = http://downloads.askmonty.org/f/mariadb-${:version}/kvm-tarbake-jaunty-x86/mariadb-${:version}.tar.gz/from/http://ftp.osuosl.org/pub/mariadb
md5sum = 3fe756bc76f0e7a3af2757e48ce0f3f4
md5sum = 565c2dce6a2fb027c9d0ffbae4934135
# compile directory is required to build mysql plugins.
keep-compile-dir = true
patch-options = -p0
......
[buildout]
extends =
../gmp/buildout.cfg
../m4/buildout.cfg
[nettle-lib-location.patch]
recipe = hexagonit.recipe.download
download-only = true
filename = ${:_buildout_section_name_}
url = ${:_profile_base_location_}/${:filename}
md5sum = 41dd0ce2a73487929bdc637b75dd62c9
[nettle]
recipe = slapos.recipe.cmmi
url = http://www.lysator.liu.se/~nisse/archive/nettle-2.7.1.tar.gz
md5sum = 003d5147911317931dd453520eb234a5
patches =
${nettle-lib-location.patch:location}/${nettle-lib-location.patch:filename}
configure-option =
--disable-static
--disable-assembler
--disable-openssl
environment =
PATH=${m4:location}/bin:%(PATH)s
CPPFLAGS=-I${gmp:location}/include
LDFLAGS=-L${gmp:location}/lib -Wl,-rpath=${gmp:location}/lib
--- configure.orig 2013-07-05 15:37:28.000000000 +0200
+++ configure 2013-07-05 15:47:48.000000000 +0200
@@ -4680,52 +4680,6 @@
if test "x$ABI" != xstandard ; then
{ $as_echo "$as_me:${as_lineno-$LINENO}: Compiler uses $ABI-bit ABI. To change, set CC." >&5
$as_echo "$as_me: Compiler uses $ABI-bit ABI. To change, set CC." >&6;}
- if test "$libdir" = '${exec_prefix}/lib' ; then
- # Try setting a better default
- case "$host_cpu:$host_os:$ABI" in
- *:solaris*:32|*:sunos*:32)
- libdir='${exec_prefix}/lib'
- ;;
- *:solaris*:64|*:sunos*:64)
- libdir='${exec_prefix}/lib/64'
- ;;
- # Linux conventions are a mess... According to the Linux File
- # Hierarchy Standard, all architectures except IA64 puts 32-bit
- # libraries in lib, and 64-bit in lib64. Some distributions,
- # e.g., Fedora and Gentoo, adhere to this standard, while at
- # least Debian has decided to put 64-bit libraries in lib and
- # 32-bit libraries in lib32.
-
- # We try to figure out the convention, except if we're cross
- # compiling. We use lib${ABI} if /usr/lib${ABI} exists and
- # appears to not be a symlink to a different name.
- *:linux*:32|*:linux*:64)
- if test "$cross_compiling" = yes ; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Cross compiling for linux. Can't guess if libraries go in lib${ABI} or lib." >&5
-$as_echo "$as_me: WARNING: Cross compiling for linux. Can't guess if libraries go in lib${ABI} or lib." >&2;}; else
- # The dash builtin pwd tries to be "helpful" and remember
- # symlink names. Use -P option, and hope it's portable enough.
- test -d /usr/lib${ABI} \
- && (cd /usr/lib${ABI} && pwd -P | grep >/dev/null "/lib${ABI}"'$') \
- && libdir='${exec_prefix}/'"lib${ABI}"
- fi
- ;;
- # On freebsd, it seems 32-bit libraries are in lib32,
- # and 64-bit in lib. Don't know about "kfreebsd", does
- # it follow the Linux fhs conventions?
- *:freebsd*:32)
- libdir='${exec_prefix}/lib32'
- ;;
- *:freebsd*:64)
- libdir='${exec_prefix}/lib'
- ;;
- *)
- { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Don't know where to install $ABI-bit libraries on this system." >&5
-$as_echo "$as_me: WARNING: Don't know where to install $ABI-bit libraries on this system." >&2;};
- esac
- { $as_echo "$as_me:${as_lineno-$LINENO}: Libraries to be installed in $libdir." >&5
-$as_echo "$as_me: Libraries to be installed in $libdir." >&6;}
- fi
fi
# Select assembler code
......@@ -3,11 +3,14 @@ extends =
../pcre/buildout.cfg
../zlib/buildout.cfg
../openssl/buildout.cfg
../coreutils/buildout.cfg
parts = nginx-output
[nginx]
recipe = slapos.recipe.cmmi
url = http://nginx.org/download/nginx-1.2.7.tar.gz
md5sum = d252f5c689a14a668e241c744ccf5f06
url = http://nginx.org/download/nginx-1.5.3.tar.gz
md5sum = 1e735dd6a6ade2b5c20e924b67c3d355
configure-options=
--with-ipv6
--with-http_ssl_module
......@@ -16,6 +19,15 @@ configure-options=
--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-output]
# Shared binary location to ease migration
recipe = plone.recipe.command
stop-on-error = true
update-command = ${:command}
command = ${coreutils-output:test} -x ${:nginx} -a -f ${:mime}
nginx = ${nginx:location}/sbin/nginx
mime = ${nginx:location}/conf/mime.types
[nginx-unstable]
<= nginx
url = http://nginx.org/download/nginx-1.3.15.tar.gz
......
......@@ -8,9 +8,10 @@ extends =
../ca-certificates/buildout.cfg
../zlib/buildout.cfg
../patch/buildout.cfg
../coreutils/buildout.cfg
parts =
openssl
openssl-output
[openssl-nodoc.patch]
# Disable doc generation part in Makefile
......@@ -51,7 +52,7 @@ configure-options =
make-options =
-j1
make-targets =
install && rm -f ${buildout:parts-directory}/${:_buildout_section_name_}/etc/ssl/certs/* && for i in ${ca-certificates:location}/certs/*/*.crt; do ln -sv $i ${buildout:parts-directory}/${:_buildout_section_name_}/etc/ssl/certs/`${buildout:parts-directory}/${:_buildout_section_name_}/bin/openssl x509 -hash -noout -in $i`.0; done; true
all install_sw && rm -f ${buildout:parts-directory}/${:_buildout_section_name_}/etc/ssl/certs/* && for i in ${ca-certificates:location}/certs/*/*.crt; do ln -sv $i ${buildout:parts-directory}/${:_buildout_section_name_}/etc/ssl/certs/`${buildout:parts-directory}/${:_buildout_section_name_}/bin/openssl x509 -hash -noout -in $i`.0; done; true
[openssl:cygwin]
share = /usr
......@@ -62,3 +63,11 @@ promises =
/usr/bin/cygcrypto-1.0.0.dll
/usr/bin/cygssl-1.0.0.dll
/usr/include/openssl/x509.h
[openssl-output]
# Shared binary location to ease migration
recipe = plone.recipe.command
stop-on-error = true
update-command = ${:command}
command = ${coreutils-output:test} -x ${:openssl}
openssl = ${openssl:location}/bin/openssl
--- poptconfig.c~ 2011-09-10 22:49:30.802250000 +0800
+++ poptconfig.c 2011-09-10 23:46:30.572048000 +0800
@@ -45,8 +45,9 @@ extern int glob_pattern_p (const char *_
#if !defined(__GLIBC__)
/* Return nonzero if PATTERN contains any metacharacters.
Metacharacters can be quoted with backslashes if QUOTE is nonzero. */
+#define glob_pattern_p glob_pattern_p_s
static int
-glob_pattern_p (const char * pattern, int quote)
+glob_pattern_p_s(const char * pattern, int quote)
/*@*/
{
const char * p;
......@@ -44,6 +44,9 @@ configure-options =
--enable-unicode=ucs4
--with-system-expat
--with-threads
# Profiled build:
make-binary =
make-targets = make profile-opt && make install
# the entry "-Wl,-rpath=${file:location}/lib" below is needed by python-magic,
# which would otherwise load the system libmagic.so with ctypes
......
......@@ -8,6 +8,8 @@ parts =
[python-openssl]
recipe = zc.recipe.egg:custom
egg = pyOpenSSL
include-dirs =
${openssl:location}/include/
library-dirs =
${openssl:location}/lib/
rpath =
......
[buildout]
extends =
extends =
../../component/gnutls/buildout.cfg
../../component/libpng/buildout.cfg
../../component/libuuid/buildout.cfg
../../component/pkgconfig/buildout.cfg
../../component/xorg/buildout.cfg
../../component/zlib/buildout.cfg
[kvm]
# Backward compatibility
<= qemu-kvm
# XXX Change all reference to kvm section to qemu section, then
# use qemu as main name section.
[qemu]
<= kvm
[qemu-kvm]
[kvm]
recipe = slapos.recipe.cmmi
# qemu-kvm and qemu are now the same since 1.3.
url = http://wiki.qemu-project.org/download/qemu-1.4.1.tar.bz2
md5sum = eb2d696956324722b5ecfa46e41f9a75
url = http://wiki.qemu-project.org/download/qemu-1.5.1.tar.bz2
md5sum = b56e73bdcfdb214d5c68e13111aca96f
depends =
${libpng:so_version}
configure-options =
--target-list=""
--target-list=x86_64-softmmu
--enable-system
--with-system-pixman
--disable-sdl
--disable-xen
--enable-vnc-tls
......@@ -36,4 +40,27 @@ configure-options =
environment =
PATH=${pkgconfig:location}/bin:%(PATH)s
PKG_CONFIG_PATH=${gnutls:location}/lib/pkgconfig:${glib:location}/lib/pkgconfig:${pixman:location}/lib/pkgconfig
LDFLAGS=-L${pixman:location}/lib -Wl,-rpath=${pixman:location}/lib
# The following is only available in buildout2, which we don't use yet.
[kvm-bits64]
configure-options =
--target-list=x86_64-softmmu
${kvm:configure-options}
[kvm-bits32]
configure-options =
--target-list=i386-softmmu
${kvm:configure-options}
[debian-amd64-netinst.iso]
# Download the installer of Debian 7 (Wheezy)
recipe = hexagonit.recipe.download
url = http://cdimage.debian.org/debian-cd/7.1.0/amd64/iso-cd/debian-7.1.0-amd64-netinst.iso
filename = ${:_buildout_section_name_}
md5sum = 80f498a1f9daa76bc911ae13692e4495
download-only = true
mode = 0644
location = ${buildout:parts-directory}/${:_buildout_section_name_}
[buildout]
extends =
../librsync/buildout.cfg
../coreutils/buildout.cfg
parts =
rdiff-backup
rdiff-backup-output
[rdiff-backup-build]
recipe = zc.recipe.egg:custom
......@@ -34,3 +35,11 @@ configure-options =
prep
compile
make-options = -C rdiff-backup-1.2.8-5/build
[rdiff-backup-output]
# Shared binary location to ease migration
recipe = plone.recipe.command
stop-on-error = true
update-command = ${:command}
command = ${coreutils-output:test} -x ${:rdiff-backup}
rdiff-backup = ${buildout:directory}/bin/rdiff-backup
# Squid: Optimising Web Delivery
# http://squid-cache.org
[buildout]
parts =
squid
extends =
../pkgconfig/buildout.cfg
[squid]
recipe = hexagonit.recipe.cmmi
url = http://www.squid-cache.org/Versions/v3/3.2/squid-3.2.1.tar.gz
md5sum = 3fb81acc6b70a432e3f0d8a0491056dc
configure-options =
--disable-dependency-tracking
--disable-translation
--disable-htcp
--disable-snmp
--disable-loadable-modules
--disable-icmp
--disable-esi
--disable-icap-client
--disable-wccp
--disable-wccpv2
--disable-eui
--enable-http-violations
--disable-ipfw-transparent
--disable-ipf-transparent
--disable-pf-transparent
--disable-linux-netfilter
--enable-follow-x-forwarded-for
--disable-auth
--disable-url-rewrite-helpers
--disable-auto-locale
--disable-kerberos
--enable-x-accelerator-vary
--disable-external-acl-helpers
--disable-auth-ntlm
--with-krb5-config=no
Environment =
PATH=${pkgconfig:location}/bin:%(PATH)s
[buildout]
extends =
../ncurses/buildout.cfg
[texinfo]
# Most other components are not happy with texinfo 5, because it treats some
# used-to-be-warnings as errors.
<= texinfo4
[texinfo4]
recipe = slapos.recipe.cmmi
url = http://ftp.gnu.org/gnu/texinfo/texinfo-4.13.tar.gz
md5sum = 71ba711519209b5fb583fed2b3d86fcb
configure-options =
--disable-static
environment =
CFLAGS=-I${ncurses:location}/include
LDFLAGS=-L${ncurses:location}/lib -Wl,-rpath=${ncurses:location}/lib
[buildout]
extends =
../libtool/buildout.cfg
../libuuid/buildout.cfg
[zeromq]
<= zeromq3
[zeromq3]
recipe = slapos.recipe.cmmi
url = http://download.zeromq.org/zeromq-3.2.3.tar.gz
md5sum = 1abf8246363249baf5931a065ee38203
configure-options = --without-documentation
environment =
PATH=${libtool:location}/bin:%(PATH)s
LDFLAGS=-L${libtool:location}/lib -Wl,-rpath -Wl,${libtool:location}/lib -L${libuuid:location}/lib -Wl,-rpath -Wl,${libuuid:location}/lib
[zeromq2]
recipe = slapos.recipe.cmmi
url = http://download.zeromq.org/zeromq-2.2.0.tar.gz
md5sum = 1b11aae09b19d18276d0717b2ea288f6
configure-options =
--without-documentation
environment =
PATH=${libtool:location}/bin:%(PATH)s
CXXFLAGS=-I${libuuid:location}/include
LDFLAGS=-L${libtool:location}/lib -Wl,-rpath -Wl,${libtool:location}/lib -L${libuuid:location}/lib -Wl,-rpath -Wl,${libuuid:location}/lib
......@@ -28,7 +28,7 @@ from setuptools import setup, find_packages
import glob
import os
version = '0.78.2.dev'
version = '0.83.1'
name = 'slapos.cookbook'
long_description = open("README.txt").read() + "\n" + \
open("CHANGES.txt").read() + "\n"
......@@ -70,7 +70,6 @@ setup(name=name,
'zc.buildout': [
'addresiliency = slapos.recipe.addresiliency:Recipe',
'agent = slapos.recipe.agent:Recipe',
'apache.frontend = slapos.recipe.apache_frontend:Recipe',
'apache.zope.backend = slapos.recipe.apache_zope_backend:Recipe',
'apacheperl = slapos.recipe.apacheperl:Recipe',
'apachephp = slapos.recipe.apachephp:Recipe',
......@@ -165,8 +164,7 @@ setup(name=name,
'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',
'readline = slapos.recipe.readline:Recipe',
'redis.server = slapos.recipe.redis:Recipe',
'request = slapos.recipe.request:Recipe',
'request.serialised = slapos.recipe.request:Serialised',
......@@ -192,6 +190,7 @@ setup(name=name,
'slaprunner.import = slapos.recipe.slaprunner.backup:ImportRecipe',
'softwaretype = slapos.recipe.softwaretype:Recipe',
'sphinx= slapos.recipe.sphinx:Recipe',
'squid = slapos.recipe.squid:Recipe',
'sshkeys_authority = slapos.recipe.sshkeys_authority:Recipe',
'sshkeys_authority.request = slapos.recipe.sshkeys_authority:Request',
'stunnel = slapos.recipe.stunnel:Recipe',
......
......@@ -12,15 +12,14 @@ On slap console, you can instanciate varnish like this:
instance = request(
software_type='varnish',
partition_parameter_kw={
'tidstorage-url':'http://[your tidstrage address]:your tid strage port',
'backend-url':'https://[your_backend_address]:your_backend_port',
'web-checker-frontend-url':'http://www.example.com',
'web-checker-mail-address':'web-checker-result@example.com',
'web-checker-smtp-host':'mail.example.com',
}
)
tidstrage-url is the backend url that varnish will cache. It is expected that
the backend is created by tidstorage recipe.
backend-url is the backend url that varnish will cache.
web-checker-frontend-url is the entry-point-url that web checker will check
the HTTP headers of all the pages in the web site.
......
......@@ -31,10 +31,10 @@ KVM with Remote and gzipped Image
gzip = true
# Use -hda instead -drive arg
# Default is drive (see Options bellow)
# Default is drive (see Options below)
image_type = hda
### Common Configuration bellow. ###
### Common Configuration below. ###
# VNC is optional
kvm_vnc = <SOME-IP>:<VNC-DISPLAY>
......
# -*- coding: utf-8 -*-
import logging
import time
import slapos
log = logging.getLogger(__name__)
logging.basicConfig(level=logging.DEBUG)
class Renamer(object):
def __init__(self, server_url, key_file, cert_file, computer_guid,
partition_id, software_release, namebase):
self.server_url = server_url
self.key_file = key_file
self.cert_file = cert_file
self.computer_guid = computer_guid
self.partition_id = partition_id
self.software_release = software_release
self.namebase = namebase
def _failover(self):
"""\
This method does
- retrieve the broken computer partition
- change its reference to 'broken-...' and its software type to 'frozen'
- retrieve the winner computer partition (attached to this process)
- change its reference to replace the broken one.
later, slapgrid will change its software_type as well.
Then, after running slapgrid-cp a few times, the winner takes over and
a new cp is created to replace it as an importer.
"""
slap = slapos.slap.slap()
slap.initializeConnection(self.server_url, self.key_file, self.cert_file)
# partition that will take over.
cp_winner = slap.registerComputerPartition(computer_guid=self.computer_guid,
partition_id=self.partition_id)
# XXX although we can already rename cp_winner, to change its software type we need to
# get hold of the root cp as well
cp_exporter_ref = self.namebase + '0' # this is ok. the boss is always number zero.
# partition to be deactivated
cp_broken = cp_winner.request(software_release=self.software_release,
software_type='frozen',
state='stopped',
partition_reference=cp_exporter_ref)
broken_new_ref = 'broken-{}'.format(time.strftime("%d-%b_%H:%M:%S", time.gmtime()))
log.debug("Renaming {}: {}".format(cp_broken.getId(), broken_new_ref))
cp_broken.rename(new_name=broken_new_ref)
cp_broken.stopped()
log.debug("Renaming {}: {}".format(cp_winner.getId(), cp_exporter_ref))
# update name (and later, software type) for the partition that will take over
cp_winner.rename(new_name=cp_exporter_ref)
cp_winner.bang(message='partitions have been renamed!')
def failover(self):
try:
self._failover()
log.info('Renaming done')
except slapos.slap.ServerError:
log.info('Internal server error')
# -*- coding: utf-8 -*-
import logging
import time
import slapos.recipe.addresiliency.renamer
import slapos
from slapos.slap.slap import NotFoundError
def run(args):
renamer = slapos.recipe.addresiliency.renamer.Renamer(server_url = args.pop('server_url'),
key_file = args.pop('key_file'),
cert_file = args.pop('cert_file'),
computer_guid = args.pop('computer_id'),
partition_id = args.pop('partition_id'),
software_release = args.pop('software'),
namebase = args.pop('namebase'))
log = logging.getLogger(__name__)
logging.basicConfig(level=logging.DEBUG)
def takeover(server_url, key_file, cert_file, computer_guid,
partition_id, software_release, namebase,
winner_instance_suffix = None):
"""
This function does
- retrieve the broken computer partition
- change its reference to 'broken-...' and its software type to 'frozen'
- retrieve the winner computer partition (attached to this process)
- change its reference to replace the broken one.
later, slapgrid will change its software_type as well.
Then, after running slapgrid-cp a few times, the winner takes over and
a new cp is created to replace it as an importer.
"""
slap = slapos.slap.slap()
slap.initializeConnection(server_url, key_file, cert_file)
current_partition = slap.registerComputerPartition(computer_guid=computer_guid,
partition_id=partition_id)
# partition that will take over.
if winner_instance_suffix:
winner_instance_name = namebase + winner_instance_suffix
# XXX: we hardcode a lot of values here, because request is a settergetter, all at once.
cp_winner = current_partition.request(software_release=software_release,
software_type='%s-import' % namebase,
partition_reference=winner_instance_name)
else:
# This script is run in the winning partition: use this one as winner
cp_winner = current_partition
# XXX although we can already rename cp_winner, to change its software type we need to
# get hold of the root cp as well
cp_exporter_ref = namebase + '0' # this is ok. the boss is always number zero.
renamer.failover()
# partition to be deactivated
cp_broken = cp_winner.request(software_release=software_release,
software_type='frozen',
state='stopped',
partition_reference=cp_exporter_ref)
broken_new_ref = 'broken-{}'.format(time.strftime("%d-%b_%H:%M:%S", time.gmtime()))
log.debug("Renaming {}: {}".format(cp_broken.getId(), broken_new_ref))
cp_broken.rename(new_name=broken_new_ref)
log.debug("Renaming {}: {}".format(cp_winner.getId(), cp_exporter_ref))
# update name (and later, software type) for the partition that will take over
while True:
time.sleep(10)
try:
cp_winner.rename(new_name=cp_exporter_ref)
break
except NotFoundError:
log.warning('Impossible to rename. Retrying in a few seconds...')
log.debug('Renamed.')
cp_winner.bang(message='partitions have been renamed!')
# Note: Root instance will reconfigure itself the winning instance (software_type
# and parameters.)
def run(args):
slapos.recipe.addresiliency.takeover.takeover(server_url = args.pop('server_url'),
key_file = args.pop('key_file'),
cert_file = args.pop('cert_file'),
computer_guid = args.pop('computer_id'),
partition_id = args.pop('partition_id'),
software_release = args.pop('software'),
namebase = args.pop('namebase'))
This diff is collapsed.
import os
import subprocess
import time
import ConfigParser
import uuid
def popenCommunicate(command_list, input=None):
subprocess_kw = dict(stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
if input is not None:
subprocess_kw.update(stdin=subprocess.PIPE)
popen = subprocess.Popen(command_list, **subprocess_kw)
result = popen.communicate(input)[0]
if popen.returncode is None:
popen.kill()
if popen.returncode != 0:
raise ValueError('Issue during calling %r, result was:\n%s' % (
command_list, result))
return result
class CertificateAuthority:
def __init__(self, key, certificate, openssl_binary,
openssl_configuration, request_dir):
self.key = key
self.certificate = certificate
self.openssl_binary = openssl_binary
self.openssl_configuration = openssl_configuration
self.request_dir = request_dir
def checkAuthority(self):
file_list = [ self.key, self.certificate ]
ca_ready = True
for f in file_list:
if not os.path.exists(f):
ca_ready = False
break
if ca_ready:
return
for f in file_list:
if os.path.exists(f):
os.unlink(f)
try:
# no CA, let us create new one
popenCommunicate([self.openssl_binary, 'req', '-nodes', '-config',
self.openssl_configuration, '-new', '-x509', '-extensions', 'v3_ca',
'-keyout', self.key, '-out', self.certificate, '-days', '10950'],
# Authority name will be random, so no instance has the same issuer
'Certificate Authority %s\n' % uuid.uuid1())
except:
try:
for f in file_list:
if os.path.exists(f):
os.unlink(f)
except:
# do not raise during cleanup
pass
raise
def _checkCertificate(self, common_name, key, certificate):
file_list = [key, certificate]
ready = True
for f in file_list:
if not os.path.exists(f):
ready = False
break
if ready:
return False
for f in file_list:
if os.path.exists(f):
os.unlink(f)
csr = certificate + '.csr'
try:
popenCommunicate([self.openssl_binary, 'req', '-config',
self.openssl_configuration, '-nodes', '-new', '-keyout',
key, '-out', csr, '-days', '3650'],
common_name + '\n')
try:
popenCommunicate([self.openssl_binary, 'ca', '-batch', '-config',
self.openssl_configuration, '-out', certificate,
'-infiles', csr])
finally:
if os.path.exists(csr):
os.unlink(csr)
except:
try:
for f in file_list:
if os.path.exists(f):
os.unlink(f)
except:
# do not raise during cleanup
pass
raise
else:
return True
def checkRequestDir(self):
for request_file in os.listdir(self.request_dir):
parser = ConfigParser.RawConfigParser()
parser.readfp(open(os.path.join(self.request_dir, request_file), 'r'))
if self._checkCertificate(parser.get('certificate', 'name'),
parser.get('certificate', 'key_file'), parser.get('certificate',
'certificate_file')):
print 'Created certificate %r' % parser.get('certificate', 'name')
def runCertificateAuthority(args):
ca_conf = args[0]
ca = CertificateAuthority(ca_conf['key'], ca_conf['certificate'],
ca_conf['openssl_binary'], ca_conf['openssl_configuration'],
ca_conf['request_dir'])
while True:
ca.checkAuthority()
ca.checkRequestDir()
time.sleep(60)
<Directory %(path)s>
Order Deny,Allow
Allow from %(access_control_string)s
</Directory>
<Directory %(document_root)s>
Order Allow,Deny
Allow from All
</Directory>
<Location %(location)s>
Order Deny,Allow
Deny from all
Allow from %(allow_string)s
</Location>
SSLCertificateFile %(login_certificate)s
SSLCertificateKeyFile %(login_key)s
SSLRandomSeed startup builtin
SSLRandomSeed connect builtin
SSLSessionCache shmcb:/%(httpd_mod_ssl_cache_directory)s/ssl_scache(512000)
SSLSessionCacheTimeout 300
SSLRandomSeed startup /dev/urandom 256
SSLRandomSeed connect builtin
SSLProtocol -ALL +SSLv3 +TLSv1
SSLHonorCipherOrder On
SSLCipherSuite RC4-SHA:HIGH:!ADH
<FilesMatch "\.(cgi|shtml|phtml|php)$">
SSLOptions +StdEnvVars
</FilesMatch>
# Accept proxy to sites using self-signed SSL certificates
SSLProxyCheckPeerCN off
SSLProxyCheckPeerExpire off
%(file_list)s {
daily
dateext
rotate 30
compress
notifempty
sharedscripts
create
postrotate
%(postrotate)s
endscript
olddir %(olddir)s
}
[%(name)s]
accept = %(public_ip)s:%(public_port)s
connect = %(private_ip)s:%(private_port)s
foreground = yes
output = %(log)s
pid = %(pid_file)s
syslog = no
client = yes
CApath = %(ca_path)s
key = %(key)s
CRLpath = %(ca_crl)s
cert = %(cert)s
sslVersion = SSLv3
socket = l:TCP_NODELAY=1
socket = r:TCP_NODELAY=1
%(entry_str)s
# This is a basic VCL configuration file for varnish. See the vcl(7)
# man page for details on VCL syntax and semantics.
#
# Default backend definition. Set this to point to your content
# server.
#
backend default {
.host = "%(backend_host)s";
.port = "%(backend_port)s";
.probe = {
.url = "/";
.timeout = 10s;
.interval = 10s;
.window = 4;
.threshold = 3;
}
}
#
# Below is a commented-out copy of the default VCL logic. If you
# redefine any of these subroutines, the built-in logic will be
# appended to your code.
#
# sub vcl_recv {
# if (req.http.x-forwarded-for) {
# set req.http.X-Forwarded-For =
# req.http.X-Forwarded-For ", " client.ip;
# } else {
# set req.http.X-Forwarded-For = client.ip;
# }
# if (req.request != "GET" &&
# req.request != "HEAD" &&
# req.request != "PUT" &&
# req.request != "POST" &&
# req.request != "TRACE" &&
# req.request != "OPTIONS" &&
# req.request != "DELETE") {
# /* Non-RFC2616 or CONNECT which is weird. */
# return (pipe);
# }
# if (req.request != "GET" && req.request != "HEAD") {
# /* We only deal with GET and HEAD by default */
# return (pass);
# }
# if (req.http.Authorization || req.http.Cookie) {
# /* Not cacheable by default */
# return (pass);
# }
# return (lookup);
# }
sub vcl_recv {
if (req.http.cache-control ~ "no-cache") {
purge_url(req.url);
}
if (req.url ~ "\.(css|js|ico)$") {
unset req.http.cookie;
}
# remove bogus cookies
if (req.http.Cookie) {
set req.http.Cookie = regsuball(req.http.Cookie, "(^|; ) *__utm.=[^;]+;? *", "\1");
set req.http.Cookie = regsuball(req.http.Cookie, "(^|; ) *__ac_name=\x22\x22;? *", "\1");
set req.http.Cookie = regsuball(req.http.Cookie, "(^|; ) *__ac=\x22Og.3D.3D\x22;? *", "\1");
}
if (req.http.Cookie == "") {
remove req.http.Cookie;
}
if (req.http.x-forwarded-for) {
set req.http.X-Forwarded-For =
req.http.X-Forwarded-For ", " client.ip;
} else {
set req.http.X-Forwarded-For = client.ip;
}
if (req.request != "GET" &&
req.request != "HEAD" &&
req.request != "PUT" &&
req.request != "POST" &&
req.request != "TRACE" &&
req.request != "OPTIONS" &&
req.request != "DELETE") {
/* Non-RFC2616 or CONNECT which is weird. */
return (pipe);
}
if (req.request != "GET" && req.request != "HEAD") {
/* We only deal with GET and HEAD by default */
return (pass);
}
if (req.http.Authorization) {
/* Not cacheable by default */
return (pass);
}
if (req.http.Cookie && req.http.Cookie ~ "(^|; ) *__ac=") {
/* Not cacheable for authorised users,
but KM images are cacheable */
if (!(req.url ~ "/km_img/.*\.(png|gif)$")) {
return (pass);
}
}
# XXX login form can defer based on __ac_name cookie value
if (req.url ~ "/(login_form|WebSite_viewLoginDialog)($|\?)") {
return (pass);
}
if (req.backend.healthy) {
set req.grace = 1h;
} else {
set req.grace = 1w;
}
return (lookup);
}
#
# sub vcl_pipe {
# # Note that only the first request to the backend will have
# # X-Forwarded-For set. If you use X-Forwarded-For and want to
# # have it set for all requests, make sure to have:
# # set req.http.connection = "close";
# # here. It is not set by default as it might break some broken web
# # applications, like IIS with NTLM authentication.
# return (pipe);
# }
#
# sub vcl_pass {
# return (pass);
# }
#
# sub vcl_hash {
# set req.hash += req.url;
# if (req.http.host) {
# set req.hash += req.http.host;
# } else {
# set req.hash += server.ip;
# }
# return (hash);
# }
#
# sub vcl_hit {
# if (!obj.cacheable) {
# return (pass);
# }
# return (deliver);
# }
#
# sub vcl_miss {
# return (fetch);
# }
#
# sub vcl_fetch {
# if (!beresp.cacheable) {
# return (pass);
# }
# if (beresp.http.Set-Cookie) {
# return (pass);
# }
# return (deliver);
# }
sub vcl_fetch {
# we only cache 200 (OK) and 304 (Not Modified) responses.
if (beresp.status != 200 && beresp.status != 304) {
set beresp.cacheable = false;
}
if (beresp.http.cache-control ~ "no-cache") {
set beresp.cacheable = false;
}
if (!beresp.cacheable) {
unset beresp.http.expires;
set beresp.http.cache-control = "no-cache";
return (pass);
}
# we don't care haproxy's cookie.
if (beresp.http.Set-Cookie && beresp.http.Set-Cookie !~ "^SERVERID=[^;]+; path=/$") {
return (pass);
}
if (req.url ~ "\.(css|js|ico)$") {
unset beresp.http.set-cookie;
set beresp.http.cache-control = regsub(beresp.http.cache-control, "^", "public,");
set beresp.http.cache-control = regsub(beresp.http.cache-control, ",$", "");
}
# remove some headers added by caching policy manager to avoid
# '304 Not Modified' in case of login <-> logout switching.
if (beresp.http.content-type ~ "^text/html") {
unset beresp.http.last-modified;
}
if (beresp.cacheable) {
/* Remove Expires from backend, it's not long enough */
unset beresp.http.expires;
/* Set the clients TTL on this object */
set beresp.http.cache-control = "max-age = 900";
/* Set how long Varnish will keep it */
set beresp.ttl = 1w;
/* marker for vcl_deliver to reset Age: */
set beresp.http.magicmarker = "1";
}
set beresp.grace = 1w;
return (deliver);
}
#
# sub vcl_deliver {
# return (deliver);
# }
sub vcl_deliver {
if (resp.http.magicmarker) {
/* Remove the magic marker */
unset resp.http.magicmarker;
/* By definition we have a fresh object */
set resp.http.age = "0";
}
if (obj.hits > 0) {
set resp.http.X-Cache = obj.hits;
} else {
set resp.http.X-Cache = "MISS";
}
return (deliver);
}
#
# sub vcl_error {
# set obj.http.Content-Type = "text/html; charset=utf-8";
# synthetic {"
# <?xml version="1.0" encoding="utf-8"?>
# <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
# "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
# <html>
# <head>
# <title>"} obj.status " " obj.response {"</title>
# </head>
# <body>
# <h1>Error "} obj.status " " obj.response {"</h1>
# <p>"} obj.response {"</p>
# <h3>Guru Meditation:</h3>
# <p>XID: "} req.xid {"</p>
# <hr>
# <p>Varnish cache server</p>
# </body>
# </html>
# "};
# return (deliver);
# }
......@@ -103,16 +103,27 @@ class Request(Recipe):
key_file = self.options['key-file']
cert_file = self.options['cert-file']
key_content = self.options.get('key-content', None)
cert_content = self.options.get('cert-content', None)
request_needed = True
name = self.options['name']
hash_ = hashlib.sha512(name).hexdigest()
key = os.path.join(self.ca_private, hash_ + self.ca_key_ext)
certificate = os.path.join(self.ca_certs, hash_ + self.ca_crt_ext)
parser = ConfigParser.RawConfigParser()
parser.add_section('certificate')
parser.set('certificate', 'name', name)
parser.set('certificate', 'key_file', key)
parser.set('certificate', 'certificate_file', certificate)
parser.write(open(os.path.join(self.request_directory, hash_), 'w'))
# XXX Ugly hack to quickly provide custom certificate/key to everyone using the recipe
if key_content and cert_content:
open(key, 'w').write(key_content)
open(certificate, 'w').write(cert_content)
request_needed = False
else:
parser = ConfigParser.RawConfigParser()
parser.add_section('certificate')
parser.set('certificate', 'name', name)
parser.set('certificate', 'key_file', key)
parser.set('certificate', 'certificate_file', certificate)
parser.write(open(os.path.join(self.request_directory, hash_), 'w'))
for link in [key_file, cert_file]:
if os.path.islink(link):
......@@ -123,11 +134,14 @@ class Request(Recipe):
os.symlink(key, key_file)
os.symlink(certificate, cert_file)
wrapper = self.createPythonScript(
self.options['wrapper'],
'slapos.recipe.librecipe.execute.execute_wait',
[ [self.options['executable']],
[certificate, key] ],
)
path_list = [key_file, cert_file]
if request_needed:
wrapper = self.createPythonScript(
self.options['wrapper'],
'slapos.recipe.librecipe.execute.execute_wait',
[ [self.options['executable']],
[certificate, key] ],
)
path_list.append(wrapper)
return [key_file, cert_file, wrapper]
return path_list
......@@ -37,6 +37,7 @@ class Recipe(GenericBaseRecipe):
'url': self.options['url'],
'shell_path': self.options['dash_path'],
'curl_path': self.options['curl_path'],
'check_secure': self.options.get('check-secure', 0)
}
# XXX-Cedric in this script, curl won't check certificate
......
......@@ -31,6 +31,13 @@ if [ $CODE -eq 000 ]; then
exit 1
fi
if [ %(check_secure)s -eq 1 ]; then
if [ $CODE -eq 401 ]; then
echo "$URL is protected (returned $CODE)." >&2
exit 0
fi
fi
if ! [ $CODE -eq 200 ]; then
echo "$URL is not available (returned $CODE)." >&2
exit 2
......
......@@ -27,6 +27,8 @@
import subprocess
import httplib
import base64
import os
import shutil
from slapos.recipe.librecipe import GenericBaseRecipe
......@@ -50,13 +52,29 @@ class Recipe(GenericBaseRecipe):
user, password
])
htdocs_location = self.options['htdocs']
if not (os.path.exists(htdocs_location) and os.listdir(htdocs_location)):
try:
os.rmdir(htdocs_location)
except:
pass
shutil.copytree(self.options['source'], 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)
apache_config = dict(
pid_file=self.options['pid-file'],
lock_file=self.options['lock-file'],
davlock_db=self.options['davdb-lock'],
ip=self.options['ip'],
port=self.options['port'],
port_webdav=self.options['port_webdav'],
port_ajax=self.options['port_ajax'],
error_log=self.options['error-log'],
access_log=self.options['access-log'],
document_root=self.options['htdocs'],
......@@ -67,6 +85,7 @@ class Recipe(GenericBaseRecipe):
htpasswd_file=htpasswd_file,
ssl_certificate=self.options['cert-file'],
ssl_key=self.options['key-file'],
php_ini_dir=self.options['php-ini-dir']
)
# Create logfiles
......@@ -86,7 +105,7 @@ class Recipe(GenericBaseRecipe):
promise = self.createPythonScript(self.options['promise'],
__name__ + '.promise',
dict(host=self.options['ip'], port=int(self.options['port']),
dict(host=self.options['ip'], port=int(self.options['port_webdav']),
user=self.options['user'], password=self.options['password'])
)
path_list.append(promise)
......
ServerRoot "%(server_root)s"
Listen [%(ip)s]:%(port)s
Listen [%(ip)s]:%(port_webdav)s
Listen [%(ip)s]:%(port_ajax)s
NameVirtualHost [%(ip)s]:%(port_webdav)s
NameVirtualHost [%(ip)s]:%(port_ajax)s
# Needed 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 unixd_module "%(modules_dir)s/mod_unixd.so"
LoadModule access_compat_module "%(modules_dir)s/mod_access_compat.so"
LoadModule authn_core_module "%(modules_dir)s/mod_authn_core.so"
LoadModule authz_core_module "%(modules_dir)s/mod_authz_core.so"
LoadModule authn_file_module "%(modules_dir)s/mod_authn_file.so"
LoadModule authz_host_module "%(modules_dir)s/mod_authz_host.so"
LoadModule authz_user_module "%(modules_dir)s/mod_authz_user.so"
LoadModule auth_basic_module "%(modules_dir)s/mod_auth_basic.so"
LoadModule auth_digest_module "%(modules_dir)s/mod_auth_digest.so"
# Comment auth_digest since we don't use it
#LoadModule auth_digest_module "%(modules_dir)s/mod_auth_digest.so"
LoadModule log_config_module "%(modules_dir)s/mod_log_config.so"
LoadModule headers_module "%(modules_dir)s/mod_headers.so"
LoadModule setenvif_module "%(modules_dir)s/mod_setenvif.so"
LoadModule socache_shmcb_module modules/mod_socache_shmcb.so
LoadModule socache_shmcb_module "%(modules_dir)s/mod_socache_shmcb.so"
LoadModule ssl_module "%(modules_dir)s/mod_ssl.so"
LoadModule mime_module "%(modules_dir)s/mod_mime.so"
LoadModule dav_module "%(modules_dir)s/mod_dav.so"
LoadModule dav_fs_module "%(modules_dir)s/mod_dav_fs.so"
LoadModule dir_module "%(modules_dir)s/mod_dir.so"
LoadModule php5_module "%(modules_dir)s/libphp5.so"
ServerAdmin %(email_address)s
# Quiet Server header (if not, Apache give its life history)
# It's safer
ServerTokens ProductOnly
PidFile "%(pid_file)s"
PHPINIDir "%(php_ini_dir)s"
SSLRandomSeed startup builtin
SSLRandomSeed connect builtin
<VirtualHost [%(ip)s]:%(port_ajax)s>
#ServerName www.example.com
# 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
SSLEngine on
SSLCertificateFile "%(ssl_certificate)s"
SSLCertificateKeyFile "%(ssl_key)s"
</VirtualHost>
<VirtualHost [%(ip)s]:%(port_webdav)s>
DocumentRoot "%(document_root)s"
PidFile "%(pid_file)s"
DavLockDB "%(davlock_db)s"
<Directory />
......@@ -66,6 +103,12 @@ DavLockDB "%(davlock_db)s"
</Directory>
SSLEngine on
SSLCertificateFile "%(ssl_certificate)s"
SSLCertificateKeyFile "%(ssl_key)s"
</VirtualHost>
ErrorLog "%(error_log)s"
LogLevel warn
......@@ -77,9 +120,5 @@ DefaultType text/plain
TypesConfig "%(mime_types)s"
AddType application/x-compress .Z
AddType application/x-gzip .gz .tgz
SSLRandomSeed startup builtin
SSLRandomSeed connect builtin
SSLEngine on
SSLCertificateFile "%(ssl_certificate)s"
SSLCertificateKeyFile "%(ssl_key)s"
AddType application/x-httpd-php .php .phtml .php5 .php4
AddType application/x-httpd-php-source .phps
\ No newline at end of file
[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
output_buffering=Off
\ No newline at end of file
......@@ -26,7 +26,11 @@
##############################################################################
import os
from slapos.recipe.librecipe import GenericBaseRecipe
if __name__ == '__main__': # Hack to easily run test below.
GenericBaseRecipe = object
else:
from slapos.recipe.librecipe import GenericBaseRecipe
from zc.buildout import UserError
class Recipe(GenericBaseRecipe):
......@@ -51,18 +55,117 @@ class Recipe(GenericBaseRecipe):
return [script]
class Part(GenericBaseRecipe):
def install(self):
try:
periodicity = self.options['frequency']
except KeyError:
periodicity = self.options['time']
try:
periodicity = systemd_to_cron(periodicity)
except Exception:
raise UserError("Invalid systemd calendar spec %r" % periodicity)
cron_d = self.options['cron-entries']
name = self.options['name']
filename = os.path.join(cron_d, name)
with open(filename, 'w') as part:
part.write('%(frequency)s %(command)s\n' % {
'frequency': self.options['frequency'],
'command': self.options['command'],
})
part.write('%s %s\n' % (periodicity, self.options['command']))
return [filename]
day_of_week_dict = dict((name, dow) for dow, name in enumerate(
"sunday monday tuesday wednesday thursday friday saturday".split())
for name in (name, name[:3]))
symbolic_dict = dict(hourly = '0 * * * *',
daily = '0 0 * * *',
monthly = '0 0 1 * *',
weekly = '0 0 * * 0')
def systemd_to_cron(spec):
"""Convert from systemd.time(7) calendar spec to crontab spec"""
try:
return symbolic_dict[spec]
except KeyError:
pass
if not spec.strip():
raise ValueError
spec = spec.split(' ')
try:
dow = ','.join(sorted('-'.join(str(day_of_week_dict[x.lower()])
for x in x.split('-', 1))
for x in spec[0].split(',')
if x))
del spec[0]
except KeyError:
dow = '*'
day = spec.pop(0) if spec else '*-*'
if spec:
time, = spec
elif ':' in day:
time = day
day = '*-*'
else:
time = '0:0'
day = day.split('-')
time = time.split(':')
if (# years not supported
len(day) > 2 and day.pop(0) != '*' or
# some crons ignore day of month if day of week is given, and dcron
# treats day of month in a way that is not compatible with systemd
dow != '*' != day[1] or
# seconds not supported
len(time) > 2 and int(time.pop())):
raise ValueError
month, day = day
hour, minute = time
spec = minute, hour, day, month, dow
for x, (y, z) in zip(spec, ((0, 60), (0, 24), (1, 31), (1, 12))):
if x != '*':
for x in x.split(','):
x = map(int, x.split('/', 1))
x[0] -= y
if x[0] < 0 or len(x) > 1 and x[0] >= x[1] or z <= sum(x):
raise ValueError
return ' '.join(spec)
def test(self):
def _(systemd, cron):
self.assertEqual(systemd_to_cron(systemd), cron)
_("Sat,Mon-Thu,Sun", "0 0 * * 0,1-4,6")
_("mon,sun *-* 2,1:23", "23 2,1 * * 0,1")
_("Wed, 17:48", "48 17 * * 3")
_("Wed-Sat,Tue 10-* 1:2", "2 1 * 10 2,3-6")
_("*-*-7 0:0:0", "0 0 7 * *")
_("10-15", "0 0 15 10 *")
_("monday *-12-* 17:00", "00 17 * 12 1")
_("12,14,13,12:20,10,30", "20,10,30 12,14,13,12 * * *") # TODO: sort
_("*-1/2-1,3 *:30", "30 * 1,3 1/2 *")
_("03-05 08:05", "05 08 05 03 *")
_("08:05:00", "05 08 * * *")
_("05:40", "40 05 * * *")
_("Sat,Sun 12-* 08:05", "05 08 * 12 0,6")
_("Sat,Sun 08:05", "05 08 * * 0,6")
def _(systemd):
self.assertRaises(Exception, systemd_to_cron, systemd)
_("test")
_("")
_("7")
_("121212:1:2")
_("Wed *-1")
_("08:05:40")
_("2003-03-05")
_("0-1"); _("13-1"); _("6/4-1"); _("5/8-1")
_("1-0"); _("1-32"); _("1-4/3"); _("1-14/18")
_("24:0");_("9/9:0"); _("8/16:0")
_("0:60"); _("0:22/22"); _("0:15/45")
if __name__ == '__main__':
import unittest
unittest.TextTestRunner().run(type('', (unittest.TestCase,), {
'runTest': test})())
......@@ -34,19 +34,23 @@ class Recipe(GenericBaseRecipe):
"""
def install(self):
promise_parser = ConfigParser.RawConfigParser()
promise_parser.add_section('portal_templates')
promise_parser.set('portal_templates', 'repository', self.options['bt5-repository-url'])
promise_parser.set('portal_templates', 'expected_bt5', self.options['bt5'])
promise_parser.add_section('external_service')
promise_parser.set('external_service', 'cloudooo_url', self.options['cloudooo-url'])
promise_parser.set('external_service', 'memcached_url', self.options['memcached-url'])
promise_parser.set('external_service', 'kumofs_url', self.options['kumofs-url'])
promise_parser.set('external_service', 'smtp_url', self.options['smtp-url'])
for section_name, option_id_list in (
('portal_templates', (
('repository', 'bt5-repository-url'),
('expected_bt5', 'bt5'),
)),
('external_service', (
('cloudooo_url', 'cloudooo-url'),
('memcached_url', 'memcached-url'),
('kumofs_url', 'kumofs-url'),
('smtp_url', 'smtp-url'),
)),
):
promise_parser.add_section(section_name)
for internal_id, option_id in option_id_list:
option = self.options.get(option_id)
if option:
promise_parser.set(section_name, internal_id, option)
promise_parser.write(open(self.options['promise-path'], 'w'))
return [self.options['promise-path']]
......@@ -26,27 +26,69 @@
#
##############################################################################
import binascii
import errno
import os
import random
import string
from slapos.recipe.librecipe import GenericBaseRecipe
def generatePassword(length):
return ''.join(random.SystemRandom().sample(string.ascii_lowercase, length))
class Recipe(GenericBaseRecipe):
class Recipe(object):
"""Generate a password that is only composed of lowercase letters
This recipe only makes sure that ${:passwd} does not end up in `.installed`
file, which is world-readable by default. So be careful not to spread it
throughout the buildout configuration by referencing it directly: see
recipes like slapos.recipe.template:jinja2 to safely process the password.
Options:
- bytes: password length (default: 8 characters)
- storage-path: plain-text persistent storage for password,
that can only be accessed by the user
(default: ${buildout:parts-directory}/${:_buildout_section_name_})
"""
def __init__(self, buildout, name, options):
if os.path.exists(options['storage-path']):
open_file = open(options['storage-path'], 'r')
options['passwd'] = open_file.read()
open_file.close()
options_get = options.get
try:
self.storage_path = options['storage-path']
except KeyError:
self.storage_path = options['storage-path'] = os.path.join(
buildout['buildout']['parts-directory'], name)
try:
with open(self.storage_path) as f:
passwd = f.read()
except IOError, e:
if e.errno != errno.ENOENT:
raise
passwd = None
if not passwd:
passwd = self.generatePassword(int(options_get('bytes', '8')))
self.update = self.install
self.passwd = passwd
# Password must not go into .installed file, for 2 reasons:
# security of course but also to prevent buildout to always reinstall.
options.get = lambda option, *args, **kw: passwd \
if option == 'passwd' else options_get(option, *args, **kw)
if options.get('passwd', '') == '':
options['passwd'] = binascii.hexlify(os.urandom(
int(options.get('bytes', '24'))))
return GenericBaseRecipe.__init__(self, buildout, name, options)
generatePassword = staticmethod(generatePassword)
def install(self):
with open(self.options['storage-path'], 'w') as fout:
fout.write(self.options['passwd'])
return [self.options['storage-path']]
if self.storage_path:
try:
os.unlink(self.storage_path)
except OSError, e:
if e.errno != errno.ENOENT:
raise
fd = os.open(self.storage_path,
os.O_CREAT | os.O_EXCL | os.O_WRONLY, 0600)
try:
os.write(fd, self.passwd)
finally:
os.close(fd)
return self.storage_path
def update(self):
return ()
......@@ -37,7 +37,12 @@ class Recipe(GenericSlapRecipe):
"""
def _install(self):
ip = self.options['ip']
backend_url = self.parameter_dict['tidstorage-url']
backend_url = self.options.get('backend-url',
# BBB: Peeking in partition parameters directly. Eew.
self.parameter_dict.get('backend-url',
self.parameter_dict.get('tidstorage-url') # BBB
)
)
backend_server, backend_port = self._getBackendServer(backend_url)
path_list = []
if backend_url.startswith('https://'):
......@@ -70,6 +75,7 @@ class Recipe(GenericSlapRecipe):
varnishd_pid_file=self.options['pid-file'],
varnish_instance_name=self.options['varnish-instance-name'],
varnish_data=self.options['varnish-data'],
gcc_location=self.options['gcc-location'],
shell_path=self.options['shell-path'],
vcl_file=self.options['vcl-file'],
backend_port=backend_port,
......
......@@ -4,11 +4,12 @@ DAEMON_OPTS="-F \
-a %(varnish_ip)s:%(varnishd_server_port)s \
-T %(varnish_ip)s:%(varnishd_manager_port)s \
-t 0 \
-p nuke_limit=500 \
-n %(varnish_instance_name)s \
-f %(vcl_file)s \
-s file,%(varnish_data)s/varnish_storage.bin,1G"
PIDFILE=%(varnishd_pid_file)s
# exporting PATH here so that we will pass the PATH variable to the subprocess
export PATH
export PATH="%(gcc_location)s:$PATH"
exec %(varnishd_binary)s -P ${PIDFILE} ${DAEMON_OPTS} 2>&1
......@@ -25,6 +25,9 @@ rest-input-encoding utf-8
rest-output-encoding utf-8
default-zpublisher-encoding utf-8
# Disable ownership checking to execute codes generated by alarm
skip-ownership-checking on
# Temporary storage database (for sessions)
<zodb_db temporary>
<temporarystorage>
......
......@@ -25,6 +25,9 @@ rest-input-encoding utf-8
rest-output-encoding utf-8
default-zpublisher-encoding utf-8
# Disable ownership checking to execute codes generated by alarm
skip-ownership-checking on
# Temporary storage database (for sessions)
<zodb_db temporary>
<temporarystorage>
......
......@@ -87,7 +87,11 @@ class Recipe(GenericBaseRecipe):
'haproxy-listen-snippet.cfg.in')
server_snippet = ""
ip = self.options['ip']
server_check_path = self.options['server-check-path']
server_check_path = self.options.get('server-check-path', None)
if server_check_path:
httpchk = 'option httpchk GET %s' % server_check_path
else:
httpchk = ''
# FIXME: maxconn must be provided per-backend, not globally
maxconn = self.options['maxconn']
i = 0
......@@ -97,7 +101,7 @@ class Recipe(GenericBaseRecipe):
'name': name,
'ip': ip,
'port': port,
'server_check_path': server_check_path,
'httpchk': httpchk,
})
for address in backend_list:
i += 1
......
listen %(name)s %(ip)s:%(port)s
cookie SERVERID insert
balance roundrobin
option httpchk GET %(server_check_path)s
%(httpchk)s
stats uri /haproxy
stats realm Global\ statistics
......@@ -41,39 +41,40 @@ class Recipe(GenericBaseRecipe):
'"virtio" value.'
self.options['disk-type'] = 'virtio'
config = dict(
tap_interface=self.options['tap'],
vnc_ip=self.options['vnc-ip'],
vnc_port=self.options['vnc-port'],
nbd_ip=self.options['nbd-host'],
nbd_port=self.options['nbd-port'],
nbd2_ip=self.options.get('nbd2-host', ''),
nbd2_port=self.options.get('nbd2-port', 1024),
disk_path=self.options['disk-path'],
disk_size=self.options['disk-size'],
disk_type=self.options['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']
)
self.options['python-path'] = sys.executable
path_list = []
if not self.isTrueValue(self.options.get('use-tap')):
# XXX This could be done using Jinja.
for port in self.options['nat-rules'].split():
tunnel_port = int(port) + 10000
tunnel_path = self.createExecutable(
'%s-%s' % (self.options['6tunnel-wrapper-path'], tunnel_port),
self.substituteTemplate(
self.getTemplateFilename('6to4.in'),
{
'ipv6': self.options['ipv6'],
'ipv6_port': tunnel_port,
'ipv4': self.options['ipv4'],
'ipv4_port': tunnel_port,
'shell_path': self.options['shell-path'],
'6tunnel_path': self.options['6tunnel-path'],
},
),
)
path_list.append(tunnel_path)
# Runners
runner_path = self.createExecutable(
self.options['runner-path'],
self.substituteTemplate(self.getTemplateFilename('kvm_run.in'),
config))
self.options['runner-path'],
self.substituteTemplate(self.getTemplateFilename('kvm_run.in'),
self.options))
path_list.append(runner_path)
controller_path = self.createExecutable(
self.options['controller-path'],
self.substituteTemplate(self.getTemplateFilename('kvm_controller_run.in'),
config))
self.options))
return [runner_path, controller_path]
return path_list
#!%(shell_path)s
# BEWARE: This file is operated by slapgrid
# BEWARE: It will be overwritten automatically
exec %(6tunnel_path)s -6 -4 -d -l %(ipv6)s %(ipv6_port)s %(ipv4)s %(ipv4_port)s
#!%(python_path)s
#!%(python-path)s
# BEWARE: This file is operated by slapgrid
# BEWARE: It will be overwritten automatically
......@@ -6,12 +6,15 @@
import socket
import time
socket_path = '%(socket-path)s'
vnc_password = '%(vnc-passwd)s'
# 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')
so.connect(socket_path)
except socket.error:
time.sleep(1)
else:
......@@ -25,7 +28,7 @@ data = so.recv(1024)
# Set VNC password
so.send('{ "execute": "change", ' \
'"arguments": { "device": "vnc", "target": "password", ' \
' "arg": "%(vnc_passwd)s" } }')
' "arg": "' + vnc_password + '" } }')
data = so.recv(1024)
# Finish
......
#!%(python_path)s
#!%(python-path)s
# BEWARE: This file is operated by slapgrid
# BEWARE: It will be overwritten automatically
# Echo client program
import hashlib
import os
import socket
import subprocess
import urllib
# XXX: give all of this through parameter, don't use this as template, but as module
qemu_img_path = '%(qemu-img-path)s'
qemu_path = '%(qemu-path)s'
disk_size = '%(disk-size)s'
disk_type = '%(disk-type)s'
socket_path = '%(socket-path)s'
nbd_list = (('%(nbd-host)s', %(nbd-port)s), ('%(nbd2-host)s', %(nbd2-port)s))
default_disk_image = '%(default-disk-image)s'
disk_path = '%(disk-path)s'
virtual_hard_drive_url = '%(virtual-hard-drive-url)s'.strip()
virtual_hard_drive_md5sum = '%(virtual-hard-drive-md5sum)s'.strip()
nat_rules = '%(nat-rules)s'.strip()
use_tap = '%(use-tap)s'
tap_interface = '%(tap-interface)s'
listen_ip = '%(ipv4)s'
mac_address = '%(mac-address)s'
smp_count = '%(smp-count)s'
ram_size = '%(ram-size)s'
pid_file_path = '%(pid-file-path)s'
def md5Checksum(file_path):
with open(file_path, 'rb') as fh:
m = hashlib.md5()
while True:
data = fh.read(8192)
if not data:
break
m.update(data)
return m.hexdigest()
def getSocketStatus(host, port):
s = None
......@@ -26,27 +57,53 @@ def getSocketStatus(host, port):
break
return s
# create disk if doesn't exist
disk_path = '%(disk_path)s'
# Download existing hard drive if needed at first boot
if not os.path.exists(disk_path) and virtual_hard_drive_url != '':
print('Downloading virtual hard drive...')
urllib.urlretrieve(virtual_hard_drive_url, disk_path)
md5sum = virtual_hard_drive_md5sum.strip()
if md5sum:
print('Checking MD5 checksum...')
local_md5sum = md5Checksum(disk_path)
if local_md5sum != md5sum:
os.remove(disk_path)
raise Exception('MD5 mismatch. MD5 of local file is %%s, Specified MD5 is %%s.' %% (
local_md5sum, md5sum))
print('MD5sum check passed.')
else:
print('Warning: not checksum specified.')
# Create disk if doesn't exist
# XXX: move to Buildout profile
if not os.path.exists(disk_path):
subprocess.Popen(['%(qemu_img_path)s', 'create' ,'-f', 'qcow2',
disk_path, '%(disk_size)sG'])
kvm_argument_list = ['%(qemu_path)s',
'-enable-kvm', '-net', 'nic,macaddr=%(mac_address)s',
'-net', 'tap,ifname=%(tap_interface)s,script=no,downscript=no',
'-smp', '%(smp_count)s',
'-m', '%(ram_size)s',
'-drive', 'file=%(disk_path)s,if=%(disk_type)s',
'-vnc', '%(vnc_ip)s:1,ipv4,password',
print('Creating virtual hard drive...')
subprocess.Popen([qemu_img_path, 'create' ,'-f', 'qcow2',
disk_path, '%%sG' %% disk_size])
print('Done.')
# Generate network parameters
# XXX: use_tap should be a boolean
if use_tap == 'True':
qemu_network_parameter = 'tap,ifname=%%s,script=no,downscript=no' %% tap_interface
else:
qemu_network_parameter = 'user,' + ','.join('hostfwd=tcp:%%s:%%s-:%%s' %% (listen_ip, int(port) + 10000, port) for port in nat_rules.split())
kvm_argument_list = [qemu_path,
'-enable-kvm', '-net', 'nic,macaddr=%%s' %% mac_address,
'-net', qemu_network_parameter,
'-smp', smp_count,
'-m', ram_size,
'-drive', 'file=%%s,if=%%s' %% (disk_path, disk_type),
'-vnc', '%%s:1,ipv4,password' %% listen_ip,
'-boot', 'menu=on',
'-qmp', 'unix:%(socket_path)s,server',
'-pidfile', '%(pid_file_path)s',
'-qmp', 'unix:%%s,server' %% socket_path,
'-pidfile', pid_file_path,
]
# Try to connect to NBD server (and second nbd if defined)
for nbd_ip, nbd_port in (
('%(nbd_ip)s', %(nbd_port)s), ('%(nbd2_ip)s', %(nbd2_port)s)):
# Try to connect to NBD server (and second nbd if defined).
# If not available, don't even specify it in qemu command line parameters.
# Reason: if qemu starts with unavailable NBD drive, it will just crash.
for nbd_ip, nbd_port in nbd_list:
if nbd_ip and nbd_port:
s = getSocketStatus(nbd_ip, nbd_port)
if s is None:
......@@ -57,5 +114,10 @@ for nbd_ip, nbd_port in (
kvm_argument_list.extend([
'-drive',
'file=nbd:[%%s]:%%s,media=cdrom' %% (nbd_ip, nbd_port)])
# If no NBD is specified/available: use internal disk image
else:
kvm_argument_list.extend([
'-drive', 'file=%%s,media=cdrom' %% default_disk_image
])
os.execv('%(qemu_path)s', kvm_argument_list)
os.execv(qemu_path, kvm_argument_list)
......@@ -33,6 +33,7 @@ import sys
import inspect
import re
import shutil
from textwrap import dedent
import urllib
import urlparse
......@@ -129,10 +130,14 @@ class GenericBaseRecipe(object):
return script
def createWrapper(self, name, command, parameters, comments=[],
parameters_extra=False, environment=None):
parameters_extra=False, environment=None,
pidfile=None
):
"""
Creates a very simple (one command) shell script for process replacement.
Takes care of quoting.
if pidfile parameter is specified, then it will make the wrapper a singleton,
accepting to run only if no other instance is running.
"""
lines = [ '#!/bin/sh' ]
......@@ -144,6 +149,21 @@ class GenericBaseRecipe(object):
for key in environment:
lines.append('export %s=%s' % (key, environment[key]))
if pidfile:
lines.append(dedent("""\
# Check for other instances
pidfile=%s
if [ -e $pidfile ]; then
pid=$(cat $pidfile)
if [[ ! -z $(ps -p "$pid" | grep $(basename %s)) ]]; then
echo "Already running with pid $pid."
exit 1
else
rm $pidfile
fi
fi
echo $$ > $pidfile""" % (pidfile, command)))
lines.append('exec %s' % shlex.quote(command))
for param in parameters:
......@@ -183,17 +203,13 @@ class GenericBaseRecipe(object):
'template/%s' % template_name)
def generatePassword(self, len_=32):
"""
The purpose of this method is to generate a password which doesn't change
from one execution to the next, so the generated password doesn't change
on each slapgrid-cp execution.
Currently, it returns a hardcoded password because no decision has been
taken on where a generated password should be kept (so it is generated
once only).
"""
# TODO: implement a real password generator which remember the last
# call.
# TODO: Consider having generate.password recipe inherit this class,
# so that it can be easily inheritable.
# In the long-term, it's probably better that passwords are provided
# by software requesters, to avoid keeping unhashed secrets in
# partitions when possible.
self.logger.warning("GenericBaseRecipe.generatePassword is deprecated."
" Use generate.password recipe instead.")
return "insecure"
def isTrueValue(self, value):
......@@ -247,7 +263,8 @@ class GenericBaseRecipe(object):
destination = self.location
if os.path.exists(destination):
# leftovers from a previous failed attempt, removing it.
log.warning('Removing already existing directory %s' % destination)
self.logger.warning('Removing already existing directory %s',
destination)
shutil.rmtree(destination)
os.mkdir(destination)
......
......@@ -64,7 +64,7 @@ class Callback(GenericBaseRecipe):
class Notify(GenericBaseRecipe):
def createNotifier(self, notifier_binary, wrapper, executable,
log, title, notification_url, feed_url):
log, title, notification_url, feed_url, pidfile=None):
if not os.path.exists(log):
# Just a touch
......@@ -82,6 +82,7 @@ class Notify(GenericBaseRecipe):
return self.createWrapper(name=wrapper,
command=notifier_binary,
parameters=parameters,
pidfile=pidfile,
comments=[
'',
'Call an executable and send notification(s).',
......@@ -101,6 +102,7 @@ class Notify(GenericBaseRecipe):
executable=options['executable'],
log=log,
title=options['title'],
pidfile=options['pidfile'],
notification_url=options['notify'],
feed_url=feed_url)
return [script]
......@@ -35,20 +35,22 @@ class Recipe(GenericSlapRecipe):
publish_dict = dict()
options = self.options.copy()
del options['recipe']
slave_reference = options.pop('-slave-reference', None)
for k, v in options.iteritems():
if k[:1] == '-':
continue
publish_dict[k] = v
self._setConnectionDict(publish_dict)
self._setConnectionDict(publish_dict, slave_reference)
return []
def _setConnectionDict(self, publish_dict):
return self.setConnectionDict(publish_dict)
def _setConnectionDict(self, publish_dict, slave_reference=None):
return self.setConnectionDict(publish_dict, slave_reference)
SERIALISED_MAGIC_KEY = '_'
class Serialised(Recipe):
def _setConnectionDict(self, publish_dict):
return super(Serialised, self)._setConnectionDict(wrap(publish_dict))
def _setConnectionDict(self, publish_dict, slave_reference=None):
return super(Serialised, self)._setConnectionDict(wrap(publish_dict), slave_reference)
......
# vim: set et sts=2:
##############################################################################
#
# Copyright (c) 2010 Vifib SARL and Contributors. All Rights Reserved.
# 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
......@@ -24,37 +25,39 @@
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#
##############################################################################
import subprocess
import os
from slapos.recipe.librecipe import GenericBaseRecipe
import errno
class Recipe(GenericBaseRecipe):
class Recipe(object):
"""Read the first line of a file.
def _options(self, options):
if not os.path.exists(self.options['file']):
password = subprocess.check_output([self.options['pwgen-binary'], '-1']).strip()
with open(self.options['file'], 'w') as password_file:
password_file.write(password)
else:
with open(self.options['file'], 'r') as password_file:
password = password_file.read()
options['password'] = password
As the result has to be provided as an options, it is mandatory that the
buildout profile fills the file content (if needed) before trying to read it.
def install(self):
os.chmod(self.options['file'], 0600)
return []
Options:
- storage-path: file to read
class StablePasswordGeneratorRecipe(GenericBaseRecipe):
Result set in options:
- readline: first line of the file
"""
The purpose of this class is to generate a password which doesn't change
from one execution to the next (hence "stable"), so the generated password
doesn't change on each slapgrid-cp execution.
See GenericBaseRecipe.generatePassword .
"""
def __init__(self, buildout, name, options):
storage_path = options['storage-path']
try:
with open(storage_path) as f:
readline = f.readline()
except IOError, e:
if e.errno != errno.ENOENT:
raise
readline = None
def _options(self, options):
options['password'] = self.generatePassword()
self.readline = readline
options['readline'] = readline
def install(self):
if self.readline is None:
raise ValueError('Unable to read the file content.')
return ()
update = install = lambda self: []
def update(self):
return ()
......@@ -33,6 +33,12 @@ import traceback
DEFAULT_SOFTWARE_TYPE = 'RootSoftwareInstance'
def getListOption(option_dict, key, default=()):
result = option_dict.get(key, default)
if isinstance(result, basestring):
result = result.split()
return result
class Recipe(object):
"""
Request a partition to a slap master.
......@@ -82,8 +88,15 @@ class Recipe(object):
installation of request section will fail.
Possible names depend on requested partition's software type.
state (optional)
Requested state, default value is the state of the requester.
Output:
See "return" input key.
"instance-state"
The current state of the instance.
"requested-state"
The requested state of the instance.
"""
failed = None
......@@ -91,21 +104,23 @@ class Recipe(object):
self.logger = logging.getLogger(name)
software_url = options['software-url']
name = options['name']
return_parameters = options.get('return', '').split()
return_parameters = getListOption(options, 'return')
if not return_parameters:
self.logger.debug("No parameter to return to main instance."
"Be careful about that...")
software_type = options.get('software-type', DEFAULT_SOFTWARE_TYPE)
filter_kw = dict(
(x, options['sla-' + x]) for x in options.get('sla', '').split()
(x, options['sla-' + x]) for x in getListOption(options, 'sla')
if options['sla-' + x]
)
partition_parameter_kw = self._filterForStorage(dict(
(x, options['config-' + x])
for x in options.get('config', '').split()
for x in getListOption(options, 'config')
))
slave = options.get('slave', 'false').lower() in \
librecipe.GenericBaseRecipe.TRUE_VALUES
# By default XXXX Way of doing it is ugly and dangerous
requested_state = options.get('state', buildout['slap-connection'].get('requested','started'))
slap = slapmodule.slap()
slap.initializeConnection(
options['server-url'],
......@@ -123,7 +138,7 @@ class Recipe(object):
try:
self.instance = request(software_url, software_type,
name, partition_parameter_kw=partition_parameter_kw,
filter_kw=filter_kw, shared=slave)
filter_kw=filter_kw, shared=slave, state=requested_state)
return_parameter_dict = self._getReturnParameterDict(self.instance,
return_parameters)
if not slave:
......@@ -147,6 +162,13 @@ class Recipe(object):
except KeyError:
if self.failed is None:
self.failed = param
options['requested-state'] = requested_state
try:
options['instance-state'] = self.instance.getState()
except slapmodule.ResourceNotReady:
# Odd case: SlapOS Master doesn't send the state of a slave partition.
# XXX Should be fixed in the SlapOS Master, we should not care here.
pass
def _filterForStorage(self, partition_parameter_kw):
return partition_parameter_kw
......
......@@ -78,6 +78,8 @@ class Recipe(object):
Partition parameter whose name cannot be represented unambiguously in
buildout syntax are ignored. They cannot be accessed from buildout syntax
anyway, and are available through "configuration" output key.
instance-state
The instance state.
"""
# XXX: used to detect if a configuration key is a valid section key. This
......@@ -91,10 +93,12 @@ class Recipe(object):
options.get('key'),
options.get('cert'),
)
parameter_dict = slap.registerComputerPartition(
computer_partition = slap.registerComputerPartition(
options['computer'],
options['partition'],
).getInstanceParameterDict()
)
parameter_dict = computer_partition.getInstanceParameterDict()
options['instance-state'] = computer_partition.getState()
# XXX: those are not partition parameters, strictly speaking.
# Make them available as individual section keys.
for his_key in (
......@@ -129,9 +133,9 @@ class Recipe(object):
# also export single ip values for those recipes that don't support sets.
if ipv4_set:
options['ipv4-random'] = list(ipv4_set)[0]
options['ipv4-random'] = list(ipv4_set)[0].encode('UTF-8')
if ipv6_set:
options['ipv6-random'] = list(ipv6_set)[0]
options['ipv6-random'] = list(ipv6_set)[0].encode('UTF-8')
options['tap'] = tap_set
parameter_dict = self._expandParameterDict(options, parameter_dict)
......
......@@ -40,8 +40,8 @@ class Recipe(GenericBaseRecipe):
self.partition_amount = options['partition-amount'].strip()
self.cloud9_url = options.get('cloud9-url', '').strip()
self.log_file = os.path.join(options['log_dir'].strip(), 'slaprunner.log')
# Set slaprunner access URL
options['access-url'] = 'http://[%s]:%s' % (self.ipv6, self.runner_port)
# Set slaprunner access URL, CLN Beware ipv6 access is made throught nginx
options['access-url'] = 'https://[%s]:%s' % (self.ipv6, self.runner_port)
def install(self):
path_list = []
......@@ -49,7 +49,7 @@ class Recipe(GenericBaseRecipe):
configuration = dict(
software_root=self.software_directory,
instance_root=self.instance_directory,
master_url='http://%s:%s/' % (self.ipv4, self.proxy_port),
master_url='http://%s:%s' % (self.ipv4, self.proxy_port),
computer_id='slaprunner',
partition_amount=self.partition_amount,
slapgrid_sr=self.options['slapgrid_sr'],
......@@ -62,7 +62,7 @@ class Recipe(GenericBaseRecipe):
etc_dir=self.options['etc_dir'],
run_dir=self.options['run_dir'],
log_dir=self.options['log_dir'],
runner_host=self.ipv6,
runner_host=self.ipv4,
runner_port=self.runner_port,
ipv4_address=self.ipv4,
ipv6_address=self.ipv6,
......@@ -132,7 +132,7 @@ class Test(GenericBaseRecipe):
etc_dir=self.options['etc_dir'],
run_dir=self.options['etc_dir'],
log_dir=self.workdir,
runner_host=self.ipv6,
runner_host=self.ipv4,
runner_port=self.runner_port,
ipv4_address=self.ipv4,
ipv6_address=self.ipv6,
......
......@@ -71,7 +71,7 @@ class ExportRecipe(GenericBaseRecipe):
done
}
sync_element %(srv-directory)s/runner %(backup-directory)s/runner/ instance project proxy.db softwareLink
sync_element %(etc-directory)s %(backup-directory)s/etc/ .rcode .project .users ssh
sync_element %(etc-directory)s %(backup-directory)s/etc/ .rcode .project .users .htpasswd ssh
if [ -d %(backup-directory)s/runner/software ]; then
rm %(backup-directory)s/runner/software/*
fi
......@@ -120,7 +120,7 @@ class ImportRecipe(GenericBaseRecipe):
done
}
restore_element %(backup-directory)s/runner/ %(srv-directory)s/runner instance project proxy.db softwareLink
restore_element %(backup-directory)s/etc/ %(etc-directory)s .rcode .project .users ssh
restore_element %(backup-directory)s/etc/ %(etc-directory)s .rcode .project .users .htpasswd ssh
ifs=$IFS IFS=';'
read user pass remaining < %(etc-directory)s/.users
IFS=$ifs
......
......@@ -87,8 +87,6 @@ class Recipe:
computer_partition_id)
self.parameter_dict = self.computer_partition.getInstanceParameterDict()
software_type = self.parameter_dict['slap_software_type']
self.logger.info('Deploying instance with software type %s' % \
software_type)
# Raise if request software_type does not exist ...
if software_type not in self.options:
......
##############################################################################
#
# 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
class Recipe(GenericBaseRecipe):
"""
squid instance configuration.
wrapper-path -- location of the init script to generate
prepare-path -- location of the directory creation script to generate
binary-path -- location of the squid command
conf-path -- location of the configuration file
cache-path -- location of the cache directory
XXXX No good, specific...
open_port -- entrance port to the host and allowed to use cache
ip -- ip of the squid server
port -- port of the squid server
backend-ip -- ip of the service to cache
backend-port -- port of the service to cache
access-log-path -- location of the access log
cache-log-path -- location of the cache log
pid-filename-path -- location of the pid filename
"""
def install(self):
config = dict(
ip=self.options['ip'],
port=self.options['port'],
backend_ip=self.options['backend-ip'],
backend_port=self.options['backend-port'],
cache_path=self.options['cache-path'],
access_log_path=self.options['access-log-path'],
cache_log_path=self.options['cache-log-path'],
pid_filename_path=self.options['pid-filename-path'],
open_port=self.options['open-port'],
)
template_filename = self.getTemplateFilename('squid.conf.in')
configuration_path = self.createFile(
self.options['conf-path'],
self.substituteTemplate(template_filename, config))
# Prepare directories
prepare_path = self.createPythonScript(
self.options['prepare-path'],
'slapos.recipe.librecipe.execute.execute',
arguments=[self.options['binary-path'].strip(),
'-z',
'-f', configuration_path,
],)
# Create running wrapper
wrapper_path = self.createPythonScript(
self.options['wrapper-path'],
'slapos.recipe.librecipe.execute.execute',
arguments=[self.options['binary-path'].strip(),
'-N',
'-f', configuration_path,
],)
return [configuration_path, wrapper_path, prepare_path]
refresh_pattern . 0 20%% 4320 max-stale=604800
# Dissallow cachemgr access
http_access deny manager
# Squid service configuration
http_port %(ip)s:%(port)s accel defaultsite=%(ip)s
cache_peer %(backend_ip)s parent %(backend_port)s 0 no-query originserver name=backend
acl our_sites port %(open_port)s
http_access allow our_sites
cache_peer_access backend allow our_sites
cache_peer_access backend deny all
# Drop squid headers
# via off
# reply_header_access X-Cache-Lookup deny all
# reply_header_access X-Squid-Error deny all
# reply_header_access X-Cache deny all
header_replace X-Forwarded-For
follow_x_forwarded_for allow all
forwarded_for on
# Use 1Go of RAM
cache_mem 1024 MB
# But do not keep big object in RAM
maximum_object_size_in_memory 2048 KB
# Log
access_log %(access_log_path)s
cache_log %(cache_log_path)s
pid_filename %(pid_filename_path)s
......@@ -43,7 +43,11 @@ class Recipe(GenericBaseRecipe):
repozo_wrapper = self.createPythonScript(
self.options['repozo-wrapper'],
'slapos.recipe.librecipe.execute.execute',
[self.options['tidstorage-repozo-binary'], '--config',
configuration_file, '--repozo', self.options['repozo-binary'], '-z'])
[self.options['tidstorage-repozo-binary'],
'--config', configuration_file,
'--repozo', self.options['repozo-binary'],
'--gzip',
'--quick',
])
return [configuration_file, tidstorage_wrapper, repozo_wrapper]
......@@ -34,11 +34,15 @@ class Recipe(GenericSlapRecipe):
"""
def _install(self):
path_list = []
web_checker_mail_address = self.parameter_dict['web-checker-mail-address']
web_checker_smtp_host = self.parameter_dict['web-checker-smtp-host']
web_checker_frontend_url = self.parameter_dict.get(
'web-checker-frontend-url',
self.options['frontend-url'])
try:
web_checker_mail_address = self.options['mail-address']
web_checker_smtp_host = self.options['smtp-host']
web_checker_frontend_url = self.options['frontend-url']
except KeyError:
# BBB
web_checker_mail_address = self.parameter_dict['web-checker-mail-address']
web_checker_smtp_host = self.parameter_dict['web-checker-smtp-host']
web_checker_frontend_url = self.parameter_dict['web-checker-frontend-url']
web_checker_working_directory = \
self.options['web-checker-working-directory']
config = dict(
......
Apache:
=======
- set a redirection of / in option
- Implement support of multiple ip (if possible) for multiple ssl (other solution is to ask master instance but quid to much apache process?)
Squid:
======
- Only cache in ram. Problems with to much squid on the computer or too many slave?
SlapOS:
=======
- Implement intelligent apache graceful -> Should check slave configuration and return error to slave if there is a problem (important but difficult)
- useless srv/squid_cache directory so far
[buildout]
extends =
# dev Stuff
../../component/git/buildout.cfg
../../stack/slapos.cfg
../../component/binutils/buildout.cfg
../../component/lxml-python/buildout.cfg
../../component/apache/buildout.cfg
../../component/gzip/buildout.cfg
../../component/stunnel/buildout.cfg
../../component/varnish/buildout.cfg
../../component/dcron/buildout.cfg
../../component/logrotate/buildout.cfg
../../component/rdiff-backup/buildout.cfg
../../stack/slapos.cfg
../../component/squid/buildout.cfg
parts =
parts +=
slapos-cookbook
slapos-toolbox
template
template-apache-frontend
template-apache-replicate
binutils
apache-2.2
apache-antiloris-apache-2.2
stunnel
varnish-2.1
dcron
logrotate
rdiff-backup
squid
# Buildoutish
eggs
instance-recipe-egg
[instance-recipe]
# Note: In case if specific instantiation recipe is used this is the place to
# put its name
egg = slapos.cookbook
module = apache.frontend
[instance-recipe-egg]
[slapos-toolbox]
recipe = zc.recipe.egg
eggs = ${instance-recipe:egg}
[eggs]
recipe = z3c.recipe.scripts
eggs =
${lxml-python:egg}
slapos.toolbox
scripts =
killpidfromfile
onetimedownload
[check-recipe]
recipe = plone.recipe.command
stop-on-error = true
update-command = ${:command}
command =
grep parts ${buildout:develop-eggs-directory}/slapos.cookbook.egg-link &&
[template]
# Default template for apache instance.
recipe = slapos.recipe.template
url = ${:_profile_base_location_}/instance.cfg
md5sum = e7b9f57da7eb1450fc15789e239388d4
md5sum = 9c6346c8eaf484748e6be0b62b65cf2e
output = ${buildout:directory}/template.cfg
mode = 0644
[template-apache-frontend]
recipe = slapos.recipe.template
url = ${:_profile_base_location_}/instance-apache-frontend.cfg
md5sum = 7e7e7599ec41cf1eb6e8e725d855c345
output = ${buildout:directory}/template-apache-frontend.cfg
mode = 0644
[template-apache-replicate]
recipe = slapos.recipe.build:download
url = ${:_profile_base_location_}/instance-apache-replicate.cfg.in
md5sum = 2c96799f1429d0541c04c0875d864777
mode = 0644
[template-slave-list]
recipe = slapos.recipe.build:download
url = ${:_profile_base_location_}/templates/apache-custom-slave-list.cfg.in
md5sum = f5eef006211809669b12422240c6f436
mode = 640
[template-slave-configuration]
recipe = slapos.recipe.build:download
url = ${:_profile_base_location_}/templates/slave-virtualhost.conf.in
md5sum = a7ad2e83b7f919fc45a7ef1e64344dcb
mode = 640
[template-replicate-publish-slave-information]
recipe = slapos.recipe.build:download
url = ${:_profile_base_location_}/templates/replicate-publish-slave-information.cfg.in
mode = 640
[template-apache-frontend-configuration]
recipe = slapos.recipe.build:download
url = ${:_profile_base_location_}/templates/apache.conf.in
md5sum = c141b9e78c7e80d75bb40493910294e5
mode = 640
[template-apache-cached-configuration]
recipe = slapos.recipe.build:download
url = ${:_profile_base_location_}/templates/apache_cached.conf.in
md5sum = 0c4393db80670daf18b432b7f07383e9
mode = 640
[template-rewrite-cached]
recipe = slapos.recipe.build:download
url = ${:_profile_base_location_}/templates/apache_cached_rewrite.txt.in
md5sum = 2f30af4f9da340c2b0618599da03ed4b
mode = 640
[template-custom-slave-list]
recipe = slapos.recipe.build:download
url = ${:_profile_base_location_}/templates/apache-default-slave-list.cfg.in
md5sum = 9362384cd80727987b34c7746a6de196
mode = 640
[template-not-found-html]
recipe = slapos.recipe.build:download
url = ${:_profile_base_location_}/templates/notfound.html
filename = notfound.html
md5sum = f20d6c3d2d94fb685f8d26dfca1e822b
mode = 640
[template-default-virtualhost]
recipe = slapos.recipe.build:download
url = ${:_profile_base_location_}/templates/000.conf.in
md5sum = c2bbf029e6adc432de0884fb5cf5d2ab
mode = 640
[template-default-slave-virtualhost]
recipe = slapos.recipe.build:download
url = ${:_profile_base_location_}/templates/default-virtualhost.conf.in
md5sum = ac845c0fa3835832307a0e7323cb339d
mode = 640
[template-empty]
recipe = slapos.recipe.build:download
url = ${:_profile_base_location_}/templates/empty.in
md5sum = c2314c3a9c3412a38d14b312d3df83c1
mode = 640
\ No newline at end of file
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
<VirtualHost *:{{ https_port }}>
ServerName www.example.org
SSLEngine on
SSLProxyEngine on
SSLProtocol -ALL +SSLv3 +TLSv1
SSLHonorCipherOrder On
SSLCipherSuite RC4-SHA:HIGH:!ADH
# Rewrite part
ProxyVia On
ProxyPreserveHost On
ProxyTimeout 600
RewriteEngine On
ErrorDocument 404 /notfound.html
</VirtualHost>
<VirtualHost *:{{ http_port }}>
ServerName www.example.org
ErrorDocument 404 /notfound.html
</VirtualHost>
\ No newline at end of file
This diff is collapsed.
{% for server_tuple in server_dict.items() -%}
{{ "%s %s" % server_tuple }}
{% endfor -%}
This diff is collapsed.
{{ content }}
\ No newline at end of file
{% set part_list = [] -%}
{% set slave_information_dict = {} -%}
# regroup slave information from all frontends
{%- for frontend, slave_list_raw in slave_information.iteritems() -%}
{% set slave_list = json_module.loads(slave_list_raw) -%}
{% for slave_dict in slave_list -%}
{% set slave_reference = slave_dict.pop('slave-reference') %}
{% set current_slave_dict = slave_information_dict.get(slave_reference, {}) %}
{% do current_slave_dict.update(slave_dict) -%}
{% do current_slave_dict.__setitem__(
'replication_number',
current_slave_dict.get('replication_number', 0) + 1
) -%}
{% do slave_information_dict.__setitem__(slave_reference, current_slave_dict) -%}
{% endfor -%}
{% endfor %}
# Publish information for each slave
{% for slave_reference, slave_information in slave_information_dict.iteritems() %}
{% set publish_section_title = 'publish-%s' % slave_reference -%}
{% do part_list.append(publish_section_title) -%}
[{{ publish_section_title }}]
recipe = slapos.cookbook:publish
-slave-reference = {{ slave_reference }}
{% for key, value in slave_information.iteritems() -%}
{{ key }} = {{ value }}
{% endfor -%}
{% endfor %}
[buildout]
parts =
{% for part in part_list %}
{{ ' %s' % part }}
{% endfor %}
eggs-directory = {{ eggs_directory }}
develop-eggs-directory = {{ develop_eggs_directory }}
offline = true
\ No newline at end of file
<VirtualHost *:{{ https_port }}>
{{ apache_custom_https }}
</VirtualHost>
<VirtualHost *:{{ http_port }}>
{{ apache_custom_http }}
</VirtualHost>
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
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