Commit 1b6f914b authored by Romain Courteaud's avatar Romain Courteaud

slapos_pdm:

* add SlapOSVirtualMasterSourceProjectConstraint on Upgrade Decision
* software product must be linked to a project
* create Software Type portal type
  It is a variation of a Software Product
* rename Software Type to Software Product Type Variation
* add Software Product Release Variation portal type
* force default use/base_contribution on Software Product
  Didn't find another way to do it (init script requires data migration)
* require Software Product to have at least one Type and one Release
* store url_string on Release Variation
* use edit_workflow on Variation portal types
* use the jump action to access Software Release
* add dedicated form to view Release
* add Software Type view
* set SoftwareProduct default quantity unit
* support document without categories property
* add constraint to ensure quantity unit of a Software Product is defined
* drop Software Release configuration. Drop hardcoded template only used in tests
* fixup
  See 1173ea0e
* drop Compute Node upgrade
  This is now handled manually by updating the Allocation Supply
* stop allowing Upgrade Decision Line creation
* Upgrade Decision is a ticket
* wip upgrade decision redesign with allocation supply
* not commited script
* really compare url strings
* update upgrade decision view
* only create upgrade decision for SOftware Instance for now
* set the compute node on the test allocation supply
* drop not used scripts
* remote tests from dropped scripts
* mark test to check
* test alarm_instance_tree_create_upgrade_decision
* drop upgrade_scope
* test upgrade decision creation for not allocated instance tree
* test Upgrade for allocated Software Instance
* drop deprecated tests
* root shared instance can not be upgraded by Allocation Supply on the same tree
* upgrade not allocated or allocated on remote slave instances
* update not allocated in there is instance node supply
* test upgrade Instance Node
* drop unused InstanceTree_getUpgradeSubscriptionRelatedValue
* drop UpgradeDecisionLine_cancel
* drop Upgrade Decision Line view
* drop SoftwareProduct_getSortedSoftwareReleaseList
* fix upgrade decision list view
* drop InstanceTree_isUpgradePossible
  No way to know which software release url on instance will request.
* drop UpgradeDecision_processUpgrade
* drop Base_acceptUpgradeDecision
* drop Base_rejectUpgradeDecision
* drop reviewRegistration
* check created upgrade decision
* do not propose again to upgrade if decision has been rejected
* no need to check all rejected decisions
* do not put newly create decision in started
  Ask review from manager
* drop UpgradeDecision_notify
* drop UpgradeDecision_notifyDelivered
* drop reviewUpgrade
* drop UpgradeDecision_getAggregateValue
* drop approveRegistration
* drop upgrade_slap_interface_workflow
* drop UpgradeDecision_requestChangeState
* drop slapos_pdm_auto_cancel_upgrade_decision
* use UpgradeDecision_processUpgrade
* alarm to destroy software installation
* drop unused template
* configure Upgrade Decision worklist
* drop not needed script arguments
* add Upgrade Decision constraints
* method moved to global mixin
* do not upgrade if there is no instance yet
* create upgrade decision as soon as Allocation Supply is validated
* workaround to prevent breaking the instance when classes are live reloaded
* test: disable alarm when creating an allocation supply
* test: disable alarm
* software_release is an optional variation
  We can not update the Open Order every time one Instance is upgraded
* sort SoftwareProduct getVariationBaseCategoryList's result
* update xml format
* optional_variation_base_category_list are not set in variation_base_category_list
* force software change from Upgrade Decision
* drop template_instance_tree
* allow to force upgrade to a specific release
* rely on self instead of one a global
* drop view_related_upgrade_decision on Compute Node
  Deprecated for a long time
* set the causality relation on the ticket
* trigger upgrade alarm as soon as accepted
* deliver the decision when finished
* if not person can be found, search for everybody only

slapos_pdm: fixup tests
parent a869ecaf
......@@ -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>language</string> </key>
<value> <string>FR</string> </value>
<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>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>
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()
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_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:
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
person = context.getDestinationSectionValue(checked_permission='Access contents information')
# 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'
)
decision_in_progress = newer_release.\
SoftwareRelease_getUpgradeDecisionInProgress(instance_tree.getUid())
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)]
if decision_in_progress:
decision_in_progress.reviewRegistration(
software_release_url=newer_release.getUrlString())
if decision_in_progress.getSimulationState() != "cancelled":
# 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
upgrade_decision = newer_release.SoftwareRelease_createUpgradeDecision(
source_url=instance_tree.getRelativeUrl(),
title=decision_title
)
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()
upgrade_decision.approveRegistration(
upgrade_scope=upgrade_scope)
# 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>
......@@ -78,9 +78,7 @@
<item>
<key> <string>bottom (Preview)</string> </key>
<value>
<list>
<string>listbox</string>
</list>
<list/>
</value>
</item>
<item>
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
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