Commit 0a0d2470 authored by Gabriel Monnerat's avatar Gabriel Monnerat

Simplify erp5_upgrader to be possible upgrade any project just enabling the...

Simplify erp5_upgrader to be possible upgrade any project just enabling the alarms that all Constraints will be called and fixed.

The alarms were renamed to cover each step of upgrader and give the possibility to call each step manually one-by-one. Also, all Scripts that the logic can be done by installing Business Template was removed.

Also added:
 - Constraints that can be used in the upgrader
 - Unit test to check different scenarios
 - Extend external method to be possible dump workflow chains to be compared with all configuration defined on Business Templates
parent 97a6db68
......@@ -32,9 +32,8 @@
from App.config import getConfiguration
from Products.ERP5Type.Log import log
from Products.CMFActivity.ActiveResult import ActiveResult
from time import sleep
import os
from Acquisition import aq_base
def ERP5Site_editERP5SiteProperty(self, prop, value):
"""
......@@ -47,28 +46,6 @@ def ERP5Site_editERP5SiteProperty(self, prop, value):
method(prop, value)
return True
def ERP5Site_restartZopeInstance(self):
"""
Zope must be restart after update the Products or Software
But the restart into one activity, will make the activity always
fail and with the server will be restart many times.
This method use a flag to define if the server was already restarted.
If yes, the flag is removed and the restart will be ignored.
This method should be run into a single activity to prevent rollback
other parts.
"""
import Lifetime
Lifetime.shutdown(1,fast=1)
log("Zope Restart was launched.")
active_result = ActiveResult()
active_result.edit(summary="Zope Restart",
severity=0,
detail="Zope was restart Sucessfully.")
return active_result
def ERP5Site_clearActivities(self):
"""
This method is used to recreated the activities keeping the
......@@ -119,42 +96,26 @@ def ERP5Site_runVerificationScript(self, method_id):
if len(integrity_result) > 0:
return '%s : \n - %s ' % (method_id, '\n - '.join(integrity_result))
def ERP5Site_changeAuthoredDocumentListOwnership(self, old_owner, new_owner):
"""
Change owneship for all documents in the system belonging to
an user (i.e. represented by user_name/reference).
"""
# Move import to here prevents the raise error when this External
# Be imported during the upgrade.
from Products.ERP5Type.Utils import _setSuperSecurityManager
from AccessControl.SecurityManagement import setSecurityManager
from Products.ERP5Security.ERP5UserManager import SUPER_USER
result = []
orginal_security_manager = _setSuperSecurityManager(self, SUPER_USER)
portal = self.getPortalObject()
user_folder = portal.acl_users
new_owner_as_user = user_folder.getUserById(new_owner).__of__(user_folder)
document_list = portal.portal_catalog.unrestrictedSearchResults(owner = old_owner)
for document in document_list:
document = document.getObject()
# change document ownership
document.changeOwnership(new_owner_as_user)
# fix local roles
for item in document.get_local_roles():
user = item[0]
role_list = item[1]
if user == old_owner:
# replace old Owner with new One
document.manage_delLocalRoles((old_owner,))
document.manage_setLocalRoles(new_owner, role_list)
result.append(document.getRelativeUrl())
# finally reindex document
document.reindexObject()
# restore security
setSecurityManager(orginal_security_manager)
return dict(old_owner = old_owner, \
new_owner = new_owner, \
changed_document_list = result)
def ERP5Site_dumpWorkflowChainByPortalType(self, REQUEST=None):
# This method outputs the workflow chain by portal type
# ---
# {"Account": ['account_workflow', "edit_workflow"]}
# ---
#
if REQUEST:
raise RuntimeError("You can not call this script from the url")
workflow_tool = self.getPortalObject().portal_workflow
cbt = workflow_tool._chains_by_type
ti = workflow_tool._listTypeInfo()
chain_by_type_dict = {}
for t in ti:
id = t.getId()
title = t.Title()
if title == id:
title = None
if cbt is not None and cbt.has_key(id):
chain = sorted(cbt[id])
else:
chain = ['(Default)']
chain_by_type_dict.setdefault(id, []).extend(chain)
return chain_by_type_dict
\ No newline at end of file
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="Alarm" module="erp5.portal_type"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>active_sense_method_id</string> </key>
<value> <string>Alarm_senseFullUpgradeNeed</string> </value>
</item>
<item>
<key> <string>alarm_notification_mode</string> </key>
<value>
<tuple>
<string>always</string>
</tuple>
</value>
</item>
<item>
<key> <string>description</string> </key>
<value> <string>This alarm checks that the upgrader is required. If yes, the upgrader have three steps:\n
\n
1. Pre-upgrade\n
This step will run all constraints that have contraint_type equal pre_upgrade.\n
\n
2. Upgrader\n
This step will run all constraints that have contraint_type equal upgrade. In this step is supposed to install/upgrade all Business Template required.\n
\n
3. Post-Upgrade\n
This step will run all constraints that have contraint_type equal post_upgrade.</string> </value>
</item>
<item>
<key> <string>enabled</string> </key>
<value> <int>0</int> </value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>promise_check_upgrade</string> </value>
</item>
<item>
<key> <string>periodicity_hour</string> </key>
<value>
<tuple/>
</value>
</item>
<item>
<key> <string>periodicity_minute</string> </key>
<value>
<tuple/>
</value>
</item>
<item>
<key> <string>periodicity_minute_frequency</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>periodicity_month</string> </key>
<value>
<tuple/>
</value>
</item>
<item>
<key> <string>periodicity_month_day</string> </key>
<value>
<tuple/>
</value>
</item>
<item>
<key> <string>periodicity_start_date</string> </key>
<value>
<object>
<klass>
<global name="DateTime" module="DateTime.DateTime"/>
</klass>
<tuple>
<none/>
</tuple>
<state>
<tuple>
<float>1384423200.0</float>
<string>GMT</string>
</tuple>
</state>
</object>
</value>
</item>
<item>
<key> <string>periodicity_week</string> </key>
<value>
<tuple/>
</value>
</item>
<item>
<key> <string>portal_type</string> </key>
<value> <string>Alarm</string> </value>
</item>
<item>
<key> <string>sense_method_id</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>solve_method_id</string> </key>
<value> <string>Alarm_runFullUpgrader</string> </value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string>Run Full Upgrade</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
......@@ -14,17 +14,13 @@
<key> <string>alarm_notification_mode</string> </key>
<value>
<tuple>
<string>never</string>
<string>always</string>
</tuple>
</value>
</item>
<item>
<key> <string>description</string> </key>
<value> <string>This alarms acts as a cron job. It will start an instance upgrade if any of the following this alarms sequence:\n
1) bt5_upgrader (supported)\n
2) finalize_upgrader (supported)\n
\n
"sense" a need of an upgrade. This alarm is likely to disappear soon as it\'s needed due to lack of functionality (which is that alarms can not automatically "solve" themselves).</string> </value>
<value> <string>This step will run all constraints that have contraint_type equal post_upgrade.</string> </value>
</item>
<item>
<key> <string>enabled</string> </key>
......@@ -32,7 +28,7 @@
</item>
<item>
<key> <string>id</string> </key>
<value> <string>upgrader_controller</string> </value>
<value> <string>upgrader_check_post_upgrade</string> </value>
</item>
<item>
<key> <string>periodicity_hour</string> </key>
......@@ -48,7 +44,9 @@
</item>
<item>
<key> <string>periodicity_minute_frequency</string> </key>
<value> <int>30</int> </value>
<value>
<none/>
</value>
</item>
<item>
<key> <string>periodicity_month</string> </key>
......@@ -74,7 +72,7 @@
</tuple>
<state>
<tuple>
<float>1136073600.0</float>
<float>1384423200.0</float>
<string>GMT</string>
</tuple>
</state>
......@@ -97,9 +95,13 @@
<none/>
</value>
</item>
<item>
<key> <string>solve_method_id</string> </key>
<value> <string>Alarm_runPostUpgrade</string> </value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string>Upgrader Controller</string> </value>
<value> <string>Run Post Upgrade</string> </value>
</item>
</dictionary>
</pickle>
......
......@@ -6,6 +6,10 @@
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>active_sense_method_id</string> </key>
<value> <string>Alarm_senseUpgradeNeed</string> </value>
</item>
<item>
<key> <string>alarm_notification_mode</string> </key>
<value>
......@@ -16,7 +20,7 @@
</item>
<item>
<key> <string>description</string> </key>
<value> <string>This business template finalize the upgrade, this should contains the last steps of upgrade system (ie.: Clear Cache).</string> </value>
<value> <string>This step will run all constraints that have contraint_type equal pre_upgrade.</string> </value>
</item>
<item>
<key> <string>enabled</string> </key>
......@@ -24,7 +28,7 @@
</item>
<item>
<key> <string>id</string> </key>
<value> <string>finalize_upgrader</string> </value>
<value> <string>upgrader_check_pre_upgrade</string> </value>
</item>
<item>
<key> <string>periodicity_hour</string> </key>
......@@ -68,7 +72,7 @@
</tuple>
<state>
<tuple>
<float>1136073600.0</float>
<float>1384423200.0</float>
<string>GMT</string>
</tuple>
</state>
......@@ -87,15 +91,17 @@
</item>
<item>
<key> <string>sense_method_id</string> </key>
<value> <string>Alarm_senseFinalizeUpgrade</string> </value>
<value>
<none/>
</value>
</item>
<item>
<key> <string>solve_method_id</string> </key>
<value> <string>Alarm_upgradeFinalize</string> </value>
<value> <string>Alarm_runPreUpgrade</string> </value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string>Finalize Upgrader</string> </value>
<value> <string>Run Pre Upgrade</string> </value>
</item>
</dictionary>
</pickle>
......
......@@ -6,6 +6,10 @@
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>active_sense_method_id</string> </key>
<value> <string>Alarm_senseUpgradeNeed</string> </value>
</item>
<item>
<key> <string>alarm_notification_mode</string> </key>
<value>
......@@ -16,7 +20,7 @@
</item>
<item>
<key> <string>description</string> </key>
<value> <string>This Alarm check that bt5 are the right ones. If not, it upgrades the bt5 using SVN (for dedicate instances) or using shared repository for Free / Express instances.</string> </value>
<value> <string>This step will run all constraints that have contraint_type equal upgrader.</string> </value>
</item>
<item>
<key> <string>enabled</string> </key>
......@@ -24,7 +28,7 @@
</item>
<item>
<key> <string>id</string> </key>
<value> <string>bt5_upgrader</string> </value>
<value> <string>upgrader_check_upgrader</string> </value>
</item>
<item>
<key> <string>periodicity_hour</string> </key>
......@@ -68,7 +72,7 @@
</tuple>
<state>
<tuple>
<float>1136073600.0</float>
<float>1384423200.0</float>
<string>GMT</string>
</tuple>
</state>
......@@ -87,15 +91,17 @@
</item>
<item>
<key> <string>sense_method_id</string> </key>
<value> <string>Alarm_senseBT5Version</string> </value>
<value>
<none/>
</value>
</item>
<item>
<key> <string>solve_method_id</string> </key>
<value> <string>Alarm_upgradeBT5Version</string> </value>
<value> <string>Alarm_runUpgrader</string> </value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string>BT5 Upgrader</string> </value>
<value> <string>Run Upgrader</string> </value>
</item>
</dictionary>
</pickle>
......
<property_sheet_list>
<portal_type id="Template Tool">
<item>TemplateToolUpgraderConstraint</item>
</portal_type>
</property_sheet_list>
\ No newline at end of file
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="Property Sheet" module="erp5.portal_type"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>_count</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAI=</string> </persistent>
</value>
</item>
<item>
<key> <string>_mt_index</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAM=</string> </persistent>
</value>
</item>
<item>
<key> <string>_tree</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAQ=</string> </persistent>
</value>
</item>
<item>
<key> <string>description</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>TemplateToolPostUpgradeConstraint</string> </value>
</item>
<item>
<key> <string>portal_type</string> </key>
<value> <string>Property Sheet</string> </value>
</item>
</dictionary>
</pickle>
</record>
<record id="2" aka="AAAAAAAAAAI=">
<pickle>
<global name="Length" module="BTrees.Length"/>
</pickle>
<pickle> <int>0</int> </pickle>
</record>
<record id="3" aka="AAAAAAAAAAM=">
<pickle>
<global name="OOBTree" module="BTrees.OOBTree"/>
</pickle>
<pickle>
<none/>
</pickle>
</record>
<record id="4" aka="AAAAAAAAAAQ=">
<pickle>
<global name="OOBTree" module="BTrees.OOBTree"/>
</pickle>
<pickle>
<none/>
</pickle>
</record>
</ZopeData>
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="Script Constraint" module="erp5.portal_type"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>_identity_criterion</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAI=</string> </persistent>
</value>
</item>
<item>
<key> <string>_range_criterion</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAM=</string> </persistent>
</value>
</item>
<item>
<key> <string>categories</string> </key>
<value>
<tuple>
<string>constraint_type/post_upgrade</string>
</tuple>
</value>
</item>
<item>
<key> <string>description</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>workflow_chain_constraint</string> </value>
</item>
<item>
<key> <string>portal_type</string> </key>
<value> <string>Script Constraint</string> </value>
</item>
<item>
<key> <string>script_id</string> </key>
<value> <string>TemplateTool_checkPostUpgradeWorkflowChainConsistency</string> </value>
</item>
</dictionary>
</pickle>
</record>
<record id="2" aka="AAAAAAAAAAI=">
<pickle>
<global name="PersistentMapping" module="Persistence.mapping"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>data</string> </key>
<value>
<dictionary/>
</value>
</item>
</dictionary>
</pickle>
</record>
<record id="3" aka="AAAAAAAAAAM=">
<pickle>
<global name="PersistentMapping" module="Persistence.mapping"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>data</string> </key>
<value>
<dictionary/>
</value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="Property Sheet" module="erp5.portal_type"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>_count</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAI=</string> </persistent>
</value>
</item>
<item>
<key> <string>_mt_index</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAM=</string> </persistent>
</value>
</item>
<item>
<key> <string>_tree</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAQ=</string> </persistent>
</value>
</item>
<item>
<key> <string>description</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>TemplateToolUpgraderConstraint</string> </value>
</item>
<item>
<key> <string>portal_type</string> </key>
<value> <string>Property Sheet</string> </value>
</item>
</dictionary>
</pickle>
</record>
<record id="2" aka="AAAAAAAAAAI=">
<pickle>
<global name="Length" module="BTrees.Length"/>
</pickle>
<pickle> <int>0</int> </pickle>
</record>
<record id="3" aka="AAAAAAAAAAM=">
<pickle>
<global name="OOBTree" module="BTrees.OOBTree"/>
</pickle>
<pickle>
<none/>
</pickle>
</record>
<record id="4" aka="AAAAAAAAAAQ=">
<pickle>
<global name="OOBTree" module="BTrees.OOBTree"/>
</pickle>
<pickle>
<none/>
</pickle>
</record>
</ZopeData>
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="Script Constraint" module="erp5.portal_type"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>_identity_criterion</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAI=</string> </persistent>
</value>
</item>
<item>
<key> <string>_range_criterion</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAM=</string> </persistent>
</value>
</item>
<item>
<key> <string>categories</string> </key>
<value>
<tuple>
<string>constraint_type/upgrader</string>
</tuple>
</value>
</item>
<item>
<key> <string>description</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>business_template_installed_constraint</string> </value>
</item>
<item>
<key> <string>portal_type</string> </key>
<value> <string>Script Constraint</string> </value>
</item>
<item>
<key> <string>script_id</string> </key>
<value> <string>TemplateTool_checkUpgradeConsistency</string> </value>
</item>
</dictionary>
</pickle>
</record>
<record id="2" aka="AAAAAAAAAAI=">
<pickle>
<global name="PersistentMapping" module="Persistence.mapping"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>data</string> </key>
<value>
<dictionary/>
</value>
</item>
</dictionary>
</pickle>
</record>
<record id="3" aka="AAAAAAAAAAM=">
<pickle>
<global name="PersistentMapping" module="Persistence.mapping"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>data</string> </key>
<value>
<dictionary/>
</value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="SQL" module="Products.ZSQLMethods.SQL"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>_col</string> </key>
<value>
<list>
<dictionary>
<item>
<key> <string>name</string> </key>
<value> <string>Field</string> </value>
</item>
<item>
<key> <string>null</string> </key>
<value> <int>0</int> </value>
</item>
<item>
<key> <string>type</string> </key>
<value> <string>t</string> </value>
</item>
<item>
<key> <string>width</string> </key>
<value> <int>18</int> </value>
</item>
</dictionary>
<dictionary>
<item>
<key> <string>name</string> </key>
<value> <string>Type</string> </value>
</item>
<item>
<key> <string>null</string> </key>
<value> <int>0</int> </value>
</item>
<item>
<key> <string>type</string> </key>
<value> <string>t</string> </value>
</item>
<item>
<key> <string>width</string> </key>
<value> <int>19</int> </value>
</item>
</dictionary>
<dictionary>
<item>
<key> <string>name</string> </key>
<value> <string>Null</string> </value>
</item>
<item>
<key> <string>null</string> </key>
<value> <int>0</int> </value>
</item>
<item>
<key> <string>type</string> </key>
<value> <string>t</string> </value>
</item>
<item>
<key> <string>width</string> </key>
<value> <int>3</int> </value>
</item>
</dictionary>
<dictionary>
<item>
<key> <string>name</string> </key>
<value> <string>Key</string> </value>
</item>
<item>
<key> <string>null</string> </key>
<value> <int>0</int> </value>
</item>
<item>
<key> <string>type</string> </key>
<value> <string>t</string> </value>
</item>
<item>
<key> <string>width</string> </key>
<value> <int>3</int> </value>
</item>
</dictionary>
<dictionary>
<item>
<key> <string>name</string> </key>
<value> <string>Default</string> </value>
</item>
<item>
<key> <string>null</string> </key>
<value> <int>1</int> </value>
</item>
<item>
<key> <string>type</string> </key>
<value> <string>t</string> </value>
</item>
<item>
<key> <string>width</string> </key>
<value> <int>2</int> </value>
</item>
</dictionary>
<dictionary>
<item>
<key> <string>name</string> </key>
<value> <string>Extra</string> </value>
</item>
<item>
<key> <string>null</string> </key>
<value> <int>0</int> </value>
</item>
<item>
<key> <string>type</string> </key>
<value> <string>t</string> </value>
</item>
<item>
<key> <string>width</string> </key>
<value> <int>0</int> </value>
</item>
</dictionary>
</list>
</value>
</item>
<item>
<key> <string>arguments_src</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>connection_id</string> </key>
<value> <string>cmf_activity_sql_connection</string> </value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>ActivityTool_showMessageQueueTableColumns</string> </value>
</item>
<item>
<key> <string>src</string> </key>
<value> <string>show columns from message_queue</string> </value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string></string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="SQL" module="Products.ZSQLMethods.SQL"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>arguments_src</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>connection_id</string> </key>
<value> <string>cmf_activity_sql_connection</string> </value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>ActivityTool_upgradeMessageQueueTable</string> </value>
</item>
<item>
<key> <string>src</string> </key>
<value> <string>alter table message_queue add column `group_method_id` VARCHAR(255) NOT NULL DEFAULT \'\' AFTER `priority`</string> </value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string></string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
......@@ -51,32 +51,27 @@
<item>
<key> <string>_body</string> </key>
<value> <string>portal = context.getPortalObject()\n
message_list = []\n
is_upgrade_required = 0\n
site_property_dict = portal.ERP5Site_getUpgraderSignature().get(\'erp5_site_property_dict\', {})\n
constraint_type_per_type, _ = context.Base_getConstraintTypeListPerPortalType()\n
constraint_type = filter_dict.get("constraint_type")\n
\n
for prop in site_property_dict:\n
if site_property_dict[prop] != getattr(portal,prop , None):\n
if not upgrade:\n
return ["Upgrade Required for Global Properties."]\n
is_upgrade_required = 1\n
break\n
\n
if is_upgrade_required:\n
for prop in site_property_dict:\n
portal.ERP5Site_editERP5SiteProperty(prop, site_property_dict[prop])\n
message_list.append("Upgrade Executed for Global Properties (%s)." % prop)\n
\n
return message_list\n
for portal_type, constraint_type_list in constraint_type_per_type.iteritems():\n
if not constraint_type and constraint_type not in constraint_type_list:\n
continue\n
method_kw = {\'fixit\': fixit,\n
\'filter\': filter_dict,\n
\'active_process\': active_process.getRelativeUrl()}\n
portal.portal_catalog.searchAndActivate(\'Base_postCheckConsistencyResult\',\n
portal_type=portal_type,\n
method_kw=method_kw)\n
</string> </value>
</item>
<item>
<key> <string>_params</string> </key>
<value> <string>upgrade=0</string> </value>
<value> <string>active_process, fixit=False, filter_dict={}</string> </value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>ERP5Site_upgradeGlobalPropertyList</string> </value>
<value> <string>Alarm_checkUpgraderConsistency</string> </value>
</item>
</dictionary>
</pickle>
......
......@@ -50,38 +50,43 @@
</item>
<item>
<key> <string>_body</string> </key>
<value> <string>"""\n
Migrate Object Classes based on upgrade signature\n
"""\n
class_signature_list = context.ERP5Site_getUpgraderSignature().get(\'upgrade_object_class_list\', [])\n
<value> <string>if REQUEST is not None:\n
from zExceptions import Unauthorized\n
raise Unauthorized("You can not call this script from the url")\n
\n
alarm_id_list = ("upgrader_check_pre_upgrade",\n
"upgrader_check_upgrader",\n
"upgrader_check_post_upgrade")\n
\n
portal = context.getPortalObject()\n
portal_alarms = portal.portal_alarms\n
message_list = []\n
\n
test_only = not upgrade\n
\n
for object_class in class_signature_list:\n
folder, test_before , from_class, to_class , test_after = object_class\n
folder_object = portal.restrictedTraverse(folder)\n
test_before_method = getattr(context, test_before )\n
test_after_method = getattr(context, test_after )\n
result = folder_object.upgradeObjectClass(test_before_method, \n
from_class, \n
to_class, \n
test_after_method, \n
test_only)\n
message_list.extend(result)\n
for alarm_id in alarm_id_list:\n
alarm = getattr(portal_alarms, alarm_id, None)\n
if alarm is not None and alarm.sense():\n
last_active_process = alarm.getLastActiveProcess()\n
result_list = last_active_process.getResultList()\n
if result_list:\n
detail = result_list[0].detail\n
else:\n
detail = ["Require solve %s" % alarm_id,]\n
message_list.extend(detail)\n
\n
return message_list\n
active_process = portal.restrictedTraverse(active_process)\n
if message_list:\n
active_process.postActiveResult(\n
summary=context.getTitle(),\n
severity=1, detail=message_list)\n
</string> </value>
</item>
<item>
<key> <string>_params</string> </key>
<value> <string>upgrade=0</string> </value>
<value> <string>active_process, REQUEST=None</string> </value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>ERP5Site_upgradeObjectClass</string> </value>
<value> <string>Alarm_postFullUpgradeNeed</string> </value>
</item>
</dictionary>
</pickle>
......
......@@ -53,35 +53,42 @@
<value> <string encoding="cdata"><![CDATA[
"""\n
Here we make sure the installed bt5 are the right ones.\n
If the installed bt5 are too old, then they must be upgraded\n
Run upgrader\n
"""\n
portal = context.getPortalObject()\n
portal_alarms = portal.portal_alarms\n
\n
NOTE: some day, we will mix multiple bt5 sources. The code\n
will be a bit longer. It could be a good idea to create\n
a kind of dict or a central data structure somewhere (like\n
the system signature in portal_introspections) instead of\n
having to repeat everywhere 5.4.3 or other release numbers.\n
def launchUpgraderAlarm(alarm_id, after_method_id=[]):\n
""" Get the alarm and use sense and solve """\n
upgrader_alarm = getattr(portal_alarms, alarm_id, None)\n
if upgrader_alarm is not None and upgrader_alarm.sense():\n
# call solve method\n
kw = dict(tag=alarm_id)\n
if len(after_method_id) > 0:\n
kw["after_method_id"] = after_method_id\n
method_id = upgrader_alarm.getSolveMethodId()\n
if method_id not in (None, \'\'):\n
method = getattr(upgrader_alarm.activate(**kw), method_id)\n
method()\n
return [method_id] + after_method_id\n
return after_method_id\n
\n
NOTE: the idea is to call a long list of "check list" scripts,\n
each of which has a "check" part and a "fix" (ie. upgrade) part, just like\n
constraints in ERP5. However, the order is very important\n
for upgrade, unlike constraints. And we need to be able\n
to override upgrade scripts for certain source releases.\n
previous_method_id = launchUpgraderAlarm(\'upgrader_check_pre_upgrade\')\n
\n
NOTE2: you can split if needed the upgrade process into more\n
alarms (this can be useful if restart is needed for example\n
between stages of upgrade)\n
"""\n
# Setup skins\n
context.ERP5Site_setupUpgraderSkinSelection()\n
previous_method_id.extend([\'recursiveImmediateReindexObject\',\n
\'immediateReindexObject\',\n
\'callMethodOnObjectList\'])\n
\n
# Right way is like this\n
# Now start the update\n
previous_method_id = launchUpgraderAlarm(\'upgrader_check_upgrader\',\n
after_method_id=previous_method_id)\n
\n
if len(context.ERP5Site_upgradeBusinessTemplateList()) > 0: \n
return True\n
previous_method_id.append(\'updateBusinessTemplateFromUrl\')\n
previous_method_id = launchUpgraderAlarm(\'upgrader_check_post_upgrade\',\n
after_method_id=previous_method_id)\n
\n
return False\n
# Nothing else to do, so we can disable.\n
context.setEnabled(False)\n
return\n
]]></string> </value>
......@@ -92,7 +99,7 @@ return False\n
</item>
<item>
<key> <string>id</string> </key>
<value> <string>Alarm_senseBT5Version</string> </value>
<value> <string>Alarm_runFullUpgrader</string> </value>
</item>
</dictionary>
</pickle>
......
......@@ -51,32 +51,35 @@
<item>
<key> <string>_body</string> </key>
<value> <string>"""\n
verify if the workflow was updated, if is not updated update it.\n
Run Post upgrade\n
"""\n
workflow_chain_dict = context.ERP5Site_getUpgraderSignature().get(\'workflow_chain_dict\', {})\n
if workflow_chain_dict is None:\n
# If no signature, ignore.\n
return []\n
portal_alarms = context.getPortalObject().portal_alarms\n
active_process = context.newActiveProcess()\n
\n
chain = context.portal_workflow.getWorkflowChainDict()\n
if chain == workflow_chain_dict:\n
return []\n
# We should not run post upgrade if upgrader was not solved or never executed\n
alarm = getattr(portal_alarms, \'upgrader_check_upgrader\')\n
if alarm.sense() in (None, True):\n
active_process.postActiveResult(summary=context.getTitle(),\n
severity=1,\n
detail="Is required run upgrade before solve it. " +\\\n
"You need run active sense once at least on this alarm")\n
return\n
\n
if int(upgrade) == 1:\n
context.portal_workflow.manage_changeWorkflows(default_chain = \'\',\n
props = workflow_chain_dict)\n
return ["Upgrade Executed for Workflow Chain."]\n
context.Alarm_checkUpgraderConsistency(fixit=True,\n
active_process=active_process,\n
filter_dict={"constraint_type": ["post_upgrade",]})\n
\n
return ["Upgrade Required for Workflow Chain."]\n
context.setEnabled(False)\n
return\n
</string> </value>
</item>
<item>
<key> <string>_params</string> </key>
<value> <string>upgrade=0</string> </value>
<value> <string>**kw</string> </value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>ERP5Site_upgradeWorkflowChain</string> </value>
<value> <string>Alarm_runPostUpgrade</string> </value>
</item>
</dictionary>
</pickle>
......
......@@ -51,22 +51,23 @@
<item>
<key> <string>_body</string> </key>
<value> <string>"""\n
First, change skin order based on introspection \n
of the current version which is installed\n
\n
XXX This configuration could be moved to upgrader signature\n
Run Pre upgrade\n
"""\n
context.Alarm_checkUpgraderConsistency(fixit=True,\n
active_process=context.newActiveProcess(),\n
filter_dict={"constraint_type": ["pre_upgrade"]})\n
\n
return True\n
context.setEnabled(False)\n
return\n
</string> </value>
</item>
<item>
<key> <string>_params</string> </key>
<value> <string></string> </value>
<value> <string>**kw</string> </value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>ERP5Site_setupUpgraderSkinSelection</string> </value>
<value> <string>Alarm_runPreUpgrade</string> </value>
</item>
</dictionary>
</pickle>
......
......@@ -53,21 +53,51 @@
<value> <string encoding="cdata"><![CDATA[
"""\n
Finalize Upgrade is the final step of upgrader. Here should contains\n
the scripts that should be executed after the business template installation.\n
Run Upgrader\n
\n
IMPORTANT: Don\'t use the constraint_type upgrader to data migration or big amount of objects,\n
because this step is suppose to run all constraints in the same transaction. \n
To not kill the instance, searchAndActivate will be used if countResults() > REINDEX_SPLIT_COUNT\n
"""\n
# Setup skins\n
context.ERP5Site_setupUpgraderSkinSelection()\n
\n
alarm_dict = context.ERP5Site_getUpgraderSignature().get(\'alarm_dict\', {})\n
if not alarm_dict.get(context.getId(), True):\n
return False\n
REINDEX_SPLIT_COUNT = 100\n
portal = context.getPortalObject()\n
portal_alarms = portal.portal_alarms\n
active_process = context.newActiveProcess()\n
\n
# We should not run upgrader if pre upgrade was not solved or never executed \n
alarm = getattr(portal_alarms, \'upgrader_check_pre_upgrade\')\n
if alarm.sense() in (None, True):\n
active_process.postActiveResult(summary=context.getTitle(),\n
severity=1,\n
detail="Is required solve Pre Upgrade first. " +\\\n
"You need run active sense once at least on this alarm")\n
return\n
\n
_, type_per_constraint_type = context.Base_getConstraintTypeListPerPortalType()\n
portal_type_list = type_per_constraint_type.get(\'upgrader\', [])\n
\n
tool_portal_type = \'Template Tool\' \n
if tool_portal_type in portal_type_list:\n
portal_type_list.remove(tool_portal_type)\n
\n
method_kw = {\'fixit\': True,\n
\'filter\': {"constraint_type": \'upgrader\'},\n
\'active_process\': active_process.getRelativeUrl()}\n
\n
for script_id in context.ERP5Site_getUpgraderSignature().get(\'finalize_upgrade_script_list\', []):\n
if len(getattr(context, script_id)()) > 0:\n
return True\n
portal.portal_templates.Base_postCheckConsistencyResult(**method_kw)\n
for portal_type in portal_type_list:\n
if portal.portal_catalog.countResults(\n
portal_type=portal_type_list)[0][0] > REINDEX_SPLIT_COUNT:\n
portal.portal_catalog.searchAndActivate(\'Base_postCheckConsistencyResult\',\n
portal_type=portal_type,\n
method_kw=method_kw)\n
else:\n
for result in portal.portal_catalog(portal_type=portal_type):\n
result.Base_postCheckConsistencyResult(**method_kw)\n
\n
return False\n
context.setEnabled(False)\n
return\n
]]></string> </value>
......@@ -78,7 +108,7 @@ return False\n
</item>
<item>
<key> <string>id</string> </key>
<value> <string>Alarm_senseFinalizeUpgrade</string> </value>
<value> <string>Alarm_runUpgrader</string> </value>
</item>
</dictionary>
</pickle>
......
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="PythonScript" module="Products.PythonScripts.PythonScript"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>Script_magic</string> </key>
<value> <int>3</int> </value>
</item>
<item>
<key> <string>_bind_names</string> </key>
<value>
<object>
<klass>
<global name="NameAssignments" module="Shared.DC.Scripts.Bindings"/>
</klass>
<tuple/>
<state>
<dictionary>
<item>
<key> <string>_asgns</string> </key>
<value>
<dictionary>
<item>
<key> <string>name_container</string> </key>
<value> <string>container</string> </value>
</item>
<item>
<key> <string>name_context</string> </key>
<value> <string>context</string> </value>
</item>
<item>
<key> <string>name_m_self</string> </key>
<value> <string>script</string> </value>
</item>
<item>
<key> <string>name_subpath</string> </key>
<value> <string>traverse_subpath</string> </value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</state>
</object>
</value>
</item>
<item>
<key> <string>_body</string> </key>
<value> <string>from Products.ERP5Type.Log import log\n
from Products.CMFActivity.ActiveResult import ActiveResult\n
\n
# Log Result to make debug easy in case of failure.\n
log("Summary: %s , Details: %s " % (summary, detail))\n
\n
active_result = ActiveResult()\n
active_result.edit(summary=summary, severity=severity, detail=detail)\n
return active_result\n
</string> </value>
</item>
<item>
<key> <string>_params</string> </key>
<value> <string>summary, severity=0, detail=\'\'</string> </value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>Alarm_saveActiveResult</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
......@@ -53,37 +53,51 @@
<value> <string encoding="cdata"><![CDATA[
"""\n
Verify if this instance is a properly configured one.\n
This script could be used in functional tests\n
Run upgrader\n
"""\n
portal = context.getPortalObject()\n
portal_alarms = portal.portal_alarms\n
\n
message_list = []\n
after_method_id = \'callMethodOnObjectList\'\n
def launchSenseAlarm(alarm_id, after_tag=[]):\n
""" Get the alarm and use sense"""\n
upgrader_alarm = getattr(portal_alarms, alarm_id, None)\n
if upgrader_alarm is not None:\n
# call solve method\n
kw = {"tag": alarm_id,\n
"after_method_id": after_method_id}\n
if len(after_tag) > 0:\n
kw["after_tag"] = after_tag\n
method_id = upgrader_alarm.getActiveSenseMethodId()\n
if method_id not in (None, \'\'):\n
method = getattr(upgrader_alarm.activate(**kw), method_id)\n
method()\n
return [alarm_id,]\n
return after_tag\n
\n
activity_failure_list = context.portal_activities.getMessageList(processing_node=-2)\n
previous_tag = launchSenseAlarm(\'upgrader_check_pre_upgrade\')\n
\n
if len(activity_failure_list) > 0:\n
message_list.append("Activity Failures was found (%s)." % (len(activity_failure_list),))\n
return message_list\n
previous_tag = launchSenseAlarm(\'upgrader_check_upgrader\',\n
after_tag=previous_tag)\n
\n
previous_tag = launchSenseAlarm(\'upgrader_check_post_upgrade\',\n
after_tag=previous_tag)\n
\n
active_process = context.newActiveProcess()\n
context.activate(after_tag=previous_tag,\n
after_method_id=after_method_id).Alarm_postFullUpgradeNeed(\n
active_process=active_process.getRelativeUrl())\n
]]></string> </value>
</item>
<item>
<key> <string>_params</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>_proxy_roles</string> </key>
<value>
<tuple>
<string>Manager</string>
</tuple>
</value>
<value> <string>REQUEST=None, **kw</string> </value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>ERP5Site_verifyActivityIntegrity</string> </value>
<value> <string>Alarm_senseFullUpgradeNeed</string> </value>
</item>
</dictionary>
</pickle>
......
......@@ -50,92 +50,18 @@
</item>
<item>
<key> <string>_body</string> </key>
<value> <string encoding="cdata"><![CDATA[
<value> <string>"""\n
Check if upgrader is required\n
"""\n
This script is used in an alarm that acts as a cron job.\n
It will start an instance upgrade if any of the following alarms:\n
- bt5_upgrader (supported)\n
\n
"sense" a need of an upgrade. This alarm is likely to disappear soon as it\'s needed \n
due to lack of functionality (which is that alarms can not automatically "solve" themselves).\n
"""\n
# If before script is present call it.\n
before_script = getattr(context, \'ERP5Site_beforeSenseUpgrade\', None)\n
if before_script is not None:\n
before_script()\n
\n
context.ERP5Site_setupUpgraderSkinSelection()\n
\n
portal_alarms = context.getPortalObject().portal_alarms\n
activate = context.portal_activities.activate\n
previous_tag = None\n
\n
# XXX get the last activate process if exists\n
active_process = context.getLastActiveProcess()\n
if active_process is None or ((DateTime() - active_process.getStartDate()) > 1):\n
active_process = context.newActiveProcess()\n
\n
active_process = active_process.getPath()\n
\n
def launchUpgraderAlarm(alarm_id, after_method_id=[]):\n
"""\n
Get the alarm and use sense and solve\n
"""\n
upgrader_alarm = getattr(portal_alarms, alarm_id, None)\n
if upgrader_alarm is not None and upgrader_alarm.sense():\n
# call solve method\n
activate(active_process=active_process,\n
activity=\'SQLQueue\', \n
priority=2).Alarm_saveActiveResult(\n
summary=upgrader_alarm.getTitle(), \n
severity=0, \n
detail="Upgrade Required for %s" % \\\n
(upgrader_alarm.getTitle()))\n
\n
kw = dict(tag=alarm_id)\n
if len(after_method_id) > 0:\n
kw["after_method_id"] = after_method_id\n
# alarm.solve() dos not support activate parameters\n
# so it is not possible to use it directly.\n
method_id = upgrader_alarm.getSolveMethodId()\n
if method_id not in (None, \'\'):\n
method = getattr(upgrader_alarm.activate(**kw), method_id)\n
method()\n
return [ method_id ]\n
return after_method_id\n
\n
# There is one strict order to run the alarms\n
# This is required because the one alarms depends the previous one be\n
# Fully done.\n
previous_method_id = launchUpgraderAlarm(\'bt5_upgrader\')\n
\n
previous_method_id.extend([\'updateBusinessTemplateFromUrl\',\n
\'immediateReindexObject\'])\n
\n
previous_method_id = launchUpgraderAlarm(\'finalize_upgrader\',\n
after_method_id = previous_method_id)\n
\n
for alarm_id in [\'bt5_upgrader\' , \'finalize_upgrader\']:\n
\n
upgrader_alarm = getattr(portal_alarms, alarm_id, None)\n
if upgrader_alarm is not None and upgrader_alarm.sense():\n
# Upgrade still needed for part.\n
#return\n
# XXX Do not retry run upgrader again, this is cause too much\n
# noise during this stage of development.\n
pass\n
\n
# Nothing else to do, so we can disable.\n
context.setEnabled(False)\n
return\n
]]></string> </value>
constraint_type = context.getId().replace("upgrader_check_", "")\n
context.Alarm_checkUpgraderConsistency(\n
active_process=context.newActiveProcess(),\n
filter_dict={"constraint_type": constraint_type})\n
</string> </value>
</item>
<item>
<key> <string>_params</string> </key>
<value> <string></string> </value>
<value> <string>REQUEST=None, **kw</string> </value>
</item>
<item>
<key> <string>id</string> </key>
......
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="PythonScript" module="Products.PythonScripts.PythonScript"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>Script_magic</string> </key>
<value> <int>3</int> </value>
</item>
<item>
<key> <string>_bind_names</string> </key>
<value>
<object>
<klass>
<global name="NameAssignments" module="Shared.DC.Scripts.Bindings"/>
</klass>
<tuple/>
<state>
<dictionary>
<item>
<key> <string>_asgns</string> </key>
<value>
<dictionary>
<item>
<key> <string>name_container</string> </key>
<value> <string>container</string> </value>
</item>
<item>
<key> <string>name_context</string> </key>
<value> <string>context</string> </value>
</item>
<item>
<key> <string>name_m_self</string> </key>
<value> <string>script</string> </value>
</item>
<item>
<key> <string>name_subpath</string> </key>
<value> <string>traverse_subpath</string> </value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</state>
</object>
</value>
</item>
<item>
<key> <string>_body</string> </key>
<value> <string>"""\n
This script explains how to upgrade bt5. This script only update\n
the business templates, nothing else. Any other post script should\n
be handle by finalize upgrader.\n
"""\n
# Setup skins\n
context.ERP5Site_setupUpgraderSkinSelection()\n
\n
alarm_dict = context.ERP5Site_getUpgraderSignature().get(\'alarm_dict\', {})\n
if not alarm_dict.get(context.getId(), True):\n
return False\n
\n
portal_alarms = context.getPortalObject().portal_alarms\n
activate = context.portal_activities.activate\n
# Group Messages into the same active process.\n
active_process = portal_alarms.upgrader_controller.getLastActiveProcess()\n
if active_process is None:\n
active_process = context.newActiveProcess()\n
\n
active_process = active_process.getPath()\n
\n
message_list = []\n
\n
# update existing bt5\n
message_list.extend(context.ERP5Site_upgradeBusinessTemplateList(upgrade=1))\n
\n
activate(active_process=active_process,\n
activity=\'SQLQueue\',\n
priority=2).Alarm_saveActiveResult(summary="Upgrade BT5 Version",\n
severity=0,\n
detail=\'\\n\'.join(message_list))\n
\n
return message_list\n
</string> </value>
</item>
<item>
<key> <string>_params</string> </key>
<value> <string>**kw</string> </value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>Alarm_upgradeBT5Version</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="PythonScript" module="Products.PythonScripts.PythonScript"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>Script_magic</string> </key>
<value> <int>3</int> </value>
</item>
<item>
<key> <string>_bind_names</string> </key>
<value>
<object>
<klass>
<global name="NameAssignments" module="Shared.DC.Scripts.Bindings"/>
</klass>
<tuple/>
<state>
<dictionary>
<item>
<key> <string>_asgns</string> </key>
<value>
<dictionary>
<item>
<key> <string>name_container</string> </key>
<value> <string>container</string> </value>
</item>
<item>
<key> <string>name_context</string> </key>
<value> <string>context</string> </value>
</item>
<item>
<key> <string>name_m_self</string> </key>
<value> <string>script</string> </value>
</item>
<item>
<key> <string>name_subpath</string> </key>
<value> <string>traverse_subpath</string> </value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</state>
</object>
</value>
</item>
<item>
<key> <string>_body</string> </key>
<value> <string>"""\n
Finalize Upgrade is the final step of upgrader. Here should contains\n
the scripts that should be executed after the business template installation.\n
"""\n
# Setup skins\n
context.ERP5Site_setupUpgraderSkinSelection()\n
\n
clear_cache_kw = dict(activity=\'SQLQueue\', \n
priority=3, \n
tag="tag_upgrader_clear_cache")\n
\n
portal_alarms = context.getPortalObject().portal_alarms\n
activate = context.portal_activities.activate\n
# Group Messages into the same active process.\n
active_process = portal_alarms.upgrader_controller.getLastActiveProcess()\n
if active_process is None:\n
active_process = context.newActiveProcess()\n
\n
active_process = active_process.getPath()\n
\n
message_list = []\n
bt5_upgrader_sense = portal_alarms.bt5_upgrader.sense()\n
if bt5_upgrader_sense:\n
activate(active_process=active_process,\n
activity=\'SQLQueue\',\n
priority=2).Alarm_saveActiveResult(\n
summary="ERROR: Finalize Upgrader not started",\n
severity=0,\n
detail=\'BT5 Upgrader Sense: %s\' % (bt5_upgrader_sense))\n
\n
for script_id in context.ERP5Site_getUpgraderSignature().get(\'finalize_upgrade_script_list\', []):\n
message_list.extend(getattr(context, script_id)(upgrade=1))\n
\n
activate(active_process=active_process,\n
activity=\'SQLQueue\',\n
priority=2).Alarm_saveActiveResult(summary="Finalize Upgrade",\n
severity=0,\n
detail=\'\\n\'.join(message_list))\n
\n
clear_cache_kw[\'after_method_id\'] = [\'Alarm_saveActiveResult\',\'immediateReindexObject\']\n
context.portal_caches.activate(**clear_cache_kw).clearAllCache()\n
\n
activate(active_process=active_process,\n
activity=\'SQLQueue\',\n
priority=4,\n
after_tag=clear_cache_kw[\'tag\']).ERP5Site_notifyUpgradeIntegrity(active_process=active_process)\n
\n
return message_list\n
</string> </value>
</item>
<item>
<key> <string>_params</string> </key>
<value> <string>**kw</string> </value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>Alarm_upgradeFinalize</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
......@@ -50,50 +50,69 @@
</item>
<item>
<key> <string>_body</string> </key>
<value> <string>"""\n
Verify if this instance is a properly configured one.\n
This script could be used in functional tests\n
"""\n
<value> <string>portal = context.getPortalObject()\n
constraint_type_list = portal.getPortalConstraintTypeList()\n
\n
portal = context.getPortalObject()\n
property_sheet_by_type_dict = {}\n
for portal_type in portal.portal_types.objectValues():\n
property_sheet_list = portal_type.getTypePropertySheetList()\n
if not property_sheet_list:\n
continue\n
for property_sheet in property_sheet_list:\n
property_sheet_by_type_dict.setdefault(\n
property_sheet, []).append(portal_type.getId())\n
\n
message_list = []\n
type_per_constraint_type = {}\n
constraint_type_per_id = {}\n
for property_sheet in portal.portal_property_sheets.objectValues():\n
constraint_list = property_sheet.objectValues(\n
portal_type=constraint_type_list)\n
if not constraint_list:\n
continue\n
type_list = []\n
type_list_append = type_list.append\n
property_sheet_id = property_sheet.getId()\n
for constraint in constraint_list:\n
method = getattr(constraint, \'getConstraintType\', None)\n
if not method:\n
continue\n
constraint_type = method()\n
if constraint_type:\n
if property_sheet_id in property_sheet_by_type_dict:\n
type_per_constraint_type.setdefault(\n
constraint_type, []).extend(\n
property_sheet_by_type_dict[property_sheet_id])\n
type_list_append(constraint_type)\n
if type_list:\n
constraint_type_per_id.setdefault(property_sheet_id, []).extend(type_list)\n
\n
message_list.extend(context.ERP5Site_upgradeBusinessTemplateList())\n
constraint_type_per_type = {}\n
for property_sheet_id, category_list in constraint_type_per_id.iteritems():\n
for portal_type in property_sheet_by_type_dict.get(property_sheet_id, []):\n
constraint_type_per_type.setdefault(portal_type, []).extend(category_list)\n
\n
message_list.extend(context.ERP5Site_upgradeGlobalPropertyList())\n
portal_type_tool = portal.portal_types\n
portal_type_list = constraint_type_per_type.keys()\n
\n
message_list.extend(context.ERP5Site_upgradeValidationStateList())\n
for portal_type in portal_type_list:\n
allowed_content_type_list = \\\n
portal_type_tool[portal_type].getTypeAllowedContentTypeList()\n
for allowed_content_type in allowed_content_type_list:\n
if allowed_content_type in portal_type_list:\n
type_list = constraint_type_per_type.pop(allowed_content_type)\n
for constraint_type in type_list:\n
type_per_constraint_type[constraint_type].remove(allowed_content_type)\n
\n
message_list.extend(context.ERP5Site_upgradeWorkflowChain())\n
\n
message_list.extend(context.ERP5Site_upgradeSQLCatalog())\n
\n
if getattr(context, \'WizardTool_isPersonReferenceGloballyUnique\', None) is not None:\n
if len(context.PersonModule_getUserAccountList(\'occupied\')) == 0 and \\\n
getattr(portal.acl_users, \'nexedi_authentication\', None) is not None:\n
# If there is collision this verification should not be launch be\n
# because it should fail anyway.\n
message_list.extend(context.ERP5Site_upgradeData())\n
\n
return message_list\n
return constraint_type_per_type, type_per_constraint_type\n
</string> </value>
</item>
<item>
<key> <string>_params</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>_proxy_roles</string> </key>
<value>
<tuple>
<string>Manager</string>
</tuple>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>ERP5Site_verifyUpgradeIntegrity</string> </value>
<value> <string>Base_getConstraintTypeListPerPortalType</string> </value>
</item>
</dictionary>
</pickle>
......
......@@ -50,17 +50,23 @@
</item>
<item>
<key> <string>_body</string> </key>
<value> <string>portal = context.getPortalObject()\n
portal.manage_addProperty(\'custom_property_without_meaning\', \'I was there\', \'string\')\n
<value> <string>"""\n
This script should returns always two list of Business Template.\n
- The first list is to resolve dependencies and upgrade.\n
- The second list is what you want to keep. This is useful if we want to keep \n
a old business template without updating it and without removing it\n
"""\n
\n
return (\'erp5_base\',), []\n
</string> </value>
</item>
<item>
<key> <string>_params</string> </key>
<value> <string></string> </value>
<value> <string>fixit=False</string> </value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>ERP5Site_updateSitePropertyForTestOnly</string> </value>
<value> <string>Base_getUpgradeBusinessTemplateList</string> </value>
</item>
</dictionary>
</pickle>
......
......@@ -50,36 +50,32 @@
</item>
<item>
<key> <string>_body</string> </key>
<value> <string>"""\n
Verify instance integrity launch all Integrity Verification scripts. \n
<value> <string>traverse = context.getPortalObject().restrictedTraverse\n
active_process = traverse(active_process)\n
\n
Run all verification scripts defined at Signature.\n
"""\n
message_list = []\n
# We don\'t need check more if something is already inconsistent\n
if (active_process.ActiveProcess_sense() and not fixit):\n
return\n
\n
for script_id in context.ERP5Site_getUpgraderSignature().get(\'integrity_verification_script_id_list\', []):\n
result = context.ERP5Site_runVerificationScript(script_id)\n
if result is not None:\n
message_list.append(result)\n
constraint_message_list = context.checkConsistency(fixit=fixit,\n
filter=filter)\n
\n
return message_list\n
if constraint_message_list and not active_process.getResultList():\n
summary = "%s Consistency - At least one inconsistent object found" % \\\n
(fixit and \'Fix\' or \'Check\')\n
active_process.postActiveResult(\n
severity=(not fixit and 1) or 0,\n
summary=summary,\n
detail=[m.message for m in constraint_message_list])\n
</string> </value>
</item>
<item>
<key> <string>_params</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>_proxy_roles</string> </key>
<value>
<tuple>
<string>Manager</string>
</tuple>
</value>
<value> <string>fixit, filter, active_process</string> </value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>ERP5Site_verifyInstanceIntegrity</string> </value>
<value> <string>Base_postCheckConsistencyResult</string> </value>
</item>
</dictionary>
</pickle>
......
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="ExternalMethod" module="Products.ExternalMethod.ExternalMethod"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>_function</string> </key>
<value> <string>ERP5Site_clearActivities</string> </value>
</item>
<item>
<key> <string>_module</string> </key>
<value> <string>ERP5UpgraderUtils</string> </value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>ERP5Site_clearActivities</string> </value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string></string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
......@@ -8,7 +8,7 @@
<dictionary>
<item>
<key> <string>_function</string> </key>
<value> <string>ERP5Site_runVerificationScript</string> </value>
<value> <string>ERP5Site_dumpWorkflowChainByPortalType</string> </value>
</item>
<item>
<key> <string>_module</string> </key>
......@@ -16,7 +16,7 @@
</item>
<item>
<key> <string>id</string> </key>
<value> <string>ERP5Site_runVerificationScript</string> </value>
<value> <string>ERP5Site_dumpWorkflowChainByPortalType</string> </value>
</item>
<item>
<key> <string>title</string> </key>
......
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="ExternalMethod" module="Products.ExternalMethod.ExternalMethod"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>_function</string> </key>
<value> <string>ERP5Site_editERP5SiteProperty</string> </value>
</item>
<item>
<key> <string>_module</string> </key>
<value> <string>ERP5UpgraderUtils</string> </value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>ERP5Site_editERP5SiteProperty</string> </value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string></string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="PythonScript" module="Products.PythonScripts.PythonScript"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>Script_magic</string> </key>
<value> <int>3</int> </value>
</item>
<item>
<key> <string>_bind_names</string> </key>
<value>
<object>
<klass>
<global name="NameAssignments" module="Shared.DC.Scripts.Bindings"/>
</klass>
<tuple/>
<state>
<dictionary>
<item>
<key> <string>_asgns</string> </key>
<value>
<dictionary>
<item>
<key> <string>name_container</string> </key>
<value> <string>container</string> </value>
</item>
<item>
<key> <string>name_context</string> </key>
<value> <string>context</string> </value>
</item>
<item>
<key> <string>name_m_self</string> </key>
<value> <string>script</string> </value>
</item>
<item>
<key> <string>name_subpath</string> </key>
<value> <string>traverse_subpath</string> </value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</state>
</object>
</value>
</item>
<item>
<key> <string>_body</string> </key>
<value> <string>"""\n
Site\'s version is the version of the erp5_core business template\n
This script could be moved to should use System Signature or \n
simple replaced by:\n
portal_instropections.getSystemSignature()["business_templates"]\n
"""\n
bt5 = context.getPortalObject().portal_templates.getInstalledBusinessTemplate("erp5_core")\n
return str(bt5.getVersion())\n
</string> </value>
</item>
<item>
<key> <string>_params</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>ERP5Site_getBusinessTemplateVersion</string> </value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string></string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="PythonScript" module="Products.PythonScripts.PythonScript"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>Script_magic</string> </key>
<value> <int>3</int> </value>
</item>
<item>
<key> <string>_bind_names</string> </key>
<value>
<object>
<klass>
<global name="NameAssignments" module="Shared.DC.Scripts.Bindings"/>
</klass>
<tuple/>
<state>
<dictionary>
<item>
<key> <string>_asgns</string> </key>
<value>
<dictionary>
<item>
<key> <string>name_container</string> </key>
<value> <string>container</string> </value>
</item>
<item>
<key> <string>name_context</string> </key>
<value> <string>context</string> </value>
</item>
<item>
<key> <string>name_m_self</string> </key>
<value> <string>script</string> </value>
</item>
<item>
<key> <string>name_subpath</string> </key>
<value> <string>traverse_subpath</string> </value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</state>
</object>
</value>
</item>
<item>
<key> <string>_body</string> </key>
<value> <string encoding="cdata"><![CDATA[
"""\n
The release signature is a kind of declarative\n
specification of an upgrader.\n
"""\n
\n
# Prevent unintended use of this script, as it would otherwise trigger an upgrade without possible site-specific settings.\n
raise Exception(\'This script is only an example. Copy, paste & customise it for your needs.\')\n
\n
# Alarm dict is used to enable/disable upgrade alarms.\n
\n
ALARM_DICT = {\n
"bt5_upgrader" : True,\n
"finalize_upgrader" : True\n
}\n
\n
# A list of bt5 which the upgrader can upgrade\n
# ie. a bt5 not in this list will not be upgraded\n
# by having an explicit list we can handle dedicate\n
# and we can allow people to create some developer mode\n
# stuff which they can control.\n
UPGRADABLE_BT5_ID_LIST = (\n
"erp5_core",\n
"erp5_mysql_innodb_catalog",\n
"erp5_xhtml_style",\n
"erp5_knowledge_pad",\n
"erp5_base",\n
"erp5_wizard",\n
"erp5_odt_style",\n
"erp5_ods_style",\n
"erp5_ingestion_mysql_innodb_catalog",\n
"erp5_ingestion",\n
"erp5_crm",\n
"erp5_web",\n
"erp5_dms",\n
"erp5_pdm",\n
"erp5_trade",\n
"erp5_accounting",\n
"erp5_invoicing",\n
"erp5_simplified_invoicing",\n
"tiolive_base",\n
"erp5_tax_resource",\n
"erp5_discount_resource",\n
"erp5_ooo_import",\n
"erp5_l10n_fr",\n
"erp5_l10n_ja",\n
"erp5_l10n_ko",\n
"erp5_l10n_pl_PL",\n
"erp5_l10n_pt-BR",\n
"erp5_accounting_l10n_ifrs",\n
"erp5_accounting_l10n_fr", \n
"erp5_accounting_l10n_sn",\n
"erp5_accounting_l10n_br_extend", \n
"erp5_mobile",\n
"erp5_ui_test_core",\n
"erp5_ui_test",\n
"erp5_jquery", \n
"erp5_jquery_ui", \n
"erp5_dhtml_style",\n
"erp5_configurator",\n
"erp5_configurator_standard",\n
)\n
\n
# A list bt5 which are required for the upgrade\n
# ie. the upgrader will install them even\n
# if they are not already installed\n
REQUIRED_BT5_ID_LIST = ()\n
\n
# A list bt5 which are required to upgrade catalog.\n
# After the bt5 be updated, update catalog will be trigger.\n
UPDATE_CATALOG_BT5_ID_LIST = ()\n
\n
# Call some scripts inside same transaction before or after BT update\n
BEFORE_TRIGGERED_BT5_SCRIPT_ID_DICT = {}\n
AFTER_TRIGGERED_BT5_SCRIPT_ID_DICT = {\'erp5_mysql_innodb_catalog\': (\'ERP5Site_updateSitePropertyForTestOnly\',)}\n
\n
# A list bt5 which require reinstallation\n
# ie. the upgrader will call reinstall\n
# on each of them and revert all local changes.\n
REINSTALLABLE_BT5_ID_LIST = ()\n
\n
# A snapshot of workflow chains which are known to be valid\n
# this snapshot will be generated automatically from release\n
# document in the future.\n
#\n
# chains are exhaustive: they may contain more workflows that\n
# installed workflows in a system (which is not perfect for\n
# example in the case of -chains in bt5)\n
WORKFLOW_CHAIN_DICT = None\n
\n
# Portal Type definition based on portal_types_roles_express.sxc\n
# Once this document changes this script should be immediately \n
# updated to include or fix any security change.\n
\n
# Workflows whose security should be updated.\n
# To upgrade entire security use context.portal_workflow.objectIds()\n
# or [] to update None.\n
\n
UPDATE_SECURITY_WORKFLOW_ID_LIST = []\n
\n
# Portal Types to be updated using updateMappingDefinition.\n
# To upgrade entire security use context.portal_types.objectIds()\n
# or [] to update None.\n
\n
UPDATE_ROLE_PORTAL_TYPE_LIST = []\n
\n
# A property sheet expected to found into a Portal Type List.\n
# Example: (\'TradeOrder\', ["Sale Packing List", "Purchase Packing List"]),\n
PORTAL_TYPE_PROPERTY_SHEET_LIST = []\n
\n
# items to keep even if marked by BT5 to \'Remove\'\n
KEEP_ORIGINAL_DICT = {\n
\'erp5_core\':(\'portal_preferences/default_site_preference\',\n
\'portal_categories/function\',\n
),\n
\n
\'erp5_dms\':(\'portal_workflow/processing_status_workflow\',\n
\'portal_categories/contributor\',\n
\'portal_skins/erp5_dms/Image_view/image_view\'\n
),\n
\n
\'erp5_base\':(\'portal_categories/specialise\',\n
),\n
\n
\'erp5_trade\':(\'portal_workflow/delivery_tax_interaction_workflow\',\n
\'portal_workflow/tax_interaction_workflow\',\n
\'tax_module\',\n
\'discount_module\',\n
\'portal_types/Discount\',\n
\'portal_types/Discount Line\',\n
\'portal_types/Discount Model Line\',\n
\'portal_types/Discount Module\',\n
\'portal_types/Tax\',\n
\'portal_types/Tax Line\',\n
\'portal_types/Tax Model Line\',\n
\'portal_types/Tax Module\',),\n
\n
\'erp5_invoicing\':(\'portal_workflow/delivery_movement_account_interaction_workflow\',\n
),\n
\n
\'erp5_wizard\':(\'portal_preferences/erp5_express_default_customer_preference\',\n
),\n
\n
}\n
\n
# Items which need validation or change at upgrade time.\n
# { BUSINESS_TEMPLATE_TITLE : (\n
# (OBJECT_PATH,\n
# SCRIPT TO COLLECT INFORMATION,\n
# RETURN EXPECTED THAT INDICATES THE OBJECT IS BROKEN,\n
# SCRIPT USED TO FIX , \n
# !OPTIONAL! PARAMETERS FOR THE SCRIPT AS A DICT),\n
# ),\n
# }\n
OBJECT_ACTION_DICT = {\n
\'erp5_base\':((\'portal_categories/group\', \'getValidationState\', \'draft\', \'embed\'),\n
(\'portal_categories/site\', \'getValidationState\', \'draft\', \'embed\'),\n
),\n
\n
\'erp5_knowledge_pad\': (# Make gadgets visible\n
(\'portal_gadgets/clock\', \'getValidationState\',\'invisible\', \'visible\'),\n
(\'portal_gadgets/erp5_advertisement\', \'getValidationState\',\'invisible\', \'visible\'),\n
(\'portal_gadgets/erp5_documentation\', \'getValidationState\',\'invisible\', \'visible\'),\n
(\'portal_gadgets/erp5_persons\', \'getValidationState\',\'invisible\', \'visible\'),\n
(\'portal_gadgets/erp5_rss\', \'getValidationState\',\'invisible\', \'visible\'),\n
(\'portal_gadgets/erp5_worklists\', \'getValidationState\',\'invisible\', \'visible\'),\n
(\'portal_gadgets/google_calendar\', \'getValidationState\',\'invisible\', \'visible\'),\n
(\'portal_gadgets/google_maps\', \'getValidationState\',\'invisible\', \'visible\'),\n
(\'portal_gadgets/google_search\', \'getValidationState\',\'invisible\', \'visible\'),\n
# Make gadgets published\n
(\'portal_gadgets/clock\', \'getValidationState\',\'visible\', \'public\'),\n
(\'portal_gadgets/erp5_advertisement\', \'getValidationState\',\'visible\', \'public\'),\n
(\'portal_gadgets/erp5_documentation\', \'getValidationState\',\'visible\', \'public\'),\n
(\'portal_gadgets/erp5_persons\', \'getValidationState\',\'visible\', \'public\'),\n
(\'portal_gadgets/erp5_rss\', \'getValidationState\',\'visible\', \'public\'),\n
(\'portal_gadgets/erp5_worklists\', \'getValidationState\',\'visible\', \'public\'),\n
(\'portal_gadgets/google_calendar\', \'getValidationState\',\'visible\', \'public\'),\n
(\'portal_gadgets/google_maps\', \'getValidationState\',\'visible\', \'public\'),\n
(\'portal_gadgets/google_search\', \'getValidationState\',\'visible\', \'public\'),\n
), \n
\n
\'erp5_trade\':((\'portal_rules/default_order_rule\', \'getValidationState\',\'draft\', \'validate\'),\n
(\'portal_rules/default_delivery_rule\', \'getValidationState\',\'draft\', \'validate\'),\n
),\n
\'erp5_invoicing\':((\'portal_rules/default_invoice_transaction_rule\', \'getValidationState\',\'draft\', \'validate\'),\n
(\'portal_rules/default_invoicing_rule\', \'getValidationState\',\'draft\', \'validate\'),\n
(\'portal_rules/default_trade_model_rule\', \'getValidationState\',\'validated\', \'invalidate\'),\n
),\n
}\n
\n
#\n
# Dictionary the expected filters for catalog. This is a usually determinated\n
# by catalog.getFilterDict()\n
#\n
CATALOG_FILTER_DICT = None\n
\n
#\n
# List of Scripts to be run after upgrade is finished to determinate \n
# the integrity and consistency of the instance.\n
#\n
\n
INTEGRITY_VERIFICATION_SCRIPT_ID_LIST = (\'ERP5Site_verifyUpgradeIntegrity\',\n
\'ERP5Site_verifyMemcachedIntegrity\',\n
\'ERP5Site_verifySQLCatalogFilterIntegrity\',\n
\'ERP5Site_verifyActivityIntegrity\')\n
\n
#\n
# List of Scripts to be sense and run after business template be upgraded. This can\n
# be consider as After methods.\n
\n
FINALIZE_ALARM_SCRIPT = ( \'ERP5Site_upgradeGlobalPropertyList\',\n
\'ERP5Site_upgradeObjectList\',\n
\'ERP5Site_upgradeWorkflowChain\',\n
\'ERP5Site_upgradePortalTypePropertySheet\',\n
\'ERP5Site_upgradeSecurity\',\n
\'ERP5Site_upgradeObjectClass\',\n
\'ERP5Site_upgradeSQLCatalogFilter\',\n
\'ERP5Site_upgradeAlarmToolConfiguration\',\n
\'ERP5Site_upgradeSQLCatalog\',\n
)\n
\n
# \n
# Define the property and value ({\'property\' : \'value\', ...} to be set or created \n
# into erp5 portal object.\n
#\n
ERP5_SITE_PROPERTY_DICT = {}\n
\n
# \n
# Define alarm configuration list, which alarm will be enabled or\n
# disabled.\n
# Usage (("alarm_id", True or False ),) \n
ALARM_TOOL_CONFIGURATION_LIST = ()\n
\n
\n
#\n
# Define instructions for migrate object class of a group of objects like:\n
# (( relative_url <- Folder Relative URL where the object is located.\n
# , \'script_to_run_before\' <- Script ID that will test if the \n
# object can be migrated or not.\n
# , \'Products.ERP5Type.Document.FROM.CLASS\' <- Expected Class to be migrated\n
# , \'Products.ERP5Type.Document.TO.CLASS\' <- Class to be Migrated.\n
# , \'script_to_run_after\' <- Script ID that will run after test it finished.\n
# ), )\n
# \n
\n
UPGRADE_OBJECT_CLASS_LIST = ( (\'portal_gadgets\', \n
\'ERP5Site_testUpgradeObjectClass\',\n
\'Products.ERP5Type.Document.Folder.Folder\', \n
\'Products.ERP5Type.Document.Gadget.Gadget\', \n
\'ERP5Site_testUpgradeObjectClass\' ), )\n
\n
RECATALOG = False\n
\n
# Wrap everything into a dict\n
signature_dict = {\n
# Defines the alarms enabled for the upgrade\n
\'alarm_dict\' : ALARM_DICT\n
# Provides a snapshot of how workflow chains should be configured\n
, \'workflow_chain_dict\': WORKFLOW_CHAIN_DICT\n
# Provides a list of required bt5 (without which upgrader wont\'t work)\n
, \'required_bt5_id_list\': REQUIRED_BT5_ID_LIST\n
# Provides a list of bt5 which can be upgraded by the upgrader (if already installed)\n
, \'upgradable_bt5_id_list\': UPGRADABLE_BT5_ID_LIST\n
, \'update_catalog_bt5_id_list\' : UPDATE_CATALOG_BT5_ID_LIST\n
, \'before_triggered_bt5_id_dict\': BEFORE_TRIGGERED_BT5_SCRIPT_ID_DICT\n
, \'after_triggered_bt5_id_dict\': AFTER_TRIGGERED_BT5_SCRIPT_ID_DICT\n
# Provide a list of bt5 which require reinstallation\n
, \'reinstallable_bt5_id_list\': REINSTALLABLE_BT5_ID_LIST\n
# Provides a list of bt5 path and items which must not be upgraded or deleted\n
, \'keep_original_dict\': KEEP_ORIGINAL_DICT\n
# Provides a list of bt5 path which require some action after upgrade\n
, \'object_action_dict\': OBJECT_ACTION_DICT\n
# Provides a list of script ids that will be run after the upgrade to check the Instance Integrity\n
, \'integrity_verification_script_id_list\': INTEGRITY_VERIFICATION_SCRIPT_ID_LIST\n
# Provides a list of script ids that will be run during finalization step\n
, \'finalize_upgrade_script_list\': FINALIZE_ALARM_SCRIPT\n
# Provides a dict with expected catalog filter expressions\n
, \'catalog_filter_dict\': CATALOG_FILTER_DICT\n
# Provides a list of workflow ids whose security should be updated.\n
, \'update_security_workflow_id_list\': UPDATE_SECURITY_WORKFLOW_ID_LIST\n
# Provides a list of portal types to had rules updated.\n
, \'update_role_portal_type_list\': UPDATE_ROLE_PORTAL_TYPE_LIST\n
# Provide a list of Property Sheet Expected into a portal type list\n
, \'portal_type_property_sheet_list\' : PORTAL_TYPE_PROPERTY_SHEET_LIST\n
# Provide a list of Properties Expected at ERP5Site portal\n
, \'erp5_site_property_dict\' : ERP5_SITE_PROPERTY_DICT\n
# Provide a list of tuples with informations to upgrade object class\n
, \'upgrade_object_class_list\' : UPGRADE_OBJECT_CLASS_LIST\n
# Define if the site will be recatalogued or not after finish upgrade.\n
, \'recatalog\' : RECATALOG\n
# Define which alarm should be enabled or disabled.\n
, \'alarm_tool_configuration_list\' : ALARM_TOOL_CONFIGURATION_LIST\n
}\n
\n
if item is not None:\n
return signature_dict.get(item, None)\n
else:\n
return signature_dict\n
]]></string> </value>
</item>
<item>
<key> <string>_params</string> </key>
<value> <string>item=None</string> </value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>ERP5Site_getUpgraderSignature</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="ExternalMethod" module="Products.ExternalMethod.ExternalMethod"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>_function</string> </key>
<value> <string>ERP5Site_restartZopeInstance</string> </value>
</item>
<item>
<key> <string>_module</string> </key>
<value> <string>ERP5UpgraderUtils</string> </value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>ERP5Site_restartZopeInstance</string> </value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string></string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="PythonScript" module="Products.PythonScripts.PythonScript"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>Script_magic</string> </key>
<value> <int>3</int> </value>
</item>
<item>
<key> <string>_bind_names</string> </key>
<value>
<object>
<klass>
<global name="NameAssignments" module="Shared.DC.Scripts.Bindings"/>
</klass>
<tuple/>
<state>
<dictionary>
<item>
<key> <string>_asgns</string> </key>
<value>
<dictionary>
<item>
<key> <string>name_container</string> </key>
<value> <string>container</string> </value>
</item>
<item>
<key> <string>name_context</string> </key>
<value> <string>context</string> </value>
</item>
<item>
<key> <string>name_m_self</string> </key>
<value> <string>script</string> </value>
</item>
<item>
<key> <string>name_subpath</string> </key>
<value> <string>traverse_subpath</string> </value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</state>
</object>
</value>
</item>
<item>
<key> <string>_body</string> </key>
<value> <string>"""\n
"""\n
message_list = []\n
portal_alarms = context.portal_alarms\n
alarm_tool_configuration_list = context.ERP5Site_getUpgraderSignature().get(\'alarm_tool_configuration_list\', [])\n
if alarm_tool_configuration_list is None:\n
return message_list\n
\n
for alarm_id, is_enabled in alarm_tool_configuration_list: \n
obj = getattr(portal_alarms, alarm_id, None)\n
if obj is not None and int(obj.getEnabled()) != int(is_enabled):\n
message = "Upgrade is required for Alarm %s, enabled = %s (expected %s)" % \\\n
(alarm_id, obj.getEnabled(),is_enabled )\n
if int(upgrade) == 1:\n
obj.setEnabled(int(is_enabled))\n
message = "[ UPDATED ] " + message\n
message_list.append(message)\n
\n
return message_list\n
</string> </value>
</item>
<item>
<key> <string>_params</string> </key>
<value> <string>upgrade=0</string> </value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>ERP5Site_upgradeAlarmToolConfiguration</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="PythonScript" module="Products.PythonScripts.PythonScript"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>Script_magic</string> </key>
<value> <int>3</int> </value>
</item>
<item>
<key> <string>_bind_names</string> </key>
<value>
<object>
<klass>
<global name="NameAssignments" module="Shared.DC.Scripts.Bindings"/>
</klass>
<tuple/>
<state>
<dictionary>
<item>
<key> <string>_asgns</string> </key>
<value>
<dictionary>
<item>
<key> <string>name_container</string> </key>
<value> <string>container</string> </value>
</item>
<item>
<key> <string>name_context</string> </key>
<value> <string>context</string> </value>
</item>
<item>
<key> <string>name_m_self</string> </key>
<value> <string>script</string> </value>
</item>
<item>
<key> <string>name_subpath</string> </key>
<value> <string>traverse_subpath</string> </value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</state>
</object>
</value>
</item>
<item>
<key> <string>_body</string> </key>
<value> <string encoding="cdata"><![CDATA[
"""\n
Check installed business templates one \n
by one. If one of the business templates does not \n
use the latest revision, then we need to install.\n
"""\n
# Initialize variables\n
portal = context.getPortalObject()\n
portal_templates = portal.portal_templates\n
signature = portal.ERP5Site_getUpgraderSignature()\n
message_list = []\n
\n
previous_bt5_id = None\n
bt5_counter = 0\n
available_bt5_list = portal_templates.getRepositoryBusinessTemplateList(newest_only=True)\n
available_bt5_id_list = [x.title for x in available_bt5_list]\n
required_bt5_id_list = signature.get(\'required_bt5_id_list\', [])\n
upgradable_bt5_id_list = signature.get(\'upgradable_bt5_id_list\', [])\n
if len(upgradable_bt5_id_list) == 0:\n
# by default, we try to upgrade all installed business templates.\n
upgradable_bt5_id_list = portal_templates.getInstalledBusinessTemplateTitleList()\n
reinstallable_bt5_id_list = signature.get(\'reinstallable_bt5_id_list\', signature.get(\'reinstalable_bt5_id_list\', []))\n
before_triggered_bt5_id_dict = signature.get(\'before_triggered_bt5_id_dict\', {})\n
after_triggered_bt5_id_dict = signature.get(\'after_triggered_bt5_id_dict\', {})\n
update_catalog_bt5_id_list = signature.get(\'update_catalog_bt5_id_list\', [])\n
not_upgradable_id_list = signature.get(\'not_upgradable_id_list\', [])\n
\n
bt5_id_list = dict([(x, True) for x in list(required_bt5_id_list) + \\\n
list(upgradable_bt5_id_list) + \\\n
list(reinstallable_bt5_id_list) \\\n
if x in available_bt5_id_list and x not in not_upgradable_id_list]).keys()\n
\n
# sort by dependencies\n
bt5_list = [portal_templates.decodeRepositoryBusinessTemplateUid(x.uid) for x in \\\n
available_bt5_list if x.title in bt5_id_list]\n
bt5_list = portal_templates.sortBusinessTemplateList(bt5_list)\n
\n
installed_bt5_title_list = [o.getTitle() for o in portal_templates.getInstalledBusinessTemplateList()]\n
\n
bt5_counter = portal_templates.countFolder()[0][0]\n
\n
def installBT5(bt5_url, bt5_title, previous_bt5, bt5_counter, force=False):\n
bt5_id = "%s_%s" % (bt5_counter, bt5_title)\n
kw = dict(activity="SQLQueue", tag=bt5_id)\n
if previous_bt5 is not None:\n
kw[\'after_tag\'] = previous_bt5\n
# We must make sure all documents from previous installations \n
# are already indexed (specially categories).\n
kw[\'after_method_id\'] = "immediateReindexObject"\n
update_catalog = bt5_title in update_catalog_bt5_id_list\n
before_triggered_bt5_id_list = before_triggered_bt5_id_dict.get(bt5_title, ())\n
after_triggered_bt5_id_list = after_triggered_bt5_id_dict.get(bt5_title, ())\n
keep_original_list = signature.get(\'keep_original_dict\', {}).get(bt5_title, ())\n
if upgrade:\n
portal_templates.activate(**kw).updateBusinessTemplateFromUrl(\n
bt5_url, # id=bt5_id, \n
keep_original_list=keep_original_list,\n
before_triggered_bt5_id_list=before_triggered_bt5_id_list,\n
after_triggered_bt5_id_list=after_triggered_bt5_id_list,\n
update_catalog=update_catalog,\n
reinstall=force)\n
previous_bt5_id = bt5_id\n
bt5_counter += 1\n
message_list.append("%s will be installed" % bt5_url)\n
return bt5_id\n
\n
previous_bt5 = None\n
for repository, bt5_id in bt5_list:\n
new_bt = [x for x in available_bt5_list \\\n
if portal_templates.decodeRepositoryBusinessTemplateUid(x.uid) == (repository, bt5_id)][0]\n
bt5_url = \'/\'.join((repository, bt5_id))\n
bt5_title = new_bt.title\n
if bt5_title in reinstallable_bt5_id_list:\n
bt5_id = installBT5(bt5_url, bt5_title, previous_bt5, bt5_counter, force=True)\n
previous_bt5 = bt5_id\n
else:\n
installed_bt = portal_templates.getInstalledBusinessTemplate(bt5_title, strict=True)\n
if installed_bt is not None:\n
if int(installed_bt.getRevision() or 0) >= int(new_bt.revision or 0):\n
continue\n
if bt5_title in required_bt5_id_list:\n
bt5_counter += 1\n
bt5_id = installBT5(bt5_url, bt5_title, previous_bt5, bt5_counter)\n
previous_bt5 = bt5_id\n
elif bt5_title in installed_bt5_title_list: # update_bt5_id_list\n
bt5_counter += 1\n
bt5_id = installBT5(bt5_url, bt5_title, previous_bt5, bt5_counter)\n
previous_bt5 = bt5_id\n
\n
return message_list\n
]]></string> </value>
</item>
<item>
<key> <string>_params</string> </key>
<value> <string>upgrade=0</string> </value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>ERP5Site_upgradeBusinessTemplateList</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="PythonScript" module="Products.PythonScripts.PythonScript"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>Script_magic</string> </key>
<value> <int>3</int> </value>
</item>
<item>
<key> <string>_bind_names</string> </key>
<value>
<object>
<klass>
<global name="NameAssignments" module="Shared.DC.Scripts.Bindings"/>
</klass>
<tuple/>
<state>
<dictionary>
<item>
<key> <string>_asgns</string> </key>
<value>
<dictionary>
<item>
<key> <string>name_container</string> </key>
<value> <string>container</string> </value>
</item>
<item>
<key> <string>name_context</string> </key>
<value> <string>context</string> </value>
</item>
<item>
<key> <string>name_m_self</string> </key>
<value> <string>script</string> </value>
</item>
<item>
<key> <string>name_subpath</string> </key>
<value> <string>traverse_subpath</string> </value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</state>
</object>
</value>
</item>
<item>
<key> <string>_body</string> </key>
<value> <string>"""\n
It is expected that some objects has some state in the after upgrade finish.\n
This alarm verify and upgrade the objects that were defined in signature.\n
"""\n
from Products.ERP5Type.Log import log\n
portal_templates = context.portal_templates\n
validation_dict = context.ERP5Site_getUpgraderSignature().get(\'object_action_dict\', {})\n
param_not_provided = "PARAM_NOT_PROVIDED"\n
\n
# get list of title of bt5 that are installed.\n
installed_bt5_title_list = [t.getTitle() for t in portal_templates.getInstalledBusinessTemplateList()]\n
\n
# get the list of keys that correspond to a valid business template.\n
upgradable_list = []\n
for k in validation_dict.keys():\n
if k in installed_bt5_title_list:\n
upgradable_list.extend(validation_dict[k])\n
\n
message_list = []\n
for definition in upgradable_list:\n
if len(definition) == 5:\n
path, method_id, expected_state, action, param_list = definition\n
else:\n
path, method_id, expected_state, action = definition\n
param_list = param_not_provided\n
sub_message_list = []\n
try:\n
obj = context.restrictedTraverse(path)\n
except KeyError:\n
obj = None\n
log("Unable to find %s" % path)\n
if obj is not None:\n
method = getattr(obj, method_id, None)\n
if method is not None and method() == expected_state:\n
sub_message_list.append("Upgrade is required for Object List (%s object is in %s state, action %s.)" %\n
(path, expected_state, action))\n
if int(upgrade) == 1:\n
action_method = getattr(obj, action , None)\n
if action_method is not None:\n
if param_list == param_not_provided:\n
action_method()\n
else:\n
action_method(*param_list)\n
sub_message_list.append("[UPDATED]")\n
message_list.append(\' \'.join(sub_message_list))\n
\n
return message_list\n
</string> </value>
</item>
<item>
<key> <string>_params</string> </key>
<value> <string>upgrade=0</string> </value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>ERP5Site_upgradeObjectList</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="PythonScript" module="Products.PythonScripts.PythonScript"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>Script_magic</string> </key>
<value> <int>3</int> </value>
</item>
<item>
<key> <string>_bind_names</string> </key>
<value>
<object>
<klass>
<global name="NameAssignments" module="Shared.DC.Scripts.Bindings"/>
</klass>
<tuple/>
<state>
<dictionary>
<item>
<key> <string>_asgns</string> </key>
<value>
<dictionary>
<item>
<key> <string>name_container</string> </key>
<value> <string>container</string> </value>
</item>
<item>
<key> <string>name_context</string> </key>
<value> <string>context</string> </value>
</item>
<item>
<key> <string>name_m_self</string> </key>
<value> <string>script</string> </value>
</item>
<item>
<key> <string>name_subpath</string> </key>
<value> <string>traverse_subpath</string> </value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</state>
</object>
</value>
</item>
<item>
<key> <string>_body</string> </key>
<value> <string>"""\n
Verify if a Property Sheet is associated with the Portal Type.\n
"""\n
\n
message_list = []\n
\n
portal_type_property_sheet_list = context.ERP5Site_getUpgraderSignature().get(\'portal_type_property_sheet_list\', [])\n
\n
for expected_property_sheet, portal_type_id_list in portal_type_property_sheet_list:\n
\n
portal_type_list = context.portal_types.searchFolder(id=portal_type_id_list)\n
portal_type_to_fix = []\n
\n
for pt in portal_type_list:\n
property_sheet_list = pt.getTypePropertySheetList()\n
if expected_property_sheet not in pt.getTypePropertySheetList():\n
if upgrade:\n
property_sheet_list.append(expected_property_sheet)\n
pt.setTypePropertySheet(property_sheet_list)\n
message_list.append("Associate PropertySheet %s into Portal Type %s." % (expected_property_sheet,pt.getId()))\n
else:\n
message_list.append("%s doesn\'t has %s associated." % (pt.getId(), expected_property_sheet))\n
\n
return message_list\n
</string> </value>
</item>
<item>
<key> <string>_params</string> </key>
<value> <string>upgrade=0</string> </value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>ERP5Site_upgradePortalTypePropertySheet</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="PythonScript" module="Products.PythonScripts.PythonScript"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>Script_magic</string> </key>
<value> <int>3</int> </value>
</item>
<item>
<key> <string>_bind_names</string> </key>
<value>
<object>
<klass>
<global name="NameAssignments" module="Shared.DC.Scripts.Bindings"/>
</klass>
<tuple/>
<state>
<dictionary>
<item>
<key> <string>_asgns</string> </key>
<value>
<dictionary>
<item>
<key> <string>name_container</string> </key>
<value> <string>container</string> </value>
</item>
<item>
<key> <string>name_context</string> </key>
<value> <string>context</string> </value>
</item>
<item>
<key> <string>name_m_self</string> </key>
<value> <string>script</string> </value>
</item>
<item>
<key> <string>name_subpath</string> </key>
<value> <string>traverse_subpath</string> </value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</state>
</object>
</value>
</item>
<item>
<key> <string>_body</string> </key>
<value> <string>"""\n
Update SQLCatalog, this script update the catalog when it is needed.\n
Finalize Upgrade never make sense become True, because there is no\n
standard way to detect if the SQLUpgrade is needed. Reindexation should \n
be only a consequence of other script only.\n
"""\n
signature = context.ERP5Site_getUpgraderSignature()\n
if not signature.get("recatalog", True):\n
return []\n
\n
if not upgrade:\n
# Never consider outdated.\n
return []\n
\n
# Could we consider always update this after some business templates\n
# was updated?\n
message_list = []\n
\n
if not upgrade:\n
# Upgrade Required\n
return [\'Upgrade required for SQLCatalog\']\n
\n
catalog = context.portal_catalog.getSQLCatalog()\n
\n
# clear the catalog\n
catalog.manage_catalogClear()\n
message_list.append("Catalog %s was Clear." % (catalog.getId()))\n
\n
tag = "tag_migration_finish"\n
# reindex the while site\n
context.getPortalObject().ERP5Site_reindexAll(final_activity_tag=tag)\n
message_list.append("Launched Reindex of ERP5.")\n
# update translation\n
context.getPortalObject().ERP5Site_updateTranslationTable()\n
message_list.append("Update Translation Table.")\n
return message_list\n
</string> </value>
</item>
<item>
<key> <string>_params</string> </key>
<value> <string>upgrade=0</string> </value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>ERP5Site_upgradeSQLCatalog</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="PythonScript" module="Products.PythonScripts.PythonScript"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>Script_magic</string> </key>
<value> <int>3</int> </value>
</item>
<item>
<key> <string>_bind_names</string> </key>
<value>
<object>
<klass>
<global name="NameAssignments" module="Shared.DC.Scripts.Bindings"/>
</klass>
<tuple/>
<state>
<dictionary>
<item>
<key> <string>_asgns</string> </key>
<value>
<dictionary>
<item>
<key> <string>name_container</string> </key>
<value> <string>container</string> </value>
</item>
<item>
<key> <string>name_context</string> </key>
<value> <string>context</string> </value>
</item>
<item>
<key> <string>name_m_self</string> </key>
<value> <string>script</string> </value>
</item>
<item>
<key> <string>name_subpath</string> </key>
<value> <string>traverse_subpath</string> </value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</state>
</object>
</value>
</item>
<item>
<key> <string>_body</string> </key>
<value> <string>message_list = []\n
expect_expression_dict = context.ERP5Site_getUpgraderSignature().get(\'catalog_filter_dict\', None)\n
if expect_expression_dict is None:\n
# If key is not provided, ignore.\n
return []\n
\n
catalog = context.portal_catalog.erp5_mysql_innodb\n
\n
filter_dict = catalog.getFilterDict()\n
catalog_filter_dict = {}\n
for key in filter_dict:\n
catalog_filter_dict[key] = filter_dict[key][\'expression\']\n
\n
# test if keys are the same\n
for key in expect_expression_dict:\n
if expect_expression_dict[key] != catalog_filter_dict[key]:\n
message_list.append("Wrong expression definition found at %s: %s (Expected) != %s (Found)" % (key, expect_expression_dict[key], catalog_filter_dict[key]))\n
\n
if not upgrade:\n
return message_list\n
\n
message_list = []\n
# test if keys are the same\n
for key in expect_expression_dict:\n
if expect_expression_dict[key] != catalog_filter_dict[key]:\n
message_list.append("Upgraded Catalog Filter Expression definition found at %s ." % (key))\n
catalog.setFilterExpression(key, expect_expression_dict[key])\n
return message_list\n
</string> </value>
</item>
<item>
<key> <string>_params</string> </key>
<value> <string>upgrade=0</string> </value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>ERP5Site_upgradeSQLCatalogFilter</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="PythonScript" module="Products.PythonScripts.PythonScript"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>Script_magic</string> </key>
<value> <int>3</int> </value>
</item>
<item>
<key> <string>_bind_names</string> </key>
<value>
<object>
<klass>
<global name="NameAssignments" module="Shared.DC.Scripts.Bindings"/>
</klass>
<tuple/>
<state>
<dictionary>
<item>
<key> <string>_asgns</string> </key>
<value>
<dictionary>
<item>
<key> <string>name_container</string> </key>
<value> <string>container</string> </value>
</item>
<item>
<key> <string>name_context</string> </key>
<value> <string>context</string> </value>
</item>
<item>
<key> <string>name_m_self</string> </key>
<value> <string>script</string> </value>
</item>
<item>
<key> <string>name_subpath</string> </key>
<value> <string>traverse_subpath</string> </value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</state>
</object>
</value>
</item>
<item>
<key> <string>_body</string> </key>
<value> <string>"""\n
Place for add Security or Roles upgrade.\n
\n
There is tools and new modules added by upgrader\n
and those the roles should be updated. \n
\n
ie.: Make Web site available for old instances or\n
update local roles.\n
\n
"""\n
message_list = []\n
\n
# Currently is never needed to update security, it is always forced.\n
if not upgrade:\n
return message_list\n
\n
portal = context.getPortalObject()\n
portal_workflow = portal.portal_workflow\n
workflow_id_list = portal.ERP5Site_getUpgraderSignature().get(\'update_security_workflow_id_list\', [])\n
for workflow_id in workflow_id_list:\n
workflow = getattr(portal_workflow, workflow_id, None)\n
if workflow is not None:\n
workflow.updateRoleMappings()\n
\n
message_list.append(\n
"Update workflow security for: \\n\\t%s" % \\\n
(\'\\n\\t\'.join(workflow_id_list)))\n
\n
types_tool = portal.portal_types\n
portal_type_list = portal.ERP5Site_getUpgraderSignature().get(\'update_role_portal_type_list\', [])\n
\n
for pt in portal_type_list:\n
# Note: Raises on purpose\n
types_tool[pt].updateRoleMapping()\n
\n
message_list.append(\n
"Update Local Roles for security groups for: \\n\\t%s" % \\\n
(\'\\n\\t\'.join(portal_type_list)))\n
\n
return message_list\n
</string> </value>
</item>
<item>
<key> <string>_params</string> </key>
<value> <string>upgrade=0</string> </value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>ERP5Site_upgradeSecurity</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="PythonScript" module="Products.PythonScripts.PythonScript"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>Script_magic</string> </key>
<value> <int>3</int> </value>
</item>
<item>
<key> <string>_bind_names</string> </key>
<value>
<object>
<klass>
<global name="NameAssignments" module="Shared.DC.Scripts.Bindings"/>
</klass>
<tuple/>
<state>
<dictionary>
<item>
<key> <string>_asgns</string> </key>
<value>
<dictionary>
<item>
<key> <string>name_container</string> </key>
<value> <string>container</string> </value>
</item>
<item>
<key> <string>name_context</string> </key>
<value> <string>context</string> </value>
</item>
<item>
<key> <string>name_m_self</string> </key>
<value> <string>script</string> </value>
</item>
<item>
<key> <string>name_subpath</string> </key>
<value> <string>traverse_subpath</string> </value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</state>
</object>
</value>
</item>
<item>
<key> <string>_body</string> </key>
<value> <string>"""\n
Verify if this instance is a properly configured one.\n
This script could be used in functional tests\n
"""\n
plugin_id_list = [\'default_memcached_plugin\',\'persistent_memcached_plugin\']\n
portal = context.getPortalObject()\n
key_prefix = \'upgrade_verification\'\n
if getattr(portal, "erp5_site_global_id", None) == "test_client_chroot":\n
# This is a test environment so all instance will have the same prefix.\n
# change key_prefix to prevent useless failure.\n
key_prefix = \'upgrade_verification%s\' % str(float(DateTime()))\n
\n
message_list = []\n
\n
def assertEquals(value1, value2, label=""):\n
if not (value1 == value2):\n
message_list.append("Memcached: %s Fail (%s != %s)" % (label, value1, value2))\n
\n
def assertNotEquals(value1, value2, label=""):\n
if not (value1 != value2):\n
message_list.append("Memcached: %s Fail (%s == %s)" % (label, value1, value2))\n
\n
# Verify if memcached and plugins are present into the instance\n
portal_memcached = getattr(portal, "portal_memcached", None)\n
if portal_memcached is not None:\n
plugin_object_id_list = portal_memcached.objectIds()\n
for plugin_id in plugin_id_list:\n
if plugin_id not in plugin_object_id_list:\n
message_list.append("Memcached plugin %s is not present." % plugin_id)\n
else: \n
message_list.append("Portal Memcached is not present.")\n
\n
# Test Plugins\n
def getMemcachedDict(plugin_path):\n
return portal_memcached.getMemcachedDict(key_prefix=key_prefix, \n
plugin_path=plugin_path)\n
\n
# If this is not None the value was get from another instance\n
site_id = getattr(portal, "erp5_site_global_id", None)\n
for plugin_id in plugin_id_list:\n
plugin_object = getMemcachedDict(\'portal_memcached/%s\' % plugin_id)\n
if plugin_object.get("upgrade_verification_key") in ("Foo Bar", None):\n
# Solve some possible legacy.\n
plugin_object["upgrade_verification_key"] = site_id\n
assertEquals(plugin_object.get("upgrade_verification_key", site_id),\n
site_id, "upgrade_verification_key")\n
plugin_object.set("upgrade_verification_key", site_id)\n
assertEquals(plugin_object.get("upgrade_verification_key", None),\n
site_id, "upgrade_verification_key")\n
\n
return message_list\n
</string> </value>
</item>
<item>
<key> <string>_params</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>_proxy_roles</string> </key>
<value>
<tuple>
<string>Manager</string>
</tuple>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>ERP5Site_verifyMemcachedIntegrity</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="PythonScript" module="Products.PythonScripts.PythonScript"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>Script_magic</string> </key>
<value> <int>3</int> </value>
</item>
<item>
<key> <string>_bind_names</string> </key>
<value>
<object>
<klass>
<global name="NameAssignments" module="Shared.DC.Scripts.Bindings"/>
</klass>
<tuple/>
<state>
<dictionary>
<item>
<key> <string>_asgns</string> </key>
<value>
<dictionary>
<item>
<key> <string>name_container</string> </key>
<value> <string>container</string> </value>
</item>
<item>
<key> <string>name_context</string> </key>
<value> <string>context</string> </value>
</item>
<item>
<key> <string>name_m_self</string> </key>
<value> <string>script</string> </value>
</item>
<item>
<key> <string>name_subpath</string> </key>
<value> <string>traverse_subpath</string> </value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</state>
</object>
</value>
</item>
<item>
<key> <string>_body</string> </key>
<value> <string encoding="cdata"><![CDATA[
message_list = []\n
\n
catalog = context.portal_catalog.erp5_mysql_innodb\n
filter_dict = catalog.getFilterDict()\n
catalog_filter_dict = {}\n
for key in filter_dict:\n
catalog_filter_dict[key] = filter_dict[key][\'expression\']\n
\n
expect_expression_dict = context.ERP5Site_getUpgraderSignature().get(\'catalog_filter_dict\', {})\n
\n
if len(catalog_filter_dict.keys()) != len(expect_expression_dict.keys()):\n
message_list.append("Catalog filter have diferent key lenght (%s != %s): %s != %s" % \\\n
(len(catalog_filter_dict.keys()), len(expect_expression_dict.keys()),\n
catalog_filter_dict.keys(), expect_expression_dict.keys()))\n
\n
missing_key_list = [ key for key in expect_expression_dict if key not in catalog_filter_dict ]\n
\n
if len(missing_key_list) > 0:\n
message_list.append("Missing keys at Catalog filter: %s" % missing_key_list)\n
\n
for key in expect_expression_dict:\n
if expect_expression_dict[key] != catalog_filter_dict[key]:\n
message_list.append("Wrong expression definition found at %s: %s (Expected) != %s (Found)" % (key, expect_expression_dict[key], catalog_filter_dict[key]))\n
\n
real_data_verified = 0\n
for person in context.getPortalObject().person_module.contentValues():\n
organisation = person.getSubordinationValue()\n
if organisation is not None:\n
real_data_verified = 1\n
if person not in organisation.getSubordinationRelatedValueList(portal_type=\'Person\'):\n
message_list.append("Catalog is broken. Acquired categories are not in category table.")\n
# it is enough to check one object - there is full reindex done\n
break\n
\n
if not real_data_verified:\n
message_list.append("It was not possible to verify catalog integrity using real data.")\n
return message_list\n
]]></string> </value>
</item>
<item>
<key> <string>_params</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>_proxy_roles</string> </key>
<value>
<tuple>
<string>Manager</string>
</tuple>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>ERP5Site_verifySQLCatalogFilterIntegrity</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
......@@ -52,80 +52,74 @@
<key> <string>_body</string> </key>
<value> <string encoding="cdata"><![CDATA[
# This script is called at the end of reindex and Run \n
# the verification scripts for this migration \n
# \n
# In addition to verification script, this send the log of\n
# migration for each instance. So we can analize the result \n
# later. One event could be created into nexedi erp5 for \n
# each instance updated.\n
# \n
try:\n
result = context.ERP5Site_verifyInstanceIntegrity()\n
except:\n
# Make Sure that the email will be send and indicates which \n
# Instance fails to verify.\n
result = ["Verification Failed."]\n
if erp5_uid is None:\n
erp5_uid = getattr(context.getPortalObject(), "erp5_site_global_id", \'%s (%s)\' % (context.getPortalObject().getTitle(), context.getPortalObject().absolute_url()))\n
import re\n
template_tool = context\n
\n
body="""\n
Result for Upgrader Verification Script for %s Instance: \n
bt5_per_title_dict = {}\n
bt5_list = [i.getTitle() for i in \\\n
context.portal_templates.getRepositoryBusinessTemplateList()]\n
\n
installed_bt5_list = template_tool.getInstalledBusinessTemplateList()\n
for bt5 in installed_bt5_list:\n
bt5_title = bt5.title\n
if bt5_title not in bt5_list:\n
continue\n
bt5_per_title_dict[bt5_title] = bt5\n
\n
""" % (erp5_uid)\n
resolved_list = template_tool.resolveBusinessTemplateListDependency(bt5_per_title_dict.iterkeys())\n
\n
status = "OK"\n
if len(result) > 0:\n
status = "Failed"\n
body += \' \\n\'.join(result)\n
else:\n
body += \'NO MESSAGE\'\n
pattern = re.compile(r"(?P<portal_type>.*)[| ]\\|[| ](?P<workflow_id>.*)")\n
portal_type_dict = {}\n
for _, bt5_id in resolved_list:\n
if bt5_id not in bt5_per_title_dict:\n
continue\n
workflow_chain_list = bt5_per_title_dict[bt5_id].getTemplatePortalTypeWorkflowChainList()\n
if not workflow_chain_list:\n
continue\n
for workflow_chain in workflow_chain_list:\n
group_dict = pattern.match(workflow_chain).groupdict()\n
portal_type = group_dict[\'portal_type\']\n
workflow_id = group_dict[\'workflow_id\']\n
workflow_id_list = portal_type_dict.setdefault("%s" % portal_type, [])\n
if workflow_id.startswith(\'-\'):\n
workflow_id_list.remove(workflow_id.replace(\'-\', \'\'))\n
continue\n
elif workflow_id in workflow_id_list:\n
continue\n
workflow_id_list.append(workflow_id)\n
\n
body += """\n
========= Upgrader Log ============\n
"""\n
error_list = []\n
workflow_chain_by_portal_type_dict = context.ERP5Site_dumpWorkflowChainByPortalType()\n
new_workflow_chain_dict = {\'chain_%s\' % portal_type : \',\'.join(chain) \\\n
for portal_type, chain in workflow_chain_by_portal_type_dict.iteritems()}\n
\n
if active_process is not None:\n
process = context.restrictedTraverse(active_process)\n
if process is not None:\n
for active_result in process.getResultList():\n
body += """\n
%s\n
""" % (active_result.detail)\n
else:\n
body += "Fail to get log from activity result!"\n
for portal_type, workflow_chain in portal_type_dict.iteritems():\n
try:\n
workflow_chain_list = list(workflow_chain_by_portal_type_dict[portal_type])\n
except:\n
return workflow_chain_by_portal_type_dict[portal_type]\n
expected_workflow_chain = sorted(workflow_chain)\n
if sorted(workflow_chain_list) != expected_workflow_chain:\n
error_list.append("%s - Expected: %s <> Found: %s" % (portal_type, \', \'.join(workflow_chain), \', \'.join(workflow_chain_list)))\n
if fixit:\n
new_workflow_chain_dict["chain_%s" % portal_type] = \',\'.join(expected_workflow_chain)\n
\n
subject = "%s: Upgrade Result for %s" % (status, erp5_uid)\n
if fixit and new_workflow_chain_dict:\n
portal_workflow = context.getPortalObject().portal_workflow\n
portal_workflow.manage_changeWorkflows(default_chain="", props=new_workflow_chain_dict)\n
\n
kw = {\'body\': body,\n
\'erp5_uid\': erp5_uid,\n
\'subject\' : subject}\n
\n
# If the instance is well configured this will send a message\n
# to email_to_address or email_from_address. \n
context.portal_notifications.sendMessage(\n
sender=None,\n
recipient=[],\n
subject=subject,\n
message=body,\n
message_text_format=\'text/plain\',\n
notifier_list=(\'Mail Message\',),\n
store_as_event=False,\n
)\n
\n
return ["Notification is sent!"]\n
return error_list\n
]]></string> </value>
</item>
<item>
<key> <string>_params</string> </key>
<value> <string>erp5_uid=None, active_process=None</string> </value>
<value> <string>fixit=False, **kw</string> </value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>ERP5Site_notifyUpgradeIntegrity</string> </value>
<value> <string>TemplateTool_checkPostUpgradeWorkflowChainConsistency</string> </value>
</item>
</dictionary>
</pickle>
......
......@@ -50,19 +50,21 @@
</item>
<item>
<key> <string>_body</string> </key>
<value> <string>"""\n
Dummy script used by Upgrader Script\n
"""\n
return [ (upgrade_object.getRelativeUrl(), upgrade_object.getMetaType()) ]\n
<value> <string>bt5_list, keep_bt5_id_set = context.Base_getUpgradeBusinessTemplateList()\n
\n
template_tool = context.getPortalObject().portal_templates\n
return template_tool.upgradeSite(bt5_list,\n
keep_bt5_id_set=keep_bt5_id_set,\n
dry_run=(not fixit))\n
</string> </value>
</item>
<item>
<key> <string>_params</string> </key>
<value> <string>upgrade_object</string> </value>
<value> <string>fixit=False, **kw</string> </value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>ERP5Site_testUpgradeObjectClass</string> </value>
<value> <string>TemplateTool_checkUpgradeConsistency</string> </value>
</item>
</dictionary>
</pickle>
......
##############################################################################
#
# Copyright (c) 2002-2011 Nexedi SA and Contributors. All Rights Reserved.
# Rafael Monnerat <rafael@nexedi.com>
#
# 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 2
# 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#
##############################################################################
from Products.ERP5Type.tests.ERP5TypeLiveTestCase import ERP5TypeLiveTestCase
from Products.ERP5Type.tests.utils import createZODBPythonScript
class TestLiveUpgrader(ERP5TypeLiveTestCase):
"""
Configurator Mixin Class
"""
def afterSetUp(self):
self.login(user_name='test_configurator_user')
self.upgrade_object_test_id = "upgrade_object_test"
self.erp5_site_global_id = getattr(self.portal, 'erp5_site_global_id', None)
self.beforeTearDown()
self.portal.portal_activities.unsubscribe()
def beforeTearDown(self):
""" Restore original state """
self.portal.portal_activities.subscribe()
custom = self.portal.portal_skins.custom
for script_id in ['ERP5Site_getUpgraderSignature', 'ERP5Site_getUpgraderSignature']:
if script_id in custom.objectIds():
custom.manage_delObjects([script_id])
if self.upgrade_object_test_id in self.portal.portal_categories.objectIds():
self.portal.portal_categories.manage_delObjects([self.upgrade_object_test_id])
if self.upgrade_object_test_id in self.portal.portal_gadgets.objectIds():
self.portal.portal_gadgets.manage_delObjects([self.upgrade_object_test_id])
self.portal._updateProperty('erp5_site_global_id', self.erp5_site_global_id)
property_sheet_list = self.portal.portal_types.Person.getTypePropertySheetList()
new_property_sheet_list = [ i for i in property_sheet_list if i !="Account" ]
self.portal.portal_types.Person.setTypePropertySheetList(new_property_sheet_list)
self.assertFalse("Account" in self.portal.portal_types.Person.getTypePropertySheetList())
self.tic()
ERP5TypeLiveTestCase.beforeTearDown(self)
def test_UpgradeSignatureAPI(self):
"""
test If the script that defines the signature follow
the API defined here. This will prevent mistakes
or change API Definition.
"""
signature_key_list = ('alarm_dict',
'workflow_chain_dict',
'required_bt5_id_list',
'upgradable_bt5_id_list',
'update_catalog_bt5_id_list',
'before_triggered_bt5_id_dict',
'after_triggered_bt5_id_dict',
'reinstalable_bt5_id_list',
'keep_original_dict',
'object_action_dict',
'integrity_verification_script_id_list',
'catalog_filter_dict',
'update_role_portal_type_list',
'portal_type_property_sheet_list',
'erp5_site_property_dict',
'upgrade_object_class_list',
'recatalog',
'alarm_tool_configuration_list'
)
signature = self.portal.ERP5Site_getUpgraderSignature()
self.assertEqual(sorted(signature_key_list), sorted(signature.keys()))
def test_StandardUpgraderSignature(self):
""" Test default behaviours provided by default ERP5Site_getUpgraderSignature
"""
signature = self.portal.ERP5Site_getUpgraderSignature()
# By default we do not recatalog the instance
self.assertEqual(signature['recatalog'], False)
# By default we do not upgrade manually the workflow
self.assertEqual(signature['workflow_chain_dict'], None)
# By Default we do not upgrade Catalog Filters
self.assertEqual(signature['catalog_filter_dict'], None)
# By Default there is no extra properties to set.
self.assertEqual(signature['erp5_site_property_dict'], {})
# Do not enable alarms by default
self.assertEqual(signature['alarm_tool_configuration_list'], ())
# By default we upgrade software, products, bt5 and so on.
self.assertTrue(signature['alarm_dict']["bt5_upgrader"])
self.assertTrue(signature['alarm_dict']["finalize_upgrader"])
# By default there is nothing to fix on skin Selection.
# (rafael) Is it really necessary?
self.assertFalse(self.portal.ERP5Site_setupUpgraderSkinSelection())
def testUpgradeObjectWorkflowState(self):
"""
Create a test to ERP5Site_upgradeObjectList which aims to update
Objects which are in bad workflow state or have a bad property.
Signature API:
{ BUSINESS_TEMPLATE_TITLE : (
(OBJECT_PATH,
SCRIPT TO COLLECT INFORMATION,
RETURN EXPECTED THAT INDICATES THE OBJECT IS BROKEN,
SCRIPT USED TO FIX ),
),
}
"""
signature_code = {'erp5_core':( ('portal_categories/%s' % self.upgrade_object_test_id,
'getValidationState',
'embedded',
'publish'),)}
createZODBPythonScript(self.getPortal().portal_skins.custom,
'ERP5Site_getUpgraderSignature', "item=None",
"return " + str(signature_code))
self.commit()
self.assertEqual(self.portal.ERP5Site_getUpgraderSignature(), signature_code)
self.assertEqual(self.portal.ERP5Site_upgradeObjectList(), [])
test_object = self.portal.portal_categories.newContent(id=self.upgrade_object_test_id,
portal_type="Base Category")
self.assertEqual(test_object.getValidationState(), 'embedded')
self.assertNotEquals(self.portal.ERP5Site_upgradeObjectList(), [])
self.assertNotEquals(self.portal.ERP5Site_upgradeObjectList(upgrade="1"), [])
self.assertEqual(test_object.getValidationState(), 'published')
def testUpgradeObjectClass(self):
"""
Verify if all objects from one class are migrated to
another class.
"""
to_class_as_string = 'Products.ERP5Type.Document.Folder.Folder'
signature_code = ( ('portal_gadgets',
'ERP5Site_testUpgradeObjectClass',
to_class_as_string,
'Products.ERP5Type.Document.Gadget.Gadget',
'ERP5Site_testUpgradeObjectClass'), )
createZODBPythonScript(self.getPortal().portal_skins.custom,
'ERP5Site_getUpgraderSignature', "item=None",
"return " + str(signature_code))
self.commit()
self.assertEqual(self.portal.ERP5Site_getUpgraderSignature(), signature_code)
# Nothing to upgrade
self.assertEqual(self.portal.ERP5Site_upgradeObjectClass(), [])
# Create one broken object
gadget = self.portal.portal_gadgets.newContent(portal_type="Gadget",
id=self.upgrade_object_test_id)
self.tic()
createZODBPythonScript(self.getPortal().portal_skins.custom,
"test_upgradeObject", 'x', 'return [1]')
test_script = self.getPortal().portal_skins.custom.test_upgradeObject
self.portal.portal_gadgets.upgradeObjectClass(
test_script,
gadget.__class__,
to_class_as_string,
test_script)
self.commit()
self.assertNotEquals(self.portal.ERP5Site_upgradeObjectClass(), [])
self.assertEqual(self.portal.ERP5Site_upgradeObjectClass(upgrade=1),
[(gadget.getRelativeUrl(), 'ERP5 Gadget')])
self.tic()
self.assertEqual(self.portal.ERP5Site_upgradeObjectClass(), [])
def test_UpgradeGlobalPropertyList(self):
"""
Verify if the upgrade is needed
"""
if getattr(self.portal, 'erp5_site_global_id', None) is not None:
self.portal._updateProperty('erp5_site_global_id', "SOME_KEY")
signature_code = {'erp5_site_global_id': self.upgrade_object_test_id}
createZODBPythonScript(self.getPortal().portal_skins.custom,
'ERP5Site_getUpgraderSignature', "item=None",
"return " + str(signature_code))
self.commit()
self.assertEqual(self.portal.ERP5Site_getUpgraderSignature(), signature_code)
self.assertEqual(self.portal.ERP5Site_upgradeGlobalPropertyList(),
["Upgrade Required for Global Properties."])
self.assertEqual(["Upgrade Executed for Global Properties (erp5_site_global_id)."],
self.portal.ERP5Site_upgradeGlobalPropertyList(upgrade=1))
self.tic()
self.assertEqual(self.portal.ERP5Site_upgradeGlobalPropertyList(), [])
self.assertEqual(getattr(self.portal, 'erp5_site_global_id', None),
self.upgrade_object_test_id)
def test_UpgradeWorkflowChain(self):
"""
Upgrade the workflow chain if required.
"""
workflow_tool = self.portal.portal_workflow
workflow_dict = workflow_tool.getWorkflowChainDict()
signature_code = workflow_dict
createZODBPythonScript(self.getPortal().portal_skins.custom,
'ERP5Site_getUpgraderSignature', "item=None",
"return " + str(signature_code))
self.commit()
self.assertEqual(self.portal.ERP5Site_upgradeWorkflowChain(), [])
original_person_chain = workflow_dict["chain_Person"]
# Modify installed workflow chain.
workflow_dict["chain_Person"] = ''
workflow_tool.manage_changeWorkflows(default_chain = '',
props = workflow_dict)
self.assertEqual(workflow_tool.getWorkflowChainDict()["chain_Person"],
"")
self.assertEqual(self.portal.ERP5Site_upgradeWorkflowChain(),
["Upgrade Required for Workflow Chain."])
self.assertEqual(self.portal.ERP5Site_upgradeWorkflowChain(upgrade=1),
["Upgrade Executed for Workflow Chain."])
self.tic()
self.assertEqual(self.portal.ERP5Site_upgradeWorkflowChain(),[])
self.assertEqual(workflow_tool.getWorkflowChainDict()["chain_Person"],
original_person_chain)
def test_RunVerificationScriptDontRaise(self):
""" Test if the script ERP5Site_runVerificationScript is
bullet of proof, and always return a result.
"""
createZODBPythonScript(self.getPortal().portal_skins.custom,
'ERP5Site_raise', "",
"raise ValueError('Error')")
createZODBPythonScript(self.getPortal().portal_skins.custom,
'ERP5Site_return', "",
"return ['A']")
failure = self.portal.ERP5Site_runVerificationScript("ERP5Site_raise")
self.assertTrue("Script ERP5Site_raise fail to run" in failure,
"'Script ERP5Site_raise fail to run not' in %s" % failure)
self.assertEqual('ERP5Site_return : \n - A ',
self.portal.ERP5Site_runVerificationScript("ERP5Site_return"))
def test_UpgradePortalTypePropertySheet(self):
"""
Test for Upgrate Portal Type Property Sheet script.
"""
signature_code = (('Account', ["Person"]), )
createZODBPythonScript(self.getPortal().portal_skins.custom,
'ERP5Site_getUpgraderSignature', "item=None",
"return " + str(signature_code))
self.commit()
self.assertEqual(self.portal.ERP5Site_getUpgraderSignature(), signature_code)
self.assertEqual(self.portal.ERP5Site_upgradePortalTypePropertySheet(),
["Person doesn't has Account associated."])
self.assertEqual(self.portal.ERP5Site_upgradePortalTypePropertySheet(upgrade=1),
["Associate PropertySheet Account into Portal Type Person."])
self.tic()
self.assertEqual(self.portal.ERP5Site_upgradePortalTypePropertySheet(), [])
def test_recreateActivities(self):
"""
The activities should be recreated after upgrade products.
"""
object_to_test = self.portal.portal_simulation
createZODBPythonScript(self.getPortal().portal_skins.custom,
'ERP5Site_testRecreateActivityScript', "",
"context.manage_addProperty('custom_property_without_meaning', 'I was there', 'string')")
self.commit()
object_to_test.activate().ERP5Site_testRecreateActivityScript()
self.commit()
# Verify if the final activity is created.
self.assertTrue(object_to_test.hasActivity(method_id="ERP5Site_testRecreateActivityScript"))
self.portal.portal_activities.activate().ERP5Site_clearActivities()
self.commit()
self.assertTrue(object_to_test.hasActivity(method_id="ERP5Site_testRecreateActivityScript"))
self.assertTrue(self.portal.portal_activities.hasActivity(method_id='ERP5Site_clearActivities'))
self.tic()
self.assertFalse(object_to_test.hasActivity(method_id="ERP5Site_testRecreateActivityScript"))
self.assertFalse(self.portal.portal_activities.hasActivity(method_id='ERP5Site_clearActivities'))
self.assertEqual(object_to_test.getProperty('custom_property_without_meaning'),
'I was there')
##############################################################################
#
# Copyright (c) 2013 Nexedi SA and Contributors. All Rights Reserved.
# Gabriel M. Monnerat <gabriel@nexedi.com>
#
# 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
# 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#
##############################################################################
import re
import transaction
from Products.ERP5Type.tests.ERP5TypeTestCase import ERP5TypeTestCase
from Products.ERP5.Tool.TemplateTool import BusinessTemplateUnknownError
from Products.ERP5Type.tests.Sequence import SequenceList
DETAIL_PATTERN = re.compile(r"(?P<relative_url>.*)\ \<\>\ " + \
r"(?P<reference>\w+)\ \-\>\ (?P<new_reference>\w+)")
class TestUpgrader(ERP5TypeTestCase):
"""
Test one upgrader using constraints
"""
script_id = "Person_checkPreUpgradeReferenceConsistency_custom"
property_sheet_id = "TestPersonConstraint"
def getTitle(self):
return "Upgrader Tests"
def getBusinessTemplateList(self):
return ('erp5_upgrader',)
def stepCreatePerson(self, sequence):
module = self.portal.person_module
person = module.newContent(portal_type="Person", title="User",
reference="user%s" % module.getLastId())
sequence.edit(person=person)
def stepValidatePerson(self, sequence):
sequence.get("person").validate()
def afterSetUp(self):
self.portal.portal_types['Person Module'].setTypePropertySheetList(None)
self.stepRemoveConstraintFromPersonPortalType()
for person in self.portal.person_module.searchFolder(
validation_state='validated', title="User"):
if person.getValidationState() == "validated":
person.invalidate()
self.tic()
def stepClearCache(self, sequence=None):
self.portal.portal_caches.clearCache(
cache_factory_list=('erp5_content_medium',))
def stepCreatePropertySheetToValidateOrganisation(self, sequence=None):
portal = self.portal
skin_folder = portal.portal_skins.custom
script_id = "Organisation_changeWorkflowFromDraftToValidated"
custom_script = getattr(skin_folder, script_id, None)
if custom_script is None:
skin_folder.manage_addProduct['PythonScripts'].manage_addPythonScript(script_id)
custom_script = getattr(skin_folder, script_id)
script_body = "error_list = []\n" + \
"if context.getValidationState() == 'draft':\n" + \
" kw = {'relative_url': context.getRelativeUrl()}\n" + \
" error_list.append('%(relative_url)s should be validated' % kw)\n" + \
" if fixit:\n" + \
" context.validate()\nreturn error_list"
custom_script.ZPythonScript_edit('fixit=False, **kw', script_body)
property_sheet_id = "OrganisationDraftConstraint"
property_sheet = getattr(portal.portal_property_sheets, property_sheet_id, None)
if property_sheet is None:
property_sheet = portal.portal_property_sheets.newContent(
portal_type="Property Sheet", id=property_sheet_id)
script_constraint_id = "organsation_draft_constraint"
script_constraint = getattr(property_sheet, script_constraint_id, None)
if script_constraint is None:
script_constraint = property_sheet.newContent(portal_type="Script Constraint",
id=script_constraint_id)
script_constraint.edit(script_id=script_id, constraint_type="upgrader")
def stepCreateScriptCheckPreUpgradeReferenceConsistency(self, sequence=None):
portal = self.portal
skin_folder = portal.portal_skins.custom
custom_script = getattr(skin_folder, self.script_id, None)
if custom_script is None:
skin_folder.manage_addProduct['PythonScripts'].manage_addPythonScript(self.script_id)
custom_script = getattr(skin_folder, self.script_id)
script_body = "error_list = []\n" + \
"person = context\n" + \
"reference = person.getReference()\n" + \
"if reference and not person.getReference().startswith('old_'):\n" + \
" kw = {'relative_url': person.getRelativeUrl(), 'reference': person.getReference()}\n" + \
" error_list.append('%(relative_url)s <> %(reference)s -> old_%(reference)s' % kw)\n" + \
" if fixit:\n" + \
" person.setReference('old_%s' % person.getReference())\nreturn error_list"
custom_script.ZPythonScript_edit('fixit=False, **kw', script_body)
property_sheet = getattr(portal.portal_property_sheets, self.property_sheet_id, None)
if property_sheet is None:
property_sheet = portal.portal_property_sheets.newContent(
portal_type="Property Sheet", id=self.property_sheet_id)
script_constraint_id = "person_old_reference_constraint"
script_constraint = getattr(property_sheet, script_constraint_id, None)
if script_constraint is None:
script_constraint = property_sheet.newContent(portal_type="Script Constraint",
id=script_constraint_id)
script_constraint.edit(script_id=self.script_id, constraint_type="pre_upgrade")
def stepCreatePersonPropertySheet(self, sequence=None):
portal = self.portal
property_sheet = getattr(portal.portal_property_sheets, self.property_sheet_id, None)
if property_sheet is None:
property_sheet = portal.portal_property_sheets.newContent(
portal_type="Property Sheet", id=self.property_sheet_id)
script_constraint_id = "person_old_reference_constraint"
script_constraint = getattr(property_sheet, script_constraint_id, None)
if script_constraint is None:
script_constraint = property_sheet.newContent(portal_type="Script Constraint",
id=script_constraint_id)
script_constraint.edit(script_id=self.script_id, constraint_type="pre_upgrade")
def stepSetConstraintInOrganisationPortalType(self, sequence=None):
types_tool = self.portal.portal_types
portal_type = types_tool['Organisation']
property_sheet_id = 'OrganisationDraftConstraint'
if property_sheet_id not in portal_type.getTypePropertySheetList():
portal_type.setTypePropertySheetList(
portal_type.getTypePropertySheetList() + [property_sheet_id,])
def stepRemoveConstraintFromOrganisationPortalType(self, sequence=None):
types_tool = self.portal.portal_types
portal_type = types_tool['Organisation']
property_sheet_id = 'OrganisationDraftConstraint'
if property_sheet_id not in portal_type.getTypePropertySheetList():
portal_type.setTypePropertySheetList(
[i for i in portal_type.getTypePropertySheetList() \
if i not in [property_sheet_id,]])
def stepSetConstraintInPersonPortalType(self, sequence=None):
types_tool = self.portal.portal_types
portal_type = types_tool['Person']
if 'TestPersonConstraint' not in portal_type.getTypePropertySheetList():
portal_type.setTypePropertySheetList(
portal_type.getTypePropertySheetList() + [self.property_sheet_id,])
def _checkAlarmSense(self, alarm_id):
alarm = getattr(self.portal.portal_alarms, alarm_id)
alarm.activeSense()
self.tic()
active_process = alarm.getLastActiveProcess()
detail_list = [result.detail for result in active_process.getResultList()]
return alarm.sense(), detail_list
def _checkEmptyConstraintList(self, alarm_id):
alarm = getattr(self.portal.portal_alarms, alarm_id)
active_process = alarm.getLastActiveProcess()
if active_process is None:
self.fail("No active process found")
self.assertEqual(active_process.getResultList(), [])
def _checkPersonPreUpgradeConstraintList(self):
alarm = getattr(self.portal.portal_alarms, 'upgrader_check_pre_upgrade')
active_process = alarm.getLastActiveProcess()
result_list = active_process.getResultList()
detail = result_list[0].detail[0]
group_dict = DETAIL_PATTERN.match(detail).groupdict()
person = self.portal.restrictedTraverse(group_dict['relative_url'])
message_list = [m.message for m in person.checkConsistency()]
self.assertNotEqual(result_list, [])
self.assertEqual(len(result_list), 1)
return person, group_dict, detail, message_list
def stepCheckPersonPreUpgradeConstraintListAfterUpgrade(self, sequence=None):
person, group_dict, _, message_list = \
self._checkPersonPreUpgradeConstraintList()
self.assertEqual(message_list, [])
self.assertEqual(person.getReference(), group_dict['new_reference'])
def stepCheckPersonPreUpgradeConstraintList(self, sequence=None):
_, _, detail, message_list = self._checkPersonPreUpgradeConstraintList()
self.assertNotEqual(message_list, [])
self.assertEqual(message_list, [detail,])
def stepRemoveConstraintFromPersonPortalType(self, sequence=None):
if 'Person' in self.portal.portal_types.objectIds():
portal_type = self.portal.portal_types['Person']
portal_type.setTypePropertySheetList(
[x for x in portal_type.getTypePropertySheetList() if x != self.property_sheet_id])
def stepCheckPreUpgradeEmptyConstraintList(self, sequence=None):
self._checkEmptyConstraintList('upgrader_check_pre_upgrade')
def stepCheckPostUpgradeEmptyConstraintList(self, sequence=None):
self._checkEmptyConstraintList('upgrader_check_post_upgrade')
def stepCheckPosUpgradeWorkflowChainConsistency(self, sequence=None):
alarm = getattr(self.portal.portal_alarms, 'upgrader_check_post_upgrade')
active_process = alarm.getLastActiveProcess()
detail_list = active_process.getResultList()[0].detail
message = 'Preference - Expected: edit_workflow, preference_workflow <> Found: (Default)'
self.assertTrue(message in detail_list, detail_list)
self.assertTrue(detail_list.count(message), 1)
def stepSetConstraintInPersonModulePortalType(self, sequence=None):
types_tool = self.portal.portal_types
portal_type = types_tool['Person Module']
if 'PersonModulePostUpgraderConstraint' not in portal_type.getTypePropertySheetList():
portal_type.setTypePropertySheetList(
portal_type.getTypePropertySheetList() + ['PersonModulePostUpgraderConstraint',])
def stepSetConstraintInTemplateToolPortalType(self, sequence=None):
types_tool = self.portal.portal_types
portal_type = types_tool['Template Tool']
property_sheet_list = portal_type.getTypePropertySheetList()
if 'TemplateToolUpgraderConstraint' not in property_sheet_list:
portal_type.setTypePropertySheetList(
portal_type.getTypePropertySheetList() + ['TemplateToolUpgraderConstraint',])
if 'TemplateToolPostUpgradeConstraint' not in property_sheet_list:
portal_type.setTypePropertySheetList(
portal_type.getTypePropertySheetList() + ['TemplateToolPostUpgradeConstraint',])
def stepSetDefaultWorkflowChainToPreference(self, sequence=None):
workflow_chain_per_type_dict = {}
for portal_type, workflow_chain_list in self.portal.ERP5Site_dumpWorkflowChainByPortalType().iteritems():
workflow_chain_per_type_dict['chain_%s' % portal_type] = ",".join(workflow_chain_list)
workflow_chain_per_type_dict['chain_Preference'] = '(Default)'
self.portal.portal_workflow.manage_changeWorkflows(default_chain="",
props=workflow_chain_per_type_dict)
def _stepSolveAlarm(self, alarm_id):
getattr(self.portal.portal_alarms, alarm_id).solve()
def stepActiveSenseUpgradeAlarm(self, sequence=None):
getattr(self.portal.portal_alarms, "upgrader_check_upgrader").activeSense()
def stepActiveSensePostUpgradeAlarm(self, sequence=None):
getattr(self.portal.portal_alarms,
"upgrader_check_post_upgrade").activeSense()
def stepActiveSensePreUpgradeAlarm(self, sequence=None):
getattr(self.portal.portal_alarms,
"upgrader_check_pre_upgrade").activeSense()
def stepActiveSensePromiseCheckUpgrade(self, sequence=None):
getattr(self.portal.portal_alarms,
"promise_check_upgrade").activeSense()
def stepRunFullUpgrader(self, sequence=None):
self._stepSolveAlarm("promise_check_upgrade")
def stepRunUpgrader(self, sequence=None):
self._stepSolveAlarm("upgrader_check_upgrader")
def stepRunPostUpgrade(self, sequence=None):
self._stepSolveAlarm("upgrader_check_post_upgrade")
def stepRunPreUpgrade(self, sequence=None):
self._stepSolveAlarm("upgrader_check_pre_upgrade")
def stepCheckUpgradeRequired(self, sequence=None):
sense, detail_list = self._checkAlarmSense(
alarm_id="upgrader_check_upgrader")
self.assertTrue(sense, detail_list)
def stepCheckUpgradeNotRequired(self, sequence=None):
sense, detail_list = self._checkAlarmSense(
alarm_id="upgrader_check_upgrader")
self.assertFalse(sense, detail_list)
def stepCheckPostUpgradeRequired(self, sequence=None):
sense, detail_list = self._checkAlarmSense(
alarm_id="upgrader_check_post_upgrade")
self.assertTrue(sense, detail_list)
def stepCheckFullUpgradeRequired(self, sequence=None):
sense, detail_list = self._checkAlarmSense(
alarm_id="promise_check_upgrade")
self.assertTrue(sense, detail_list)
def stepCheckPostUpgradeNotRequired(self, sequence=None):
sense, detail_list = self._checkAlarmSense(
alarm_id="upgrader_check_post_upgrade")
self.assertFalse(sense, detail_list)
def stepUninstallERP5Web(self, sequence=None):
bt5 = self.portal.portal_templates.getInstalledBusinessTemplate('erp5_web')
if bt5 is not None:
bt5.uninstall()
def stepCheckERP5WebBTInstalled(self, sequence=None):
self.assertTrue('erp5_web' in \
self.portal.portal_templates.getInstalledBusinessTemplateTitleList())
def stepCheckNoActivitiesCreated(self, sequence=None):
transaction.commit()
portal_activities = self.getActivityTool()
message = portal_activities.getMessageList()[0]
self.assertEqual(message.method_id, "Alarm_runUpgrader")
portal_templates = self.getTemplateTool()
title_list = portal_templates.getInstalledBusinessTemplateTitleList()
self.assertTrue('erp5_web' not in title_list,
"%s found in %s" % ('erp5_web', title_list))
portal_activities.manageInvoke(message.object_path, message.method_id)
title_list = portal_templates.getInstalledBusinessTemplateTitleList()
self.assertTrue('erp5_web' in title_list,
"%s not found in %s" % ('erp5_web', title_list))
transaction.commit()
message_list = set([i.method_id for i in portal_activities.getMessageList()])
self.assertTrue('callMethodOnObjectList' not in message_list)
def stepCreateBigIncosistentData(self, sequence=None):
for _ in range(101):
self.portal.organisation_module.newContent(
portal_type="Organisation",
title="org_%s" % self.portal.organisation_module.getLastId())
def stepCreateSmallIncosistentData(self, sequence=None):
for _ in range(4):
self.portal.organisation_module.newContent(
portal_type="Organisation",
title="org_%s" % self.portal.organisation_module.getLastId())
def stepCheckActivitiesCreated(self, sequence=None):
transaction.commit()
portal_activities = self.getActivityTool()
message = portal_activities.getMessageList()[0]
self.assertEqual(message.method_id, "Alarm_runUpgrader")
portal_activities.manageInvoke(message.object_path, message.method_id)
transaction.commit()
message_list = portal_activities.getMessageList()
method_id_list = set([i.method_id for i in message_list])
self.assertTrue('callMethodOnObjectList' in method_id_list)
for message in message_list:
if message.method_id == 'callMethodOnObjectList':
self.assertEqual(message.args[-1], 'Base_postCheckConsistencyResult')
def stepUninstallERP5UpgraderTestBT(self, sequence=None):
bt5 = self.portal.portal_templates.getInstalledBusinessTemplate('erp5_web')
bt5.uninstall()
def stepInstallERP5UpgraderTestBT(self, sequence=None):
template_tool = self.portal.portal_templates
if 'erp5_upgrader_test' not in template_tool.getInstalledBusinessTemplateTitleList():
template_tool.installBusinessTemplateListFromRepository('erp5_upgrader_test')
def _getTemplateToolLastTimestampIndexation(self):
portal = self.portal
return portal.portal_catalog(select_list=['indexation_timestamp'],
uid=portal.portal_templates.getUid())[0].indexation_timestamp
def stepCheckSummaryForPreUpgradeRequired(self, sequence=None):
alarm = self.portal.portal_alarms.upgrader_check_upgrader
active_process = alarm.getLastActiveProcess()
detail = active_process.getResultList()[0].detail
self.assertTrue("Is required solve Pre Upgrade first" in detail)
def stepCheckPersonNotInConstraintTypeListPerPortalType(self, sequence=None):
constraint_type_per_type, _ = \
self.portal.Base_getConstraintTypeListPerPortalType()
self.assertFalse("Person" in constraint_type_per_type.keys(), \
"Person in %s" % constraint_type_per_type.keys())
def stepRemoveSameConstraintInPersonAndPersonModule(self, sequence=None):
types_tool = self.portal.portal_types
person_type = types_tool["Person"]
constraint_id = "PersonModulePostUpgraderConstraint"
propery_sheet_list = person_type.getTypePropertySheetList()
if constraint_id in propery_sheet_list:
propery_sheet_list.remove(constraint_id)
person_type.setTypePropertySheetList(propery_sheet_list)
person_module_type = types_tool["Person Module"]
propery_sheet_list = person_module_type.getTypePropertySheetList()
if constraint_id in propery_sheet_list:
propery_sheet_list.remove(constraint_id)
person_module_type.setTypePropertySheetList(propery_sheet_list)
def stepSameConstraintToPersonAndPersonModule(self, sequence=None):
types_tool = self.portal.portal_types
person_type = types_tool["Person"]
constraint_id = "PersonModulePostUpgraderConstraint"
propery_sheet_list = person_type.getTypePropertySheetList()
if constraint_id not in propery_sheet_list:
person_type.setTypePropertySheetList(
[constraint_id,] + propery_sheet_list)
person_module_type = types_tool["Person Module"]
propery_sheet_list = person_module_type.getTypePropertySheetList()
if constraint_id not in propery_sheet_list:
person_module_type.setTypePropertySheetList(
[constraint_id,] + propery_sheet_list)
self.assertTrue(constraint_id in person_type.getTypePropertySheetList())
self.assertTrue(
constraint_id in person_module_type.getTypePropertySheetList())
def stepCreateAndInstallBusinessTemplate(self, sequence=None):
bt5 = self.portal.portal_templates.newContent(
portal_type='Business Template',
title=self.id())
bt5.install()
sequence.edit(bt5=bt5)
def stepUninstallBusinessTemplateInstalled(self, sequence=None):
sequence.get("bt5").uninstall()
def stepCheckBusinessTemplateInstalled(self, sequence=None):
self.assertTrue(sequence.get('bt5').getTitle() in \
self.portal.portal_templates.getInstalledBusinessTemplateTitleList())
def stepCheckConsistencyInTemplateTool(self, sequence=None):
try:
self.portal.portal_templates.checkConsistency()
except BusinessTemplateUnknownError:
self.fail("checkConsistency should not raise exception."
"It means that one Business Template was not found in repositories")
def test_workflow_chain_constraint(self):
""" Check if Workflow chains is broken, it can be detected and fixed after
upgrade"""
sequence_list = SequenceList()
sequence_string = """
stepActiveSensePreUpgradeAlarm
stepTic
stepRunUpgrader
stepTic
stepCheckUpgradeNotRequired
stepTic
stepSetConstraintInTemplateToolPortalType
stepActiveSensePostUpgradeAlarm
stepTic
stepCheckPostUpgradeEmptyConstraintList
stepSetDefaultWorkflowChainToPreference
stepActiveSensePostUpgradeAlarm
stepTic
stepCheckPosUpgradeWorkflowChainConsistency
stepRunPostUpgrade
stepTic
stepActiveSensePostUpgradeAlarm
stepTic
stepCheckPostUpgradeEmptyConstraintList
"""
sequence_list.addSequenceString(sequence_string)
sequence_list.play(self)
def test_not_post_many_active_result_when_upgrade(self):
""" Check that is possible fix consistency before the upgrade"""
sequence_list = SequenceList()
sequence_string = """
stepCreatePerson
stepCreatePerson
stepTic
stepCreateScriptCheckPreUpgradeReferenceConsistency
stepCreatePersonPropertySheet
stepSetConstraintInPersonPortalType
stepActiveSensePreUpgradeAlarm
stepTic
stepCheckPersonPreUpgradeConstraintList
stepRunPreUpgrade
stepTic
stepCheckPersonPreUpgradeConstraintListAfterUpgrade
"""
sequence_list.addSequenceString(sequence_string)
sequence_list.play(self)
def test_add_pre_upgrade_constraint(self):
""" Check that is possible fix consistency before the upgrade"""
sequence_list = SequenceList()
sequence_string = """
stepCreatePerson
stepTic
stepCreateScriptCheckPreUpgradeReferenceConsistency
stepCreatePersonPropertySheet
stepSetConstraintInPersonPortalType
stepTic
stepActiveSensePreUpgradeAlarm
stepTic
stepCheckPersonPreUpgradeConstraintList
stepRemoveConstraintFromPersonPortalType
stepActiveSensePreUpgradeAlarm
stepTic
stepCheckPreUpgradeEmptyConstraintList
stepSetConstraintInPersonPortalType
stepRunPreUpgrade
stepTic
stepCheckPersonPreUpgradeConstraintListAfterUpgrade
stepActiveSensePreUpgradeAlarm
stepTic
stepCheckPreUpgradeEmptyConstraintList
"""
sequence_list.addSequenceString(sequence_string)
sequence_list.play(self)
def test_can_not_run_post_upgrade_without_solve_upgrade(self):
"""Check that if there is something to solve in pre_upgrade and upgrade is
not possible run the post upgrade"""
sequence_list = SequenceList()
sequence_string = """
stepUninstallERP5Web
stepSetConstraintInPersonModulePortalType
stepTic
stepCheckUpgradeRequired
stepCheckPostUpgradeNotRequired
stepCreatePerson
stepValidatePerson
stepTic
stepCheckPostUpgradeRequired
stepRunPostUpgrade
stepTic
stepCheckUpgradeRequired
stepCheckPostUpgradeRequired
"""
sequence_list.addSequenceString(sequence_string)
sequence_list.play(self)
def test_can_not_run_upgrade_without_solve_pre_upgrade(self):
"""Check that if there is something to solve in pre_upgrade is not possible
run the upgrade"""
sequence_list = SequenceList()
sequence_string = """
stepCreatePerson
stepCreateScriptCheckPreUpgradeReferenceConsistency
stepCreatePersonPropertySheet
stepSetConstraintInPersonPortalType
stepUninstallERP5Web
stepTic
stepActiveSensePreUpgradeAlarm
stepTic
stepRunUpgrader
stepTic
stepCheckSummaryForPreUpgradeRequired
"""
sequence_list.addSequenceString(sequence_string)
sequence_list.play(self)
def test_upgrade_in_one_transaction(self):
"""Check that all constraints with contraint_type equal upgrade run in the
same transaction"""
sequence_list = SequenceList()
sequence_string = """
stepCreatePropertySheetToValidateOrganisation
stepUninstallERP5Web
stepInstallERP5UpgraderTestBT
stepTic
stepActiveSensePromiseCheckUpgrade
stepTic
stepRunPreUpgrade
stepTic
stepSetConstraintInOrganisationPortalType
stepCreateSmallIncosistentData
stepTic
stepActiveSenseUpgradeAlarm
stepTic
stepRunUpgrader
stepCheckNoActivitiesCreated
stepCreateBigIncosistentData
stepTic
stepActiveSenseUpgradeAlarm
stepTic
stepRunUpgrader
stepCheckActivitiesCreated
stepRemoveConstraintFromOrganisationPortalType
"""
sequence_list.addSequenceString(sequence_string)
sequence_list.play(self)
def test_ignore_allowed_content_type(self):
"""
Check that allowed content types should be ignored from a give \
portal type in Base_getConstraintTypeListPerPortalType, \
because checkConsistency is recursive in folders.
Then, if not ignored this method will be called twice
"""
sequence_list = SequenceList()
sequence_string = """
stepSameConstraintToPersonAndPersonModule
stepCheckPersonNotInConstraintTypeListPerPortalType
stepRemoveSameConstraintInPersonAndPersonModule
"""
sequence_list.addSequenceString(sequence_string)
sequence_list.play(self)
def test_post_upgrade_with_bt5_that_not_exists_in_repository(self):
"""
One Business Template installed that not exists in repository,
should not block checkConsistency in portal_templates
"""
sequence_list = SequenceList()
sequence_string = """
stepCreateAndInstallBusinessTemplate
stepTic
stepCheckBusinessTemplateInstalled
stepCheckConsistencyInTemplateTool
stepUninstallBusinessTemplateInstalled
"""
sequence_list.addSequenceString(sequence_string)
sequence_list.play(self)
def test_upgrade_instance(self):
"""Check that running the alarm the instance is upgraded completely"""
sequence_list = SequenceList()
sequence_string = """
stepUninstallERP5Web
stepInstallERP5UpgraderTestBT
stepTic
stepActiveSensePreUpgradeAlarm
stepActiveSensePostUpgradeAlarm
stepActiveSenseUpgradeAlarm
stepTic
stepCheckFullUpgradeRequired
stepRunFullUpgrader
stepTic
stepCheckERP5WebBTInstalled
"""
sequence_list.addSequenceString(sequence_string)
sequence_list.play(self)
......@@ -6,13 +6,25 @@
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>_recorded_property_dict</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAI=</string> </persistent>
</value>
</item>
<item>
<key> <string>default_reference</string> </key>
<value> <string>testLiveUpgrader</string> </value>
<value> <string>testUpgrader</string> </value>
</item>
<item>
<key> <string>description</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>test.erp5.testLiveUpgrader</string> </value>
<value> <string>test.erp5.testUpgrader</string> </value>
</item>
<item>
<key> <string>portal_type</string> </key>
......@@ -24,6 +36,31 @@
<none/>
</value>
</item>
<item>
<key> <string>text_content_error_message</string> </key>
<value>
<tuple/>
</value>
</item>
<item>
<key> <string>text_content_warning_message</string> </key>
<value>
<tuple>
<string>R: 33, 0: Too many ancestors (9/7) (too-many-ancestors)</string>
<string>W: 59,64: Unused argument \'sequence\' (unused-argument)</string>
<string>W: 76,42: Unused argument \'sequence\' (unused-argument)</string>
<string>W: 89,48: Unused argument \'sequence\' (unused-argument)</string>
<string>W:104,53: Unused argument \'sequence\' (unused-argument)</string>
<string>W:109,51: Unused argument \'sequence\' (unused-argument)</string>
<string>W:112,52: Unused argument \'sequence\' (unused-argument)</string>
<string>W:115,56: Unused argument \'sequence\' (unused-argument)</string>
<string>W:122,54: Unused argument \'sequence\' (unused-argument)</string>
<string>W:140,54: Unused argument \'sequence\' (unused-argument)</string>
<string>W:147,54: Unused argument \'sequence\' (unused-argument)</string>
<string>R: 33, 0: Too many public methods (136/20) (too-many-public-methods)</string>
</tuple>
</value>
</item>
<item>
<key> <string>version</string> </key>
<value> <string>erp5</string> </value>
......@@ -31,13 +68,28 @@
<item>
<key> <string>workflow_history</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAI=</string> </persistent>
<persistent> <string encoding="base64">AAAAAAAAAAM=</string> </persistent>
</value>
</item>
</dictionary>
</pickle>
</record>
<record id="2" aka="AAAAAAAAAAI=">
<pickle>
<global name="PersistentMapping" module="Persistence.mapping"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>data</string> </key>
<value>
<dictionary/>
</value>
</item>
</dictionary>
</pickle>
</record>
<record id="3" aka="AAAAAAAAAAM=">
<pickle>
<global name="PersistentMapping" module="Persistence.mapping"/>
</pickle>
......@@ -50,7 +102,7 @@
<item>
<key> <string>component_validation_workflow</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAM=</string> </persistent>
<persistent> <string encoding="base64">AAAAAAAAAAQ=</string> </persistent>
</value>
</item>
</dictionary>
......@@ -59,7 +111,7 @@
</dictionary>
</pickle>
</record>
<record id="3" aka="AAAAAAAAAAM=">
<record id="4" aka="AAAAAAAAAAQ=">
<pickle>
<global name="WorkflowHistoryList" module="Products.ERP5Type.patches.WorkflowTool"/>
</pickle>
......@@ -74,7 +126,7 @@
</item>
<item>
<key> <string>actor</string> </key>
<value> <string>ERP5TypeTestCase</string> </value>
<value> <string>zope</string> </value>
</item>
<item>
<key> <string>comment</string> </key>
......@@ -92,8 +144,8 @@
</tuple>
<state>
<tuple>
<float>1377844666.57</float>
<string>GMT+9</string>
<float>1384357832.27</float>
<string>GMT+1</string>
</tuple>
</state>
</object>
......
2013-11-18 Gabriel Monnerat
* The alarms were renamed to cover each step of upgrader and give the possibility to call each step manually one-by-one.
* Also, all Scripts that the logic can be done by installing Business Template was removed.
2013-09-03 arnaud.fontaine
* ZODB Components: Workflow History must always be kept, so avoid an extra step for developers.
......
erp5_upgrader can be used to upgrade any site:
* create Business Template which overrides upgrader scripts in its own skin (XXX_erp5_upgrader)
* set extremely high business_template_skin_layer_priority (like 10000.0)
* develop this Business Template
* to upgrade site install first XXX_erp5_upgrader, then erp5_upgrader
* voilà - site upgraded
\ No newline at end of file
* Create Business Template and override TemplateTool_checkUpgradeConsistency script to set the Business Template list related to your project
* Set extremely high business_template_skin_layer_priority (like 10000.0)
* Develop constraints and set Constraint Type following upgrader steps
* To upgrade site install first XXX_erp5_upgrader, then erp5_upgrader
* Solve the alarm portal_alarms/upgrader_launch_full_upgrade
\ No newline at end of file
601
\ No newline at end of file
612
\ No newline at end of file
portal_alarms/bt5_upgrader
portal_alarms/finalize_upgrader
portal_alarms/upgrader_controller
\ No newline at end of file
portal_alarms/promise_check_upgrade
portal_alarms/upgrader_check_post_upgrade
portal_alarms/upgrader_check_pre_upgrade
portal_alarms/upgrader_check_upgrader
\ No newline at end of file
Template Tool | TemplateToolPostUpgradeConstraint
Template Tool | TemplateToolUpgraderConstraint
\ No newline at end of file
TemplateToolUpgraderConstraint
TemplateToolPostUpgradeConstraint
\ No newline at end of file
test.erp5.testLiveUpgrader
\ No newline at end of file
test.erp5.testUpgrader
\ No newline at end of file
erp5_full_text_myisam_catalog
erp5_base
erp5_upgrader_test
\ No newline at end of file
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