Commit 7208a30d authored by Julien Muchembled's avatar Julien Muchembled

wip

parent bed64f31
......@@ -17,7 +17,7 @@
import threading
from weakref import ref as weakref
from OFS.Application import Application
from OFS.Application import Application, AppInitializer
from Products.ERP5Type import Globals
from Products.ERP5Type.Globals import package_home
......@@ -68,9 +68,12 @@ def manage_addERP5Site(self,
email_from_address='postmaster@localhost',
email_from_name='Portal Administrator',
validate_email=0,
erp5_catalog_storage='',
erp5_catalog_storage='erp5_mysql_innodb_catalog',
erp5_sql_connection_string='test test',
cmf_activity_sql_connection_string='test test',
bt5_repository_url='',
bt5='',
cloudooo_url='',
light_install=0,
reindex=1,
sql_reset=0,
......@@ -86,6 +89,9 @@ def manage_addERP5Site(self,
erp5_catalog_storage,
erp5_sql_connection_string,
cmf_activity_sql_connection_string,
bt5_repository_url,
bt5,
cloudooo_url,
create_activities=create_activities,
light_install=light_install,
reindex=reindex,
......@@ -258,6 +264,24 @@ class ERP5Site(FolderMixIn, CMFSite, CacheCookieMixin):
request.RESPONSE.realm = None
return super(ERP5Site, self).__before_publishing_traverse__(self2, request)
def _initSystemPreference(self, cloudooo_url):
"""
Post-addERP5Site code to make sure that cloudoo is configured,
which is often required by the configurator.
"""
preference_tool = self.portal_preferences
id = 'default_system_preference'
portal_type = 'System Preference'
for pref in preference_tool.objectValues(portal_type=portal_type):
if pref.getPreferenceState() == 'global':
break
else:
from Products.ERP5Form.PreferenceTool import Priority
pref = preference_tool.newContent(id, portal_type,
priority=Priority.SITE, title='Default ' + portal_type)
pref.enable()
pref.setPreferredDocumentConversionServerUrl(cloudooo_url)
def _createInitialSiteManager(self):
# This section of code is inspired by
# Products.CMFDefault.upgrade.to21.upgrade_root_site_manager(),
......@@ -1844,6 +1868,9 @@ class ERP5Generator(PortalGenerator):
erp5_catalog_storage,
erp5_sql_connection_string,
cmf_activity_sql_connection_string,
bt5_repository_url,
bt5,
cloudooo_url,
create_activities=True,
reindex=1,
**kw):
......@@ -1878,6 +1905,20 @@ class ERP5Generator(PortalGenerator):
p._v_bootstrapping = False
# XXX: Is it useful to wait for indexing ?
after_method_id = 'immediateReindexObject'
if bt5_repository_url:
p.portal_templates.repository_dict = dict.fromkeys(
bt5_repository_url.split())
if bt5:
method_id = 'upgradeSite'
getattr(p.portal_templates.activate(after_method_id=after_method_id),
method_id)(bt5.split(), update_catalog=True)
after_method_id = method_id
if cloudooo_url:
p.portal_activities.activateObject(p, after_method_id=after_method_id,
)._initSystemPreference(cloudooo_url=cloudooo_url)
return p
@classmethod
......@@ -2281,3 +2322,81 @@ class ERP5Generator(PortalGenerator):
template_tool.installBusinessTemplateListFromRepository(
['erp5_promise'], activate=True, install_dependency=True)
p.portal_alarms.subscribe()
# Zope offers no mechanism to extend AppInitializer so let's monkey-patch.
AppInitializer_initialize = AppInitializer.initialize.__func__
def initialize(self):
AppInitializer.initialize = AppInitializer_initialize
self.initialize()
try:
kw = getConfiguration().product_config['initsite']
except KeyError:
return
meta_type = ERP5Site.meta_type
for _ in self.getApp().objectIds(meta_type):
return
# We defer the call to manage_addERP5Site via ZServer.PubCore because:
# - we use ZPublisher so that get_request() works
# (see new_publish in Localizer.patches)
# - we want errors to be logged correctly
# (see Zope2.zpublisher_exception_hook in Zope2.App.startup)
import inspect, time
from AccessControl.SecurityManagement import newSecurityManager
from cStringIO import StringIO
from Products.ZMySQLDA.db import DB, OperationalError
from ZPublisher import HTTPRequest, HTTPResponse
from ZServer.PubCore import handle
def addERP5Site():
default_kw = inspect.getcallargs(manage_addERP5Site, None, '')
db = (kw.get('erp5_sql_connection_string') or
default_kw['erp5_sql_connection_string'])
# The lock is to avoid that multiple zopes try to create a site when
# they're started at the same time, because this is a quite long operation
# (-> high probably of conflict with a lot of wasted CPU).
# Theoretically, the same precaution should be taken for previous initial
# commits, but they're small operations. At worst, SlapOS restarts zopes
# automatically.
# A ZODB lock would be better but unless we extend ZODB, this is only
# possible with NEO, by voting a change to oid 0 in a parallel transaction
# (and abort at the end): thanks to locking at object-level, this would not
# block the main transaction.
app = last = None
while 1:
try:
with DB(db).lock():
transaction.begin()
app = request['PARENTS'][0] = request['PARENTS'][0]()
for _ in app.objectIds(meta_type):
return
uf = app.acl_users
user = uf.getUser(kw['owner'])
if not user.has_role('Manager'):
response.unauthorized()
newSecurityManager(None, user.__of__(uf))
manage_addERP5Site(app.__of__(RequestContainer(REQUEST=request)),
**{k: kw.get(k, v) for k, v in default_kw.iteritems()
if isinstance(v, str)})
transaction.get().note('Created ' + meta_type)
transaction.commit()
break
except OperationalError as e:
if app is not None:
raise
# MySQL server not ready (down or user not created).
e = str(e)
if last != e:
last = e
LOG('ERP5Site', WARNING,
'MySQL error while trying to create ERP5 site. Retrying...',
error=1)
time.sleep(5)
response = HTTPResponse.HTTPResponse(stdout=StringIO())
response._finish = lambda: None
request = HTTPRequest.HTTPRequest(
StringIO(), dict(REQUEST_METHOD='GET', SERVER_URL=''), response)
request.traverse = lambda *args, **kw: addERP5Site
handle('Zope2', request, response)
AppInitializer.initialize = initialize
......@@ -365,10 +365,10 @@ class TemplateTool (BaseTool):
if id is None:
id = self.generateNewId()
urltype, name = splittype(url)
if WIN and urltype and '\\' in name:
urltype, path = splittype(url)
if WIN and urltype and '\\' in path:
urltype = None
name = url
path = url
if urltype and urltype != 'file':
if '/portal_templates/asRepository/' in url:
# In this case, the downloaded BT is already built.
......@@ -378,7 +378,8 @@ class TemplateTool (BaseTool):
return self[self._setObject(id, bt)]
bt = self._download_url(url, id)
else:
bt = self._download_local(os.path.normpath(name), id)
path = os.path.normpath(os.path.expanduser(path))
bt = self._download_local(path, id)
bt.build(no_action=True)
return bt
......@@ -590,8 +591,10 @@ class TemplateTool (BaseTool):
"""
Update the information on Business Templates from repositories.
For local repositories, if bt5list is missing or if genbt5list > 1,
bt5list is automatically generated (but not saved on disk).
For local repositories, genbt5list > 0 enables automatic generation
of bt5list, without saving it on disk:
- genbt5list=1: only if bt5list is missing
- genbt5list>1: always
"""
self.repository_dict = PersistentMapping()
property_list = ('title', 'version', 'revision', 'description', 'license',
......@@ -607,6 +610,7 @@ class TemplateTool (BaseTool):
if urltype and urltype != 'file':
f = urlopen(repository + '/bt5list')
else:
url = os.path.expanduser(url)
bt5list = os.path.join(url, 'bt5list')
if genbt5list > os.path.exists(bt5list):
f = generateInformation(url)
......
......@@ -322,10 +322,6 @@ It\'s the lowest priority one; ie. managers can create higher priority preferenc
<key> <string>preferred_money_quantity_field_width</string> </key>
<value> <int>10</int> </value>
</item>
<item>
<key> <string>preferred_document_conversion_server_url</string> </key>
<value> <string>http://erp5-cloudooo:2020</string> </value>
</item>
<item>
<key> <string>preferred_quantity_field_width</string> </key>
<value> <int>5</int> </value>
......
......@@ -13,7 +13,7 @@
Form style based on Aleksandar Vacić's work,
ditributed under Creative Commons Paternity Licence:
* http://creativecommons.org/licenses/by/2.0/
* http://www.aplus.co.yu/css/forms/?css=1
* http://aplus.rs/lab/forms/
-->
<style type="text/css">
......@@ -91,11 +91,11 @@ label {
</div>
<div>
<label class="form-label" for="erp5_sql_connection_string">ERP5 Database</label>
<input class="form-element" name="erp5_sql_connection_string" id="erp5_sql_connection_string" type="text" size="40" value="test test"/>
<input class="form-element" name="erp5_sql_connection_string" id="erp5_sql_connection_string" type="text" size="60" value="test test"/>
</div>
<div>
<label class="form-label" for="cmf_activity_sql_connection_string">CMF Activity Database</label>
<input class="form-element" name="cmf_activity_sql_connection_string" id="cmf_activity_sql_connection_string" type="text" size="40" value="test test"/>
<input class="form-element" name="cmf_activity_sql_connection_string" id="cmf_activity_sql_connection_string" type="text" size="60" value="test test"/>
</div>
<div>
<label class="form-label" for="sql_reset">Drop any existing table</label>
......@@ -108,6 +108,19 @@ label {
<br/>
</fieldset>
<fieldset>
<legend class="form-title">Business Templates</legend>
<div title="Business Template names, or (TODO) URL pointing to a file in BT5 or ZEXP format.">
<label class="form-label" for="bt5">Install BT5</label>
<input class="form-element" name="bt5" id="bt5" type="text" size="60"/>
</div>
<div>
<label class="form-label" for="bt5_repository_url">Repositories</label>
<textarea class="form-element" name="bt5_repository_url" id="bt5_repository_url" cols="60" rows="4"></textarea>
</div>
<br/>
</fieldset>
<input style="float:right" class="form-element" type="submit" name="submit" value="Create a new ERP5 Site instance"/>
</form>
......
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