diff --git a/CHANGES.txt b/CHANGES.txt index c87df4074c215e69fe7295f197c67a316460068b..7c7a38458e224a4f4c423db31c427649ee1cfc25 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -1,6 +1,40 @@ Changes ======= +0.46 (Unreleased) +----------------- + + * No change yet. + +0.45 (2012-03-29) +----------------- + + * slaprunner: change number of available partitions to 7 [Alain Takoudjou] + +0.44 (2012-03-28) +----------------- + + * minor: apachephp: update apache configuration to work with Apache2.4 + +0.43 (2012-03-28) +----------------- + + * minor: erp5: add missing .zcml files into egg. [Cedric de Saint Martin] + +0.42 (2012-03-26) +----------------- + + * erp5: Add web_checker recipe. [Tatuya Kamada] + * erp5: Add generic_varnish recipe. [Tatuya Kamada] + * erp5: Simplify erp5_update to only create the ERP5 site. [Romain Courteaud] + * erp5: Allow to pass CA parameters from section. [艁ukasz Nowak] + +0.41 (2012-03-21) +----------------- + + * Release new "generic" version of KVM, includes frontend. + [Cedric de Saint Martin] + 0.40.1 (2012-03-01) ----------------- diff --git a/MANIFEST.in b/MANIFEST.in index 7a7a46ad5854e867ebfe05a2d61bd67914c1cc51..baa42c13a7d5241c999f964b98c679ceaa9b02cb 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -1,6 +1,7 @@ include CHANGES.txt -include slapos/recipe/generic_zope/template/site.zcml include slapos/recipe/apache_frontend/template/notfound.html recursive-include slapos/recipe *.in recursive-include slapos/recipe *.bin recursive-include slapos/recipe README.*.txt +recursive-include slapos/recipe *.js +recursive-include slapos/recipe *.zcml diff --git a/component/alsa/buildout.cfg b/component/alsa/buildout.cfg index 3c91b1fdfd3e392dc589c33b54bf42eaad54cf81..452bb71207ad6caa76e781c837974ca44ffafdeb 100644 --- a/component/alsa/buildout.cfg +++ b/component/alsa/buildout.cfg @@ -6,7 +6,7 @@ parts = # Contains libasound recipe = hexagonit.recipe.cmmi url = ftp://ftp.alsa-project.org/pub/lib/alsa-lib-1.0.24.1.tar.bz2 -#md5sum = d55a9d7d2a79d738a1b7a511cffda4b6 +md5sum = 7cc05f25e1d5b65da8fb3fdcd540f226 configure-options = --disable-static --disable-aload @@ -18,4 +18,4 @@ configure-options = --disable-ucm --disable-alisp --disable-old-symbols - --disable-python \ No newline at end of file + --disable-python diff --git a/component/apache-php/buildout.cfg b/component/apache-php/buildout.cfg index 7dcc0f5a7df281068643f53d393dc901b9f27c05..dcf667fa68463892ceee1eb0e6b76f4cc874597f 100644 --- a/component/apache-php/buildout.cfg +++ b/component/apache-php/buildout.cfg @@ -3,6 +3,7 @@ parts = apache-php extends = ../apache/buildout.cfg + ../bzip2/buildout.cfg ../cclient/buildout.cfg ../curl/buildout.cfg ../freetype/buildout.cfg @@ -20,12 +21,13 @@ extends = # Note: Shall react on each build of apache and reinstall itself recipe = hexagonit.recipe.cmmi url = http://fr2.php.net/distributions/php-5.3.10.tar.gz -md5sum = 816259e5ca7d0a7e943e56a3bb32b17f +md5sum = 2b3d2d0ff22175685978fb6a5cbcdc13 configure-options = --with-apxs2=${apache:location}/bin/apxs --with-libxml-dir=${libxml2:location} --with-mysql=${mariadb:location} --with-zlib-dir=${zlib:location} + --with-bz2-dir=${bzip2:location} --with-mcrypt=${libmcrypt:location} --with-gd --with-jpeg-dir=${libjpeg:location} @@ -48,12 +50,13 @@ configure-options = --enable-session --enable-exif --enable-zip + --enable-bz2 --enable-ftp environment = PKG_CONFIG_PATH=${libxml2:location}/lib/pkgconfig:${openssl:location}/lib/pkgconfig - PATH=${pkgconfig:location}/bin:${libxml2:location}/bin:%(PATH)s - LDFLAGS =-L${libtool:location}/lib -Wl,-rpath -Wl,${libtool:location}/lib -L${mariadb:location}/lib -Wl,-rpath -Wl,${mariadb:location}/lib -L${zlib:location}/lib -Wl,-rpath -Wl,${zlib:location}/lib -L${libmcrypt:location}/lib -Wl,-rpath -Wl,${libmcrypt:location}/libblkid + PATH=${pkgconfig:location}/bin:${bzip2:location}/bin:${libxml2:location}/bin:%(PATH)s + LDFLAGS =-L${bzip2:location}/lib -Wl,-rpath -Wl,${bzip2:location}/lib -L${libtool:location}/lib -Wl,-rpath -Wl,${libtool:location}/lib -L${mariadb:location}/lib -Wl,-rpath -Wl,${mariadb:location}/lib -L${zlib:location}/lib -Wl,-rpath -Wl,${zlib:location}/lib -L${libmcrypt:location}/lib -Wl,-rpath -Wl,${libmcrypt:location}/libblkid [libmcrypt] @@ -64,4 +67,4 @@ md5sum = c4f491dd411a09e9de3b8702ea6f73eb [xml-rpc] recipe = hexagonit.recipe.cmmi url = http://downloads.sourceforge.net/project/phpxmlrpc/phpxmlrpc/2.2.2/xmlrpc-2.2.2.tar.gz -md5sum = 59a644c636c6d98267d0c99b406ae9e8 \ No newline at end of file +md5sum = 59a644c636c6d98267d0c99b406ae9e8 diff --git a/component/cloud9/buildout.cfg b/component/cloud9/buildout.cfg new file mode 100644 index 0000000000000000000000000000000000000000..71f299a6b3d56290a39ec8bedf92fa95f71e9a70 --- /dev/null +++ b/component/cloud9/buildout.cfg @@ -0,0 +1,45 @@ +[buildout] +extends = + ../dcron/buildout.cfg + ../libxml2/buildout.cfg + ../logrotate/buildout.cfg + ../rdiff-backup/buildout.cfg + ../nodejs/buildout.cfg + +parts = + nodejs + npm + cloud9 + +[cloud9] +<= cloud9-git + +[cloud9-git] +# Online IDE written in javascript/node.js +# URL : c9.io +# You can use it using the following command : +# NODE_PATH=${:destination}/node_modules ${nodejs:node_location} ${:cloud9_js_location} +recipe = plone.recipe.command +stop-on-error = true +commit = 97db1467c517d265438684bd2a70b0b76ee282f6 +repository = https://github.com/ajaxorg/cloud9.git +location = ${buildout:parts-directory}/${:_buildout_section_name_} +git-binary = ${git:location}/bin/git +npm-binary = ${nodejs-0.4:location}/bin/node ${npm:location}/bin/npm +command = export GIT_SSL_NO_VERIFY=true; (${:git-binary} clone --quiet ${:repository} ${:location} && cd ${:location} && ${:git-binary} reset --hard ${:commit} && ${:git-binary} submodule update --init && cd support/jsdav && PATH=${nodejs-0.4:location}/bin:$PATH LDFLAGS=-L${libxml2:location}/lib ${:npm-binary} install) || (rm -fr ${:location}; exit 1) +update-command = + +[cloud9-npm] +# Online IDE written in javascript/node.js +# URL : c9.io +# You can use it using the following command : +# NODE_PATH=${:destination}/node_modules ${nodejs:node_location} ${:cloud9_js_location} +recipe = slapos.recipe.npm +# Node part has to be specified, otherwise system node is used. +node = nodejs-0.6 +# List of packages to install +packages = + cloud9 +# Specify environment jsDAV (dependency of cloud9) needs libxml2 +environment = + LDFLAGS=-L${libxml2:location}/lib -Wl,-rpath=${libxml2:location}/lib diff --git a/component/firefox/buildout.cfg b/component/firefox/buildout.cfg index 4b8bf8a4d5d48b1144835ecc1d9124c81cc813b1..b55f70653aa8868102cf284871f62e3dfeabd41b 100644 --- a/component/firefox/buildout.cfg +++ b/component/firefox/buildout.cfg @@ -20,8 +20,8 @@ depends = ${liberation-fonts:location} ${ipaex-fonts:location} -x86 = http://releases.mozilla.org/pub/mozilla.org/firefox/releases/7.0.1/linux-i686/fr/firefox-7.0.1.tar.bz2 42c2559892f26ed2a0563faaf693a00f -x86-64 = http://releases.mozilla.org/pub/mozilla.org/firefox/releases/7.0.1/linux-x86_64/en-US/firefox-7.0.1.tar.bz2 20d6c8e3dfc97d08d1dec7d0479f924f +x86 = http://releases.mozilla.org/pub/mozilla.org/firefox/releases/11.0/linux-i686/fr/firefox-11.0.tar.bz2 a7e9c614ddac993476ef771afaedf568 +x86-64 = http://releases.mozilla.org/pub/mozilla.org/firefox/releases/11.0/linux-x86_64/fr/firefox-11.0.tar.bz2 b358865c08145211314a62660e871614 script = if not self.options.get('url'): self.options['url'], self.options['md5sum'] = self.options[guessPlatform()].split(' ') diff --git a/component/noVNC/buildout.cfg b/component/noVNC/buildout.cfg index 00dad6c804d8c077bcb44ffe946a889fa95b14a1..41b6f8ae2886031efe5dc3c11497f4420a370ec0 100644 --- a/component/noVNC/buildout.cfg +++ b/component/noVNC/buildout.cfg @@ -3,6 +3,6 @@ parts = noVNC [noVNC] -recipe = hexagonit.recipe.download -url = https://github.com/kanaka/noVNC/tarball/master +recipe = slapos.recipe.build:download-unpacked +url = https://github.com/kanaka/noVNC/tarball/v0.2 strip-top-level-dir = true diff --git a/component/nodejs/buildout.cfg b/component/nodejs/buildout.cfg new file mode 100644 index 0000000000000000000000000000000000000000..dddcf4bef82274e0e4d7c02f1c275fac93574b0c --- /dev/null +++ b/component/nodejs/buildout.cfg @@ -0,0 +1,50 @@ +[buildout] +extends = + ../git/buildout.cfg + ../pkgconfig/buildout.cfg + ../openssl/buildout.cfg + ../python-2.7/buildout.cfg + ../zlib/buildout.cfg + +parts = + nodejs + +[nodejs] +# Server-side Javascript. +recipe = hexagonit.recipe.cmmi +url = http://nodejs.org/dist/v0.6.12/node-v0.6.12.tar.gz +md5sum = a12766ae4003c9712927d1fa134ed9f6 +configure-options = + --openssl-includes=${openssl:location}/include + --openssl-libpath=${openssl:location}/lib +environment = + PATH=${pkgconfig:location}/bin:${python2.7:location}/bin:%(PATH)s + PKG_CONFIG_PATH=${openssl:location}/lib/pkgconfig/ + CPPFLAGS=-I${zlib:location}/include + LDFLAGS=-Wl,-rpath=${openssl:location}/lib -L${zlib:location}/lib -Wl,-rpath=${zlib:location}/lib + +[nodejs-0.4] +recipe = hexagonit.recipe.cmmi +url = http://nodejs.org/dist/node-v0.4.12.tar.gz +md5sum = a6375eaa43db5356bf443e25b828ae16 +configure-options = + --openssl-includes=${openssl:location}/include + --openssl-libpath=${openssl:location}/lib +environment = + PATH=${pkgconfig:location}/bin:${python2.7:location}/bin:%(PATH)s + PKG_CONFIG_PATH=${openssl:location}/lib/pkgconfig/ + CPPFLAGS=-I${zlib:location}/include + LDFLAGS=-Wl,-rpath=${openssl:location}/lib -L${zlib:location}/lib -Wl,-rpath=${zlib:location}/lib + +[npm] +# Node.js Package Manager +# Deprecated. Included in node >= 0.6.3. +recipe = plone.recipe.command +location = ${buildout:parts-directory}/${:_buildout_section_name_} +stop-on-error = true +commit = 3136abc5c6b3ed332c4700ece24450fada63639b +origin = https://github.com/isaacs/npm.git +git-bin = ${git:location}/bin/git +node-bin = ${nodejs-0.4:location}/bin/node +command = (GIT_SSL_NO_VERIFY=true ${:git-bin} clone --quiet ${:origin} ${:location} && cd ${:location} && ${:git-bin} reset --hard ${:commit} && ${:location}/configure --prefix=${:location} && GIT_SSL_NO_VERIFY=true ${:git-bin} submodule update --init --recursive && ${:node-bin} cli.js install npm@1.0.106 -g -f) || (rm -fr ${:location}; exit 1) +update-command = diff --git a/component/slapos/buildout.cfg b/component/slapos/buildout.cfg index 3552cffc575883ef0a55ca640cd789424aaabc5a..0088c4709030c33159f60734cb6acb5402071282 100644 --- a/component/slapos/buildout.cfg +++ b/component/slapos/buildout.cfg @@ -120,17 +120,17 @@ Werkzeug = 0.8.3 buildout-versions = 1.7 collective.recipe.template = 1.9 hexagonit.recipe.cmmi = 1.5.0 -lxml = 2.3.3 +lxml = 2.3.4 meld3 = 0.6.8 netaddr = 0.7.6 -slapos.core = 0.23 +slapos.core = 0.24 slapos.libnetworkcache = 0.12 xml-marshaller = 0.9.7 -z3c.recipe.scripts = 1.0.1 +z3c.recipe.scripts = 1.0.1 zc.recipe.egg = 1.3.2 # Required by: -# slapos.core==0.23 +# slapos.core==0.24 Flask = 0.8 # Required by: @@ -138,11 +138,11 @@ Flask = 0.8 hexagonit.recipe.download = 1.5.0 # Required by: -# slapos.core==0.23 +# slapos.core==0.24 netifaces = 0.8 # Required by: -# slapos.core==0.23 +# slapos.core==0.24 # slapos.libnetworkcache==0.12 # supervisor==3.0a12 # zc.buildout==1.6.0-dev-SlapOS-004 @@ -150,9 +150,9 @@ netifaces = 0.8 setuptools = 0.6c12dev-r88846 # Required by: -# slapos.core==0.23 +# slapos.core==0.24 supervisor = 3.0a12 # Required by: -# slapos.core==0.23 +# slapos.core==0.24 zope.interface = 3.8.0 diff --git a/component/stunnel/buildout.cfg b/component/stunnel/buildout.cfg index 8321200e7becbc25dbb364092978c176574c2a6e..63eb5e6b098c8e9086eca629de947eb923238972 100644 --- a/component/stunnel/buildout.cfg +++ b/component/stunnel/buildout.cfg @@ -17,8 +17,8 @@ filename = stunnel-4-hooks.py [stunnel-4] recipe = hexagonit.recipe.cmmi -url = http://mirror.bit.nl/stunnel/stunnel-4.52.tar.gz -md5sum = f5e713dda0e8efa659f372832ecd0c2c +url = http://mirror.bit.nl/stunnel/stunnel-4.53.tar.gz +md5sum = ab3bfc915357d67da18c73f73610d593 pre-configure-hook = ${stunnel-4-hook-download:location}/${stunnel-4-hook-download:filename}:pre_configure_hook configure-options = --enable-ipv6 diff --git a/setup.py b/setup.py index ee7523d52672dff85c181be7938df4214730fd10..df5eb713bd231d5f26de3d7eb8834a4815365ee0 100644 --- a/setup.py +++ b/setup.py @@ -2,7 +2,7 @@ from setuptools import setup, find_packages import glob import os -version = '0.40.1' +version = '0.46-dev' name = 'slapos.cookbook' long_description = open("README.txt").read() + "\n" + \ open("CHANGES.txt").read() + "\n" @@ -46,6 +46,7 @@ setup(name=name, 'apache.zope.backend = slapos.recipe.apache_zope_backend:Recipe', 'certificate_authority = slapos.recipe.certificate_authority:Recipe', 'certificate_authority.request = slapos.recipe.certificate_authority:Request', + 'check_port_listening = slapos.recipe.check_port_listening:Recipe', 'cron = slapos.recipe.dcron:Recipe', 'cron.d = slapos.recipe.dcron:Part', 'davstorage = slapos.recipe.davstorage:Recipe', @@ -56,14 +57,18 @@ setup(name=name, 'erp5scalabilitytestbed = slapos.recipe.erp5scalabilitytestbed:Recipe', 'equeue = slapos.recipe.equeue:Recipe', 'erp5testnode = slapos.recipe.erp5testnode:Recipe', + 'generate.mac = slapos.recipe.generatemac:Recipe', + 'nbdserver = slapos.recipe.nbdserver:Recipe', + 'generic.onetimeupload = slapos.recipe.generic_onetimeupload:Recipe', 'helloworld = slapos.recipe.helloworld:Recipe', 'generic.cloudooo = slapos.recipe.generic_cloudooo:Recipe', 'fontconfig = slapos.recipe.fontconfig:Recipe', 'java = slapos.recipe.java:Recipe', 'kumofs = slapos.recipe.kumofs:Recipe', + 'kvm = slapos.recipe.kvm:Recipe', + 'kvm.frontend = slapos.recipe.kvm_frontend:Recipe', 'generic.kumofs = slapos.recipe.generic_kumofs:Recipe', 'haproxy = slapos.recipe.haproxy:Recipe', - 'kvm = slapos.recipe.kvm:Recipe', 'libcloud = slapos.recipe.libcloud:Recipe', 'libcloudrequest = slapos.recipe.libcloudrequest:Recipe', 'lockfile = slapos.recipe.lockfile:Recipe', @@ -73,11 +78,11 @@ setup(name=name, 'mydumper = slapos.recipe.mydumper:Recipe', 'generic.mysql = slapos.recipe.generic_mysql:Recipe', 'mkdirectory = slapos.recipe.mkdirectory:Recipe', - 'nbdserver = slapos.recipe.nbdserver:Recipe', 'nosqltestbed = slapos.recipe.nosqltestbed:NoSQLTestBed', 'notifier = slapos.recipe.notifier:Recipe', 'notifier.callback = slapos.recipe.notifier:Callback', 'notifier.notify = slapos.recipe.notifier:Notify', + 'novnc = slapos.recipe.novnc:Recipe', 'lamp = slapos.recipe.lamp:Request', 'lamp.request = slapos.recipe.lamp:Request', 'lamp.static = slapos.recipe.lamp:Static', diff --git a/slapos/recipe/README.apache_frontend.txt b/slapos/recipe/README.apache_frontend.txt index f701b6591426405201b92a3437759362b574eeba..89da1b88f1d91025b3cff543c0025a5d39dd727a 100644 --- a/slapos/recipe/README.apache_frontend.txt +++ b/slapos/recipe/README.apache_frontend.txt @@ -1,4 +1,36 @@ apache_frontend ========== -Frontend using Apache, allowing to rewrite and proxy URLs like myinstance.myfrontenddomainname.com to real IP/URL of myinstance. \ No newline at end of file +Frontend using Apache, allowing to rewrite and proxy URLs like +myinstance.myfrontenddomainname.com to real IP/URL of myinstance. + +apache_frontend works using the master instance / slave instance design. +It means that a single main instance of Apache will be used to act as frontend +for many slaves. + + +How to use +======== +First, you will need to request a "master" instance of Apache Frontend with +"domain" parameter, like : +<?xml version='1.0' encoding='utf-8'?> +<instance> + <parameter id="domain">moulefrite.com</parameter> + <parameter id="port">443</parameter> +</instance> + +Then, it is possible to request many slave instances +(currently only from slapconsole, UI doesn't work yet) +of Apache Frontend, like : +instance = request( + software_release=apache_frontend, + partition_reference='frontend2', + shared=True, + partition_parameter_kw={"url":"https://[1:2:3:4]:1234/someresource"} + ) +Those slave instances will be redirected to the "master" instance, +and you will see on the "master" instance the associated RewriteRules of +all slave instances. + +Finally, the slave instance will be accessible from : +https://someidentifier.moulefrite.com. diff --git a/slapos/recipe/README.kvm_frontend.txt b/slapos/recipe/README.kvm_frontend.txt new file mode 100644 index 0000000000000000000000000000000000000000..b600221c6a89767798aa1a94834e786b53f680ab --- /dev/null +++ b/slapos/recipe/README.kvm_frontend.txt @@ -0,0 +1,56 @@ +kvm_frontend +=== + +Introduction +------------ + +The ``slapos.recipe.kvm_frontend`` aims to provide proxy server to KVM instances. + +It allows HTTPS IPv4/IPv6 proxying (with or without domain name), and supports +the WebSocket technology needed for VNC-in-webapplication noVNC. + +It works following the master/slave instances system. A master instance is +created, containing all what is needed to run the proxy. Slave instances +are later created, adding one line in the master instance's proxy configuration +that specify the IP/port to proxy to the KVM. + +The slave instance (kvm) is then accessible from +http://[masterinstanceIPorhostname]/[randomgeneratednumber] + + +Instance parameters +------------ + +Incoming master instance parameters ++++++++ + +``port`` - Port of server, optional, defaults to 4443. +``domain`` - domain name to use, optional, default to + "host.vifib.net". +``redirect_plain_http`` - if value is one of ['y', 'yes', '1', 'true'], instance + will try to create a simple http server on port 80 + redirecting to the proxy. Optional. + +Incoming slave instance parameters ++++++++ + +``host`` - KVM instance IP or hostname. Mandatory. +``port`` - KVM instance port, Mandatory. +``https`` - if value is one of ['n', 'no', '0', 'false'], will try to connect + to target in plain http. Optional. + +Connection parameters +------------- + +Outgoing master connection parameters ++++++++ + +``domain_ipv6_address`` - Proxy IP +``site_url`` - Proxy URL + +Outgoing slave connection parameters are : ++++++++ + +``site_url`` - URL of instance +``domain_name`` - Domain name of proxy +``port`` - Port of proxy diff --git a/slapos/recipe/apachephp/template/apache.in b/slapos/recipe/apachephp/template/apache.in index 8dc3ef81d383ccbeb5d1fbd269f4013f64ec7622..a354890425d6f96e946627a659c65299e4c0091c 100644 --- a/slapos/recipe/apachephp/template/apache.in +++ b/slapos/recipe/apachephp/template/apache.in @@ -3,7 +3,6 @@ # Basic server configuration PidFile "%(pid_file)s" -LockFile "%(lock_file)s" Listen %(ip)s:%(port)s PHPINIDir %(php_ini_dir)s ServerAdmin someone@email @@ -25,20 +24,21 @@ CustomLog "%(access_log)s" common <Directory /> Options FollowSymLinks AllowOverride None - Order deny,allow - Deny from all + Require all denied </Directory> <Directory %(document_root)s> Options FollowSymLinks AllowOverride All - Order allow,deny - Allow from all + Require all granted </Directory> DocumentRoot %(document_root)s DirectoryIndex index.html index.php # List of modules +LoadModule unixd_module modules/mod_unixd.so +LoadModule access_compat_module modules/mod_access_compat.so +LoadModule authz_core_module modules/mod_authz_core.so LoadModule authz_host_module modules/mod_authz_host.so LoadModule log_config_module modules/mod_log_config.so LoadModule setenvif_module modules/mod_setenvif.so diff --git a/slapos/recipe/check_port_listening/__init__.py b/slapos/recipe/check_port_listening/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..542072d68f8b9e331dd52f88e8557cc1e406d250 --- /dev/null +++ b/slapos/recipe/check_port_listening/__init__.py @@ -0,0 +1,48 @@ +############################################################################## +# +# Copyright (c) 2011 Vifib SARL and Contributors. All Rights Reserved. +# +# WARNING: This program as such is intended to be used by professional +# programmers who take the whole responsibility of assessing all potential +# consequences resulting from its eventual inadequacies and bugs +# End users who are looking for a ready-to-use solution with commercial +# guarantees and support are strongly adviced to contract a Free Software +# Service Company +# +# This program is Free Software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 3 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +# +############################################################################## +from slapos.recipe.librecipe import GenericBaseRecipe +import sys + +class Recipe(GenericBaseRecipe): + """ + Check listening port promise + """ + + def install(self): + config = dict( + hostname=self.options['hostname'], + port=self.options['port'], + python_path=sys.executable, + ) + + vnc_promise = self.createExecutable( + self.options['path'], + self.substituteTemplate( + self.getTemplateFilename('socket_connection_attempt.py.in'), + config)) + + return [vnc_promise] diff --git a/slapos/recipe/check_port_listening/template/socket_connection_attempt.py.in b/slapos/recipe/check_port_listening/template/socket_connection_attempt.py.in new file mode 100644 index 0000000000000000000000000000000000000000..7c7a2699123fffd451900f6f604b2c74133dd68f --- /dev/null +++ b/slapos/recipe/check_port_listening/template/socket_connection_attempt.py.in @@ -0,0 +1,21 @@ +#!%(python_path)s +# BEWARE: This file is operated by slapgrid +# BEWARE: It will be overwritten automatically +import socket +import sys + +hostname = "%(hostname)s" +port = %(port)s + +connection_okay = False + +try: + s = socket.create_connection((hostname, port)) + connection_okay = True + s.close() +except (socket.error, socket.timeout): + connection_okay = False + +if not connection_okay: + print >> sys.stderr, "%(port)s on %(hostname)s isn't listening" + sys.exit(127) diff --git a/slapos/recipe/generatemac.py b/slapos/recipe/generatemac.py new file mode 100644 index 0000000000000000000000000000000000000000..45abf6d2ee8961b025539b442403af8a62ee2036 --- /dev/null +++ b/slapos/recipe/generatemac.py @@ -0,0 +1,40 @@ + +############################################################################## +# +# Copyright (c) 2010 Vifib SARL and Contributors. All Rights Reserved. +# +# WARNING: This program as such is intended to be used by professional +# programmers who take the whole responsibility of assessing all potential +# consequences resulting from its eventual inadequacies and bugs +# End users who are looking for a ready-to-use solution with commercial +# guarantees and support are strongly adviced to contract a Free Software +# Service Company +# +# This program is Free Software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 3 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +# +############################################################################## +import random + +from slapos.recipe.librecipe import GenericBaseRecipe + +class Recipe(GenericBaseRecipe): + + def __init__(self, buildout, name, options): + # First octet has to represent a locally administered address + octet_list = [254] + [random.randint(0x00, 0xff) for x in range(5)] + options['mac-address'] = ':'.join(['%02x' % x for x in octet_list]) + + def install(self): + return [] diff --git a/slapos/recipe/generic_onetimeupload/__init__.py b/slapos/recipe/generic_onetimeupload/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..97ef798220e045de31c3d917ba7daf1167b182b1 --- /dev/null +++ b/slapos/recipe/generic_onetimeupload/__init__.py @@ -0,0 +1,59 @@ +############################################################################## +# +# Copyright (c) 2011 Vifib SARL and Contributors. All Rights Reserved. +# +# WARNING: This program as such is intended to be used by professional +# programmers who take the whole responsibility of assessing all potential +# consequences resulting from its eventual inadequacies and bugs +# End users who are looking for a ready-to-use solution with commercial +# guarantees and support are strongly adviced to contract a Free Software +# Service Company +# +# This program is Free Software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 3 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +# +############################################################################## +from slapos.recipe.librecipe import GenericBaseRecipe +import binascii +import os +import sys + +class Recipe(GenericBaseRecipe): + """ + kvm instance configuration. + """ + + def __init__(self, buildout, name, options): + options['key'] = binascii.hexlify(os.urandom(24)) + return GenericBaseRecipe.__init__(self, buildout, name, options) + + def install(self): + config = dict( + ip=self.options['ip'], + port=self.options['port'], + onetimeupload_path=self.options['onetimeupload-path'], + shell_path=self.options['shell-path'], + log_path=self.options['log-path'], + image=self.options['image-path'], + key=self.options['key'], + ) + + # Runners + runner_path = self.createExecutable( + self.options['path'], + self.substituteTemplate(self.getTemplateFilename('onetimeupload_run.in'), + config)) + + return [runner_path] + diff --git a/slapos/recipe/nbdserver/template/onetimeupload_run.in b/slapos/recipe/generic_onetimeupload/template/onetimeupload_run.in similarity index 90% rename from slapos/recipe/nbdserver/template/onetimeupload_run.in rename to slapos/recipe/generic_onetimeupload/template/onetimeupload_run.in index 9d6cfe22248f543a22fc43e9c0b5deb2080500a3..a09627d5501af0b3e2d71835ea345c71efc1b37b 100644 --- a/slapos/recipe/nbdserver/template/onetimeupload_run.in +++ b/slapos/recipe/generic_onetimeupload/template/onetimeupload_run.in @@ -1,4 +1,4 @@ -#!/bin/sh +#!%(shell_path)s # BEWARE: This file is operated by slapgrid # BEWARE: It will be overwritten automatically exec %(onetimeupload_path)s -l %(log_path)s %(ip)s %(port)s %(image)s %(key)s diff --git a/slapos/recipe/kvm/__init__.py b/slapos/recipe/kvm/__init__.py index e4d5688562bd5d1590f8922d144ef582d86965ec..54ec9a442a48014717616d341d37e705fcd53bd3 100644 --- a/slapos/recipe/kvm/__init__.py +++ b/slapos/recipe/kvm/__init__.py @@ -1,6 +1,6 @@ ############################################################################## # -# Copyright (c) 2010 Vifib SARL and Contributors. All Rights Reserved. +# Copyright (c) 2011 Vifib SARL and Contributors. All Rights Reserved. # # WARNING: This program as such is intended to be used by professional # programmers who take the whole responsibility of assessing all potential @@ -24,333 +24,53 @@ # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. # ############################################################################## +from slapos.recipe.librecipe import GenericBaseRecipe +import binascii import os import sys -from slapos.recipe.librecipe import BaseSlapRecipe -import subprocess -import binascii -import random -import zc.buildout -import pkg_resources -import ConfigParser -import hashlib - -class Recipe(BaseSlapRecipe): - - # To avoid magic numbers - VNC_BASE_PORT = 5900 - - def _install(self): - """ - Set the connection dictionnary for the computer partition and create a list - of paths to the different wrappers - - Parameters : none - - Returns : List path_list - """ - self.path_list = [] - - self.requirements, self.ws = self.egg.working_set() - self.cron_d = self.installCrond() - - self.ca_conf = self.installCertificateAuthority() - self.key_path, self.certificate_path = self.requestCertificate('noVNC') - - # Install the socket_connection_attempt script - catcher = zc.buildout.easy_install.scripts( - [('check_port_listening', 'slapos.recipe.kvm.socket_connection_attempt', - 'connection_attempt')], - self.ws, - sys.executable, - self.bin_directory, - ) - # Save the check_port_listening script path - check_port_listening_script = catcher[0] - # Get the port_listening_promise template path, and save it - self.port_listening_promise_path = pkg_resources.resource_filename( - __name__, 'template/port_listening_promise.in') - self.port_listening_promise_conf = dict( - check_port_listening_script=check_port_listening_script, - ) - - kvm_conf = self.installKvm(vnc_ip = self.getLocalIPv4Address()) - - vnc_port = Recipe.VNC_BASE_PORT + kvm_conf['vnc_display'] - - noVNC_conf = self.installNoVnc(source_ip = self.getGlobalIPv6Address(), - source_port = 6080, - target_ip = kvm_conf['vnc_ip'], - target_port = vnc_port) - - self.linkBinary() - self.computer_partition.setConnectionDict(dict( - url = "https://[%s]:%s/vnc_auto.html?host=[%s]&port=%s&encrypt=1" % ( - noVNC_conf['source_ip'], - noVNC_conf['source_port'], - noVNC_conf['source_ip'], - noVNC_conf['source_port']), - password = kvm_conf['vnc_passwd'])) - - return self.path_list - - def installKvm(self, vnc_ip): - """ - Create kvm configuration dictionnary and instanciate a wrapper for kvm and - kvm controller - - Parameters : IP the vnc server is listening on - - Returns : Dictionnary kvm_conf - """ - kvm_conf = dict(vnc_ip = vnc_ip) - - connection_found = False - for tap_interface, dummy in self.parameter_dict['ip_list']: - # Get an ip associated to a tap interface - if tap_interface: - connection_found = True - if not connection_found: - raise NotImplementedError("Do not support ip without tap interface") - - kvm_conf['tap_interface'] = tap_interface - - # Disk path - kvm_conf['disk_path'] = os.path.join(self.data_root_directory, - 'virtual.qcow2') - kvm_conf['socket_path'] = os.path.join(self.var_directory, 'qmp_socket') - # XXX Weak password - ##XXX -Vivien: add an option to generate one password for all instances - # and/or to input it yourself - kvm_conf['vnc_passwd'] = binascii.hexlify(os.urandom(4)) - - #XXX pid_file path, database_path, path to python binary and xml path - kvm_conf['pid_file_path'] = os.path.join(self.run_directory, 'pid_file') - kvm_conf['database_path'] = os.path.join(self.data_root_directory, - 'slapmonitor_database') - kvm_conf['python_path'] = sys.executable - kvm_conf['qemu_path'] = self.options['qemu_path'] - #xml_path = os.path.join(self.var_directory, 'slapreport.xml' ) - # Create disk if needed - if not os.path.exists(kvm_conf['disk_path']): - retcode = subprocess.call(["%s create -f qcow2 %s %iG" % ( - self.options['qemu_img_path'], kvm_conf['disk_path'], - int(self.options['disk_size']))], shell=True) - if retcode != 0: - raise OSError, "Disk creation failed!" - - # Options nbd_ip and nbd_port are provided by slapos master - kvm_conf['nbd_ip'] = self.parameter_dict['nbd_ip'] - kvm_conf['nbd_port'] = self.parameter_dict['nbd_port'] - - # First octet has to represent a locally administered address - octet_list = [254] + [random.randint(0x00, 0xff) for x in range(5)] - kvm_conf['mac_address'] = ':'.join(['%02x' % x for x in octet_list]) - - kvm_conf['hostname'] = "slaposkvm" - kvm_conf['smp_count'] = self.options['smp_count'] - kvm_conf['ram_size'] = self.options['ram_size'] - - kvm_conf['vnc_display'] = 1 - - # Instanciate KVM - kvm_template_location = pkg_resources.resource_filename( - __name__, os.path.join( - 'template', 'kvm_run.in')) - - kvm_runner_path = self.createRunningWrapper("kvm", - self.substituteTemplate(kvm_template_location, - kvm_conf)) - - self.path_list.append(kvm_runner_path) - - # Instanciate KVM controller - kvm_controller_template_location = pkg_resources.resource_filename( - __name__, os.path.join( - 'template', - 'kvm_controller_run.in' )) - - kvm_controller_runner_path = self.createRunningWrapper("kvm_controller", - self.substituteTemplate(kvm_controller_template_location, - kvm_conf)) - - self.path_list.append(kvm_controller_runner_path) - - # Instanciate Slapmonitor - ##slapmonitor_runner_path = self.instanciate_wrapper("slapmonitor", - # [database_path, pid_file_path, python_path]) - # Instanciate Slapreport - ##slapreport_runner_path = self.instanciate_wrapper("slapreport", - # [database_path, python_path]) - - # Add VNC promise - self.port_listening_promise_conf.update( - hostname=kvm_conf['vnc_ip'], - port=Recipe.VNC_BASE_PORT + kvm_conf['vnc_display'], +class Recipe(GenericBaseRecipe): + """ + kvm instance configuration. + """ + + def __init__(self, buildout, name, options): + options['passwd'] = binascii.hexlify(os.urandom(4)) + return GenericBaseRecipe.__init__(self, buildout, name, options) + + def install(self): + config = dict( + tap_interface=self.options['tap'], + vnc_ip=self.options['vnc-ip'], + vnc_port=self.options['vnc-port'], + nbd_ip=self.options['nbd-ip'], + nbd_port=self.options['nbd-port'], + disk_path=self.options['disk-path'], + disk_size=self.options['disk-size'], + 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'], + # XXX Weak password + vnc_passwd=self.options['passwd'] ) - self.createPromiseWrapper("vnc_promise", - self.substituteTemplate(self.port_listening_promise_path, - self.port_listening_promise_conf, - ) - ) - return kvm_conf + # Runners + runner_path = self.createExecutable( + self.options['runner-path'], + self.substituteTemplate(self.getTemplateFilename('kvm_run.in'), + config)) - def installNoVnc(self, source_ip, source_port, target_ip, target_port): - """ - Create noVNC configuration dictionnary and instanciate Websockify proxy + controller_path = self.createExecutable( + self.options['controller-path'], + self.substituteTemplate(self.getTemplateFilename('kvm_controller_run.in'), + config)) - Parameters : IP of the proxy, port on which is situated the proxy, - IP of the vnc server, port on which is situated the vnc server, - path to python binary - - Returns : noVNC configuration dictionnary - """ - - noVNC_conf = {} - - noVNC_conf['source_ip'] = source_ip - noVNC_conf['source_port'] = source_port - - execute_arguments = [[ - self.options['websockify'].strip(), - '--web', - self.options['noVNC_location'], - '--key=%s' % (self.key_path), - '--cert=%s' % (self.certificate_path), - '--ssl-only', - '%s:%s' % (source_ip, source_port), - '%s:%s' % (target_ip, target_port)], - [self.certificate_path, self.key_path]] - - self.path_list.extend(zc.buildout.easy_install.scripts([('websockify', - 'slapos.recipe.librecipe.execute', 'execute_wait')], self.ws, sys.executable, - self.wrapper_directory, arguments=execute_arguments)) - - # Add noVNC promise - self.port_listening_promise_conf.update(hostname=noVNC_conf['source_ip'], - port=noVNC_conf['source_port'], - ) - self.createPromiseWrapper("novnc_promise", - self.substituteTemplate(self.port_listening_promise_path, - self.port_listening_promise_conf, - ) - ) - - return noVNC_conf - - def linkBinary(self): - """Links binaries to instance's bin directory for easier exposal""" - for linkline in self.options.get('link_binary_list', '').splitlines(): - if not linkline: - continue - target = linkline.split() - if len(target) == 1: - target = target[0] - path, linkname = os.path.split(target) - else: - linkname = target[1] - target = target[0] - link = os.path.join(self.bin_directory, linkname) - if os.path.lexists(link): - if not os.path.islink(link): - raise zc.buildout.UserError( - 'Target link already %r exists but it is not link' % link) - os.unlink(link) - os.symlink(target, link) - self.logger.debug('Created link %r -> %r' % (link, target)) - self.path_list.append(link) - - def installCertificateAuthority(self, ca_country_code='XX', - ca_email='xx@example.com', ca_state='State', ca_city='City', - ca_company='Company'): - backup_path = self.createBackupDirectory('ca') - self.ca_dir = os.path.join(self.data_root_directory, 'ca') - self._createDirectory(self.ca_dir) - self.ca_request_dir = os.path.join(self.ca_dir, 'requests') - self._createDirectory(self.ca_request_dir) - config = dict(ca_dir=self.ca_dir, request_dir=self.ca_request_dir) - self.ca_private = os.path.join(self.ca_dir, 'private') - self.ca_certs = os.path.join(self.ca_dir, 'certs') - self.ca_crl = os.path.join(self.ca_dir, 'crl') - self.ca_newcerts = os.path.join(self.ca_dir, 'newcerts') - self.ca_key_ext = '.key' - self.ca_crt_ext = '.crt' - for d in [self.ca_private, self.ca_crl, self.ca_newcerts, self.ca_certs]: - self._createDirectory(d) - for f in ['crlnumber', 'serial']: - if not os.path.exists(os.path.join(self.ca_dir, f)): - open(os.path.join(self.ca_dir, f), 'w').write('01') - if not os.path.exists(os.path.join(self.ca_dir, 'index.txt')): - open(os.path.join(self.ca_dir, 'index.txt'), 'w').write('') - openssl_configuration = os.path.join(self.ca_dir, 'openssl.cnf') - config.update( - working_directory=self.ca_dir, - country_code=ca_country_code, - state=ca_state, - city=ca_city, - company=ca_company, - email_address=ca_email, - ) - self._writeFile(openssl_configuration, pkg_resources.resource_string( - __name__, 'template/openssl.cnf.ca.in') % config) - self.path_list.extend(zc.buildout.easy_install.scripts([ - ('certificate_authority', - __name__ + '.certificate_authority', 'runCertificateAuthority')], - self.ws, sys.executable, self.wrapper_directory, arguments=[dict( - openssl_configuration=openssl_configuration, - openssl_binary=self.options['openssl_binary'], - certificate=os.path.join(self.ca_dir, 'cacert.pem'), - key=os.path.join(self.ca_private, 'cakey.pem'), - crl=os.path.join(self.ca_crl), - request_dir=self.ca_request_dir - )])) - # configure backup - backup_cron = os.path.join(self.cron_d, 'ca_rdiff_backup') - open(backup_cron, 'w').write( - '''0 0 * * * %(rdiff_backup)s %(source)s %(destination)s'''%dict( - rdiff_backup=self.options['rdiff_backup_binary'], - source=self.ca_dir, - destination=backup_path)) - self.path_list.append(backup_cron) - - return dict( - ca_certificate=os.path.join(config['ca_dir'], 'cacert.pem'), - ca_crl=os.path.join(config['ca_dir'], 'crl'), - certificate_authority_path=config['ca_dir'] - ) - def requestCertificate(self, 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.ca_request_dir, hash), 'w')) - return key, certificate + return [runner_path, controller_path] - def installCrond(self): - timestamps = self.createDataDirectory('cronstamps') - cron_output = os.path.join(self.log_directory, 'cron-output') - self._createDirectory(cron_output) - catcher = zc.buildout.easy_install.scripts([('catchcron', - __name__ + '.catdatefile', 'catdatefile')], self.ws, sys.executable, - self.bin_directory, arguments=[cron_output])[0] - self.path_list.append(catcher) - cron_d = os.path.join(self.etc_directory, 'cron.d') - crontabs = os.path.join(self.etc_directory, 'crontabs') - self._createDirectory(cron_d) - self._createDirectory(crontabs) - # Use execute from erp5. - wrapper = zc.buildout.easy_install.scripts([('crond', - 'slapos.recipe.librecipe.execute', 'execute')], self.ws, sys.executable, - self.wrapper_directory, arguments=[ - self.options['dcrond_binary'].strip(), '-s', cron_d, '-c', crontabs, - '-t', timestamps, '-f', '-l', '5', '-M', catcher] - )[0] - self.path_list.append(wrapper) - return cron_d diff --git a/slapos/recipe/kvm/certificate_authority.py b/slapos/recipe/kvm/certificate_authority.py deleted file mode 100755 index d05a460649c01edefd09e5caa09f3feab899ddcf..0000000000000000000000000000000000000000 --- a/slapos/recipe/kvm/certificate_authority.py +++ /dev/null @@ -1,114 +0,0 @@ -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) diff --git a/slapos/recipe/kvm/socket_connection_attempt.py b/slapos/recipe/kvm/socket_connection_attempt.py deleted file mode 100644 index dfd9fad4b930518c6ef94a88c69ed40ce6b22539..0000000000000000000000000000000000000000 --- a/slapos/recipe/kvm/socket_connection_attempt.py +++ /dev/null @@ -1,26 +0,0 @@ -import socket -import sys - -def connection_attempt(): - - try: - hostname, port = sys.argv[1:3] - except ValueError: - print >> sys.stderr, """Bad command line. - Usage: %s hostname|ip port""" % sys.argv[0] - sys.exit(1) - - connection_okay = False - - try: - s = socket.create_connection((hostname, port)) - connection_okay = True - s.close() - except (socket.error, socket.timeout): - connection_okay = False - - if not connection_okay: - print >> sys.stderr, "%(port)s on %(ip)s isn't listening" % { - 'port': port, 'ip': hostname - } - sys.exit(127) diff --git a/slapos/recipe/kvm/template/kvm_run.in b/slapos/recipe/kvm/template/kvm_run.in index 3987f1df1135c832be80d5e0b19a9dc9dc3192ea..d4f770a2d6f471b0ab208f67e57816b93a8f82c7 100644 --- a/slapos/recipe/kvm/template/kvm_run.in +++ b/slapos/recipe/kvm/template/kvm_run.in @@ -1,17 +1,55 @@ -#!/bin/sh +#!%(python_path)s # BEWARE: This file is operated by slapgrid # BEWARE: It will be overwritten automatically -# TODO: -net nic,model=virtio, but OS installer has to provide the virtio_net -# module -exec %(qemu_path)s \ - -net nic,macaddr=%(mac_address)s \ - -net tap,ifname=%(tap_interface)s,script=no,downscript=no \ - -smp %(smp_count)s \ - -m %(ram_size)s \ - -cdrom nbd:[%(nbd_ip)s]:%(nbd_port)s \ - -drive file=%(disk_path)s,if=virtio,boot=on \ - -vnc %(vnc_ip)s:1,ipv4,password \ - -boot menu=on \ - -qmp unix:%(socket_path)s,server \ - -pidfile %(pid_file_path)s +# Echo client program +import os +import socket +import subprocess + +def getSocketStatus(host, port): + s = None + for res in socket.getaddrinfo(host, port, + socket.AF_UNSPEC, socket.SOCK_STREAM): + af, socktype, proto, canonname, sa = res + try: + s = socket.socket(af, socktype, proto) + except socket.error, msg: + s = None + continue + try: + s.connect(sa) + except socket.error, msg: + s.close() + s = None + continue + break + return s + +# create disk if doesn't exist +disk_path = '%(disk_path)s' +if not os.path.exists(disk_path): + subprocess.Popen(['%(qemu_img_path)s', 'create' ,'-f', 'qcow2', + '%(disk_path)s', '%(disk_size)sG']) + +kvm_argument_list = ['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=virtio,boot=on', + '-vnc', '%(vnc_ip)s:1,ipv4,password', + '-boot', 'menu=on', + '-qmp', 'unix:%(socket_path)s,server', + '-pidfile', '%(pid_file_path)s', +] + +# Try to connect to NBD server +s = getSocketStatus('%(nbd_ip)s', %(nbd_port)s) +if s is None: + # NBD is not available : launch kvm without it + print 'Warning : Nbd is not available.' + os.execv('%(qemu_path)s', kvm_argument_list) +else: + # NBD is available + kvm_argument_list.extend(['-cdrom', 'nbd:[%(nbd_ip)s]:%(nbd_port)s']) + os.execv('%(qemu_path)s', kvm_argument_list) diff --git a/slapos/recipe/kvm/template/openssl.cnf.ca.in b/slapos/recipe/kvm/template/openssl.cnf.ca.in deleted file mode 100644 index 67067178b951729004cc20c0156bc76d8d968d23..0000000000000000000000000000000000000000 --- a/slapos/recipe/kvm/template/openssl.cnf.ca.in +++ /dev/null @@ -1,350 +0,0 @@ -# -# OpenSSL example configuration file. -# This is mostly being used for generation of certificate requests. -# - -# This definition stops the following lines choking if HOME isn't -# defined. -HOME = . -RANDFILE = $ENV::HOME/.rnd - -# Extra OBJECT IDENTIFIER info: -#oid_file = $ENV::HOME/.oid -oid_section = new_oids - -# To use this configuration file with the "-extfile" option of the -# "openssl x509" utility, name here the section containing the -# X.509v3 extensions to use: -# extensions = -# (Alternatively, use a configuration file that has only -# X.509v3 extensions in its main [= default] section.) - -[ new_oids ] - -# We can add new OIDs in here for use by 'ca', 'req' and 'ts'. -# Add a simple OID like this: -# testoid1=1.2.3.4 -# Or use config file substitution like this: -# testoid2=${testoid1}.5.6 - -# Policies used by the TSA examples. -tsa_policy1 = 1.2.3.4.1 -tsa_policy2 = 1.2.3.4.5.6 -tsa_policy3 = 1.2.3.4.5.7 - -#################################################################### -[ ca ] -default_ca = CA_default # The default ca section - -#################################################################### -[ CA_default ] - -dir = %(working_directory)s # Where everything is kept -certs = $dir/certs # Where the issued certs are kept -crl_dir = $dir/crl # Where the issued crl are kept -database = $dir/index.txt # database index file. -#unique_subject = no # Set to 'no' to allow creation of - # several ctificates with same subject. -new_certs_dir = $dir/newcerts # default place for new certs. - -certificate = $dir/cacert.pem # The CA certificate -serial = $dir/serial # The current serial number -crlnumber = $dir/crlnumber # the current crl number - # must be commented out to leave a V1 CRL -crl = $dir/crl.pem # The current CRL -private_key = $dir/private/cakey.pem # The private key -RANDFILE = $dir/private/.rand # private random number file - -x509_extensions = usr_cert # The extentions to add to the cert - -# Comment out the following two lines for the "traditional" -# (and highly broken) format. -name_opt = ca_default # Subject Name options -cert_opt = ca_default # Certificate field options - -# Extension copying option: use with caution. -# copy_extensions = copy - -# Extensions to add to a CRL. Note: Netscape communicator chokes on V2 CRLs -# so this is commented out by default to leave a V1 CRL. -# crlnumber must also be commented out to leave a V1 CRL. -# crl_extensions = crl_ext - -default_days = 3650 # how long to certify for -default_crl_days = 30 # how long before next CRL -default_md = default # use public key default MD -preserve = no # keep passed DN ordering - -# A few difference way of specifying how similar the request should look -# For type CA, the listed attributes must be the same, and the optional -# and supplied fields are just that :-) -policy = policy_match - -# For the CA policy -[ policy_match ] -countryName = match -stateOrProvinceName = match -organizationName = match -organizationalUnitName = optional -commonName = supplied -emailAddress = optional - -# For the 'anything' policy -# At this point in time, you must list all acceptable 'object' -# types. -[ policy_anything ] -countryName = optional -stateOrProvinceName = optional -localityName = optional -organizationName = optional -organizationalUnitName = optional -commonName = supplied -emailAddress = optional - -#################################################################### -[ req ] -default_bits = 2048 -default_md = sha1 -default_keyfile = privkey.pem -distinguished_name = req_distinguished_name -#attributes = req_attributes -x509_extensions = v3_ca # The extentions to add to the self signed cert - -# Passwords for private keys if not present they will be prompted for -# input_password = secret -# output_password = secret - -# This sets a mask for permitted string types. There are several options. -# default: PrintableString, T61String, BMPString. -# pkix : PrintableString, BMPString (PKIX recommendation before 2004) -# utf8only: only UTF8Strings (PKIX recommendation after 2004). -# nombstr : PrintableString, T61String (no BMPStrings or UTF8Strings). -# MASK:XXXX a literal mask value. -# WARNING: ancient versions of Netscape crash on BMPStrings or UTF8Strings. -string_mask = utf8only - -# req_extensions = v3_req # The extensions to add to a certificate request - -[ req_distinguished_name ] -countryName = Country Name (2 letter code) -countryName_value = %(country_code)s -countryName_min = 2 -countryName_max = 2 - -stateOrProvinceName = State or Province Name (full name) -stateOrProvinceName_value = %(state)s - -localityName = Locality Name (eg, city) -localityName_value = %(city)s - -0.organizationName = Organization Name (eg, company) -0.organizationName_value = %(company)s - -# we can do this but it is not needed normally :-) -#1.organizationName = Second Organization Name (eg, company) -#1.organizationName_default = World Wide Web Pty Ltd - -commonName = Common Name (eg, your name or your server\'s hostname) -commonName_max = 64 - -emailAddress = Email Address -emailAddress_value = %(email_address)s -emailAddress_max = 64 - -# SET-ex3 = SET extension number 3 - -#[ req_attributes ] -#challengePassword = A challenge password -#challengePassword_min = 4 -#challengePassword_max = 20 -# -#unstructuredName = An optional company name - -[ usr_cert ] - -# These extensions are added when 'ca' signs a request. - -# This goes against PKIX guidelines but some CAs do it and some software -# requires this to avoid interpreting an end user certificate as a CA. - -basicConstraints=CA:FALSE - -# Here are some examples of the usage of nsCertType. If it is omitted -# the certificate can be used for anything *except* object signing. - -# This is OK for an SSL server. -# nsCertType = server - -# For an object signing certificate this would be used. -# nsCertType = objsign - -# For normal client use this is typical -# nsCertType = client, email - -# and for everything including object signing: -# nsCertType = client, email, objsign - -# This is typical in keyUsage for a client certificate. -# keyUsage = nonRepudiation, digitalSignature, keyEncipherment - -# This will be displayed in Netscape's comment listbox. -nsComment = "OpenSSL Generated Certificate" - -# PKIX recommendations harmless if included in all certificates. -subjectKeyIdentifier=hash -authorityKeyIdentifier=keyid,issuer - -# This stuff is for subjectAltName and issuerAltname. -# Import the email address. -# subjectAltName=email:copy -# An alternative to produce certificates that aren't -# deprecated according to PKIX. -# subjectAltName=email:move - -# Copy subject details -# issuerAltName=issuer:copy - -#nsCaRevocationUrl = http://www.domain.dom/ca-crl.pem -#nsBaseUrl -#nsRevocationUrl -#nsRenewalUrl -#nsCaPolicyUrl -#nsSslServerName - -# This is required for TSA certificates. -# extendedKeyUsage = critical,timeStamping - -[ v3_req ] - -# Extensions to add to a certificate request - -basicConstraints = CA:FALSE -keyUsage = nonRepudiation, digitalSignature, keyEncipherment - -[ v3_ca ] - - -# Extensions for a typical CA - - -# PKIX recommendation. - -subjectKeyIdentifier=hash - -authorityKeyIdentifier=keyid:always,issuer - -# This is what PKIX recommends but some broken software chokes on critical -# extensions. -#basicConstraints = critical,CA:true -# So we do this instead. -basicConstraints = CA:true - -# Key usage: this is typical for a CA certificate. However since it will -# prevent it being used as an test self-signed certificate it is best -# left out by default. -# keyUsage = cRLSign, keyCertSign - -# Some might want this also -# nsCertType = sslCA, emailCA - -# Include email address in subject alt name: another PKIX recommendation -# subjectAltName=email:copy -# Copy issuer details -# issuerAltName=issuer:copy - -# DER hex encoding of an extension: beware experts only! -# obj=DER:02:03 -# Where 'obj' is a standard or added object -# You can even override a supported extension: -# basicConstraints= critical, DER:30:03:01:01:FF - -[ crl_ext ] - -# CRL extensions. -# Only issuerAltName and authorityKeyIdentifier make any sense in a CRL. - -# issuerAltName=issuer:copy -authorityKeyIdentifier=keyid:always - -[ proxy_cert_ext ] -# These extensions should be added when creating a proxy certificate - -# This goes against PKIX guidelines but some CAs do it and some software -# requires this to avoid interpreting an end user certificate as a CA. - -basicConstraints=CA:FALSE - -# Here are some examples of the usage of nsCertType. If it is omitted -# the certificate can be used for anything *except* object signing. - -# This is OK for an SSL server. -# nsCertType = server - -# For an object signing certificate this would be used. -# nsCertType = objsign - -# For normal client use this is typical -# nsCertType = client, email - -# and for everything including object signing: -# nsCertType = client, email, objsign - -# This is typical in keyUsage for a client certificate. -# keyUsage = nonRepudiation, digitalSignature, keyEncipherment - -# This will be displayed in Netscape's comment listbox. -nsComment = "OpenSSL Generated Certificate" - -# PKIX recommendations harmless if included in all certificates. -subjectKeyIdentifier=hash -authorityKeyIdentifier=keyid,issuer - -# This stuff is for subjectAltName and issuerAltname. -# Import the email address. -# subjectAltName=email:copy -# An alternative to produce certificates that aren't -# deprecated according to PKIX. -# subjectAltName=email:move - -# Copy subject details -# issuerAltName=issuer:copy - -#nsCaRevocationUrl = http://www.domain.dom/ca-crl.pem -#nsBaseUrl -#nsRevocationUrl -#nsRenewalUrl -#nsCaPolicyUrl -#nsSslServerName - -# This really needs to be in place for it to be a proxy certificate. -proxyCertInfo=critical,language:id-ppl-anyLanguage,pathlen:3,policy:foo - -#################################################################### -[ tsa ] - -default_tsa = tsa_config1 # the default TSA section - -[ tsa_config1 ] - -# These are used by the TSA reply generation only. -dir = /etc/pki/tls # TSA root directory -serial = $dir/tsaserial # The current serial number (mandatory) -crypto_device = builtin # OpenSSL engine to use for signing -signer_cert = $dir/tsacert.pem # The TSA signing certificate - # (optional) -certs = $dir/cacert.pem # Certificate chain to include in reply - # (optional) -signer_key = $dir/private/tsakey.pem # The TSA private key (optional) - -default_policy = tsa_policy1 # Policy if request did not specify it - # (optional) -other_policies = tsa_policy2, tsa_policy3 # acceptable policies (optional) -digests = md5, sha1 # Acceptable message digests (mandatory) -accuracy = secs:1, millisecs:500, microsecs:100 # (optional) -clock_precision_digits = 0 # number of digits after dot. (optional) -ordering = yes # Is ordering defined for timestamps? - # (optional, default: no) -tsa_name = yes # Must the TSA name be included in the reply? - # (optional, default: no) -ess_cert_id_chain = no # Must the ESS cert id chain be included? - # (optional, default: no) diff --git a/slapos/recipe/kvm/template/port_listening_promise.in b/slapos/recipe/kvm/template/port_listening_promise.in deleted file mode 100644 index 15fa390d01e38096cfb8a9d01356bf1687e3f740..0000000000000000000000000000000000000000 --- a/slapos/recipe/kvm/template/port_listening_promise.in +++ /dev/null @@ -1,4 +0,0 @@ -#!/usr/bin/env sh - -"%(check_port_listening_script)s" "%(hostname)s" "%(port)s" -exit $? diff --git a/slapos/recipe/kvm/template/slapmonitor_run.in b/slapos/recipe/kvm/template/slapmonitor_run.in deleted file mode 100644 index c790e0904af68481fb1b6f13d9cdbd64454b4ad7..0000000000000000000000000000000000000000 --- a/slapos/recipe/kvm/template/slapmonitor_run.in +++ /dev/null @@ -1,4 +0,0 @@ -#!/bin/sh -# BEWARE: This file is operated by slapgrid -# BEWARE: It will be overwritten automatically -exec %(python_path)s %(slapmonitor_path)s %(pid_file_path)s %(database_path)s diff --git a/slapos/recipe/kvm/template/slapreport_run.in b/slapos/recipe/kvm/template/slapreport_run.in deleted file mode 100644 index 4b3dd99a377d0dcbcf256255c056877811dce397..0000000000000000000000000000000000000000 --- a/slapos/recipe/kvm/template/slapreport_run.in +++ /dev/null @@ -1,4 +0,0 @@ -#!/bin/sh -# BEWARE: This file is operated by slapgrid -# BEWARE: It will be overwritten automatically -exec %(python_path)s %(slapreport_path)s $1 %(database_path)s diff --git a/slapos/recipe/kvm_frontend/__init__.py b/slapos/recipe/kvm_frontend/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..0da2573480b73e3aa0d0c62c739991a0ebc5cd87 --- /dev/null +++ b/slapos/recipe/kvm_frontend/__init__.py @@ -0,0 +1,137 @@ +############################################################################## +# +# Copyright (c) 2011 Vifib SARL and Contributors. All Rights Reserved. +# +# WARNING: This program as such is intended to be used by professional +# programmers who take the whole responsibility of assessing all potential +# consequences resulting from its eventual inadequacies and bugs +# End users who are looking for a ready-to-use solution with commercial +# guarantees and support are strongly adviced to contract a Free Software +# Service Company +# +# This program is Free Software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 3 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +# +############################################################################## +from slapos.recipe.librecipe import GenericBaseRecipe, GenericSlapRecipe +import json +import zc.buildout + +class Recipe(GenericSlapRecipe): + """ + kvm frontend instance configuration. + """ + + def _getRewriteRuleContent(self, slave_instance_list): + """Generate rewrite rules list from slaves list""" + rewrite_rule_list = [] + for slave_instance in slave_instance_list: + self.logger.info("Processing slave instance %s..." % + slave_instance['slave_reference']) + # Check for mandatory fields + if slave_instance.get('host', None) is None: + self.logger.warn('No "host" parameter is defined for %s slave'\ + 'instance. Ignoring it.' % slave_instance['slave_reference']) + continue + if slave_instance.get('port', None) is None: + self.logger.warn('No "host" parameter is defined for %s slave'\ + 'instance. Ignoring it.' % slave_instance['slave_reference']) + continue + + current_slave_dict = dict() + + # Get host, and if IPv6 address, remove "[" and "]" + current_slave_dict['host'] = slave_instance['host'].\ + replace('[', '').replace(']', '') + current_slave_dict['port'] = slave_instance['port'] + + # Check if target is https or http + current_slave_dict['https'] = slave_instance.get('https', 'true') + if current_slave_dict['https'] in GenericBaseRecipe.FALSE_VALUES: + current_slave_dict['https'] = 'false' + # Set reference and resource url + # Reference is raw reference from SlapOS Master, resource is + # URL-compatible name + reference = slave_instance.get('slave_reference') + current_slave_dict['reference'] = reference + current_slave_dict['resource'] = reference.replace('-', '') + rewrite_rule_list.append(current_slave_dict) + return rewrite_rule_list + + def _getProxyTableContent(self, rewrite_rule_list): + """Generate proxy table file content from rewrite rules list""" + proxy_table = dict() + for rewrite_rule in rewrite_rule_list: + proxy_table[rewrite_rule['resource']] = { + 'port': rewrite_rule['port'], + 'host': rewrite_rule['host'], + 'https': rewrite_rule['https'], + } + + proxy_table_content = json.dumps(proxy_table) + return proxy_table_content + + def _install(self): + # Check for mandatory field + if self.options.get('domain', None) is None: + raise zc.buildout.UserError('No domain name specified. Please define ' + 'the "domain" instance parameter.') + # Generate rewrite rules + rewrite_rule_list = self._getRewriteRuleContent( + json.loads(self.options['slave-instance-list'])) + # Create Map + map_content = self._getProxyTableContent(rewrite_rule_list) + map_file = self.createFile(self.options['map-path'], map_content) + + # Create configuration + conf = open(self.getTemplateFilename('kvm-proxy.js'), 'r') + conf_file = self.createFile(self.options['conf-path'], conf.read()) + conf.close() + + # Do we create http dummy server used to redirect to https? + if self.options['http-redirection'] in GenericBaseRecipe.TRUE_VALUES: + http_redirect_server = '1' + else: + http_redirect_server = '' + + config = dict( + ip=self.options['ip'], + port=self.options['port'], + key=self.options['ssl-key-path'], + certificate=self.options['ssl-cert-path'], + name=self.options['domain'], + shell_path=self.options['shell-path'], + node_path=self.options['node-binary'], + node_env=self.options['node-env'], + conf_path=conf_file, + map_path=map_file, + plain_http=http_redirect_server, + ) + + runner_path = self.createExecutable( + self.options['wrapper-path'], + self.substituteTemplate(self.getTemplateFilename('nodejs_run.in'), + config)) + + # Send connection parameters of slave instances + site_url = "https://%s:%s/" % (self.options['domain'], self.options['port']) + for slave in rewrite_rule_list: + self.setConnectionDict( + dict(url="%s%s" % (site_url, slave['resource']), + domainname=self.options['domain'], + port=self.options['port'], + resource=slave['resource']), + slave['reference']) + + return [map_file, conf_file, runner_path] diff --git a/slapos/recipe/kvm_frontend/template/kvm-proxy.js b/slapos/recipe/kvm_frontend/template/kvm-proxy.js new file mode 100644 index 0000000000000000000000000000000000000000..9c83d6930e1732ae9aa1efb75ecced8b93274004 --- /dev/null +++ b/slapos/recipe/kvm_frontend/template/kvm-proxy.js @@ -0,0 +1,128 @@ +/***************************************************************************** +* +* 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. +* +*****************************************************************************/ + +/* Wrapper used to configure the httpproxy node package to proxy + http://myhost/myinstance + to real IP/URL of myinstance +*/ + +var fs = require('fs'), + util = require('util'), + colors = require('colors'), + http = require('http'), + httpProxy = require('http-proxy'), + proxyByUrl = require('proxy-by-url'); + +var listenInterface = process.argv[2], + port = process.argv[3], + sslKeyFile = process.argv[4], + sslCertFile = process.argv[5], + proxyTable = process.argv[6], + redirect = process.argv[7] || false, + isRawIPv6; + +if (process.argv.length < 7) { + console.error("Too few arguments. Exiting."); + process.exit(1); +} + +isRawIPv6 = function checkipv6(str) { + // Inspired by http://forums.intermapper.com/viewtopic.php?t=452 + return (/^\s*((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){5}(((:[0-9A-Fa-f]{1,4}){1,2})|:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){4}(((:[0-9A-Fa-f]{1,4}){1,3})|((:[0-9A-Fa-f]{1,4})?:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){3}(((:[0-9A-Fa-f]{1,4}){1,4})|((:[0-9A-Fa-f]{1,4}){0,2}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){2}(((:[0-9A-Fa-f]{1,4}){1,5})|((:[0-9A-Fa-f]{1,4}){0,3}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){1}(((:[0-9A-Fa-f]{1,4}){1,6})|((:[0-9A-Fa-f]{1,4}){0,4}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(:(((:[0-9A-Fa-f]{1,4}){1,7})|((:[0-9A-Fa-f]{1,4}){0,5}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:)))(%.+)?\s*$/.test(str)); +}(listenInterface); + +/** + * Dummy middleware that throws 404 not found. Does not contain websocket + * middleware. + */ +var middlewareNotFound = function(req, res, proxy) { + res.statusCode = 404; + res.setHeader('Content-Type', 'text/plain'); + res.end('This URL is not known. Please check your URL or contact your ' + + 'SlapOS administrator.'); +}; + +/** + * Create server + */ +var proxyServer = httpProxy.createServer( + // We declare our proxyByUrl middleware + proxyByUrl(proxyTable), + // Then we add your dummy middleware, called when proxyByUrl doesn't find url. + middlewareNotFound, + // And we set HTTPS options for server. HTTP will be forbidden. + { + https: { + key: fs.readFileSync( + sslKeyFile, + 'utf8' + ), + cert: fs.readFileSync( + sslCertFile, + 'utf8' + ) + }, + source: { + host: listenInterface, + port: port + }} +); + +console.log('HTTPS server starting and trying to listen on ' + + listenInterface + ':' + port); +// Release the beast. +proxyServer.listen(port, listenInterface); + +// Dummy HTTP server redirecting to HTTPS. Only has sense if we can use port 80 +if (redirect === '1') { + console.log('HTTP redirect server starting and trying to listen on ' + + listenInterface + ':' + httpPort); + try { + var httpPort = 80; + http.createServer(function(req, res) { + var url; + if (isRawIPv6 === true) { + url = 'https://[' + listenInterface + ']'; + } else { + url = 'https://' + listenInterface; + } + // If non standard port : need to specify it + if (port !== 443) { + url = url + ':' + port; + } + // Add last part of URL + url = url + req.url; + console.log(url); + // Anwser "permanently redirected" + res.statusCode = 301; + res.setHeader('Location', url); + res.end(); + }).listen(httpPort, listenInterface); + } catch (error) { + console.log('Couldn\'t start plain HTTP redirection server : ' + error) + } +} diff --git a/slapos/recipe/kvm_frontend/template/nodejs_run.in b/slapos/recipe/kvm_frontend/template/nodejs_run.in new file mode 100644 index 0000000000000000000000000000000000000000..8384f05deba13f9e6be0a9417dd54a2b945a9eb9 --- /dev/null +++ b/slapos/recipe/kvm_frontend/template/nodejs_run.in @@ -0,0 +1,5 @@ +#!%(shell_path)s +# BEWARE: This file is operated by slapgrid +# BEWARE: It will be overwritten automatically +export NODE_PATH=%(node_env)s +exec %(node_path)s %(conf_path)s %(ip)s %(port)s %(key)s %(certificate)s %(map_path)s %(plain_http)s diff --git a/slapos/recipe/lamp/__init__.py b/slapos/recipe/lamp/__init__.py index 55ae815bcc6c859406b57b352b13c3c0eeef2bfa..710cc076032c2692df652dd9e354ef53695572b0 100644 --- a/slapos/recipe/lamp/__init__.py +++ b/slapos/recipe/lamp/__init__.py @@ -33,6 +33,8 @@ import sys import zc.recipe.egg import urlparse +# Warning : this recipe is deprecated and has been replaced by apachephp. + class BaseRecipe(BaseSlapRecipe): def getTemplateFilename(self, template_name): return pkg_resources.resource_filename(__name__, diff --git a/slapos/recipe/librecipe/generic.py b/slapos/recipe/librecipe/generic.py index 86829c378ceea8061730cf1add7811beff75173c..19729c6352d1018967c7c586c5999d9b646c5776 100644 --- a/slapos/recipe/librecipe/generic.py +++ b/slapos/recipe/librecipe/generic.py @@ -38,6 +38,7 @@ import zc.buildout class GenericBaseRecipe(object): TRUE_VALUES = ['y', 'yes', '1', 'true'] + FALSE_VALUES = ['n', 'no', '0', 'false'] def __init__(self, buildout, name, options): """Recipe initialisation""" diff --git a/slapos/recipe/nbdserver/__init__.py b/slapos/recipe/nbdserver/__init__.py index 3b7e654b90dfa737f885b30c31c102b9ff068474..6f35add02be7a81cd558b7464ca6c125eb7469b0 100644 --- a/slapos/recipe/nbdserver/__init__.py +++ b/slapos/recipe/nbdserver/__init__.py @@ -1,6 +1,6 @@ ############################################################################## # -# Copyright (c) 2010 Vifib SARL and Contributors. All Rights Reserved. +# Copyright (c) 2011 Vifib SARL and Contributors. All Rights Reserved. # # WARNING: This program as such is intended to be used by professional # programmers who take the whole responsibility of assessing all potential @@ -24,59 +24,29 @@ # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. # ############################################################################## -import os +from slapos.recipe.librecipe import GenericBaseRecipe import binascii -from slapos.recipe.librecipe import BaseSlapRecipe - -import pkg_resources - -class Recipe(BaseSlapRecipe): - - def _install(self): - - # Image path - cdrom_iso = os.path.join(self.data_root_directory, 'cdrom.iso') - - #Get the IP list - ip = self.getGlobalIPv6Address() - http_port = 9999 - nbd_port = 1024 - - # Instanciate onetimeupload - onetimeupload_config = {} - onetimeupload_config.update(self.options) - onetimeupload_config['port'] = http_port - onetimeupload_config['ip'] = ip - onetimeupload_config['image'] = cdrom_iso - onetimeupload_config['key'] = binascii.hexlify(os.urandom(24)) - onetimeupload_config['log_path'] = os.path.join(self.log_directory, - 'onetimeupload.log') - - wrapper_template_location = pkg_resources.resource_filename( - __name__, os.path.join( - 'template', 'onetimeupload_run.in')) - onetimeupload_runner_path = self.createRunningWrapper("onetimeupload", - self.substituteTemplate(wrapper_template_location, - onetimeupload_config)) - - # Instanciate qemu - qemu_config = {} - qemu_config.update(self.options) - qemu_config['ip'] = ip - qemu_config['port'] = nbd_port - qemu_config['image'] = cdrom_iso - - wrapper_template_location = pkg_resources.resource_filename( - __name__, os.path.join( - 'template', 'nbdserver_run.in')) - nbdserver_runner_path = self.createRunningWrapper("nbdserver", - self.substituteTemplate(wrapper_template_location, qemu_config)) - - # Publish connection dict - self.computer_partition.setConnectionDict(dict( - upload_connection_string="https://[%s]:%s/" % (ip, http_port), - upload_key=onetimeupload_config['key'], - nbd_connection_string="nbd:[%s]:%s" % (ip, nbd_port), - )) - - return [onetimeupload_runner_path, nbdserver_runner_path] +import os +import sys + +class Recipe(GenericBaseRecipe): + """ + nbd instance configuration. + """ + + def install(self): + config = dict( + ip=self.options['ip'], + port=self.options['port'], + image_path=self.options['image-path'], + qemu_path=self.options['qemu-path'], + shell_path=self.options['shell-path'], + ) + + # Runners + runner_path = self.createExecutable( + self.options['path'], + self.substituteTemplate(self.getTemplateFilename('nbdserver_run.in'), + config)) + + return [runner_path] diff --git a/slapos/recipe/nbdserver/template/nbdserver_run.in b/slapos/recipe/nbdserver/template/nbdserver_run.in index ca93f73b70fd273c59c559104e05eb7cdab3f968..dd7068a0e0e39f1f5e78e5f6fddb5fd5a9f76d48 100644 --- a/slapos/recipe/nbdserver/template/nbdserver_run.in +++ b/slapos/recipe/nbdserver/template/nbdserver_run.in @@ -1,6 +1,6 @@ -#!/bin/sh +#!%(shell_path)s # BEWARE: This file is operated by slapgrid # BEWARE: It will be overwritten automatically # 32767 is the maximum number of connections allowed by the nbd server -exec %(qemu_path)s -b %(ip)s %(image)s -r -t -p %(port)s -e 32767 +exec %(qemu_path)s -b %(ip)s %(image_path)s -r -t -p %(port)s -e 32767 diff --git a/slapos/recipe/novnc/__init__.py b/slapos/recipe/novnc/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..a24588d54c40e571e5c97ab508506356429f096f --- /dev/null +++ b/slapos/recipe/novnc/__init__.py @@ -0,0 +1,54 @@ +############################################################################## +# +# Copyright (c) 2011 Vifib SARL and Contributors. All Rights Reserved. +# +# WARNING: This program as such is intended to be used by professional +# programmers who take the whole responsibility of assessing all potential +# consequences resulting from its eventual inadequacies and bugs +# End users who are looking for a ready-to-use solution with commercial +# guarantees and support are strongly adviced to contract a Free Software +# Service Company +# +# This program is Free Software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 3 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +# +############################################################################## +from slapos.recipe.librecipe import GenericBaseRecipe +import binascii +import os +import sys + +class Recipe(GenericBaseRecipe): + """ + novnc instance configuration. + """ + + def install(self): + runner_path = self.createPythonScript( + self.options['path'], + 'slapos.recipe.librecipe.execute.execute_wait', + [[ + self.options['websockify-path'], + '--web', + self.options['novnc-location'], + '--key=%s' % self.options['ssl-key-path'], + '--cert=%s' % self.options['ssl-cert-path'], + '--ssl-only', + '%s:%s' % (self.options['ip'], self.options['port']), + '%s:%s' % (self.options['vnc-ip'], self.options['vnc-port']), + ], + [self.options['ssl-key-path'], self.options['ssl-cert-path']]], + ) + + return [runner_path] diff --git a/slapos/recipe/request.py b/slapos/recipe/request.py index 1aeb72fbb28d08b2cad311628e1171ec93875d56..52c8454f9bb2fa9c836c30d7e12b31bf93204fac 100644 --- a/slapos/recipe/request.py +++ b/slapos/recipe/request.py @@ -72,14 +72,15 @@ class Recipe(object): partition_parameter_kw[config_parameter] = \ options['config-%s' % config_parameter] - instance = self.request(options['software-url'], software_type, + self.instance = self.request(options['software-url'], software_type, options.get('name', name), partition_parameter_kw=partition_parameter_kw, filter_kw=filter_kw, shared=self.isSlave) self.failed = None for param in self.return_parameters: try: - options['connection-%s' % param] = str(instance.getConnectionParameter(param)) + options['connection-%s' % param] = str( + self.instance.getConnectionParameter(param)) except slapmodule.NotFoundError: options['connection-%s' % param] = '' if self.failed is None: @@ -87,7 +88,16 @@ class Recipe(object): def install(self): if self.failed is not None: - raise KeyError("Connection parameter %r not found." % self.failed) + # Check instance status to know if instance has been deployed + try: + status = self.instance.getState() + except slapmodule.NotFoundError: + status = "not ready yet, please try again" + # XXX-Cedric : currently raise an error. So swallow it... + except AttributeError: + status = "unknown" + raise KeyError("Connection parameter %s not found. " + "Status of requested instance is : %s." % (self.failed, status)) return [] update = install diff --git a/slapos/recipe/slaprunner/__init__.py b/slapos/recipe/slaprunner/__init__.py index 3c74cb5b21bde688d1163612fcff06280a629428..347c13ef9e06c238dc01e6ef326336a684ce4078 100644 --- a/slapos/recipe/slaprunner/__init__.py +++ b/slapos/recipe/slaprunner/__init__.py @@ -40,6 +40,7 @@ class Recipe(BaseSlapRecipe): ipv6 = self.getGlobalIPv6Address() proxy_port = '50000' runner_port = '50000' + cloud9_port = '30000' workdir = self.createDataDirectory('runner') software_root = os.path.join(workdir, 'software') instance_root = os.path.join(workdir, 'instance') @@ -48,7 +49,7 @@ class Recipe(BaseSlapRecipe): instance_root=instance_root, master_url='http://%s:%s/' % (ipv4, proxy_port), computer_id='slaprunner', - partition_amount=2, + partition_amount=7, slapgrid_sr=self.options['slapgrid_sr'], slapgrid_cp=self.options['slapgrid_cp'], slapproxy=self.options['slapproxy'], @@ -64,22 +65,33 @@ class Recipe(BaseSlapRecipe): proxy_port=proxy_port, proxy_database=os.path.join(workdir, 'proxy.db'), git=self.options['git'], + cloud9_url='http://[%s]:%s' % (ipv6, cloud9_port), ssh_client=self.options['ssh_client'], public_key=self.options['public_key'], - private_key=self.options['private_key'] + private_key=self.options['private_key'], + ) config_file = self.createConfigurationFile('slapos.cfg', self.substituteTemplate(pkg_resources.resource_filename(__name__, 'template/slapos.cfg.in'), configuration)) self.path_list.append(config_file) - + environment = dict( PATH=os.path.dirname(self.options['git']) + ':' + os.environ['PATH'], GIT_SSH=self.options['ssh_client'] ) + workdir = os.path.join(workdir, 'project') + if not os.path.exists(workdir): + os.mkdir(workdir) launch_args = [self.options['slaprunner'].strip(), config_file, '--debug'] + cloud9_args = [self.options['node-bin'].strip(), self.options['cloud9'].strip(), + '-l', ipv6, '-p', cloud9_port, '-w', workdir] self.path_list.extend(zc.buildout.easy_install.scripts([('slaprunner', 'slapos.recipe.librecipe.execute', 'executee')], self.ws, sys.executable, self.wrapper_directory, arguments=[launch_args, environment])) - self.setConnectionDict(dict(url='http://[%s]:%s' % (ipv6, runner_port))) + self.path_list.extend(zc.buildout.easy_install.scripts([('cloud9IDE', + 'slapos.recipe.librecipe.execute', 'executee')], self.ws, sys.executable, + self.wrapper_directory, arguments=[cloud9_args, environment])) + self.setConnectionDict(dict(slaprunner_url='http://[%s]:%s' % (ipv6, runner_port), + cloud9_url='http://[%s]:%s' % (ipv6, cloud9_port))) return self.path_list diff --git a/slapos/recipe/slaprunner/template/slapos.cfg.in b/slapos/recipe/slaprunner/template/slapos.cfg.in index 5dc00060eccae8c5842ae6500da3459e4bb9e200..a10da0cf5e11a414df22ed6f8dd6adb7955b6e4b 100644 --- a/slapos/recipe/slaprunner/template/slapos.cfg.in +++ b/slapos/recipe/slaprunner/template/slapos.cfg.in @@ -31,3 +31,6 @@ private_key = %(private_key)s [gitclient] git = %(git)s + +[cloud9_IDE] +cloud9 = %(cloud9_url)s \ No newline at end of file diff --git a/slapos/recipe/softwaretype.py b/slapos/recipe/softwaretype.py index 43ff451f1e8a30c1dfba1b107f22abdb8ed7d655..825a153f1a91a5a48729b6f76232e83a15a53ad0 100644 --- a/slapos/recipe/softwaretype.py +++ b/slapos/recipe/softwaretype.py @@ -64,6 +64,15 @@ class Recipe: # XXX: Lack checking for globality of address return self._getIpAddress(netaddr.valid_ipv6) + def getNetworkInterface(self): + """Returns the network interface available on partition""" + if not 'ip_list' in self.parameter_dict: + raise AttributeError + for name, ip in self.parameter_dict['ip_list']: + if name: + return name + raise AttributeError, "Not network interface found" + def install(self): slap = slapos.slap.slap() slap_connection = self.buildout['slap_connection'] @@ -111,6 +120,8 @@ class Recipe: self.getLocalIPv4Address()) buildout.set('slap-network-information', 'global-ipv6', self.getGlobalIPv6Address()) + buildout.set('slap-network-information', 'network-interface', + self.getNetworkInterface()) # Copy/paste slap_connection buildout.add_section('slap-connection') diff --git a/software/kvm/README.txt b/software/kvm/README.txt new file mode 100644 index 0000000000000000000000000000000000000000..17e9a2cdf5ade017b1a82899e829168524d47291 --- /dev/null +++ b/software/kvm/README.txt @@ -0,0 +1,80 @@ +kvm +=== + +Introduction +------------ + +This software release is used to deploy KVM instances, NBD instances and +Frontend instances of KVM. + +Examples +-------- + +The following examples listhow to request different possible instances of KVM +Software Release from slap console or command line. + +KVM instance (1GB of RAM, 10GB of SSD, one core) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Note that the KVM instance will request a frontend slave instance in order +to be accessible from IPv4. + +KVM instance needs a NBD to fetch disk image at first boot. Working NBD IP/port +has to be specified. + +:: + myawesomekvm = request( + software_release=kvm, + partition_reference="myawesomekvm", + partition_parameter_kw={ + "ndb_ip":"2a01:e35:2e27:460:e2cb:4eff:fed9:48dc", + "ndb_port": 1024 + } + ) + + +KVM+ instance (2GB of RAM, 20GB of SSD, two cores) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +:: + myevenmoreawesomekvm = request( + software_release=kvm, + partition_reference="myevenmoreawesomekvm", + partition_parameter_kw={ + "ndb_ip":"2a01:e35:2e27:460:e2cb:4eff:fed9:48dc", + "ndb_port": 1024 + }, + software_type="kvm+", + ) + + +NBD instance +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +This type of instance will allow to host a disk image that will be used by +any KVM instance. + +:: + mynbd = request( + software_release=kvm, + partition_reference="mynbd", + software_type="nbd", + ) + + +KVM Frontend Master Instance (will host all frontend Slave Instances) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +This type of instance will allow to host any frontend slave instance requested +by KVM instances. Slave instances (and thus KVM instance) will be accessible +at : https://mydomain.com/instancereference . + +:: + mykvmfrontend = request( + software_release=kvm, + partition_reference="mykvmfrontend", + partition_parameter_kw={ + "domain":"mydomain.com" + }, + software_type="frontend", + ) diff --git a/software/kvm/instance-frontend.cfg b/software/kvm/instance-frontend.cfg new file mode 100644 index 0000000000000000000000000000000000000000..277674c850734d60e80fecbc604b724bf59aa44b --- /dev/null +++ b/software/kvm/instance-frontend.cfg @@ -0,0 +1,148 @@ +############################# +# +# Instanciate kvm frontend +# +############################# +[buildout] +parts = + logrotate +# logrotate-entry-frontend + cron + cron-entry-logrotate + ca-frontend + certificate-authority + frontend-promise + publish-kvm-frontend-connection-information + +eggs-directory = ${buildout:eggs-directory} +develop-eggs-directory = ${buildout:develop-eggs-directory} +offline = true + +[rootdirectory] +recipe = slapos.cookbook:mkdirectory +etc = $${buildout:directory}/etc +bin = $${buildout:directory}/bin +srv = $${buildout:directory}/srv +var = $${buildout:directory}/var + +[basedirectory] +recipe = slapos.cookbook:mkdirectory +services = $${rootdirectory:etc}/run +promises = $${rootdirectory:etc}/promise +nodejs-conf = $${rootdirectory:etc}/nodejs +run = $${rootdirectory:var}/run +log = $${rootdirectory:var}/log +ca-dir = $${rootdirectory:srv}/ssl +backup = $${rootdirectory:srv}/backup + +[directory] +recipe = slapos.cookbook:mkdirectory +cron-entries = $${rootdirectory:etc}/cron.d +crontabs = $${rootdirectory:etc}/crontabs +cronstamps = $${rootdirectory:etc}/cronstamps +ca-dir = $${rootdirectory:srv}/ssl +logrotate-backup = $${basedirectory:backup}/logrotate +logrotate-entries = $${rootdirectory:etc}/logrotate.d + +[frontend-instance] +recipe = slapos.cookbook:kvm.frontend +domain = $${ca-frontend:name} +# port = $${slap-parameter:port} +ip = $${slap-network-information:global-ipv6} +port = $${slap-parameter:port} +http-redirection = $${slap-parameter:http-redirection} +ssl-key-path = $${ca-frontend:key-file} +ssl-cert-path = $${ca-frontend:cert-file} +slave-instance-list = $${slap-parameter:slave_instance_list} +map-path = $${basedirectory:nodejs-conf}/proxy_table.json +conf-path = $${basedirectory:nodejs-conf}/kvm-proxy.js +wrapper-path = $${rootdirectory:bin}/kvm_frontend +node-binary = ${nodejs:location}/bin/node +node-env = ${buildout:parts-directory}:${npm-modules:location}/node_modules +shell-path = ${dash:location}/bin/dash + +[frontend-promise] +recipe = slapos.cookbook:check_port_listening +path = $${basedirectory:promises}/frontend_promise +hostname = $${frontend-instance:ip} +port = $${frontend-instance:port} + +[certificate-authority] +recipe = slapos.cookbook:certificate_authority +openssl-binary = ${openssl:location}/bin/openssl +ca-dir = $${basedirectory:ca-dir} +requests-directory = $${cadirectory:requests} +wrapper = $${basedirectory:services}/certificate_authority +ca-private = $${cadirectory:private} +ca-certs = $${cadirectory:certs} +ca-newcerts = $${cadirectory:newcerts} +ca-crl = $${cadirectory:crl} + +[cadirectory] +recipe = slapos.cookbook:mkdirectory +requests = $${basedirectory:ca-dir}/requests/ +private = $${basedirectory:ca-dir}/private/ +certs = $${basedirectory:ca-dir}/certs/ +newcerts = $${basedirectory:ca-dir}/newcerts/ +crl = $${basedirectory:ca-dir}/crl/ + +[ca-frontend] +<= certificate-authority +recipe = slapos.cookbook:certificate_authority.request +key-file = $${basedirectory:nodejs-conf}/nodejs.key +cert-file = $${basedirectory:nodejs-conf}/nodejs.crt +executable = $${frontend-instance:wrapper-path} +wrapper = $${basedirectory:services}/nodejs +# Put domain name +name = $${slap-parameter:domain} + +[cron] +recipe = slapos.cookbook:cron +dcrond-binary = ${dcron:location}/sbin/crond +cron-entries = $${directory:cron-entries} +crontabs = $${directory:crontabs} +cronstamps = $${directory:cronstamps} +catcher = $${cron-simplelogger:wrapper} +binary = $${basedirectory:services}/crond + +[cron-simplelogger] +recipe = slapos.cookbook:simplelogger +wrapper = $${rootdirectory:bin}/cron_simplelogger +log = $${basedirectory:log}/cron.log + +[cron-entry-logrotate] +<= cron +recipe = slapos.cookbook:cron.d +name = logrotate +frequency = 0 0 * * * +command = $${logrotate:wrapper} + +[logrotate] +recipe = slapos.cookbook:logrotate +# Binaries +logrotate-binary = ${logrotate:location}/usr/sbin/logrotate +gzip-binary = ${gzip:location}/bin/gzip +gunzip-binary = ${gzip:location}/bin/gunzip +# Directories +wrapper = $${rootdirectory:bin}/logrotate +conf = $${rootdirectory:etc}/logrotate.conf +logrotate-entries = $${directory:logrotate-entries} +backup = $${directory:logrotate-backup} +state-file = $${rootdirectory:srv}/logrotate.status + +[publish-kvm-frontend-connection-information] +recipe = slapos.cookbook:publish +ip = $${frontend-instance:ip} +port = $${frontend-instance:port} + +[slap-parameter] +# Default value if no port is specified +port = 4443 +http-redirection = 0 + +# [logrotate-entry-frontend] +# <= logrotate +# recipe = slapos.cookbook:logrotate.d +# name = frontend +# log = $${mariadb-instance:error-log} $${mariadb-instance:slow-query-log} +# post = $${mariadb-instance:mysql-binary} --no-defaults -B --socket=$${mariadb-instance:socket} -e "FLUSH LOGS" diff --git a/software/kvm/instance-kvm.cfg b/software/kvm/instance-kvm.cfg new file mode 100644 index 0000000000000000000000000000000000000000..bfd9715ba9cbaecca2f66a5bf87a8e699daa6ea8 --- /dev/null +++ b/software/kvm/instance-kvm.cfg @@ -0,0 +1,136 @@ +############################# +# +# Instanciate kvm +# +############################# +[buildout] +parts = + request-slave-frontend + certificate-authority + kvm-promise + novnc-promise + publish-kvm-connection-information + +eggs-directory = ${buildout:eggs-directory} +develop-eggs-directory = ${buildout:develop-eggs-directory} +offline = true + +[rootdirectory] +recipe = slapos.cookbook:mkdirectory +etc = $${buildout:directory}/etc +bin = $${buildout:directory}/bin +srv = $${buildout:directory}/srv +var = $${buildout:directory}/var + +[basedirectory] +recipe = slapos.cookbook:mkdirectory +services = $${rootdirectory:etc}/run +promises = $${rootdirectory:etc}/promise +novnc-conf = $${rootdirectory:etc}/novnc +run = $${rootdirectory:var}/run +ca-dir = $${rootdirectory:srv}/ssl + +[create-mac] +recipe = slapos.cookbook:generate.mac + +[kvm-instance] +recipe = slapos.cookbook:kvm +vnc-ip = $${slap-network-information:local-ipv4} +vnc-port = 5901 +nbd-ip = $${slap-parameter:nbd_ip} +nbd-port = $${slap-parameter:nbd_port} +tap = $${slap-network-information:network-interface} +disk-path = $${rootdirectory:srv}/virtual.qcow2 +disk-size = 10 +socket-path = $${rootdirectory:var}/qmp_socket +pid-path = $${basedirectory:run}/pid_file +smp-count = 1 +ram-size = 1024 +mac-address = $${create-mac:mac-address} +runner-path = $${basedirectory:services}/kvm +controller-path = $${basedirectory:services}/kvm_controller +shell-path = ${dash:location}/bin/dash +qemu-path = ${kvm:location}/bin/qemu-system-x86_64 +qemu-img-path = ${kvm:location}/bin/qemu-img + +[kvm-promise] +recipe = slapos.cookbook:check_port_listening +path = $${basedirectory:promises}/vnc_promise +hostname = $${kvm-instance:vnc-ip} +port = $${kvm-instance:vnc-port} + +[novnc-instance] +recipe = slapos.cookbook:novnc +path = $${ca-novnc:executable} +ip = $${slap-network-information:global-ipv6} +port = 6080 +vnc-ip = $${kvm-instance:vnc-ip} +vnc-port = $${kvm-instance:vnc-port} +novnc-location = ${noVNC:location} +websockify-path = ${buildout:directory}/bin/websockify +ssl-key-path = $${ca-novnc:key-file} +ssl-cert-path = $${ca-novnc:cert-file} + +[certificate-authority] +recipe = slapos.cookbook:certificate_authority +openssl-binary = ${openssl:location}/bin/openssl +ca-dir = $${basedirectory:ca-dir} +requests-directory = $${cadirectory:requests} +wrapper = $${basedirectory:services}/certificate_authority +ca-private = $${cadirectory:private} +ca-certs = $${cadirectory:certs} +ca-newcerts = $${cadirectory:newcerts} +ca-crl = $${cadirectory:crl} + +[cadirectory] +recipe = slapos.cookbook:mkdirectory +requests = $${basedirectory:ca-dir}/requests/ +private = $${basedirectory:ca-dir}/private/ +certs = $${basedirectory:ca-dir}/certs/ +newcerts = $${basedirectory:ca-dir}/newcerts/ +crl = $${basedirectory:ca-dir}/crl/ + +[ca-novnc] +<= certificate-authority +recipe = slapos.cookbook:certificate_authority.request +key-file = $${basedirectory:novnc-conf}/novnc.key +cert-file = $${basedirectory:novnc-conf}/novnc.crt +executable = $${rootdirectory:bin}/novnc +wrapper = $${basedirectory:services}/websockify + +[novnc-promise] +recipe = slapos.cookbook:check_port_listening +path = $${basedirectory:promises}/novnc_promise +hostname = $${novnc-instance:ip} +port = $${novnc-instance:port} + +[kvm-monitor] +recipe = slapos.cookbook:generic.slapmonitor +db-path = $${rootdirectory:srv}/slapmonitor_database + +[request-common] +recipe = slapos.cookbook:request +software-url = $${slap-connection:software-release-url} +sla = computer_guid +sla-computer_guid = $${slap-connection:computer-id} +server-url = $${slap-connection:server-url} +key-file = $${slap-connection:key-file} +cert-file = $${slap-connection:cert-file} +computer-id = $${slap-connection:computer-id} +partition-id = $${slap-connection:partition-id} + +[request-slave-frontend] +<=request-common +name = SlaveFrontend +software-type = frontend +slave = true +config = host port +config-host = $${novnc-instance:ip} +config-port = $${novnc-instance:port} +return = url resource port domainname + +[publish-kvm-connection-information] +recipe = slapos.cookbook:publish +backend_url = https://[$${novnc-instance:ip}]:$${novnc-instance:port}/vnc_auto.html?host=[$${novnc-instance:ip}]&port=$${novnc-instance:port}&encrypt=1 +url = $${request-slave-frontend:connection-url}/vnc_auto.html?host=$${request-slave-frontend:connection-domainname}&port=$${request-slave-frontend:connection-port}&encrypt=1&path=$${request-slave-frontend:connection-resource} +password = $${kvm-instance:passwd} diff --git a/software/kvm/instance-kvmplus.cfg b/software/kvm/instance-kvmplus.cfg new file mode 100644 index 0000000000000000000000000000000000000000..1babe8bf0c4de089a06c9505d9148b0bf03b4a87 --- /dev/null +++ b/software/kvm/instance-kvmplus.cfg @@ -0,0 +1,27 @@ +############################# +# +# Instanciate kvm+ +# +############################# +[buildout] +extends = instance-kvm.cfg + +[kvm-instance] +recipe = slapos.cookbook:kvm +vnc-ip = $${slap-network-information:local-ipv4} +vnc-port = 5901 +nbd-ip = $${slap-parameter:nbd_ip} +nbd-port = $${slap-parameter:nbd_port} +tap = $${slap-network-information:network-interface} +disk-path = $${rootdirectory:srv}/virtual.qcow2 +disk-size = 20 +socket-path = $${rootdirectory:var}/qmp_socket +pid-path = $${basedirectory:run}/pid_file +smp-count = 2 +ram-size = 2048 +mac-address = $${create-mac:mac-address} +runner-path = $${basedirectory:services}/kvm +controller-path = $${basedirectory:services}/kvm_controller +shell-path = ${dash:location}/bin/dash +qemu-path = ${kvm:location}/bin/qemu-system-x86_64 +qemu-img-path = ${kvm:location}/bin/qemu-img diff --git a/software/kvm/instance-nbd.cfg b/software/kvm/instance-nbd.cfg new file mode 100644 index 0000000000000000000000000000000000000000..9df5cfcf508fd4dab3bb10e32eadbc041979c748 --- /dev/null +++ b/software/kvm/instance-nbd.cfg @@ -0,0 +1,63 @@ +############################# +# +# Instanciate nbdserver +# +############################# +[buildout] +parts = + nbd-promise + onetimeupload-promise + publish-connection-information + +eggs-directory = ${buildout:eggs-directory} +develop-eggs-directory = ${buildout:develop-eggs-directory} +offline = true + +[rootdirectory] +recipe = slapos.cookbook:mkdirectory +etc = $${buildout:directory}/etc +srv = $${buildout:directory}/srv +log = $${buildout:directory}/log + +[basedirectory] +recipe = slapos.cookbook:mkdirectory +services = $${rootdirectory:etc}/run +promises = $${rootdirectory:etc}/promise + +[nbd-instance] +recipe = slapos.cookbook:nbdserver +ip = $${slap-network-information:global-ipv6} +port = 1024 +image-path = $${onetimeupload-instance:image-path} +qemu-path = ${kvm:location}/bin/qemu-nbd +shell-path = ${dash:location}/bin/dash +# XXX TODO: Wait for the iso to be uploaded (execute_wait) +path = $${basedirectory:services}/nbdserver + +[nbd-promise] +recipe = slapos.cookbook:check_port_listening +path = $${basedirectory:promises}/nbd_promise +hostname = $${nbd-instance:ip} +port = $${nbd-instance:port} + +[onetimeupload-instance] +recipe = slapos.cookbook:generic.onetimeupload +ip = $${slap-network-information:global-ipv6} +port = 9999 +image-path = $${rootdirectory:srv}/cdrom.iso +log-path = $${rootdirectory:log}/onetimeupload.log +shell-path = ${dash:location}/bin/dash +onetimeupload-path = ${buildout:bin-directory}/onetimeupload +path = $${basedirectory:services}/onetimeupload + +[onetimeupload-promise] +recipe = slapos.cookbook:check_port_listening +path = $${basedirectory:promises}/onetimeupload_promise +hostname = $${onetimeupload-instance:ip} +port = $${onetimeupload-instance:port} + +[publish-connection-information] +recipe = slapos.cookbook:publish +nbd_url = nbd://[$${nbd-instance:ip}]:$${nbd-instance:port} +upload_url = http://[$${onetimeupload-instance:ip}]:$${onetimeupload-instance:port}/ +upload_key = $${onetimeupload-instance:key} diff --git a/software/kvm/instance.cfg b/software/kvm/instance.cfg index 65041a3f9aff4c2f506ad283d6b5520aec5233ce..8d44ea5663dd9c71d101a97d0a149a16602a6964 100644 --- a/software/kvm/instance.cfg +++ b/software/kvm/instance.cfg @@ -1,22 +1,24 @@ [buildout] parts = - kvminstance + switch-softwaretype eggs-directory = ${buildout:eggs-directory} -develop-eggs-directory = ${buildout:develop-eggs-directory} +develop-eggs-directory = ${buildout:develop-eggs-directory} +offline = true -[kvminstance] -recipe = slapos.cookbook:kvm -qemu_path = ${kvm:location}/bin/qemu-system-x86_64 -qemu_img_path = ${kvm:location}/bin/qemu-img -#slapmonitor_path = ${buildout:bin-directory}/slapmonitor -#slapreport_path = ${buildout:bin-directory}/slapreport -websockify = ${buildout:directory}/bin/websockify -noVNC_location = ${noVNC:location} -openssl_binary = ${openssl:location}/bin/openssl -rdiff_backup_binary = ${buildout:bin-directory}/rdiff-backup -dcrond_binary = ${dcron:location}/sbin/crond +[switch-softwaretype] +recipe = slapos.cookbook:softwaretype +default = ${template-kvm:output} +kvm = ${template-kvm:output} +kvm+ = ${template-kvmplus:output} +nbd = ${template-nbd:output} +frontend = ${template-frontend:output} -smp_count = 1 -ram_size = 1024 -disk_size = 10 +[slap-connection] +# part to migrate to new - separated words +computer-id = $${slap_connection:computer_id} +partition-id = $${slap_connection:partition_id} +server-url = $${slap_connection:server_url} +software-release-url = $${slap_connection:software_release_url} +key-file = $${slap_connection:key_file} +cert-file = $${slap_connection:cert_file} diff --git a/software/kvm/software.cfg b/software/kvm/software.cfg index 541d80f78fdac489e51223edd05641e564ccdf69..5100d46b330b8ffff16631e5af90e1494637068a 100644 --- a/software/kvm/software.cfg +++ b/software/kvm/software.cfg @@ -3,46 +3,37 @@ extensions = buildout-versions extends = + ../../component/gzip/buildout.cfg ../../component/dcron/buildout.cfg + ../../component/logrotate/buildout.cfg ../../component/git/buildout.cfg ../../component/gnutls/buildout.cfg ../../component/libpng/buildout.cfg ../../component/libuuid/buildout.cfg - ../../component/lxml-python/buildout.cfg ../../component/noVNC/buildout.cfg ../../component/openssl/buildout.cfg - ../../component/python-2.7/buildout.cfg - ../../component/rdiff-backup/buildout.cfg - ../../stack/shacache-client.cfg + ../../component/dash/buildout.cfg + ../../component/lxml-python/buildout.cfg + ../../stack/nodejs.cfg develop = ${:parts-directory}/websockify parts = template + dash kvm eggs check-local-eggs - -find-links += - http://www.nexedi.org/static/packages/source/slapos.buildout/ + nodejs + http-proxy + proxy-by-url + npm-modules + dcron + logrotate versions = versions -# Use only quite well working sites. -allow-hosts = - *.nexedi.org - *.python.org - *.sourceforge.net - alastairs-place.net - dist.repoze.org - effbot.org - github.com - peak.telecommunity.com - psutil.googlecode.com - www.dabeaz.com - www.owlfish.com - #XXX-Cedric : Currently, one can only access to KVM using noVNC. # Ideally one should be able to access KVM by using either NoVNC or VNC. # Problem is : no native crypto support in web browsers. So we have to disable ssl @@ -54,15 +45,14 @@ allow-hosts = # Websockify (socket <-> websocket proxy server) when it is ready. # May solve previous XXX depending on the implementation. -#XXX-Cedric: Check status of -# https://www.tiolive.com/nexedi/bug_module/20110819-11F4F70 for -# Chrome >= 14 and Firefox >=7 can access to noVNC. (should be solved) - #XXX-Cedric : add list of keyboard layouts (azerty/us querty/...) parameter to qemu [kvm] recipe = hexagonit.recipe.cmmi url = http://downloads.sourceforge.net/project/kvm/qemu-kvm/0.15.1/qemu-kvm-0.15.1.tar.gz +# XXX-Cedric : Upgrade to 1.0 +# url = http://downloads.sourceforge.net/project/kvm/qemu-kvm/1.0/qemu-kvm-1.0.tar.gz +# md5sum = 00a825db46a70ba8ef9fc95da9cc7c1e md5sum = 8800a7d6b3aa4a168ea7f78dc66c0320 configure-options = --disable-sdl @@ -76,7 +66,7 @@ configure-options = --enable-vnc-png --disable-vnc-jpeg --extra-cflags="-I${gnutls:location}/include -I${libuuid:location}/include -I${zlib:location}/include -I${libpng:location}/include" - --extra-ldflags="-Wl,-rpath -Wl,${glib:location}/lib -L${glib:location}/lib -Wl,-rpath -Wl,${gnutls:location}/lib -L${gnutls:location}/lib -L${gettext:location}/lib -Wl,-rpath -Wl,${gettext:location}/lib -Wl,-rpath -Wl,${libpng:location}/lib -L${libpng:location}/lib -L${libuuid:location}/lib -Wl,-rpath -Wl,${libuuid:location}/lib -L${zlib:location}/lib -Wl,-rpath -Wl,${zlib:location}/lib -lpng -lz -lgnutls" + --extra-ldflags="-Wl,-rpath -Wl,${glib:location}/lib -L${glib:location}/lib -Wl,-rpath -Wl,${gnutls:location}/lib -L${gnutls:location}/lib -Wl,-rpath -Wl,${gpg-error:location}/lib -L${gpg-error:location}/lib -L${gettext:location}/lib -Wl,-rpath -Wl,${gettext:location}/lib -Wl,-rpath -Wl,${libpng:location}/lib -L${libpng:location}/lib -L${libuuid:location}/lib -Wl,-rpath -Wl,${libuuid:location}/lib -L${zlib:location}/lib -Wl,-rpath -Wl,${zlib:location}/lib -lpng -lz -lgnutls" --disable-werror environment = PATH=${pkgconfig:location}/bin:%(PATH)s @@ -86,8 +76,8 @@ environment = # XXX-Cedric : use official egg from pypi when it is released recipe = plone.recipe.command stop-on-error = true -commit = e7363f43443deb9982bdb5c3db50eec475584b06 -repository = https://github.com/desaintmartin/websockify.git +commit = 301f3ae580557da47fa5ea2050aa671ce9c5a1a0 +repository = https://github.com/SlapOS/websockify.git location = ${buildout:parts-directory}/${:_buildout_section_name_} git-binary = ${git:location}/bin/git command = export GIT_SSL_NO_VERIFY=true; (${:git-binary} clone --quiet ${:repository} ${:location} && cd ${:location} && ${:git-binary} reset --hard ${:commit}) || (rm -fr ${:location}; exit 1) @@ -101,83 +91,199 @@ command = grep parts ${buildout:develop-eggs-directory}/websockify.egg-link depends = ${eggs:dummy} [eggs] -python = python2.7 recipe = z3c.recipe.scripts dummy = ${websockify:location} eggs = ${lxml-python:egg} - slapos.cookbook websockify - + slapos.cookbook + slapos.toolbox + +[http-proxy] +# https://github.com/nodejitsu/node-http-proxy +recipe = slapos.recipe.build:download-unpacked +#XXX-Cedric : use upstream when merged +url = https://nodeload.github.com/desaintmartin/node-http-proxy/zipball/master +md5sum = 20204d0b29c2cef26e1c91e99eedca6b + +[proxy-by-url] +# https://github.com/dominictarr/proxy-by-url +recipe = slapos.recipe.build:download-unpacked +#XXX-Cedric : use upstream when merged +url = https://nodeload.github.com/desaintmartin/proxy-by-url/zipball/master +md5sum = c2609948aa708581f93b981b23880314 + +[npm-modules] +recipe = plone.recipe.command +destination = ${buildout:parts-directory}/${:_buildout_section_name_} +location = ${buildout:parts-directory}/${:_buildout_section_name_} +command = + rm -fr ${:destination} && + mkdir -p ${:destination} && + cd ${:destination} && + ${nodejs:location}/bin/node ${nodejs:location}/bin/npm install colors@0.6.0-1 && + ${nodejs:location}/bin/node ${nodejs:location}/bin/npm install socket.io@0.8.7 && + ${nodejs:location}/bin/node ${nodejs:location}/bin/npm install socket.io-client@0.8.7 && + ${nodejs:location}/bin/node ${nodejs:location}/bin/npm install optimist@0.3.1 && + ${nodejs:location}/bin/node ${nodejs:location}/bin/npm install pkginfo@0.2.3 + + +[template-kvm] +recipe = slapos.recipe.template +url = ${:_profile_base_location_}/instance-kvm.cfg +md5sum = b6572c018e44d4676e76805116bcade0 +output = ${buildout:directory}/template-kvm.cfg +mode = 0644 + +[template-kvmplus] +recipe = slapos.recipe.template +url = ${:_profile_base_location_}/instance-kvmplus.cfg +md5sum = 2e35c5b2ac9ee51d8f98fb1199f011c4 +output = ${buildout:directory}/template-kvmplus.cfg +mode = 0644 + +[template-nbd] +recipe = slapos.recipe.template +url = ${:_profile_base_location_}/instance-nbd.cfg +md5sum = 7691fadfc8d4392c58ac1bf0ebd5aaf2 +output = ${buildout:directory}/template-nbd.cfg +mode = 0644 + +[template-frontend] +recipe = slapos.recipe.template +url = ${:_profile_base_location_}/instance-frontend.cfg +md5sum = 123bf4e5bea9e86c03b62e9afb8ca04b +output = ${buildout:directory}/template-frontend.cfg +mode = 0644 + [template] recipe = slapos.recipe.template url = ${:_profile_base_location_}/instance.cfg -md5sum = 298b146e4efce41bfd58b3f85d064ff1 +md5sum = 68788763d23f70f24b9e575871c903a8 output = ${buildout:directory}/template.cfg mode = 0644 -[versions] -zc.buildout = 1.5.3-dev-SlapOS-010 +[networkcache] +# signature certificates of the following uploaders. +# Romain Courteaud +# Cedric de Saint Martin +signature-certificate-list = + -----BEGIN CERTIFICATE----- + MIIB4DCCAUkCADANBgkqhkiG9w0BAQsFADA5MQswCQYDVQQGEwJGUjEZMBcGA1UE + CBMQRGVmYXVsdCBQcm92aW5jZTEPMA0GA1UEChMGTmV4ZWRpMB4XDTExMDkxNTA5 + MDAwMloXDTEyMDkxNTA5MDAwMlowOTELMAkGA1UEBhMCRlIxGTAXBgNVBAgTEERl + ZmF1bHQgUHJvdmluY2UxDzANBgNVBAoTBk5leGVkaTCBnzANBgkqhkiG9w0BAQEF + AAOBjQAwgYkCgYEApYZv6OstoqNzxG1KI6iE5U4Ts2Xx9lgLeUGAMyfJLyMmRLhw + boKOyJ9Xke4dncoBAyNPokUR6iWOcnPHtMvNOsBFZ2f7VA28em3+E1JRYdeNUEtX + Z0s3HjcouaNAnPfjFTXHYj4um1wOw2cURSPuU5dpzKBbV+/QCb5DLheynisCAwEA + ATANBgkqhkiG9w0BAQsFAAOBgQBCZLbTVdrw3RZlVVMFezSHrhBYKAukTwZrNmJX + mHqi2tN8tNo6FX+wmxUUAf3e8R2Ymbdbn2bfbPpcKQ2fG7PuKGvhwMG3BlF9paEC + q7jdfWO18Zp/BG7tagz0jmmC4y/8akzHsVlruo2+2du2freE8dK746uoMlXlP93g + QUUGLQ== + -----END CERTIFICATE----- + -----BEGIN CERTIFICATE----- + MIIB9jCCAV+gAwIBAgIJAO4V/jiMoICoMA0GCSqGSIb3DQEBBQUAMBMxETAPBgNV + BAMMCENPTVAtMjMyMCAXDTEyMDIxNjExMTAyM1oYDzIxMTIwMTIzMTExMDIzWjAT + MREwDwYDVQQDDAhDT01QLTIzMjCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA + wi/3Z8W9pUiegUXIk/AiFDQ0UJ4JFAwjqr+HSRUirlUsHHT+8DzH/hfcTDX1I5BB + D1ADk+ydXjMm3OZrQcXjn29OUfM5C+g+oqeMnYQImN0DDQIOcUyr7AJc4xhvuXQ1 + P2pJ5NOd3tbd0kexETa1LVhR6EgBC25LyRBRae76qosCAwEAAaNQME4wHQYDVR0O + BBYEFMDmW9aFy1sKTfCpcRkYnP6zUd1cMB8GA1UdIwQYMBaAFMDmW9aFy1sKTfCp + cRkYnP6zUd1cMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEFBQADgYEAskbFizHr + b6d3iIyN+wffxz/V9epbKIZVEGJd/6LrTdLiUfJPec7FaxVCWNyKBlCpINBM7cEV + Gn9t8mdVQflNqOlAMkOlUv1ZugCt9rXYQOV7rrEYJBWirn43BOMn9Flp2nibblby + If1a2ZoqHRxoNo2yTmm7TSYRORWVS+vvfjY= + -----END CERTIFICATE----- -slapos.cookbook = 0.37 +[versions] Jinja2 = 2.6 -Werkzeug = 0.8.1 +Werkzeug = 0.8.3 +apache-libcloud = 0.8.0 +async = 0.6.1 buildout-versions = 1.7 +gitdb = 0.5.4 hexagonit.recipe.cmmi = 1.5.0 -lxml = 2.3.2 -meld3 = 0.6.7 +lxml = 2.3.3 +meld3 = 0.6.8 plone.recipe.command = 1.1 +pycrypto = 2.5 +slapos.cookbook = 0.41 +slapos.recipe.build = 0.7 slapos.recipe.template = 2.2 +slapos.toolbox = 0.18 +smmap = 0.8.2 z3c.recipe.scripts = 1.0.1 # Required by: -# slapos.core==0.20 +# slapos.core==0.23 +# slapos.toolbox==0.18 Flask = 0.8 # Required by: -# slapos.cookbook==0.37 +# slapos.toolbox==0.18 +GitPython = 0.3.2.RC1 + +# Required by: +# slapos.cookbook==0.41 PyXML = 0.8.4 # Required by: -# hexagonit.recipe.cmmi==1.5.0 -hexagonit.recipe.download = 1.5.0 +# slapos.toolbox==0.18 +atomize = 0.1.1 + +# Required by: +# slapos.toolbox==0.18 +feedparser = 5.1.1 + +# Required by: +# slapos.cookbook==0.41 +inotifyx = 0.2.0 # Required by: -# slapos.cookbook==0.37 +# slapos.cookbook==0.41 netaddr = 0.7.6 # Required by: -# slapos.core==0.20 -netifaces = 0.6 +# slapos.core==0.23 +netifaces = 0.8 # Required by: # websockify==0.1-dev numpy = 1.6.1 # Required by: -# slapos.cookbook==0.37 -# slapos.core==0.20 -# zc.buildout==1.5.3-dev-SlapOS-010 -# zc.recipe.egg==1.3.2 +# slapos.toolbox==0.18 +paramiko = 1.7.7.1 + +# Required by: +# slapos.toolbox==0.18 +psutil = 0.4.1 + +# Required by: +# slapos.cookbook==0.41 +# slapos.core==0.23 +# slapos.toolbox==0.18 setuptools = 0.6c12dev-r88846 # Required by: -# slapos.cookbook==0.37 -slapos.core = 0.20 +# slapos.cookbook==0.41 +# slapos.toolbox==0.18 +slapos.core = 0.23 # Required by: -# slapos.core==0.20 -supervisor = 3.0a10 +# slapos.core==0.23 +supervisor = 3.0a12 # Required by: -# slapos.cookbook==0.37 +# slapos.cookbook==0.41 +# slapos.toolbox==0.18 xml-marshaller = 0.9.7 # Required by: -# slapos.cookbook==0.37 +# slapos.cookbook==0.41 zc.recipe.egg = 1.3.2 # Required by: -# slapos.core==0.20 +# slapos.core==0.23 zope.interface = 3.8.0 \ No newline at end of file diff --git a/software/nbd/instance.cfg b/software/nbd/instance.cfg deleted file mode 100644 index dcc2d0a62cecc520e7d3eb37c39af67d713d091e..0000000000000000000000000000000000000000 --- a/software/nbd/instance.cfg +++ /dev/null @@ -1,11 +0,0 @@ -[buildout] -parts = - nbdserverinstance - -eggs-directory = ${buildout:eggs-directory} -develop-eggs-directory = ${buildout:develop-eggs-directory} - -[nbdserverinstance] -recipe = ${instance-recipe:egg}:${instance-recipe:module} -qemu_path = ${nbdserver:location}/bin/qemu-nbd -onetimeupload_path = ${buildout:bin-directory}/onetimeupload diff --git a/software/nbd/software.cfg b/software/nbd/software.cfg deleted file mode 100644 index 2735046e37ff296efde2ea571b7584131d6fe314..0000000000000000000000000000000000000000 --- a/software/nbd/software.cfg +++ /dev/null @@ -1,20 +0,0 @@ -[buildout] - -extends = - ../../stack/nbd.cfg - ../../stack/shacache-client.cfg - -parts += - template - -[template] -recipe = slapos.recipe.template -url = ${:_profile_base_location_}/instance.cfg -md5sum = 82e948e1c0cb0d5540ef185edeef3ec3 -output = ${buildout:directory}/template.cfg -mode = 0644 - -[versions] -# XXX-CEDRIC Quick and dirty workaround to avoid m2crypto problems. -# should not be used elsewhere unless for urgent cases. -slapos.libnetworkcache = 0.2 diff --git a/software/slaprunner/instance.cfg b/software/slaprunner/instance.cfg index f9427ba5b784e6b1a80dd1c813a584f300376d98..182887a686342b03b7a68db2bd14de3dc3cf0242 100644 --- a/software/slaprunner/instance.cfg +++ b/software/slaprunner/instance.cfg @@ -16,6 +16,8 @@ slapgrid_cp = ${buildout:directory}/bin/slapgrid-cp slapproxy = ${buildout:directory}/bin/slapproxy supervisor = ${buildout:directory}/bin/slapgrid-supervisorctl git = ${git:location}/bin/git +node-bin = ${nodejs-0.4:location}/bin/node +cloud9 = ${cloud9:location}/bin/cloud9.js ssh_client = $${sshkeys-dropbear:wrapper} public_key = $${sshkeys-dropbear:public-key} private_key = $${sshkeys-dropbear:private-key} @@ -62,4 +64,4 @@ bin = $${buildout:directory}/bin/ recipe = slapos.cookbook:mkdirectory sshkeys = $${rootdirectory:srv}/sshkeys services = $${rootdirectory:etc}/run/ -ssh = $${rootdirectory:etc}/ssh/ +ssh = $${rootdirectory:etc}/ssh/ \ No newline at end of file diff --git a/software/slaprunner/software.cfg b/software/slaprunner/software.cfg index 8a2e90bb72e9f594dcafa5111ebc8b20e8f445e2..e6ee0edd7a7d68ece8108b9dee768aeca0d2030e 100644 --- a/software/slaprunner/software.cfg +++ b/software/slaprunner/software.cfg @@ -1,4 +1,5 @@ [buildout] + extensions = buildout-versions @@ -8,6 +9,7 @@ extends = ../../stack/shacache-client.cfg ../../component/dropbear/buildout.cfg ../../component/git/buildout.cfg + ../../component/cloud9/buildout.cfg parts = template @@ -31,7 +33,7 @@ recipe = slapos.recipe.template url = ${:_profile_base_location_}/instance.cfg output = ${buildout:directory}/template.cfg mode = 0644 -md5sum = cd69efd5c3a7e9adca7387b9a401590a +md5sum = 7cfd248cdc6fa6cbb4957d25a0aed884 [eggs] eggs += @@ -60,6 +62,7 @@ signature-certificate-list = [versions] # Use SlapOS patched zc.buildout zc.buildout = 1.6.0-dev-SlapOS-003 + Jinja2 = 2.6 Werkzeug = 0.8.3 apache-libcloud = 0.8.0 @@ -68,68 +71,65 @@ buildout-versions = 1.7 gitdb = 0.5.4 hexagonit.recipe.cmmi = 1.5.0 meld3 = 0.6.8 +plone.recipe.command = 1.1 pycrypto = 2.5 -slapos.cookbook = 0.39 +slapos.cookbook = 0.45 slapos.libnetworkcache = 0.12 -slapos.recipe.template = 2.2 -slapos.toolbox = 0.18 +slapos.recipe.template = 2.3 +slapos.toolbox = 0.20 smmap = 0.8.2 # Required by: -# slapos.core==0.22 +# slapos.core==0.24 Flask = 0.8 # Required by: -# slapos.toolbox==0.18 +# slapos.toolbox==0.20 GitPython = 0.3.2.RC1 # Required by: -# slapos.cookbook==0.39 +# slapos.cookbook==0.45 PyXML = 0.8.4 # Required by: -# slapos.toolbox==0.18 +# slapos.toolbox==0.20 atomize = 0.1.1 # Required by: -# slapos.toolbox==0.18 -feedparser = 5.1 - -# Required by: -# hexagonit.recipe.cmmi==1.5.0 -hexagonit.recipe.download = 1.5.0 +# slapos.toolbox==0.20 +feedparser = 5.1.1 # Required by: -# slapos.cookbook==0.39 +# slapos.cookbook==0.45 inotifyx = 0.2.0 # Required by: -# slapos.cookbook==0.39 -# slapos.core==0.22 +# slapos.cookbook==0.45 +# slapos.core==0.24 # xml-marshaller==0.9.7 -lxml = 2.3.3 +lxml = 2.3.4 # Required by: -# slapos.cookbook==0.39 +# slapos.cookbook==0.45 netaddr = 0.7.6 # Required by: -# slapos.core==0.22 +# slapos.core==0.24 netifaces = 0.8 # Required by: -# slapos.toolbox==0.18 +# slapos.toolbox==0.20 paramiko = 1.7.7.1 # Required by: -# slapos.toolbox==0.18 +# slapos.toolbox==0.20 psutil = 0.4.1 # Required by: -# slapos.cookbook==0.39 -# slapos.core==0.22 +# slapos.cookbook==0.45 +# slapos.core==0.24 # slapos.libnetworkcache==0.12 -# slapos.toolbox==0.18 +# slapos.toolbox==0.20 # supervisor==3.0a12 # zc.buildout==1.6.0-dev-SlapOS-003 # zc.recipe.egg==1.3.2 @@ -137,21 +137,21 @@ psutil = 0.4.1 setuptools = 0.6c12dev-r88846 # Required by: -# slapos.cookbook==0.39 -slapos.core = 0.22 +# slapos.cookbook==0.45 +slapos.core = 0.24 # Required by: -# slapos.core==0.22 +# slapos.core==0.24 supervisor = 3.0a12 # Required by: -# slapos.cookbook==0.39 +# slapos.cookbook==0.45 xml-marshaller = 0.9.7 # Required by: -# slapos.cookbook==0.39 +# slapos.cookbook==0.45 zc.recipe.egg = 1.3.2 # Required by: -# slapos.core==0.22 -zope.interface = 3.8.0 +# slapos.core==0.24 +zope.interface = 3.8.0 \ No newline at end of file diff --git a/stack/lamp/buildout.cfg b/stack/lamp/buildout.cfg index b17f8a7b38267a00e274c9e55d7fd8479a80a20f..51d91cad404946c79c030e8e4ca72597704303ca 100644 --- a/stack/lamp/buildout.cfg +++ b/stack/lamp/buildout.cfg @@ -51,6 +51,7 @@ extends = ../../component/mydumper/buildout.cfg ../../component/mysql-python/buildout.cfg ../../component/dropbear/buildout.cfg + ../slapos.cfg versions = versions @@ -83,7 +84,7 @@ mode = 0644 recipe = slapos.recipe.template url = ${:_profile_base_location_}/instance-apache-php.cfg output = ${buildout:directory}/template-apache-php.cfg -md5sum = 45bc82dc468e7f418d95c846d1a33d74 +md5sum = 8ebed1e26127c066e5b69372e69e6c38 mode = 0644 [template-apache-backup] diff --git a/stack/lamp/instance-apache-php.cfg b/stack/lamp/instance-apache-php.cfg index 77e266f21def3d68a1ee1cfbe374e9eb4bb86ea6..d77125de685bf8ea09133792e50442de11f4489a 100644 --- a/stack/lamp/instance-apache-php.cfg +++ b/stack/lamp/instance-apache-php.cfg @@ -12,6 +12,7 @@ parts = logrotate-entry-stunnel cron cron-entry-logrotate + promise eggs-directory = ${buildout:eggs-directory} develop-eggs-directory = ${buildout:develop-eggs-directory} @@ -21,6 +22,12 @@ offline = true recipe = slapos.cookbook:publishurl url = http://[$${apache-php:ip}]:$${apache-php:port}/ +[promise] +recipe = slapos.cookbook:check_port_listening +path = $${basedirectory:promises}/apache +hostname = $${apache-php:ip} +port = $${apache-php:port} + [mariadb-urlparse] recipe = slapos.cookbook:urlparse url = $${request-mariadb:connection-url} @@ -43,8 +50,6 @@ tmp-dir = $${directory:tmp-php} httpd-conf = $${rootdirectory:etc}/apache.conf wrapper = $${basedirectory:services}/apache -promise = $${basedirectory:promises}/apache - httpd-binary = ${apache:location}/bin/httpd mysql-username = $${mariadb-urlparse:username} diff --git a/stack/nodejs.cfg b/stack/nodejs.cfg new file mode 100644 index 0000000000000000000000000000000000000000..04b47bc9b8947ab717c769451a4d73c8178613cd --- /dev/null +++ b/stack/nodejs.cfg @@ -0,0 +1,18 @@ +[buildout] +extends = + ../component/nodejs/buildout.cfg + ../component/lxml-python/buildout.cfg + ../stack/slapos.cfg + +versions = versions + +parts = + eggs + nodejs + npm + +[eggs] +recipe = zc.recipe.egg +eggs = + slapos.cookbook + ${lxml-python:egg} diff --git a/stack/slapos.cfg b/stack/slapos.cfg index 83267a377f3333aa6929e326378a7f406c737f63..2054ec53eaaea2f8c5b4eb9f70eb57f1bb43fe1f 100644 --- a/stack/slapos.cfg +++ b/stack/slapos.cfg @@ -18,6 +18,7 @@ exec-sitecustomize = false # Add location for modified non-official slapos.buildout find-links += http://www.nexedi.org/static/packages/source/slapos.buildout/ + http://www.nexedi.org/static/packages/source/hexagonit.recipe.download/ # Use only quite well working sites. allow-hosts += @@ -38,3 +39,12 @@ allow-hosts += # Unzippig of eggs is required, as SlapOS do not yet provide nicely working # development / fast switching environment for whole software unzip = true + +versions = versions + +[versions] +# Use patched hexagonit.recipe.download from +# https://github.com/SlapOS/hexagonit.recipe.download +hexagonit.recipe.download = 1.5.1-dev-slapos-001 +# Use SlapOS patched zc.buildout +zc.buildout = 1.6.0-dev-SlapOS-004