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

wip

parent bed64f31
...@@ -17,7 +17,7 @@ ...@@ -17,7 +17,7 @@
import threading import threading
from weakref import ref as weakref 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 import Globals
from Products.ERP5Type.Globals import package_home from Products.ERP5Type.Globals import package_home
...@@ -68,9 +68,12 @@ def manage_addERP5Site(self, ...@@ -68,9 +68,12 @@ def manage_addERP5Site(self,
email_from_address='postmaster@localhost', email_from_address='postmaster@localhost',
email_from_name='Portal Administrator', email_from_name='Portal Administrator',
validate_email=0, validate_email=0,
erp5_catalog_storage='', erp5_catalog_storage='erp5_mysql_innodb_catalog',
erp5_sql_connection_string='test test', erp5_sql_connection_string='test test',
cmf_activity_sql_connection_string='test test', cmf_activity_sql_connection_string='test test',
bt5_repository_url='',
bt5='',
cloudooo_url='',
light_install=0, light_install=0,
reindex=1, reindex=1,
sql_reset=0, sql_reset=0,
...@@ -86,6 +89,9 @@ def manage_addERP5Site(self, ...@@ -86,6 +89,9 @@ def manage_addERP5Site(self,
erp5_catalog_storage, erp5_catalog_storage,
erp5_sql_connection_string, erp5_sql_connection_string,
cmf_activity_sql_connection_string, cmf_activity_sql_connection_string,
bt5_repository_url,
bt5,
cloudooo_url,
create_activities=create_activities, create_activities=create_activities,
light_install=light_install, light_install=light_install,
reindex=reindex, reindex=reindex,
...@@ -258,6 +264,24 @@ class ERP5Site(FolderMixIn, CMFSite, CacheCookieMixin): ...@@ -258,6 +264,24 @@ class ERP5Site(FolderMixIn, CMFSite, CacheCookieMixin):
request.RESPONSE.realm = None request.RESPONSE.realm = None
return super(ERP5Site, self).__before_publishing_traverse__(self2, request) 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): def _createInitialSiteManager(self):
# This section of code is inspired by # This section of code is inspired by
# Products.CMFDefault.upgrade.to21.upgrade_root_site_manager(), # Products.CMFDefault.upgrade.to21.upgrade_root_site_manager(),
...@@ -1844,6 +1868,9 @@ class ERP5Generator(PortalGenerator): ...@@ -1844,6 +1868,9 @@ class ERP5Generator(PortalGenerator):
erp5_catalog_storage, erp5_catalog_storage,
erp5_sql_connection_string, erp5_sql_connection_string,
cmf_activity_sql_connection_string, cmf_activity_sql_connection_string,
bt5_repository_url,
bt5,
cloudooo_url,
create_activities=True, create_activities=True,
reindex=1, reindex=1,
**kw): **kw):
...@@ -1878,6 +1905,20 @@ class ERP5Generator(PortalGenerator): ...@@ -1878,6 +1905,20 @@ class ERP5Generator(PortalGenerator):
p._v_bootstrapping = False 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 return p
@classmethod @classmethod
...@@ -2281,3 +2322,81 @@ class ERP5Generator(PortalGenerator): ...@@ -2281,3 +2322,81 @@ class ERP5Generator(PortalGenerator):
template_tool.installBusinessTemplateListFromRepository( template_tool.installBusinessTemplateListFromRepository(
['erp5_promise'], activate=True, install_dependency=True) ['erp5_promise'], activate=True, install_dependency=True)
p.portal_alarms.subscribe() 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): ...@@ -365,10 +365,10 @@ class TemplateTool (BaseTool):
if id is None: if id is None:
id = self.generateNewId() id = self.generateNewId()
urltype, name = splittype(url) urltype, path = splittype(url)
if WIN and urltype and '\\' in name: if WIN and urltype and '\\' in path:
urltype = None urltype = None
name = url path = url
if urltype and urltype != 'file': if urltype and urltype != 'file':
if '/portal_templates/asRepository/' in url: if '/portal_templates/asRepository/' in url:
# In this case, the downloaded BT is already built. # In this case, the downloaded BT is already built.
...@@ -378,7 +378,8 @@ class TemplateTool (BaseTool): ...@@ -378,7 +378,8 @@ class TemplateTool (BaseTool):
return self[self._setObject(id, bt)] return self[self._setObject(id, bt)]
bt = self._download_url(url, id) bt = self._download_url(url, id)
else: 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) bt.build(no_action=True)
return bt return bt
...@@ -590,8 +591,10 @@ class TemplateTool (BaseTool): ...@@ -590,8 +591,10 @@ class TemplateTool (BaseTool):
""" """
Update the information on Business Templates from repositories. Update the information on Business Templates from repositories.
For local repositories, if bt5list is missing or if genbt5list > 1, For local repositories, genbt5list > 0 enables automatic generation
bt5list is automatically generated (but not saved on disk). of bt5list, without saving it on disk:
- genbt5list=1: only if bt5list is missing
- genbt5list>1: always
""" """
self.repository_dict = PersistentMapping() self.repository_dict = PersistentMapping()
property_list = ('title', 'version', 'revision', 'description', 'license', property_list = ('title', 'version', 'revision', 'description', 'license',
...@@ -607,6 +610,7 @@ class TemplateTool (BaseTool): ...@@ -607,6 +610,7 @@ class TemplateTool (BaseTool):
if urltype and urltype != 'file': if urltype and urltype != 'file':
f = urlopen(repository + '/bt5list') f = urlopen(repository + '/bt5list')
else: else:
url = os.path.expanduser(url)
bt5list = os.path.join(url, 'bt5list') bt5list = os.path.join(url, 'bt5list')
if genbt5list > os.path.exists(bt5list): if genbt5list > os.path.exists(bt5list):
f = generateInformation(url) f = generateInformation(url)
......
...@@ -322,10 +322,6 @@ It\'s the lowest priority one; ie. managers can create higher priority preferenc ...@@ -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> <key> <string>preferred_money_quantity_field_width</string> </key>
<value> <int>10</int> </value> <value> <int>10</int> </value>
</item> </item>
<item>
<key> <string>preferred_document_conversion_server_url</string> </key>
<value> <string>http://erp5-cloudooo:2020</string> </value>
</item>
<item> <item>
<key> <string>preferred_quantity_field_width</string> </key> <key> <string>preferred_quantity_field_width</string> </key>
<value> <int>5</int> </value> <value> <int>5</int> </value>
......
...@@ -13,7 +13,7 @@ ...@@ -13,7 +13,7 @@
Form style based on Aleksandar Vacić's work, Form style based on Aleksandar Vacić's work,
ditributed under Creative Commons Paternity Licence: ditributed under Creative Commons Paternity Licence:
* http://creativecommons.org/licenses/by/2.0/ * 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"> <style type="text/css">
...@@ -91,11 +91,11 @@ label { ...@@ -91,11 +91,11 @@ label {
</div> </div>
<div> <div>
<label class="form-label" for="erp5_sql_connection_string">ERP5 Database</label> <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>
<div> <div>
<label class="form-label" for="cmf_activity_sql_connection_string">CMF Activity Database</label> <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>
<div> <div>
<label class="form-label" for="sql_reset">Drop any existing table</label> <label class="form-label" for="sql_reset">Drop any existing table</label>
...@@ -108,6 +108,19 @@ label { ...@@ -108,6 +108,19 @@ label {
<br/> <br/>
</fieldset> </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"/> <input style="float:right" class="form-element" type="submit" name="submit" value="Create a new ERP5 Site instance"/>
</form> </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