Commit e9384c58 authored by Romain Courteaud's avatar Romain Courteaud

slapos_pdm: support for the virtual master logic

A Software Product is a variated resource with 2 axes:
- Software Product Release Variation (optional variation),
  to not force updating Order/Delivery every time one Instance is upgraded
- Software Product Type Variation
It is linked to a Project (virtual master).

Redesign the Upgrade Decision logic.
It is now a Ticket, generated by the Allocation Supply configuration:
- upgrade is different for every Project
- upgrade can be triggered on a specific Node, or for a specific user

Upgrade Decision is created automatically only if there is a single possible release allocable
for a Software Product.
Otherwise, it must be created manually.

The Upgrade Decision must be approved by the Project manager,
who is responsible for the Allocation Supply configuration.

Also in this commit:
* drop template usage
* trigger alarm with interaction workflow
parent b3b6e300
......@@ -50,10 +50,6 @@
</tuple>
</value>
</item>
<item>
<key> <string>portal_type</string> </key>
<value> <string>Action Information</string> </value>
</item>
<item>
<key> <string>priority</string> </key>
<value> <float>1.0</float> </value>
......@@ -77,7 +73,7 @@
<dictionary>
<item>
<key> <string>text</string> </key>
<value> <string>string:${object_url}/UpgradeDecisionLine_view</string> </value>
<value> <string>string:${object_url}/SoftwareProductReleaseVariation_view</string> </value>
</item>
</dictionary>
</pickle>
......
......@@ -40,7 +40,7 @@
</item>
<item>
<key> <string>id</string> </key>
<value> <string>view_related_upgrade_decision</string> </value>
<value> <string>view</string> </value>
</item>
<item>
<key> <string>permissions</string> </key>
......@@ -52,11 +52,11 @@
</item>
<item>
<key> <string>priority</string> </key>
<value> <float>6.0</float> </value>
<value> <float>1.0</float> </value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string>Upgrade Decision</string> </value>
<value> <string>View</string> </value>
</item>
<item>
<key> <string>visible</string> </key>
......@@ -73,7 +73,7 @@
<dictionary>
<item>
<key> <string>text</string> </key>
<value> <string>string:${object_url}/ComputeNode_viewUpgradeDecision</string> </value>
<value> <string>string:${object_url}/SoftwareProductTypeVariation_view</string> </value>
</item>
</dictionary>
</pickle>
......
......@@ -2,34 +2,30 @@
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="Software Release" module="erp5.portal_type"/>
<global name="Base Category" module="erp5.portal_type"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>_Access_contents_information_Permission</string> </key>
<key> <string>_Add_portal_content_Permission</string> </key>
<value>
<tuple>
<string>Assignee</string>
<string>Assignor</string>
<string>Manager</string>
<string>Owner</string>
</tuple>
</value>
</item>
<item>
<key> <string>_Add_portal_content_Permission</string> </key>
<key> <string>_Add_portal_folders_Permission</string> </key>
<value>
<tuple>
<string>Assignee</string>
<string>Assignor</string>
<string>Manager</string>
<string>Owner</string>
</tuple>
</value>
</item>
<item>
<key> <string>_Change_local_roles_Permission</string> </key>
<key> <string>_Copy_or_Move_Permission</string> </key>
<value>
<tuple>
<string>Assignor</string>
......@@ -38,18 +34,16 @@
</value>
</item>
<item>
<key> <string>_Modify_portal_content_Permission</string> </key>
<key> <string>_Delete_objects_Permission</string> </key>
<value>
<tuple>
<string>Assignee</string>
<string>Assignor</string>
<string>Manager</string>
<string>Owner</string>
</tuple>
</value>
</item>
<item>
<key> <string>_View_Permission</string> </key>
<key> <string>_Modify_portal_content_Permission</string> </key>
<value>
<tuple>
<string>Assignee</string>
......@@ -59,6 +53,59 @@
</tuple>
</value>
</item>
<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>acquisition_append_value</string> </key>
<value> <int>0</int> </value>
</item>
<item>
<key> <string>acquisition_base_category</string> </key>
<value>
<tuple>
<string>order</string>
<string>parent</string>
</tuple>
</value>
</item>
<item>
<key> <string>acquisition_copy_value</string> </key>
<value> <int>0</int> </value>
</item>
<item>
<key> <string>acquisition_mask_value</string> </key>
<value> <int>1</int> </value>
</item>
<item>
<key> <string>acquisition_object_id</string> </key>
<value>
<tuple/>
</value>
</item>
<item>
<key> <string>acquisition_portal_type</string> </key>
<value> <string>python: []</string> </value>
</item>
<item>
<key> <string>acquisition_sync_value</string> </key>
<value> <int>0</int> </value>
</item>
<item>
<key> <string>categories</string> </key>
<value>
......@@ -66,8 +113,19 @@
</value>
</item>
<item>
<key> <string>default_reference</string> </key>
<value> <string>template_software_release</string> </value>
<key> <string>category_type</string> </key>
<value>
<tuple>
<string>variation</string>
<string>line</string>
</tuple>
</value>
</item>
<item>
<key> <string>criterion_property</string> </key>
<value>
<tuple/>
</value>
</item>
<item>
<key> <string>description</string> </key>
......@@ -75,43 +133,111 @@
<none/>
</value>
</item>
<item>
<key> <string>fallback_base_category</string> </key>
<value>
<tuple/>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>template_software_release</string> </value>
<value> <string>software_release</string> </value>
</item>
<item>
<key> <string>id_generator</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>id_group</string> </key>
<value> <string>None</string> </value>
</item>
<item>
<key> <string>membership_criterion_base_category</string> </key>
<value>
<tuple/>
</value>
</item>
<item>
<key> <string>membership_criterion_category</string> </key>
<value>
<tuple/>
</value>
</item>
<item>
<key> <string>language</string> </key>
<value> <string>FR</string> </value>
<key> <string>multimembership_criterion_base_category</string> </key>
<value>
<tuple/>
</value>
</item>
<item>
<key> <string>portal_type</string> </key>
<value> <string>Software Release</string> </value>
<value> <string>Base Category</string> </value>
</item>
<item>
<key> <string>short_title</string> </key>
<key> <string>read_permission</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string>Template Software Release</string> </value>
<key> <string>rid</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>url_protocol</string> </key>
<value> <string>http</string> </value>
<key> <string>short_title</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>url_string</string> </key>
<key> <string>sid</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>version</string> </key>
<value> <string>0.1</string> </value>
<key> <string>test_method_id</string> </key>
<value>
<tuple/>
</value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string>Software Release</string> </value>
</item>
<item>
<key> <string>write_permission</string> </key>
<value>
<none/>
</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>
......@@ -2,67 +2,52 @@
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="Upgrade Decision" module="erp5.portal_type"/>
<global name="Base Category" module="erp5.portal_type"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>_Access_contents_information_Permission</string> </key>
<key> <string>_Add_portal_content_Permission</string> </key>
<value>
<tuple>
<string>Assignee</string>
<string>Assignor</string>
<string>Associate</string>
<string>Auditor</string>
<string>Manager</string>
<string>Owner</string>
</tuple>
</value>
</item>
<item>
<key> <string>_Add_portal_content_Permission</string> </key>
<key> <string>_Add_portal_folders_Permission</string> </key>
<value>
<tuple>
<string>Assignee</string>
<string>Assignor</string>
<string>Associate</string>
<string>Manager</string>
<string>Owner</string>
</tuple>
</value>
</item>
<item>
<key> <string>_Delete_objects_Permission</string> </key>
<key> <string>_Copy_or_Move_Permission</string> </key>
<value>
<tuple>
<string>Assignee</string>
<string>Assignor</string>
<string>Associate</string>
<string>Manager</string>
<string>Owner</string>
</tuple>
</value>
</item>
<item>
<key> <string>_Modify_portal_content_Permission</string> </key>
<key> <string>_Delete_objects_Permission</string> </key>
<value>
<tuple>
<string>Assignee</string>
<string>Assignor</string>
<string>Associate</string>
<string>Manager</string>
<string>Owner</string>
</tuple>
</value>
</item>
<item>
<key> <string>_View_Permission</string> </key>
<key> <string>_Modify_portal_content_Permission</string> </key>
<value>
<tuple>
<string>Assignee</string>
<string>Assignor</string>
<string>Associate</string>
<string>Auditor</string>
<string>Manager</string>
<string>Owner</string>
</tuple>
......@@ -86,17 +71,61 @@
<persistent> <string encoding="base64">AAAAAAAAAAQ=</string> </persistent>
</value>
</item>
<item>
<key> <string>acquisition_append_value</string> </key>
<value> <int>0</int> </value>
</item>
<item>
<key> <string>acquisition_base_category</string> </key>
<value>
<tuple>
<string>order</string>
<string>parent</string>
</tuple>
</value>
</item>
<item>
<key> <string>acquisition_copy_value</string> </key>
<value> <int>0</int> </value>
</item>
<item>
<key> <string>acquisition_mask_value</string> </key>
<value> <int>1</int> </value>
</item>
<item>
<key> <string>acquisition_object_id</string> </key>
<value>
<tuple/>
</value>
</item>
<item>
<key> <string>acquisition_portal_type</string> </key>
<value> <string>python: []</string> </value>
</item>
<item>
<key> <string>acquisition_sync_value</string> </key>
<value> <int>0</int> </value>
</item>
<item>
<key> <string>categories</string> </key>
<value>
<tuple/>
</value>
</item>
<item>
<key> <string>category_type</string> </key>
<value>
<tuple>
<string>resource/service_module/slapos_crm_upgrade</string>
<string>variation</string>
<string>line</string>
</tuple>
</value>
</item>
<item>
<key> <string>default_reference</string> </key>
<value> <string>UD-TEMPLATE</string> </value>
<key> <string>criterion_property</string> </key>
<value>
<tuple/>
</value>
</item>
<item>
<key> <string>description</string> </key>
......@@ -104,23 +133,87 @@
<none/>
</value>
</item>
<item>
<key> <string>fallback_base_category</string> </key>
<value>
<tuple/>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>template_upgrade_decision</string> </value>
<value> <string>software_type</string> </value>
</item>
<item>
<key> <string>language</string> </key>
<key> <string>id_generator</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>id_group</string> </key>
<value> <string>None</string> </value>
</item>
<item>
<key> <string>membership_criterion_base_category</string> </key>
<value>
<tuple/>
</value>
</item>
<item>
<key> <string>membership_criterion_category</string> </key>
<value>
<tuple/>
</value>
</item>
<item>
<key> <string>multimembership_criterion_base_category</string> </key>
<value>
<tuple/>
</value>
</item>
<item>
<key> <string>portal_type</string> </key>
<value> <string>Upgrade Decision</string> </value>
<value> <string>Base Category</string> </value>
</item>
<item>
<key> <string>read_permission</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>rid</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>short_title</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>sid</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>test_method_id</string> </key>
<value>
<tuple/>
</value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string>UD-TEMPLATE</string> </value>
<value> <string>Software Type</string> </value>
</item>
<item>
<key> <string>write_permission</string> </key>
<value>
<none/>
</value>
</item>
</dictionary>
</pickle>
......
##############################################################################
#
# Copyright (c) 2022 Nexedi SARL and Contributors. All Rights Reserved.
# Jean-Paul Smets-Solanes <jp@nexedi.com>
#
# WARNING: This program as such is intended to be used by professional
# programmers who take the whole responsability 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
# garantees 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#
##############################################################################
from AccessControl import ClassSecurityInfo
from Products.ERP5Type import Permissions, PropertySheet
from erp5.component.document.Variation import Variation
class SoftwareProductReleaseVariation(Variation):
"""
A Variation
"""
meta_type = 'ERP5 Software Product Type Release'
portal_type = 'Software Product Type Release'
add_permission = Permissions.AddPortalContent
# Declarative security
security = ClassSecurityInfo()
security.declareObjectProtected(Permissions.AccessContentsInformation)
# Declarative properties
property_sheets = ( PropertySheet.Base
, PropertySheet.CategoryCore
, PropertySheet.DublinCore
, PropertySheet.Price
, PropertySheet.Variation
, PropertySheet.VariationRange
, PropertySheet.Reference
, PropertySheet.Url
)
variation_base_category_list=('software_release',)
......@@ -2,19 +2,13 @@
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="Test Component" module="erp5.portal_type"/>
<global name="Document Component" module="erp5.portal_type"/>
</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>testSlapOSCloudUpgradeSlapInterfaceWorkflow</string> </value>
<value> <string>SoftwareProductReleaseVariation</string> </value>
</item>
<item>
<key> <string>default_source_reference</string> </key>
......@@ -30,11 +24,11 @@
</item>
<item>
<key> <string>id</string> </key>
<value> <string>test.erp5.testSlapOSCloudUpgradeSlapInterfaceWorkflow</string> </value>
<value> <string>document.erp5.SoftwareProductReleaseVariation</string> </value>
</item>
<item>
<key> <string>portal_type</string> </key>
<value> <string>Test Component</string> </value>
<value> <string>Document Component</string> </value>
</item>
<item>
<key> <string>sid</string> </key>
......@@ -61,28 +55,13 @@
<item>
<key> <string>workflow_history</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAM=</string> </persistent>
<persistent> <string encoding="base64">AAAAAAAAAAI=</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>
......@@ -95,7 +74,7 @@
<item>
<key> <string>component_validation_workflow</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAQ=</string> </persistent>
<persistent> <string encoding="base64">AAAAAAAAAAM=</string> </persistent>
</value>
</item>
</dictionary>
......@@ -104,7 +83,7 @@
</dictionary>
</pickle>
</record>
<record id="4" aka="AAAAAAAAAAQ=">
<record id="3" aka="AAAAAAAAAAM=">
<pickle>
<global name="WorkflowHistoryList" module="Products.ERP5Type.Workflow"/>
</pickle>
......
##############################################################################
#
# Copyright (c) 2022 Nexedi SARL and Contributors. All Rights Reserved.
# Jean-Paul Smets-Solanes <jp@nexedi.com>
#
# WARNING: This program as such is intended to be used by professional
# programmers who take the whole responsability 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
# garantees 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#
##############################################################################
from AccessControl import ClassSecurityInfo
from Products.ERP5Type import Permissions, PropertySheet
from erp5.component.document.Variation import Variation
class SoftwareProductTypeVariation(Variation):
"""
A Variation
"""
meta_type = 'ERP5 Software Product Type Variation'
portal_type = 'Software Product Type Variation'
add_permission = Permissions.AddPortalContent
# Declarative security
security = ClassSecurityInfo()
security.declareObjectProtected(Permissions.AccessContentsInformation)
# Declarative properties
property_sheets = ( PropertySheet.Base
, PropertySheet.CategoryCore
, PropertySheet.DublinCore
, PropertySheet.Price
, PropertySheet.Variation
, PropertySheet.VariationRange
, PropertySheet.Reference
)
variation_base_category_list=('software_type',)
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="Document Component" module="erp5.portal_type"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>default_reference</string> </key>
<value> <string>SoftwareProductTypeVariation</string> </value>
</item>
<item>
<key> <string>default_source_reference</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>description</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>document.erp5.SoftwareProductTypeVariation</string> </value>
</item>
<item>
<key> <string>portal_type</string> </key>
<value> <string>Document Component</string> </value>
</item>
<item>
<key> <string>sid</string> </key>
<value>
<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/>
</value>
</item>
<item>
<key> <string>version</string> </key>
<value> <string>erp5</string> </value>
</item>
<item>
<key> <string>workflow_history</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAI=</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>
<item>
<key> <string>component_validation_workflow</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAM=</string> </persistent>
</value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</pickle>
</record>
<record id="3" aka="AAAAAAAAAAM=">
<pickle>
<global name="WorkflowHistoryList" module="Products.ERP5Type.Workflow"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>_log</string> </key>
<value>
<list>
<dictionary>
<item>
<key> <string>action</string> </key>
<value> <string>validate</string> </value>
</item>
<item>
<key> <string>validation_state</string> </key>
<value> <string>validated</string> </value>
</item>
</dictionary>
</list>
</value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
# -*- coding: utf-8 -*-
##############################################################################
#
# Copyright (c) 2010 Nexedi SA and Contributors. All Rights Reserved.
# Fabien Morin <fabien@nexedi.com>
#
# WARNING: This program as such is intended to be used by professional
# programmers who take the whole responsability 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
# garantees 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#
##############################################################################
from AccessControl import ClassSecurityInfo
from Products.ERP5Type import Permissions, PropertySheet
from erp5.component.document.erp5_version.SoftwareProduct import SoftwareProduct as ERP5SoftwareProduct
class SoftwareProduct(ERP5SoftwareProduct):
"""
"""
meta_type = 'ERP5 Software Product'
portal_type = 'Software Product'
add_permission = Permissions.AddPortalContent
# Declarative security
security = ClassSecurityInfo()
security.declareObjectProtected(Permissions.AccessContentsInformation)
# Declarative properties
property_sheets = ( PropertySheet.TextDocument,
PropertySheet.Document,
PropertySheet.Version,
PropertySheet.Url,
PropertySheet.Data,
PropertySheet.Task,
PropertySheet.SoftwareProduct,
)
# content_type property is also a method from PortalFolder, so we need a
# valid type by default.
content_type = ''
variation_base_category_list = ('software_type', )
optional_variation_base_category_list = ('software_release', )
default_category_list = (
'base_contribution/base_amount/invoicing/discounted',
'base_contribution/base_amount/invoicing/taxable',
'use/trade/sale',
'quantity_unit/time/month'
)
def __getattribute__(self, name):
if SoftwareProduct is None:
# XXX check lazy_class to understand why the class is None sometimes...
# raising this error prevents breaking the instance in such case
raise AttributeError('SoftwareProduct class is None.')
try:
result = super(SoftwareProduct, self).__getattribute__(name)
except AttributeError:
if name == 'categories':
result = []
else:
raise
if name == 'categories':
# Force getting default_category_list
# if not category from this base_category is set
base_category_dict = {}
for category in self.default_category_list:
base_category = category.split('/', 1)[0]
if base_category in base_category_dict:
base_category_dict[base_category].append(category)
else:
base_category_dict[base_category] = [category]
for category in result:
base_category_dict.pop(category.split('/', 1)[0], None)
if base_category_dict:
new_result = [x for x in result]
for v in base_category_dict.values():
new_result.extend(v)
return new_result
return result
def getVariationBaseCategoryList(self, *args, **kw):
# Sort the base category list, to prevent optional variation to be at the end
# which prevent so easily sort the variation_list when filling matrixbox
result_list = super(SoftwareProduct, self).getVariationBaseCategoryList(*args, **kw)
result_list.sort()
return result_list
\ No newline at end of file
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="Document Component" module="erp5.portal_type"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>default_reference</string> </key>
<value> <string>SoftwareProduct</string> </value>
</item>
<item>
<key> <string>default_source_reference</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>description</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>document.erp5_slapos.SoftwareProduct</string> </value>
</item>
<item>
<key> <string>portal_type</string> </key>
<value> <string>Document Component</string> </value>
</item>
<item>
<key> <string>sid</string> </key>
<value>
<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/>
</value>
</item>
<item>
<key> <string>version</string> </key>
<value> <string>erp5_slapos</string> </value>
</item>
<item>
<key> <string>workflow_history</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAI=</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>
<item>
<key> <string>component_validation_workflow</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAM=</string> </persistent>
</value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</pickle>
</record>
<record id="3" aka="AAAAAAAAAAM=">
<pickle>
<global name="WorkflowHistoryList" module="Products.ERP5Type.Workflow"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>_log</string> </key>
<value>
<list>
<dictionary>
<item>
<key> <string>action</string> </key>
<value> <string>validate</string> </value>
</item>
<item>
<key> <string>validation_state</string> </key>
<value> <string>validated</string> </value>
</item>
</dictionary>
</list>
</value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="Notification Message" module="erp5.portal_type"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>_Access_contents_information_Permission</string> </key>
<value>
<tuple>
<string>Assignee</string>
<string>Assignor</string>
<string>Associate</string>
<string>Manager</string>
<string>Owner</string>
</tuple>
</value>
</item>
<item>
<key> <string>_Add_portal_content_Permission</string> </key>
<value>
<tuple>
<string>Assignee</string>
<string>Assignor</string>
<string>Manager</string>
<string>Owner</string>
</tuple>
</value>
</item>
<item>
<key> <string>_Delete_objects_Permission</string> </key>
<value>
<tuple>
<string>Assignee</string>
<string>Assignor</string>
<string>Manager</string>
<string>Owner</string>
</tuple>
</value>
</item>
<item>
<key> <string>_Modify_portal_content_Permission</string> </key>
<value>
<tuple>
<string>Assignee</string>
<string>Assignor</string>
<string>Manager</string>
<string>Owner</string>
</tuple>
</value>
</item>
<item>
<key> <string>_View_Permission</string> </key>
<value>
<tuple>
<string>Assignee</string>
<string>Assignor</string>
<string>Associate</string>
<string>Manager</string>
<string>Owner</string>
</tuple>
</value>
</item>
<item>
<key> <string>categories</string> </key>
<value>
<tuple>
<string>group/company</string>
</tuple>
</value>
</item>
<item>
<key> <string>content_md5</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>content_type</string> </key>
<value> <string>text/html</string> </value>
</item>
<item>
<key> <string>default_reference</string> </key>
<value> <string>slapos-upgrade-compute-node.notification</string> </value>
</item>
<item>
<key> <string>description</string> </key>
<value> <string>This email is used to inform the user about an Upgrade</string> </value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>slapos_upgrade_compute_node_notification</string> </value>
</item>
<item>
<key> <string>language</string> </key>
<value> <string>en</string> </value>
</item>
<item>
<key> <string>portal_type</string> </key>
<value> <string>Notification Message</string> </value>
</item>
<item>
<key> <string>text_content</string> </key>
<value> <string encoding="cdata"><![CDATA[
Dear User,\n
<br>\n
<br> New version of the ${software_product_title} has been released.\n
<br>\n
<br> Install right now on Compute Node <b> ${compute_node_title} (${compute_node_reference}) </b> the newest version of ${software_product_title}:\n
<br>\n
<br> &nbsp;&nbsp;&nbsp; <b> ${software_release_name} ${software_release_reference} </b>\n
<br>\n
<br> Click <Accept> button to launch the Installation.\n
<br>\n
<br> If you don\'t want to use this new version, please cancel the upgrade request by clicking on <Reject> button.\n
<br>\n
<br>Thank you for use our services,\n
<br>Support Team\n
<br>\n
<br> Details:\n
<br>\n
<br> ${software_release_name} ${software_release_reference} Software Release URL :\n
<br>\n
<br> &nbsp;&nbsp;&nbsp; ${new_software_release_url}\n
<br>
]]></string> </value>
</item>
<item>
<key> <string>text_content_substitution_mapping_method_id</string> </key>
<value> <string>NotificationMessage_getSubstitutionMappingDictFromArgument</string> </value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string>Upgrade your Software Installation</string> </value>
</item>
<item>
<key> <string>version</string> </key>
<value> <string>001</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="Notification Message" module="erp5.portal_type"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>_Access_contents_information_Permission</string> </key>
<value>
<tuple>
<string>Assignee</string>
<string>Assignor</string>
<string>Associate</string>
<string>Manager</string>
<string>Owner</string>
</tuple>
</value>
</item>
<item>
<key> <string>_Add_portal_content_Permission</string> </key>
<value>
<tuple>
<string>Assignee</string>
<string>Assignor</string>
<string>Manager</string>
<string>Owner</string>
</tuple>
</value>
</item>
<item>
<key> <string>_Delete_objects_Permission</string> </key>
<value>
<tuple>
<string>Assignee</string>
<string>Assignor</string>
<string>Manager</string>
<string>Owner</string>
</tuple>
</value>
</item>
<item>
<key> <string>_Modify_portal_content_Permission</string> </key>
<value>
<tuple>
<string>Assignee</string>
<string>Assignor</string>
<string>Manager</string>
<string>Owner</string>
</tuple>
</value>
</item>
<item>
<key> <string>_View_Permission</string> </key>
<value>
<tuple>
<string>Assignee</string>
<string>Assignor</string>
<string>Associate</string>
<string>Manager</string>
<string>Owner</string>
</tuple>
</value>
</item>
<item>
<key> <string>categories</string> </key>
<value>
<tuple>
<string>group/company</string>
</tuple>
</value>
</item>
<item>
<key> <string>content_md5</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>content_type</string> </key>
<value> <string>text/html</string> </value>
</item>
<item>
<key> <string>default_reference</string> </key>
<value> <string>slapos-upgrade-delivered-compute-node.notification</string> </value>
</item>
<item>
<key> <string>description</string> </key>
<value> <string>This email is used to inform the user about an Upgrade</string> </value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>slapos_upgrade_delivered_compute_node_notification</string> </value>
</item>
<item>
<key> <string>language</string> </key>
<value> <string>en</string> </value>
</item>
<item>
<key> <string>portal_type</string> </key>
<value> <string>Notification Message</string> </value>
</item>
<item>
<key> <string>text_content</string> </key>
<value> <string encoding="cdata"><![CDATA[
Dear User,\n
<br>\n
<br> The new version of the ${software_product_title} has been installed on your Compute Node <b> ${compute_node_title} (${compute_node_reference}) </b>:\n
<br>\n
<br> &nbsp;&nbsp;&nbsp; <b> ${software_release_name} ${software_release_reference} </b>\n
<br>\n
<br>Thank you for use our Service,\n
<br>Support Team\n
<br>\n
<br> Details:\n
<br>\n
<br> ${software_release_name} ${software_release_reference} Software Release URL :\n
<br> \n
<br> &nbsp;&nbsp;&nbsp; ${new_software_release_url}\n
<br>\n
]]></string> </value>
</item>
<item>
<key> <string>text_content_substitution_mapping_method_id</string> </key>
<value> <string>NotificationMessage_getSubstitutionMappingDictFromArgument</string> </value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string>Upgrade your Software Installation Finished</string> </value>
</item>
<item>
<key> <string>version</string> </key>
<value> <string>001</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="Notification Message" module="erp5.portal_type"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>_Access_contents_information_Permission</string> </key>
<value>
<tuple>
<string>Assignee</string>
<string>Assignor</string>
<string>Associate</string>
<string>Manager</string>
<string>Owner</string>
</tuple>
</value>
</item>
<item>
<key> <string>_Add_portal_content_Permission</string> </key>
<value>
<tuple>
<string>Assignee</string>
<string>Assignor</string>
<string>Manager</string>
<string>Owner</string>
</tuple>
</value>
</item>
<item>
<key> <string>_Delete_objects_Permission</string> </key>
<value>
<tuple>
<string>Assignee</string>
<string>Assignor</string>
<string>Manager</string>
<string>Owner</string>
</tuple>
</value>
</item>
<item>
<key> <string>_Modify_portal_content_Permission</string> </key>
<value>
<tuple>
<string>Assignee</string>
<string>Assignor</string>
<string>Manager</string>
<string>Owner</string>
</tuple>
</value>
</item>
<item>
<key> <string>_View_Permission</string> </key>
<value>
<tuple>
<string>Assignee</string>
<string>Assignor</string>
<string>Associate</string>
<string>Manager</string>
<string>Owner</string>
</tuple>
</value>
</item>
<item>
<key> <string>categories</string> </key>
<value>
<tuple>
<string>group/company</string>
</tuple>
</value>
</item>
<item>
<key> <string>content_md5</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>content_type</string> </key>
<value> <string>text/html</string> </value>
</item>
<item>
<key> <string>default_reference</string> </key>
<value> <string>slapos-upgrade-delivered-instance-tree.notification</string> </value>
</item>
<item>
<key> <string>description</string> </key>
<value> <string>This email is used to inform the user about an Upgrade</string> </value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>slapos_upgrade_delivered_instance_tree_notification</string> </value>
</item>
<item>
<key> <string>language</string> </key>
<value> <string>en</string> </value>
</item>
<item>
<key> <string>portal_type</string> </key>
<value> <string>Notification Message</string> </value>
</item>
<item>
<key> <string>text_content</string> </key>
<value> <string encoding="cdata"><![CDATA[
Dear User,\n
<br>\n
<br> Your instance <strong> ${instance_tree_title} </strong> has been upgraded to the newest version of ${software_product_title} :\n
<br> \n
<br> &nbsp;&nbsp;&nbsp; <strong> ${software_release_name} ${software_release_reference} </strong>\n
<br> \n
<br>Thank you for use our Service,\n
<br>Support Team\n
<br>\n
<br> Details:\n
<br>\n
<br> Previous Software Release URL:\n
<br> \n
<br> &nbsp;&nbsp;&nbsp; ${old_software_release_url}\n
<br>\n
<br> Current Software Release URL:\n
<br> \n
<br> &nbsp;&nbsp;&nbsp; ${new_software_release_url}\n
<br>
]]></string> </value>
</item>
<item>
<key> <string>text_content_substitution_mapping_method_id</string> </key>
<value> <string>NotificationMessage_getSubstitutionMappingDictFromArgument</string> </value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string>Upgrade your Instance Tree Finished</string> </value>
</item>
<item>
<key> <string>version</string> </key>
<value> <string>001</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="Notification Message" module="erp5.portal_type"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>_Access_contents_information_Permission</string> </key>
<value>
<tuple>
<string>Assignee</string>
<string>Assignor</string>
<string>Associate</string>
<string>Manager</string>
<string>Owner</string>
</tuple>
</value>
</item>
<item>
<key> <string>_Add_portal_content_Permission</string> </key>
<value>
<tuple>
<string>Assignee</string>
<string>Assignor</string>
<string>Manager</string>
<string>Owner</string>
</tuple>
</value>
</item>
<item>
<key> <string>_Delete_objects_Permission</string> </key>
<value>
<tuple>
<string>Assignee</string>
<string>Assignor</string>
<string>Manager</string>
<string>Owner</string>
</tuple>
</value>
</item>
<item>
<key> <string>_Modify_portal_content_Permission</string> </key>
<value>
<tuple>
<string>Assignee</string>
<string>Assignor</string>
<string>Manager</string>
<string>Owner</string>
</tuple>
</value>
</item>
<item>
<key> <string>_View_Permission</string> </key>
<value>
<tuple>
<string>Assignee</string>
<string>Assignor</string>
<string>Associate</string>
<string>Manager</string>
<string>Owner</string>
</tuple>
</value>
</item>
<item>
<key> <string>categories</string> </key>
<value>
<tuple>
<string>group/company</string>
</tuple>
</value>
</item>
<item>
<key> <string>content_md5</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>content_type</string> </key>
<value> <string>text/html</string> </value>
</item>
<item>
<key> <string>default_reference</string> </key>
<value> <string>slapos-upgrade-instance-tree.notification</string> </value>
</item>
<item>
<key> <string>description</string> </key>
<value> <string>This email is used to inform the user about an Upgrade</string> </value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>slapos_upgrade_instance_tree_notification</string> </value>
</item>
<item>
<key> <string>language</string> </key>
<value> <string>en</string> </value>
</item>
<item>
<key> <string>portal_type</string> </key>
<value> <string>Notification Message</string> </value>
</item>
<item>
<key> <string>text_content</string> </key>
<value> <string encoding="cdata"><![CDATA[
Dear User,\n
<br>\n
<br> New version of the ${software_product_title} has been released.\n
<br>\n
<br> Launch the upgrade on your instance <strong> ${instance_tree_title} </strong> to the newest version <strong> ${software_release_name} ${software_release_reference} </strong> by clicking on <Accept> button.\n
<br>\n
<br> If you don\'t want to use this new version, please cancel the upgrade request by clicking on <Reject> button.\n
<br>\n
<br>Thank you for use our services,\n
<br>Support Team\n
<br>\n
<br> Details:\n
<br>\n
<br> Current Software Release URL:\n
<br>\n
<br> &nbsp;&nbsp;&nbsp; ${old_software_release_url}\n
<br>\n
<br> New Software Release URL:\n
<br>\n
<br> &nbsp;&nbsp;&nbsp; ${new_software_release_url}\n
<br>
]]></string> </value>
</item>
<item>
<key> <string>text_content_substitution_mapping_method_id</string> </key>
<value> <string>NotificationMessage_getSubstitutionMappingDictFromArgument</string> </value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string>Upgrade your Instance Tree</string> </value>
</item>
<item>
<key> <string>version</string> </key>
<value> <string>001</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
<?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_cancelUpgradeDecision</string> </value>
</item>
<item>
<key> <string>automatic_solve</string> </key>
<value> <int>0</int> </value>
</item>
<item>
<key> <string>description</string> </key>
<value> <string>Cancel Upgrade Decision which arent applicable anymore (Destroyed Instance Trees, Closed compute_nodes, already deployed softwares)</string> </value>
</item>
<item>
<key> <string>enabled</string> </key>
<value> <int>1</int> </value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>slapos_pdm_auto_cancel_upgrade_decision</string> </value>
</item>
<item>
<key> <string>periodicity_day_frequency</string> </key>
<value> <int>1</int> </value>
</item>
<item>
<key> <string>periodicity_hour</string> </key>
<value>
<tuple>
<int>5</int>
</tuple>
</value>
</item>
<item>
<key> <string>periodicity_hour_frequency</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>periodicity_minute</string> </key>
<value>
<tuple>
<int>0</int>
</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="_reconstructor" module="copy_reg"/>
</klass>
<tuple>
<global name="DateTime" module="DateTime.DateTime"/>
<global name="object" module="__builtin__"/>
<none/>
</tuple>
<state>
<tuple>
<float>1406073600.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>title</string> </key>
<value> <string>Auto Cancel Upgrade Decision when not applicable</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
<?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_ComputeNodeCheckUpgradeSoftwareRelease</string> </value>
</item>
<item>
<key> <string>description</string> </key>
<value> <string>Create Upgrade Decision for compute_nodes to upgrade Software Releases to a newer version.</string> </value>
</item>
<item>
<key> <string>enabled</string> </key>
<value> <int>1</int> </value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>slapos_pdm_compute_node_create_upgrade_decision</string> </value>
</item>
<item>
<key> <string>periodicity_day_frequency</string> </key>
<value> <int>1</int> </value>
</item>
<item>
<key> <string>periodicity_hour</string> </key>
<value>
<tuple>
<int>0</int>
</tuple>
</value>
</item>
<item>
<key> <string>periodicity_hour_frequency</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>periodicity_minute</string> </key>
<value>
<tuple>
<int>8</int>
</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="_reconstructor" module="copy_reg"/>
</klass>
<tuple>
<global name="DateTime" module="DateTime.DateTime"/>
<global name="object" module="__builtin__"/>
<none/>
</tuple>
<state>
<tuple>
<float>1406073600.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>title</string> </key>
<value> <string>Create Upgrade Decision for compute_nodes</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
......@@ -8,7 +8,7 @@
<dictionary>
<item>
<key> <string>active_sense_method_id</string> </key>
<value> <string>Alarm_destroySoftwareInstallationWithArchivedSoftwareRelease</string> </value>
<value> <string>Alarm_destroyUnusedSoftwareInstallation</string> </value>
</item>
<item>
<key> <string>automatic_solve</string> </key>
......@@ -26,7 +26,7 @@
</item>
<item>
<key> <string>id</string> </key>
<value> <string>slapos_pdm_destroy_software_installation_with_archived_software_release</string> </value>
<value> <string>slapos_pdm_destroy_unused_software_installation</string> </value>
</item>
<item>
<key> <string>periodicity_hour</string> </key>
......@@ -95,7 +95,7 @@
</item>
<item>
<key> <string>title</string> </key>
<value> <string>Destroy Software Installation related to archived Software Releases</string> </value>
<value> <string>Destroy Unused Software Installation</string> </value>
</item>
</dictionary>
</pickle>
......
<?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_processPlannedUpgradeDecision</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_pdm_upgrade_decision_process_planned</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="_reconstructor" module="copy_reg"/>
</klass>
<tuple>
<global name="DateTime" module="DateTime.DateTime"/>
<global name="object" module="__builtin__"/>
<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 Planned Upgrade Decisions</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
<?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_processStoppedUpgradeDecision</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_pdm_upgrade_decision_process_stopped</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="_reconstructor" module="copy_reg"/>
</klass>
<tuple>
<global name="DateTime" module="DateTime.DateTime"/>
<global name="object" module="__builtin__"/>
<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 Stopped Upgrade Decisions</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="Software Product" module="erp5.portal_type"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>_Access_contents_information_Permission</string> </key>
<value>
<tuple>
<string>Assignee</string>
<string>Assignor</string>
<string>Associate</string>
<string>Auditor</string>
<string>Author</string>
<string>Manager</string>
<string>Owner</string>
</tuple>
</value>
</item>
<item>
<key> <string>_Add_portal_content_Permission</string> </key>
<value>
<tuple>
<string>Assignee</string>
<string>Assignor</string>
<string>Associate</string>
<string>Author</string>
<string>Manager</string>
<string>Owner</string>
</tuple>
</value>
</item>
<item>
<key> <string>_Modify_portal_content_Permission</string> </key>
<value>
<tuple>
<string>Assignee</string>
<string>Assignor</string>
<string>Associate</string>
<string>Author</string>
<string>Manager</string>
<string>Owner</string>
</tuple>
</value>
</item>
<item>
<key> <string>_View_Permission</string> </key>
<value>
<tuple>
<string>Assignee</string>
<string>Assignor</string>
<string>Associate</string>
<string>Auditor</string>
<string>Author</string>
<string>Manager</string>
<string>Owner</string>
</tuple>
</value>
</item>
<item>
<key> <string>categories</string> </key>
<value>
<tuple>
<string>product_line/software/application</string>
</tuple>
</value>
</item>
<item>
<key> <string>content_type</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>description</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>template_software_product</string> </value>
</item>
<item>
<key> <string>portal_type</string> </key>
<value> <string>Software Product</string> </value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string>Template Software Release</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
......@@ -2,9 +2,8 @@
<portal_type id="Software Product">
<item>Embedded File</item>
<item>Software Product Individual Variation</item>
</portal_type>
<portal_type id="Upgrade Decision">
<item>Upgrade Decision Line</item>
<item>Software Product Release Variation</item>
<item>Software Product Type Variation</item>
</portal_type>
<portal_type id="Upgrade Decision Module">
<item>Upgrade Decision</item>
......
<hidden_content_type_list>
<portal_type id="Software Product">
<item>Software Product Individual Variation</item>
</portal_type>
</hidden_content_type_list>
\ No newline at end of file
......@@ -2,12 +2,20 @@
<portal_type id="Software Product">
<item>DefaultImage</item>
<item>SlapOSSoftwareProductConstraint</item>
<item>SlapOSVirtualMasterConstraint</item>
<item>SlaposCapacity</item>
</portal_type>
<portal_type id="Software Product Individual Variation">
<item>SlaposCapacity</item>
</portal_type>
<portal_type id="Software Release">
<item>SlapOSSoftwareReleaseConstraint</item>
<portal_type id="Software Product Release Variation">
<item>SlaposCapacity</item>
</portal_type>
<portal_type id="Software Product Type Variation">
<item>SlaposCapacity</item>
</portal_type>
<portal_type id="Upgrade Decision">
<item>SlapOSVirtualMasterSourceProjectConstraint</item>
<item>SlaposUpgradeDecisionConstraint</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="Base Type" module="erp5.portal_type"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>acquire_local_roles</string> </key>
<value> <int>1</int> </value>
</item>
<item>
<key> <string>content_icon</string> </key>
<value> <string>document.gif</string> </value>
</item>
<item>
<key> <string>content_meta_type</string> </key>
<value> <string>ERP5 Variation</string> </value>
</item>
<item>
<key> <string>description</string> </key>
<value> <string>Subdivision of a product that helps define variations of this product based on different axis such as colour or size for instance. Each variation can have its own price.</string> </value>
</item>
<item>
<key> <string>factory</string> </key>
<value> <string>addVariation</string> </value>
</item>
<item>
<key> <string>filter_content_types</string> </key>
<value> <int>1</int> </value>
</item>
<item>
<key> <string>group_list</string> </key>
<value>
<tuple>
<string>variation</string>
</tuple>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>Software Product Release Variation</string> </value>
</item>
<item>
<key> <string>init_script</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>permission</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>type_class</string> </key>
<value> <string>SoftwareProductReleaseVariation</string> </value>
</item>
<item>
<key> <string>type_interface</string> </key>
<value>
<tuple/>
</value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
......@@ -2,63 +2,71 @@
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="Workflow Transition" module="erp5.portal_type"/>
<global name="Base Type" module="erp5.portal_type"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>action</string> </key>
<value>
<none/>
</value>
<key> <string>acquire_local_roles</string> </key>
<value> <int>1</int> </value>
</item>
<item>
<key> <string>action_name</string> </key>
<value>
<none/>
</value>
<key> <string>content_icon</string> </key>
<value> <string>document.gif</string> </value>
</item>
<item>
<key> <string>content_meta_type</string> </key>
<value> <string>ERP5 Variation</string> </value>
</item>
<item>
<key> <string>description</string> </key>
<value> <string>Subdivision of a product that helps define variations of this product based on different axis such as colour or size for instance. Each variation can have its own price.</string> </value>
</item>
<item>
<key> <string>categories</string> </key>
<key> <string>factory</string> </key>
<value> <string>addVariation</string> </value>
</item>
<item>
<key> <string>filter_content_types</string> </key>
<value> <int>1</int> </value>
</item>
<item>
<key> <string>group_list</string> </key>
<value>
<tuple>
<string>action_type/workflow</string>
<string>before_script/portal_workflow/upgrade_slap_interface_workflow/script_UpgradeDecision_checkConsistency</string>
<string>after_script/portal_workflow/upgrade_slap_interface_workflow/script_UpgradeDecision_notify</string>
<string>variation</string>
</tuple>
</value>
</item>
<item>
<key> <string>description</string> </key>
<value> <string>Create an event for the Upgrade Decision</string> </value>
<key> <string>id</string> </key>
<value> <string>Software Product Type Variation</string> </value>
</item>
<item>
<key> <string>guard_permission</string> </key>
<key> <string>init_script</string> </key>
<value>
<tuple/>
<none/>
</value>
</item>
<item>
<key> <string>icon</string> </key>
<key> <string>permission</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>transition_notify</string> </value>
</item>
<item>
<key> <string>portal_type</string> </key>
<value> <string>Workflow Transition</string> </value>
<key> <string>title</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string>Notify</string> </value>
<key> <string>type_class</string> </key>
<value> <string>SoftwareProductTypeVariation</string> </value>
</item>
<item>
<key> <string>trigger_type</string> </key>
<value> <int>2</int> </value>
<key> <string>type_interface</string> </key>
<value>
<tuple/>
</value>
</item>
</dictionary>
</pickle>
......
......@@ -48,7 +48,7 @@
</item>
<item>
<key> <string>type_class</string> </key>
<value> <string>Delivery</string> </value>
<value> <string>Ticket</string> </value>
</item>
<item>
<key> <string>type_interface</string> </key>
......
<workflow_chain>
<chain>
<type>Allocation Supply</type>
<workflow>slapos_pdm_interaction_workflow</workflow>
</chain>
<chain>
<type>Software Product</type>
<workflow>-validation_workflow, commerce_validation_workflow</workflow>
</chain>
<chain>
<type>Software Product Release Variation</type>
<workflow>edit_workflow</workflow>
</chain>
<chain>
<type>Software Product Type Variation</type>
<workflow>edit_workflow</workflow>
</chain>
<chain>
<type>Upgrade Decision</type>
<workflow>edit_workflow, ticket_interaction_workflow, upgrade_decision_workflow, upgrade_slap_interface_workflow</workflow>
<workflow>edit_workflow, slapos_pdm_interaction_workflow, ticket_interaction_workflow, upgrade_decision_workflow</workflow>
</chain>
</workflow_chain>
\ No newline at end of file
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="TALES 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>description</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>expression</string> </key>
<value> <string>python: context.getQuantityUnit() == \'time/month\'</string> </value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>forced_quantity_unit_constraint</string> </value>
</item>
<item>
<key> <string>portal_type</string> </key>
<value> <string>TALES Constraint</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="Content Existence 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>constraint_portal_type</string> </key>
<value> <string>python: (\'Software Product Release Variation\', )</string> </value>
</item>
<item>
<key> <string>description</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>software_release_existence_constraint</string> </value>
</item>
<item>
<key> <string>message_no_subobject</string> </key>
<value> <string>The document does not contain any Software Release</string> </value>
</item>
<item>
<key> <string>portal_type</string> </key>
<value> <string>Content Existence Constraint</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="Content Existence 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>constraint_portal_type</string> </key>
<value> <string>python: (\'Software Product Type Variation\', )</string> </value>
</item>
<item>
<key> <string>description</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>software_type_existence_constraint</string> </value>
</item>
<item>
<key> <string>message_no_subobject</string> </key>
<value> <string>The document does not contain any Software Type</string> </value>
</item>
<item>
<key> <string>portal_type</string> </key>
<value> <string>Content Existence Constraint</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>SlaposUpgradeDecisionConstraint</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>
......@@ -2,34 +2,34 @@
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="Workflow State" module="erp5.portal_type"/>
<global name="Category Existence Constraint" module="erp5.portal_type"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>acquire_permission</string> </key>
<key> <string>_identity_criterion</string> </key>
<value>
<tuple/>
<persistent> <string encoding="base64">AAAAAAAAAAI=</string> </persistent>
</value>
</item>
<item>
<key> <string>categories</string> </key>
<key> <string>_range_criterion</string> </key>
<value>
<tuple>
<string>destination/portal_workflow/upgrade_slap_interface_workflow/transition_approve_registration</string>
<string>destination/portal_workflow/upgrade_slap_interface_workflow/transition_notify</string>
<string>destination/portal_workflow/upgrade_slap_interface_workflow/transition_request_upgrade</string>
<string>destination/portal_workflow/upgrade_slap_interface_workflow/transition_review_registration</string>
<string>destination/portal_workflow/upgrade_slap_interface_workflow/transition_review_upgrade</string>
</tuple>
<persistent> <string encoding="base64">AAAAAAAAAAM=</string> </persistent>
</value>
</item>
<item>
<key> <string>comment</string> </key>
<key> <string>constraint_base_category</string> </key>
<value>
<none/>
<tuple>
<string>destination_decision</string>
</tuple>
</value>
</item>
<item>
<key> <string>constraint_portal_type</string> </key>
<value> <string>python: (\'Person\',)</string> </value>
</item>
<item>
<key> <string>description</string> </key>
<value>
......@@ -38,32 +38,35 @@
</item>
<item>
<key> <string>id</string> </key>
<value> <string>state_draft</string> </value>
<value> <string>destination_decision_constraint</string> </value>
</item>
<item>
<key> <string>portal_type</string> </key>
<value> <string>Workflow State</string> </value>
<value> <string>Category Existence Constraint</string> </value>
</item>
<item>
<key> <string>state_permission_role_list_dict</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAI=</string> </persistent>
</value>
<key> <string>use_acquisition</string> </key>
<value> <int>0</int> </value>
</item>
</dictionary>
</pickle>
</record>
<record id="2" aka="AAAAAAAAAAI=">
<pickle>
<global name="PersistentMapping" module="Persistence.mapping"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>state_type</string> </key>
<key> <string>data</string> </key>
<value>
<tuple/>
<dictionary/>
</value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string>Draft</string> </value>
</item>
</dictionary>
</pickle>
</record>
<record id="2" aka="AAAAAAAAAAI=">
<record id="3" aka="AAAAAAAAAAM=">
<pickle>
<global name="PersistentMapping" module="Persistence.mapping"/>
</pickle>
......
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="Category Existence 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>constraint_base_category</string> </key>
<value>
<tuple>
<string>destination_project</string>
</tuple>
</value>
</item>
<item>
<key> <string>constraint_portal_type</string> </key>
<value> <string>python: (\'Project\',)</string> </value>
</item>
<item>
<key> <string>description</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>destination_project_constraint</string> </value>
</item>
<item>
<key> <string>portal_type</string> </key>
<value> <string>Category Existence Constraint</string> </value>
</item>
<item>
<key> <string>use_acquisition</string> </key>
<value> <int>0</int> </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="Category Existence 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>constraint_base_category</string> </key>
<value>
<tuple>
<string>destination_section</string>
</tuple>
</value>
</item>
<item>
<key> <string>constraint_portal_type</string> </key>
<value> <string>python: (\'Person\',)</string> </value>
</item>
<item>
<key> <string>description</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>destination_section_constraint</string> </value>
</item>
<item>
<key> <string>portal_type</string> </key>
<value> <string>Category Existence Constraint</string> </value>
</item>
<item>
<key> <string>use_acquisition</string> </key>
<value> <int>0</int> </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>
......@@ -2,7 +2,7 @@
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="Attribute Unicity Constraint" module="erp5.portal_type"/>
<global name="Category Existence Constraint" module="erp5.portal_type"/>
</pickle>
<pickle>
<dictionary>
......@@ -19,60 +19,34 @@
</value>
</item>
<item>
<key> <string>constraint_property</string> </key>
<key> <string>constraint_base_category</string> </key>
<value>
<tuple>
<string>title</string>
<string>aggregate</string>
</tuple>
</value>
</item>
<item>
<key> <string>description</string> </key>
<value> <string>Title already exists</string> </value>
</item>
<item>
<key> <string>filter_parameter</string> </key>
<value> <string>python: {\'portal_type\': object.getPortalType(), \'title\': object.getTitle()}</string> </value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>title_unicity_constraint</string> </value>
<key> <string>constraint_portal_type</string> </key>
<value> <string>python: (\'Instance Tree\',)</string> </value>
</item>
<item>
<key> <string>int_index</string> </key>
<key> <string>description</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>membership_criterion_category</string> </key>
<value>
<tuple/>
</value>
</item>
<item>
<key> <string>message_invalid_attribute_unicity</string> </key>
<value> <string>Title already exists</string> </value>
<key> <string>id</string> </key>
<value> <string>instance_tree_constraint</string> </value>
</item>
<item>
<key> <string>portal_type</string> </key>
<value> <string>Attribute Unicity Constraint</string> </value>
</item>
<item>
<key> <string>string_index</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>test_method_id</string> </key>
<value>
<tuple/>
</value>
<value> <string>Category Existence Constraint</string> </value>
</item>
<item>
<key> <string>test_tales_expression</string> </key>
<value> <string>python: object.getTitle("") != ""</string> </value>
<key> <string>use_acquisition</string> </key>
<value> <int>0</int> </value>
</item>
</dictionary>
</pickle>
......
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="Category Existence 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>constraint_base_category</string> </key>
<value>
<tuple>
<string>resource</string>
</tuple>
</value>
</item>
<item>
<key> <string>constraint_portal_type</string> </key>
<value> <string>python: (\'Software Product\',)</string> </value>
</item>
<item>
<key> <string>description</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>software_product_constraint</string> </value>
</item>
<item>
<key> <string>portal_type</string> </key>
<value> <string>Category Existence Constraint</string> </value>
</item>
<item>
<key> <string>use_acquisition</string> </key>
<value> <int>0</int> </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="Category Existence 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>constraint_base_category</string> </key>
<value>
<tuple>
<string>software_release</string>
</tuple>
</value>
</item>
<item>
<key> <string>constraint_portal_type</string> </key>
<value> <string>python: (\'Software Product Release Variation\',)</string> </value>
</item>
<item>
<key> <string>description</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>software_release_constraint</string> </value>
</item>
<item>
<key> <string>portal_type</string> </key>
<value> <string>Category Existence Constraint</string> </value>
</item>
<item>
<key> <string>use_acquisition</string> </key>
<value> <int>0</int> </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="Category Existence 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>constraint_base_category</string> </key>
<value>
<tuple>
<string>software_type</string>
</tuple>
</value>
</item>
<item>
<key> <string>constraint_portal_type</string> </key>
<value> <string>python: (\'Software Product Type Variation\',)</string> </value>
</item>
<item>
<key> <string>description</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>software_type_constraint</string> </value>
</item>
<item>
<key> <string>portal_type</string> </key>
<value> <string>Category Existence Constraint</string> </value>
</item>
<item>
<key> <string>use_acquisition</string> </key>
<value> <int>0</int> </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>
portal = context.getPortalObject()
default_upgrade_scope_uid = [
portal.portal_categories.upgrade_scope.auto.getUid(),
portal.portal_categories.upgrade_scope.confirmation.getUid()
]
if default_upgrade_scope_uid:
portal.portal_catalog.searchAndActivate(
portal_type='Compute Node',
validation_state = 'validated',
default_upgrade_scope_uid=default_upgrade_scope_uid,
method_id = 'ComputeNode_checkAndCreateUpgradeDecision',
activate_kw = {'tag':tag}
)
context.activate(after_tag=tag).getId()
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="PythonScript" module="Products.PythonScripts.PythonScript"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>_bind_names</string> </key>
<value>
<object>
<klass>
<global name="_reconstructor" module="copy_reg"/>
</klass>
<tuple>
<global name="NameAssignments" module="Shared.DC.Scripts.Bindings"/>
<global name="object" module="__builtin__"/>
<none/>
</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>_params</string> </key>
<value> <string>tag, fixit, params</string> </value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>Alarm_ComputeNodeCheckUpgradeSoftwareRelease</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
portal = context.getPortalObject()
portal.portal_catalog.searchAndActivate(
portal_type="Upgrade Decision Line",
simulation_state=["confirmed", "draft", "planned"],
method_id = 'UpgradeDecisionLine_cancel',
activate_kw = {'tag':tag}
)
context.activate(after_tag=tag).getId()
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="PythonScript" module="Products.PythonScripts.PythonScript"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>_bind_names</string> </key>
<value>
<object>
<klass>
<global name="_reconstructor" module="copy_reg"/>
</klass>
<tuple>
<global name="NameAssignments" module="Shared.DC.Scripts.Bindings"/>
<global name="object" module="__builtin__"/>
<none/>
</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>_params</string> </key>
<value> <string>tag, fixit, params</string> </value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>Alarm_cancelUpgradeDecision</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
portal = context.getPortalObject()
portal.portal_catalog.searchAndActivate(
portal_type='Software Release',
validation_state = 'archived',
method_id = 'SoftwareRelease_findAndDestroySoftwareInstallation',
method_kw = {'tag': tag},
activate_kw = {'tag':tag}
)
context.activate(after_tag=tag).getId()
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="PythonScript" module="Products.PythonScripts.PythonScript"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>_bind_names</string> </key>
<value>
<object>
<klass>
<global name="_reconstructor" module="copy_reg"/>
</klass>
<tuple>
<global name="NameAssignments" module="Shared.DC.Scripts.Bindings"/>
<global name="object" module="__builtin__"/>
<none/>
</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>_params</string> </key>
<value> <string>tag, fixit, params</string> </value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>Alarm_destroySoftwareInstallationWithArchivedSoftwareRelease</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
if context.getValidationState() != 'archived':
return
portal = context.getPortalObject()
catalog_kw = dict(
portal.portal_catalog.searchAndActivate(
method_id = 'SoftwareInstallation_destroyIfUnused',
activate_kw = {'tag':tag},
portal_type='Software Installation',
validation_state='validated',
url_string=context.getUrlString(),
**{"slapos_item.slap_state": "start_requested"}
)
portal.portal_catalog.searchAndActivate(
method_id = 'SoftwareInstallation_destroyWithSoftwareReleaseArchived',
activate_kw = {'tag':tag},
**catalog_kw
)
context.activate(after_tag=tag).getId()
......@@ -54,7 +54,7 @@
</item>
<item>
<key> <string>id</string> </key>
<value> <string>Alarm_processStoppedUpgradeDecision</string> </value>
<value> <string>Alarm_destroyUnusedSoftwareInstallation</string> </value>
</item>
</dictionary>
</pickle>
......
portal = context.getPortalObject()
portal.portal_catalog.searchAndActivate(
portal_type='Upgrade Decision',
simulation_state='planned',
method_id='UpgradeDecision_notify',
activate_kw={'tag': tag }
)
context.activate(after_tag=tag).getId()
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="PythonScript" module="Products.PythonScripts.PythonScript"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>_bind_names</string> </key>
<value>
<object>
<klass>
<global name="_reconstructor" module="copy_reg"/>
</klass>
<tuple>
<global name="NameAssignments" module="Shared.DC.Scripts.Bindings"/>
<global name="object" module="__builtin__"/>
<none/>
</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>_params</string> </key>
<value> <string>tag, fixit, params</string> </value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>Alarm_processPlannedUpgradeDecision</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
portal = context.getPortalObject()
portal.portal_catalog.searchAndActivate(
portal_type='Upgrade Decision',
simulation_state='stopped',
method_id='UpgradeDecision_notifyDelivered',
activate_kw={'tag': tag }
)
context.activate(after_tag=tag).getId()
if reference is None:
raise ValueError("Missing Reference")
portal = context.getPortalObject()
upgrade_decision_list = portal.portal_catalog(
portal_type="Upgrade Decision",
reference=reference, limit=2)
if not len(upgrade_decision_list):
return context.Base_redirect("",
keep_items={"portal_status_message":
context.Base_translateString("Unable to find the Upgrade Decision.")})
if len(upgrade_decision_list) > 1:
raise ValueError("Duplicated reference for %s. Please contact site administrators." % reference)
upgrade_decision = upgrade_decision_list[0]
if upgrade_decision.getSimulationState() in ['draft', 'planned']:
message = "Sorry, the upgrade is not possible yet!"
elif upgrade_decision.getSimulationState() in ['cancelled', 'rejected']:
message = "Sorry, the upgrade is not possble, Upgrade Decision was Canceled or Rejected!"
elif upgrade_decision.getSimulationState() == 'started':
message = "This Upgrade Decision is already Started."
elif upgrade_decision.getSimulationState() in ['stopped', 'delivered']:
message = "This Upgrade Decision has been already processed."
elif upgrade_decision.getSimulationState() == 'confirmed':
message = "This Upgrade Decision has been requested, it will be processed in few minutes."
upgrade_decision.start()
return context.Base_redirect("",
keep_items={"portal_status_message":
context.Base_translateString(message)})
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="PythonScript" module="Products.PythonScripts.PythonScript"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>_bind_names</string> </key>
<value>
<object>
<klass>
<global name="_reconstructor" module="copy_reg"/>
</klass>
<tuple>
<global name="NameAssignments" module="Shared.DC.Scripts.Bindings"/>
<global name="object" module="__builtin__"/>
<none/>
</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>_params</string> </key>
<value> <string>reference</string> </value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>Base_acceptUpgradeDecision</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
if reference is None:
raise ValueError("Missing Reference")
portal = context.getPortalObject()
upgrade_decision_list = portal.portal_catalog(
portal_type="Upgrade Decision",
reference=reference, limit=2)
if len(upgrade_decision_list) == 0:
return context.Base_redirect("",
keep_items={"portal_status_message":
context.Base_translateString("Unable to find the Upgrade Decision.")})
if len(upgrade_decision_list) > 1:
raise ValueError("Duplicated reference for %s. Please contact site administrators." % reference)
upgrade_decision = upgrade_decision_list[0]
if upgrade_decision.getSimulationState() in ['cancelled', 'rejected']:
message = "Upgrade Decision is already Rejected!"
elif upgrade_decision.getSimulationState() == 'started':
message = "Sorry, This Upgrade Decision is already Started, you cannot reject it anymore."
elif upgrade_decision.getSimulationState() in ['stopped', 'delivered']:
message = "Sorry, this Upgrade Decision has been already processed."
elif upgrade_decision.getSimulationState() in ['confirmed', 'draft', 'planned']:
message = "Thanks Upgrade Decision has been rejected Successfully (You cannot use it anymore)."
upgrade_decision.reject()
return context.Base_redirect("",
keep_items={"portal_status_message":
context.Base_translateString(message)})
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="PythonScript" module="Products.PythonScripts.PythonScript"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>_bind_names</string> </key>
<value>
<object>
<klass>
<global name="_reconstructor" module="copy_reg"/>
</klass>
<tuple>
<global name="NameAssignments" module="Shared.DC.Scripts.Bindings"/>
<global name="object" module="__builtin__"/>
<none/>
</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>_params</string> </key>
<value> <string>reference</string> </value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>Base_rejectUpgradeDecision</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
from DateTime import DateTime
compute_node = context
portal = context.getPortalObject()
upgrade_scope = context.getUpgradeScope()
if upgrade_scope in ["never", "disabled"]:
return
full_software_release_list = [si.url_string for si in
portal.portal_catalog(
select_dict = {"url_string": None},
portal_type='Software Installation',
default_aggregate_uid=compute_node.getUid(),
validation_state='validated'
) if si.getSlapState() == 'start_requested']
if len(full_software_release_list) == 0:
return
# group SR by Software Product to avoid two upgrade Decision for the same product
software_release_list = portal.portal_catalog(
portal_type='Software Release',
url_string=full_software_release_list,
group_by=['default_aggregate_uid']
)
upgrade_decision_list = []
for software_release in software_release_list:
software_product_reference = software_release.getAggregateReference()
if software_product_reference in [None, ""]:
continue
sorted_list = portal.SoftwareProduct_getSortedSoftwareReleaseList(
software_product_reference=software_product_reference)
# Check if there is a new version of this software Product
if sorted_list and \
sorted_list[0].getUrlString() not in full_software_release_list:
newer_release = sorted_list[0]
title = 'A new version of %s is available for %s' % \
(software_product_reference, context.getTitle())
# If exist upgrade decision in progress try to cancel it
decision_in_progress = newer_release.\
SoftwareRelease_getUpgradeDecisionInProgress(compute_node.getUid())
if decision_in_progress:
decision_in_progress.reviewRegistration(
software_release_url=newer_release.getUrlString())
if decision_in_progress.getSimulationState() != "cancelled":
continue
upgrade_decision = newer_release.SoftwareRelease_createUpgradeDecision(
source_url=compute_node.getRelativeUrl(),
title=title)
upgrade_decision.approveRegistration(
upgrade_scope=compute_node.getUpgradeScope("ask_confirmation"))
upgrade_decision_list.append(upgrade_decision)
return upgrade_decision_list
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="PythonScript" module="Products.PythonScripts.PythonScript"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>_bind_names</string> </key>
<value>
<object>
<klass>
<global name="_reconstructor" module="copy_reg"/>
</klass>
<tuple>
<global name="NameAssignments" module="Shared.DC.Scripts.Bindings"/>
<global name="object" module="__builtin__"/>
<none/>
</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>_params</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>ComputeNode_checkAndCreateUpgradeDecision</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="ProxyField" module="Products.ERP5Form.ProxyField"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>delegated_list</string> </key>
<value>
<list>
<string>columns</string>
<string>count_method</string>
<string>default_params</string>
<string>editable_columns</string>
<string>hide_rows_on_no_search_criterion</string>
<string>list_method</string>
<string>portal_types</string>
<string>search_columns</string>
<string>selection_name</string>
<string>sort</string>
<string>sort_columns</string>
<string>title</string>
</list>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>listbox</string> </value>
</item>
<item>
<key> <string>message_values</string> </key>
<value>
<dictionary>
<item>
<key> <string>external_validator_failed</string> </key>
<value> <string>The input failed the external validator.</string> </value>
</item>
</dictionary>
</value>
</item>
<item>
<key> <string>overrides</string> </key>
<value>
<dictionary>
<item>
<key> <string>field_id</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>form_id</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>target</string> </key>
<value> <string></string> </value>
</item>
</dictionary>
</value>
</item>
<item>
<key> <string>tales</string> </key>
<value>
<dictionary>
<item>
<key> <string>columns</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>count_method</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>default_params</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAI=</string> </persistent>
</value>
</item>
<item>
<key> <string>editable_columns</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>field_id</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>form_id</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>hide_rows_on_no_search_criterion</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>list_method</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>portal_types</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>search_columns</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>selection_name</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAM=</string> </persistent>
</value>
</item>
<item>
<key> <string>sort</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>sort_columns</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>target</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string></string> </value>
</item>
</dictionary>
</value>
</item>
<item>
<key> <string>values</string> </key>
<value>
<dictionary>
<item>
<key> <string>columns</string> </key>
<value>
<list>
<tuple>
<string>reference</string>
<string>Reference</string>
</tuple>
<tuple>
<string>title</string>
<string>Title</string>
</tuple>
<tuple>
<string>UpgradeDecision_getAggregateUrlString</string>
<string>Software Release Url</string>
</tuple>
<tuple>
<string>translated_simulation_state_title</string>
<string>State</string>
</tuple>
</list>
</value>
</item>
<item>
<key> <string>count_method</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>default_params</string> </key>
<value>
<list/>
</value>
</item>
<item>
<key> <string>editable_columns</string> </key>
<value>
<list/>
</value>
</item>
<item>
<key> <string>field_id</string> </key>
<value> <string>my_list_mode_listbox</string> </value>
</item>
<item>
<key> <string>form_id</string> </key>
<value> <string>Base_viewWebFieldLibrary</string> </value>
</item>
<item>
<key> <string>hide_rows_on_no_search_criterion</string> </key>
<value> <int>0</int> </value>
</item>
<item>
<key> <string>list_method</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAQ=</string> </persistent>
</value>
</item>
<item>
<key> <string>portal_types</string> </key>
<value>
<list>
<tuple>
<string>Upgrade Decision</string>
<string>Upgrade Decision</string>
</tuple>
</list>
</value>
</item>
<item>
<key> <string>search_columns</string> </key>
<value>
<list>
<tuple>
<string>reference</string>
<string>Reference</string>
</tuple>
<tuple>
<string>title</string>
<string>Title</string>
</tuple>
<tuple>
<string>translated_simulation_state_title</string>
<string>State</string>
</tuple>
</list>
</value>
</item>
<item>
<key> <string>selection_name</string> </key>
<value> <string>software_instance_selection</string> </value>
</item>
<item>
<key> <string>sort</string> </key>
<value>
<list>
<tuple>
<string>modification_date</string>
<string>Modification Date</string>
</tuple>
</list>
</value>
</item>
<item>
<key> <string>sort_columns</string> </key>
<value>
<list>
<tuple>
<string>modification_date</string>
<string>Modification Date</string>
</tuple>
</list>
</value>
</item>
<item>
<key> <string>target</string> </key>
<value> <string>Click to edit the target</string> </value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string>Upgrade Decisions</string> </value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</pickle>
</record>
<record id="2" aka="AAAAAAAAAAI=">
<pickle>
<global name="TALESMethod" module="Products.Formulator.TALESField"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>_text</string> </key>
<value> <string>python: [(\'child_aggregate_relative_url\', here.getRelativeUrl())]</string> </value>
</item>
</dictionary>
</pickle>
</record>
<record id="3" aka="AAAAAAAAAAM=">
<pickle>
<global name="TALESMethod" module="Products.Formulator.TALESField"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>_text</string> </key>
<value> <string>python: \'instance_tree_%s_upgrade_list\' % here.getUid()</string> </value>
</item>
</dictionary>
</pickle>
</record>
<record id="4" aka="AAAAAAAAAAQ=">
<pickle>
<global name="Method" module="Products.Formulator.MethodField"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>method_name</string> </key>
<value> <string>portal_catalog</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
from DateTime import DateTime
portal = context.getPortalObject()
from zExceptions import Unauthorized
if REQUEST is not None:
raise Unauthorized
instance_tree = context
upgrade_scope = context.getUpgradeScope("ask_confirmation")
if upgrade_scope in ["never", "disabled"]:
return
root_instance_list = [
q for q in instance_tree.getSuccessorValueList(portal_type=["Software Instance", "Slave Instance"])
if q.getSlapState() != 'destroy_requested']
if len(root_instance_list) == 0:
if instance_tree.getSlapState() == "destroy_requested":
return
root_instance = root_instance_list[0]
slave_upgrade = False
if root_instance.getPortalType() == 'Slave Instance':
slave_upgrade = True
upgrade_scope = "auto"
if (target_software_release is not None) or (target_software_type is not None):
# Those parameters will be use to force an upgrade decision
# to a specific release / type
# used by Remote Node for example
assert target_software_release is not None
assert target_software_type is not None
if instance_tree.getSlapState() == "destroy_requested":
if portal.portal_catalog.getResultValue(
portal_type='Upgrade Decision',
aggregate__uid=instance_tree.getUid(),
simulation_state=['started', 'stopped', 'planned', 'confirmed']
) is not None:
# There is already a upgrade decision, do nothing
return
# Check if UpgradeDecision_approveRegistration is running
# XXX we should instead look at the current upgrade decision state
tag = "%s_requestUpgradeDecisionCreation_inProgress" % instance_tree.getUid()
if portal.portal_activities.countMessageWithTag(tag) > 0:
# nothing to do
# previous run not finished, skip
return
partition = root_instance.getAggregateValue(portal_type="Compute Partition")
if partition is None:
software_product, software_release, software_type = instance_tree.InstanceTree_getSoftwareProduct()
if software_product is None:
# No way to upgrade, if we can find which Software Product to upgrade
return
assert software_release.getUrlString() == instance_tree.getUrlString()
decision_title = 'A new upgrade is available for %s' % instance_tree.getTitle()
newer_release = None
if slave_upgrade:
software_instance = partition.getAggregateRelatedValue(portal_type='Software Instance')
if software_instance:
url_string = software_instance.getUrlString()
if url_string != instance_tree.getUrlString():
newer_release = context.portal_catalog.getResultValue(portal_type='Software Release', url_string=url_string)
else:
newer_release = instance_tree.\
InstanceTree_getUpgradableSoftwareRelease()
if newer_release is None:
return
compute_node = None
root_instance = None
root_instance_list = [
q for q in instance_tree.getSuccessorValueList(portal_type=["Software Instance", "Slave Instance"])
if q.getSlapState() != 'destroy_requested']
if len(root_instance_list) != 0:
root_instance = root_instance_list[0]
partition = root_instance.getAggregateValue()
if partition is not None:
compute_node = partition.getParentValue()
decision_in_progress = newer_release.\
SoftwareRelease_getUpgradeDecisionInProgress(instance_tree.getUid())
if (root_instance.getPortalType() == 'Slave Instance'):
if (compute_node.getPortalType() == 'Compute Node'):
# Search the instance node linked to this partition
soft_instance = partition.getAggregateRelatedValue(portal_type='Software Instance')
if soft_instance is None:
return
instance_node = soft_instance.getSpecialiseRelatedValue(portal_type='Instance Node')
if instance_node is None:
return
compute_node = instance_node
elif (compute_node.getPortalType() != 'Remote Node'):
return
if decision_in_progress:
decision_in_progress.reviewRegistration(
software_release_url=newer_release.getUrlString())
if decision_in_progress.getSimulationState() != "cancelled":
return
person = context.getDestinationSectionValue(checked_permission='Access contents information')
upgrade_decision = newer_release.SoftwareRelease_createUpgradeDecision(
source_url=instance_tree.getRelativeUrl(),
title=decision_title
# Search if the product with the same type
# XXX search only for the main node
allocation_cell_list = software_product.getFollowUpValue().Project_getSoftwareProductPredicateList(
software_product=software_product,
software_product_type=target_software_type or software_type,
software_product_release=target_software_release,
destination_value=person,
node_value=compute_node,
predicate_portal_type='Allocation Supply Cell'
)
upgrade_decision.approveRegistration(
upgrade_scope=upgrade_scope)
if (compute_node is None) and (root_instance is not None):
# Do not upgrade if there is no instance yet
allocation_cell_node_list = [(x, [y.getPortalType() for y in x.getParentValue().getParentValue().getAggregateValueList()]) for x in allocation_cell_list]
if (root_instance.getPortalType() == 'Slave Instance'):
allocation_cell_list = [x for x, y in allocation_cell_node_list if ("Remote Node" in y) or ("Instance Node" in y)]
elif (root_instance.getPortalType() == 'Software Instance'):
allocation_cell_list = [x for x, y in allocation_cell_node_list if ("Remote Node" in y) or ("Compute Node" in y)]
# Only upgrade if there is no doubt (ie, only 1 url is allowed)
if len(allocation_cell_list) == 1:
if (allocation_cell_list[0].getSoftwareReleaseValue().getUrlString() != instance_tree.getUrlString()):
# XXX Upgrade
if compute_node is not None:
assert compute_node.getRelativeUrl() in allocation_cell_list[0].getParentValue().getParentValue().getAggregateList()
if portal.portal_catalog.getResultValue(
portal_type='Upgrade Decision',
aggregate__uid=instance_tree.getUid(),
simulation_state=['rejected'],
software_release__uid=allocation_cell_list[0].getSoftwareReleaseUid()
):
# If same upgrade decision has been rejected, do nothing
return
decision_title = 'A new upgrade is available for %s' % instance_tree.getTitle()
person_relative_url = context.getDestinationSection()
upgrade_decision = portal.upgrade_decision_module.newContent(
portal_type='Upgrade Decision',
title=decision_title,
destination_section=person_relative_url,
destination_decision=person_relative_url,
destination_project_value=instance_tree.getFollowUpValue(),
resource_value=software_product,
variation_category_list=allocation_cell_list[0].getVariationCategoryList(),
aggregate_value=instance_tree,
# As a ticket, give the ticket original context
causality_value=instance_tree,
)
with upgrade_decision.defaultActivateParameterDict({'tag': tag}):
if upgrade_decision.getSimulationState() == "draft":
upgrade_decision.plan()
upgrade_decision.setStartDate(DateTime())
if upgrade_decision.getSimulationState() == "planned":
upgrade_decision.confirm()
# Prevent concurrent transaction to create 2 upgrade decision for the same instance_tree
instance_tree.serialize()
return upgrade_decision
return upgrade_decision
......@@ -50,7 +50,7 @@
</item>
<item>
<key> <string>_params</string> </key>
<value> <string></string> </value>
<value> <string>REQUEST=None, target_software_release=None, target_software_type=None</string> </value>
</item>
<item>
<key> <string>id</string> </key>
......
slap_state = ['start_requested', 'stop_requested']
if not context.getSlapState() in slap_state:
return None
software_instance_list = [q for q in context.getSuccessorValueList() if q.getSlapState() in slap_state]
if len(software_instance_list) == 0:
return None
software_instance = software_instance_list[0]
software_release_list = context.SoftwareProduct_getSortedSoftwareReleaseList(
software_release_url=software_instance.getUrlString())
if not software_release_list:
return None
latest_software_release = software_release_list[0]
if latest_software_release.getUrlString() == software_instance.getUrlString():
return None
else:
return latest_software_release
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="PythonScript" module="Products.PythonScripts.PythonScript"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>_bind_names</string> </key>
<value>
<object>
<klass>
<global name="_reconstructor" module="copy_reg"/>
</klass>
<tuple>
<global name="NameAssignments" module="Shared.DC.Scripts.Bindings"/>
<global name="object" module="__builtin__"/>
<none/>
</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>_params</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>InstanceTree_getNewerSofwareRelease</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
"""
Check if this instance tree is upgradable to the latest version,
and return the software release to upgrade with.
"""
instance_tree = context
portal = context.getPortalObject()
slap_state = ['start_requested', 'stop_requested']
if not instance_tree.getSlapState() in slap_state:
return None
source_instance_list = [q for q in instance_tree.getSuccessorValueList() if q.getSlapState() in slap_state]
if len(source_instance_list) == 0:
return None
source_instance = source_instance_list[0]
software_release = instance_tree.InstanceTree_getNewerSofwareRelease()
if not software_release:
return None
compute_node = source_instance.getAggregateValue().getParentValue()
if compute_node.getValidationState() != 'validated':
return None
#Find Software Installation
software_installation_list = portal.portal_catalog(
portal_type="Software Installation",
validation_state="validated",
url_string=software_release.getUrlString(),
default_aggregate_uid=compute_node.getUid(),
)
# check again slap_state because it might be ignored in previous request!
if 'start_requested' in [software_installation.getSlapState() \
for software_installation in software_installation_list]:
return software_release
return None
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="PythonScript" module="Products.PythonScripts.PythonScript"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>_bind_names</string> </key>
<value>
<object>
<klass>
<global name="_reconstructor" module="copy_reg"/>
</klass>
<tuple>
<global name="NameAssignments" module="Shared.DC.Scripts.Bindings"/>
<global name="object" module="__builtin__"/>
<none/>
</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>_params</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>InstanceTree_getUpgradableSoftwareRelease</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
"""
Get a related Upgrade Decision
"""
if simulation_state not in ["confirmed", "started", "stopped"]:
raise ValueError(
"You shouldn't request for this state: %s" % simulation_state)
decision_line_list = context.getAggregateValueList(
portal_type="Upgrade Decision Line",
simulation_state=simulation_state)
if len(decision_line_list) > 1:
raise ValueError("Your have more them one valid decison line!")
if len(decision_line_list) == 0:
return None
return decision_line_list[0].getParentValue()
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="PythonScript" module="Products.PythonScripts.PythonScript"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>_bind_names</string> </key>
<value>
<object>
<klass>
<global name="_reconstructor" module="copy_reg"/>
</klass>
<tuple>
<global name="NameAssignments" module="Shared.DC.Scripts.Bindings"/>
<global name="object" module="__builtin__"/>
<none/>
</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>_params</string> </key>
<value> <string>simulation_state=\'confirmed\'</string> </value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>InstanceTree_getUpgradeSubscriptionRelatedValue</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
portal = context.getPortalObject()
# This won't work well on clusters deployed on multiple compute_nodes.
root_instance = context.getSuccessorValue(
portal_type=["Software Instance", "Slave Instance"])
if root_instance is not None and root_instance.getPortalType() == 'Slave Instance':
return True
# Get Compute Node List
instance_list = context.getSpecialiseRelatedValueList(
portal_type="Software Instance")
compute_node_list = []
for instance in instance_list:
if instance.getSlapState() == "destroy_requested":
continue
partition = instance.getAggregateValue(portal_type="Compute Partition")
if partition is None:
continue
compute_node_list.append(partition.getParentValue().getUid())
if not compute_node_list:
return True
full_software_installation_list = [si for si in
portal.portal_catalog(
portal_type='Software Installation',
url_string=software_release_url,
default_aggregate_uid=compute_node_list,
validation_state='validated'
) if si.getSlapState() == 'start_requested']
if len(full_software_installation_list) > 0 and \
len(full_software_installation_list) == len(set(compute_node_list)):
# Software is available for the root instance
software_installation = full_software_installation_list[0]
message = software_installation.getTextAccessStatus()
if message.startswith("#access"):
return True
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="PythonScript" module="Products.PythonScripts.PythonScript"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>_bind_names</string> </key>
<value>
<object>
<klass>
<global name="_reconstructor" module="copy_reg"/>
</klass>
<tuple>
<global name="NameAssignments" module="Shared.DC.Scripts.Bindings"/>
<global name="object" module="__builtin__"/>
<none/>
</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>_params</string> </key>
<value> <string>software_release_url</string> </value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>InstanceTree_isUpgradePossible</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
portal = context.getPortalObject()
software_installation = context
if software_installation.getValidationState() != 'validated':
return
if software_installation.getSlapState() != 'start_requested':
return
compute_node = software_installation.getAggregateValue(portal_type='Compute Node')
if compute_node is None:
return
# Search related software release
url_string = software_installation.getUrlString()
software_release = None
if url_string:
use_category_uid = portal.restrictedTraverse("portal_categories/use/trade/sale").getUid(),
product_list = portal.portal_catalog(
portal_type="Software Product",
validation_state=['validated', 'published'],
use__uid=use_category_uid,
follow_up__uid=compute_node.getFollowUpUid()
)
if len(product_list) != 0:
software_release = portal.portal_catalog.getResultValue(
portal_type="Software Product Release Variation",
url_string=url_string,
parent_uid=[x.getUid() for x in product_list]
)
if software_release is None:
return
software_product = software_release.getParentValue()
# If one Supply uses this software release, do nothing
for allocation_cell in portal.portal_catalog(
portal_type='Allocation Supply Cell',
# Follow up is not acquired.
# But as the software release object is project related, it should be ok to skip this filter
# follow_up__uid=software_product.getFollowUpUid(),
resource__uid=software_product.getUid(),
software_release__uid=software_release.getUid()
):
if allocation_cell.isAllocable():
return
# XXX check validation state
partition = portal.portal_catalog.getResultValue(
portal_type='Compute Partition',
parent_uid=compute_node.getUid(),
free_for_request=0,
software_release_url=url_string
)
if partition is not None:
return
software_installation.requestDestroy(
comment='Destroyed by %s as unused.' % script.id)
......@@ -54,7 +54,7 @@
</item>
<item>
<key> <string>id</string> </key>
<value> <string>UpgradeDecision_isUpgradeFinished</string> </value>
<value> <string>SoftwareInstallation_destroyIfUnused</string> </value>
</item>
</dictionary>
</pickle>
......
software_installation = context
url_string = software_installation.getUrlString()
if software_installation.getValidationState() != 'validated':
return
if software_installation.getSlapState() != 'start_requested':
return
software_release = software_installation.portal_catalog.getResultValue(
portal_type='Software Release',
validation_state='archived',
url_string=url_string
)
if software_release is None:
return
compute_node = software_installation.getAggregateValue(portal_type='Compute Node')
if compute_node is None:
return
if compute_node.ComputeNode_getSoftwareReleaseUsage(url_string) != 0:
return
if compute_node.getUpgradeScope() != 'auto':
# handle only Compute Nodes with automatic software management
return
software_installation.requestDestroy(
comment='Destroyed by %s as %s is archived.' % (script.id, software_release.getRelativeUrl(),))
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="PythonScript" module="Products.PythonScripts.PythonScript"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>_bind_names</string> </key>
<value>
<object>
<klass>
<global name="_reconstructor" module="copy_reg"/>
</klass>
<tuple>
<global name="NameAssignments" module="Shared.DC.Scripts.Bindings"/>
<global name="object" module="__builtin__"/>
<none/>
</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>_params</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>SoftwareInstallation_destroyWithSoftwareReleaseArchived</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="ProxyField" module="Products.ERP5Form.ProxyField"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>delegated_list</string> </key>
<value>
<list/>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>my_reference</string> </value>
</item>
<item>
<key> <string>message_values</string> </key>
<value>
<dictionary>
<item>
<key> <string>external_validator_failed</string> </key>
<value> <string>The input failed the external validator.</string> </value>
</item>
</dictionary>
</value>
</item>
<item>
<key> <string>overrides</string> </key>
<value>
<dictionary>
<item>
<key> <string>field_id</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>form_id</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>target</string> </key>
<value> <string></string> </value>
</item>
</dictionary>
</value>
</item>
<item>
<key> <string>tales</string> </key>
<value>
<dictionary>
<item>
<key> <string>field_id</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>form_id</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>target</string> </key>
<value> <string></string> </value>
</item>
</dictionary>
</value>
</item>
<item>
<key> <string>values</string> </key>
<value>
<dictionary>
<item>
<key> <string>field_id</string> </key>
<value> <string>my_reference</string> </value>
</item>
<item>
<key> <string>form_id</string> </key>
<value> <string>Base_viewPDMFieldLibrary</string> </value>
</item>
<item>
<key> <string>target</string> </key>
<value> <string>Click to edit the target</string> </value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
......@@ -41,6 +41,10 @@
<key> <string>action</string> </key>
<value> <string>Base_edit</string> </value>
</item>
<item>
<key> <string>action_title</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>description</string> </key>
<value> <string></string> </value>
......@@ -100,16 +104,14 @@
<value>
<list>
<string>my_title</string>
<string>my_reference</string>
<string>my_url_string</string>
</list>
</value>
</item>
<item>
<key> <string>right</string> </key>
<value>
<list>
<string>my_capacity_quantity</string>
</list>
<list/>
</value>
</item>
</dictionary>
......@@ -117,7 +119,7 @@
</item>
<item>
<key> <string>id</string> </key>
<value> <string>SoftwareProductIndividualVariation_view</string> </value>
<value> <string>SoftwareProductReleaseVariation_view</string> </value>
</item>
<item>
<key> <string>method</string> </key>
......@@ -125,7 +127,7 @@
</item>
<item>
<key> <string>name</string> </key>
<value> <string>IndividualVariation_view</string> </value>
<value> <string>SoftwareProductReleaseVariation_view</string> </value>
</item>
<item>
<key> <string>pt</string> </key>
......@@ -141,7 +143,7 @@
</item>
<item>
<key> <string>title</string> </key>
<value> <string>Individual Variation</string> </value>
<value> <string>Software Product Release Variation</string> </value>
</item>
<item>
<key> <string>unicode_mode</string> </key>
......@@ -151,6 +153,10 @@
<key> <string>update_action</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>update_action_title</string> </key>
<value> <string></string> </value>
</item>
</dictionary>
</pickle>
</record>
......
......@@ -11,13 +11,13 @@
<value>
<list>
<string>display_width</string>
<string>editable</string>
<string>title</string>
</list>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>my_title</string> </value>
<value> <string>my_url_string</string> </value>
</item>
<item>
<key> <string>message_values</string> </key>
......@@ -66,20 +66,20 @@
<dictionary>
<item>
<key> <string>display_width</string> </key>
<value> <int>20</int> </value>
</item>
<item>
<key> <string>editable</string> </key>
<value> <int>0</int> </value>
<value> <int>40</int> </value>
</item>
<item>
<key> <string>field_id</string> </key>
<value> <string>my_view_mode_title</string> </value>
<value> <string>my_string_field</string> </value>
</item>
<item>
<key> <string>form_id</string> </key>
<value> <string>Base_viewFieldLibrary</string> </value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string>URL</string> </value>
</item>
</dictionary>
</value>
</item>
......
......@@ -82,15 +82,15 @@
<item>
<key> <string>bottom</string> </key>
<value>
<list>
<string>listbox</string>
</list>
<list/>
</value>
</item>
<item>
<key> <string>center</string> </key>
<value>
<list/>
<list>
<string>my_description</string>
</list>
</value>
</item>
<item>
......@@ -104,16 +104,13 @@
<value>
<list>
<string>my_title</string>
<string>my_reference</string>
</list>
</value>
</item>
<item>
<key> <string>right</string> </key>
<value>
<list>
<string>my_upgrade_scope</string>
</list>
<list/>
</value>
</item>
</dictionary>
......@@ -121,7 +118,7 @@
</item>
<item>
<key> <string>id</string> </key>
<value> <string>ComputeNode_viewUpgradeDecision</string> </value>
<value> <string>SoftwareProductTypeVariation_view</string> </value>
</item>
<item>
<key> <string>method</string> </key>
......@@ -129,7 +126,7 @@
</item>
<item>
<key> <string>name</string> </key>
<value> <string>ComputeNode_viewUpgradeDecision</string> </value>
<value> <string>SoftwareProductTypeVariation_view</string> </value>
</item>
<item>
<key> <string>pt</string> </key>
......@@ -145,7 +142,7 @@
</item>
<item>
<key> <string>title</string> </key>
<value> <string>Compute Node</string> </value>
<value> <string>Software Product Type Variation</string> </value>
</item>
<item>
<key> <string>unicode_mode</string> </key>
......
......@@ -10,13 +10,13 @@
<key> <string>delegated_list</string> </key>
<value>
<list>
<string>display_width</string>
<string>height</string>
</list>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>my_title</string> </value>
<value> <string>my_description</string> </value>
</item>
<item>
<key> <string>message_values</string> </key>
......@@ -71,17 +71,17 @@
<key> <string>values</string> </key>
<value>
<dictionary>
<item>
<key> <string>display_width</string> </key>
<value> <int>20</int> </value>
</item>
<item>
<key> <string>field_id</string> </key>
<value> <string>my_view_mode_title</string> </value>
<value> <string>my_description</string> </value>
</item>
<item>
<key> <string>form_id</string> </key>
<value> <string>Base_viewFieldLibrary</string> </value>
<value> <string>erp5_software_pdm/SoftwareProduct_view</string> </value>
</item>
<item>
<key> <string>height</string> </key>
<value> <int>3</int> </value>
</item>
<item>
<key> <string>target</string> </key>
......
......@@ -9,14 +9,12 @@
<item>
<key> <string>delegated_list</string> </key>
<value>
<list>
<string>title</string>
</list>
<list/>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>my_capacity_quantity</string> </value>
<value> <string>my_title</string> </value>
</item>
<item>
<key> <string>message_values</string> </key>
......@@ -71,13 +69,17 @@
<key> <string>values</string> </key>
<value>
<dictionary>
<item>
<key> <string>description</string> </key>
<value> <string>Title of the transformation</string> </value>
</item>
<item>
<key> <string>field_id</string> </key>
<value> <string>my_integer_value</string> </value>
<value> <string>my_title</string> </value>
</item>
<item>
<key> <string>form_id</string> </key>
<value> <string>Base_viewFieldLibrary</string> </value>
<value> <string>Base_viewPDMFieldLibrary</string> </value>
</item>
<item>
<key> <string>target</string> </key>
......@@ -85,7 +87,7 @@
</item>
<item>
<key> <string>title</string> </key>
<value> <string>Capacity</string> </value>
<value> <string>Title</string> </value>
</item>
</dictionary>
</value>
......
from DateTime import DateTime
portal = context.getPortalObject()
if software_release_url is None and \
context.getPortalType() == "Software Product":
software_product_reference = context.getReference()
if software_product_reference is None:
assert(software_release_url is not None)
software_release = portal.portal_catalog.getResultValue(
portal_type='Software Release',
url_string=software_release_url
)
if not software_release:
return []
if strict:
return [software_release]
software_product_reference = software_release.getAggregateReference()
if not software_product_reference:
return []
else:
# Don't accept both parameters
assert(software_release_url is None)
product_list = portal.portal_catalog(
portal_type='Software Product',
reference=software_product_reference,
validation_state=['published', 'validated'],
limit=2)
if not product_list:
return []
if len(product_list) > 1:
raise ValueError('Several Software Product with the same reference.')
software_release_list = product_list[0].getAggregateRelatedValueList()
def sortkey(software_release):
publication_date = software_release.getEffectiveDate()
delta = 0
if software_release.getValidationState() == "archived":
# Decrease 80 years, to be sure it goes last but still on the list
delta = 365*80
if publication_date:
if (publication_date - DateTime()) > 0:
# Decrease 100 years, to be sure it goes at the end of the queue
delta = 365*100
return publication_date - delta
return software_release.getCreationDate() - delta
software_release_list = sorted(
software_release_list,
key=sortkey, reverse=True,
)
return [software_release for software_release in software_release_list
if software_release.getValidationState() in
["published", "published_alive", "archived"]]
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="PythonScript" module="Products.PythonScripts.PythonScript"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>_bind_names</string> </key>
<value>
<object>
<klass>
<global name="_reconstructor" module="copy_reg"/>
</klass>
<tuple>
<global name="NameAssignments" module="Shared.DC.Scripts.Bindings"/>
<global name="object" module="__builtin__"/>
<none/>
</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>_params</string> </key>
<value> <string>software_product_reference=None, software_release_url=None, strict=None</string> </value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>SoftwareProduct_getSortedSoftwareReleaseList</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
......@@ -78,9 +78,7 @@
<item>
<key> <string>bottom (Preview)</string> </key>
<value>
<list>
<string>listbox</string>
</list>
<list/>
</value>
</item>
<item>
......
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="ProxyField" module="Products.ERP5Form.ProxyField"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>delegated_list</string> </key>
<value>
<list>
<string>columns</string>
<string>list_method</string>
<string>portal_types</string>
<string>title</string>
</list>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>listbox</string> </value>
</item>
<item>
<key> <string>message_values</string> </key>
<value>
<dictionary>
<item>
<key> <string>external_validator_failed</string> </key>
<value> <string>The input failed the external validator.</string> </value>
</item>
</dictionary>
</value>
</item>
<item>
<key> <string>overrides</string> </key>
<value>
<dictionary>
<item>
<key> <string>field_id</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>form_id</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>target</string> </key>
<value> <string></string> </value>
</item>
</dictionary>
</value>
</item>
<item>
<key> <string>tales</string> </key>
<value>
<dictionary>
<item>
<key> <string>field_id</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>form_id</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>target</string> </key>
<value> <string></string> </value>
</item>
</dictionary>
</value>
</item>
<item>
<key> <string>values</string> </key>
<value>
<dictionary>
<item>
<key> <string>columns</string> </key>
<value>
<list>
<tuple>
<string>title</string>
<string>Title</string>
</tuple>
<tuple>
<string>version</string>
<string>Version</string>
</tuple>
<tuple>
<string>translated_validation_state_title</string>
<string>State</string>
</tuple>
</list>
</value>
</item>
<item>
<key> <string>field_id</string> </key>
<value> <string>my_view_mode_listbox</string> </value>
</item>
<item>
<key> <string>form_id</string> </key>
<value> <string>Base_viewFieldLibrary</string> </value>
</item>
<item>
<key> <string>list_method</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAI=</string> </persistent>
</value>
</item>
<item>
<key> <string>portal_types</string> </key>
<value>
<list>
<tuple>
<string>Software Release</string>
<string>Software Release</string>
</tuple>
</list>
</value>
</item>
<item>
<key> <string>target</string> </key>
<value> <string>Click to edit the target</string> </value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string>Sotware Release</string> </value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</pickle>
</record>
<record id="2" aka="AAAAAAAAAAI=">
<pickle>
<tuple>
<global name="Method" module="Products.Formulator.MethodField"/>
<tuple/>
</tuple>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>method_name</string> </key>
<value> <string>Base_getRelatedObjectList</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
......@@ -112,8 +112,8 @@
<value>
<list>
<tuple>
<string>Software Product Individual Variation</string>
<string>Software Product Individual Variation</string>
<string>Software Type</string>
<string>Software Type</string>
</tuple>
</list>
</value>
......
from DateTime import DateTime
portal = context.getPortalObject()
software_release = context
source_product = portal.restrictedTraverse(source_url, None)
if not source_product:
return
portal_type = source_product.getPortalType()
if portal_type == 'Compute Node':
person_url = source_product.getSourceAdministration()
elif portal_type == 'Instance Tree':
person_url = source_product.getDestinationSection()
else:
return
if not person_url:
return
upgrade_decision = portal.upgrade_decision_module.\
template_upgrade_decision.Base_createCloneDocument(batch_mode=1)
upgrade_decision.edit(title=title)
upgrade_decision.setDestinationSection(person_url)
upgrade_decision.setDestinationDecision(person_url)
decision_line_list = upgrade_decision.contentValues(
portal_type='Upgrade Decision Line')
if len(decision_line_list) > 0:
decision_line = decision_line_list[0]
else:
decision_line = upgrade_decision.newContent(
portal_type='Upgrade Decision Line')
decision_line.edit(
title='Request decision upgrade for %s on %s %s' % (
software_release.getTitle(), portal_type, source_product.getReference()),
aggregate=[source_url, software_release.getRelativeUrl()])
return upgrade_decision
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="PythonScript" module="Products.PythonScripts.PythonScript"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>_bind_names</string> </key>
<value>
<object>
<klass>
<global name="_reconstructor" module="copy_reg"/>
</klass>
<tuple>
<global name="NameAssignments" module="Shared.DC.Scripts.Bindings"/>
<global name="object" module="__builtin__"/>
<none/>
</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>_params</string> </key>
<value> <string>source_url, title</string> </value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>SoftwareRelease_createUpgradeDecision</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>_bind_names</string> </key>
<value>
<object>
<klass>
<global name="_reconstructor" module="copy_reg"/>
</klass>
<tuple>
<global name="NameAssignments" module="Shared.DC.Scripts.Bindings"/>
<global name="object" module="__builtin__"/>
<none/>
</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>_params</string> </key>
<value> <string>tag</string> </value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>SoftwareRelease_findAndDestroySoftwareInstallation</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
portal = context.getPortalObject()
product_reference = context.getAggregateReference()
decision_line_in_progress_list = portal.portal_catalog(
portal_type='Upgrade Decision Line',
default_aggregate_uid=aggregate_uid)
for decision_line in decision_line_in_progress_list:
upgrade_decision = decision_line.getParentValue()
simulation_state = upgrade_decision.getSimulationState()
if simulation_state not in ['planned', 'confirmed',
'started', 'stopped', 'rejected']:
continue
release_list = decision_line.getAggregateValueList(portal_type="Software Release")
if len(release_list) > 1:
continue
if not release_list:
continue
# If the current sr in rejected we must prevent creation of new upgrade decision for this sr
if simulation_state == 'rejected' and \
release_list[0].getUrlString() != context.getUrlString():
continue
# If both software release belong to the same software product, there is an upgrade decision in progress
if product_reference == release_list[0].getAggregateReference():
return upgrade_decision
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="PythonScript" module="Products.PythonScripts.PythonScript"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>_bind_names</string> </key>
<value>
<object>
<klass>
<global name="_reconstructor" module="copy_reg"/>
</klass>
<tuple>
<global name="NameAssignments" module="Shared.DC.Scripts.Bindings"/>
<global name="object" module="__builtin__"/>
<none/>
</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>_params</string> </key>
<value> <string>aggregate_uid</string> </value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>SoftwareRelease_getUpgradeDecisionInProgress</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>_bind_names</string> </key>
<value>
<object>
<klass>
<global name="_reconstructor" module="copy_reg"/>
</klass>
<tuple>
<global name="NameAssignments" module="Shared.DC.Scripts.Bindings"/>
<global name="object" module="__builtin__"/>
<none/>
</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>_params</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>UpgradeDecisionLine_cancel</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="ERP5 Form" module="erp5.portal_type"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>_objects</string> </key>
<value>
<tuple/>
</value>
</item>
<item>
<key> <string>action</string> </key>
<value> <string>Base_edit</string> </value>
</item>
<item>
<key> <string>description</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>edit_order</string> </key>
<value>
<list/>
</value>
</item>
<item>
<key> <string>encoding</string> </key>
<value> <string>UTF-8</string> </value>
</item>
<item>
<key> <string>enctype</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>group_list</string> </key>
<value>
<list>
<string>left</string>
<string>right</string>
<string>center</string>
<string>bottom</string>
<string>hidden</string>
</list>
</value>
</item>
<item>
<key> <string>groups</string> </key>
<value>
<dictionary>
<item>
<key> <string>bottom</string> </key>
<value>
<list/>
</value>
</item>
<item>
<key> <string>center</string> </key>
<value>
<list/>
</value>
</item>
<item>
<key> <string>hidden</string> </key>
<value>
<list/>
</value>
</item>
<item>
<key> <string>left</string> </key>
<value>
<list>
<string>my_title</string>
<string>my_aggregate_title_list</string>
</list>
</value>
</item>
<item>
<key> <string>right</string> </key>
<value>
<list>
<string>my_start_date</string>
<string>my_stop_date</string>
</list>
</value>
</item>
</dictionary>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>UpgradeDecisionLine_view</string> </value>
</item>
<item>
<key> <string>method</string> </key>
<value> <string>POST</string> </value>
</item>
<item>
<key> <string>name</string> </key>
<value> <string>UpgradeDecisionLine_view</string> </value>
</item>
<item>
<key> <string>pt</string> </key>
<value> <string>form_view</string> </value>
</item>
<item>
<key> <string>row_length</string> </key>
<value> <int>4</int> </value>
</item>
<item>
<key> <string>stored_encoding</string> </key>
<value> <string>UTF-8</string> </value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string>Upgrade Decision</string> </value>
</item>
<item>
<key> <string>unicode_mode</string> </key>
<value> <int>0</int> </value>
</item>
<item>
<key> <string>update_action</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>update_action_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="ProxyField" module="Products.ERP5Form.ProxyField"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>delegated_list</string> </key>
<value>
<list/>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>my_aggregate_title_list</string> </value>
</item>
<item>
<key> <string>message_values</string> </key>
<value>
<dictionary>
<item>
<key> <string>external_validator_failed</string> </key>
<value> <string>The input failed the external validator.</string> </value>
</item>
</dictionary>
</value>
</item>
<item>
<key> <string>overrides</string> </key>
<value>
<dictionary>
<item>
<key> <string>field_id</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>form_id</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>target</string> </key>
<value> <string></string> </value>
</item>
</dictionary>
</value>
</item>
<item>
<key> <string>tales</string> </key>
<value>
<dictionary>
<item>
<key> <string>field_id</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>form_id</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>target</string> </key>
<value> <string></string> </value>
</item>
</dictionary>
</value>
</item>
<item>
<key> <string>values</string> </key>
<value>
<dictionary>
<item>
<key> <string>field_id</string> </key>
<value> <string>my_view_mode_aggregate_title_list</string> </value>
</item>
<item>
<key> <string>form_id</string> </key>
<value> <string>Base_viewTradeFieldLibrary</string> </value>
</item>
<item>
<key> <string>target</string> </key>
<value> <string>Click to edit the target</string> </value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="ProxyField" module="Products.ERP5Form.ProxyField"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>delegated_list</string> </key>
<value>
<list/>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>my_start_date</string> </value>
</item>
<item>
<key> <string>message_values</string> </key>
<value>
<dictionary>
<item>
<key> <string>external_validator_failed</string> </key>
<value> <string>The input failed the external validator.</string> </value>
</item>
</dictionary>
</value>
</item>
<item>
<key> <string>overrides</string> </key>
<value>
<dictionary>
<item>
<key> <string>field_id</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>form_id</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>target</string> </key>
<value> <string></string> </value>
</item>
</dictionary>
</value>
</item>
<item>
<key> <string>tales</string> </key>
<value>
<dictionary>
<item>
<key> <string>field_id</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>form_id</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>target</string> </key>
<value> <string></string> </value>
</item>
</dictionary>
</value>
</item>
<item>
<key> <string>values</string> </key>
<value>
<dictionary>
<item>
<key> <string>field_id</string> </key>
<value> <string>my_view_mode_start_date</string> </value>
</item>
<item>
<key> <string>form_id</string> </key>
<value> <string>Base_viewTradeFieldLibrary</string> </value>
</item>
<item>
<key> <string>target</string> </key>
<value> <string>Click to edit the target</string> </value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="ProxyField" module="Products.ERP5Form.ProxyField"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>delegated_list</string> </key>
<value>
<list/>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>my_stop_date</string> </value>
</item>
<item>
<key> <string>message_values</string> </key>
<value>
<dictionary>
<item>
<key> <string>external_validator_failed</string> </key>
<value> <string>The input failed the external validator.</string> </value>
</item>
</dictionary>
</value>
</item>
<item>
<key> <string>overrides</string> </key>
<value>
<dictionary>
<item>
<key> <string>field_id</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>form_id</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>target</string> </key>
<value> <string></string> </value>
</item>
</dictionary>
</value>
</item>
<item>
<key> <string>tales</string> </key>
<value>
<dictionary>
<item>
<key> <string>field_id</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>form_id</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>target</string> </key>
<value> <string></string> </value>
</item>
</dictionary>
</value>
</item>
<item>
<key> <string>values</string> </key>
<value>
<dictionary>
<item>
<key> <string>field_id</string> </key>
<value> <string>my_view_mode_stop_date</string> </value>
</item>
<item>
<key> <string>form_id</string> </key>
<value> <string>Base_viewTradeFieldLibrary</string> </value>
</item>
<item>
<key> <string>target</string> </key>
<value> <string>Click to edit the target</string> </value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
......@@ -67,10 +67,7 @@
<item>
<key> <string>hidden</string> </key>
<value>
<list>
<string>listbox_instance_tree_title</string>
<string>listbox_software_release_url</string>
</list>
<list/>
</value>
</item>
<item>
......
......@@ -12,7 +12,6 @@
<list>
<string>all_columns</string>
<string>columns</string>
<string>editable_columns</string>
<string>selection_name</string>
<string>title</string>
</list>
......@@ -103,11 +102,11 @@
<string>User</string>
</tuple>
<tuple>
<string>instance_tree_title</string>
<string>aggregate_title</string>
<string>Instance Tree</string>
</tuple>
<tuple>
<string>software_release_url</string>
<string>software_release_title</string>
<string>Software Release URL</string>
</tuple>
<tuple>
......@@ -121,21 +120,6 @@
</list>
</value>
</item>
<item>
<key> <string>editable_columns</string> </key>
<value>
<list>
<tuple>
<string>instance_tree_title</string>
<string>Instance Tree</string>
</tuple>
<tuple>
<string>software_release_url</string>
<string>Software Release URL</string>
</tuple>
</list>
</value>
</item>
<item>
<key> <string>field_id</string> </key>
<value> <string>my_list_mode_listbox</string> </value>
......
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="StringField" module="Products.Formulator.StandardFields"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>id</string> </key>
<value> <string>listbox_instance_tree_title</string> </value>
</item>
<item>
<key> <string>message_values</string> </key>
<value>
<dictionary>
<item>
<key> <string>external_validator_failed</string> </key>
<value> <string>The input failed the external validator.</string> </value>
</item>
<item>
<key> <string>required_not_found</string> </key>
<value> <string>Input is required but no input given.</string> </value>
</item>
<item>
<key> <string>too_long</string> </key>
<value> <string>Too much input was given.</string> </value>
</item>
</dictionary>
</value>
</item>
<item>
<key> <string>overrides</string> </key>
<value>
<dictionary>
<item>
<key> <string>alternate_name</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>css_class</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>default</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>description</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>display_maxwidth</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>display_width</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>editable</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>enabled</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>external_validator</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>extra</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>hidden</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>max_length</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>required</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>truncate</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>unicode</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>whitespace_preserve</string> </key>
<value> <string></string> </value>
</item>
</dictionary>
</value>
</item>
<item>
<key> <string>tales</string> </key>
<value>
<dictionary>
<item>
<key> <string>alternate_name</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>css_class</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>default</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAI=</string> </persistent>
</value>
</item>
<item>
<key> <string>description</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>display_maxwidth</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>display_width</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>editable</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>enabled</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>external_validator</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>extra</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>hidden</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>input_type</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>max_length</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>required</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>truncate</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>unicode</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>whitespace_preserve</string> </key>
<value> <string></string> </value>
</item>
</dictionary>
</value>
</item>
<item>
<key> <string>values</string> </key>
<value>
<dictionary>
<item>
<key> <string>alternate_name</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>css_class</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>default</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>description</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>display_maxwidth</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>display_width</string> </key>
<value> <int>20</int> </value>
</item>
<item>
<key> <string>editable</string> </key>
<value> <int>0</int> </value>
</item>
<item>
<key> <string>enabled</string> </key>
<value> <int>1</int> </value>
</item>
<item>
<key> <string>external_validator</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>extra</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>hidden</string> </key>
<value> <int>0</int> </value>
</item>
<item>
<key> <string>max_length</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>required</string> </key>
<value> <int>0</int> </value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string>Instance Tree</string> </value>
</item>
<item>
<key> <string>truncate</string> </key>
<value> <int>0</int> </value>
</item>
<item>
<key> <string>unicode</string> </key>
<value> <int>0</int> </value>
</item>
<item>
<key> <string>whitespace_preserve</string> </key>
<value> <int>0</int> </value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</pickle>
</record>
<record id="2" aka="AAAAAAAAAAI=">
<pickle>
<global name="TALESMethod" module="Products.Formulator.TALESField"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>_text</string> </key>
<value> <string>python: cell.UpgradeDecision_getAggregateValue() and cell.UpgradeDecision_getAggregateValue().getTitle() or \'\'</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="StringField" module="Products.Formulator.StandardFields"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>id</string> </key>
<value> <string>listbox_software_release_url</string> </value>
</item>
<item>
<key> <string>message_values</string> </key>
<value>
<dictionary>
<item>
<key> <string>external_validator_failed</string> </key>
<value> <string>The input failed the external validator.</string> </value>
</item>
<item>
<key> <string>required_not_found</string> </key>
<value> <string>Input is required but no input given.</string> </value>
</item>
<item>
<key> <string>too_long</string> </key>
<value> <string>Too much input was given.</string> </value>
</item>
</dictionary>
</value>
</item>
<item>
<key> <string>overrides</string> </key>
<value>
<dictionary>
<item>
<key> <string>alternate_name</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>css_class</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>default</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>description</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>display_maxwidth</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>display_width</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>editable</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>enabled</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>external_validator</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>extra</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>hidden</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>max_length</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>required</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>truncate</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>unicode</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>whitespace_preserve</string> </key>
<value> <string></string> </value>
</item>
</dictionary>
</value>
</item>
<item>
<key> <string>tales</string> </key>
<value>
<dictionary>
<item>
<key> <string>alternate_name</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>css_class</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>default</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAI=</string> </persistent>
</value>
</item>
<item>
<key> <string>description</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>display_maxwidth</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>display_width</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>editable</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>enabled</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>external_validator</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>extra</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>hidden</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>input_type</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>max_length</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>required</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>truncate</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>unicode</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>whitespace_preserve</string> </key>
<value> <string></string> </value>
</item>
</dictionary>
</value>
</item>
<item>
<key> <string>values</string> </key>
<value>
<dictionary>
<item>
<key> <string>alternate_name</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>css_class</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>default</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>description</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>display_maxwidth</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>display_width</string> </key>
<value> <int>20</int> </value>
</item>
<item>
<key> <string>editable</string> </key>
<value> <int>0</int> </value>
</item>
<item>
<key> <string>enabled</string> </key>
<value> <int>1</int> </value>
</item>
<item>
<key> <string>external_validator</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>extra</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>hidden</string> </key>
<value> <int>0</int> </value>
</item>
<item>
<key> <string>input_type</string> </key>
<value> <string>text</string> </value>
</item>
<item>
<key> <string>max_length</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>required</string> </key>
<value> <int>0</int> </value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string>Software Release</string> </value>
</item>
<item>
<key> <string>truncate</string> </key>
<value> <int>0</int> </value>
</item>
<item>
<key> <string>unicode</string> </key>
<value> <int>0</int> </value>
</item>
<item>
<key> <string>whitespace_preserve</string> </key>
<value> <int>0</int> </value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</pickle>
</record>
<record id="2" aka="AAAAAAAAAAI=">
<pickle>
<global name="TALESMethod" module="Products.Formulator.TALESField"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>_text</string> </key>
<value> <string>python: cell.UpgradeDecision_getAggregateValue(\'Software Release\') and cell.UpgradeDecision_getAggregateValue(\'Software Release\').getUrlString() or \'\'</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
document_list = []
for decision_line in context.contentValues():
try:
document_list.extend(
decision_line.getAggregateValueList(portal_type=document_portal_type))
except:
raise ValueError(context)
if len(document_list) > 1:
raise ValueError("It is only allowed to have more them 1 %s" % document_list)
if len(document_list) == 0:
return None
return document_list[0]
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="PythonScript" module="Products.PythonScripts.PythonScript"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>_bind_names</string> </key>
<value>
<object>
<klass>
<global name="_reconstructor" module="copy_reg"/>
</klass>
<tuple>
<global name="NameAssignments" module="Shared.DC.Scripts.Bindings"/>
<global name="object" module="__builtin__"/>
<none/>
</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>_params</string> </key>
<value> <string>document_portal_type="Instance Tree"</string> </value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>UpgradeDecision_getAggregateValue</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
portal = context.getPortalObject()
instance_tree = context.UpgradeDecision_getAggregateValue("Instance Tree")
compute_node = context.UpgradeDecision_getAggregateValue("Compute Node")
software_release = context.UpgradeDecision_getAggregateValue("Software Release")
if instance_tree is not None:
if instance_tree.getUrlString() == software_release.getUrlString():
return True
elif compute_node is not None:
full_software_release_list = [si for si in
portal.portal_catalog(
portal_type='Software Installation',
url_string=software_release.getUrlString(),
default_aggregate_uid=compute_node.getUid(),
validation_state='validated'
) if si.getSlapState() == 'start_requested']
if len(full_software_release_list) > 0:
return True
return False
from DateTime import DateTime
# Review if the upgrade is applicable before notify.
context.reviewUpgrade()
if context.getSimulationState() != 'planned':
# XXX Don't notify the ones which are not planned.
return
portal = context.getPortalObject()
person = context.getDestinationDecisionValue(portal_type="Person")
if not person:
raise ValueError("Inconsistent Upgrade Decision, No Destination Decision")
instance_tree = context.UpgradeDecision_getAggregateValue("Instance Tree")
compute_node = context.UpgradeDecision_getAggregateValue("Compute Node")
software_release = context.UpgradeDecision_getAggregateValue("Software Release")
software_product_title = software_release.getAggregateTitle(
portal_type="Software Product")
mapping_dict = {
'software_product_title': software_product_title,
'software_release_name': software_release.getTitle(),
'software_release_reference': software_release.getReference(),
'new_software_release_url': software_release.getUrlString(),
}
if instance_tree is not None:
notification_message_reference = 'slapos-upgrade-instance-tree.notification'
title = "New Upgrade available for %s" % instance_tree.getTitle()
mapping_dict.update(**{
'instance_tree_title': instance_tree.getTitle(),
'old_software_release_url': instance_tree.getUrlString()})
elif compute_node is not None:
notification_message_reference = 'slapos-upgrade-compute-node.notification'
title = "New Software available for Installation at %s" % compute_node.getTitle()
mapping_dict.update(**{'compute_node_title': compute_node.getTitle(),
'compute_node_reference': compute_node.getReference()})
if notification_message_reference is None:
raise ValueError("No Notification Message")
notification_message = portal.portal_notifications.getDocumentValue(
reference=notification_message_reference)
message = notification_message.asEntireHTML(
substitution_method_parameter_dict={'mapping_dict': mapping_dict})
context.notify(message_title=title,
message=message,
destination_relative_url=person.getRelativeUrl())
event = context.REQUEST.get("upgrade_decision_notified_item")
if event is not None:
context.confirm()
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="PythonScript" module="Products.PythonScripts.PythonScript"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>_bind_names</string> </key>
<value>
<object>
<klass>
<global name="_reconstructor" module="copy_reg"/>
</klass>
<tuple>
<global name="NameAssignments" module="Shared.DC.Scripts.Bindings"/>
<global name="object" module="__builtin__"/>
<none/>
</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>_params</string> </key>
<value> <string>**kw</string> </value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>UpgradeDecision_notify</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
from DateTime import DateTime
if context.getSimulationState() != 'stopped':
return
if not context.UpgradeDecision_isUpgradeFinished():
return
portal = context.getPortalObject()
person = context.getDestinationDecisionValue(portal_type="Person")
if not person:
raise ValueError("Inconsistent Upgrade Decision, No Destination Decision")
instance_tree = context.UpgradeDecision_getAggregateValue("Instance Tree")
compute_node = context.UpgradeDecision_getAggregateValue("Compute Node")
software_release = context.UpgradeDecision_getAggregateValue("Software Release")
software_product_title = software_release.getAggregateTitle(
portal_type="Software Product")
mapping_dict = {
'software_product_title': software_product_title,
'software_release_name': software_release.getTitle(),
'software_release_reference': software_release.getReference(),
'new_software_release_url': software_release.getUrlString(),
}
if instance_tree is not None:
notification_message_reference = 'slapos-upgrade-delivered-instance-tree.notification'
title = "Upgrade Processed for %s (%s)" % (instance_tree.getTitle(),
software_release.getReference())
mapping_dict.update(**{
'instance_tree_title': instance_tree.getTitle(),
'old_software_release_url': instance_tree.getUrlString()})
elif compute_node is not None:
notification_message_reference = 'slapos-upgrade-delivered-compute-node.notification'
title = "Upgrade processed at %s for %s" % (compute_node.getTitle(), software_release.getReference())
mapping_dict.update(**{'compute_node_title': compute_node.getTitle(),
'compute_node_reference': compute_node.getReference()})
if notification_message_reference is None:
raise ValueError("No Notification Message")
notification_message = portal.portal_notifications.getDocumentValue(
reference=notification_message_reference)
message = notification_message.asEntireHTML(
substitution_method_parameter_dict={'mapping_dict': mapping_dict})
context.notify(message_title=title,
message=message,
destination_relative_url=person.getRelativeUrl())
event = context.REQUEST.get("upgrade_decision_notified_item")
if event is not None:
context.setStopDate(DateTime())
context.deliver()
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="PythonScript" module="Products.PythonScripts.PythonScript"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>_bind_names</string> </key>
<value>
<object>
<klass>
<global name="_reconstructor" module="copy_reg"/>
</klass>
<tuple>
<global name="NameAssignments" module="Shared.DC.Scripts.Bindings"/>
<global name="object" module="__builtin__"/>
<none/>
</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>_params</string> </key>
<value> <string>**kw</string> </value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>UpgradeDecision_notifyDelivered</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
return context.requestUpgrade()
from DateTime import DateTime
upgrade_decision = context
if upgrade_decision.getSimulationState() != 'started':
# Update Decision is not on started state, Upgrade is not possible!
return
instance_tree = upgrade_decision.getAggregateValue("Instance Tree")
software_release_url = upgrade_decision.getSoftwareReleaseValue().getUrlString()
status = instance_tree.getSlapState()
if status == "start_requested":
state = "started"
elif status == "stop_requested":
state = "stopped"
elif status == "destroy_requested":
state = "destroyed"
else:
raise ValueError('Unhandled state: %s' % status)
if state == 'destroyed':
# Nothing to do
upgrade_decision.reject(
comment="Instance Tree destroyed")
else:
person = instance_tree.getDestinationSectionValue(portal_type="Person")
person.requestSoftwareInstance(
state=state,
software_release=software_release_url,
software_title=instance_tree.getTitle(),
software_type=instance_tree.getSourceReference(),
instance_xml=instance_tree.getTextContent(),
sla_xml=instance_tree.getSlaXml(),
shared=instance_tree.isRootSlave(),
project_reference=instance_tree.getFollowUpReference(),
force_software_change=True
)
upgrade_decision.stop(
comment="Upgrade Processed for the Instance Tree!")
upgrade_decision.deliver(
comment="Upgrade Processed for the Instance Tree!")
upgrade_decision = context
state = upgrade_decision.getSimulationState()
message = "Transition from state %s to %s is not permitted" % (state, requested_state)
if requested_state == "started":
if state == "confirmed":
message = "This Upgrade Decision has been requested, it will be processed in few minutes."
upgrade_decision.start()
elif requested_state == "rejected":
if state in ['confirmed', 'draft', 'planned']:
message = "Thanks Upgrade Decision has been rejected Successfully (You cannot use it anymore)."
upgrade_decision.reject()
else:
message = "Unknow Upgrade Decision state %r" % requested_state
return context.Base_translateString(message)
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="PythonScript" module="Products.PythonScripts.PythonScript"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>_bind_names</string> </key>
<value>
<object>
<klass>
<global name="_reconstructor" module="copy_reg"/>
</klass>
<tuple>
<global name="NameAssignments" module="Shared.DC.Scripts.Bindings"/>
<global name="object" module="__builtin__"/>
<none/>
</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>_params</string> </key>
<value> <string>requested_state</string> </value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>UpgradeDecision_requestChangeState</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
......@@ -53,9 +53,7 @@
<item>
<key> <string>bottom</string> </key>
<value>
<list>
<string>listbox</string>
</list>
<list/>
</value>
</item>
<item>
......@@ -67,11 +65,7 @@
<item>
<key> <string>hidden</string> </key>
<value>
<list>
<string>listbox_aggregate_title_list</string>
<string>listbox_reference</string>
<string>listbox_stop_date</string>
</list>
<list/>
</value>
</item>
<item>
......@@ -81,6 +75,8 @@
<string>my_title</string>
<string>my_reference</string>
<string>my_resource_title</string>
<string>my_variation_category_list</string>
<string>my_aggregate_title</string>
</list>
</value>
</item>
......
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="ProxyField" module="Products.ERP5Form.ProxyField"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>delegated_list</string> </key>
<value>
<list>
<string>columns</string>
<string>editable_columns</string>
<string>list_method</string>
<string>report_root_list</string>
<string>sort</string>
<string>title</string>
</list>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>listbox</string> </value>
</item>
<item>
<key> <string>message_values</string> </key>
<value>
<dictionary>
<item>
<key> <string>external_validator_failed</string> </key>
<value> <string>The input failed the external validator.</string> </value>
</item>
</dictionary>
</value>
</item>
<item>
<key> <string>overrides</string> </key>
<value>
<dictionary>
<item>
<key> <string>field_id</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>form_id</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>target</string> </key>
<value> <string></string> </value>
</item>
</dictionary>
</value>
</item>
<item>
<key> <string>tales</string> </key>
<value>
<dictionary>
<item>
<key> <string>field_id</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>form_id</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>target</string> </key>
<value> <string></string> </value>
</item>
</dictionary>
</value>
</item>
<item>
<key> <string>values</string> </key>
<value>
<dictionary>
<item>
<key> <string>columns</string> </key>
<value>
<list>
<tuple>
<string>title</string>
<string>Title</string>
</tuple>
<tuple>
<string>resource_title</string>
<string>Product or Service</string>
</tuple>
<tuple>
<string>aggregate_title_list</string>
<string>Items</string>
</tuple>
<tuple>
<string>stop_date</string>
<string>Delivery Date</string>
</tuple>
</list>
</value>
</item>
<item>
<key> <string>editable_columns</string> </key>
<value>
<list>
<tuple>
<string>aggregate_title_list</string>
<string>Items</string>
</tuple>
<tuple>
<string>stop_date</string>
<string>Delivery Date</string>
</tuple>
</list>
</value>
</item>
<item>
<key> <string>field_id</string> </key>
<value> <string>my_view_mode_listbox</string> </value>
</item>
<item>
<key> <string>form_id</string> </key>
<value> <string>Base_viewTradeFieldLibrary</string> </value>
</item>
<item>
<key> <string>list_method</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAI=</string> </persistent>
</value>
</item>
<item>
<key> <string>report_root_list</string> </key>
<value>
<list/>
</value>
</item>
<item>
<key> <string>sort</string> </key>
<value>
<list/>
</value>
</item>
<item>
<key> <string>target</string> </key>
<value> <string>Click to edit the target</string> </value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string>Upgrade Decisions</string> </value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</pickle>
</record>
<record id="2" aka="AAAAAAAAAAI=">
<pickle>
<global name="Method" module="Products.Formulator.MethodField"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>method_name</string> </key>
<value> <string>contentValues</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="ProxyField" module="Products.ERP5Form.ProxyField"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>delegated_list</string> </key>
<value>
<list/>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>listbox_aggregate_title_list</string> </value>
</item>
<item>
<key> <string>message_values</string> </key>
<value>
<dictionary>
<item>
<key> <string>external_validator_failed</string> </key>
<value> <string>The input failed the external validator.</string> </value>
</item>
</dictionary>
</value>
</item>
<item>
<key> <string>overrides</string> </key>
<value>
<dictionary>
<item>
<key> <string>field_id</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>form_id</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>target</string> </key>
<value> <string></string> </value>
</item>
</dictionary>
</value>
</item>
<item>
<key> <string>tales</string> </key>
<value>
<dictionary>
<item>
<key> <string>field_id</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>form_id</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>target</string> </key>
<value> <string></string> </value>
</item>
</dictionary>
</value>
</item>
<item>
<key> <string>values</string> </key>
<value>
<dictionary>
<item>
<key> <string>field_id</string> </key>
<value> <string>my_view_mode_listbox_aggregate_title_list</string> </value>
</item>
<item>
<key> <string>form_id</string> </key>
<value> <string>Base_viewTradeFieldLibrary</string> </value>
</item>
<item>
<key> <string>target</string> </key>
<value> <string>Click to edit the target</string> </value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="ProxyField" module="Products.ERP5Form.ProxyField"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>delegated_list</string> </key>
<value>
<list/>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>listbox_reference</string> </value>
</item>
<item>
<key> <string>message_values</string> </key>
<value>
<dictionary>
<item>
<key> <string>external_validator_failed</string> </key>
<value> <string>The input failed the external validator.</string> </value>
</item>
</dictionary>
</value>
</item>
<item>
<key> <string>overrides</string> </key>
<value>
<dictionary>
<item>
<key> <string>field_id</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>form_id</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>target</string> </key>
<value> <string></string> </value>
</item>
</dictionary>
</value>
</item>
<item>
<key> <string>tales</string> </key>
<value>
<dictionary>
<item>
<key> <string>field_id</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>form_id</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>target</string> </key>
<value> <string></string> </value>
</item>
</dictionary>
</value>
</item>
<item>
<key> <string>values</string> </key>
<value>
<dictionary>
<item>
<key> <string>field_id</string> </key>
<value> <string>my_view_mode_listbox_reference</string> </value>
</item>
<item>
<key> <string>form_id</string> </key>
<value> <string>Base_viewTradeFieldLibrary</string> </value>
</item>
<item>
<key> <string>target</string> </key>
<value> <string>Click to edit the target</string> </value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="ProxyField" module="Products.ERP5Form.ProxyField"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>delegated_list</string> </key>
<value>
<list>
<string>editable</string>
</list>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>listbox_stop_date</string> </value>
</item>
<item>
<key> <string>message_values</string> </key>
<value>
<dictionary>
<item>
<key> <string>external_validator_failed</string> </key>
<value> <string>The input failed the external validator.</string> </value>
</item>
</dictionary>
</value>
</item>
<item>
<key> <string>overrides</string> </key>
<value>
<dictionary>
<item>
<key> <string>field_id</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>form_id</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>target</string> </key>
<value> <string></string> </value>
</item>
</dictionary>
</value>
</item>
<item>
<key> <string>tales</string> </key>
<value>
<dictionary>
<item>
<key> <string>field_id</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>form_id</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>target</string> </key>
<value> <string></string> </value>
</item>
</dictionary>
</value>
</item>
<item>
<key> <string>values</string> </key>
<value>
<dictionary>
<item>
<key> <string>editable</string> </key>
<value> <int>0</int> </value>
</item>
<item>
<key> <string>field_id</string> </key>
<value> <string>my_view_mode_listbox_stop_date</string> </value>
</item>
<item>
<key> <string>form_id</string> </key>
<value> <string>Base_viewTradeFieldLibrary</string> </value>
</item>
<item>
<key> <string>target</string> </key>
<value> <string>Click to edit the target</string> </value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
......@@ -10,14 +10,14 @@
<key> <string>delegated_list</string> </key>
<value>
<list>
<string>display_width</string>
<string>editable</string>
<string>portal_type</string>
<string>title</string>
</list>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>my_reference</string> </value>
<value> <string>my_aggregate_title</string> </value>
</item>
<item>
<key> <string>message_values</string> </key>
......@@ -65,20 +65,27 @@
<value>
<dictionary>
<item>
<key> <string>display_width</string> </key>
<value> <int>20</int> </value>
<key> <string>field_id</string> </key>
<value> <string>my_relation_field</string> </value>
</item>
<item>
<key> <string>editable</string> </key>
<value> <int>0</int> </value>
<key> <string>form_id</string> </key>
<value> <string>Base_viewFieldLibrary</string> </value>
</item>
<item>
<key> <string>field_id</string> </key>
<value> <string>my_view_mode_reference</string> </value>
<key> <string>portal_type</string> </key>
<value>
<list>
<tuple>
<string>Instance Tree</string>
<string>Instance Tree</string>
</tuple>
</list>
</value>
</item>
<item>
<key> <string>form_id</string> </key>
<value> <string>Base_viewFieldLibrary</string> </value>
<key> <string>title</string> </key>
<value> <string>Instance Tree</string> </value>
</item>
</dictionary>
</value>
......
......@@ -10,6 +10,10 @@
<key> <string>delegated_list</string> </key>
<value>
<list>
<string>columns</string>
<string>description</string>
<string>portal_type</string>
<string>proxy_listbox_ids</string>
<string>title</string>
</list>
</value>
......@@ -41,10 +45,6 @@
<key> <string>form_id</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>target</string> </key>
<value> <string></string> </value>
</item>
</dictionary>
</value>
</item>
......@@ -60,10 +60,6 @@
<key> <string>form_id</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>target</string> </key>
<value> <string></string> </value>
</item>
</dictionary>
</value>
</item>
......@@ -71,17 +67,90 @@
<key> <string>values</string> </key>
<value>
<dictionary>
<item>
<key> <string>columns</string> </key>
<value>
<list>
<tuple>
<string>title</string>
<string>Usual Name</string>
</tuple>
<tuple>
<string>description</string>
<string>Description</string>
</tuple>
<tuple>
<string>getDefaultTelephoneText</string>
<string>Telephone</string>
</tuple>
<tuple>
<string>getDefaultAddressText</string>
<string>Address</string>
</tuple>
<tuple>
<string>translated_portal_type</string>
<string>Type</string>
</tuple>
<tuple>
<string>translated_validation_state_title</string>
<string>State</string>
</tuple>
</list>
</value>
</item>
<item>
<key> <string>description</string> </key>
<value> <string>The organisation or person who is delivered goods or services in this operation</string> </value>
</item>
<item>
<key> <string>field_id</string> </key>
<value> <string>my_view_mode_destination_title</string> </value>
<value> <string>my_relation_field</string> </value>
</item>
<item>
<key> <string>form_id</string> </key>
<value> <string>Base_viewTradeFieldLibrary</string> </value>
<value> <string>Base_viewFieldLibrary</string> </value>
</item>
<item>
<key> <string>portal_type</string> </key>
<value>
<list>
<tuple>
<string>Organisation</string>
<string>Organisation</string>
</tuple>
<tuple>
<string>Person</string>
<string>Person</string>
</tuple>
</list>
</value>
</item>
<item>
<key> <string>target</string> </key>
<value> <string>Click to edit the target</string> </value>
<key> <string>proxy_listbox_ids</string> </key>
<value>
<list>
<tuple>
<string>Base_viewRelatedObjectListBase/listbox</string>
<string>All</string>
</tuple>
<tuple>
<string>ERP5Site_viewClientNodeList/listbox</string>
<string>Clients</string>
</tuple>
<tuple>
<string>ERP5Site_viewSupplierNodeList/listbox</string>
<string>Suppliers</string>
</tuple>
<tuple>
<string>OrganisationModule_viewOrganisationList/listbox</string>
<string>Organisations</string>
</tuple>
<tuple>
<string>PersonModule_viewPersonList/listbox</string>
<string>Persons</string>
</tuple>
</list>
</value>
</item>
<item>
<key> <string>title</string> </key>
......
......@@ -10,6 +10,10 @@
<key> <string>delegated_list</string> </key>
<value>
<list>
<string>columns</string>
<string>description</string>
<string>portal_type</string>
<string>proxy_listbox_ids</string>
<string>title</string>
</list>
</value>
......@@ -41,10 +45,6 @@
<key> <string>form_id</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>target</string> </key>
<value> <string></string> </value>
</item>
</dictionary>
</value>
</item>
......@@ -60,10 +60,6 @@
<key> <string>form_id</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>target</string> </key>
<value> <string></string> </value>
</item>
</dictionary>
</value>
</item>
......@@ -71,17 +67,90 @@
<key> <string>values</string> </key>
<value>
<dictionary>
<item>
<key> <string>columns</string> </key>
<value>
<list>
<tuple>
<string>title</string>
<string>Usual Name</string>
</tuple>
<tuple>
<string>description</string>
<string>Description</string>
</tuple>
<tuple>
<string>getDefaultTelephoneText</string>
<string>Telephone</string>
</tuple>
<tuple>
<string>getDefaultAddressText</string>
<string>Address</string>
</tuple>
<tuple>
<string>translated_portal_type</string>
<string>Type</string>
</tuple>
<tuple>
<string>translated_validation_state_title</string>
<string>State</string>
</tuple>
</list>
</value>
</item>
<item>
<key> <string>description</string> </key>
<value> <string>The organisation or person who is delivered goods or services in this operation</string> </value>
</item>
<item>
<key> <string>field_id</string> </key>
<value> <string>my_view_mode_destination_title</string> </value>
<value> <string>my_relation_field</string> </value>
</item>
<item>
<key> <string>form_id</string> </key>
<value> <string>Base_viewTradeFieldLibrary</string> </value>
<value> <string>Base_viewFieldLibrary</string> </value>
</item>
<item>
<key> <string>portal_type</string> </key>
<value>
<list>
<tuple>
<string>Organisation</string>
<string>Organisation</string>
</tuple>
<tuple>
<string>Person</string>
<string>Person</string>
</tuple>
</list>
</value>
</item>
<item>
<key> <string>target</string> </key>
<value> <string>Click to edit the target</string> </value>
<key> <string>proxy_listbox_ids</string> </key>
<value>
<list>
<tuple>
<string>Base_viewRelatedObjectListBase/listbox</string>
<string>All</string>
</tuple>
<tuple>
<string>ERP5Site_viewClientNodeList/listbox</string>
<string>Clients</string>
</tuple>
<tuple>
<string>ERP5Site_viewSupplierNodeList/listbox</string>
<string>Suppliers</string>
</tuple>
<tuple>
<string>OrganisationModule_viewOrganisationList/listbox</string>
<string>Organisations</string>
</tuple>
<tuple>
<string>PersonModule_viewPersonList/listbox</string>
<string>Persons</string>
</tuple>
</list>
</value>
</item>
<item>
<key> <string>title</string> </key>
......
......@@ -39,10 +39,6 @@
<key> <string>form_id</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>target</string> </key>
<value> <string></string> </value>
</item>
</dictionary>
</value>
</item>
......@@ -58,10 +54,6 @@
<key> <string>form_id</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>target</string> </key>
<value> <string></string> </value>
</item>
</dictionary>
</value>
</item>
......@@ -75,11 +67,7 @@
</item>
<item>
<key> <string>form_id</string> </key>
<value> <string>Base_viewTradeFieldLibrary</string> </value>
</item>
<item>
<key> <string>target</string> </key>
<value> <string>Click to edit the target</string> </value>
<value> <string>Base_viewFieldLibrary</string> </value>
</item>
</dictionary>
</value>
......
......@@ -9,7 +9,14 @@
<item>
<key> <string>delegated_list</string> </key>
<value>
<list/>
<list>
<string>columns</string>
<string>description</string>
<string>enabled</string>
<string>portal_type</string>
<string>proxy_listbox_ids</string>
<string>title</string>
</list>
</value>
</item>
<item>
......@@ -39,10 +46,6 @@
<key> <string>form_id</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>target</string> </key>
<value> <string></string> </value>
</item>
</dictionary>
</value>
</item>
......@@ -50,6 +53,18 @@
<key> <string>tales</string> </key>
<value>
<dictionary>
<item>
<key> <string>columns</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>description</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>enabled</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>field_id</string> </key>
<value> <string></string> </value>
......@@ -59,7 +74,17 @@
<value> <string></string> </value>
</item>
<item>
<key> <string>target</string> </key>
<key> <string>portal_type</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAI=</string> </persistent>
</value>
</item>
<item>
<key> <string>proxy_listbox_ids</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string></string> </value>
</item>
</dictionary>
......@@ -69,17 +94,98 @@
<key> <string>values</string> </key>
<value>
<dictionary>
<item>
<key> <string>columns</string> </key>
<value>
<list>
<tuple>
<string>title</string>
<string>Title</string>
</tuple>
<tuple>
<string>reference</string>
<string>Reference</string>
</tuple>
<tuple>
<string>description</string>
<string>Description</string>
</tuple>
<tuple>
<string>default_use_title</string>
<string>Use</string>
</tuple>
<tuple>
<string>translated_portal_type</string>
<string>Type</string>
</tuple>
<tuple>
<string>translated_validation_state_title</string>
<string>State</string>
</tuple>
</list>
</value>
</item>
<item>
<key> <string>description</string> </key>
<value> <string>A resource in ERP5 can be a product or a service. This term will be found in orders for instance, or accounting and inventories.</string> </value>
</item>
<item>
<key> <string>enabled</string> </key>
<value> <int>1</int> </value>
</item>
<item>
<key> <string>field_id</string> </key>
<value> <string>my_view_mode_resource_title</string> </value>
<value> <string>my_relation_field</string> </value>
</item>
<item>
<key> <string>form_id</string> </key>
<value> <string>Base_viewTradeFieldLibrary</string> </value>
<value> <string>Base_viewFieldLibrary</string> </value>
</item>
<item>
<key> <string>portal_type</string> </key>
<value>
<list>
<tuple>
<string>Resource</string>
<string>Resource</string>
</tuple>
</list>
</value>
</item>
<item>
<key> <string>proxy_listbox_ids</string> </key>
<value>
<list>
<tuple>
<string>Base_viewRelatedObjectListBase/listbox</string>
<string>All</string>
</tuple>
<tuple>
<string>ERP5Site_viewSaleResourceList/listbox</string>
<string>Sales</string>
</tuple>
<tuple>
<string>ERP5Site_viewInternalResourceList/listbox</string>
<string>Internal</string>
</tuple>
<tuple>
<string>ERP5Site_viewPurchaseResourceList/listbox</string>
<string>Purchase</string>
</tuple>
<tuple>
<string>ProductModule_viewProductList/listbox</string>
<string>Products</string>
</tuple>
<tuple>
<string>ServiceModule_viewServiceList/listbox</string>
<string>Services</string>
</tuple>
</list>
</value>
</item>
<item>
<key> <string>target</string> </key>
<value> <string>Click to edit the target</string> </value>
<key> <string>title</string> </key>
<value> <string>Product or Service</string> </value>
</item>
</dictionary>
</value>
......@@ -87,4 +193,17 @@
</dictionary>
</pickle>
</record>
<record id="2" aka="AAAAAAAAAAI=">
<pickle>
<global name="TALESMethod" module="Products.Formulator.TALESField"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>_text</string> </key>
<value> <string>python: [(x, x) for x in (list(here.getPortalProductTypeList()) + list(here.getPortalServiceTypeList()))]</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
......@@ -10,6 +10,10 @@
<key> <string>delegated_list</string> </key>
<value>
<list>
<string>columns</string>
<string>description</string>
<string>portal_type</string>
<string>proxy_listbox_ids</string>
<string>title</string>
</list>
</value>
......@@ -41,10 +45,6 @@
<key> <string>form_id</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>target</string> </key>
<value> <string></string> </value>
</item>
</dictionary>
</value>
</item>
......@@ -60,10 +60,6 @@
<key> <string>form_id</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>target</string> </key>
<value> <string></string> </value>
</item>
</dictionary>
</value>
</item>
......@@ -71,17 +67,90 @@
<key> <string>values</string> </key>
<value>
<dictionary>
<item>
<key> <string>columns</string> </key>
<value>
<list>
<tuple>
<string>title</string>
<string>Usual Name</string>
</tuple>
<tuple>
<string>description</string>
<string>Description</string>
</tuple>
<tuple>
<string>getDefaultTelephoneText</string>
<string>Telephone</string>
</tuple>
<tuple>
<string>getDefaultAddressText</string>
<string>Address</string>
</tuple>
<tuple>
<string>translated_portal_type</string>
<string>Type</string>
</tuple>
<tuple>
<string>translated_validation_state_title</string>
<string>State</string>
</tuple>
</list>
</value>
</item>
<item>
<key> <string>description</string> </key>
<value> <string>The organisation or person who sends merchandise or provides service.</string> </value>
</item>
<item>
<key> <string>field_id</string> </key>
<value> <string>my_view_mode_source_title</string> </value>
<value> <string>my_relation_field</string> </value>
</item>
<item>
<key> <string>form_id</string> </key>
<value> <string>Base_viewTradeFieldLibrary</string> </value>
<value> <string>Base_viewFieldLibrary</string> </value>
</item>
<item>
<key> <string>portal_type</string> </key>
<value>
<list>
<tuple>
<string>Organisation</string>
<string>Organisation</string>
</tuple>
<tuple>
<string>Person</string>
<string>Person</string>
</tuple>
</list>
</value>
</item>
<item>
<key> <string>target</string> </key>
<value> <string>Click to edit the target</string> </value>
<key> <string>proxy_listbox_ids</string> </key>
<value>
<list>
<tuple>
<string>Base_viewRelatedObjectListBase/listbox</string>
<string>All</string>
</tuple>
<tuple>
<string>ERP5Site_viewSupplierNodeList/listbox</string>
<string>Suppliers</string>
</tuple>
<tuple>
<string>ERP5Site_viewClientNodeList/listbox</string>
<string>Clients</string>
</tuple>
<tuple>
<string>OrganisationModule_viewOrganisationList/listbox</string>
<string>Organisations</string>
</tuple>
<tuple>
<string>PersonModule_viewPersonList/listbox</string>
<string>Persons</string>
</tuple>
</list>
</value>
</item>
<item>
<key> <string>title</string> </key>
......
......@@ -10,6 +10,7 @@
<key> <string>delegated_list</string> </key>
<value>
<list>
<string>description</string>
<string>title</string>
</list>
</value>
......@@ -41,10 +42,6 @@
<key> <string>form_id</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>target</string> </key>
<value> <string></string> </value>
</item>
</dictionary>
</value>
</item>
......@@ -60,10 +57,6 @@
<key> <string>form_id</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>target</string> </key>
<value> <string></string> </value>
</item>
</dictionary>
</value>
</item>
......@@ -72,16 +65,16 @@
<value>
<dictionary>
<item>
<key> <string>field_id</string> </key>
<value> <string>my_view_mode_start_date</string> </value>
<key> <string>description</string> </key>
<value> <string>The date at which products were shipped or the date at which a service started.</string> </value>
</item>
<item>
<key> <string>form_id</string> </key>
<value> <string>Base_viewTradeFieldLibrary</string> </value>
<key> <string>field_id</string> </key>
<value> <string>my_date_time_field</string> </value>
</item>
<item>
<key> <string>target</string> </key>
<value> <string>Click to edit the target</string> </value>
<key> <string>form_id</string> </key>
<value> <string>Base_viewFieldLibrary</string> </value>
</item>
<item>
<key> <string>title</string> </key>
......
......@@ -10,6 +10,7 @@
<key> <string>delegated_list</string> </key>
<value>
<list>
<string>description</string>
<string>title</string>
</list>
</value>
......@@ -41,10 +42,6 @@
<key> <string>form_id</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>target</string> </key>
<value> <string></string> </value>
</item>
</dictionary>
</value>
</item>
......@@ -60,10 +57,6 @@
<key> <string>form_id</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>target</string> </key>
<value> <string></string> </value>
</item>
</dictionary>
</value>
</item>
......@@ -72,16 +65,16 @@
<value>
<dictionary>
<item>
<key> <string>field_id</string> </key>
<value> <string>my_view_mode_stop_date</string> </value>
<key> <string>description</string> </key>
<value> <string>The date at which shipped products were delivered or the date at which a service was completed.</string> </value>
</item>
<item>
<key> <string>form_id</string> </key>
<value> <string>Base_viewTradeFieldLibrary</string> </value>
<key> <string>field_id</string> </key>
<value> <string>my_date_time_field</string> </value>
</item>
<item>
<key> <string>target</string> </key>
<value> <string>Click to edit the target</string> </value>
<key> <string>form_id</string> </key>
<value> <string>Base_viewFieldLibrary</string> </value>
</item>
<item>
<key> <string>title</string> </key>
......
......@@ -39,10 +39,6 @@
<key> <string>form_id</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>target</string> </key>
<value> <string></string> </value>
</item>
</dictionary>
</value>
</item>
......@@ -58,10 +54,6 @@
<key> <string>form_id</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>target</string> </key>
<value> <string></string> </value>
</item>
</dictionary>
</value>
</item>
......@@ -71,15 +63,11 @@
<dictionary>
<item>
<key> <string>field_id</string> </key>
<value> <string>my_view_mode_translated_simulation_state_title</string> </value>
<value> <string>my_view_mode_translated_workflow_state_title</string> </value>
</item>
<item>
<key> <string>form_id</string> </key>
<value> <string>Base_viewTradeFieldLibrary</string> </value>
</item>
<item>
<key> <string>target</string> </key>
<value> <string>Click to edit the target</string> </value>
<value> <string>Base_viewFieldLibrary</string> </value>
</item>
</dictionary>
</value>
......
......@@ -10,15 +10,17 @@
<key> <string>delegated_list</string> </key>
<value>
<list>
<string>default</string>
<string>editable</string>
<string>hash_script_id</string>
<string>items</string>
<string>size</string>
<string>title</string>
</list>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>my_upgrade_scope</string> </value>
<value> <string>my_variation_category_list</string> </value>
</item>
<item>
<key> <string>message_values</string> </key>
......@@ -43,10 +45,6 @@
<key> <string>form_id</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>target</string> </key>
<value> <string></string> </value>
</item>
</dictionary>
</value>
</item>
......@@ -54,12 +52,6 @@
<key> <string>tales</string> </key>
<value>
<dictionary>
<item>
<key> <string>default</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAI=</string> </persistent>
</value>
</item>
<item>
<key> <string>field_id</string> </key>
<value> <string></string> </value>
......@@ -71,17 +63,9 @@
<item>
<key> <string>items</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAM=</string> </persistent>
<persistent> <string encoding="base64">AAAAAAAAAAI=</string> </persistent>
</value>
</item>
<item>
<key> <string>target</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string></string> </value>
</item>
</dictionary>
</value>
</item>
......@@ -90,17 +74,21 @@
<value>
<dictionary>
<item>
<key> <string>default</string> </key>
<value> <string></string> </value>
<key> <string>editable</string> </key>
<value> <int>0</int> </value>
</item>
<item>
<key> <string>field_id</string> </key>
<value> <string>my_dialog_mode_category</string> </value>
<value> <string>my_parallel_list_field</string> </value>
</item>
<item>
<key> <string>form_id</string> </key>
<value> <string>Base_viewFieldLibrary</string> </value>
</item>
<item>
<key> <string>hash_script_id</string> </key>
<value> <string>Base_getMultiListFieldPropertyDictList</string> </value>
</item>
<item>
<key> <string>items</string> </key>
<value>
......@@ -108,12 +96,12 @@
</value>
</item>
<item>
<key> <string>target</string> </key>
<value> <string>Click to edit the target</string> </value>
<key> <string>size</string> </key>
<value> <int>5</int> </value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string>Upgrade Scope</string> </value>
<value> <string>Variation</string> </value>
</item>
</dictionary>
</value>
......@@ -129,20 +117,7 @@
<dictionary>
<item>
<key> <string>_text</string> </key>
<value> <string>python: context.getUpgradeScope()</string> </value>
</item>
</dictionary>
</pickle>
</record>
<record id="3" aka="AAAAAAAAAAM=">
<pickle>
<global name="TALESMethod" module="Products.Formulator.TALESField"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>_text</string> </key>
<value> <string>python: getattr(here.portal_categories[field.getId().replace(\'my_\', \'\', 1)], preferences.getPreference(\'preferred_category_child_item_list_method_id\', \'getCategoryChildCompactLogicalPathItemList\'))(local_sort_id=(\'int_index\', \'translated_title\'), checked_permission=\'View\')</string> </value>
<value> <string>python: here.getVariationRangeCategoryItemList(display_base_category=0, display_id=\'translated_title\')</string> </value>
</item>
</dictionary>
</pickle>
......
# -*- coding: utf-8 -*-
##############################################################################
#
# Copyright (c) 2002-2012 Nexedi SA and Contributors. All Rights Reserved.
#
# 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#
##############################################################################
from erp5.component.test.SlapOSTestCaseMixin import SlapOSTestCaseMixin, simulate
#from zExceptions import Unauthorized
import transaction
class TestSlapOSCoreProjectSlapInterfaceWorkflow(SlapOSTestCaseMixin):
def afterSetUp(self):
SlapOSTestCaseMixin.afterSetUp(self)
portal = self.getPortalObject()
person_user = self.makePerson()
self.tic()
self.login()
self.compute_node = self.portal.compute_node_module.template_compute_node\
.Base_createCloneDocument(batch_mode=1)
new_id = self.generateNewId()
self.compute_node.edit(
title="compute node %s" % (new_id, ),
reference="TESTCOMP-%s" % (new_id, ),
source_administration=person_user.getRelativeUrl()
)
self.compute_node.validate()
self.upgrade_decision = portal.upgrade_decision_module.newContent(
portal_type="Upgrade Decision",
)
# Value set by the init
self.assertTrue(self.upgrade_decision.getReference().startswith("UD-"),
"Reference don't start with UD- : %s" % self.upgrade_decision.getReference())
self.software_release = self._makeSoftwareRelease()
self.tic()
def _addUpgradeLine(self, aggregate):
self.upgrade_decision.newContent(
portal_type="Upgrade Decision Line",
aggregate_value_list=[self.software_release,
aggregate]
)
def beforeTearDown(self):
transaction.abort()
def test_upgrade_decision_approveRegistration_no_line(self):
self.assertRaises(ValueError, self.upgrade_decision.approveRegistration)
def test_upgrade_decision_approveRegistration_no_aggregate(self):
self.upgrade_decision.newContent(
portal_type="Upgrade Decision Line",
aggregate=self.software_release.getRelativeUrl()
)
self.assertRaises(ValueError, self.upgrade_decision.approveRegistration)
def test_upgrade_decision_approveRegistration_no_upgrade_scope(self):
self._addUpgradeLine(self.compute_node)
self.assertRaises(TypeError, self.upgrade_decision.approveRegistration)
def test_upgrade_decision_approveRegistration_computer(self):
self._addUpgradeLine(self.compute_node)
self.upgrade_decision.approveRegistration(
upgrade_scope="ask_confirmation"
)
self.assertEqual("planned",
self.upgrade_decision.getSimulationState())
self.commit()
tag = "%s_requestUpgradeDecisionCreation_inProgress" % self.compute_node.getUid()
self.assertEqual(2,
self.portal.portal_activities.countMessageWithTag(tag))
# Call again does nothing
self.upgrade_decision.approveRegistration(
upgrade_scope="ask_confirmation"
)
self.assertEqual("planned",
self.upgrade_decision.getSimulationState())
self.commit()
tag = "%s_requestUpgradeDecisionCreation_inProgress" % self.compute_node.getUid()
self.assertEqual(2,
self.portal.portal_activities.countMessageWithTag(tag))
self.tic()
# Call again does nothing again
self.upgrade_decision.approveRegistration(
upgrade_scope="ask_confirmation"
)
self.assertEqual("planned",
self.upgrade_decision.getSimulationState())
self.commit()
tag = "%s_requestUpgradeDecisionCreation_inProgress" % self.compute_node.getUid()
self.assertEqual(2,
self.portal.portal_activities.countMessageWithTag(tag))
def test_upgrade_decision_approveRegistration_instance_tree(self):
self._makeTree()
self._addUpgradeLine(self.instance_tree)
self.upgrade_decision.approveRegistration(
upgrade_scope="ask_confirmation"
)
self.assertEqual("planned",
self.upgrade_decision.getSimulationState())
self.commit()
tag = "%s_requestUpgradeDecisionCreation_inProgress" % self.instance_tree.getUid()
self.assertEqual(2,
self.portal.portal_activities.countMessageWithTag(tag))
# Call again does nothing
self.upgrade_decision.approveRegistration(
upgrade_scope="ask_confirmation"
)
self.assertEqual("planned",
self.upgrade_decision.getSimulationState())
self.commit()
tag = "%s_requestUpgradeDecisionCreation_inProgress" % self.instance_tree.getUid()
self.assertEqual(2,
self.portal.portal_activities.countMessageWithTag(tag))
self.tic()
# Call again does nothing again
self.upgrade_decision.approveRegistration(
upgrade_scope="ask_confirmation"
)
self.assertEqual("planned",
self.upgrade_decision.getSimulationState())
self.commit()
tag = "%s_requestUpgradeDecisionCreation_inProgress" % self.instance_tree.getUid()
self.assertEqual(2,
self.portal.portal_activities.countMessageWithTag(tag))
def test_upgrade_decision_approveRegistration_computer_auto(self):
self._addUpgradeLine(self.compute_node)
self.upgrade_decision.approveRegistration(
upgrade_scope="auto"
)
self.assertEqual("started",
self.upgrade_decision.getSimulationState())
self.commit()
tag = "%s_requestUpgradeDecisionCreation_inProgress" % self.compute_node.getUid()
self.assertEqual(2,
self.portal.portal_activities.countMessageWithTag(tag))
# Call again does nothing
self.upgrade_decision.approveRegistration(
upgrade_scope="auto"
)
self.assertEqual("started",
self.upgrade_decision.getSimulationState())
self.commit()
tag = "%s_requestUpgradeDecisionCreation_inProgress" % self.compute_node.getUid()
self.assertEqual(2,
self.portal.portal_activities.countMessageWithTag(tag))
self.tic()
# Call again does nothing again
self.upgrade_decision.approveRegistration(
upgrade_scope="auto"
)
self.assertEqual("started",
self.upgrade_decision.getSimulationState())
self.commit()
tag = "%s_requestUpgradeDecisionCreation_inProgress" % self.compute_node.getUid()
self.assertEqual(2,
self.portal.portal_activities.countMessageWithTag(tag))
def test_upgrade_decision_approveRegistration_instance_tree_auto(self):
self._makeTree()
self._addUpgradeLine(self.instance_tree)
self.upgrade_decision.approveRegistration(
upgrade_scope="auto"
)
self.assertEqual("started",
self.upgrade_decision.getSimulationState())
self.commit()
tag = "%s_requestUpgradeDecisionCreation_inProgress" % self.instance_tree.getUid()
self.assertEqual(2,
self.portal.portal_activities.countMessageWithTag(tag))
# Call again does nothing
self.upgrade_decision.approveRegistration(
upgrade_scope="auto"
)
self.assertEqual("started",
self.upgrade_decision.getSimulationState())
self.commit()
tag = "%s_requestUpgradeDecisionCreation_inProgress" % self.instance_tree.getUid()
self.assertEqual(2,
self.portal.portal_activities.countMessageWithTag(tag))
self.tic()
# Call again does nothing again
# Call again does nothing
self.upgrade_decision.approveRegistration(
upgrade_scope="auto"
)
self.assertEqual("started",
self.upgrade_decision.getSimulationState())
self.commit()
tag = "%s_requestUpgradeDecisionCreation_inProgress" % self.instance_tree.getUid()
self.assertEqual(2,
self.portal.portal_activities.countMessageWithTag(tag))
def test_upgrade_decision_reviewRegistration_no_software_release_url(self):
self.assertRaises(TypeError, self.upgrade_decision.reviewRegistration)
def test_upgrade_decision_reviewRegistration_draft(self):
# Do nothing as draft
software_release = self.generateNewSoftwareReleaseUrl()
self.upgrade_decision.reviewRegistration(software_release_url=software_release)
def test_upgrade_decision_reviewRegistration(self):
self._addUpgradeLine(self.compute_node)
software_release = self.generateNewSoftwareReleaseUrl()
self.upgrade_decision.reviewRegistration(
software_release_url=software_release)
self.assertEqual("draft",
self.upgrade_decision.getSimulationState())
self.upgrade_decision.plan()
self.tic()
self.upgrade_decision.reviewRegistration(
software_release_url=software_release)
self.assertEqual("cancelled",
self.upgrade_decision.getSimulationState())
def test_upgrade_decision_reviewRegistration_confirm(self):
self._addUpgradeLine(self.compute_node)
software_release = self.generateNewSoftwareReleaseUrl()
self.upgrade_decision.reviewRegistration(
software_release_url=software_release)
self.assertEqual("draft",
self.upgrade_decision.getSimulationState())
self.upgrade_decision.confirm()
self.tic()
self.upgrade_decision.reviewRegistration(
software_release_url=software_release)
self.assertEqual("cancelled",
self.upgrade_decision.getSimulationState())
def test_upgrade_decision_reviewRegistration_rejected(self):
self._addUpgradeLine(self.compute_node)
software_release = self.generateNewSoftwareReleaseUrl()
self.upgrade_decision.reviewRegistration(
software_release_url=software_release)
self.assertEqual("draft",
self.upgrade_decision.getSimulationState())
self.upgrade_decision.reject()
self.tic()
self.upgrade_decision.reviewRegistration(
software_release_url=software_release)
self.assertEqual("rejected",
self.upgrade_decision.getSimulationState())
def test_upgrade_decision_reviewRegistration_same_url(self):
self._addUpgradeLine(self.compute_node)
self.upgrade_decision.reviewRegistration(
software_release_url=self.software_release.getUrlString())
self.assertEqual("draft",
self.upgrade_decision.getSimulationState())
self.upgrade_decision.plan()
self.tic()
self.upgrade_decision.reviewRegistration(
software_release_url=self.software_release.getUrlString())
self.assertEqual("planned",
self.upgrade_decision.getSimulationState())
def test_upgrade_decision_reviewRegistration_confirm_same_url(self):
self._addUpgradeLine(self.compute_node)
self.upgrade_decision.reviewRegistration(
software_release_url=self.software_release.getUrlString())
self.assertEqual("draft",
self.upgrade_decision.getSimulationState())
self.upgrade_decision.confirm()
self.tic()
self.upgrade_decision.reviewRegistration(
software_release_url=self.software_release.getUrlString())
self.assertEqual("confirmed",
self.upgrade_decision.getSimulationState())
def test_upgrade_decision_reviewRegistration_rejected_same_url(self):
self._addUpgradeLine(self.compute_node)
self.upgrade_decision.reviewRegistration(
software_release_url=self.software_release.getUrlString())
self.assertEqual("draft",
self.upgrade_decision.getSimulationState())
self.upgrade_decision.reject()
self.tic()
self.upgrade_decision.reviewRegistration(
software_release_url=self.software_release.getUrlString())
self.assertEqual("rejected",
self.upgrade_decision.getSimulationState())
def test_upgrade_decision_reviewRegistration_started(self):
self._addUpgradeLine(self.compute_node)
software_release = self.generateNewSoftwareReleaseUrl()
self.upgrade_decision.reviewRegistration(
software_release_url=software_release)
self.assertEqual("draft",
self.upgrade_decision.getSimulationState())
self.upgrade_decision.plan()
self.upgrade_decision.start()
self.tic()
self.upgrade_decision.reviewRegistration(
software_release_url=software_release)
self.assertEqual("started",
self.upgrade_decision.getSimulationState())
def test_upgrade_decision_reviewRegistration_instance_tree(self):
self._makeTree()
self._addUpgradeLine(self.instance_tree)
self.upgrade_decision.reviewRegistration(
software_release_url=self.instance_tree.getUrlString())
self.assertEqual("draft",
self.upgrade_decision.getSimulationState())
self.upgrade_decision.plan()
self.tic()
self.upgrade_decision.reviewRegistration(
software_release_url=self.instance_tree.getUrlString())
self.assertEqual("cancelled",
self.upgrade_decision.getSimulationState())
def test_upgrade_decision_reviewRegistration_instance_tree_confirmed(self):
self._makeTree()
self._addUpgradeLine(self.instance_tree)
self.upgrade_decision.reviewRegistration(
software_release_url=self.instance_tree.getUrlString())
self.assertEqual("draft",
self.upgrade_decision.getSimulationState())
self.upgrade_decision.confirm()
self.tic()
self.upgrade_decision.reviewRegistration(
software_release_url=self.instance_tree.getUrlString())
self.assertEqual("cancelled",
self.upgrade_decision.getSimulationState())
def test_upgrade_decision_reviewRegistration_instance_tree_started(self):
self._makeTree()
self._addUpgradeLine(self.instance_tree)
self.upgrade_decision.reviewRegistration(
software_release_url=self.instance_tree.getUrlString())
self.assertEqual("draft",
self.upgrade_decision.getSimulationState())
self.upgrade_decision.start()
self.tic()
self.upgrade_decision.reviewRegistration(
software_release_url=self.instance_tree.getUrlString())
self.assertEqual("started",
self.upgrade_decision.getSimulationState())
@simulate('InstanceTree_isUpgradePossible',
'software_release_url', 'return 1')
def test_upgrade_decision_requestUpgrade_instance_tree(self):
self._makeTree()
self._addUpgradeLine(self.instance_tree)
self.tic()
slap_state = self.instance_tree.getSlapState()
self.upgrade_decision.requestUpgrade()
self.assertNotEqual(self.software_release.getUrlString(),
self.instance_tree.getUrlString())
self.upgrade_decision.confirm()
self.upgrade_decision.start()
# Check that url_string change, but slap state doesn't
self.assertNotEqual(self.software_release.getUrlString(),
self.instance_tree.getUrlString())
self.upgrade_decision.requestUpgrade()
self.assertEqual(self.software_release.getUrlString(),
self.instance_tree.getUrlString())
self.assertEqual(slap_state, self.instance_tree.getSlapState())
self.assertEqual('stopped', self.upgrade_decision.getSimulationState())
def test_upgrade_decision_requestUpgrade_instance_tree_no_software_release(self):
self._makeTree()
self.upgrade_decision.newContent(
portal_type="Upgrade Decision Line",
aggregate_value_list=[self.instance_tree]
)
self.upgrade_decision.confirm()
self.upgrade_decision.start()
self.tic()
self.upgrade_decision.requestUpgrade()
self.assertEqual('started', self.upgrade_decision.getSimulationState())
def test_upgrade_decision_requestUpgrade_compute_node_no_software_release(self):
self.upgrade_decision.newContent(
portal_type="Upgrade Decision Line",
aggregate_value_list=[self.compute_node]
)
self.upgrade_decision.confirm()
self.upgrade_decision.start()
self.tic()
self.upgrade_decision.requestUpgrade()
self.assertEqual('started', self.upgrade_decision.getSimulationState())
def test_upgrade_decision_requestUpgrade_only_software_release(self):
self.upgrade_decision.newContent(
portal_type="Upgrade Decision Line",
aggregate_value_list=[self.software_release]
)
self.upgrade_decision.confirm()
self.upgrade_decision.start()
self.tic()
self.upgrade_decision.requestUpgrade()
self.assertEqual('started', self.upgrade_decision.getSimulationState())
def test_upgrade_decision_requestUpgrade_duplicated(self):
self._makeTree()
self.upgrade_decision.newContent(
portal_type="Upgrade Decision Line",
aggregate_value_list=[
self.software_release,
self.instance_tree,
self.compute_node]
)
self.upgrade_decision.confirm()
self.upgrade_decision.start()
self.tic()
self.assertRaises(ValueError, self.upgrade_decision.requestUpgrade)
self.assertEqual('started', self.upgrade_decision.getSimulationState())
def test_upgrade_decision_requestUpgrade_compute_node(self):
self._addUpgradeLine(self.compute_node)
self.upgrade_decision.confirm()
self.upgrade_decision.start()
self.tic()
self.upgrade_decision.requestUpgrade()
self.tic()
self.assertEqual('stopped', self.upgrade_decision.getSimulationState())
software_installation = self.compute_node.getAggregateRelatedValue(
portal_type='Software Installation')
self.assertEqual('start_requested', software_installation.getSlapState())
self.assertEqual(self.software_release.getUrlString(),
software_installation.getUrlString())
self.assertEqual('validated', software_installation.getValidationState())
@simulate('InstanceTree_isUpgradePossible',
'software_release_url', 'return 0')
def test_upgrade_decision_requestUpgrade_instance_tree_not_possible(self):
self._makeTree()
self._addUpgradeLine(self.instance_tree)
self.assertNotEqual(self.instance_tree.getUrlString(),
self.software_release.getUrlString())
slap_state = self.instance_tree.getSlapState()
self.upgrade_decision.confirm()
self.upgrade_decision.start()
self.tic()
self.upgrade_decision.requestUpgrade()
self.tic()
self.assertEqual('started', self.upgrade_decision.getSimulationState())
self.assertNotEqual(self.instance_tree.getUrlString(),
self.software_release.getUrlString())
self.assertEqual(slap_state,
self.instance_tree.getSlapState())
# -*- coding:utf-8 -*-
##############################################################################
#
# Copyright (c) 2002-2013 Nexedi SA and Contributors. All Rights Reserved.
#
# 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 erp5.component.test.SlapOSTestCaseMixin import SlapOSTestCaseMixin
# Copyright (c) 2013 Nexedi SA and Contributors. All Rights Reserved.
from erp5.component.test.SlapOSTestCaseMixin import SlapOSTestCaseMixin, TemporaryAlarmScript
class TestSlapOSUpgradeDecisionProcess(SlapOSTestCaseMixin):
def afterSetUp(self):
SlapOSTestCaseMixin.afterSetUp(self)
self.new_id = self.generateNewId()
def _makeUpgradeDecision(self, confirm=True):
upgrade_decision = self.portal.\
upgrade_decision_module.newContent(
portal_type="Upgrade Decision",
title="TESTUPDE-%s" % self.new_id)
title="TESTUPDE-%s" % self.generateNewId())
if confirm:
upgrade_decision.confirm()
return upgrade_decision
def _makeInstanceTree(self, slap_state="start_requested"):
instance_tree = self.portal\
.instance_tree_module.template_instance_tree\
.Base_createCloneDocument(batch_mode=1)
.instance_tree_module\
.newContent(portal_type="Instance Tree")
instance_tree.validate()
new_id = self.generateNewId()
instance_tree.edit(
title= "Test hosting sub start %s" % self.new_id,
reference="TESTHSS-%s" % self.new_id,
title= "Test hosting sub start %s" % new_id,
reference="TESTHSS-%s" % new_id
)
self.portal.portal_workflow._jumpToStateFor(instance_tree, slap_state)
......@@ -49,86 +28,57 @@ class TestSlapOSUpgradeDecisionProcess(SlapOSTestCaseMixin):
def test_alarm_upgrade_decision_process_instance_tree(self):
upgrade_decision = self._makeUpgradeDecision()
upgrade_decision.start()
with TemporaryAlarmScript(self.portal, 'Base_reindexAndSenseAlarm', "'disabled'"):
upgrade_decision.start()
self.tic()
self._test_alarm(
self.portal.portal_alarms.slapos_pdm_upgrade_decision_process_started,
upgrade_decision,
'UpgradeDecision_processUpgrade')
def test_alarm_upgrade_decision_process_planned(self):
upgrade_decision = self._makeUpgradeDecision(confirm=0)
upgrade_decision.plan()
self._test_alarm(
self.portal.portal_alarms.slapos_pdm_upgrade_decision_process_planned,
upgrade_decision,
'UpgradeDecision_notify')
def test_alarm_upgrade_decision_process_stopped(self):
upgrade_decision = self._makeUpgradeDecision()
upgrade_decision.start()
upgrade_decision.stop()
self.tic()
self._test_alarm(
self.portal.portal_alarms.slapos_pdm_upgrade_decision_process_stopped,
upgrade_decision,
'UpgradeDecision_notifyDelivered')
def _test_alarm_compute_node_create_upgrade_decision(self, allocation_scope, upgrade_scope):
compute_node = self._makeComputeNode(allocation_scope=allocation_scope)[0]
compute_node.setUpgradeScope(upgrade_scope)
self._test_alarm(
self.portal.portal_alarms.slapos_pdm_compute_node_create_upgrade_decision,
compute_node,
'ComputeNode_checkAndCreateUpgradeDecision')
def _test_alarm_compute_node_create_upgrade_decision_not_visited(self, allocation_scope, upgrade_scope):
compute_node = self._makeComputeNode(allocation_scope=allocation_scope)[0]
compute_node.setUpgradeScope(upgrade_scope)
self._test_alarm_not_visited(
self.portal.portal_alarms.slapos_pdm_compute_node_create_upgrade_decision,
compute_node,
'ComputeNode_checkAndCreateUpgradeDecision')
def test_alarm_compute_node_create_upgrade_decision_auto(self):
self._test_alarm_compute_node_create_upgrade_decision('open/public', 'auto')
self._test_alarm_compute_node_create_upgrade_decision('open/personal', 'auto')
self._test_alarm_compute_node_create_upgrade_decision('open/subscription', 'auto')
self._test_alarm_compute_node_create_upgrade_decision('close/outdated', 'auto')
self._test_alarm_compute_node_create_upgrade_decision('close/maintanance', 'auto')
self._test_alarm_compute_node_create_upgrade_decision('close/termination', 'auto')
self._test_alarm_compute_node_create_upgrade_decision('close/noallocation', 'auto')
def test_alarm_compute_node_create_upgrade_decision_ask_confirmation(self):
self._test_alarm_compute_node_create_upgrade_decision('open/public', 'confirmation')
self._test_alarm_compute_node_create_upgrade_decision('open/personal', 'confirmation')
self._test_alarm_compute_node_create_upgrade_decision('open/subscription', 'confirmation')
self._test_alarm_compute_node_create_upgrade_decision('close/outdated', 'confirmation')
self._test_alarm_compute_node_create_upgrade_decision('close/maintanance', 'confirmation')
self._test_alarm_compute_node_create_upgrade_decision('close/termination', 'confirmation')
self._test_alarm_compute_node_create_upgrade_decision('close/noallocation', 'confirmation')
def test_alarm_compute_node_create_upgrade_decision_never(self):
self._test_alarm_compute_node_create_upgrade_decision_not_visited('open/public', 'never')
self._test_alarm_compute_node_create_upgrade_decision_not_visited('open/personal', 'never')
self._test_alarm_compute_node_create_upgrade_decision_not_visited('open/subscription', 'never')
self._test_alarm_compute_node_create_upgrade_decision_not_visited('close/outdated', 'never')
self._test_alarm_compute_node_create_upgrade_decision_not_visited('close/maintanance', 'never')
self._test_alarm_compute_node_create_upgrade_decision_not_visited('close/termination', 'never')
self._test_alarm_compute_node_create_upgrade_decision_not_visited('close/noallocation', 'never')
with TemporaryAlarmScript(self.portal, 'UpgradeDecision_processUpgrade'):
self.portal.portal_alarms.slapos_pdm_upgrade_decision_process_started.\
activeSense()
self.tic()
self.assertEqual(
'Visited by UpgradeDecision_processUpgrade',
upgrade_decision.workflow_history['edit_workflow'][-1]['comment'])
def test_alarm_instance_tree_create_upgrade_decision(self):
instance_tree = self._makeInstanceTree()
self._test_alarm(
self.portal.portal_alarms.slapos_pdm_instance_tree_create_upgrade_decision,
instance_tree,
'InstanceTree_createUpgradeDecision')
self.tic()
with TemporaryAlarmScript(self.portal, 'InstanceTree_createUpgradeDecision'):
self.portal.portal_alarms.slapos_pdm_instance_tree_create_upgrade_decision.\
activeSense()
self.tic()
self.assertEqual('Visited by InstanceTree_createUpgradeDecision',
instance_tree.workflow_history['edit_workflow'][-1]['comment'])
def test_alarm_create_upgrade_decision_destroyed_instance_tree(self):
instance_tree = self._makeInstanceTree(slap_state="destroy_requested")
self._test_alarm_not_visited(
self.portal.portal_alarms.slapos_pdm_instance_tree_create_upgrade_decision,
instance_tree,
'InstanceTree_createUpgradeDecision')
self.tic()
with TemporaryAlarmScript(self.portal, 'InstanceTree_createUpgradeDecision'):
self.portal.portal_alarms.slapos_pdm_instance_tree_create_upgrade_decision.\
activeSense()
self.tic()
self.assertNotEqual('Visited by InstanceTree_createUpgradeDecision',
instance_tree.workflow_history['edit_workflow'][-1]['comment'])
def test_alarm_destroy_unused_software_installation(self):
software_installation = self.portal.software_installation_module.newContent(
portal_type='Software Installation'
)
self.portal.portal_workflow._jumpToStateFor(software_installation,
'start_requested')
self.portal.portal_workflow._jumpToStateFor(software_installation,
'validated')
self.tic()
with TemporaryAlarmScript(self.portal, 'SoftwareInstallation_destroyIfUnused'):
self.portal.portal_alarms.slapos_pdm_destroy_unused_software_installation.\
activeSense()
self.tic()
self.assertEqual('Visited by SoftwareInstallation_destroyIfUnused',
software_installation.workflow_history['edit_workflow'][-1]['comment'])
\ No newline at end of file
......@@ -19,411 +19,538 @@
#
##############################################################################
from erp5.component.test.testSlapOSPDMSkins import TestSlapOSPDMMixinSkins
from DateTime import DateTime
import transaction
class TestSlapOSPDMCreateUpgradeDecisionSkins(TestSlapOSPDMMixinSkins):
def _makeSoftwareProductCatalog(self):
self.software_product = self._makeSoftwareProduct(self.generateNewId())
self.previous_software_release = self._makeSoftwareRelease(self.generateNewId())
self.new_software_release = self._makeSoftwareRelease(self.generateNewId())
self.previous_software_release.publish()
self.new_software_release.publish()
self.previous_software_release.edit(
aggregate=self.software_product.getRelativeUrl(),
url_string=self.generateNewSoftwareReleaseUrl(),
version='1',
effective_date=DateTime()-1,
from erp5.component.test.SlapOSTestCaseMixin import SlapOSTestCaseMixin
class TestSlapOSPDMCreateUpgradeDecisionSkins(SlapOSTestCaseMixin):
def test_createUpgradeDecision_destroyed_instance(self):
instance_tree = self.portal.instance_tree_module.newContent(
portal_type="Instance Tree"
)
self.portal.portal_workflow._jumpToStateFor(instance_tree,
'destroy_requested')
self.assertEqual(None, instance_tree.InstanceTree_createUpgradeDecision())
self.new_software_release.edit(
aggregate=self.software_product.getRelativeUrl(),
url_string=self.generateNewSoftwareReleaseUrl(),
version='2',
effective_date=DateTime(),
def test_createUpgradeDecision_without_softwareProduct(self):
instance_tree = self.portal.instance_tree_module.newContent(
portal_type="Instance Tree"
)
self.assertEqual(None, instance_tree.InstanceTree_createUpgradeDecision())
def checkCreatedUpgradeDecision(self, upgrade_decision, instance_tree,
software_product, release_variation,
type_variation):
self.assertEqual('confirmed', upgrade_decision.getSimulationState())
project = instance_tree.getFollowUpValue()
self.assertEqual(instance_tree.getRelativeUrl(),
upgrade_decision.getAggregate())
self.assertEqual(software_product.getRelativeUrl(),
upgrade_decision.getResource())
self.assertEqual(release_variation.getRelativeUrl(),
upgrade_decision.getSoftwareRelease())
self.assertEqual(type_variation.getRelativeUrl(),
upgrade_decision.getSoftwareType())
self.assertEqual(project.getRelativeUrl(),
upgrade_decision.getDestinationProject())
person = instance_tree.getDestinationSectionValue()
self.assertEqual(person.getRelativeUrl(),
upgrade_decision.getDestinationDecision())
self.assertEqual(person.getRelativeUrl(),
upgrade_decision.getDestinationSection())
# Check that software release url is not the same
self.assertEqual(type_variation.getTitle(),
instance_tree.getSourceReference())
self.assertNotEqual(release_variation.getUrlString(),
instance_tree.getUrlString())
##########################################################################
# Not allocated
##########################################################################
def test_createUpgradeDecision_notAllocated_newReleaseOnComputeNode(self):
software_product, _, type_variation, compute_node, _, instance_tree = self.bootstrapAllocableInstanceTree()
self.tic()
def _installSoftwareOnTheComputeNode(self, software_release_url_list):
for software_release in software_release_url_list:
software_installation = self.portal.software_installation_module\
.newContent(portal_type='Software Installation',
url_string=software_release,
aggregate=self.compute_node.getRelativeUrl())
software_installation.validate()
software_installation.requestStart()
new_release_variation = self._makeSoftwareRelease(software_product)
self.addAllocationSupply("for compute node", compute_node, software_product,
new_release_variation, type_variation, disable_alarm=True)
self.tic()
def _createInstance(self, url_string, shared=False):
instance_tree = self.portal.instance_tree_module\
.template_instance_tree.Base_createCloneDocument(batch_mode=1)
instance_tree.edit(
)
instance_tree.validate()
instance_tree.edit(
title=self.generateNewSoftwareTitle(),
reference="TESTHS-%s" % self.generateNewId(),
destination_section_value=self.person
self.checkCreatedUpgradeDecision(
instance_tree.InstanceTree_createUpgradeDecision(),
instance_tree, software_product, new_release_variation, type_variation
)
request_kw = dict(
software_release=url_string,
software_type=self.generateNewSoftwareType(),
instance_xml=self.generateSafeXml(),
sla_xml=self.generateSafeXml(),
shared=shared,
software_title=instance_tree.getTitle(),
state='started'
def test_createUpgradeDecision_notAllocated_newReleaseOnRemoteNode(self):
software_product, _, type_variation, compute_node, _, instance_tree = self.bootstrapAllocableInstanceTree(node="remote")
self.tic()
new_release_variation = self._makeSoftwareRelease(software_product)
self.addAllocationSupply("for remote node", compute_node, software_product,
new_release_variation, type_variation, disable_alarm=True)
self.tic()
self.checkCreatedUpgradeDecision(
instance_tree.InstanceTree_createUpgradeDecision(),
instance_tree, software_product, new_release_variation, type_variation
)
instance_tree.requestStart(**request_kw)
instance_tree.requestInstance(**request_kw)
instance = instance_tree.getSuccessorValue()
def test_createUpgradeDecision_notAllocated_newReleaseOnInstanceNode(self):
software_product, _, type_variation, compute_node, _, instance_tree = self.bootstrapAllocableInstanceTree(allocation_state="impossible", node="instance")
self.tic()
return instance_tree, instance
def _makeTreeForTestSlapOSPDMCreateUpgradeDecisionSkins(self, software_release_url):
self.instance_tree, self.instance = self._createInstance(software_release_url)
self.shared_instance_tree, self.shared_instance = self._createInstance(software_release_url, True)
self.instance.setAggregate(self.partition.getRelativeUrl())
self.shared_instance.setAggregate(self.partition.getRelativeUrl())
self.partition.markBusy()
new_release_variation = self._makeSoftwareRelease(software_product)
self.addAllocationSupply("for instance node", compute_node, software_product,
new_release_variation, type_variation, disable_alarm=True)
self.tic()
def afterSetUp(self):
TestSlapOSPDMMixinSkins.afterSetUp(self)
preference = self.portal.portal_preferences.getActiveSystemPreference()
preference.setPreferredCloudContractEnabled(True)
self.assertEqual(None, instance_tree.InstanceTree_createUpgradeDecision())
def test_createUpgradeDecision_notAllocated_sameRelease(self):
software_product, release_variation, type_variation, compute_node, _, instance_tree = self.bootstrapAllocableInstanceTree()
self.tic()
self.addAllocationSupply(
"for compute node", compute_node, software_product,
release_variation, type_variation, disable_alarm=True)
self.assertEqual(None, instance_tree.InstanceTree_createUpgradeDecision())
def test_createUpgradeDecision_notAllocated_twoRelease(self):
software_product, release_variation, type_variation, compute_node, _, instance_tree = self.bootstrapAllocableInstanceTree()
self.tic()
self._makeComputeNode()
self._makeSoftwareProductCatalog()
self._installSoftwareOnTheComputeNode([
self.previous_software_release.getUrlString(),
self.new_software_release.getUrlString()
])
self.person = self.makePerson()
self.addAllocationSupply(
"for compute node", compute_node, software_product,
release_variation, type_variation, disable_alarm=True)
new_release_variation = self._makeSoftwareRelease(software_product)
self.addAllocationSupply("for compute node 2", compute_node, software_product,
new_release_variation, type_variation, disable_alarm=True)
self.tic()
self._makeTreeForTestSlapOSPDMCreateUpgradeDecisionSkins(
self.previous_software_release.getUrlString())
def test_InstanceTree_createUpgradeDecision_upgradeScopeConfirmation(self):
# check upgrade decision on HS
self.instance_tree.setUpgradeScope('manual')
self.assertEqual(None, instance_tree.InstanceTree_createUpgradeDecision())
def test_createUpgradeDecision_notAllocated_newRelease_ongoingDecision(self):
software_product, _, type_variation, compute_node, _, instance_tree = self.bootstrapAllocableInstanceTree()
self.tic()
upgrade_decision = self.instance_tree.InstanceTree_createUpgradeDecision()
self.assertEqual('planned', upgrade_decision.getSimulationState())
shared_upgrade_decision = self.shared_instance_tree.InstanceTree_createUpgradeDecision()
self.assertEqual(None, shared_upgrade_decision)
# simulate upgrade of the instance tree
upgrade_decision.confirm()
upgrade_decision.start()
upgrade_decision.stop()
upgrade_decision.deliver()
self.instance_tree.edit(url_string=self.new_software_release.getUrlString())
self.instance.edit(url_string=self.new_software_release.getUrlString())
new_release_variation = self._makeSoftwareRelease(software_product)
self.addAllocationSupply("for compute node 2", compute_node, software_product,
new_release_variation, type_variation, disable_alarm=True)
self.tic()
# check upgrade decision on shared HS related to upgraded HS
self.shared_instance_tree.setUpgradeScope('manual')
self.checkCreatedUpgradeDecision(
instance_tree.InstanceTree_createUpgradeDecision(),
instance_tree, software_product, new_release_variation, type_variation
)
self.tic()
shared_upgrade_decision = self.shared_instance_tree.InstanceTree_createUpgradeDecision()
self.assertEqual('started', shared_upgrade_decision.getSimulationState())
self.assertEqual(None, instance_tree.InstanceTree_createUpgradeDecision())
def test_InstanceTree_createUpgradeDecision_upgradeScopeAuto(self):
# check upgrade decision on HS
self.instance_tree.setUpgradeScope('auto')
def test_createUpgradeDecision_notAllocated_newRelease_ongoingDecisionActivity(self):
software_product, _, type_variation, compute_node, _, instance_tree = self.bootstrapAllocableInstanceTree()
self.tic()
upgrade_decision = self.instance_tree.InstanceTree_createUpgradeDecision()
self.assertEqual('started', upgrade_decision.getSimulationState())
shared_upgrade_decision = self.shared_instance_tree.InstanceTree_createUpgradeDecision()
self.assertEqual(None, shared_upgrade_decision)
# simulate upgrade of the instance tree
upgrade_decision.stop()
upgrade_decision.deliver()
self.instance_tree.edit(url_string=self.new_software_release.getUrlString())
self.instance.edit(url_string=self.new_software_release.getUrlString())
new_release_variation = self._makeSoftwareRelease(software_product)
self.addAllocationSupply("for compute node 2", compute_node, software_product,
new_release_variation, type_variation, disable_alarm=True)
self.tic()
# check upgrade decision on shared HS related to upgraded HS
self.shared_instance_tree.setUpgradeScope('auto')
self.checkCreatedUpgradeDecision(
instance_tree.InstanceTree_createUpgradeDecision(),
instance_tree, software_product, new_release_variation, type_variation
)
self.commit()
shared_upgrade_decision = self.shared_instance_tree.InstanceTree_createUpgradeDecision()
self.assertEqual('started', shared_upgrade_decision.getSimulationState())
self.assertEqual(None, instance_tree.InstanceTree_createUpgradeDecision())
def test_InstanceTree_createUpgradeDecision_upgradeScopeDisabled(self):
# check upgrade decision on HS
self.instance_tree.setUpgradeScope('disabled')
def test_createUpgradeDecision_notAllocated_newRelease_cancelledDecision(self):
software_product, _, type_variation, compute_node, _, instance_tree = self.bootstrapAllocableInstanceTree()
self.tic()
upgrade_decision = self.instance_tree.InstanceTree_createUpgradeDecision()
self.assertEqual(None, upgrade_decision)
shared_upgrade_decision = self.shared_instance_tree.InstanceTree_createUpgradeDecision()
self.assertEqual(None, shared_upgrade_decision)
new_release_variation = self._makeSoftwareRelease(software_product)
self.addAllocationSupply("for compute node 2", compute_node, software_product,
new_release_variation, type_variation, disable_alarm=True)
self.tic()
upgrade_decision = instance_tree.InstanceTree_createUpgradeDecision()
self.checkCreatedUpgradeDecision(
upgrade_decision,
instance_tree, software_product, new_release_variation, type_variation
)
upgrade_decision.cancel()
self.tic()
def testInstanceTree_createUpgradeDecision_no_newer(self):
person = self._makePerson()
compute_node, _ = self._makeComputeNode(owner=person)
self._makeComputePartitions(compute_node)
software_product = self._makeSoftwareProduct()
software_release = self._requestSoftwareRelease(
software_product.getRelativeUrl())
url_string = software_release.getUrlString()
self._makeSoftwareInstallation(compute_node, url_string)
self.checkCreatedUpgradeDecision(
instance_tree.InstanceTree_createUpgradeDecision(),
instance_tree, software_product, new_release_variation, type_variation
)
def test_createUpgradeDecision_notAllocated_newRelease_rejectedDecisionSameRelease(self):
software_product, _, type_variation, compute_node, _, instance_tree = self.bootstrapAllocableInstanceTree()
self.tic()
# Create Instance Tree
instance_tree = self._makeFullInstanceTree(
url_string, person)
new_release_variation = self._makeSoftwareRelease(software_product)
self.addAllocationSupply("for compute node 2", compute_node, software_product,
new_release_variation, type_variation, disable_alarm=True)
self.tic()
upgrade_decision = instance_tree.InstanceTree_createUpgradeDecision()
self.assertEqual(upgrade_decision, None)
self._makeFullSoftwareInstance(instance_tree, url_string)
self._markComputePartitionBusy(compute_node,
instance_tree.getSuccessorValue())
self._requestSoftwareRelease(software_product.getRelativeUrl())
self.tic()
self.checkCreatedUpgradeDecision(
upgrade_decision,
instance_tree, software_product, new_release_variation, type_variation
)
upgrade_decision.reject()
self.tic()
self.assertEqual(None, instance_tree.InstanceTree_createUpgradeDecision())
def test_createUpgradeDecision_notAllocated_newRelease_rejectedDecisionAnotherRelease(self):
software_product, _, type_variation, compute_node, _, instance_tree = self.bootstrapAllocableInstanceTree()
self.tic()
new_release_variation = self._makeSoftwareRelease(software_product)
supply = self.addAllocationSupply("for compute node 2", compute_node, software_product,
new_release_variation, type_variation, disable_alarm=True)
self.tic()
upgrade_decision = instance_tree.InstanceTree_createUpgradeDecision()
self.assertEqual(upgrade_decision, None)
def testInstanceTree_createUpgradeDecision_closed_compute_node(self):
person = self._makePerson()
compute_node, _ = self._makeComputeNode(owner=person, allocation_scope="close/outdated")
self._makeComputePartitions(compute_node)
software_product = self._makeSoftwareProduct()
software_release = self._requestSoftwareRelease(
software_product.getRelativeUrl())
url_string = software_release.getUrlString()
self._makeSoftwareInstallation( compute_node, url_string)
# Create Instance Tree and Software Instance
instance_tree = self._makeFullInstanceTree(
url_string, person)
self._makeFullSoftwareInstance(instance_tree, url_string)
self._markComputePartitionBusy(compute_node,
instance_tree.getSuccessorValue())
# Install the Newest software release
software_release2 = self._requestSoftwareRelease(
software_product.getRelativeUrl())
self._makeSoftwareInstallation(compute_node,
software_release2.getUrlString())
self.tic()
up_decision = instance_tree.InstanceTree_createUpgradeDecision()
self.assertNotEqual(up_decision, None)
self.assertEqual(up_decision.getSimulationState(), 'planned')
self.assertEqual(up_decision.UpgradeDecision_getAggregateValue("Instance Tree").\
getReference(), instance_tree.getReference())
self.assertEqual(software_release2.getUrlString(),
up_decision.UpgradeDecision_getAggregateValue("Software Release").\
getUrlString())
def testInstanceTree_createUpgradeDecision_create_once_transaction(self):
person = self._makePerson()
compute_node, _ = self._makeComputeNode(owner=person, allocation_scope="open/personal")
self._makeComputePartitions(compute_node)
software_product = self._makeSoftwareProduct()
software_release = self._requestSoftwareRelease(
software_product.getRelativeUrl())
url_string = software_release.getUrlString()
self._makeSoftwareInstallation( compute_node, url_string)
# Create Instance Tree and Software Instance
instance_tree = self._makeFullInstanceTree(
url_string, person)
self._makeFullSoftwareInstance(instance_tree, url_string)
self._markComputePartitionBusy(compute_node,
instance_tree.getSuccessorValue())
# Install the Newest software release
software_release2 = self._requestSoftwareRelease(
software_product.getRelativeUrl())
self._makeSoftwareInstallation(compute_node,
software_release2.getUrlString())
self.tic()
up_decision = instance_tree.InstanceTree_createUpgradeDecision()
self.assertNotEqual(up_decision, None)
self.assertEqual(up_decision.getSimulationState(), 'planned')
transaction.commit()
# call a second time without tic
up_decision = instance_tree.InstanceTree_createUpgradeDecision()
# no new Upgrade decision created
self.assertEqual(up_decision, None)
def testInstanceTree_createUpgradeDecision(self):
person = self._makePerson()
compute_node, _ = self._makeComputeNode(owner=person)
self._makeComputePartitions(compute_node)
software_product = self._makeSoftwareProduct()
software_release = self._requestSoftwareRelease(
software_product.getRelativeUrl())
url_string = software_release.getUrlString()
self._makeSoftwareInstallation( compute_node, url_string)
# Create Instance Tree and Software Instance
instance_tree = self._makeFullInstanceTree(
url_string, person)
self._makeFullSoftwareInstance(instance_tree, url_string)
self._markComputePartitionBusy(compute_node,
instance_tree.getSuccessorValue())
# Install the Newest software release
software_release2 = self._requestSoftwareRelease(
software_product.getRelativeUrl())
self._makeSoftwareInstallation(compute_node,
software_release2.getUrlString())
self.tic()
up_decision = instance_tree.InstanceTree_createUpgradeDecision()
self.assertNotEqual(up_decision, None)
self.assertEqual(up_decision.getSimulationState(), 'planned')
self.assertEqual(up_decision.UpgradeDecision_getAggregateValue("Instance Tree").\
getReference(), instance_tree.getReference())
self.assertEqual(software_release2.getUrlString(),
up_decision.UpgradeDecision_getAggregateValue("Software Release").\
getUrlString())
self.tic()
up_decision2 = instance_tree.InstanceTree_createUpgradeDecision()
self.assertEqual(up_decision2, None)
def testInstanceTree_createUpgradeDecision_with_exist(self):
person = self._makePerson()
compute_node, _ = self._makeComputeNode(owner=person)
self._makeComputePartitions(compute_node)
software_product = self._makeSoftwareProduct()
software_release = self._requestSoftwareRelease(
software_product.getRelativeUrl())
url_string = software_release.getUrlString()
self._makeSoftwareInstallation( compute_node, url_string)
# Create Instance Tree and Software Instance
instance_tree = self._makeFullInstanceTree(
url_string, person)
self._makeFullSoftwareInstance(instance_tree, url_string)
self._markComputePartitionBusy(compute_node,
instance_tree.getSuccessorValue())
# Install the Newest software release
software_release2 = self._requestSoftwareRelease(
software_product.getRelativeUrl())
self._makeSoftwareInstallation(compute_node, software_release2.getUrlString())
self.tic()
up_decision = instance_tree.InstanceTree_createUpgradeDecision()
self.assertEqual(up_decision.getSimulationState(), 'planned')
# Install the another software release
software_release3 = self._requestSoftwareRelease(
software_product.getRelativeUrl())
self._makeSoftwareInstallation(compute_node, software_release3.getUrlString())
self.tic()
up_decision2 = instance_tree.InstanceTree_createUpgradeDecision()
self.assertEqual(up_decision2.getSimulationState(), 'planned')
self.assertEqual(up_decision.getSimulationState(), 'cancelled')
release = up_decision2.UpgradeDecision_getAggregateValue("Software Release")
self.assertEqual(release.getUrlString(),
software_release3.getUrlString())
def testInstanceTree_createUpgradeDecision_rejected(self):
person = self._makePerson()
compute_node, _ = self._makeComputeNode(owner=person)
self._makeComputePartitions(compute_node)
software_product = self._makeSoftwareProduct()
software_release = self._requestSoftwareRelease(
software_product.getRelativeUrl())
url_string = software_release.getUrlString()
self._makeSoftwareInstallation(compute_node, url_string)
# Create Instance Tree and Software Instance
instance_tree = self._makeFullInstanceTree(
url_string, person)
self._makeFullSoftwareInstance(instance_tree, url_string)
self._markComputePartitionBusy(compute_node,
instance_tree.getSuccessorValue())
# Install the Newest software release
software_release2 = self._requestSoftwareRelease(
software_product.getRelativeUrl())
self._makeSoftwareInstallation(compute_node, software_release2.getUrlString())
self.tic()
up_decision = instance_tree.InstanceTree_createUpgradeDecision()
self.assertEqual(up_decision.getSimulationState(), 'planned')
# Reject upgrade decision
up_decision.reject()
self.tic()
in_progress = software_release2.SoftwareRelease_getUpgradeDecisionInProgress(
instance_tree.getUid())
up_decision = instance_tree.InstanceTree_createUpgradeDecision()
# There is an upgrade decision in progress
self.assertNotEqual(in_progress, None)
# No new upgrade decision created with software_release2
self.assertEqual(up_decision, None)
def testInstanceTree_createUpgradeDecision_rejected_2(self):
person = self._makePerson()
compute_node, _ = self._makeComputeNode(owner=person)
self._makeComputePartitions(compute_node)
software_product = self._makeSoftwareProduct()
software_release = self._requestSoftwareRelease(
software_product.getRelativeUrl())
url_string = software_release.getUrlString()
self._makeSoftwareInstallation(compute_node, url_string)
# Create Instance Tree and Software Instance
instance_tree = self._makeFullInstanceTree(
url_string, person)
self._makeFullSoftwareInstance(instance_tree, url_string)
self._markComputePartitionBusy(compute_node,
instance_tree.getSuccessorValue())
# Install the Newest software release
software_release2 = self._requestSoftwareRelease(
software_product.getRelativeUrl())
self._makeSoftwareInstallation(compute_node, software_release2.getUrlString())
self.tic()
up_decision = instance_tree.InstanceTree_createUpgradeDecision()
self.assertEqual(up_decision.getSimulationState(), 'planned')
# Reject upgrade decision
up_decision.reject()
self.tic()
# Install the another software release
software_release3 = self._requestSoftwareRelease(
software_product.getRelativeUrl())
self._makeSoftwareInstallation(compute_node, software_release3.getUrlString())
self.tic()
decision2 = instance_tree.InstanceTree_createUpgradeDecision()
self.assertEqual(decision2.getSimulationState(), 'planned')
self.assertEqual(up_decision.getSimulationState(), 'rejected')
release = decision2.UpgradeDecision_getAggregateValue("Software Release")
self.assertEqual(release.getUrlString(),
software_release3.getUrlString())
\ No newline at end of file
self.checkCreatedUpgradeDecision(
upgrade_decision,
instance_tree, software_product, new_release_variation, type_variation
)
upgrade_decision.reject()
supply.invalidate()
self.tic()
new_release_variation2 = self._makeSoftwareRelease(software_product)
supply = self.addAllocationSupply("for compute node 3", compute_node, software_product,
new_release_variation2, type_variation, disable_alarm=True)
self.tic()
self.checkCreatedUpgradeDecision(
instance_tree.InstanceTree_createUpgradeDecision(),
instance_tree, software_product, new_release_variation2, type_variation
)
##########################################################################
# Shared not allocated
##########################################################################
def test_createUpgradeDecision_sharedNotAllocated_newReleaseOnComputeNode(self):
software_product, _, type_variation, compute_node, _, instance_tree = self.bootstrapAllocableInstanceTree(shared=True)
self.tic()
new_release_variation = self._makeSoftwareRelease(software_product)
self.addAllocationSupply("for compute node", compute_node, software_product,
new_release_variation, type_variation, disable_alarm=True)
self.tic()
self.assertEqual(None, instance_tree.InstanceTree_createUpgradeDecision())
def test_createUpgradeDecision_sharedNotAllocated_newReleaseOnRemoteNode(self):
software_product, _, type_variation, compute_node, _, instance_tree = self.bootstrapAllocableInstanceTree(shared=True, node="remote")
self.tic()
new_release_variation = self._makeSoftwareRelease(software_product)
self.addAllocationSupply("for remote node", compute_node, software_product,
new_release_variation, type_variation, disable_alarm=True)
self.tic()
self.checkCreatedUpgradeDecision(
instance_tree.InstanceTree_createUpgradeDecision(),
instance_tree, software_product, new_release_variation, type_variation
)
def test_createUpgradeDecision_sharedNotAllocated_newReleaseOnInstanceNode(self):
software_product, _, type_variation, compute_node, _, instance_tree = self.bootstrapAllocableInstanceTree(shared=True, node="instance")
self.tic()
new_release_variation = self._makeSoftwareRelease(software_product)
self.addAllocationSupply("for instance node", compute_node, software_product,
new_release_variation, type_variation, disable_alarm=True)
self.tic()
self.checkCreatedUpgradeDecision(
instance_tree.InstanceTree_createUpgradeDecision(),
instance_tree, software_product, new_release_variation, type_variation
)
##########################################################################
# Allocated on Compute Node
##########################################################################
def test_createUpgradeDecision_allocatedOnComputeNode_newReleaseOnAnotherComputeNode(self):
software_product, _, type_variation, _, _, instance_tree = self.bootstrapAllocableInstanceTree(allocation_state='allocated')
project = instance_tree.getFollowUpValue()
person = instance_tree.getDestinationSectionValue()
person.requestComputeNode(compute_node_title='another test compute node',
project_reference=project.getReference())
self.tic()
compute_node2 = self.portal.portal_catalog.getResultValue(
portal_type='Compute Node',
reference=self.portal.REQUEST.get('compute_node_reference')
)
assert compute_node2 is not None
new_release_variation = self._makeSoftwareRelease(software_product)
self.addAllocationSupply("for compute node 2", compute_node2, software_product,
new_release_variation, type_variation, disable_alarm=True)
self.tic()
self.assertEqual(None, instance_tree.InstanceTree_createUpgradeDecision())
def test_createUpgradeDecision_allocatedOnComputeNode_newReleaseOnComputeNode(self):
software_product, _, type_variation, compute_node, _, instance_tree = self.bootstrapAllocableInstanceTree(allocation_state='allocated')
new_release_variation = self._makeSoftwareRelease(software_product)
self.addAllocationSupply("for compute node", compute_node, software_product,
new_release_variation, type_variation, disable_alarm=True)
self.tic()
self.checkCreatedUpgradeDecision(
instance_tree.InstanceTree_createUpgradeDecision(),
instance_tree, software_product, new_release_variation, type_variation
)
def test_createUpgradeDecision_allocatedOnComputeNode_newReleaseOnComputeNodeAndCorrectTarget(self):
software_product, _, type_variation, compute_node, _, instance_tree = self.bootstrapAllocableInstanceTree(allocation_state='allocated')
new_release_variation = self._makeSoftwareRelease(software_product)
self.addAllocationSupply("for compute node", compute_node, software_product,
new_release_variation, type_variation, disable_alarm=True)
self.tic()
self.checkCreatedUpgradeDecision(
instance_tree.InstanceTree_createUpgradeDecision(
target_software_release=new_release_variation,
target_software_type=type_variation
),
instance_tree, software_product, new_release_variation, type_variation
)
def test_createUpgradeDecision_allocatedOnComputeNode_newReleaseOnComputeNodeAndIncorrectTarget(self):
software_product, _, type_variation, compute_node, _, instance_tree = self.bootstrapAllocableInstanceTree(allocation_state='allocated')
new_release_variation = self._makeSoftwareRelease(software_product)
incorrect_release_variation = self._makeSoftwareRelease(software_product)
self.addAllocationSupply("for compute node", compute_node, software_product,
new_release_variation, type_variation, disable_alarm=True)
self.tic()
self.assertEqual(
None,
instance_tree.InstanceTree_createUpgradeDecision(
target_software_release=incorrect_release_variation,
target_software_type=type_variation
)
)
def test_createUpgradeDecision_allocatedOnComputeNode_twoRelease(self):
software_product, release_variation, type_variation, compute_node, _, instance_tree = self.bootstrapAllocableInstanceTree(allocation_state='allocated')
self.tic()
self.addAllocationSupply(
"for compute node", compute_node, software_product,
release_variation, type_variation, disable_alarm=True)
new_release_variation = self._makeSoftwareRelease(software_product)
self.addAllocationSupply("for compute node 2", compute_node, software_product,
new_release_variation, type_variation, disable_alarm=True)
self.tic()
self.assertEqual(None, instance_tree.InstanceTree_createUpgradeDecision())
def test_createUpgradeDecision_allocatedOnComputeNode_twoReleaseAndCorrectTarget(self):
software_product, release_variation, type_variation, compute_node, _, instance_tree = self.bootstrapAllocableInstanceTree(allocation_state='allocated')
self.tic()
self.addAllocationSupply(
"for compute node", compute_node, software_product,
release_variation, type_variation, disable_alarm=True)
new_release_variation = self._makeSoftwareRelease(software_product)
self.addAllocationSupply("for compute node 2", compute_node, software_product,
new_release_variation, type_variation, disable_alarm=True)
self.tic()
self.checkCreatedUpgradeDecision(
instance_tree.InstanceTree_createUpgradeDecision(
target_software_release=new_release_variation,
target_software_type=type_variation
),
instance_tree, software_product, new_release_variation, type_variation
)
def test_createUpgradeDecision_allocatedOnComputeNode_twoReleaseAndIncorrectTarget(self):
software_product, release_variation, type_variation, compute_node, _, instance_tree = self.bootstrapAllocableInstanceTree(allocation_state='allocated')
self.tic()
self.addAllocationSupply(
"for compute node", compute_node, software_product,
release_variation, type_variation, disable_alarm=True)
new_release_variation = self._makeSoftwareRelease(software_product)
incorrect_release_variation = self._makeSoftwareRelease(software_product)
self.addAllocationSupply("for compute node 2", compute_node, software_product,
new_release_variation, type_variation, disable_alarm=True)
self.tic()
self.assertEqual(
instance_tree.InstanceTree_createUpgradeDecision(
target_software_release=incorrect_release_variation,
target_software_type=type_variation
),
None
)
##########################################################################
# Shared allocated on Compute Node
##########################################################################
def test_createUpgradeDecision_slaveAllocatedOnComputeNodeSameTree_newReleaseOnComputeNodeButNotTree(self):
software_product, _, type_variation, compute_node, _, instance_tree = self.bootstrapAllocableInstanceTree(allocation_state='allocated', shared=True)
self.tic()
new_release_variation = self._makeSoftwareRelease(software_product)
self.addAllocationSupply("for compute node", compute_node, software_product,
new_release_variation, type_variation, disable_alarm=True)
self.tic()
self.assertEqual(None, instance_tree.InstanceTree_createUpgradeDecision())
def test_createUpgradeDecision_slaveAllocatedOnComputeNodeSameTree_newReleaseOnComputeNode(self):
# A Slave Instance can not be the root instance and allocated on the same tree
# at the same time
software_product, _, type_variation, compute_node, _, instance_tree = self.bootstrapAllocableInstanceTree(allocation_state='allocated', shared=True)
self.tic()
new_release_variation = self._makeSoftwareRelease(software_product)
self.addAllocationSupply("for compute node", compute_node, software_product,
new_release_variation, type_variation,
is_slave_on_same_instance_tree_allocable=True, disable_alarm=True)
self.tic()
self.assertEqual(None, instance_tree.InstanceTree_createUpgradeDecision())
##########################################################################
# Allocated on Remote Node
##########################################################################
def test_createUpgradeDecision_allocatedOnRemoteNode_newReleaseOnRemoteNode(self):
software_product, _, type_variation, remote_node, _, instance_tree = self.bootstrapAllocableInstanceTree(allocation_state='allocated', node="remote")
self.tic()
new_release_variation = self._makeSoftwareRelease(software_product)
self.addAllocationSupply("for remote node", remote_node, software_product,
new_release_variation, type_variation, disable_alarm=True)
self.tic()
self.checkCreatedUpgradeDecision(
instance_tree.InstanceTree_createUpgradeDecision(),
instance_tree, software_product, new_release_variation, type_variation
)
def test_createUpgradeDecision_allocatedOnRemoteNode_twoRelease(self):
software_product, release_variation, type_variation, remote_node, _, instance_tree = self.bootstrapAllocableInstanceTree(allocation_state='allocated', node="remote")
self.tic()
self.addAllocationSupply(
"for remote node", remote_node, software_product,
release_variation, type_variation, disable_alarm=True)
new_release_variation = self._makeSoftwareRelease(software_product)
self.addAllocationSupply("for compute node 2", remote_node, software_product,
new_release_variation, type_variation, disable_alarm=True)
self.tic()
self.assertEqual(None, instance_tree.InstanceTree_createUpgradeDecision())
def test_createUpgradeDecision_allocatedOnRemoteNode_newReleaseOnAnoterRemoteNode(self):
software_product, _, type_variation, _, _, instance_tree = self.bootstrapAllocableInstanceTree(allocation_state='allocated', node="remote")
self.tic()
project = instance_tree.getFollowUpValue()
remote_node2 = self.portal.compute_node_module.newContent(
portal_type="Remote Node",
follow_up_value=project
)
new_release_variation = self._makeSoftwareRelease(software_product)
self.addAllocationSupply("for remote node 2", remote_node2, software_product,
new_release_variation, type_variation, disable_alarm=True)
self.tic()
self.assertEqual(None, instance_tree.InstanceTree_createUpgradeDecision())
##########################################################################
# Shared allocated on Remote Node
##########################################################################
def test_createUpgradeDecision_slaveAllocatedOnRemoteNode_newReleaseOnComputeNode(self):
software_product, _, type_variation, remote_node, _, instance_tree = self.bootstrapAllocableInstanceTree(allocation_state='allocated', shared=True, node="remote")
self.tic()
new_release_variation = self._makeSoftwareRelease(software_product)
self.addAllocationSupply("for remote node", remote_node, software_product,
new_release_variation, type_variation, disable_alarm=True)
self.tic()
self.checkCreatedUpgradeDecision(
instance_tree.InstanceTree_createUpgradeDecision(),
instance_tree, software_product, new_release_variation, type_variation
)
def test_createUpgradeDecision_slaveAllocatedOnRemoteNode_twoRelease(self):
software_product, release_variation, type_variation, remote_node, _, instance_tree = self.bootstrapAllocableInstanceTree(allocation_state='allocated', shared=True, node="remote")
self.tic()
self.addAllocationSupply(
"for remote node", remote_node, software_product,
release_variation, type_variation, disable_alarm=True)
new_release_variation = self._makeSoftwareRelease(software_product)
self.addAllocationSupply("for compute node 2", remote_node, software_product,
new_release_variation, type_variation, disable_alarm=True)
self.tic()
self.assertEqual(None, instance_tree.InstanceTree_createUpgradeDecision())
def test_createUpgradeDecision_slaveAllocatedOnRemoteNode_newReleaseOnAnoterRemoteNode(self):
software_product, _, type_variation, _, _, instance_tree = self.bootstrapAllocableInstanceTree(allocation_state='allocated', shared=True, node="remote")
self.tic()
project = instance_tree.getFollowUpValue()
remote_node2 = self.portal.compute_node_module.newContent(
portal_type="Remote Node",
follow_up_value=project
)
new_release_variation = self._makeSoftwareRelease(software_product)
self.addAllocationSupply("for remote node 2", remote_node2, software_product,
new_release_variation, type_variation, disable_alarm=True)
self.tic()
self.assertEqual(None, instance_tree.InstanceTree_createUpgradeDecision())
##########################################################################
# Shared allocated on Instance Node
##########################################################################
def test_createUpgradeDecision_slaveAllocatedOnInstanceNode_newReleaseOnInstanceNode(self):
software_product, _, type_variation, compute_node, _, instance_tree = self.bootstrapAllocableInstanceTree(allocation_state='allocated', shared=True, node="instance")
self.tic()
new_release_variation = self._makeSoftwareRelease(software_product)
self.addAllocationSupply("for compute node", compute_node, software_product,
new_release_variation, type_variation, disable_alarm=True)
self.tic()
self.checkCreatedUpgradeDecision(
instance_tree.InstanceTree_createUpgradeDecision(),
instance_tree, software_product, new_release_variation, type_variation
)
def test_createUpgradeDecision_slaveAllocatedOnInstanceNode_newReleaseOnAnotherInstanceNode(self):
software_product, _, type_variation, _, _, instance_tree = self.bootstrapAllocableInstanceTree(allocation_state='allocated', shared=True, node="instance")
self.tic()
project = instance_tree.getFollowUpValue()
instance_node2 = self.portal.compute_node_module.newContent(
portal_type="Instance Node",
follow_up_value=project
)
new_release_variation = self._makeSoftwareRelease(software_product)
self.addAllocationSupply("for compute node", instance_node2, software_product,
new_release_variation, type_variation, disable_alarm=True)
self.tic()
self.assertEqual(None, instance_tree.InstanceTree_createUpgradeDecision())
# -*- coding: utf-8 -*-
##############################################################################
#
# Copyright (c) 2019 Nexedi SA and Contributors. All Rights Reserved.
#
# 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 erp5.component.test.SlapOSTestCaseMixin import SlapOSTestCaseMixin
class TestSlapOSDestroySoftwareInstallation(SlapOSTestCaseMixin):
def bootstrapSoftwareInstallation(self, is_allocated=True, is_supplied=True):
if is_allocated:
allocation_state = 'allocated'
else:
allocation_state = 'possible'
software_product, release_variation, type_variation, compute_node, _, _ = \
self.bootstrapAllocableInstanceTree(allocation_state=allocation_state)
software_installation = self.portal.software_installation_module.newContent(
portal_type='Software Installation',
follow_up_value=compute_node.getFollowUpValue(),
url_string=release_variation.getUrlString(),
aggregate_value=compute_node
)
self.portal.portal_workflow._jumpToStateFor(software_installation,
'start_requested')
self.portal.portal_workflow._jumpToStateFor(software_installation,
'validated')
supply = None
if is_supplied:
supply = self.addAllocationSupply("for compute node", compute_node, software_product,
release_variation, type_variation)
self.tic()
return software_installation, supply
########################################################
# Software Installation in expected state
########################################################
def test_destroyIfUnused_toDestroy(self):
software_installation, _ = self.bootstrapSoftwareInstallation(is_allocated=False, is_supplied=False)
software_installation.SoftwareInstallation_destroyIfUnused()
self.assertEqual('destroy_requested', software_installation.getSlapState())
self.assertEqual('validated', software_installation.getValidationState())
########################################################
# Software Installation not in expected state
########################################################
def test_destroyIfUnused_notStarted(self):
software_installation, _ = self.bootstrapSoftwareInstallation()
self.portal.portal_workflow._jumpToStateFor(software_installation,
'draft',
wf_id='installation_slap_interface_workflow')
software_installation.SoftwareInstallation_destroyIfUnused()
self.assertEqual('draft', software_installation.getSlapState())
self.assertEqual('validated', software_installation.getValidationState())
def test_destroyIfUnused_notValidated(self):
software_installation, _ = self.bootstrapSoftwareInstallation()
self.portal.portal_workflow._jumpToStateFor(software_installation,
'draft',
wf_id='item_workflow')
software_installation.SoftwareInstallation_destroyIfUnused()
self.assertEqual('start_requested', software_installation.getSlapState())
self.assertEqual('draft', software_installation.getValidationState())
########################################################
# Software Installation used
########################################################
def test_destroyIfUnused_oneInstanceUsed(self):
software_installation, _ = self.bootstrapSoftwareInstallation(is_allocated=True, is_supplied=False)
software_installation.SoftwareInstallation_destroyIfUnused()
self.assertEqual('start_requested', software_installation.getSlapState())
self.assertEqual('validated', software_installation.getValidationState())
def test_destroyIfUnused_oneSupply(self):
software_installation, _ = self.bootstrapSoftwareInstallation(is_allocated=False, is_supplied=True)
software_installation.SoftwareInstallation_destroyIfUnused()
self.assertEqual('start_requested', software_installation.getSlapState())
self.assertEqual('validated', software_installation.getValidationState())
########################################################
# Supply invalidated
########################################################
def test_destroyIfUnused_oneInvalidatedSupply(self):
software_installation, supply = self.bootstrapSoftwareInstallation(is_allocated=False, is_supplied=True)
supply.invalidate()
self.tic()
software_installation.SoftwareInstallation_destroyIfUnused()
self.assertEqual('start_requested', software_installation.getSlapState())
self.assertEqual('validated', software_installation.getValidationState())
......@@ -6,15 +6,9 @@
</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>testSlapOSPDMDestroySoftwareInstallationWithArchivedSoftwareReleaseAlarm</string> </value>
<value> <string>testSlapOSPDMDestroySoftwareInstallation</string> </value>
</item>
<item>
<key> <string>description</string> </key>
......@@ -24,7 +18,7 @@
</item>
<item>
<key> <string>id</string> </key>
<value> <string>test.erp5.testSlapOSPDMDestroySoftwareInstallationWithArchivedSoftwareReleaseAlarm</string> </value>
<value> <string>test.erp5.testSlapOSPDMDestroySoftwareInstallation</string> </value>
</item>
<item>
<key> <string>portal_type</string> </key>
......@@ -55,28 +49,13 @@
<item>
<key> <string>workflow_history</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAM=</string> </persistent>
<persistent> <string encoding="base64">AAAAAAAAAAI=</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>
......@@ -89,7 +68,7 @@
<item>
<key> <string>component_validation_workflow</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAQ=</string> </persistent>
<persistent> <string encoding="base64">AAAAAAAAAAM=</string> </persistent>
</value>
</item>
</dictionary>
......@@ -98,7 +77,7 @@
</dictionary>
</pickle>
</record>
<record id="4" aka="AAAAAAAAAAQ=">
<record id="3" aka="AAAAAAAAAAM=">
<pickle>
<global name="WorkflowHistoryList" module="Products.ERP5Type.Workflow"/>
</pickle>
......
# -*- coding: utf-8 -*-
##############################################################################
#
# Copyright (c) 2019 Nexedi SA and Contributors. All Rights Reserved.
#
# 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 erp5.component.test.SlapOSTestCaseMixin import SlapOSTestCaseMixin
from erp5.component.test.testSlapOSAccountingAlarm import simulateByEditWorkflowMark
class TestSlapOSDestroySoftwareInstallationWithArchivedSoftwareReleaseAlarm(SlapOSTestCaseMixin):
def createInstance(self, url_string):
instance_tree = self.portal.instance_tree_module\
.template_instance_tree.Base_createCloneDocument(batch_mode=1)
instance_tree.edit(
)
instance_tree.validate()
instance_tree.edit(
title=self.generateNewSoftwareTitle(),
reference="TESTHS-%s" % self.generateNewId(),
)
request_kw = dict(
software_release=url_string,
software_type=self.generateNewSoftwareType(),
instance_xml=self.generateSafeXml(),
sla_xml=self.generateSafeXml(),
shared=False,
software_title=instance_tree.getTitle(),
state='started'
)
instance_tree.requestStart(**request_kw)
instance_tree.requestInstance(**request_kw)
instance = instance_tree.getSuccessorValue()
self.tic()
return instance
def test(self):
preference = self.portal.portal_preferences.getActiveSystemPreference()
preference.setPreferredCloudContractEnabled(True)
self.tic()
compute_node, partition = self._makeComputeNode()
compute_node.setUpgradeScope('auto')
archived_url_string = self.generateNewSoftwareReleaseUrl()
# create software release
archived_software_release = self.portal.software_release_module.newContent(
portal_type='Software Release',
version='1',
url_string=archived_url_string
)
archived_software_release.publish()
archived_software_release.archive()
# install an software release
archived_software_installation = self.portal.software_installation_module\
.newContent(portal_type='Software Installation',
url_string=archived_url_string,
aggregate=compute_node.getRelativeUrl())
archived_software_installation.validate()
archived_software_installation.requestStart()
archived_used_url_string = self.generateNewSoftwareReleaseUrl()
# create software release
archived_used_software_release = self.portal.software_release_module.newContent(
portal_type='Software Release',
version='1',
url_string=archived_used_url_string
)
archived_used_software_release.publish()
archived_used_software_release.archive()
# install an software release
archived_used_software_installation = self.portal.software_installation_module\
.newContent(portal_type='Software Installation',
url_string=archived_used_url_string,
aggregate=compute_node.getRelativeUrl())
archived_used_software_installation.validate()
archived_used_software_installation.requestStart()
# use the software release
instance = self.createInstance(archived_used_url_string)
instance.setAggregate(partition.getRelativeUrl())
partition.markBusy()
self.tic()
published_url_string = self.generateNewSoftwareReleaseUrl()
# create software release
published_software_release = self.portal.software_release_module.newContent(
portal_type='Software Release',
version='1',
url_string=published_url_string
)
published_software_release.publish()
# install an software release
published_software_installation = self.portal.software_installation_module\
.newContent(portal_type='Software Installation',
url_string=published_url_string,
aggregate=compute_node.getRelativeUrl())
published_software_installation.validate()
published_software_installation.requestStart()
self.tic()
# first run touches software installation
self.stepCallSlaposPdmDestroySoftwareInstallationWithArchivedSoftwareReleaseAlarm()
self.tic()
self.assertEqual('destroy_requested', archived_software_installation.getSlapState())
self.assertEqual('validated', archived_software_installation.getValidationState())
self.assertEqual('start_requested', published_software_installation.getSlapState())
self.assertEqual('validated', published_software_installation.getValidationState())
self.assertEqual('start_requested', archived_used_software_installation.getSlapState())
self.assertEqual('validated', archived_used_software_installation.getValidationState())
# second run, but it is still not reported that software installation is destroyed
self.stepCallSlaposPdmDestroySoftwareInstallationWithArchivedSoftwareReleaseAlarm()
self.tic()
self.assertEqual('start_requested', published_software_installation.getSlapState())
self.assertEqual('validated', archived_used_software_installation.getValidationState())
self.assertEqual('start_requested', archived_used_software_installation.getSlapState())
def test_manual_upgrade_scope(self):
preference = self.portal.portal_preferences.getActiveSystemPreference()
preference.setPreferredCloudContractEnabled(True)
self.tic()
compute_node, partition = self._makeComputeNode()
compute_node.setUpgradeScope('confirmation')
archived_url_string = self.generateNewSoftwareReleaseUrl()
# create software release
archived_software_release = self.portal.software_release_module.newContent(
portal_type='Software Release',
version='1',
url_string=archived_url_string
)
archived_software_release.publish()
archived_software_release.archive()
# install an software release
archived_software_installation = self.portal.software_installation_module\
.newContent(portal_type='Software Installation',
url_string=archived_url_string,
aggregate=compute_node.getRelativeUrl())
archived_software_installation.validate()
archived_software_installation.requestStart()
archived_used_url_string = self.generateNewSoftwareReleaseUrl()
# create software release
archived_used_software_release = self.portal.software_release_module.newContent(
portal_type='Software Release',
version='1',
url_string=archived_used_url_string
)
archived_used_software_release.publish()
archived_used_software_release.archive()
# install an software release
archived_used_software_installation = self.portal.software_installation_module\
.newContent(portal_type='Software Installation',
url_string=archived_used_url_string,
aggregate=compute_node.getRelativeUrl())
archived_used_software_installation.validate()
archived_used_software_installation.requestStart()
# use the software release
instance = self.createInstance(archived_used_url_string)
instance.setAggregate(partition.getRelativeUrl())
partition.markBusy()
self.tic()
published_url_string = self.generateNewSoftwareReleaseUrl()
# create software release
published_software_release = self.portal.software_release_module.newContent(
portal_type='Software Release',
version='1',
url_string=published_url_string
)
published_software_release.publish()
# install an software release
published_software_installation = self.portal.software_installation_module\
.newContent(portal_type='Software Installation',
url_string=published_url_string,
aggregate=compute_node.getRelativeUrl())
published_software_installation.validate()
published_software_installation.requestStart()
self.tic()
# as Compute Node is manually managed, nothing happens
self.stepCallSlaposPdmDestroySoftwareInstallationWithArchivedSoftwareReleaseAlarm()
self.tic()
self.assertEqual('start_requested', archived_software_installation.getSlapState())
self.assertEqual('validated', archived_software_installation.getValidationState())
self.assertEqual('start_requested', published_software_installation.getSlapState())
self.assertEqual('validated', published_software_installation.getValidationState())
self.assertEqual('start_requested', archived_used_software_installation.getSlapState())
self.assertEqual('validated', archived_used_software_installation.getValidationState())
@simulateByEditWorkflowMark('SoftwareRelease_findAndDestroySoftwareInstallation')
def test_no_op_run_software_release(self):
archived_software_release = self.portal.software_release_module.newContent(
portal_type='Software Release',
version='1',
url_string=self.generateNewSoftwareReleaseUrl(),
)
archived_software_release.publish()
archived_software_release.archive()
archived_cleaned_software_release = self.portal.software_release_module.newContent(
portal_type='Software Release',
version='1',
url_string=self.generateNewSoftwareReleaseUrl(),
)
archived_cleaned_software_release.publish()
archived_cleaned_software_release.archive()
published_software_release = self.portal.software_release_module.newContent(
portal_type='Software Release',
version='1',
url_string=self.generateNewSoftwareReleaseUrl(),
)
published_software_release.publish()
self.tic()
self.stepCallSlaposPdmDestroySoftwareInstallationWithArchivedSoftwareReleaseAlarm()
self.tic()
v = 'Visited by SoftwareRelease_findAndDestroySoftwareInstallation'
self.assertNotIn(v,
[q['comment'] for q in published_software_release.workflow_history['edit_workflow']])
self.assertIn(v,
[q['comment'] for q in archived_cleaned_software_release.workflow_history['edit_workflow']])
self.assertIn(v,
[q['comment'] for q in archived_software_release.workflow_history['edit_workflow']])
@simulateByEditWorkflowMark('SoftwareInstallation_destroyWithSoftwareReleaseArchived')
def test_no_op_run_software_installation(self):
preference = self.portal.portal_preferences.getActiveSystemPreference()
preference.setPreferredCloudContractEnabled(True)
self.tic()
compute_node, partition = self._makeComputeNode()
partition.invalidate()
partition.markBusy()
url_string = self.generateNewSoftwareReleaseUrl()
archived_software_release = self.portal.software_release_module.newContent(
portal_type='Software Release',
version='1',
url_string=url_string,
)
archived_software_release.publish()
archived_software_release.archive()
software_installation_validated_request_start = self.portal.software_installation_module\
.newContent(portal_type='Software Installation',
url_string=url_string,
aggregate=compute_node.getRelativeUrl())
software_installation_validated_request_start.validate()
software_installation_validated_request_start.requestStart()
software_installation_validated_request_destroy = self.portal.software_installation_module\
.newContent(portal_type='Software Installation',
url_string=url_string,
aggregate=compute_node.getRelativeUrl())
software_installation_validated_request_destroy.validate()
software_installation_validated_request_destroy.requestStart()
software_installation_validated_request_destroy.requestDestroy()
software_installation_invalidated_request_destroy = self.portal.software_installation_module\
.newContent(portal_type='Software Installation',
url_string=url_string,
aggregate=compute_node.getRelativeUrl())
software_installation_invalidated_request_destroy.validate()
software_installation_invalidated_request_destroy.requestStart()
software_installation_invalidated_request_destroy.requestDestroy()
software_installation_invalidated_request_destroy.invalidate()
self.tic()
# sanity check
self.assertEqual('validated', software_installation_validated_request_start.getValidationState())
self.assertEqual('start_requested', software_installation_validated_request_start.getSlapState())
self.assertEqual('validated', software_installation_validated_request_destroy.getValidationState())
self.assertEqual('destroy_requested', software_installation_validated_request_destroy.getSlapState())
self.assertEqual('invalidated', software_installation_invalidated_request_destroy.getValidationState())
self.assertEqual('destroy_requested', software_installation_invalidated_request_destroy.getSlapState())
self.stepCallSlaposPdmDestroySoftwareInstallationWithArchivedSoftwareReleaseAlarm()
self.tic()
v = 'Visited by SoftwareInstallation_destroyWithSoftwareReleaseArchived'
self.assertIn(v,
[q['comment'] for q in software_installation_validated_request_start.workflow_history['edit_workflow']])
self.assertNotIn(v,
[q['comment'] for q in software_installation_validated_request_destroy.workflow_history['edit_workflow']])
self.assertNotIn(v,
[q['comment'] for q in software_installation_invalidated_request_destroy.workflow_history['edit_workflow']])
\ No newline at end of file
......@@ -19,1488 +19,49 @@
#
##############################################################################
from erp5.component.test.SlapOSTestCaseMixin import SlapOSTestCaseMixin, simulate
from DateTime import DateTime
from erp5.component.test.SlapOSTestCaseMixin import SlapOSTestCaseMixin
class TestSlapOSPDMMixinSkins(SlapOSTestCaseMixin):
def afterSetUp(self):
SlapOSTestCaseMixin.afterSetUp(self)
self.new_id = self.generateNewId()
self.request_kw = dict(
software_title=self.generateNewSoftwareTitle(),
software_type=self.generateNewSoftwareType(),
instance_xml=self.generateSafeXml(),
sla_xml=self.generateEmptyXml(),
shared=False,
state="started"
)
class TestSlapOSPDMSkins(SlapOSTestCaseMixin):
def _makePerson(self):
person_user = self.makePerson(new_id=self.new_id)
return person_user
def _makeComputePartitions(self, compute_node):
for i in range(1, 5):
id_ = 'partition%s' % (i, )
p = compute_node.newContent(portal_type='Compute Partition',
id=id_,
title=id_,
reference=id_,
default_network_address_ip_address='ip_address_%s' % i,
default_network_address_netmask='netmask_%s' % i)
p.markFree()
p.validate()
def _markComputePartitionBusy(self, compute_node, software_instance):
for partition in compute_node.contentValues(portal_type='Compute Partition'):
if partition.getSlapState() == 'free':
software_instance.edit(aggregate=partition.getRelativeUrl())
partition.markBusy()
break
def _requestSoftwareRelease(self, software_product_url, effective_date=None):
software_release = self._makeSoftwareRelease()
if not effective_date:
effective_date = DateTime()
software_release.edit(
aggregate_value=software_product_url,
effective_date=effective_date
)
software_release.publish()
return software_release
def _makeCustomSoftwareRelease(self, software_product_url, software_url):
software_release = self._makeSoftwareRelease()
software_release.edit(
aggregate_value=software_product_url,
url_string=software_url
)
software_release.publish()
return software_release
def _makeSoftwareInstallation(self, compute_node, software_release_url):
software_installation = self.portal\
.software_installation_module.template_software_installation\
.Base_createCloneDocument(batch_mode=1)
new_id = self.generateNewId()
software_installation.edit(
url_string=software_release_url,
aggregate=compute_node.getRelativeUrl(),
reference='TESTSOFTINSTS-%s' % new_id,
title='Start requested for %s' % compute_node.getUid()
)
software_installation.validate()
software_installation.requestStart()
return software_installation
def _makeInstanceTree(self):
instance_tree = self.portal\
.instance_tree_module.template_instance_tree\
.Base_createCloneDocument(batch_mode=1)
instance_tree.validate()
instance_tree.edit(
title= "Test hosting sub start %s" % self.new_id,
reference="TESTHSS-%s" % self.new_id,
)
return instance_tree
def _makeSoftwareInstance(self, instance_tree, software_url):
kw = dict(
software_release=software_url,
software_type=self.generateNewSoftwareType(),
instance_xml=self.generateSafeXml(),
sla_xml=self.generateSafeXml(),
shared=False,
software_title=instance_tree.getTitle(),
state='started'
)
instance_tree.requestStart(**kw)
instance_tree.requestInstance(**kw)
def _makeFullInstanceTree(self, software_url="", person=None):
if not person:
person = self._makePerson()
instance_tree = self.portal\
.instance_tree_module.template_instance_tree\
.Base_createCloneDocument(batch_mode=1)
instance_tree.edit(
title=self.request_kw['software_title'],
reference="TESTHS-%s" % self.new_id,
url_string=software_url,
source_reference=self.request_kw['software_type'],
text_content=self.request_kw['instance_xml'],
sla_xml=self.request_kw['sla_xml'],
root_slave=self.request_kw['shared'],
destination_section=person.getRelativeUrl()
)
instance_tree.validate()
self.portal.portal_workflow._jumpToStateFor(instance_tree, 'start_requested')
return instance_tree
def _makeFullSoftwareInstance(self, instance_tree, software_url):
software_instance = self.portal.software_instance_module\
.template_software_instance.Base_createCloneDocument(batch_mode=1)
software_instance.edit(
title=self.request_kw['software_title'],
reference="TESTSI-%s" % self.generateNewId(),
url_string=software_url,
source_reference=self.request_kw['software_type'],
text_content=self.request_kw['instance_xml'],
sla_xml=self.request_kw['sla_xml'],
specialise=instance_tree.getRelativeUrl()
)
instance_tree.edit(
successor=software_instance.getRelativeUrl()
)
self.portal.portal_workflow._jumpToStateFor(software_instance, 'start_requested')
software_instance.validate()
return software_instance
def _makeUpgradeDecision(self):
return self.portal.\
upgrade_decision_module.newContent(
portal_type="Upgrade Decision",
title="TESTUPDE-%s" % self.new_id)
def _makeUpgradeDecisionLine(self, upgrade_decision):
return upgrade_decision.newContent(
portal_type="Upgrade Decision Line",
title="TESTUPDE-%s" % self.new_id)
class TestSlapOSPDMSkins(TestSlapOSPDMMixinSkins):
def beforeTearDown(self):
id_list = []
for upgrade_decision in self.portal.portal_catalog(
portal_type="Upgrade Decision", reference="UD-TEST%"):
id_list.append(upgrade_decision.getId())
self.portal.upgrade_decision_module.manage_delObjects(id_list)
self.tic()
def test_getSortedSoftwareReleaseListFromSoftwareProduct(self):
software_product = self._makeSoftwareProduct()
release_list = software_product.SoftwareProduct_getSortedSoftwareReleaseList(
software_product.getReference())
self.assertEqual(release_list, [])
# published software release
software_release1 = self._makeSoftwareRelease()
software_release1.edit(aggregate_value=software_product.getRelativeUrl(),
url_string='http://example.org/1-%s.cfg' % self.new_id,
effective_date=(DateTime() + 5)
)
software_release1.publish()
software_release2 = self._makeSoftwareRelease()
software_release2.edit(aggregate_value=software_product.getRelativeUrl(),
url_string='http://example.org/2-%s.cfg' % self.new_id
)
software_release2.publish()
# 1 released software release, should not appear
software_release3 = self._makeSoftwareRelease()
self.assertTrue(software_release3.getValidationState() == 'released')
software_release3.edit(aggregate_value=software_product.getRelativeUrl(),
url_string='http://example.org/3-%s.cfg' % self.new_id
)
self.tic()
release_list = software_product.SoftwareProduct_getSortedSoftwareReleaseList(
software_product.getReference())
self.assertEqual([release.getUrlString() for release in release_list],
['http://example.org/2-%s.cfg' % self.new_id, 'http://example.org/1-%s.cfg' % self.new_id])
def test_getSortedSoftwareReleaseListFromSoftwareProduct_Changed(self):
software_product = self._makeSoftwareProduct()
release_list = software_product.SoftwareProduct_getSortedSoftwareReleaseList(
software_product.getReference())
self.assertEqual(release_list, [])
# 2 published software releases
software_release2 = self._makeSoftwareRelease()
software_release2.publish()
software_release2.edit(aggregate_value=software_product.getRelativeUrl(),
url_string='http://example.org/2-%s.cfg' % self.new_id,
effective_date=(DateTime() - 2)
)
# Newest software release
software_release1 = self._makeSoftwareRelease()
software_release1.publish()
software_release1.edit(aggregate_value=software_product.getRelativeUrl(),
url_string='http://example.org/1-%s.cfg' % self.new_id,
effective_date=DateTime()
)
self.tic()
release_list = software_product.SoftwareProduct_getSortedSoftwareReleaseList(
software_product.getReference())
self.assertEqual([release.getUrlString() for release in release_list],
['http://example.org/1-%s.cfg' % self.new_id, 'http://example.org/2-%s.cfg' % self.new_id])
release_list = software_product.SoftwareProduct_getSortedSoftwareReleaseList(
software_release_url='http://example.org/1-%s.cfg' % self.new_id)
self.assertEqual([release.getUrlString() for release in release_list],
['http://example.org/1-%s.cfg' % self.new_id, 'http://example.org/2-%s.cfg' % self.new_id])
def test_InstanceTree_getNewerSofwareRelease(self):
person = self._makePerson()
compute_node, _ = self._makeComputeNode(owner=person)
software_product = self._makeSoftwareProduct()
oldest_software_url = 'http://example.org/oldest-%s.cfg' % self.new_id
newest_software_url = 'http://example.org/newest-%s.cfg' % self.new_id
self._makeCustomSoftwareRelease(
software_product.getRelativeUrl(),
oldest_software_url)
self._makeCustomSoftwareRelease(software_product.getRelativeUrl(),
newest_software_url)
self._makeSoftwareInstallation( compute_node, oldest_software_url)
instance_tree = self._makeFullInstanceTree(
oldest_software_url, person)
self.tic()
self.assertEqual(instance_tree.InstanceTree_getNewerSofwareRelease(),
None)
self._makeFullSoftwareInstance(instance_tree, oldest_software_url)
self.tic()
release = instance_tree.InstanceTree_getNewerSofwareRelease()
self.assertEqual(release.getUrlString(), newest_software_url)
def testInstanceTree_getUpgradableSoftwareRelease_no_installation(self):
person = self._makePerson()
compute_node, _ = self._makeComputeNode(owner=person)
self._makeComputePartitions(compute_node)
software_product = self._makeSoftwareProduct()
oldest_software_url = 'http://example.org/oldest-%s.cfg' % self.new_id
newest_software_url = 'http://example.org/newest-%s.cfg' % self.new_id
self._makeCustomSoftwareRelease(
software_product.getRelativeUrl(),
oldest_software_url)
self._makeSoftwareInstallation( compute_node, oldest_software_url)
hs = self._makeFullInstanceTree(
oldest_software_url, person)
self.tic()
self.assertEqual(hs.InstanceTree_getUpgradableSoftwareRelease(),
None)
self._makeFullSoftwareInstance(hs, oldest_software_url)
self._markComputePartitionBusy(compute_node, hs.getSuccessorValue())
self._makeCustomSoftwareRelease(software_product.getRelativeUrl(),
newest_software_url)
self.tic()
self.assertEqual(hs.InstanceTree_getUpgradableSoftwareRelease(),
None)
def testInstanceTree_getUpgradableSoftwareRelease(self):
person = self._makePerson()
compute_node, _ = self._makeComputeNode(owner=person)
self._makeComputePartitions(compute_node)
software_product = self._makeSoftwareProduct()
oldest_software_url = 'http://example.org/oldest-%s.cfg' % self.new_id
newest_software_url = 'http://example.org/newest-%s.cfg' % self.new_id
self._makeCustomSoftwareRelease(
software_product.getRelativeUrl(),
oldest_software_url)
self._makeSoftwareInstallation( compute_node, oldest_software_url)
hs = self._makeFullInstanceTree(
oldest_software_url, person)
self._makeFullSoftwareInstance(hs, oldest_software_url)
self._markComputePartitionBusy(compute_node, hs.getSuccessorValue())
self._makeCustomSoftwareRelease(software_product.getRelativeUrl(),
newest_software_url)
self._makeSoftwareInstallation(compute_node,
newest_software_url)
# software_release should be ignored!
software_release = self._makeSoftwareRelease()
self._makeSoftwareInstallation(compute_node, software_release.getUrlString())
self.tic()
release = hs.InstanceTree_getUpgradableSoftwareRelease()
self.assertEqual(release.getUrlString(), newest_software_url)
self.portal.portal_workflow._jumpToStateFor(hs, 'destroy_requested')
self.tic()
self.assertEqual(hs.InstanceTree_getUpgradableSoftwareRelease(),
None)
def testUpgradeDecision_getComputeNode(self):
compute_node, _ = self._makeComputeNode()
upgrade_decision = self._makeUpgradeDecision()
upgrade_decision_line = self._makeUpgradeDecisionLine(upgrade_decision)
upgrade_decision_line.setAggregateValue(compute_node)
found_compute_node = upgrade_decision.UpgradeDecision_getAggregateValue("Compute Node")
self.assertEqual(compute_node.getRelativeUrl(),
found_compute_node.getRelativeUrl())
def testUpgradeDecision_getComputeNode_2_lines(self):
compute_node, _ = self._makeComputeNode()
upgrade_decision = self._makeUpgradeDecision()
upgrade_decision_line = self._makeUpgradeDecisionLine(upgrade_decision)
upgrade_decision_line.setAggregateValue(compute_node)
upgrade_decision_line = self._makeUpgradeDecisionLine(upgrade_decision)
found_compute_node = upgrade_decision.UpgradeDecision_getAggregateValue("Compute Node")
self.assertEqual(compute_node.getRelativeUrl(),
found_compute_node.getRelativeUrl())
def testUpgradeDecision_getComputeNode_2_compute_node(self):
compute_node, _ = self._makeComputeNode()
upgrade_decision = self._makeUpgradeDecision()
upgrade_decision_line = self._makeUpgradeDecisionLine(upgrade_decision)
upgrade_decision_line.setAggregateValue(compute_node)
upgrade_decision_line = self._makeUpgradeDecisionLine(upgrade_decision)
upgrade_decision_line.setAggregateValue(compute_node)
self.assertRaises(ValueError, upgrade_decision.UpgradeDecision_getAggregateValue,
document_portal_type="Compute Node")
def testUpgradeDecision_getComputeNode_O_compute_node(self):
upgrade_decision = self._makeUpgradeDecision()
self._makeUpgradeDecisionLine(upgrade_decision)
found_compute_node = upgrade_decision.UpgradeDecision_getAggregateValue("Compute Node")
self.assertEqual(None, found_compute_node)
def testUpgradeDecision_getInstanceTree(self):
instance_tree = self._makeInstanceTree()
upgrade_decision = self._makeUpgradeDecision()
upgrade_decision_line = self._makeUpgradeDecisionLine(upgrade_decision)
upgrade_decision_line.setAggregateValue(instance_tree)
found_instance_tree = upgrade_decision.UpgradeDecision_getAggregateValue("Instance Tree")
self.assertEqual(instance_tree.getRelativeUrl(),
found_instance_tree.getRelativeUrl())
def testUpgradeDecision_getInstanceTree_2_lines(self):
instance_tree = self._makeInstanceTree()
upgrade_decision = self._makeUpgradeDecision()
upgrade_decision_line = self._makeUpgradeDecisionLine(upgrade_decision)
upgrade_decision_line.setAggregateValue(instance_tree)
upgrade_decision_line = self._makeUpgradeDecisionLine(upgrade_decision)
found_instance_tree = upgrade_decision.UpgradeDecision_getAggregateValue("Instance Tree")
self.assertEqual(instance_tree.getRelativeUrl(),
found_instance_tree.getRelativeUrl())
def testUpgradeDecision_getInstanceTree_2_hosting(self):
instance_tree = self._makeInstanceTree()
upgrade_decision = self._makeUpgradeDecision()
upgrade_decision_line = self._makeUpgradeDecisionLine(upgrade_decision)
upgrade_decision_line.setAggregateValue(instance_tree)
upgrade_decision_line = self._makeUpgradeDecisionLine(upgrade_decision)
upgrade_decision_line.setAggregateValue(instance_tree)
self.assertRaises(ValueError, upgrade_decision.UpgradeDecision_getAggregateValue,
document_portal_type="Instance Tree")
def testUpgradeDecision_getInstanceTree_O_hosting(self):
upgrade_decision = self._makeUpgradeDecision()
self._makeUpgradeDecisionLine(upgrade_decision)
found_instance_tree = upgrade_decision.UpgradeDecision_getAggregateValue("Instance Tree")
self.assertEqual(None, found_instance_tree)
def testUpgradeDecision_getAggregateValue_SoftwareRelease(self):
software_release = self._makeSoftwareRelease()
upgrade_decision = self._makeUpgradeDecision()
upgrade_decision_line = self._makeUpgradeDecisionLine(upgrade_decision)
upgrade_decision_line.setAggregateValue(software_release)
found_software_release = upgrade_decision.UpgradeDecision_getAggregateValue("Software Release")
self.assertEqual(software_release.getRelativeUrl(),
found_software_release.getRelativeUrl())
def testUpgradeDecision_getAggregateValue_SoftwareRelease_2_lines(self):
software_release = self._makeSoftwareRelease()
upgrade_decision = self._makeUpgradeDecision()
upgrade_decision_line = self._makeUpgradeDecisionLine(upgrade_decision)
upgrade_decision_line.setAggregateValue(software_release)
upgrade_decision_line = self._makeUpgradeDecisionLine(upgrade_decision)
found_software_release = upgrade_decision.UpgradeDecision_getAggregateValue("Software Release")
self.assertEqual(software_release.getRelativeUrl(),
found_software_release.getRelativeUrl())
def testUpgradeDecision_getAggregateValue_SoftwareRelease_2_sr(self):
software_release = self._makeSoftwareRelease()
upgrade_decision = self._makeUpgradeDecision()
upgrade_decision_line = self._makeUpgradeDecisionLine(upgrade_decision)
upgrade_decision_line.setAggregateValue(software_release)
upgrade_decision_line = self._makeUpgradeDecisionLine(upgrade_decision)
upgrade_decision_line.setAggregateValue(software_release)
self.assertRaises(ValueError, upgrade_decision.UpgradeDecision_getAggregateValue,
document_portal_type="Software Release")
def testUpgradeDecision_getAggregateValue_SoftwareRelease_O_sr(self):
upgrade_decision = self._makeUpgradeDecision()
self._makeUpgradeDecisionLine(upgrade_decision)
found_software_release = upgrade_decision.UpgradeDecision_getAggregateValue("Software Release")
self.assertEqual(None, found_software_release)
def testUpgradeDecision_getAggregateUrlString_SoftwareRelease(self):
software_release = self._makeSoftwareRelease()
upgrade_decision = self._makeUpgradeDecision()
upgrade_decision_line = self._makeUpgradeDecisionLine(upgrade_decision)
upgrade_decision_line.setAggregateValue(software_release)
url_string = upgrade_decision.UpgradeDecision_getAggregateUrlString()
self.assertNotEqual(None, url_string)
self.assertEqual(software_release.getUrlString(), url_string)
def testSoftwareRelease_createUpgradeDecision_compute_node(self):
person = self._makePerson()
compute_node, _ = self._makeComputeNode(owner=person)
software_release = self._makeSoftwareRelease()
upgrade_decision = software_release.SoftwareRelease_createUpgradeDecision(
source_url=compute_node.getRelativeUrl(),
title="TEST-SRUPDE-%s" % self.new_id)
self.tic()
self.assertEqual(upgrade_decision.getSimulationState(), 'draft')
self.assertEqual(upgrade_decision.getDestinationSection(),
person.getRelativeUrl())
decision_line = upgrade_decision.contentValues(
portal_type='Upgrade Decision Line')[0]
self.assertEqual(decision_line.getTitle(),
'Request decision upgrade for %s on Compute Node %s' % (
software_release.getTitle(), compute_node.getReference())
)
self.assertEqual(decision_line.getAggregate(portal_type='Compute Node'),
compute_node.getRelativeUrl())
self.assertEqual(decision_line.getAggregate(portal_type='Software Release'),
software_release.getRelativeUrl())
def testSoftwareRelease_createUpgradeDecision_hostingSubscription(self):
person = self._makePerson()
instance_tree = self._makeInstanceTree()
instance_tree.edit(
destination_section_value = person.getRelativeUrl())
software_release = self._makeSoftwareRelease()
upgrade_decision = software_release.SoftwareRelease_createUpgradeDecision(
source_url=instance_tree.getRelativeUrl(),
title="TEST-SRUPDE-%s" % self.new_id)
self.tic()
self.assertEqual(upgrade_decision.getSimulationState(), 'draft')
self.assertEqual(upgrade_decision.getDestinationSection(),
person.getRelativeUrl())
decision_line = upgrade_decision.contentValues(
portal_type='Upgrade Decision Line')[0]
self.assertEqual(decision_line.getAggregate(portal_type='Instance Tree'),
instance_tree.getRelativeUrl())
self.assertEqual(decision_line.getAggregate(portal_type='Software Release'),
software_release.getRelativeUrl())
def testSoftwareRelease_getUpgradeDecisionInProgress(self):
compute_node, _ = self._makeComputeNode()
software_product = self._makeSoftwareProduct()
software_release = self._requestSoftwareRelease(
software_product.getRelativeUrl())
upgrade_decision = self._makeUpgradeDecision()
upgrade_decision_line = self._makeUpgradeDecisionLine(upgrade_decision)
upgrade_decision_line.setAggregateValueList([software_release, compute_node])
software_release2 = self._makeSoftwareRelease()
upgrade_decision.confirm()
reference = upgrade_decision.getReference()
self.tic()
in_progress = software_release.SoftwareRelease_getUpgradeDecisionInProgress(
compute_node.getUid())
self.assertEqual(in_progress.getReference(), reference)
in_progress = software_release.SoftwareRelease_getUpgradeDecisionInProgress(
software_release.getUid())
self.assertEqual(in_progress.getReference(), reference)
in_progress = software_release2.SoftwareRelease_getUpgradeDecisionInProgress(
compute_node.getUid())
self.assertEqual(in_progress, None)
def testSoftwareRelease_getUpgradeDecisionInProgress_cancelled(self):
compute_node, _ = self._makeComputeNode()
software_product = self._makeSoftwareProduct()
software_release = self._requestSoftwareRelease(
software_product.getRelativeUrl())
upgrade_decision = self._makeUpgradeDecision()
upgrade_decision_line = self._makeUpgradeDecisionLine(upgrade_decision)
upgrade_decision_line.setAggregateValueList([software_release, compute_node])
upgrade_decision.confirm()
upgrade_decision.cancel()
self.tic()
in_progress = software_release.SoftwareRelease_getUpgradeDecisionInProgress(
compute_node.getUid())
self.assertEqual(in_progress, None)
upgrade_decision2 = self._makeUpgradeDecision()
upgrade_decision_line2 = self._makeUpgradeDecisionLine(upgrade_decision2)
upgrade_decision_line2.setAggregateValueList([software_release, compute_node])
upgrade_decision2.confirm()
upgrade_decision2.start()
self.tic()
in_progress = software_release.SoftwareRelease_getUpgradeDecisionInProgress(
compute_node.getUid())
self.assertEqual(in_progress.getReference(), upgrade_decision2.getReference())
def testSoftwareRelease_getUpgradeDecisionInProgress_rejected(self):
compute_node, _ = self._makeComputeNode()
software_product = self._makeSoftwareProduct()
software_release = self._requestSoftwareRelease(
software_product.getRelativeUrl())
upgrade_decision = self._makeUpgradeDecision()
upgrade_decision_line = self._makeUpgradeDecisionLine(upgrade_decision)
upgrade_decision_line.setAggregateValueList([software_release, compute_node])
upgrade_decision.confirm()
upgrade_decision.reject()
self.tic()
in_progress = software_release.SoftwareRelease_getUpgradeDecisionInProgress(
compute_node.getUid())
# XXX - in_progress is the rejected upgrade decision
self.assertEqual(in_progress.getReference(), upgrade_decision.getReference())
new_release = self._requestSoftwareRelease(
software_product.getRelativeUrl())
self.tic()
in_progress = new_release.SoftwareRelease_getUpgradeDecisionInProgress(
compute_node.getUid())
self.assertEqual(in_progress, None)
upgrade_decision2 = self._makeUpgradeDecision()
upgrade_decision_line2 = self._makeUpgradeDecisionLine(upgrade_decision2)
upgrade_decision_line2.setAggregateValueList([new_release, compute_node])
upgrade_decision2.confirm()
upgrade_decision2.start()
self.tic()
in_progress = new_release.SoftwareRelease_getUpgradeDecisionInProgress(
compute_node.getUid())
self.assertEqual(in_progress.getReference(), upgrade_decision2.getReference())
def testSoftwareRelease_getUpgradeDecisionInProgress_hosting_subs(self):
person = self._makePerson()
instance_tree = self._makeInstanceTree()
instance_tree.edit(
destination_section_value = person.getRelativeUrl())
software_product = self._makeSoftwareProduct()
software_release = self._requestSoftwareRelease(
software_product.getRelativeUrl())
upgrade_decision = self._makeUpgradeDecision()
upgrade_decision_line = self._makeUpgradeDecisionLine(upgrade_decision)
upgrade_decision_line.setAggregateValueList([software_release,
instance_tree])
upgrade_decision.confirm()
reference = upgrade_decision.getReference()
self.tic()
in_progress = software_release.SoftwareRelease_getUpgradeDecisionInProgress(
instance_tree.getUid())
self.assertEqual(in_progress.getReference(), reference)
upgrade_decision.cancel()
self.tic()
in_progress = software_release.SoftwareRelease_getUpgradeDecisionInProgress(
instance_tree.getUid())
self.assertEqual(in_progress, None)
def testSoftwareRelease_getUpgradeDecisionInProgress_software_product(self):
compute_node, _ = self._makeComputeNode()
software_product = self._makeSoftwareProduct()
software_release = self._requestSoftwareRelease(
software_product.getRelativeUrl())
software_release2 = self._requestSoftwareRelease(
software_product.getRelativeUrl())
software_release3 = self._makeSoftwareRelease()
upgrade_decision = self._makeUpgradeDecision()
upgrade_decision_line = self._makeUpgradeDecisionLine(upgrade_decision)
upgrade_decision_line.setAggregateValueList([software_release, compute_node])
upgrade_decision.confirm()
reference = upgrade_decision.getReference()
self.tic()
in_progress = software_release.SoftwareRelease_getUpgradeDecisionInProgress(
compute_node.getUid())
self.assertEqual(in_progress.getReference(), reference)
in_progress = software_release2.SoftwareRelease_getUpgradeDecisionInProgress(
compute_node.getUid())
self.assertEqual(in_progress.getReference(), reference)
in_progress = software_release3.SoftwareRelease_getUpgradeDecisionInProgress(
compute_node.getUid())
self.assertEqual(in_progress, None)
def testSoftwareRelease_getUpgradeDecisionInProgress_software_product_hs(self):
person = self._makePerson()
instance_tree = self._makeInstanceTree()
instance_tree.edit(
destination_section_value = person.getRelativeUrl())
software_product = self._makeSoftwareProduct()
software_release = self._requestSoftwareRelease(
software_product.getRelativeUrl())
software_release2 = self._requestSoftwareRelease(
software_product.getRelativeUrl())
software_release3 = self._makeSoftwareRelease()
upgrade_decision = self._makeUpgradeDecision()
upgrade_decision_line = self._makeUpgradeDecisionLine(upgrade_decision)
upgrade_decision_line.setAggregateValueList([software_release,
instance_tree])
upgrade_decision.confirm()
reference = upgrade_decision.getReference()
reference = upgrade_decision.getReference()
self.tic()
in_progress = software_release.SoftwareRelease_getUpgradeDecisionInProgress(
instance_tree.getUid())
self.assertEqual(in_progress.getReference(), reference)
in_progress = software_release2.SoftwareRelease_getUpgradeDecisionInProgress(
instance_tree.getUid())
self.assertEqual(in_progress.getReference(), reference)
in_progress = software_release3.SoftwareRelease_getUpgradeDecisionInProgress(
instance_tree.getUid())
self.assertEqual(in_progress, None)
def testComputeNode_checkAndCreateUpgradeDecision_auto(self):
person = self._makePerson()
compute_node, _ = self._makeComputeNode(owner=person,
allocation_scope="open/public")
compute_node.edit(upgrade_scope="auto")
software_product = self._makeSoftwareProduct()
software_release = self._requestSoftwareRelease(
software_product.getRelativeUrl())
self._makeSoftwareInstallation(
compute_node, software_release.getUrlString())
self.tic()
upgrade_decision = compute_node.ComputeNode_checkAndCreateUpgradeDecision()
self.assertEqual(len(upgrade_decision), 0)
software_release2 = self._requestSoftwareRelease(
software_product.getRelativeUrl())
# Should be ignored, Publication Date is for tomorrow
self._requestSoftwareRelease(software_product.getRelativeUrl(),
(DateTime() + 1))
def test_requestUpgrade(self):
software_product, _, type_variation, compute_node, _, instance_tree = self.bootstrapAllocableInstanceTree()
self.tic()
upgrade_decision = compute_node.ComputeNode_checkAndCreateUpgradeDecision()
self.assertEqual(len(upgrade_decision), 1)
self.assertEqual(upgrade_decision[0].getSimulationState(), 'started')
compute_node_aggregate = upgrade_decision[0].UpgradeDecision_getAggregateValue("Compute Node")
self.assertEqual(compute_node_aggregate,
compute_node)
release = upgrade_decision[0].UpgradeDecision_getAggregateValue("Software Release")
self.assertEqual(release.getUrlString(),
software_release2.getUrlString())
self.tic()
upgrade_decision2 = compute_node.ComputeNode_checkAndCreateUpgradeDecision()
self.assertEqual(len(upgrade_decision2), 0)
def testComputeNode_checkAndCreateUpgradeDecision_ask_confirmation_with_exist(self):
person = self._makePerson()
compute_node, _ = self._makeComputeNode(owner=person,
allocation_scope="open/personal")
compute_node.edit(upgrade_scope="ask_confirmation")
software_product = self._makeSoftwareProduct()
software_release = self._requestSoftwareRelease(
software_product.getRelativeUrl())
self._makeSoftwareInstallation(
compute_node, software_release.getUrlString())
self._requestSoftwareRelease(software_product.getRelativeUrl())
self.tic()
self.assertEqual(compute_node.getUpgradeScope(), "ask_confirmation")
upgrade_decision = compute_node.ComputeNode_checkAndCreateUpgradeDecision()[0]
self.assertEqual(upgrade_decision.getSimulationState(), 'planned')
software_release3 = self._requestSoftwareRelease(
software_product.getRelativeUrl())
self.tic()
upgrade_decision2 = compute_node.ComputeNode_checkAndCreateUpgradeDecision()[0]
self.assertEqual(upgrade_decision.getSimulationState(), 'cancelled')
self.assertEqual(upgrade_decision2.getSimulationState(), 'planned')
release = upgrade_decision2.UpgradeDecision_getAggregateValue("Software Release")
self.assertEqual(release.getUrlString(),
software_release3.getUrlString())
def testComputeNode_checkAndCreateUpgradeDecision_auto_with_exist(self):
person = self._makePerson()
compute_node, _ = self._makeComputeNode(owner=person,
allocation_scope="open/public")
compute_node.edit(upgrade_scope="auto")
software_product = self._makeSoftwareProduct()
software_release = self._requestSoftwareRelease(
software_product.getRelativeUrl())
self._makeSoftwareInstallation(compute_node, software_release.getUrlString())
self._requestSoftwareRelease(software_product.getRelativeUrl())
self.tic()
upgrade_decision = compute_node.ComputeNode_checkAndCreateUpgradeDecision()[0]
self.assertEqual(upgrade_decision.getSimulationState(), 'started')
self._requestSoftwareRelease(software_product.getRelativeUrl())
self.tic()
upgrade_decision2 = compute_node.ComputeNode_checkAndCreateUpgradeDecision()
self.assertEqual(len(upgrade_decision2), 0)
self.assertEqual(upgrade_decision.getSimulationState(), 'started')
def testBase_acceptUpgradeDecision_no_reference(self):
self._makeUpgradeDecision()
self.assertRaises(ValueError, self.portal.Base_acceptUpgradeDecision, None)
def testBase_acceptUpgradeDecision_duplicated_reference(self):
upgrade_decision = self._makeUpgradeDecision()
upgrade_decision.setReference("UD-TESTBADREFERENCE")
upgrade_decision = self._makeUpgradeDecision()
upgrade_decision.setReference("UD-TESTBADREFERENCE")
self.tic()
self.assertRaises(ValueError, self.portal.Base_acceptUpgradeDecision, None)
def testBase_acceptUpgradeDecision_no_upgrade_decision(self):
redirect_url = self.portal.Base_acceptUpgradeDecision('UD-UNEXISTING')
self.assertTrue(redirect_url.endswith(
"?portal_status_message=Unable%20to%20find%20the%20Upgrade%20Decision."),
"%s contains the wrong message" % redirect_url)
def testBase_acceptUpgradeDecision_draft_upgrade_decision(self):
upgrade_decision = self._makeUpgradeDecision()
upgrade_decision.setReference("UD-TESTDRAFT")
self.tic()
redirect_url = self.portal.Base_acceptUpgradeDecision('UD-TESTDRAFT')
self.assertTrue(redirect_url.endswith(
"?portal_status_message=Sorry%2C%20the%20upgrade%20is%20not%20possible%20yet%21"),
"%s contains the wrong message" % redirect_url)
def testBase_acceptUpgradeDecision_planned_upgrade_decision(self):
upgrade_decision = self._makeUpgradeDecision()
upgrade_decision.setReference("UD-TESTPLANNED")
upgrade_decision.plan()
self.tic()
redirect_url = self.portal.Base_acceptUpgradeDecision('UD-TESTPLANNED')
self.assertTrue(redirect_url.endswith(
"?portal_status_message=Sorry%2C%20the%20upgrade%20is%20not%20possible%20yet%21"),
"%s contains the wrong message" % redirect_url)
def testBase_acceptUpgradeDecision_confirmed_upgrade_decision(self):
upgrade_decision = self._makeUpgradeDecision()
upgrade_decision.setReference("UD-TESTCONFIRMED")
upgrade_decision.confirm()
self.tic()
redirect_url = self.portal.Base_acceptUpgradeDecision('UD-TESTCONFIRMED')
self.assertTrue(redirect_url.endswith(
"?portal_status_message=This%20Upgrade%20Decision%20has%20been%20"\
"requested%2C%20it%20will%20be%20processed%20in%20few%20minutes."),
"%s contains the wrong message" % redirect_url)
self.assertEqual(upgrade_decision.getSimulationState(), 'started')
def testBase_acceptUpgradeDecision_started_decision(self):
upgrade_decision = self._makeUpgradeDecision()
upgrade_decision.setReference("UD-TESTSTARTED")
upgrade_decision.start()
self.tic()
redirect_url = self.portal.Base_acceptUpgradeDecision('UD-TESTSTARTED')
self.assertTrue(redirect_url.endswith(
"?portal_status_message=This%20Upgrade%20Decision%20is%20already%20Started."),
"%s contains the wrong message" % redirect_url)
def testBase_acceptUpgradeDecision_stop_decision(self):
upgrade_decision = self._makeUpgradeDecision()
upgrade_decision.setReference("UD-TESTSTOP")
upgrade_decision.start()
upgrade_decision.stop()
self.tic()
redirect_url = self.portal.Base_acceptUpgradeDecision('UD-TESTSTOP')
self.assertTrue(redirect_url.endswith(
"?portal_status_message=This%20Upgrade%20Decision%20has%20been%20already%20processed."),
"%s contains the wrong message" % redirect_url)
def testBase_acceptUpgradeDecision_delivered_decision(self):
upgrade_decision = self._makeUpgradeDecision()
upgrade_decision.setReference("UD-TESTDELIVERED")
upgrade_decision.start()
upgrade_decision.stop()
upgrade_decision.deliver()
self.tic()
redirect_url = self.portal.Base_acceptUpgradeDecision('UD-TESTDELIVERED')
self.assertTrue(redirect_url.endswith(
"?portal_status_message=This%20Upgrade%20Decision%20has%20been%20already%20processed."),
"%s contains the wrong message" % redirect_url)
def testBase_acceptUpgradeDecision_cancelled_decision(self):
upgrade_decision = self._makeUpgradeDecision()
upgrade_decision.setReference("UD-TESTCANCELLED")
upgrade_decision.cancel()
self.tic()
redirect_url = self.portal.Base_acceptUpgradeDecision('UD-TESTCANCELLED')
self.assertTrue(redirect_url.endswith(
"?portal_status_message=Sorry%2C%20the%20upgrade%20is%20not%20possble%2C%20Upgrade%20Decision%20was%20Canceled%20or%20Rejected%21"),
"%s contains the wrong message" % redirect_url)
def testBase_acceptUpgradeDecision_rejected_decision(self):
upgrade_decision = self._makeUpgradeDecision()
upgrade_decision.setReference("UD-TESTREJECT")
upgrade_decision.cancel()
self.tic()
redirect_url = self.portal.Base_acceptUpgradeDecision('UD-TESTREJECT')
self.assertTrue(redirect_url.endswith(
"?portal_status_message=Sorry%2C%20the%20upgrade%20is%20not%20possble%2C%20Upgrade%20Decision%20was%20Canceled%20or%20Rejected%21"),
"%s contains the wrong message" % redirect_url)
def testBase_rejectUpgradeDecision_no_reference(self):
self._makeUpgradeDecision()
self.assertRaises(ValueError, self.portal.Base_rejectUpgradeDecision, None)
def testBase_rejectUpgradeDecision_duplicated_reference(self):
upgrade_decision = self._makeUpgradeDecision()
upgrade_decision.setReference("UD-TESTBADREFERENCE")
upgrade_decision = self._makeUpgradeDecision()
upgrade_decision.setReference("UD-TESTBADREFERENCE")
self.tic()
self.assertRaises(ValueError, self.portal.Base_acceptUpgradeDecision, None)
def testBase_rejectUpgradeDecision_no_upgrade_decision(self):
redirect_url = self.portal.Base_rejectUpgradeDecision('UD-UNEXISTING')
self.assertTrue(redirect_url.endswith(
"?portal_status_message=Unable%20to%20find%20the%20Upgrade%20Decision."),
"%s contains the wrong message" % redirect_url)
def testBase_rejectUpgradeDecision_draft_upgrade_decision(self):
upgrade_decision = self._makeUpgradeDecision()
upgrade_decision.setReference("UD-TESTDRAFT")
self.tic()
redirect_url = self.portal.Base_rejectUpgradeDecision('UD-TESTDRAFT')
self.assertTrue(redirect_url.endswith(
"?portal_status_message=Thanks%20Upgrade%20Decision%20has%20been"\
"%20rejected%20Successfully%20%28You%20cannot%20use%20it%20anymore%29."),
"%s contains the wrong message" % redirect_url)
self.assertEqual(upgrade_decision.getSimulationState(), 'rejected')
def testBase_rejectUpgradeDecision_planned_upgrade_decision(self):
upgrade_decision = self._makeUpgradeDecision()
upgrade_decision.setReference("UD-TESTPLANNED")
upgrade_decision.plan()
self.tic()
redirect_url = self.portal.Base_rejectUpgradeDecision('UD-TESTPLANNED')
self.assertTrue(redirect_url.endswith(
"?portal_status_message=Thanks%20Upgrade%20Decision%20has%20been"\
"%20rejected%20Successfully%20%28You%20cannot%20use%20it%20anymore%29."),
"%s contains the wrong message" % redirect_url)
self.assertEqual(upgrade_decision.getSimulationState(), 'rejected')
def testBase_rejectUpgradeDecision_confirmed_upgrade_decision(self):
upgrade_decision = self._makeUpgradeDecision()
upgrade_decision.setReference("UD-TESTCONFIRMED")
upgrade_decision.confirm()
new_release_variation = self._makeSoftwareRelease(software_product)
self.addAllocationSupply("for compute node", compute_node, software_product,
new_release_variation, type_variation, disable_alarm=True)
self.tic()
redirect_url = self.portal.Base_rejectUpgradeDecision('UD-TESTCONFIRMED')
self.assertTrue(redirect_url.endswith(
"?portal_status_message=Thanks%20Upgrade%20Decision%20has%20been"\
"%20rejected%20Successfully%20%28You%20cannot%20use%20it%20anymore%29."),
"%s contains the wrong message" % redirect_url)
self.assertEqual(upgrade_decision.getSimulationState(), 'rejected')
def testBase_rejectUpgradeDecision_started_decision(self):
upgrade_decision = self._makeUpgradeDecision()
upgrade_decision.setReference("UD-TESTSTARTED")
upgrade_decision = instance_tree.InstanceTree_createUpgradeDecision()
upgrade_decision.start()
self.tic()
redirect_url = self.portal.Base_rejectUpgradeDecision('UD-TESTSTARTED')
self.assertTrue(redirect_url.endswith(
"?portal_status_message=Sorry%2C%20This%20Upgrade%20Decision%20is%20"\
"already%20Started%2C%20you%20cannot%20reject%20it%20anymore."),
"%s contains the wrong message" % redirect_url)
self.portal.portal_workflow._jumpToStateFor(instance_tree,
'stop_requested')
def testBase_rejectUpgradeDecision_stop_decision(self):
upgrade_decision = self._makeUpgradeDecision()
upgrade_decision.setReference("UD-TESTSTOP")
upgrade_decision.start()
upgrade_decision.stop()
self.tic()
redirect_url = self.portal.Base_rejectUpgradeDecision('UD-TESTSTOP')
self.assertTrue(redirect_url.endswith(
"?portal_status_message=Sorry%2C%20this%20Upgrade%20Decision%20has%20been%20already%20processed."),
"%s contains the wrong message" % redirect_url)
upgrade_decision.UpgradeDecision_processUpgrade()
def testBase_rejectUpgradeDecision_delivered_decision(self):
upgrade_decision = self._makeUpgradeDecision()
upgrade_decision.setReference("UD-TESTDELIVERED")
upgrade_decision.start()
upgrade_decision.stop()
upgrade_decision.deliver()
self.tic()
redirect_url = self.portal.Base_rejectUpgradeDecision('UD-TESTDELIVERED')
self.assertTrue(redirect_url.endswith(
"?portal_status_message=Sorry%2C%20this%20Upgrade%20Decision%20has%20been%20already%20processed."),
"%s contains the wrong message" % redirect_url)
def testBase_rejectUpgradeDecision_cancelled_decision(self):
upgrade_decision = self._makeUpgradeDecision()
upgrade_decision.setReference("UD-TESTCANCELLED")
upgrade_decision.cancel()
self.tic()
redirect_url = self.portal.Base_rejectUpgradeDecision('UD-TESTCANCELLED')
self.assertTrue(redirect_url.endswith(
"?portal_status_message=Upgrade%20Decision%20is%20already%20Rejected%21"),
"%s contains the wrong message" % redirect_url)
self.assertEqual(new_release_variation.getUrlString(),
instance_tree.getUrlString())
self.assertEqual('stop_requested', instance_tree.getSlapState())
self.assertEqual('delivered', upgrade_decision.getSimulationState())
def testBase_rejectUpgradeDecision_reject_decision(self):
upgrade_decision = self._makeUpgradeDecision()
upgrade_decision.setReference("UD-TESTREJECT")
upgrade_decision.reject()
def test_requestUpgrade_destroyed_instance_tree(self):
software_product, _, type_variation, compute_node, _, instance_tree = self.bootstrapAllocableInstanceTree()
self.tic()
redirect_url = self.portal.Base_rejectUpgradeDecision('UD-TESTREJECT')
self.assertTrue(redirect_url.endswith(
"?portal_status_message=Upgrade%20Decision%20is%20already%20Rejected%21"),
"%s contains the wrong message" % redirect_url)
def testUpgradeDecision_isUpgradeFinished_compute_node(self):
compute_node, _ = self._makeComputeNode()
software_release = self._makeSoftwareRelease()
upgrade_decision = self._makeUpgradeDecision()
upgrade_decision_line = self._makeUpgradeDecisionLine(upgrade_decision)
upgrade_decision_line.setAggregateValueList([software_release, compute_node])
upgrade_decision.confirm()
upgrade_decision.stop()
self.assertFalse(upgrade_decision.UpgradeDecision_isUpgradeFinished())
self._makeSoftwareInstallation( compute_node,
software_release.getUrlString())
new_release_variation = self._makeSoftwareRelease(software_product)
self.addAllocationSupply("for compute node", compute_node, software_product,
new_release_variation, type_variation, disable_alarm=True)
self.tic()
self.assertTrue(upgrade_decision.UpgradeDecision_isUpgradeFinished())
def testUpgradeDecision_requestChangeState_started(self):
upgrade_decision = self._makeUpgradeDecision()
upgrade_decision.setReference("UD-TESTDECISION")
upgrade_decision.confirm()
requested_state = "started"
self.assertEqual(upgrade_decision.getSimulationState(), 'confirmed')
upgrade_decision.UpgradeDecision_requestChangeState(requested_state)
self.assertEqual(upgrade_decision.getSimulationState(), 'started')
def testUpgradeDecision_requestChangeState_reject(self):
upgrade_decision = self._makeUpgradeDecision()
upgrade_decision.setReference("UD-TESTDECISION")
upgrade_decision.confirm()
requested_state = "rejected"
self.assertEqual(upgrade_decision.getSimulationState(), 'confirmed')
upgrade_decision.UpgradeDecision_requestChangeState(requested_state)
self.assertEqual(upgrade_decision.getSimulationState(), 'rejected')
def testUpgradeDecision_requestChangeState_stopped(self):
upgrade_decision = self._makeUpgradeDecision()
upgrade_decision.setReference("UD-TESTDECISION")
upgrade_decision.confirm()
upgrade_decision.stop()
requested_state = "started"
self.assertEqual(upgrade_decision.getSimulationState(), 'stopped')
result = upgrade_decision.UpgradeDecision_requestChangeState(requested_state)
self.assertEqual(upgrade_decision.getSimulationState(), 'stopped')
self.assertEqual(result, "Transition from state %s to %s is not permitted" % (
upgrade_decision.getSimulationState(), requested_state))
def testUpgradeDecision_requestChangeState_rejected(self):
upgrade_decision = self._makeUpgradeDecision()
upgrade_decision.setReference("UD-TESTDECISION")
upgrade_decision.confirm()
upgrade_decision = instance_tree.InstanceTree_createUpgradeDecision()
upgrade_decision.start()
requested_state = "rejected"
self.assertEqual(upgrade_decision.getSimulationState(), 'started')
result = upgrade_decision.UpgradeDecision_requestChangeState(requested_state)
self.assertEqual(upgrade_decision.getSimulationState(), 'started')
self.assertEqual(result, "Transition from state %s to %s is not permitted" % (
upgrade_decision.getSimulationState(), requested_state))
def testUpgradeDecision_isUpgradeFinished_instance_tree(self):
instance_tree = self._makeInstanceTree()
software_release = self._makeSoftwareRelease()
upgrade_decision = self._makeUpgradeDecision()
upgrade_decision_line = self._makeUpgradeDecisionLine(upgrade_decision)
upgrade_decision_line.setAggregateValueList([software_release,
instance_tree])
upgrade_decision.confirm()
upgrade_decision.stop()
self.assertFalse(upgrade_decision.UpgradeDecision_isUpgradeFinished())
instance_tree.setUrlString(software_release.getUrlString())
self.assertTrue(upgrade_decision.UpgradeDecision_isUpgradeFinished())
self.portal.portal_workflow._jumpToStateFor(instance_tree,
'destroy_requested')
@simulate('NotificationTool_getDocumentValue',
'reference=None',
'assert reference == "slapos-upgrade-compute-node.notification"\n' \
'return context.restrictedTraverse(' \
'context.REQUEST["testUpgradeDecision_notify_compute_node"])')
def testUpgradeDecision_notify_compute_node(self):
person = self._makePerson()
compute_node, _ = self._makeComputeNode()
software_release = self._makeSoftwareRelease()
software_product = self._makeSoftwareProduct()
software_release.setAggregateValue(software_product)
upgrade_decision = self._makeUpgradeDecision()
upgrade_decision.edit(destination_decision_value=person)
upgrade_decision_line = self._makeUpgradeDecisionLine(upgrade_decision)
upgrade_decision_line.setAggregateValueList([software_release, compute_node])
notification_message = self.portal.notification_message_module.newContent(
portal_type="Notification Message",
title='Test NM title %s' % self.new_id,
text_content_substitution_mapping_method_id=
"NotificationMessage_getSubstitutionMappingDictFromArgument",
text_content="""${software_product_title}
${compute_node_title}
${compute_node_reference}
${software_release_name}
${software_release_reference}
${new_software_release_url}""",
content_type='text/html',
)
self.portal.REQUEST\
['testUpgradeDecision_notify_compute_node'] = \
notification_message.getRelativeUrl()
self.tic()
self.assertEqual(None, upgrade_decision.UpgradeDecision_notify())
upgrade_decision.plan()
self.tic()
self.assertEqual(None, upgrade_decision.UpgradeDecision_notify())
self.tic()
self.assertEqual(upgrade_decision.getSimulationState(), 'confirmed')
self.assertEqual(len(upgrade_decision.getFollowUpRelatedValueList()), 1)
event = upgrade_decision.getFollowUpRelatedValue()
self.assertEqual(event.getTitle(),
"New Software available for Installation at %s" % compute_node.getTitle())
self.assertEqual(event.getTextContent().splitlines(),
[software_product.getTitle(), compute_node.getTitle(), compute_node.getReference(),
software_release.getTitle(), software_release.getReference(),
software_release.getUrlString()])
self.assertEqual(event.getSimulationState(), "delivered")
@simulate('NotificationTool_getDocumentValue',
'reference=None',
'assert reference == "slapos-upgrade-instance-tree.notification"\n' \
'return context.restrictedTraverse(' \
'context.REQUEST["testUpgradeDecision_notify_instance_tree"])')
def testUpgradeDecision_notify_instance_tree(self):
person = self._makePerson()
instance_tree = self._makeInstanceTree()
software_release = self._makeSoftwareRelease()
software_product = self._makeSoftwareProduct()
software_release.setAggregateValue(software_product)
upgrade_decision = self._makeUpgradeDecision()
upgrade_decision.edit(destination_decision_value=person)
upgrade_decision_line = self._makeUpgradeDecisionLine(upgrade_decision)
upgrade_decision_line.setAggregateValueList([software_release,
instance_tree])
old_url = instance_tree.getUrlString()
notification_message = self.portal.notification_message_module.newContent(
portal_type="Notification Message",
title='Test NM title %s' % self.new_id,
text_content_substitution_mapping_method_id=
"NotificationMessage_getSubstitutionMappingDictFromArgument",
text_content="""${software_product_title}
${instance_tree_title}
${old_software_release_url}
${software_release_name}
${software_release_reference}
${new_software_release_url}""",
content_type='text/html',
)
self.portal.REQUEST\
['testUpgradeDecision_notify_instance_tree'] = \
notification_message.getRelativeUrl()
self.tic()
self.assertEqual(None, upgrade_decision.UpgradeDecision_notify())
upgrade_decision.plan()
self.tic()
self.assertEqual(None, upgrade_decision.UpgradeDecision_notify())
self.tic()
self.assertEqual(upgrade_decision.getSimulationState(), 'confirmed')
self.assertEqual(len(upgrade_decision.getFollowUpRelatedValueList()), 1)
event = upgrade_decision.getFollowUpRelatedValue()
self.assertEqual(event.getTitle(),
"New Upgrade available for %s" % instance_tree.getTitle())
self.assertEqual(event.getTextContent().splitlines(),
[software_product.getTitle(), instance_tree.getTitle(),
old_url, software_release.getTitle(), software_release.getReference(),
software_release.getUrlString()])
self.assertEqual(event.getSimulationState(), "delivered")
@simulate('NotificationTool_getDocumentValue',
'reference=None',
'assert reference == "slapos-upgrade-delivered-compute-node.notification"\n' \
'return context.restrictedTraverse(' \
'context.REQUEST["testUpgradeDecision_notifyDelivered_compute_node"])')
@simulate('UpgradeDecision_isUpgradeFinished',
'', 'return 1')
def testUpgradeDecision_notifyDelivered_compute_node(self):
person = self._makePerson()
compute_node, _ = self._makeComputeNode()
software_release = self._makeSoftwareRelease()
software_product = self._makeSoftwareProduct()
software_release.setAggregateValue(software_product)
upgrade_decision = self._makeUpgradeDecision()
upgrade_decision.edit(destination_decision_value=person)
upgrade_decision_line = self._makeUpgradeDecisionLine(upgrade_decision)
upgrade_decision_line.setAggregateValueList([software_release, compute_node])
notification_message = self.portal.notification_message_module.newContent(
portal_type="Notification Message",
title='Test NM title %s' % self.new_id,
text_content_substitution_mapping_method_id=
"NotificationMessage_getSubstitutionMappingDictFromArgument",
text_content="""${software_product_title}
${compute_node_title}
${compute_node_reference}
${software_release_name}
${software_release_reference}
${new_software_release_url}""",
content_type='text/html',
)
self.portal.REQUEST\
['testUpgradeDecision_notifyDelivered_compute_node'] = \
notification_message.getRelativeUrl()
self.tic()
self.assertEqual(None, upgrade_decision.UpgradeDecision_notifyDelivered())
upgrade_decision.start()
upgrade_decision.stop()
self.tic()
self.assertEqual(None, upgrade_decision.UpgradeDecision_notifyDelivered())
self.tic()
self.assertEqual(upgrade_decision.getSimulationState(), 'delivered')
self.assertEqual(len(upgrade_decision.getFollowUpRelatedValueList()), 1)
event = upgrade_decision.getFollowUpRelatedValue()
self.assertEqual(event.getTitle(),
"Upgrade processed at %s for %s" % (compute_node.getTitle(),
software_release.getReference()))
self.assertEqual(event.getTextContent().splitlines(),
[software_product.getTitle(), compute_node.getTitle(), compute_node.getReference(),
software_release.getTitle(), software_release.getReference(),
software_release.getUrlString()])
self.assertEqual(event.getSimulationState(), "delivered")
@simulate('NotificationTool_getDocumentValue',
'reference=None',
'assert reference == "slapos-upgrade-delivered-instance-tree.notification"\n' \
'return context.restrictedTraverse(' \
'context.REQUEST["testUpgradeDecision_notifyDelivered_instance_tree"])')
@simulate('UpgradeDecision_isUpgradeFinished',
'', 'return 1')
def testUpgradeDecision_notifyDelivered_instance_tree(self):
person = self._makePerson()
instance_tree = self._makeInstanceTree()
software_release = self._makeSoftwareRelease()
software_product = self._makeSoftwareProduct()
software_release.setAggregateValue(software_product)
upgrade_decision = self._makeUpgradeDecision()
upgrade_decision.edit(destination_decision_value=person)
upgrade_decision_line = self._makeUpgradeDecisionLine(upgrade_decision)
upgrade_decision_line.setAggregateValueList([software_release,
instance_tree])
old_url = instance_tree.getUrlString()
notification_message = self.portal.notification_message_module.newContent(
portal_type="Notification Message",
title='Test NM title %s' % self.new_id,
text_content_substitution_mapping_method_id=
"NotificationMessage_getSubstitutionMappingDictFromArgument",
text_content="""${software_product_title}
${instance_tree_title}
${old_software_release_url}
${software_release_name}
${software_release_reference}
${new_software_release_url}""",
content_type='text/html',
)
self.portal.REQUEST\
['testUpgradeDecision_notifyDelivered_instance_tree'] = \
notification_message.getRelativeUrl()
self.tic()
self.assertEqual(None, upgrade_decision.UpgradeDecision_notifyDelivered())
upgrade_decision.start()
upgrade_decision.stop()
self.tic()
self.assertEqual(None, upgrade_decision.UpgradeDecision_notifyDelivered())
self.tic()
self.assertEqual(upgrade_decision.getSimulationState(), 'delivered')
self.assertEqual(len(upgrade_decision.getFollowUpRelatedValueList()), 1)
event = upgrade_decision.getFollowUpRelatedValue()
self.assertEqual(event.getTitle(),
"Upgrade Processed for %s (%s)" % (instance_tree.getTitle(),
software_release.getReference()))
self.assertEqual(event.getTextContent().splitlines(),
[software_product.getTitle(), instance_tree.getTitle(),
old_url, software_release.getTitle(), software_release.getReference(),
software_release.getUrlString()])
self.assertEqual(event.getSimulationState(), "delivered")
def testUpgradeDecisionLine_cancel_already_cancelled(self):
software_release = self._makeSoftwareRelease()
upgrade_decision = self._makeUpgradeDecision()
upgrade_decision.cancel(comment="Cancelled by the test")
upgrade_decision_line = self._makeUpgradeDecisionLine(upgrade_decision)
upgrade_decision_line.setAggregateValueList([software_release])
self.tic()
upgrade_decision_line.UpgradeDecisionLine_cancel()
self.assertEqual('cancelled', upgrade_decision.getSimulationState())
workflow_history_list = upgrade_decision.Base_getWorkflowHistoryItemList('upgrade_decision_workflow', display=0)
self.assertEqual("Cancelled by the test", workflow_history_list[-1].comment)
def testUpgradeDecisionLine_cancel_archived_software_release(self):
software_release = self._makeSoftwareRelease()
software_product = self._makeSoftwareProduct()
upgrade_decision = self._makeUpgradeDecision()
upgrade_decision_line = self._makeUpgradeDecisionLine(upgrade_decision)
upgrade_decision_line.setAggregateValueList([software_release])
software_release.setAggregateValue(software_product)
self.tic()
software_release.archive()
upgrade_decision_line.UpgradeDecisionLine_cancel()
self.assertEqual('draft', upgrade_decision.getSimulationState())
software_product.invalidate()
upgrade_decision_line.UpgradeDecisionLine_cancel()
self.assertEqual('cancelled', upgrade_decision.getSimulationState())
workflow_history_list = upgrade_decision.Base_getWorkflowHistoryItemList('upgrade_decision_workflow', display=0)
self.assertEqual("Software Product is invalidated.", workflow_history_list[-1].comment)
@simulate('NotificationTool_getDocumentValue',
'reference=None',
'assert reference == "slapos-upgrade-delivered-compute-node.notification"\n' \
'return context.restrictedTraverse(' \
'context.REQUEST["testUpgradeDecisionLine_cancel_destroyed_instance_tree"])')
def testUpgradeDecisionLine_cancel_destroyed_instance_tree(self):
software_release = self._makeSoftwareRelease()
instance_tree = self._makeFullInstanceTree(software_release.getUrlString())
upgrade_decision = self._makeUpgradeDecision()
upgrade_decision_line = self._makeUpgradeDecisionLine(upgrade_decision)
upgrade_decision_line.setAggregateValueList([software_release, instance_tree])
notification_message = self.portal.notification_message_module.newContent(
portal_type="Notification Message",
title='Test NM title %s' % self.new_id,
text_content_substitution_mapping_method_id=
"NotificationMessage_getSubstitutionMappingDictFromArgument",
text_content="""${software_product_title}
${compute_node_title}
${compute_node_reference}
${software_release_name}
${software_release_reference}
${new_software_release_url}""",
content_type='text/html',
)
self.portal.REQUEST\
['testUpgradeDecisionLine_cancel_destroyed_instance_tree'] = \
notification_message.getRelativeUrl()
self.tic()
kw = dict(
software_release = instance_tree.getUrlString(),
software_type = instance_tree.getSourceReference(),
instance_xml = instance_tree.getTextContent(),
sla_xml = self.generateSafeXml(),
shared = False
)
instance_tree.requestDestroy(**kw)
self.tic()
upgrade_decision_line.UpgradeDecisionLine_cancel()
self.assertEqual('cancelled', upgrade_decision.getSimulationState())
workflow_history_list = upgrade_decision.Base_getWorkflowHistoryItemList('upgrade_decision_workflow', display=0)
self.assertEqual("Instance Tree is destroyed.", workflow_history_list[-1].comment)
@simulate('NotificationTool_getDocumentValue',
'reference=None',
'assert reference == "slapos-upgrade-delivered-compute-node.notification"\n' \
'return context.restrictedTraverse(' \
'context.REQUEST["testUpgradeDecisionLine_cancel_destroyed_instance_tree"])')
def testUpgradeDecisionLine_cancel_destroyed_instance_tree_and_disabled_monitor(self):
software_release = self._makeSoftwareRelease()
instance_tree = self._makeFullInstanceTree(software_release.getUrlString())
upgrade_decision = self._makeUpgradeDecision()
upgrade_decision_line = self._makeUpgradeDecisionLine(upgrade_decision)
upgrade_decision_line.setAggregateValueList([software_release, instance_tree])
notification_message = self.portal.notification_message_module.newContent(
portal_type="Notification Message",
title='Test NM title %s' % self.new_id,
text_content_substitution_mapping_method_id=
"NotificationMessage_getSubstitutionMappingDictFromArgument",
text_content="""${software_product_title}
${compute_node_title}
${compute_node_reference}
${software_release_name}
${software_release_reference}
${new_software_release_url}""",
content_type='text/html',
)
self.portal.REQUEST\
['testUpgradeDecisionLine_cancel_destroyed_instance_tree'] = \
notification_message.getRelativeUrl()
self.tic()
kw = dict(
software_release = instance_tree.getUrlString(),
software_type = instance_tree.getSourceReference(),
instance_xml = instance_tree.getTextContent(),
sla_xml = self.generateSafeXml(),
shared = False
)
instance_tree.requestDestroy(**kw)
instance_tree.setMonitorScope("disabled")
self.tic()
upgrade_decision_line.UpgradeDecisionLine_cancel()
self.assertEqual('cancelled', upgrade_decision.getSimulationState())
workflow_history_list = upgrade_decision.Base_getWorkflowHistoryItemList('upgrade_decision_workflow', display=0)
self.assertEqual("Instance Tree is destroyed.", workflow_history_list[-1].comment)
@simulate('NotificationTool_getDocumentValue',
'reference=None',
'assert reference == "slapos-upgrade-delivered-compute-node.notification"\n' \
'return context.restrictedTraverse(' \
'context.REQUEST["testUpgradeDecisionLine_cancel_destroyed_hs_archived_sr"])')
def testUpgradeDecisionLine_cancel_destroyed_hs_archived_sr(self):
software_release = self._makeSoftwareRelease()
software_product = self._makeSoftwareProduct()
software_release.setAggregateValue(software_product)
instance_tree = self._makeFullInstanceTree(software_release.getUrlString())
upgrade_decision = self._makeUpgradeDecision()
upgrade_decision_line = self._makeUpgradeDecisionLine(upgrade_decision)
upgrade_decision_line.setAggregateValueList([software_release, instance_tree])
notification_message = self.portal.notification_message_module.newContent(
portal_type="Notification Message",
title='Test NM title %s' % self.new_id,
text_content_substitution_mapping_method_id=
"NotificationMessage_getSubstitutionMappingDictFromArgument",
text_content="""${software_product_title}
${compute_node_title}
${compute_node_reference}
${software_release_name}
${software_release_reference}
${new_software_release_url}""",
content_type='text/html',
)
self.portal.REQUEST\
['testUpgradeDecisionLine_cancel_destroyed_hs_archived_sr'] = \
notification_message.getRelativeUrl()
self.tic()
kw = dict(
software_release = instance_tree.getUrlString(),
software_type = instance_tree.getSourceReference(),
instance_xml = instance_tree.getTextContent(),
sla_xml = self.generateSafeXml(),
shared = False
)
instance_tree.requestDestroy(**kw)
software_release.archive()
software_product.invalidate()
self.tic()
upgrade_decision_line.UpgradeDecisionLine_cancel()
self.assertEqual('cancelled', upgrade_decision.getSimulationState())
workflow_history_list = upgrade_decision.Base_getWorkflowHistoryItemList('upgrade_decision_workflow', display=0)
self.assertEqual("Software Product is invalidated.", workflow_history_list[-1].comment)
upgrade_decision.UpgradeDecision_processUpgrade()
self.assertNotEqual(new_release_variation.getUrlString(),
instance_tree.getUrlString())
self.assertEqual('destroy_requested', instance_tree.getSlapState())
self.assertEqual('rejected', upgrade_decision.getSimulationState())
......@@ -2,7 +2,7 @@
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="Workflow" module="erp5.portal_type"/>
<global name="Interaction Workflow" module="erp5.portal_type"/>
</pickle>
<pickle>
<dictionary>
......@@ -24,14 +24,6 @@
<persistent> <string encoding="base64">AAAAAAAAAAQ=</string> </persistent>
</value>
</item>
<item>
<key> <string>categories</string> </key>
<value>
<tuple>
<string>source/portal_workflow/upgrade_slap_interface_workflow/state_draft</string>
</tuple>
</value>
</item>
<item>
<key> <string>comment</string> </key>
<value>
......@@ -40,7 +32,7 @@
</item>
<item>
<key> <string>default_reference</string> </key>
<value> <string>person_slap_interface_workflow</string> </value>
<value> <string>slapos_cloud_interaction_workflow</string> </value>
</item>
<item>
<key> <string>description</string> </key>
......@@ -50,7 +42,7 @@
</item>
<item>
<key> <string>id</string> </key>
<value> <string>upgrade_slap_interface_workflow</string> </value>
<value> <string>slapos_pdm_interaction_workflow</string> </value>
</item>
<item>
<key> <string>language</string> </key>
......@@ -58,27 +50,13 @@
<none/>
</value>
</item>
<item>
<key> <string>manager_bypass</string> </key>
<value> <int>0</int> </value>
</item>
<item>
<key> <string>portal_type</string> </key>
<value> <string>Workflow</string> </value>
</item>
<item>
<key> <string>state_variable</string> </key>
<value> <string>slap_state</string> </value>
<value> <string>Interaction Workflow</string> </value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string>Upgrade Slap Interface Workflow</string> </value>
</item>
<item>
<key> <string>workflow_managed_permission</string> </key>
<value>
<tuple/>
</value>
<value> <string>SlapOS pdm Interaction Workflow</string> </value>
</item>
</dictionary>
</pickle>
......
......@@ -2,59 +2,67 @@
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="Workflow Transition" module="erp5.portal_type"/>
<global name="Interaction Workflow Interaction" module="erp5.portal_type"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>action</string> </key>
<key> <string>categories</string> </key>
<value>
<none/>
<tuple>
<string>after_script/portal_workflow/slapos_pdm_interaction_workflow/script_Instance_triggerUpgradeDecisionAlarm</string>
</tuple>
</value>
</item>
<item>
<key> <string>action_name</string> </key>
<key> <string>description</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>categories</string> </key>
<key> <string>id</string> </key>
<value> <string>interaction_AllocationSupply_validate</string> </value>
</item>
<item>
<key> <string>portal_type</string> </key>
<value> <string>Interaction Workflow Interaction</string> </value>
</item>
<item>
<key> <string>portal_type_filter</string> </key>
<value>
<tuple>
<string>action_type/workflow</string>
<string>before_script/portal_workflow/upgrade_slap_interface_workflow/script_UpgradeDecision_checkConsistency</string>
<string>after_script/portal_workflow/upgrade_slap_interface_workflow/script_UpgradeDecision_requestUpgrade</string>
<string>Allocation Supply</string>
</tuple>
</value>
</item>
<item>
<key> <string>description</string> </key>
<value> <string>Perform the Upgrade</string> </value>
</item>
<item>
<key> <string>guard_permission</string> </key>
<key> <string>portal_type_group_filter</string> </key>
<value>
<tuple/>
</value>
</item>
<item>
<key> <string>icon</string> </key>
<key> <string>temporary_document_disallowed</string> </key>
<value> <int>1</int> </value>
</item>
<item>
<key> <string>title</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>transition_request_upgrade</string> </value>
</item>
<item>
<key> <string>portal_type</string> </key>
<value> <string>Workflow Transition</string> </value>
<key> <string>trigger_method_id</string> </key>
<value>
<tuple>
<string>validate</string>
</tuple>
</value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string>Request Upgrade</string> </value>
<key> <string>trigger_once_per_transaction</string> </key>
<value> <int>1</int> </value>
</item>
<item>
<key> <string>trigger_type</string> </key>
......
......@@ -2,61 +2,67 @@
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="Workflow Transition" module="erp5.portal_type"/>
<global name="Interaction Workflow Interaction" module="erp5.portal_type"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>action</string> </key>
<key> <string>categories</string> </key>
<value>
<none/>
<tuple>
<string>after_script/portal_workflow/slapos_pdm_interaction_workflow/script_UpgradeDecision_triggerUpgradeAlarm</string>
</tuple>
</value>
</item>
<item>
<key> <string>action_name</string> </key>
<key> <string>description</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>categories</string> </key>
<key> <string>id</string> </key>
<value> <string>interaction_UpgradeDecision_start</string> </value>
</item>
<item>
<key> <string>portal_type</string> </key>
<value> <string>Interaction Workflow Interaction</string> </value>
</item>
<item>
<key> <string>portal_type_filter</string> </key>
<value>
<tuple>
<string>action_type/workflow</string>
<string>before_script/portal_workflow/upgrade_slap_interface_workflow/script_UpgradeDecision_checkConsistency</string>
<string>after_script/portal_workflow/upgrade_slap_interface_workflow/script_UpgradeDecision_approveRegistration</string>
<string>Upgrade Decision</string>
</tuple>
</value>
</item>
<item>
<key> <string>description</string> </key>
<key> <string>portal_type_group_filter</string> </key>
<value>
<none/>
<tuple/>
</value>
</item>
<item>
<key> <string>guard_permission</string> </key>
<value>
<tuple/>
</value>
<key> <string>temporary_document_disallowed</string> </key>
<value> <int>1</int> </value>
</item>
<item>
<key> <string>icon</string> </key>
<key> <string>title</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>transition_approve_registration</string> </value>
</item>
<item>
<key> <string>portal_type</string> </key>
<value> <string>Workflow Transition</string> </value>
<key> <string>trigger_method_id</string> </key>
<value>
<tuple>
<string>start</string>
</tuple>
</value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string>Approve Registration</string> </value>
<key> <string>trigger_once_per_transaction</string> </key>
<value> <int>1</int> </value>
</item>
<item>
<key> <string>trigger_type</string> </key>
......
return state_change['object'].Base_reindexAndSenseAlarm(['slapos_pdm_instance_tree_create_upgrade_decision'])
......@@ -52,14 +52,6 @@
<key> <string>_params</string> </key>
<value> <string>state_change</string> </value>
</item>
<item>
<key> <string>_proxy_roles</string> </key>
<value>
<tuple>
<string>Manager</string>
</tuple>
</value>
</item>
<item>
<key> <string>description</string> </key>
<value>
......@@ -68,7 +60,7 @@
</item>
<item>
<key> <string>id</string> </key>
<value> <string>script_UpgradeDecision_notify</string> </value>
<value> <string>script_Instance_triggerUpgradeDecisionAlarm</string> </value>
</item>
<item>
<key> <string>portal_type</string> </key>
......@@ -76,7 +68,9 @@
</item>
<item>
<key> <string>title</string> </key>
<value> <string>UpgradeDecision_notify</string> </value>
<value>
<none/>
</value>
</item>
</dictionary>
</pickle>
......
return state_change['object'].Base_reindexAndSenseAlarm(['slapos_pdm_upgrade_decision_process_started'])
......@@ -60,7 +60,7 @@
</item>
<item>
<key> <string>id</string> </key>
<value> <string>script_UpgradeDecision_checkConsistency</string> </value>
<value> <string>script_UpgradeDecision_triggerUpgradeAlarm</string> </value>
</item>
<item>
<key> <string>portal_type</string> </key>
......
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="Worklist" 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>action</string> </key>
<value> <string encoding="cdata"><![CDATA[
purchase_packing_list_module/view?simulation_state=draft&portal_type=Purchase+Packing+List&local_roles:list=Owner&reset=1
]]></string> </value>
</item>
<item>
<key> <string>action_name</string> </key>
<value> <string>Purchase Packing List to Confirm (%(count)s)</string> </value>
</item>
<item>
<key> <string>categories</string> </key>
<value>
<tuple>
<string>action_type/global</string>
</tuple>
</value>
</item>
<item>
<key> <string>criterion_property</string> </key>
<value>
<tuple>
<string>portal_type</string>
<string>simulation_state</string>
<string>local_roles</string>
</tuple>
</value>
</item>
<item>
<key> <string>description</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>guard_group</string> </key>
<value>
<tuple/>
</value>
</item>
<item>
<key> <string>guard_permission</string> </key>
<value>
<tuple/>
</value>
</item>
<item>
<key> <string>icon</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>worklist_01_draft_purchase_packing_list_list</string> </value>
</item>
<item>
<key> <string>portal_type</string> </key>
<value> <string>Worklist</string> </value>
</item>
<item>
<key> <string>title</string> </key>
<value>
<none/>
</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>
<item>
<key> <string>local_roles</string> </key>
<value>
<tuple>
<string>Owner</string>
</tuple>
</value>
</item>
<item>
<key> <string>portal_type</string> </key>
<value>
<tuple>
<string>Purchase Packing List</string>
</tuple>
</value>
</item>
<item>
<key> <string>simulation_state</string> </key>
<value>
<tuple>
<string>draft</string>
</tuple>
</value>
</item>
</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>
......@@ -22,13 +22,13 @@
<key> <string>action</string> </key>
<value> <string encoding="cdata"><![CDATA[
sale_packing_list_module/view?simulation_state=draft&portal_type=Sale+Packing+List&local_roles:list=Owner&reset=1
upgrade_decision_module/view?simulation_state=draft&portal_type=Upgrade+Decision&local_roles:list=Owner&reset=1
]]></string> </value>
</item>
<item>
<key> <string>action_name</string> </key>
<value> <string>Sale Packing List to Process (%(count)s)</string> </value>
<value> <string>Upgrade Decision to Confirm (%(count)s)</string> </value>
</item>
<item>
<key> <string>categories</string> </key>
......@@ -54,6 +54,12 @@ sale_packing_list_module/view?simulation_state=draft&portal_type=Sale+Packing+Li
<none/>
</value>
</item>
<item>
<key> <string>guard_expression</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>guard_group</string> </key>
<value>
......@@ -74,7 +80,7 @@ sale_packing_list_module/view?simulation_state=draft&portal_type=Sale+Packing+Li
</item>
<item>
<key> <string>id</string> </key>
<value> <string>worklist_11_draft_sale_packing_list_list</string> </value>
<value> <string>worklist_01_draft_upgrade_decision_list</string> </value>
</item>
<item>
<key> <string>portal_type</string> </key>
......@@ -102,25 +108,25 @@ sale_packing_list_module/view?simulation_state=draft&portal_type=Sale+Packing+Li
<item>
<key> <string>local_roles</string> </key>
<value>
<tuple>
<list>
<string>Owner</string>
</tuple>
</list>
</value>
</item>
<item>
<key> <string>portal_type</string> </key>
<value>
<tuple>
<string>Sale Packing List</string>
</tuple>
<list>
<string>Upgrade Decision</string>
</list>
</value>
</item>
<item>
<key> <string>simulation_state</string> </key>
<value>
<tuple>
<list>
<string>draft</string>
</tuple>
</list>
</value>
</item>
</dictionary>
......
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="Worklist" 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>action</string> </key>
<value> <string encoding="cdata"><![CDATA[
purchase_packing_list_module/view?simulation_state=confirmed&portal_type=Purchase+Packing+List&local_roles:list=Assignee&local_roles:list=Assignor&reset=1
]]></string> </value>
</item>
<item>
<key> <string>action_name</string> </key>
<value> <string>Purchase Packing List to Receive (%(count)s)</string> </value>
</item>
<item>
<key> <string>categories</string> </key>
<value>
<tuple>
<string>action_type/global</string>
</tuple>
</value>
</item>
<item>
<key> <string>criterion_property</string> </key>
<value>
<tuple>
<string>portal_type</string>
<string>simulation_state</string>
<string>local_roles</string>
</tuple>
</value>
</item>
<item>
<key> <string>description</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>guard_group</string> </key>
<value>
<tuple/>
</value>
</item>
<item>
<key> <string>guard_permission</string> </key>
<value>
<tuple/>
</value>
</item>
<item>
<key> <string>icon</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>worklist_02_confirmed_purchase_packing_list_list</string> </value>
</item>
<item>
<key> <string>portal_type</string> </key>
<value> <string>Worklist</string> </value>
</item>
<item>
<key> <string>title</string> </key>
<value>
<none/>
</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>
<item>
<key> <string>local_roles</string> </key>
<value>
<tuple>
<string>Assignor</string>
<string>Assignee</string>
</tuple>
</value>
</item>
<item>
<key> <string>portal_type</string> </key>
<value>
<tuple>
<string>Purchase Packing List</string>
</tuple>
</value>
</item>
<item>
<key> <string>simulation_state</string> </key>
<value>
<tuple>
<string>confirmed</string>
</tuple>
</value>
</item>
</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>
......@@ -22,13 +22,13 @@
<key> <string>action</string> </key>
<value> <string encoding="cdata"><![CDATA[
returned_sale_packing_list_module/view?simulation_state=confirmed&portal_type=Returned+Sale+Packing+List&local_roles:list=Assignee&local_roles:list=Assignor&reset=1
upgrade_decision_module/view?simulation_state=confirmed&portal_type=Upgrade+Decision&local_roles:list=Assignee&local_roles:list=Assignor&reset=1
]]></string> </value>
</item>
<item>
<key> <string>action_name</string> </key>
<value> <string>Returned Sale Packing List to Prepare (%(count)s)</string> </value>
<value> <string>Upgrade Decision to Accept (%(count)s)</string> </value>
</item>
<item>
<key> <string>categories</string> </key>
......@@ -54,6 +54,12 @@ returned_sale_packing_list_module/view?simulation_state=confirmed&portal_type=Re
<none/>
</value>
</item>
<item>
<key> <string>guard_expression</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>guard_group</string> </key>
<value>
......@@ -74,7 +80,7 @@ returned_sale_packing_list_module/view?simulation_state=confirmed&portal_type=Re
</item>
<item>
<key> <string>id</string> </key>
<value> <string>worklist_32_confirmed_returned_sale_packing_list</string> </value>
<value> <string>worklist_03_confirmed_upgrade_decision_list</string> </value>
</item>
<item>
<key> <string>portal_type</string> </key>
......@@ -102,26 +108,26 @@ returned_sale_packing_list_module/view?simulation_state=confirmed&portal_type=Re
<item>
<key> <string>local_roles</string> </key>
<value>
<tuple>
<list>
<string>Assignor</string>
<string>Assignee</string>
</tuple>
</list>
</value>
</item>
<item>
<key> <string>portal_type</string> </key>
<value>
<tuple>
<string>Returned Sale Packing List</string>
</tuple>
<list>
<string>Upgrade Decision</string>
</list>
</value>
</item>
<item>
<key> <string>simulation_state</string> </key>
<value>
<tuple>
<list>
<string>confirmed</string>
</tuple>
</list>
</value>
</item>
</dictionary>
......
......@@ -22,13 +22,13 @@
<key> <string>action</string> </key>
<value> <string encoding="cdata"><![CDATA[
sale_packing_list_module/view?simulation_state=ready&portal_type=Sale+Packing+List&local_roles:list=Assignee&local_roles:list=Assignor&reset=1
upgrade_decision_module/view?simulation_state=planned&portal_type=Upgrade+Decision&local_roles:list=Assignee&local_roles:list=Assignor&reset=1
]]></string> </value>
</item>
<item>
<key> <string>action_name</string> </key>
<value> <string>Sale Packing List to Ship (%(count)s)</string> </value>
<value> <string>Upgrade Decision to Confirm (%(count)s)</string> </value>
</item>
<item>
<key> <string>categories</string> </key>
......@@ -54,6 +54,12 @@ sale_packing_list_module/view?simulation_state=ready&portal_type=Sale+Packing+Li
<none/>
</value>
</item>
<item>
<key> <string>guard_expression</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>guard_group</string> </key>
<value>
......@@ -74,7 +80,7 @@ sale_packing_list_module/view?simulation_state=ready&portal_type=Sale+Packing+Li
</item>
<item>
<key> <string>id</string> </key>
<value> <string>worklist_13_ready_sale_packing_list_list</string> </value>
<value> <string>worklist_03_planned_upgrade_decision_list</string> </value>
</item>
<item>
<key> <string>portal_type</string> </key>
......@@ -102,26 +108,26 @@ sale_packing_list_module/view?simulation_state=ready&portal_type=Sale+Packing+Li
<item>
<key> <string>local_roles</string> </key>
<value>
<tuple>
<string>Assignee</string>
<list>
<string>Assignor</string>
</tuple>
<string>Assignee</string>
</list>
</value>
</item>
<item>
<key> <string>portal_type</string> </key>
<value>
<tuple>
<string>Sale Packing List</string>
</tuple>
<list>
<string>Upgrade Decision</string>
</list>
</value>
</item>
<item>
<key> <string>simulation_state</string> </key>
<value>
<tuple>
<string>ready</string>
</tuple>
<list>
<string>planned</string>
</list>
</value>
</item>
</dictionary>
......
......@@ -22,13 +22,13 @@
<key> <string>action</string> </key>
<value> <string encoding="cdata"><![CDATA[
purchase_packing_list_module/view?simulation_state=stopped&portal_type=Purchase+Packing+List&local_roles:list=Assignor&reset=1
upgrade_decision_module/view?simulation_state=stopped&portal_type=Upgrade+Decision&local_roles:list=Assignor&reset=1
]]></string> </value>
</item>
<item>
<key> <string>action_name</string> </key>
<value> <string>Purchase Packing List to Validate (%(count)s)</string> </value>
<value> <string>Upgrade Decision to Validate (%(count)s)</string> </value>
</item>
<item>
<key> <string>categories</string> </key>
......@@ -54,6 +54,12 @@ purchase_packing_list_module/view?simulation_state=stopped&portal_type=Purchase+
<none/>
</value>
</item>
<item>
<key> <string>guard_expression</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>guard_group</string> </key>
<value>
......@@ -74,7 +80,7 @@ purchase_packing_list_module/view?simulation_state=stopped&portal_type=Purchase+
</item>
<item>
<key> <string>id</string> </key>
<value> <string>worklist_03_stopped_purchase_packing_list_list</string> </value>
<value> <string>worklist_04_stopped_upgrade_decision_list</string> </value>
</item>
<item>
<key> <string>portal_type</string> </key>
......@@ -102,25 +108,25 @@ purchase_packing_list_module/view?simulation_state=stopped&portal_type=Purchase+
<item>
<key> <string>local_roles</string> </key>
<value>
<tuple>
<list>
<string>Assignor</string>
</tuple>
</list>
</value>
</item>
<item>
<key> <string>portal_type</string> </key>
<value>
<tuple>
<string>Purchase Packing List</string>
</tuple>
<list>
<string>Upgrade Decision</string>
</list>
</value>
</item>
<item>
<key> <string>simulation_state</string> </key>
<value>
<tuple>
<list>
<string>stopped</string>
</tuple>
</list>
</value>
</item>
</dictionary>
......
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="Worklist" 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>action</string> </key>
<value> <string encoding="cdata"><![CDATA[
sale_packing_list_module/view?simulation_state=confirmed&portal_type=Sale+Packing+List&local_roles:list=Assignee&local_roles:list=Assignor&reset=1
]]></string> </value>
</item>
<item>
<key> <string>action_name</string> </key>
<value> <string>Sale Packing List to Prepare (%(count)s)</string> </value>
</item>
<item>
<key> <string>categories</string> </key>
<value>
<tuple>
<string>action_type/global</string>
</tuple>
</value>
</item>
<item>
<key> <string>criterion_property</string> </key>
<value>
<tuple>
<string>portal_type</string>
<string>simulation_state</string>
<string>local_roles</string>
</tuple>
</value>
</item>
<item>
<key> <string>description</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>guard_group</string> </key>
<value>
<tuple/>
</value>
</item>
<item>
<key> <string>guard_permission</string> </key>
<value>
<tuple/>
</value>
</item>
<item>
<key> <string>icon</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>worklist_12_confirmed_sale_packing_list_list</string> </value>
</item>
<item>
<key> <string>portal_type</string> </key>
<value> <string>Worklist</string> </value>
</item>
<item>
<key> <string>title</string> </key>
<value>
<none/>
</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>
<item>
<key> <string>local_roles</string> </key>
<value>
<tuple>
<string>Assignee</string>
<string>Assignor</string>
</tuple>
</value>
</item>
<item>
<key> <string>portal_type</string> </key>
<value>
<tuple>
<string>Sale Packing List</string>
</tuple>
</value>
</item>
<item>
<key> <string>simulation_state</string> </key>
<value>
<tuple>
<string>confirmed</string>
</tuple>
</value>
</item>
</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="Worklist" 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>action</string> </key>
<value> <string encoding="cdata"><![CDATA[
sale_packing_list_module/view?simulation_state=started&portal_type=Sale+Packing+List&local_roles:list=Assignor&reset=1
]]></string> </value>
</item>
<item>
<key> <string>action_name</string> </key>
<value> <string>Sale Packing List to Validate (%(count)s)</string> </value>
</item>
<item>
<key> <string>categories</string> </key>
<value>
<tuple>
<string>action_type/global</string>
</tuple>
</value>
</item>
<item>
<key> <string>criterion_property</string> </key>
<value>
<tuple>
<string>portal_type</string>
<string>simulation_state</string>
<string>local_roles</string>
</tuple>
</value>
</item>
<item>
<key> <string>description</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>guard_group</string> </key>
<value>
<tuple/>
</value>
</item>
<item>
<key> <string>guard_permission</string> </key>
<value>
<tuple/>
</value>
</item>
<item>
<key> <string>icon</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>worklist_14_started_sale_packing_list_list</string> </value>
</item>
<item>
<key> <string>portal_type</string> </key>
<value> <string>Worklist</string> </value>
</item>
<item>
<key> <string>title</string> </key>
<value>
<none/>
</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>
<item>
<key> <string>local_roles</string> </key>
<value>
<tuple>
<string>Assignor</string>
</tuple>
</value>
</item>
<item>
<key> <string>portal_type</string> </key>
<value>
<tuple>
<string>Sale Packing List</string>
</tuple>
</value>
</item>
<item>
<key> <string>simulation_state</string> </key>
<value>
<tuple>
<string>started</string>
</tuple>
</value>
</item>
</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="Worklist" 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>action</string> </key>
<value> <string encoding="cdata"><![CDATA[
returned_sale_packing_list_module/view?simulation_state=draft&portal_type=Returned+Sale+Packing+List&local_roles:list=Owner&reset=1
]]></string> </value>
</item>
<item>
<key> <string>action_name</string> </key>
<value> <string>Returned Sale Packing List to Process (%(count)s)</string> </value>
</item>
<item>
<key> <string>categories</string> </key>
<value>
<tuple>
<string>action_type/global</string>
</tuple>
</value>
</item>
<item>
<key> <string>criterion_property</string> </key>
<value>
<tuple>
<string>portal_type</string>
<string>simulation_state</string>
<string>local_roles</string>
</tuple>
</value>
</item>
<item>
<key> <string>description</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>guard_group</string> </key>
<value>
<tuple/>
</value>
</item>
<item>
<key> <string>guard_permission</string> </key>
<value>
<tuple/>
</value>
</item>
<item>
<key> <string>icon</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>worklist_31_draft_returned_sale_packing_list</string> </value>
</item>
<item>
<key> <string>portal_type</string> </key>
<value> <string>Worklist</string> </value>
</item>
<item>
<key> <string>title</string> </key>
<value>
<none/>
</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>
<item>
<key> <string>local_roles</string> </key>
<value>
<tuple>
<string>Owner</string>
</tuple>
</value>
</item>
<item>
<key> <string>portal_type</string> </key>
<value>
<tuple>
<string>Returned Sale Packing List</string>
</tuple>
</value>
</item>
<item>
<key> <string>simulation_state</string> </key>
<value>
<tuple>
<string>draft</string>
</tuple>
</value>
</item>
</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="Worklist" 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>action</string> </key>
<value> <string encoding="cdata"><![CDATA[
returned_sale_packing_list_module/view?simulation_state=ready&portal_type=Returned+Sale+Packing+List&local_roles:list=Assignee&local_roles:list=Assignor&reset=1
]]></string> </value>
</item>
<item>
<key> <string>action_name</string> </key>
<value> <string>Returned Sale Packing List to Ship (%(count)s)</string> </value>
</item>
<item>
<key> <string>categories</string> </key>
<value>
<tuple>
<string>action_type/global</string>
</tuple>
</value>
</item>
<item>
<key> <string>criterion_property</string> </key>
<value>
<tuple>
<string>portal_type</string>
<string>simulation_state</string>
<string>local_roles</string>
</tuple>
</value>
</item>
<item>
<key> <string>description</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>guard_group</string> </key>
<value>
<tuple/>
</value>
</item>
<item>
<key> <string>guard_permission</string> </key>
<value>
<tuple/>
</value>
</item>
<item>
<key> <string>icon</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>worklist_33_ready_returned_sale_packing_list</string> </value>
</item>
<item>
<key> <string>portal_type</string> </key>
<value> <string>Worklist</string> </value>
</item>
<item>
<key> <string>title</string> </key>
<value>
<none/>
</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>
<item>
<key> <string>local_roles</string> </key>
<value>
<tuple>
<string>Assignor</string>
<string>Assignee</string>
</tuple>
</value>
</item>
<item>
<key> <string>portal_type</string> </key>
<value>
<tuple>
<string>Returned Sale Packing List</string>
</tuple>
</value>
</item>
<item>
<key> <string>simulation_state</string> </key>
<value>
<tuple>
<string>ready</string>
</tuple>
</value>
</item>
</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="Worklist" 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>action</string> </key>
<value> <string encoding="cdata"><![CDATA[
returned_sale_packing_list_module/view?simulation_state=started&portal_type=Returned+Sale+Packing+List&local_roles:list=Assignor&reset=1
]]></string> </value>
</item>
<item>
<key> <string>action_name</string> </key>
<value> <string>Returned Sale Packing List to Receive (%(count)s)</string> </value>
</item>
<item>
<key> <string>categories</string> </key>
<value>
<tuple>
<string>action_type/global</string>
</tuple>
</value>
</item>
<item>
<key> <string>criterion_property</string> </key>
<value>
<tuple>
<string>portal_type</string>
<string>simulation_state</string>
<string>local_roles</string>
</tuple>
</value>
</item>
<item>
<key> <string>description</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>guard_group</string> </key>
<value>
<tuple/>
</value>
</item>
<item>
<key> <string>guard_permission</string> </key>
<value>
<tuple/>
</value>
</item>
<item>
<key> <string>icon</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>worklist_34_started_returned_sale_packing_list_list</string> </value>
</item>
<item>
<key> <string>portal_type</string> </key>
<value> <string>Worklist</string> </value>
</item>
<item>
<key> <string>title</string> </key>
<value>
<none/>
</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>
<item>
<key> <string>local_roles</string> </key>
<value>
<tuple>
<string>Assignor</string>
</tuple>
</value>
</item>
<item>
<key> <string>portal_type</string> </key>
<value>
<tuple>
<string>Returned Sale Packing List</string>
</tuple>
</value>
</item>
<item>
<key> <string>simulation_state</string> </key>
<value>
<tuple>
<string>started</string>
</tuple>
</value>
</item>
</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="Worklist" 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>action</string> </key>
<value> <string encoding="cdata"><![CDATA[
sale_packing_list_module/view?causality_state=diverged&portal_type=Sale+Packing+List&local_roles:list=Assignor&reset=1
]]></string> </value>
</item>
<item>
<key> <string>action_name</string> </key>
<value> <string>Sale Packing List to Solve (%(count)s)</string> </value>
</item>
<item>
<key> <string>categories</string> </key>
<value>
<tuple>
<string>action_type/global</string>
</tuple>
</value>
</item>
<item>
<key> <string>criterion_property</string> </key>
<value>
<tuple>
<string>causality_state</string>
<string>portal_type</string>
<string>local_roles</string>
</tuple>
</value>
</item>
<item>
<key> <string>description</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>guard_group</string> </key>
<value>
<tuple/>
</value>
</item>
<item>
<key> <string>guard_permission</string> </key>
<value>
<tuple/>
</value>
</item>
<item>
<key> <string>icon</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>worklist_99a_diverged_sale_packing_list_list</string> </value>
</item>
<item>
<key> <string>portal_type</string> </key>
<value> <string>Worklist</string> </value>
</item>
<item>
<key> <string>title</string> </key>
<value>
<none/>
</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>
<item>
<key> <string>causality_state</string> </key>
<value>
<tuple>
<string>diverged</string>
</tuple>
</value>
</item>
<item>
<key> <string>local_roles</string> </key>
<value>
<tuple>
<string>Assignor</string>
</tuple>
</value>
</item>
<item>
<key> <string>portal_type</string> </key>
<value>
<tuple>
<string>Sale Packing List</string>
</tuple>
</value>
</item>
</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="Worklist" 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>action</string> </key>
<value> <string encoding="cdata"><![CDATA[
purchase_packing_list_module/view?causality_state=diverged&portal_type=Purchase+Packing+List&local_roles:list=Assignor&reset=1
]]></string> </value>
</item>
<item>
<key> <string>action_name</string> </key>
<value> <string>Purchase Packing List to Solve (%(count)s)</string> </value>
</item>
<item>
<key> <string>categories</string> </key>
<value>
<tuple>
<string>action_type/global</string>
</tuple>
</value>
</item>
<item>
<key> <string>criterion_property</string> </key>
<value>
<tuple>
<string>causality_state</string>
<string>portal_type</string>
<string>local_roles</string>
</tuple>
</value>
</item>
<item>
<key> <string>description</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>guard_group</string> </key>
<value>
<tuple/>
</value>
</item>
<item>
<key> <string>guard_permission</string> </key>
<value>
<tuple/>
</value>
</item>
<item>
<key> <string>icon</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>worklist_99b_diverged_purchase_packing_list</string> </value>
</item>
<item>
<key> <string>portal_type</string> </key>
<value> <string>Worklist</string> </value>
</item>
<item>
<key> <string>title</string> </key>
<value>
<none/>
</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>
<item>
<key> <string>causality_state</string> </key>
<value>
<tuple>
<string>diverged</string>
</tuple>
</value>
</item>
<item>
<key> <string>local_roles</string> </key>
<value>
<tuple>
<string>Assignor</string>
</tuple>
</value>
</item>
<item>
<key> <string>portal_type</string> </key>
<value>
<tuple>
<string>Purchase Packing List</string>
</tuple>
</value>
</item>
</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>
upgrade_decision = state_change["object"]
from DateTime import DateTime
portal = upgrade_decision.getPortalObject()
document = upgrade_decision.UpgradeDecision_getAggregateValue("Instance Tree")
if document is None:
document = upgrade_decision.UpgradeDecision_getAggregateValue("Compute Node")
if document is None:
raise ValueError("No Compute Node or Instance Tree associated to upgrade.")
# Get required arguments
kwargs = state_change.kwargs
# Required args
# Raise TypeError if all parameters are not provided
try:
upgrade_scope = kwargs['upgrade_scope']
except KeyError:
raise TypeError("UpgradeDecision_approveRegistration takes exactly 1 arguments")
tag = "%s_requestUpgradeDecisionCreation_inProgress" % document.getUid()
activate_kw = {'tag': tag}
if portal.portal_activities.countMessageWithTag(tag) > 0:
# nothing to do
return
with upgrade_decision.defaultActivateParameterDict(activate_kw):
if upgrade_decision.getSimulationState() == "draft":
upgrade_decision.plan()
upgrade_decision.setStartDate(DateTime())
if upgrade_scope == "auto":
if upgrade_decision.getSimulationState() == "planned":
upgrade_decision.start()
# Prevent concurrent transaction to create 2 upgrade decision for the same instance_tree
document.serialize()
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="Workflow Script" module="erp5.portal_type"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>_bind_names</string> </key>
<value>
<object>
<klass>
<global name="_reconstructor" module="copy_reg"/>
</klass>
<tuple>
<global name="NameAssignments" module="Shared.DC.Scripts.Bindings"/>
<global name="object" module="__builtin__"/>
<none/>
</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>_params</string> </key>
<value> <string>state_change</string> </value>
</item>
<item>
<key> <string>_proxy_roles</string> </key>
<value>
<tuple>
<string>Manager</string>
</tuple>
</value>
</item>
<item>
<key> <string>description</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>script_UpgradeDecision_approveRegistration</string> </value>
</item>
<item>
<key> <string>portal_type</string> </key>
<value> <string>Workflow Script</string> </value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string>UpgradeDecision_approveRegistration</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
upgrade_decision = state_change["object"]
from DateTime import DateTime
portal = context.getPortalObject()
# Get required arguments
kwargs = state_change.kwargs
# Required args
# Raise TypeError if all parameters are not provided
try:
message_title = kwargs['message_title']
message = kwargs['message']
destination_relative_url = kwargs['destination_relative_url']
except KeyError:
raise TypeError("UpgradeDecision_requestEvent takes exactly 3 arguments")
resource = portal.service_module.slapos_crm_information.getRelativeUrl()
# create Web message if needed for this ticket
last_event = portal.portal_catalog.getResultValue(
title=message_title,
follow_up_uid=upgrade_decision.getUid(),
sort_on=[('delivery.start_date', 'DESC')],
)
if last_event:
# User has already been notified for this problem.
return last_event
transactional_event = context.REQUEST.get("upgrade_decision_notified_item", None)
if transactional_event is not None:
if (transactional_event.getFollowUpUid() == upgrade_decision.getUid()) and \
(transactional_event.getTitle() == message_title):
return transactional_event
template = portal.restrictedTraverse(
portal.portal_preferences.getPreferredWebMessageTemplate())
event = template.Base_createCloneDocument(batch_mode=1)
event.edit(
title=message_title,
text_content=message,
start_date = DateTime(),
resource = resource,
source=upgrade_decision.getSource(),
destination=destination_relative_url,
follow_up=upgrade_decision.getRelativeUrl(),
)
event.stop()
event.deliver()
upgrade_decision.serialize()
upgrade_decision.REQUEST.set("upgrade_decision_notified_item", event)
upgrade_decision = state_change["object"]
from DateTime import DateTime
if upgrade_decision.getSimulationState() != 'started':
# Update Decision is not on started state, Upgrade is not possible!
return
instance_tree = upgrade_decision.UpgradeDecision_getAggregateValue("Instance Tree")
software_release = upgrade_decision.UpgradeDecision_getAggregateValue("Software Release")
compute_node = upgrade_decision.UpgradeDecision_getAggregateValue("Compute Node")
if software_release is None:
return
if compute_node is None and instance_tree is None:
return
if compute_node is not None and instance_tree is not None:
raise ValueError("Something is wrong, you cannot upgrade Compute Node and Instance Tree on the same decision.")
software_release_url = software_release.getUrlString()
if compute_node is not None:
compute_node.requestSoftwareRelease(
software_release_url=software_release_url,
state="available")
upgrade_decision.stop(comment="Upgrade Processed for the Compute Node!")
return
# Test if the Software is available at the ComputeNode.
if not instance_tree.InstanceTree_isUpgradePossible(
software_release_url=software_release_url):
return
status = instance_tree.getSlapState()
if status == "start_requested":
state = "started"
elif status == "stop_requested":
state = "stopped"
elif status == "destroy_requested":
state = "destroyed"
person = instance_tree.getDestinationSectionValue(portal_type="Person")
person.requestSoftwareInstance(
state=state,
software_release=software_release_url,
software_title=instance_tree.getTitle(),
software_type=instance_tree.getSourceReference(),
instance_xml=instance_tree.getTextContent(),
sla_xml=instance_tree.getSlaXml(),
shared=instance_tree.isRootSlave()
)
upgrade_decision.stop(
comment="Upgrade Processed for the Instance Tree!")
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="Workflow Script" module="erp5.portal_type"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>_bind_names</string> </key>
<value>
<object>
<klass>
<global name="_reconstructor" module="copy_reg"/>
</klass>
<tuple>
<global name="NameAssignments" module="Shared.DC.Scripts.Bindings"/>
<global name="object" module="__builtin__"/>
<none/>
</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>_params</string> </key>
<value> <string>state_change</string> </value>
</item>
<item>
<key> <string>_proxy_roles</string> </key>
<value>
<tuple>
<string>Manager</string>
</tuple>
</value>
</item>
<item>
<key> <string>description</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>script_UpgradeDecision_requestUpgrade</string> </value>
</item>
<item>
<key> <string>portal_type</string> </key>
<value> <string>Workflow Script</string> </value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string>UpgradeDecision_requestUpgrade</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
upgrade_decision = state_change["object"]
from DateTime import DateTime
cancellable_state_list = ['confirmed', 'planned']
require_state_list = ['rejected', 'confirmed', 'planned']
simulation_state = upgrade_decision.getSimulationState()
# Get required arguments
kwargs = state_change.kwargs
# Required args
# Raise TypeError if all parameters are not provided
try:
software_release_url = kwargs['software_release_url']
except KeyError:
raise TypeError("UpgradeDecision_reviewRegistration takes exactly 1 arguments")
if simulation_state in require_state_list:
current_release = upgrade_decision.UpgradeDecision_getAggregateValue("Software Release")
if not current_release:
# This upgrade decision is not valid
return
instance_tree = upgrade_decision.UpgradeDecision_getAggregateValue("Instance Tree")
if instance_tree is not None:
current_instance_tree_release = instance_tree.getUrlString()
if current_instance_tree_release == software_release_url:
if simulation_state in cancellable_state_list:
upgrade_decision.cancel(comment="Instance tree is already upgraded.")
return
if current_release.getUrlString() == software_release_url:
# Cannot cancel because the software releases are the same
return False
if simulation_state in cancellable_state_list:
upgrade_decision.cancel()
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="Workflow Script" module="erp5.portal_type"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>_bind_names</string> </key>
<value>
<object>
<klass>
<global name="_reconstructor" module="copy_reg"/>
</klass>
<tuple>
<global name="NameAssignments" module="Shared.DC.Scripts.Bindings"/>
<global name="object" module="__builtin__"/>
<none/>
</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>_params</string> </key>
<value> <string>state_change</string> </value>
</item>
<item>
<key> <string>_proxy_roles</string> </key>
<value>
<tuple>
<string>Manager</string>
</tuple>
</value>
</item>
<item>
<key> <string>description</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>script_UpgradeDecision_reviewRegistration</string> </value>
</item>
<item>
<key> <string>portal_type</string> </key>
<value> <string>Workflow Script</string> </value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string>UpgradeDecision_reviewRegistration</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
upgrade_decision = state_change["object"]
from DateTime import DateTime
portal = upgrade_decision.getPortalObject()
instance_tree = upgrade_decision.UpgradeDecision_getAggregateValue("Instance Tree")
software_release = upgrade_decision.UpgradeDecision_getAggregateValue("Software Release")
if upgrade_decision.getSimulationState() == "cancelled":
return
if software_release.getValidationState() == "archived":
software_product = software_release.getAggregateValue()
if software_product is not None and \
software_product.getValidationState() == "invalidated":
upgrade_decision.cancel(comment="Software Product is invalidated.")
return
if instance_tree is not None:
if instance_tree.getUpgradeScope() in ['never', 'disabled']:
upgrade_decision.cancel("Upgrade scope was disabled on the related Instance Tree")
elif instance_tree.getSlapState() == "destroy_requested":
upgrade_decision.cancel(comment="Instance Tree is destroyed.")
elif instance_tree.getUrlString() == software_release.getUrlString():
upgrade_decision.cancel(comment="Instance tree is already upgraded.")
return
compute_node = upgrade_decision.UpgradeDecision_getAggregateValue("Compute Node")
if compute_node is not None:
if compute_node.getUpgradeScope() in ['never', 'disabled']:
upgrade_decision.cancel("Upgrade scope was disabled on the related Compute Node")
return
elif compute_node.getAllocationScope() == "close/forever":
upgrade_decision.cancel(comment="Compute Node is close forever.")
return
already_deployed = len(portal.portal_catalog(limit=1,
portal_type="Compute Partition",
parent_reference=compute_node.getReference(),
software_release_url=software_release.getUrlString()))
if already_deployed:
upgrade_decision.cancel(comment="Compute Node already has the software release")
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="Workflow Script" module="erp5.portal_type"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>_bind_names</string> </key>
<value>
<object>
<klass>
<global name="_reconstructor" module="copy_reg"/>
</klass>
<tuple>
<global name="NameAssignments" module="Shared.DC.Scripts.Bindings"/>
<global name="object" module="__builtin__"/>
<none/>
</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>_params</string> </key>
<value> <string>state_change</string> </value>
</item>
<item>
<key> <string>_proxy_roles</string> </key>
<value>
<tuple>
<string>Manager</string>
</tuple>
</value>
</item>
<item>
<key> <string>description</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>script_UpgradeDecision_reviewUpgrade</string> </value>
</item>
<item>
<key> <string>portal_type</string> </key>
<value> <string>Workflow Script</string> </value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string>UpgradeDecision_reviewUpgrade</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="Workflow Transition" module="erp5.portal_type"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>action</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>action_name</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>categories</string> </key>
<value>
<tuple>
<string>action_type/workflow</string>
<string>before_script/portal_workflow/upgrade_slap_interface_workflow/script_UpgradeDecision_checkConsistency</string>
<string>after_script/portal_workflow/upgrade_slap_interface_workflow/script_UpgradeDecision_reviewRegistration</string>
</tuple>
</value>
</item>
<item>
<key> <string>description</string> </key>
<value> <string>Cancel if the current upgrade isn\'t valid anymore. </string> </value>
</item>
<item>
<key> <string>guard_permission</string> </key>
<value>
<tuple/>
</value>
</item>
<item>
<key> <string>icon</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>transition_review_registration</string> </value>
</item>
<item>
<key> <string>portal_type</string> </key>
<value> <string>Workflow Transition</string> </value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string>Review Registration</string> </value>
</item>
<item>
<key> <string>trigger_type</string> </key>
<value> <int>2</int> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="Workflow Transition" module="erp5.portal_type"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>action</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>action_name</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>categories</string> </key>
<value>
<tuple>
<string>action_type/workflow</string>
<string>before_script/portal_workflow/upgrade_slap_interface_workflow/script_UpgradeDecision_checkConsistency</string>
<string>after_script/portal_workflow/upgrade_slap_interface_workflow/script_UpgradeDecision_reviewUpgrade</string>
</tuple>
</value>
</item>
<item>
<key> <string>description</string> </key>
<value> <string>Review if the upgrade still applicable</string> </value>
</item>
<item>
<key> <string>guard_permission</string> </key>
<value>
<tuple/>
</value>
</item>
<item>
<key> <string>icon</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>transition_review_upgrade</string> </value>
</item>
<item>
<key> <string>portal_type</string> </key>
<value> <string>Workflow Transition</string> </value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string>Review Upgrade</string> </value>
</item>
<item>
<key> <string>trigger_type</string> </key>
<value> <int>2</int> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="Workflow Variable" module="erp5.portal_type"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>automatic_update</string> </key>
<value> <int>1</int> </value>
</item>
<item>
<key> <string>description</string> </key>
<value> <string>The last transition</string> </value>
</item>
<item>
<key> <string>for_catalog</string> </key>
<value> <int>0</int> </value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>variable_action</string> </value>
</item>
<item>
<key> <string>portal_type</string> </key>
<value> <string>Workflow Variable</string> </value>
</item>
<item>
<key> <string>status_included</string> </key>
<value> <int>1</int> </value>
</item>
<item>
<key> <string>title</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>variable_default_expression</string> </key>
<value> <string>transition/getReference|nothing</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="Workflow Variable" module="erp5.portal_type"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>automatic_update</string> </key>
<value> <int>1</int> </value>
</item>
<item>
<key> <string>description</string> </key>
<value> <string>The name of the user who performed the last transition</string> </value>
</item>
<item>
<key> <string>for_catalog</string> </key>
<value> <int>0</int> </value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>variable_actor</string> </value>
</item>
<item>
<key> <string>portal_type</string> </key>
<value> <string>Workflow Variable</string> </value>
</item>
<item>
<key> <string>status_included</string> </key>
<value> <int>1</int> </value>
</item>
<item>
<key> <string>title</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>variable_default_expression</string> </key>
<value> <string>user/getUserName</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="Workflow Variable" module="erp5.portal_type"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>automatic_update</string> </key>
<value> <int>1</int> </value>
</item>
<item>
<key> <string>description</string> </key>
<value> <string>Comments about the last transition</string> </value>
</item>
<item>
<key> <string>for_catalog</string> </key>
<value> <int>0</int> </value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>variable_comment</string> </value>
</item>
<item>
<key> <string>portal_type</string> </key>
<value> <string>Workflow Variable</string> </value>
</item>
<item>
<key> <string>status_included</string> </key>
<value> <int>1</int> </value>
</item>
<item>
<key> <string>title</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>variable_default_expression</string> </key>
<value> <string>python:state_change.kwargs.get(\'comment\', \'\')</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="Workflow Variable" module="erp5.portal_type"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>automatic_update</string> </key>
<value> <int>1</int> </value>
</item>
<item>
<key> <string>description</string> </key>
<value> <string>Error message if validation failed</string> </value>
</item>
<item>
<key> <string>for_catalog</string> </key>
<value> <int>0</int> </value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>variable_error_message</string> </value>
</item>
<item>
<key> <string>portal_type</string> </key>
<value> <string>Workflow Variable</string> </value>
</item>
<item>
<key> <string>status_included</string> </key>
<value> <int>1</int> </value>
</item>
<item>
<key> <string>title</string> </key>
<value>
<none/>
</value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="Workflow Variable" module="erp5.portal_type"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>automatic_update</string> </key>
<value> <int>0</int> </value>
</item>
<item>
<key> <string>description</string> </key>
<value> <string>Provides access to workflow history</string> </value>
</item>
<item>
<key> <string>for_catalog</string> </key>
<value> <int>0</int> </value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>variable_history</string> </value>
</item>
<item>
<key> <string>portal_type</string> </key>
<value> <string>Workflow Variable</string> </value>
</item>
<item>
<key> <string>status_included</string> </key>
<value> <int>0</int> </value>
</item>
<item>
<key> <string>title</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>variable_default_expression</string> </key>
<value> <string>state_change/getHistory</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="Workflow Variable" module="erp5.portal_type"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>automatic_update</string> </key>
<value> <int>0</int> </value>
</item>
<item>
<key> <string>description</string> </key>
<value> <string>portal type (use as filter for worklists)</string> </value>
</item>
<item>
<key> <string>for_catalog</string> </key>
<value> <int>1</int> </value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>variable_portal_type</string> </value>
</item>
<item>
<key> <string>portal_type</string> </key>
<value> <string>Workflow Variable</string> </value>
</item>
<item>
<key> <string>status_included</string> </key>
<value> <int>0</int> </value>
</item>
<item>
<key> <string>title</string> </key>
<value>
<none/>
</value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="Workflow Variable" module="erp5.portal_type"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>automatic_update</string> </key>
<value> <int>1</int> </value>
</item>
<item>
<key> <string>description</string> </key>
<value> <string>Time of the last transition</string> </value>
</item>
<item>
<key> <string>for_catalog</string> </key>
<value> <int>0</int> </value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>variable_time</string> </value>
</item>
<item>
<key> <string>portal_type</string> </key>
<value> <string>Workflow Variable</string> </value>
</item>
<item>
<key> <string>status_included</string> </key>
<value> <int>1</int> </value>
</item>
<item>
<key> <string>title</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>variable_default_expression</string> </key>
<value> <string>state_change/getDateTime</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
Compute Node | view_related_upgrade_decision
Instance Tree | view_upgrade
Software Product Individual Variation | view
Software Product Release Variation | view
Software Product Type Variation | view
Software Product | capacity
Upgrade Decision Line | view
Upgrade Decision Module | rss_view
Upgrade Decision Module | view
Upgrade Decision | view
......
software_release
software_type
\ No newline at end of file
document.erp5.SoftwareProductTypeVariation
document.erp5.SoftwareProductReleaseVariation
document.erp5_slapos.SoftwareProduct
\ No newline at end of file
notification_message_module/slapos_upgrade_compute_node_notification
notification_message_module/slapos_upgrade_delivered_compute_node_notification
notification_message_module/slapos_upgrade_delivered_instance_tree_notification
notification_message_module/slapos_upgrade_instance_tree_notification
portal_alarms/slapos_pdm_auto_cancel_upgrade_decision
portal_alarms/slapos_pdm_compute_node_create_upgrade_decision
portal_alarms/slapos_pdm_destroy_software_installation_with_archived_software_release
portal_alarms/slapos_pdm_destroy_unused_software_installation
portal_alarms/slapos_pdm_instance_tree_create_upgrade_decision
portal_alarms/slapos_pdm_upgrade_decision_process_planned
portal_alarms/slapos_pdm_upgrade_decision_process_started
portal_alarms/slapos_pdm_upgrade_decision_process_stopped
software_product_module/template_software_product
software_release_module/template_software_release
upgrade_decision_module/template_upgrade_decision
\ No newline at end of file
portal_alarms/slapos_pdm_upgrade_decision_process_started
\ No newline at end of file
Software Product | Embedded File
Software Product | Software Product Individual Variation
Upgrade Decision Module | Upgrade Decision
Upgrade Decision | Upgrade Decision Line
\ No newline at end of file
Software Product | Software Product Release Variation
Software Product | Software Product Type Variation
Upgrade Decision Module | Upgrade Decision
\ No newline at end of file
Software Product | Software Product Individual Variation
\ No newline at end of file
Software Product Individual Variation
Software Product Release Variation
Software Product Type Variation
Upgrade Decision
Upgrade Decision Line
Upgrade Decision Module
\ No newline at end of file
Software Product Individual Variation | SlaposCapacity
Software Product Release Variation | SlaposCapacity
Software Product Type Variation | SlaposCapacity
Software Product | DefaultImage
Software Product | SlapOSSoftwareProductConstraint
Software Product | SlapOSVirtualMasterConstraint
Software Product | SlaposCapacity
Software Release | SlapOSSoftwareReleaseConstraint
\ No newline at end of file
Upgrade Decision | SlapOSVirtualMasterSourceProjectConstraint
Upgrade Decision | SlaposUpgradeDecisionConstraint
\ No newline at end of file
Allocation Supply | slapos_pdm_interaction_workflow
Software Product Release Variation | edit_workflow
Software Product Type Variation | edit_workflow
Software Product | -validation_workflow
Software Product | commerce_validation_workflow
Upgrade Decision | edit_workflow
Upgrade Decision | slapos_pdm_interaction_workflow
Upgrade Decision | ticket_interaction_workflow
Upgrade Decision | upgrade_decision_workflow
Upgrade Decision | upgrade_slap_interface_workflow
\ No newline at end of file
Upgrade Decision | upgrade_decision_workflow
\ No newline at end of file
SlapOSSoftwareProductConstraint
SlapOSSoftwareReleaseConstraint
\ No newline at end of file
SlapOSSoftwareReleaseConstraint
SlaposUpgradeDecisionConstraint
\ No newline at end of file
test.erp5.testSlapOSPDMAlarm
test.erp5.testSlapOSPDMSkins
test.erp5.testSlapOSPDMDestroySoftwareInstallationWithArchivedSoftwareReleaseAlarm
test.erp5.testSlapOSPDMCreateUpgradeDecisionSkins
test.erp5.testSlapOSCloudUpgradeSlapInterfaceWorkflow
\ No newline at end of file
test.erp5.testSlapOSPDMDestroySoftwareInstallation
test.erp5.testSlapOSPDMCreateUpgradeDecisionSkins
\ No newline at end of file
upgrade_decision_workflow
upgrade_slap_interface_workflow
\ No newline at end of file
slapos_pdm_interaction_workflow
upgrade_decision_workflow
\ 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