[slapos_cloud] Add support for "unique_by_network" SLA mode.

parent 1f9ac435
...@@ -53,7 +53,7 @@ ...@@ -53,7 +53,7 @@
<value> <string encoding="cdata"><![CDATA[ <value> <string encoding="cdata"><![CDATA[
import random\n import random\n
from Products.ZSQLCatalog.SQLCatalog import SimpleQuery\n from Products.ZSQLCatalog.SQLCatalog import SimpleQuery, ComplexQuery\n
person = context\n person = context\n
\n \n
computer_partition = None\n computer_partition = None\n
...@@ -88,6 +88,15 @@ if \'network_guid\' in filter_kw:\n ...@@ -88,6 +88,15 @@ if \'network_guid\' in filter_kw:\n
network_guid = filter_kw.pop(\'network_guid\')\n network_guid = filter_kw.pop(\'network_guid\')\n
query_kw["default_subordination_reference"] = SimpleQuery(default_subordination_reference=network_guid)\n query_kw["default_subordination_reference"] = SimpleQuery(default_subordination_reference=network_guid)\n
\n \n
if computer_network_query:\n
if query_kw.get("default_subordination_reference"):\n
query_kw["default_subordination_reference"] = ComplexQuery(\n
query_kw["default_subordination_reference"],\n
computer_network_query\n
)\n
else:\n
query_kw["default_subordination_reference"] = computer_network_query\n
\n
computer_base_category_list = [\n computer_base_category_list = [\n
\'group\',\n \'group\',\n
\'cpu_core\',\n \'cpu_core\',\n
...@@ -161,7 +170,7 @@ return computer_partition.getRelativeUrl()\n ...@@ -161,7 +170,7 @@ return computer_partition.getRelativeUrl()\n
</item> </item>
<item> <item>
<key> <string>_params</string> </key> <key> <string>_params</string> </key>
<value> <string>software_release_url, software_type, software_instance_portal_type, filter_kw, test_mode=False</string> </value> <value> <string>software_release_url, software_type, software_instance_portal_type, filter_kw, computer_network_query=None, test_mode=False</string> </value>
</item> </item>
<item> <item>
<key> <string>id</string> </key> <key> <string>id</string> </key>
......
...@@ -50,7 +50,10 @@ ...@@ -50,7 +50,10 @@
</item> </item>
<item> <item>
<key> <string>_body</string> </key> <key> <string>_body</string> </key>
<value> <string>from Products.DCWorkflow.DCWorkflow import ValidationFailed\n <value> <string encoding="cdata"><![CDATA[
from Products.DCWorkflow.DCWorkflow import ValidationFailed\n
from Products.ZSQLCatalog.SQLCatalog import SimpleQuery, ComplexQuery\n
from zExceptions import Unauthorized\n from zExceptions import Unauthorized\n
\n \n
if context.getPortalType() not in (\'Software Instance\', \'Slave Instance\'):\n if context.getPortalType() not in (\'Software Instance\', \'Slave Instance\'):\n
...@@ -63,7 +66,7 @@ def markHistory(document, comment):\n ...@@ -63,7 +66,7 @@ def markHistory(document, comment):\n
if last_workflow_item != comment:\n if last_workflow_item != comment:\n
portal_workflow.doActionFor(document, action=\'edit_action\', comment=comment)\n portal_workflow.doActionFor(document, action=\'edit_action\', comment=comment)\n
\n \n
def assignComputerPartition(software_instance):\n def assignComputerPartition(software_instance, hosting_subscription):\n
computer_partition = software_instance.getAggregateValue(\n computer_partition = software_instance.getAggregateValue(\n
portal_type="Computer Partition")\n portal_type="Computer Partition")\n
if computer_partition is None:\n if computer_partition is None:\n
...@@ -75,18 +78,66 @@ def assignComputerPartition(software_instance):\n ...@@ -75,18 +78,66 @@ def assignComputerPartition(software_instance):\n
if not person.Person_isAllowedToAllocate():\n if not person.Person_isAllowedToAllocate():\n
raise Unauthorized(\'Allocation disallowed\')\n raise Unauthorized(\'Allocation disallowed\')\n
\n \n
tag = None\n
try:\n try:\n
sla_dict = software_instance.getSlaXmlAsDict()\n sla_dict = software_instance.getSlaXmlAsDict()\n
except Exception:\n except Exception:\n
# Note: it is impossible to import module exceptions from python scripts\n # Note: it is impossible to import module exceptions from python scripts\n
computer_partition_relative_url = None\n computer_partition_relative_url = None\n
else:\n else:\n
\n
# "Each instance should be allocated to a different network." (i.e at most one instance of the tree per network)\n
computer_network_query = None\n
if sla_dict.get(\'mode\', None) == \'unique_by_network\':\n
# Prevent creating two instances in the same computer_network\n
hosting_subscription_uid = hosting_subscription.getUid()\n
tag = "%s_inProgress" % hosting_subscription_uid\n
if (context.getPortalObject().portal_activities.countMessageWithTag(tag) > 0):\n
# The software instance is already under creation but can not be fetched from catalog\n
# As it is not possible to fetch informations, just ignore\n
markHistory(software_instance,\n
\'Allocation failed: blocking activites in progress for %s\' % hosting_subscription_uid)\n
\n
sla_dict.pop(\'mode\')\n
# XXX: does NOT scale if hosting subscription contains many SoftwareInstance\n
hosting_subscription = software_instance.getSpecialiseValue()\n
software_instance_tree_list = [sql_obj.getObject() \\\n
for sql_obj in context.getPortalObject().portal_catalog(\n
portal_type=[\'Software Instance\', \'Slave Instance\'],\n
default_specialise_uid=hosting_subscription.getUid(),\n
)\n
]\n
computer_network_query_list = []\n
# Don\'t deploy in computer with no network\n
computer_network_query_list.append(ComplexQuery(\n
SimpleQuery(\n
default_subordination_uid=\'\'),\n
logical_operator=\'not\',\n
))\n
for software_instance in software_instance_tree_list:\n
computer_partition = software_instance.getAggregateValue()\n
if not computer_partition:\n
continue\n
computer_network = computer_partition.getParentValue().getSubordinationValue()\n
if computer_network:\n
computer_network_query_list.append(ComplexQuery(\n
SimpleQuery(\n
default_subordination_uid=computer_network.getUid()),\n
logical_operator=\'not\',\n
))\n
\n
computer_network_query = ComplexQuery(*computer_network_query_list)\n
hosting_subscription.serialize()\n
\n
elif sla_dict.get(\'mode\'):\n
computer_network_query = \'-1\'\n
\n
computer_partition_relative_url = person.Person_restrictMethodAsShadowUser(\n computer_partition_relative_url = person.Person_restrictMethodAsShadowUser(\n
shadow_document=person,\n shadow_document=person,\n
callable_object=person.Person_findPartition,\n callable_object=person.Person_findPartition,\n
argument_list=[software_instance.getUrlString(), software_instance.getSourceReference(),\n argument_list=[software_instance.getUrlString(), software_instance.getSourceReference(),\n
software_instance.getPortalType(), sla_dict])\n software_instance.getPortalType(), sla_dict, computer_network_query])\n
return computer_partition_relative_url\n return computer_partition_relative_url, tag\n
\n \n
software_instance = context\n software_instance = context\n
if software_instance.getValidationState() != \'validated\' \\\n if software_instance.getValidationState() != \'validated\' \\\n
...@@ -94,14 +145,25 @@ if software_instance.getValidationState() != \'validated\' \\\n ...@@ -94,14 +145,25 @@ if software_instance.getValidationState() != \'validated\' \\\n
or software_instance.getAggregateValue(portal_type=\'Computer Partition\') is not None:\n or software_instance.getAggregateValue(portal_type=\'Computer Partition\') is not None:\n
return\n return\n
\n \n
hosting_subscription = software_instance.getSpecialiseValue()\n
try:\n try:\n
computer_partition_url = assignComputerPartition(software_instance)\n computer_partition_url, tag = assignComputerPartition(software_instance,\n
hosting_subscription)\n
\n
# XXX: We create a dummy activity to prevent to allocations on the same network\n
if tag:\n
hosting_subscription.activate(activity="SQLQueue", tag=tag,\n
after_tag="allocate_%s" % computer_partition_url).getId()\n
\n
except ValueError:\n except ValueError:\n
# It was not possible to find free Computer Partition\n # It was not possible to find free Computer Partition\n
markHistory(software_instance, \'Allocation failed: no free Computer Partition\')\n markHistory(software_instance, \'Allocation failed: no free Computer Partition\')\n
except Unauthorized, e:\n except Unauthorized, e:\n
# user has bad balance\n # user has bad balance\n
markHistory(software_instance, \'Allocation failed: %s\' % e)\n markHistory(software_instance, \'Allocation failed: %s\' % e)\n
except NotImplementedError, e:\n
# user has bad balance\n
markHistory(software_instance, \'Allocation failed: %s\' % e)\n
else:\n else:\n
if computer_partition_url is not None:\n if computer_partition_url is not None:\n
try:\n try:\n
...@@ -111,7 +173,9 @@ else:\n ...@@ -111,7 +173,9 @@ else:\n
markHistory(software_instance, \'Allocation failed: consistency failed\')\n markHistory(software_instance, \'Allocation failed: consistency failed\')\n
else:\n else:\n
software_instance.allocatePartition(computer_partition_url=computer_partition_url)\n software_instance.allocatePartition(computer_partition_url=computer_partition_url)\n
</string> </value>
]]></string> </value>
</item> </item>
<item> <item>
<key> <string>_params</string> </key> <key> <string>_params</string> </key>
......
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