diff --git a/setup.py b/setup.py index 92efe332e706ef68d727a737ad0fb3021d3c8829..0d609603b56a698eafcd636110641da49db54afa 100644 --- a/setup.py +++ b/setup.py @@ -43,7 +43,7 @@ setup(name=name, 'slapos.core', # as it provides library for slap 'xml_marshaller', # needed to dump information 'GitPython', #needed for git manipulation into slaprunner - 'netifaces', 'rpdb' + 'netifaces', ] + additional_install_requires, extras_require = { 'lampconfigure': ["mysql-python"], #needed for MySQL Database access diff --git a/slapos/resiliencytest/suites/erp5.py b/slapos/resiliencytest/suites/erp5.py index 9e1e116a51de778b2d6e391ab2f766aedc9dbc22..959f42c650e880b11de4a59154435ed22900fb31 100644 --- a/slapos/resiliencytest/suites/erp5.py +++ b/slapos/resiliencytest/suites/erp5.py @@ -66,9 +66,9 @@ class ERP5TestSuite(SlaprunnerTestSuite): self.logger.info('Retrieved erp5 url is:\n%s' % url) return url - def _connectToERP5(self, url, data=None): + def _connectToERP5(self, url, data=None, password='insecure'): auth_handler = urllib2.HTTPBasicAuthHandler() - auth_handler.add_password(realm='Zope', uri=url, user='zope', passwd='insecure') + auth_handler.add_password(realm='Zope', uri=url, user='zope', passwd=password) ssl_context = ssl._create_unverified_context() opener_director = urllib2.build_opener( auth_handler, @@ -85,12 +85,12 @@ class ERP5TestSuite(SlaprunnerTestSuite): raise NotHttpOkException(result.getcode()) return result.read() - def _createRandomERP5Document(self): + def _createRandomERP5Document(self, password='insecure'): """ Create a document with random content in erp5 site.""" # XXX currently only sets erp5 site title. # XXX could be simplified to /erp5/setTitle?title=slapos erp5_site_title = self.slaprunner_user - url = "%s/erp5?__ac_name=zope&__ac_password=insecure" % self._getERP5Url() + url = "%s/erp5?__ac_name=zope&__ac_password=%s" % (self._getERP5Url(), password) form = 'title%%3AUTF-8:string=%s&manage_editProperties%%3Amethod=Save+Changes' % erp5_site_title self._connectToERP5(url, form) return erp5_site_title @@ -127,6 +127,9 @@ class ERP5TestSuite(SlaprunnerTestSuite): time.sleep(15) + # In case erp5 bootstrap (in erp5-cluster) couldn't connect to zope through HAProxy + self._connectToSlaprunner('/startAllPartition') + def generateData(self): self.slaprunner_password = ''.join( random.SystemRandom().sample(string.ascii_lowercase, 8) @@ -163,6 +166,7 @@ class ERP5TestSuite(SlaprunnerTestSuite): ) self._login() + time.sleep(10) self._gitClone() self._openSoftwareRelease('erp5') @@ -175,6 +179,7 @@ class ERP5TestSuite(SlaprunnerTestSuite): self._deployInstance() self._deployInstance() self._deployInstance() + self._deployInstance() self._editHAProxyconfiguration() diff --git a/slapos/resiliencytest/suites/erp5cluster.py b/slapos/resiliencytest/suites/erp5cluster.py new file mode 100644 index 0000000000000000000000000000000000000000..89a68261a97b244c9c40b86b23508b079fa377e0 --- /dev/null +++ b/slapos/resiliencytest/suites/erp5cluster.py @@ -0,0 +1,125 @@ +# -*- coding: utf-8 -*- +############################################################################## +# +# Copyright (c) 2014 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 json +import urllib +import time + +from .erp5 import ERP5TestSuite + +class ERP5ClusterTestSuite(ERP5TestSuite): + """ + Run ERP5 (erp5-cluster flavor) inside Slaprunner Resiliency Test. + Note: requires specific kernel allowing long shebang paths. + """ + def _setERP5InstanceParameter(self): + """ + Set inside of slaprunner the instance parameter to use to deploy erp5 instance. + """ + self._connectToSlaprunner( + resource='saveParameterXml', + data='software_type=create-erp5-site¶meter=%3C%3Fxml+version%3D%221.0%22+encoding%3D%22utf-8%22%3F%3E%0A%3Cinstance%3E%0A%3Cparameter+id%3D%22_%22%3E%7B%22zodb-zeo%22%3A+%7B%22backup-periodicity%22%3A+%22minutely%22%7D%2C+%22mariadb%22%3A+%7B%22backup-periodicity%22%3A+%22minutely%22%7D%7D%3C%2Fparameter%3E%0A%3C%2Finstance%3E%0A' + ) + + def _getERP5Url(self): + """ + Return the backend url of erp5 instance. + Note: it is not connection parameter of slaprunner, + but connection parameter of what is inside of webrunner. + """ + data = self._connectToSlaprunner( + resource='getConnectionParameter/slappart7' + ) + url = json.loads(json.loads(data)['_'])['default-v6'] + self.logger.info('Retrieved erp5 url is:\n%s' % url) + return url + + def _getERP5Password(self): + data = self._connectToSlaprunner( + resource='getConnectionParameter/slappart0' + ) + password = json.loads(json.loads(data)['_'])['inituser-password'] + self.logger.info('Retrieved erp5 password is:\n%s' % password) + return password + + def _editHAProxyconfiguration(self): + """ + XXX pure hack. + haproxy processes don't support long path for sockets. + Edit haproxy configuration file of erp5 to make it compatible with long paths + Then restart haproxy. + """ + self.logger.info('Editing HAProxy configuration...') + + result = self._connectToSlaprunner( + resource='/getFileContent', + data='file=runner_workdir%2Finstance%2Fslappart7%2Fetc%2Fhaproxy.cfg' + ) + file_content = json.loads(result)['result'] + file_content = file_content.replace('var/run/haproxy.sock', 'ha.sock') + self._connectToSlaprunner( + resource='/saveFileContent', + data='file=runner_workdir%%2Finstance%%2Fslappart7%%2Fetc%%2Fhaproxy.cfg&content=%s' % urllib.quote(file_content) + ) + + # Restart HAProxy + self._connectToSlaprunner( + resource='/startStopProccess/name/slappart7:haproxy/cmd/STOPPED' + ) + + time.sleep(15) + + def _gitClone(self): + ERP5TestSuite._gitClone(self) + self._connectToSlaprunner( + resource='/newBranch', + data='project=workspace%2Fslapos&name=erp5-cluster&create=0' + ) + + def _connectToERP5(self, url, data=None, password=None): + if password is None: + password = self._getERP5Password() + return ERP5TestSuite._connectToERP5(self, url, data, password) + + def _createRandomERP5Document(self, password=None): + if password is None: + password = self._getERP5Password() + + return ERP5TestSuite._createRandomERP5Document(self, password) + + def _getCreatedERP5Document(self): + """ Fetch and return content of ERP5 document created above.""" + url = "%s/erp5/getTitle" % self._getERP5Url() + return self._connectToERP5(url) + +def runTestSuite(*args, **kwargs): + """ + Run ERP5 erp5-cluster Resiliency Test. + """ + return ERP5ClusterTestSuite(*args, **kwargs).runTestSuite() + diff --git a/slapos/runner/utils.py b/slapos/runner/utils.py index 214dac425917a6e03abc53ad75cd85cd4af9783d..b5a5ad0c0c23040cb5fd019a1cc0c4d8ee3c8fc6 100644 --- a/slapos/runner/utils.py +++ b/slapos/runner/utils.py @@ -460,6 +460,13 @@ def svcStopAll(config): except: pass +def svcStartAll(config): + """Start all Instance processes on this computer""" + try: + return Popen([config['slapos'], 'node', 'supervisorctl', '--cfg', config['configuration_file_path'], + 'start', 'all']).communicate()[0] + except: + pass def removeInstanceRoot(config): """Clean instance directory and stop all its running processes""" diff --git a/slapos/runner/views.py b/slapos/runner/views.py index 1a4d8a0e2f54e7035ed44d67e7aa432931664bce..44986258d2a42d59a20e5792c18ece8be2297bd1 100644 --- a/slapos/runner/views.py +++ b/slapos/runner/views.py @@ -30,7 +30,7 @@ from slapos.runner.utils import (checkSoftwareFolder, configNewSR, saveSession, saveBuildAndRunParams, setMiniShellHistory, stopProxy, - svcStartStopProcess, svcStopAll, tail, + svcStartStopProcess, svcStartAll, svcStopAll, tail, updateInstanceParameter) from slapos.runner.fileBrowser import FileBrowser @@ -252,6 +252,9 @@ def stopAllPartition(): svcStopAll(app.config) return redirect(url_for('inspectInstance')) +def startAllPartition(): + svcStartAll(app.config) + return redirect(url_for('inspectInstance')) def tailProcess(process): return render_template('processTail.html', @@ -790,6 +793,8 @@ app.add_url_rule("/getFileLog", 'getFileLog', getFileLog, methods=['POST']) app.add_url_rule('/stopAllPartition', 'stopAllPartition', stopAllPartition, methods=['GET']) +app.add_url_rule('/startAllPartition', 'startAllPartition', + startAllPartition, methods=['GET']) app.add_url_rule('/tailProcess/name/<process>', 'tailProcess', tailProcess, methods=['GET']) app.add_url_rule('/startStopProccess/name/<process>/cmd/<action>',