Commit 8d73cc9b authored by Rafael Monnerat's avatar Rafael Monnerat

slapos_pdm: Automate Upgrade and supply when Upgrade Decision are started

- Started Upgrade Decision trigger request or supply which include softwares on computers or change SR of the Hosting Subscriptions
- Alarm to process Started Upgrade Decisions
parent 1c117569
<?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_processStartedUpgradeDecision</string> </value>
</item>
<item>
<key> <string>description</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>enabled</string> </key>
<value> <int>1</int> </value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>slapos_upgrade_decision_process</string> </value>
</item>
<item>
<key> <string>periodicity_day_frequency</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>periodicity_hour</string> </key>
<value>
<tuple/>
</value>
</item>
<item>
<key> <string>periodicity_hour_frequency</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>periodicity_minute</string> </key>
<value>
<tuple/>
</value>
</item>
<item>
<key> <string>periodicity_minute_frequency</string> </key>
<value> <int>5</int> </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>3660.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>title</string> </key>
<value> <string>Process Started Upgrade Decisions</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>portal = context.getPortalObject()\n
portal.portal_catalog.searchAndActivate(\n
portal_type=\'Upgrade Decision\',\n
simulation_state=\'started\',\n
method_id=\'UpgradeDecision_processUpgrade\',\n
activate_kw={\'tag\': tag }\n
)\n
\n
context.activate(after_tag=tag).getId()\n
</string> </value>
</item>
<item>
<key> <string>_params</string> </key>
<value> <string>tag, fixit, params</string> </value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>Alarm_processStartedUpgradeDecision</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[
computer_list = []\n
for decision_line in context.contentValues():\n
computer_list.extend(\n
decision_line.getAggregateValueList(portal_type="Computer"))\n
\n
if len(computer_list) > 1: \n
raise ValueError("It is only allowed to have more them 1 Computer")\n
\n
if len(computer_list) == 0:\n
return None\n
\n
\n
return computer_list[0]\n
]]></string> </value>
</item>
<item>
<key> <string>_params</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>UpgradeDecision_getComputer</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>if context.UpgradeDecision_upgradeHostingSubscription():\n
return True\n
\n
if context.UpgradeDecision_upgradeComputer():\n
return True\n
\n
return False\n
</string> </value>
</item>
<item>
<key> <string>_params</string> </key>
<value> <string>**kw</string> </value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>UpgradeDecision_processUpgrade</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>if context.getSimulationState() != \'started\':\n
# Update Decision is not on started state, Upgrade is not possible!\n
return False\n
\n
computer = context.UpgradeDecision_getComputer()\n
software_release = context.UpgradeDecision_getSoftwareRelease()\n
\n
if computer is None:\n
return False\n
\n
if software_release is None:\n
return False \n
\n
software_release_url = software_release.getUrlString()\n
\n
computer.requestSoftwareRelease(\n
software_release_url=software_release_url,\n
state="available")\n
\n
context.stop()\n
\n
return True\n
</string> </value>
</item>
<item>
<key> <string>_params</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>UpgradeDecision_upgradeComputer</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
......@@ -52,10 +52,18 @@
<key> <string>_body</string> </key>
<value> <string>if context.getSimulationState() != \'started\':\n
# Update Decision is not on started state, Upgrade is not possible!\n
return\n
return False\n
\n
hosting_subscription = context.UpgradeDecision_getHostingSubscription()\n
software_release_url = context.UpgradeDecision_getSoftwareReleaseUrl()\n
software_release = context.UpgradeDecision_getSoftwareRelease()\n
\n
if hosting_subscription is None:\n
return False\n
\n
if software_release is None:\n
return False \n
\n
software_release_url = software_release.getUrlString()\n
\n
person = hosting_subscription.getDestinationSectionValue(portal_type="Person")\n
\n
......@@ -70,13 +78,17 @@ elif status == "destroy_requested":\n
\n
person.requestSoftwareInstance(\n
state=state,\n
software_release=new_sr_url,\n
software_release=software_release_url,\n
software_title=hosting_subscription.getTitle(),\n
software_type=hosting_subscription.getSourceReference(),\n
instance_xml=hosting_subscription.getTextContent(),\n
sla_xml=hosting_subscription.getSlaXml(),\n
shared=hosting_subscription.isRootSlave()\n
)\n
\n
context.stop()\n
\n
return True\n
</string> </value>
</item>
<item>
......
# Copyright (c) 2013 Nexedi SA and Contributors. All Rights Reserved.
import transaction
from Products.SlapOS.tests.testSlapOSMixin import \
testSlapOSMixin
from Products.ERP5Type.tests.utils import createZODBPythonScript
class TestSlapOSUpgradeDecisionProcess(testSlapOSMixin):
def afterSetUp(self):
super(TestSlapOSUpgradeDecisionProcess, self).afterSetUp()
self.new_id = self.generateNewId()
def generateNewId(self):
return "%sTEST" % self.portal.portal_ids.generateNewId(
id_group=('slapos_core_test'))
def _makeUpgradeDecision(self):
upgrade_decision = self.portal.\
upgrade_decision_module.newContent(
portal_type="Upgrade Decision",
title="TESTUPDE-%s" % self.new_id)
upgrade_decision.confirm()
return upgrade_decision
def _simulateUpgradeDecision_upgradeHostingSubscription(self, fake_return="True"):
self._simulateScript('UpgradeDecision_upgradeHostingSubscription', fake_return)
def _simulateUpgradeDecision_upgradeComputer(self, fake_return="True"):
self._simulateScript('UpgradeDecision_upgradeComputer', fake_return)
def _simulateScript(self, script_name, fake_return):
if script_name in self.portal.portal_skins.custom.objectIds():
raise ValueError('Precondition failed: %s exists in custom' % script_name)
createZODBPythonScript(self.portal.portal_skins.custom,
script_name,
'*args, **kwargs',
'# Script body\n'
"""portal_workflow = context.portal_workflow
portal_workflow.doActionFor(context, action='edit_action', comment='Visited by %s')
return %s
""" % (script_name, fake_return ))
transaction.commit()
def _dropUpgradeDecision_upgradeHostingSubscription(self):
self._dropScript('UpgradeDecision_upgradeHostingSubscription')
def _dropUpgradeDecision_upgradeComputer(self):
self._dropScript('UpgradeDecision_upgradeComputer')
def _dropScript(self, script_name):
if script_name in self.portal.portal_skins.custom.objectIds():
self.portal.portal_skins.custom.manage_delObjects(script_name)
transaction.commit()
def test_alarm_upgrade_decision_process_hosting_subscription(self):
upgrade_decision = self._makeUpgradeDecision()
upgrade_decision.start()
self.tic()
self._simulateUpgradeDecision_upgradeHostingSubscription()
try:
self.portal.portal_alarms.slapos_upgrade_decision_process.activeSense()
self.tic()
finally:
self._dropUpgradeDecision_upgradeHostingSubscription()
self.assertEqual(
'Visited by UpgradeDecision_upgradeHostingSubscription',
upgrade_decision.workflow_history['edit_workflow'][-1]['comment'])
def test_alarm_upgrade_decision_process_computer(self):
upgrade_decision = self._makeUpgradeDecision()
upgrade_decision.start()
self.tic()
self._simulateUpgradeDecision_upgradeHostingSubscription("False")
self._simulateUpgradeDecision_upgradeComputer()
try:
self.portal.portal_alarms.slapos_upgrade_decision_process.activeSense()
self.tic()
finally:
self._dropUpgradeDecision_upgradeHostingSubscription()
self._dropUpgradeDecision_upgradeComputer()
self.assertEqual(
'Visited by UpgradeDecision_upgradeComputer',
upgrade_decision.workflow_history['edit_workflow'][-1]['comment'])
This diff is collapsed.
13
\ No newline at end of file
14
\ No newline at end of file
portal_alarms/slapos_manage_software_catalog
portal_alarms/slapos_upgrade_decision_process
software_product_module/template_software_product
software_release_module/template_software_release
\ 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