Commit 83c572f5 authored by Jérome Perrin's avatar Jérome Perrin

upgrader: refactor dependencies between each steps

This should fix some race conditions which made post-upgrade steps not
executed sometimes.

* each steps use an defaultActivateParameterDict so that activity they
  may create inherits the same tag, so that next step also runs after
  this). This makes it possible for example to use post-upgrade step on
  documents newly installed in upgrade step.
* use tag / after tag between upgrader steps instead of checking if
  previous alarm had errors. We also now allow force running only one
  step regardless of the previous step completion state, there was no
  strong reason to prevernt this.
* do not use two different active sense and fix method for alarms, just
  use an active sense method understanding `fixit` parameter
parent bbd4e66e
......@@ -8,7 +8,7 @@
<dictionary>
<item>
<key> <string>active_sense_method_id</string> </key>
<value> <string>Alarm_senseFullUpgradeNeed</string> </value>
<value> <string>Alarm_runFullUpgrader</string> </value>
</item>
<item>
<key> <string>alarm_notification_mode</string> </key>
......@@ -18,6 +18,10 @@
</tuple>
</value>
</item>
<item>
<key> <string>automatic_solve</string> </key>
<value> <int>0</int> </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
......@@ -106,7 +110,9 @@ This step will run all constraints that have contraint_type equal post_upgrade.<
</item>
<item>
<key> <string>solve_method_id</string> </key>
<value> <string>Alarm_runFullUpgrader</string> </value>
<value>
<none/>
</value>
</item>
<item>
<key> <string>title</string> </key>
......
......@@ -8,7 +8,7 @@
<dictionary>
<item>
<key> <string>active_sense_method_id</string> </key>
<value> <string>Alarm_senseUpgradeNeed</string> </value>
<value> <string>Alarm_runPostUpgrade</string> </value>
</item>
<item>
<key> <string>alarm_notification_mode</string> </key>
......@@ -18,6 +18,10 @@
</tuple>
</value>
</item>
<item>
<key> <string>automatic_solve</string> </key>
<value> <int>0</int> </value>
</item>
<item>
<key> <string>description</string> </key>
<value> <string>This step will run all constraints that have contraint_type equal post_upgrade.</string> </value>
......@@ -97,7 +101,9 @@
</item>
<item>
<key> <string>solve_method_id</string> </key>
<value> <string>Alarm_runPostUpgrade</string> </value>
<value>
<none/>
</value>
</item>
<item>
<key> <string>title</string> </key>
......
......@@ -8,7 +8,7 @@
<dictionary>
<item>
<key> <string>active_sense_method_id</string> </key>
<value> <string>Alarm_senseUpgradeNeed</string> </value>
<value> <string>Alarm_runPreUpgrade</string> </value>
</item>
<item>
<key> <string>alarm_notification_mode</string> </key>
......@@ -18,6 +18,10 @@
</tuple>
</value>
</item>
<item>
<key> <string>automatic_solve</string> </key>
<value> <int>0</int> </value>
</item>
<item>
<key> <string>description</string> </key>
<value> <string>This step will run all constraints that have contraint_type equal pre_upgrade.</string> </value>
......@@ -97,7 +101,9 @@
</item>
<item>
<key> <string>solve_method_id</string> </key>
<value> <string>Alarm_runPreUpgrade</string> </value>
<value>
<none/>
</value>
</item>
<item>
<key> <string>title</string> </key>
......
......@@ -8,7 +8,7 @@
<dictionary>
<item>
<key> <string>active_sense_method_id</string> </key>
<value> <string>Alarm_senseUpgradeNeed</string> </value>
<value> <string>Alarm_runUpgrader</string> </value>
</item>
<item>
<key> <string>alarm_notification_mode</string> </key>
......@@ -18,6 +18,10 @@
</tuple>
</value>
</item>
<item>
<key> <string>automatic_solve</string> </key>
<value> <int>0</int> </value>
</item>
<item>
<key> <string>description</string> </key>
<value> <string>This step will run all constraints that have contraint_type equal upgrader.</string> </value>
......@@ -97,7 +101,9 @@
</item>
<item>
<key> <string>solve_method_id</string> </key>
<value> <string>Alarm_runUpgrader</string> </value>
<value>
<none/>
</value>
</item>
<item>
<key> <string>title</string> </key>
......
......@@ -50,45 +50,50 @@
</item>
<item>
<key> <string>_body</string> </key>
<value> <string>"""\n
Run upgrader\n
<value> <string>"""Run all upgrader steps:\n
\n
- pre-upgrade\n
- upgrade\n
- post-upgrade\n
\n
"""\n
portal = context.getPortalObject()\n
portal_alarms = portal.portal_alarms\n
\n
def launchUpgraderAlarm(alarm_id, after_tag=None):\n
""" Get the alarm and use sense and solve """\n
if after_tag is None:\n
after_tag = []\n
upgrader_alarm = getattr(portal_alarms, alarm_id, None)\n
if upgrader_alarm is not None and (force or upgrader_alarm.sense()):\n
# call solve method\n
tag = alarm_id\n
activate_kw = dict(tag=tag)\n
activate_kw["after_tag"] = after_tag\n
method_id = upgrader_alarm.getSolveMethodId()\n
if method_id not in (None, \'\'):\n
method = getattr(upgrader_alarm.activate(**activate_kw), method_id)\n
method(force=force, activate_kw=activate_kw)\n
return [tag] + after_tag\n
return after_tag\n
pre_upgrade_tag = \'%s-preupgrade\' % tag\n
upgrade_tag = \'%s-upgrade\' % tag\n
post_upgrade_tag = \'%s-postupgrade\' % tag\n
\n
portal_alarms.upgrader_check_pre_upgrade.activate(\n
activity=\'SQLQueue\',\n
tag=pre_upgrade_tag,\n
).activeSense(fixit=fixit, params={\'tag\': pre_upgrade_tag})\n
\n
portal_alarms.upgrader_check_upgrader.activate(\n
activity=\'SQLQueue\',\n
tag=upgrade_tag,\n
after_tag=pre_upgrade_tag,\n
).activeSense(fixit=fixit, params={\'tag\': upgrade_tag})\n
\n
previous_tag = launchUpgraderAlarm(\'upgrader_check_pre_upgrade\')\n
portal_alarms.upgrader_check_post_upgrade.activate(\n
activity=\'SQLQueue\',\n
tag=post_upgrade_tag,\n
after_tag=upgrade_tag,\n
).activeSense(fixit=fixit, params={\'tag\': post_upgrade_tag})\n
\n
previous_tag = launchUpgraderAlarm(\'upgrader_check_upgrader\',\n
after_tag=previous_tag)\n
\n
previous_tag = launchUpgraderAlarm(\'upgrader_check_post_upgrade\',\n
after_tag=previous_tag)\n
# start another activity to collect the results from each upgrader step\n
active_process = context.newActiveProcess()\n
context.activate(after_tag=post_upgrade_tag).Alarm_postFullUpgradeNeed(\n
active_process=active_process.getRelativeUrl())\n
\n
# Nothing else to do, so we can disable.\n
context.setEnabled(False)\n
return\n
</string> </value>
</item>
<item>
<key> <string>_params</string> </key>
<value> <string>force=0, **kw</string> </value>
<value> <string>tag, fixit=False</string> </value>
</item>
<item>
<key> <string>id</string> </key>
......
......@@ -53,29 +53,22 @@
<value> <string>"""\n
Run Post upgrade\n
"""\n
portal_alarms = context.getPortalObject().portal_alarms\n
active_process = context.newActiveProcess()\n
activate_kw = params or {}\n
\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 not(force) and alarm.sense() in (None, True):\n
active_process.postActiveResult(summary=context.getTitle(),\n
severity=1,\n
detail=["Is required run upgrade before solve it. You need run active sense once at least on this alarm"])\n
return\n
with context.defaultActivateParameterDict(activate_kw, placeless=True):\n
active_process = context.newActiveProcess()\n
\n
context.ERP5Site_checkUpgraderConsistency(fixit=True,\n
context.ERP5Site_checkUpgraderConsistency(fixit=fixit,\n
activate_kw=activate_kw,\n
active_process=active_process,\n
filter_dict={"constraint_type": "post_upgrade"})\n
\n
context.setEnabled(False)\n
return\n
</string> </value>
</item>
<item>
<key> <string>_params</string> </key>
<value> <string>force=0, activate_kw={}, **kw</string> </value>
<value> <string>tag, fixit, params</string> </value>
</item>
<item>
<key> <string>id</string> </key>
......
......@@ -53,18 +53,22 @@
<value> <string>"""\n
Run Pre upgrade\n
"""\n
context.ERP5Site_checkUpgraderConsistency(fixit=True,\n
activate_kw = params or {}\n
\n
with context.defaultActivateParameterDict(activate_kw, placeless=True):\n
active_process = context.newActiveProcess()\n
\n
context.ERP5Site_checkUpgraderConsistency(fixit=fixit,\n
activate_kw=activate_kw,\n
active_process=context.newActiveProcess(),\n
active_process=active_process,\n
filter_dict={"constraint_type": "pre_upgrade"})\n
\n
context.setEnabled(False)\n
return\n
</string> </value>
</item>
<item>
<key> <string>_params</string> </key>
<value> <string>force=0, activate_kw={}, **kw</string> </value>
<value> <string>tag, fixit, params</string> </value>
</item>
<item>
<key> <string>id</string> </key>
......
......@@ -53,7 +53,7 @@
<value> <string encoding="cdata"><![CDATA[
"""\n
Run Upgrader\n
Run Upgrade step\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
......@@ -63,15 +63,6 @@
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 not(force) and alarm.sense() in (None, True):\n
active_process.postActiveResult(summary=context.getTitle(),\n
severity=1,\n
detail=["Is required solve Pre Upgrade first. 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
......@@ -80,31 +71,37 @@ 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
activate_kw = params or {}\n
\n
with context.defaultActivateParameterDict(activate_kw, placeless=True):\n
active_process = context.newActiveProcess()\n
\n
method_kw = {\'fixit\': fixit,\n
\'filter\': {"constraint_type": \'upgrader\'},\n
\'active_process\': active_process.getRelativeUrl(),\n
\'activate_kw\': activate_kw,\n
}\n
\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
activate_kw=activate_kw,\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
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
activate_kw=activate_kw,\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
context.setEnabled(False)\n
return\n
]]></string> </value>
</item>
<item>
<key> <string>_params</string> </key>
<value> <string>force=0, activate_kw={}, **kw</string> </value>
<value> <string>tag, fixit, params</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 encoding="cdata"><![CDATA[
"""\n
Run upgrader\n
"""\n
portal = context.getPortalObject()\n
portal_alarms = portal.portal_alarms\n
\n
after_method_id = \'Base_postCheckConsistencyResult\'\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
previous_tag = launchSenseAlarm(\'upgrader_check_pre_upgrade\')\n
\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>REQUEST=None, **kw</string> </value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>Alarm_senseFullUpgradeNeed</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
Check if upgrader is required\n
"""\n
constraint_type = context.getId().replace("upgrader_check_", "")\n
context.ERP5Site_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>REQUEST=None, **kw</string> </value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>Alarm_senseUpgradeNeed</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
......@@ -56,8 +56,9 @@
if active_process.ActiveProcess_sense() and not fixit:\n
return\n
\n
constraint_message_list = context.checkConsistency(\n
fixit=fixit, filter=filter,)\n
with context.defaultActivateParameterDict(activate_kw, placeless=True):\n
constraint_message_list = context.checkConsistency(\n
fixit=fixit, filter=filter,)\n
\n
if constraint_message_list and not active_process.getResultList():\n
active_process.postActiveResult(\n
......@@ -68,7 +69,7 @@ if constraint_message_list and not active_process.getResultList():\n
</item>
<item>
<key> <string>_params</string> </key>
<value> <string>fixit, filter, active_process</string> </value>
<value> <string>fixit, filter, active_process, activate_kw</string> </value>
</item>
<item>
<key> <string>id</string> </key>
......
......@@ -70,6 +70,7 @@ if portal_type_list:\n
\'fixit\': fixit,\n
\'filter\': filter_dict,\n
\'active_process\': active_process.getRelativeUrl(),\n
\'activate_kw\': activate_kw,\n
},\n
)\n
</string> </value>
......
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