Commit c54efeaa authored by Romain Courteaud's avatar Romain Courteaud

slapos_cloud:

* open personal
* allocation scope is meaningless to restrict allocation permission
* add follow_up category on Compute Node
  To attach to a project
* require a project reference when requesting a compute node
* requesting a compute node requires a project
* increase error verbosity
* stop using shadow to allocate instance
  Use project only
* set follow up on Instance Tree and Software Instance portal type
* requesting an instance tree requires a project
* assert project reference is provided
* propagate follow up when requesting instance
* requesting an instance requires a project
* add follow_up accessor on compute partition
* no need for follow_up on Compute Partition
* directly search follow_up value on parent Compute Node
* use new related key format
* drop source_administration from Compute Node
* drop source_administration on Compute Node
* drop source_administration from Compute Node
* Software Installation drop destination_section and use follow_up
* stop setting role/member on Assignment by default
* requesting an instance tree need a project reference
* add SlapOSVirtualMasterConstraint
  XXX TODO fix broken TALES expression which prevent entering invaludated/suspended
* configure SlapOSVirtualMasterConstraint on most slapos cloud portal types
  XXX TODO check if some are missing
* SlapOSVirtualMasterConstraint need f#+=!$ TALES expression
parent 1d56e5d0
<base_category_list>
<portal_type id="Compute Node">
<item>destination_section</item>
<item>source_administration</item>
</portal_type>
<portal_type id="Computer Model">
<item>source_administration</item>
......@@ -24,7 +23,6 @@
</portal_type>
<portal_type id="Software Installation">
<item>aggregate</item>
<item>destination_section</item>
</portal_type>
<portal_type id="Software Installation Module">
<item>business_application</item>
......
......@@ -10,6 +10,7 @@
<item>ComputerUpgradeConstraint</item>
<item>ERP5User</item>
<item>SlapOSReferenceConstraint</item>
<item>SlapOSVirtualMasterConstraint</item>
<item>SlaposCapacity</item>
<item>SlaposComputeNodeConstraint</item>
<item>Url</item>
......@@ -21,10 +22,15 @@
</portal_type>
<portal_type id="Computer">
<item>ComputerUpgradeConstraint</item>
<item>SlapOSVirtualMasterConstraint</item>
</portal_type>
<portal_type id="Computer Model">
<item>SlapOSVirtualMasterConstraint</item>
<item>SlaposCapacity</item>
</portal_type>
<portal_type id="Computer Network">
<item>SlapOSVirtualMasterConstraint</item>
</portal_type>
<portal_type id="Computer Partition">
<item>ComputerPartitionUpgradeConstraint</item>
</portal_type>
......@@ -37,6 +43,7 @@
<portal_type id="Instance Tree">
<item>HostingSubscriptionUpgradeConstraint</item>
<item>InstanceTree</item>
<item>SlapOSVirtualMasterConstraint</item>
<item>SlaposInstanceTreeConstraint</item>
<item>SoftwareInstance</item>
<item>SoftwareInstanceUpgradeConstraint</item>
......@@ -51,6 +58,7 @@
<item>InstanceTree</item>
<item>Reference</item>
<item>SlapOSReferenceConstraint</item>
<item>SlapOSVirtualMasterConstraint</item>
<item>SlaveInstanceConstraint</item>
<item>SoftwareInstance</item>
<item>SoftwareInstanceDuplicationConstraint</item>
......@@ -60,6 +68,7 @@
</portal_type>
<portal_type id="Software Installation">
<item>SlapOSReferenceConstraint</item>
<item>SlapOSVirtualMasterConstraint</item>
<item>Url</item>
<item>VariationRange</item>
</portal_type>
......@@ -68,6 +77,7 @@
<item>InstanceTree</item>
<item>Reference</item>
<item>SlapOSReferenceConstraint</item>
<item>SlapOSVirtualMasterConstraint</item>
<item>SoftwareInstance</item>
<item>SoftwareInstanceConstraint</item>
<item>SoftwareInstanceDuplicationConstraint</item>
......@@ -77,6 +87,7 @@
<item>VariationRange</item>
</portal_type>
<portal_type id="Software Release">
<item>SlapOSVirtualMasterConstraint</item>
<item>SlaposCapacity</item>
</portal_type>
</property_sheet_list>
\ No newline at end of file
</property_sheet_list>
......@@ -312,7 +312,7 @@
<key> <string>preferred_subscription_assignment_category</string> </key>
<value>
<tuple>
<string>role/member</string>
<string>function/customer</string>
</tuple>
</value>
</item>
......
<?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> <string>Require a portal type to be linked to a virtual master.\n
\n
XXX for now, use follow up category and project portal type</string> </value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>SlapOSVirtualMasterConstraint</string> </value>
</item>
<item>
<key> <string>portal_type</string> </key>
<value> <string>Property Sheet</string> </value>
</item>
</dictionary>
</pickle>
</record>
<record id="2" aka="AAAAAAAAAAI=">
<pickle>
<global name="Length" module="BTrees.Length"/>
</pickle>
<pickle> <int>0</int> </pickle>
</record>
<record id="3" aka="AAAAAAAAAAM=">
<pickle>
<global name="OOBTree" module="BTrees.OOBTree"/>
</pickle>
<pickle>
<none/>
</pickle>
</record>
<record id="4" aka="AAAAAAAAAAQ=">
<pickle>
<global name="OOBTree" module="BTrees.OOBTree"/>
</pickle>
<pickle>
<none/>
</pickle>
</record>
</ZopeData>
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="Category Property" module="erp5.portal_type"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>description</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>follow_up_category</string> </value>
</item>
<item>
<key> <string>portal_type</string> </key>
<value> <string>Category Property</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
......@@ -22,41 +22,25 @@
<key> <string>constraint_base_category</string> </key>
<value>
<tuple>
<string>role</string>
<string>follow_up</string>
</tuple>
</value>
</item>
<item>
<key> <string>constraint_portal_type</string> </key>
<value> <string>python: (\'Category\',)</string> </value>
<value> <string>python: (\'Project\', )</string> </value>
</item>
<item>
<key> <string>description</string> </key>
<value> <string>Role must be defined</string> </value>
<value> <string>Require to link to a Project</string> </value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>role_constraint</string> </value>
<value> <string>follow_up_project_contraint_constraint</string> </value>
</item>
<item>
<key> <string>max_arity</string> </key>
<value> <int>2</int> </value>
</item>
<item>
<key> <string>message_arity_not_in_range</string> </key>
<value> <string>One role should be defined</string> </value>
</item>
<item>
<key> <string>message_arity_too_small</string> </key>
<value> <string>No role is defined</string> </value>
</item>
<item>
<key> <string>message_arity_with_portal_type_not_in_range</string> </key>
<value> <string>One role should be defined</string> </value>
</item>
<item>
<key> <string>message_arity_with_portal_type_too_small</string> </key>
<value> <string>No role is defined</string> </value>
<value> <int>1</int> </value>
</item>
<item>
<key> <string>min_arity</string> </key>
......@@ -68,7 +52,7 @@
</item>
<item>
<key> <string>use_acquisition</string> </key>
<value> <int>1</int> </value>
<value> <int>0</int> </value>
</item>
</dictionary>
</pickle>
......
......@@ -2,45 +2,10 @@
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="Assignment" module="erp5.portal_type"/>
<global name="Category Membership State Constraint" 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>Auditor</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>Auditor</string>
<string>Manager</string>
<string>Owner</string>
</tuple>
</value>
</item>
<item>
<key> <string>_identity_criterion</string> </key>
<value>
......@@ -54,12 +19,8 @@
</value>
</item>
<item>
<key> <string>categories</string> </key>
<value>
<tuple>
<string>role/member</string>
</tuple>
</value>
<key> <string>base_category</string> </key>
<value> <string>follup_up</string> </value>
</item>
<item>
<key> <string>description</string> </key>
......@@ -69,21 +30,30 @@
</item>
<item>
<key> <string>id</string> </key>
<value> <string>1</string> </value>
<value> <string>follow_up_project_state_constraint_constraint</string> </value>
</item>
<item>
<key> <string>membership_portal_type_list</string> </key>
<value> <string>python: (\'Project\', )</string> </value>
</item>
<item>
<key> <string>portal_type</string> </key>
<value> <string>Assignment</string> </value>
<value> <string>Category Membership State Constraint</string> </value>
</item>
<item>
<key> <string>workflow_state_list</string> </key>
<value> <string>python: (\'validated\', \'invalidated\', \'suspended\')</string> </value>
</item>
<item>
<key> <string>workflow_variable</string> </key>
<value> <string>validation_state</string> </value>
</item>
</dictionary>
</pickle>
</record>
<record id="2" aka="AAAAAAAAAAI=">
<pickle>
<tuple>
<global name="PersistentMapping" module="Persistence.mapping"/>
<tuple/>
</tuple>
<global name="PersistentMapping" module="Persistence.mapping"/>
</pickle>
<pickle>
<dictionary>
......@@ -98,10 +68,7 @@
</record>
<record id="3" aka="AAAAAAAAAAM=">
<pickle>
<tuple>
<global name="PersistentMapping" module="Persistence.mapping"/>
<tuple/>
</tuple>
<global name="PersistentMapping" module="Persistence.mapping"/>
</pickle>
<pickle>
<dictionary>
......
......@@ -90,10 +90,6 @@
<string>modification_date</string>
<string>Modification Date</string>
</tuple>
<tuple>
<string>source_administration_title</string>
<string>Owner</string>
</tuple>
<tuple>
<string>python_version</string>
<string>Python</string>
......
if context.getPortalObject().portal_workflow.isTransitionPossible(context, 'mark_busy') and context.getParentValue().isMemberOf('allocation_scope/open'):
if context.getPortalObject().portal_workflow.isTransitionPossible(context, 'mark_busy'):
return 1
return 0
......@@ -13,5 +13,6 @@ person.requestSoftwareInstance(
software_type=context.getSourceReference(),
instance_xml=instance_xml,
sla_xml=context.getSlaXml(),
shared=context.isRootSlave()
shared=context.isRootSlave(),
project_reference=context.getFollowUpReference()
)
import random
from Products.ZSQLCatalog.SQLCatalog import SimpleQuery, ComplexQuery
person = context
portal = context.getPortalObject()
def getOpenAllocationScopeUidList(exclude_uid_list):
return [scope.getUid() for scope in portal.portal_categories.allocation_scope.open.objectValues()
if scope.getUid() not in exclude_uid_list]
assert project_uid
compute_partition = None
filter_kw_copy = filter_kw.copy()
query_kw = {
'parent__follow_up__uid': project_uid,
'software_release_url': software_release_url,
'portal_type': 'Compute Partition',
}
......@@ -35,6 +32,7 @@ if 'network_guid' in filter_kw:
network_guid = filter_kw.pop('network_guid')
query_kw["default_subordination_reference"] = SimpleQuery(default_subordination_reference=network_guid)
"""
if 'project_guid' in filter_kw:
# This implementation isn't optimal, as we would prefere place a direct query rather them make an
# direct query.
......@@ -47,6 +45,7 @@ if 'project_guid' in filter_kw:
if project is not None:
query_kw["parent_reference"] = SimpleQuery(parent_reference=project.Project_getComputeNodeReferenceList())
"""
if computer_network_query:
if query_kw.get("default_subordination_reference"):
......@@ -86,27 +85,12 @@ for base_category in compute_node_base_category_list:
if category is None:
query_kw["uid"] = "-1"
else:
query_kw["%s_uid" % base_category] = category.getUid()
query_kw["%s__uid" % base_category] = category.getUid()
if 'capability' in filter_kw:
capability = filter_kw.pop('capability')
query_kw['subject'] = {'query': capability, 'key': 'ExactMatch'}
query_kw["capacity_scope_uid"] = portal.portal_categories.capacity_scope.open.getUid()
if subscription_reference is not None and software_instance_portal_type != "Slave Instance":
# Subscriptions uses a specific set of allocation scope
query_kw["allocation_scope_uid"] = portal.portal_categories.allocation_scope.open.subscription.getUid()
elif subscription_reference is not None and \
software_instance_portal_type == "Slave Instance" and \
is_root_slave:
# Subscriptions uses a specific set of allocation scope
query_kw["allocation_scope_uid"] = getOpenAllocationScopeUidList([])
else:
# else pic anything but open/subscription
query_kw["allocation_scope_uid"] = getOpenAllocationScopeUidList(
exclude_uid_list=[portal.portal_categories.allocation_scope.open.subscription.getUid()])
extra_query_kw = context.ComputePartition_getCustomAllocationParameterDict(
software_release_url, software_type, software_instance_portal_type,
filter_kw_copy, computer_network_query, test_mode)
......
......@@ -50,7 +50,7 @@
</item>
<item>
<key> <string>_params</string> </key>
<value> <string>software_release_url, software_type, software_instance_portal_type, filter_kw, computer_network_query=None, subscription_reference=None, is_root_slave=False, test_mode=False</string> </value>
<value> <string>project_uid, software_release_url, software_type, software_instance_portal_type, filter_kw, computer_network_query=None, subscription_reference=None, is_root_slave=False, test_mode=False</string> </value>
</item>
<item>
<key> <string>id</string> </key>
......
......@@ -17,7 +17,8 @@ def assignComputePartition(software_instance, instance_tree):
portal_type="Compute Partition")
if compute_partition is None:
instance_tree = software_instance.getSpecialiseValue(
portal_type='Instance Tree')
portal_type='Instance Tree'
)
if instance_tree is None:
raise ValueError('%s does not have related instance tree' % software_instance.getRelativeUrl())
......@@ -109,12 +110,23 @@ def assignComputePartition(software_instance, instance_tree):
elif sla_dict.get('mode'):
computer_network_query = '-1'
"""
compute_partition_relative_url = person.Person_restrictMethodAsShadowUser(
shadow_document=person,
callable_object=person.Person_findPartition,
argument_list=[software_instance.getUrlString(), software_instance.getSourceReference(),
software_instance.getPortalType(), sla_dict, computer_network_query,
subscription_reference, instance_tree.isRootSlave()])
"""
compute_partition_relative_url = person.Person_findPartition(
software_instance.getFollowUpUid(portal_type='Project'),
software_instance.getUrlString(),
software_instance.getSourceReference(),
software_instance.getPortalType(),
sla_dict, computer_network_query,
subscription_reference,
instance_tree.isRootSlave()
)
return compute_partition_relative_url, tag
software_instance = context
......
......@@ -122,8 +122,8 @@ class DefaultScenarioMixin(TestSlapOSSecurityMixin):
def setAccessToMemcached(self, agent):
agent.setAccessStatus("#access ")
def requestComputeNode(self, title):
requestXml = self.portal.portal_slap.requestComputer(title)
def requestComputeNode(self, title, project_reference):
requestXml = self.portal.portal_slap.requestComputer(title, project_reference)
self.tic()
self.assertTrue('marshal' in requestXml)
compute_node = xml_marshaller.xml_marshaller.loads(requestXml)
......@@ -329,14 +329,16 @@ class DefaultScenarioMixin(TestSlapOSSecurityMixin):
return software_instance
def checkSlaveInstanceAllocation(self, person_user_id, person_reference,
instance_title, software_release, software_type, server):
instance_title, software_release, software_type, server,
project_reference):
self.login(person_user_id)
self.personRequestInstanceNotReady(
software_release=software_release,
software_type=software_type,
partition_reference=instance_title,
shared_xml='<marshal><bool>1</bool></marshal>'
shared_xml='<marshal><bool>1</bool></marshal>',
project_reference=project_reference
)
self.stepCallSlaposAllocateInstanceAlarm()
......@@ -374,7 +376,8 @@ class DefaultScenarioMixin(TestSlapOSSecurityMixin):
def checkSlaveInstanceUnallocation(self, person_user_id,
person_reference, instance_title,
software_release, software_type, server):
software_release, software_type, server,
project_reference):
self.login(person_user_id)
self.personRequestInstanceNotReady(
......@@ -382,7 +385,8 @@ class DefaultScenarioMixin(TestSlapOSSecurityMixin):
software_type=software_type,
partition_reference=instance_title,
shared_xml='<marshal><bool>1</bool></marshal>',
state='<marshal><string>destroyed</string></marshal>'
state='<marshal><string>destroyed</string></marshal>',
project_reference=project_reference
)
# let's find instances of user and check connection strings
......@@ -394,14 +398,15 @@ class DefaultScenarioMixin(TestSlapOSSecurityMixin):
def checkInstanceUnallocation(self, person_user_id,
person_reference, instance_title,
software_release, software_type, server):
software_release, software_type, server, project_reference):
self.login(person_user_id)
self.personRequestInstanceNotReady(
software_release=software_release,
software_type=software_type,
partition_reference=instance_title,
state='<marshal><string>destroyed</string></marshal>'
state='<marshal><string>destroyed</string></marshal>',
project_reference=project_reference
)
# now instantiate it on compute_node and set some nice connection dict
......@@ -477,7 +482,8 @@ class DefaultScenarioMixin(TestSlapOSSecurityMixin):
def checkInstanceAllocation(self, person_user_id, person_reference,
instance_title, software_release, software_type, server):
instance_title, software_release, software_type, server,
project_reference):
self.login(person_user_id)
......@@ -485,6 +491,7 @@ class DefaultScenarioMixin(TestSlapOSSecurityMixin):
software_release=software_release,
software_type=software_type,
partition_reference=instance_title,
project_reference=project_reference
)
self.checkCloudContract(person_user_id, person_reference,
......@@ -497,6 +504,7 @@ class DefaultScenarioMixin(TestSlapOSSecurityMixin):
software_release=software_release,
software_type=software_type,
partition_reference=instance_title,
project_reference=project_reference
)
# now instantiate it on compute_node and set some nice connection dict
......@@ -706,11 +714,12 @@ class DefaultScenarioMixin(TestSlapOSSecurityMixin):
self.assertEqual(subscription.getSlapState(), "destroy_requested")
def requestInstance(self, person_user_id, instance_title,
software_release, software_type):
software_release, software_type, project_reference):
self.login(person_user_id)
self.personRequestInstanceNotReady(
software_release=software_release,
software_type=software_type,
partition_reference=instance_title,
project_reference=project_reference
)
......@@ -640,8 +640,8 @@ class TestSlapOSCorePersonRequestComputeNode(SlapOSTestCaseMixin):
self.assertEqual(compute_node_reference, compute_node.getReference())
self.assertEqual('COMP-%s' % (previous_id + 1), compute_node.getReference())
self.assertEqual('validated', compute_node.getValidationState())
self.assertEqual('open/personal', compute_node.getAllocationScope())
self.assertEqual('close', compute_node.getCapacityScope())
self.assertEqual(None, compute_node.getAllocationScope())
self.assertEqual('open', compute_node.getCapacityScope())
def test_request_notReindexedCompute(self):
person = self.portal.portal_membership.getAuthenticatedMember().getUserValue()
......
compute_node = state_change['object']
portal = compute_node.getPortalObject()
person = portal.portal_membership.getAuthenticatedMember().getUserValue()
compute_node.edit(
source_administration_value=person,
upgrade_scope='auto',
capacity_scope='open'
)
......
......@@ -48,8 +48,8 @@ else:
reference=software_installation_reference,
url_string=software_release_url,
aggregate=compute_node.getRelativeUrl(),
activate_kw={'tag': tag},
destination_section=compute_node.getSourceAdministration()
follow_up_value=compute_node.getFollowUpValue(),
activate_kw={'tag': tag}
)
# Change desired state
......
......@@ -52,6 +52,12 @@
<key> <string>_params</string> </key>
<value> <string>state_change</string> </value>
</item>
<item>
<key> <string>description</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>script_ComputeNode_requestSoftwareReleaseChange</string> </value>
......
......@@ -91,6 +91,7 @@ if (request_software_instance is None):
portal_type=software_instance_portal_type,
title=software_title,
specialise_value=instance_tree,
follow_up_value=instance_tree.getFollowUpValue(portal_type='Project'),
reference=reference,
activate_kw={'tag': tag}
)
......
......@@ -8,7 +8,12 @@ kwargs = state_change.kwargs
try:
compute_node_title = kwargs['compute_node_title']
except KeyError:
raise TypeError, "Person_requestComputeNode takes exactly 1 argument"
raise TypeError, "Person_requestComputeNode takes exactly 2 arguments. Missing compute_node_title."
try:
project_reference = kwargs['project_reference']
except KeyError:
raise TypeError, "Person_requestComputeNode takes exactly 2 arguments. Missing project_reference."
tag = "%s_%s_ComputeNodeInProgress" % (person.getUid(),
compute_node_title)
......@@ -17,6 +22,12 @@ if (portal.portal_activities.countMessageWithTag(tag) > 0):
# As it is not possible to fetch informations, it is better to raise an error
raise NotImplementedError(tag)
# Ensure project is correctly set
project_list = portal.portal_catalog.portal_catalog(portal_type='Project', reference=project_reference,
validation_state='validated', limit=2)
if len(project_list) != 1:
raise NotImplementedError("%i projects '%s'" % (len(project_list), project_reference))
compute_node_portal_type = "Compute Node"
compute_node_list = portal.portal_catalog.portal_catalog(portal_type=compute_node_portal_type, title=compute_node_title, limit=2)
......@@ -24,6 +35,7 @@ if len(compute_node_list) == 2:
raise NotImplementedError
elif len(compute_node_list) == 1:
compute_node = compute_node_list[0]
assert compute_node.getFollowUp() == project_list[0].getRelativeUrl()
else:
reference = "COMP-%s" % portal.portal_ids.generateNewId(
......@@ -34,6 +46,7 @@ else:
portal_type=compute_node_portal_type,
title=compute_node_title,
reference=reference,
follow_up_value=project_list[0],
activate_kw={'tag': tag}
)
compute_node.approveComputeNodeRegistration()
......
......@@ -13,8 +13,9 @@ try:
sla_xml = kwargs["sla_xml"]
is_slave = kwargs["shared"]
root_state = kwargs["state"]
project_reference = kwargs['project_reference']
except KeyError:
raise TypeError, "Person_requestSoftwareInstance takes exactly 7 arguments"
raise TypeError, "Person_requestSoftwareInstance takes exactly 8 arguments"
if is_slave not in [True, False]:
raise ValueError, "shared should be a boolean"
......@@ -29,6 +30,13 @@ if (portal.portal_activities.countMessageWithTag(tag) > 0):
# As it is not possible to fetch informations, it is better to raise an error
raise NotImplementedError(tag)
# Ensure project is correctly set
assert project_reference, 'No project reference'
project_list = portal.portal_catalog.portal_catalog(portal_type='Project', reference=project_reference,
validation_state='validated', limit=2)
if len(project_list) != 1:
raise NotImplementedError("%i projects '%s'" % (len(project_list), project_reference))
# Check if it already exists
request_instance_tree_list = portal.portal_catalog(
portal_type=instance_tree_portal_type,
......@@ -41,6 +49,7 @@ if len(request_instance_tree_list) > 1:
raise NotImplementedError, "Too many instance tree %s found %s" % (software_title, [x.path for x in request_instance_tree_list])
elif len(request_instance_tree_list) == 1:
request_instance_tree = request_instance_tree_list[0].getObject()
assert request_instance_tree.getFollowUp() == project_list[0].getRelativeUrl()
if (request_instance_tree.getSlapState() == "destroy_requested") or \
(request_instance_tree.getTitle() != software_title) or \
(request_instance_tree.getValidationState() != "validated") or \
......@@ -59,6 +68,7 @@ else:
title=software_title,
destination_section=person.getRelativeUrl(),
upgrade_scope="auto",
follow_up_value=project_list[0],
activate_kw={'tag': tag},
)
......
Compute Node | destination_section
Compute Node | source_administration
Computer Model | source_administration
Computer Network | source_administration
Hosting Subscription Module | business_application
......@@ -9,7 +8,6 @@ Slave Instance | aggregate
Slave Instance | specialise
Software Installation Module | business_application
Software Installation | aggregate
Software Installation | destination_section
Software Instance Module | business_application
Software Instance | aggregate
Software Instance | specialise
......
......@@ -4,19 +4,24 @@ Compute Node | ComputeNodeSlapOSMetadata
Compute Node | ComputerUpgradeConstraint
Compute Node | ERP5User
Compute Node | SlapOSReferenceConstraint
Compute Node | SlapOSVirtualMasterConstraint
Compute Node | SlaposCapacity
Compute Node | SlaposComputeNodeConstraint
Compute Node | Url
Compute Partition | ComputePartition
Compute Partition | ComputerPartitionUpgradeConstraint
Compute Partition | SlaposComputePartitionConstraint
Computer Model | SlapOSVirtualMasterConstraint
Computer Model | SlaposCapacity
Computer Network | SlapOSVirtualMasterConstraint
Computer Partition | ComputerPartitionUpgradeConstraint
Computer | ComputerUpgradeConstraint
Computer | SlapOSVirtualMasterConstraint
Email | SlaposEmailConstraint
Hosting Subscription | HostingSubscriptionUpgradeConstraint
Instance Tree | HostingSubscriptionUpgradeConstraint
Instance Tree | InstanceTree
Instance Tree | SlapOSVirtualMasterConstraint
Instance Tree | SlaposInstanceTreeConstraint
Instance Tree | SoftwareInstance
Instance Tree | SoftwareInstanceUpgradeConstraint
......@@ -27,6 +32,7 @@ Person | SlaposPersonConstraint
Slave Instance | InstanceTree
Slave Instance | Reference
Slave Instance | SlapOSReferenceConstraint
Slave Instance | SlapOSVirtualMasterConstraint
Slave Instance | SlaveInstanceConstraint
Slave Instance | SoftwareInstance
Slave Instance | SoftwareInstanceDuplicationConstraint
......@@ -34,12 +40,14 @@ Slave Instance | TextDocument
Slave Instance | Url
Slave Instance | VariationRange
Software Installation | SlapOSReferenceConstraint
Software Installation | SlapOSVirtualMasterConstraint
Software Installation | Url
Software Installation | VariationRange
Software Instance | ERP5User
Software Instance | InstanceTree
Software Instance | Reference
Software Instance | SlapOSReferenceConstraint
Software Instance | SlapOSVirtualMasterConstraint
Software Instance | SoftwareInstance
Software Instance | SoftwareInstanceConstraint
Software Instance | SoftwareInstanceDuplicationConstraint
......@@ -47,4 +55,5 @@ Software Instance | SoftwareInstanceUpgradeConstraint
Software Instance | TextDocument
Software Instance | Url
Software Instance | VariationRange
Software Release | SlaposCapacity
\ No newline at end of file
Software Release | SlapOSVirtualMasterConstraint
Software Release | SlaposCapacity
......@@ -18,4 +18,5 @@ SlaposAssignmentConstraint
SlaposEmailConstraint
SlaposComputeNodeConstraint
ComputeNodeSlapOSMetadata
SlapOSReferenceConstraint
\ No newline at end of file
SlapOSReferenceConstraint
SlapOSVirtualMasterConstraint
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