Commit 863dceac authored by Rafael Monnerat's avatar Rafael Monnerat

cleanup: erp5_update was replaced by bootstrap script.

parent d6bc2dbf
......@@ -106,7 +106,6 @@ setup(name=name,
'erp5.bootstrap = slapos.recipe.erp5_bootstrap:Recipe',
'erp5.promise = slapos.recipe.erp5_promise:Recipe',
'erp5.test = slapos.recipe.erp5_test:Recipe',
'erp5.update = slapos.recipe.erp5_update:Recipe',
'erp5scalabilitytestbed = slapos.recipe.erp5scalabilitytestbed:Recipe',
'erp5testnode = slapos.recipe.erp5testnode:Recipe',
'firefox = slapos.recipe.firefox:Recipe',
......
##############################################################################
#
# 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.
#
##############################################################################
import urlparse
from slapos.recipe.librecipe import GenericSlapRecipe
class Recipe(GenericSlapRecipe):
def _install(self):
self.logger.warn('DEPRECATED: Please update your configuration to use erp5.promise and erp5.bootstrap instead.')
conversion_server = None
if 'cloudooo-url' in self.options and self.options['cloudooo-url']:
parsed = urlparse.urlparse(self.options['cloudooo-url'])
conversion_server = "%s:%s" % (parsed.hostname, parsed.port)
memcached = None
if 'memcached-url' in self.options and self.options['memcached-url']:
parsed = urlparse.urlparse(self.options['memcached-url'])
memcached = "%s:%s" % (parsed.hostname, parsed.port)
kumofs = None
if 'kumofs-url' in self.options and self.options['kumofs-url']:
parsed = urlparse.urlparse(self.options['kumofs-url'])
kumofs = "%s:%s" % (parsed.hostname, parsed.port)
parsed = urlparse.urlparse(self.options['mysql-url'])
mysql_connection_string = "%(database)s@%(hostname)s:%(port)s "\
"%(username)s %(password)s" % dict(
database=parsed.path.split('/')[1],
hostname=parsed.hostname,
port=parsed.port,
username=parsed.username,
password=parsed.password
)
parsed = urlparse.urlparse(self.options['url'])
zope_user = parsed.username
zope_password = parsed.password
zope_host = '%s:%s' % (parsed.hostname, parsed.port)
bt5_list = []
if len(self.parameter_dict.get("bt5_list", "").strip()):
bt5_list = self.parameter_dict["bt5_list"].split()
elif self.parameter_dict.get("flavour", "default") == 'configurator':
bt5_list = self.options['configurator-bt5-list'].split()
bt5_repository_list = self.parameter_dict.get("bt5_repository_list",
"").split() or self.options['bt5-repository-list'].split()
script = self.createPythonScript(self.options['update-wrapper'],
__name__+'.erp5.updateERP5', [
self.options['site-id'], mysql_connection_string,
[zope_user, zope_password, zope_host],
memcached, conversion_server, kumofs, bt5_list, bt5_repository_list,
self.options['cadir-path'], self.options['openssl-binary']])
return [script]
##############################################################################
#
# 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 httplib
import json
import base64
import socket
import time
class ERP5Updater(object):
erp5_catalog_storage = "erp5_mysql_innodb_catalog"
header_dict = {}
sleeping_time = 300
short_sleeping_time = 60
def __init__(self, user, password, host,
site_id, mysql_url, memcached_address,
conversion_server_address, persistent_cache_address,
bt5_list, bt5_repository_list, certificate_authority_path,
openssl_binary):
authentication_string = '%s:%s' % (user, password)
base64string = base64.encodestring(authentication_string).strip()
self.header_dict['Authorization'] = 'Basic %s' % base64string
self.header_dict['Referer'] = 'http://%s/manage_addProduct/ERP5/addERP5Site' % host
self.host = host
self.site_id = site_id
self.business_template_repository_list = bt5_repository_list
self.business_template_list = bt5_list
self.memcached_address = memcached_address
self.persistent_cached_address = persistent_cache_address
self.mysql_url = mysql_url
host, port = conversion_server_address.split(":")
self.conversion_server_address = host
self.conversion_server_port = int(port)
# Certificate Authority Tool configuration
self.certificate_authority_path = certificate_authority_path
self.openssl_binary = openssl_binary
def log(self, level, message):
date = time.strftime("%a, %d %b %Y %H:%M:%S +0000")
print "%s - %s : %s" % (date, level, message)
def getConnectionToZope(self):
return httplib.HTTPConnection(self.host)
def GET(self, path):
zope_connection = self.getConnectionToZope()
self.log("INFO", "GET ZOPE: %s, PATH: %s" % (self.host, path))
try:
zope_connection.request('GET', path, headers=self.header_dict)
result = zope_connection.getresponse()
data = result.read()
status = result.status
except socket.error, e:
data = "Unable to connect to %s (socket.error: %s)" % (self.host, e)
self.log("ERROR", data)
status = 0
finally:
zope_connection.close()
return status, data
def POST(self, path, post_dict):
zope_connection = self.getConnectionToZope()
param_list = []
for item in post_dict:
value = post_dict[item]
if isinstance(value, type([])):
for v in value:
param_list.append("%s:list=%s" % (item, v))
else:
param_list.append("%s=%s" % (item, value))
params = "&".join(param_list)
self.log("INFO", "GET ZOPE: %s, PATH: %s, PARAMS: %s" % \
(self.host, path, params))
try:
zope_connection.request('POST', path, params, headers=self.header_dict)
result = zope_connection.getresponse()
data = result.read()
status = result.status
except socket.error, e:
data = "Unable to connect to %s (socket.error: %s)" % (self.host, e)
self.log("ERROR", data)
status = 0
finally:
zope_connection.close()
return status, data
def isERP5Present(self):
status, data = self.GET("/isERP5SitePresent")
self.log("DEBUG", "isERP5Present : %s, %s" % (status, data))
return status == 200 and not (data == "False")
def loadSystemSignatureDict(self):
base_path = \
"/%s/portal_introspections/getSystemSignatureAsJSON" % self.site_id
status, data = self.GET(base_path)
if status == 200:
data_dict = json.loads(data)
self.system_signature_dict = data_dict
elif status == 404:
# Unable to find portal_introspection, this means erp5_base is not
# installed yet.
self.system_signature_dict = None
self.log("DEBUG", "Unable to find portal_introspection, this means " + \
"erp5_base is not installed yet.")
else:
self.log("ERROR", "Unable to get SystemSignature to %s (status: %s, data: %s)" % \
(self.host, status, data))
def getSystemSignatureDict(self, item=None, default=None):
system_signature_dict = getattr(self, 'system_signature_dict', None)
if system_signature_dict is not None and item is not None:
return system_signature_dict.get(item, default)
return system_signature_dict
def getMissingBusinessTemplateRepositoryList(self):
found_list = self.getSystemSignatureDict(
"business_template_repository_list", [])
return [i for i in self.business_template_repository_list
if i not in found_list]
def getMissingBusinessTemplateSet(self):
found_dict = self.getSystemSignatureDict("business_template_dict", {})
return set(self.business_template_list).difference(found_dict)
def updateBusinessTemplateList(self):
""" Update Business Template Configuration, including the repositories
"""
missing_business_template_set = self.getMissingBusinessTemplateSet()
if missing_business_template_set:
# Before updating the business templates, it is required to make sure
# the repositories are updated, thus update them even if they are
# already present because there may be new business templates...
repository_list = self.getSystemSignatureDict(
"business_template_repository_list", [])
repository_list.extend(self.getMissingBusinessTemplateRepositoryList())
self._setRepositoryList(repository_list)
# Require to update Business template
self._installBusinessTemplateList(list(missing_business_template_set))
return True
return False
def _setRepositoryList(self, repository_list):
""" Set repository list on portal_templates """
set_path = "/%s/portal_templates/updateRepositoryBusinessTemplateList" % self.site_id
self.POST(set_path, {"repository_list": repository_list})
def _installBusinessTemplateList(self, name_list, update_catalog=False):
""" Install a Business Template on Remote ERP5 setup """
set_path = "/%s/portal_templates/installBusinessTemplateListFromRepository" % self.site_id
self.POST(set_path, {"template_list": name_list,
"only_newer": 1,
"update_catalog": int(update_catalog),
"activate": 1,
"install_dependency": 1})
def _createActiveSystemPreference(self, edit_kw={}):
""" Assert that at least one enabled System Preference is present on
the erp5 instance.
"""
self.log("INFO", "Try to create New System Preference into ERP5!")
path = "/%s/portal_preferences/createActiveSystemPreference" % self.site_id
status, data = self.POST(path, edit_kw)
if status != 200:
self.log("ERROR", "Unable to create System Preference, an error ocurred %s." % data)
def updateConversionServer(self):
""" Update Conversion server Configuration """
external_connection_dict = self.getSystemSignatureDict("external_connection_dict")
host_key = None
port_key = None
for external_connection in external_connection_dict:
# Search for Configurated value for Conversion Server
if external_connection.endswith("getPreferredOoodocServerAddress"):
host_key = external_connection
elif external_connection.endswith("getPreferredOoodocServerPortNumber"):
port_key = external_connection
if None not in [host_key, port_key]:
break
if None in [host_key, port_key]:
self.log("ERROR", "Unable to find the Active System Preference to Update!")
self._createActiveSystemPreference(
{"preferred_ooodoc_server_address" : self.conversion_server_address,
"preferred_ooodoc_server_port_number": self.conversion_server_port })
return True
is_updated = self._assertAndUpdateDocument(host_key, self.conversion_server_address,
"setPreferredOoodocServerAddress")
is_updated = self._assertAndUpdateDocument(port_key,
self.conversion_server_port,
"setPreferredOoodocServerPortNumber") or is_updated
return is_updated
def updateCertificateAuthority(self):
""" Update the certificate authority only if is not configured yet """
if self.isCertificateAuthorityAvailable():
if self.isCertificateAuthorityConfigured():
return True
path = "/%s/portal_certificate_authority/" \
"manage_editCertificateAuthorityTool" % self.site_id
self.POST(path, {"certificate_authority_path": self.certificate_authority_path,
"openssl_binary": self.openssl_binary})
def isCertificateAuthorityAvailable(self):
""" Check if certificate Authority is available. """
external_connection_dict = self.system_signature_dict[
'external_connection_dict']
if 'portal_certificate_authority/certificate_authority_path' in \
external_connection_dict:
return True
return False
def isCertificateAuthorityConfigured(self):
""" Check if certificate Authority is configured correctly. """
external_connection_dict = self.system_signature_dict[
'external_connection_dict']
if self.certificate_authority_path == external_connection_dict.get(
'portal_certificate_authority/certificate_authority_path') and \
self.openssl_binary == external_connection_dict.get(
'portal_certificate_authority/openssl_binary'):
return True
return False
def updateMemcached(self):
# Assert Memcached configuration
self._assertAndUpdateDocument(
"portal_memcached/default_memcached_plugin/getUrlString",
self.memcached_address,
"setUrlString")
# Assert Persistent cache configuration (Kumofs)
self._assertAndUpdateDocument(
"portal_memcached/persistent_memcached_plugin/getUrlString",
self.persistent_cached_address,
"setUrlString")
def _assertAndUpdateDocument(self, key, expected_value, update_method):
external_connection_dict = self.getSystemSignatureDict("external_connection_dict")
# Assert Memcached configuration
found_address = external_connection_dict.get(key)
if found_address != expected_value:
document_path = "/".join(key.split("/")[:-1])
self.log("INFO",
"Document require update at %s (Found: %s, Expected: %s)" % \
(document_path, found_address, expected_value))
set_path = "/%s/%s/%s" % (self.site_id, document_path, update_method)
self.POST(set_path, {"value": expected_value})
return True
return False
def updateERP5Site(self):
if not self.isERP5Present():
self.log('INFO', 'No site present, adding new with id %r' % self.site_id)
self.POST('/manage_addProduct/ERP5/manage_addERP5Site', {
"id": self.site_id,
"erp5_catalog_storage": self.erp5_catalog_storage,
"erp5_sql_connection_string": self.mysql_url,
"cmf_activity_sql_connection_string": self.mysql_url})
return True
return False
def _hasActivityPresent(self):
activity_dict = self.getSystemSignatureDict("activity_dict")
if activity_dict["total"] > 0:
self.log("DEBUG", "Waiting for activities on ERP5...")
return True
return False
def _hasFailureActivity(self):
activity_dict = self.getSystemSignatureDict("activity_dict")
if activity_dict["failure"] > 0:
self.log("ERROR", "Update progress found Failure activities" +\
"and it will not be able to progress until" +\
" activites issue be solved")
return True
return False
def run(self):
""" Keep running until kill"""
while 1:
self.log('INFO', 'Sleeping for %s' % self.short_sleeping_time)
time.sleep(self.short_sleeping_time)
if not self.updateERP5Site():
self.loadSystemSignatureDict()
if self._hasFailureActivity():
time.sleep(self.sleeping_time)
continue
if self._hasActivityPresent():
continue
if self.updateBusinessTemplateList():
continue
self.updateMemcached()
if self.updateConversionServer():
continue
self.updateCertificateAuthority()
time.sleep(self.sleeping_time)
def updateERP5(argument_list):
site_id = argument_list[0]
mysql_url = argument_list[1]
user, password, host = argument_list[2]
memcached_address = argument_list[3]
conversion_server_address = argument_list[4]
persistent_cache_provider = argument_list[5]
bt5_list = argument_list[6]
certificate_authority_path = argument_list[8]
openssl_binary = argument_list[9]
bt5_repository_list = []
if len(argument_list) > 7:
bt5_repository_list = argument_list[7]
if len(bt5_list) > 0 and len(bt5_repository_list) == 0:
bt5_repository_list = ["http://www.erp5.org/dists/snapshot/bt5"]
erp5_upgrader = ERP5Updater(
user=user,
password=password,
host=host,
site_id=site_id,
mysql_url=mysql_url,
memcached_address=memcached_address,
conversion_server_address=conversion_server_address,
persistent_cache_address=persistent_cache_provider,
bt5_list=bt5_list,
bt5_repository_list=bt5_repository_list,
certificate_authority_path=certificate_authority_path,
openssl_binary=openssl_binary)
erp5_upgrader.run()
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment