<?xml version="1.0"?>
<ZopeData>
  <record id="1" aka="AAAAAAAAAAE=">
    <pickle>
      <global name="PythonScript" module="Products.PythonScripts.PythonScript"/>
    </pickle>
    <pickle>
      <dictionary>
        <item>
            <key> <string>Script_magic</string> </key>
            <value> <int>3</int> </value>
        </item>
        <item>
            <key> <string>_bind_names</string> </key>
            <value>
              <object>
                <klass>
                  <global name="NameAssignments" module="Shared.DC.Scripts.Bindings"/>
                </klass>
                <tuple/>
                <state>
                  <dictionary>
                    <item>
                        <key> <string>_asgns</string> </key>
                        <value>
                          <dictionary>
                            <item>
                                <key> <string>name_container</string> </key>
                                <value> <string>container</string> </value>
                            </item>
                            <item>
                                <key> <string>name_context</string> </key>
                                <value> <string>context</string> </value>
                            </item>
                            <item>
                                <key> <string>name_m_self</string> </key>
                                <value> <string>script</string> </value>
                            </item>
                            <item>
                                <key> <string>name_subpath</string> </key>
                                <value> <string>traverse_subpath</string> </value>
                            </item>
                          </dictionary>
                        </value>
                    </item>
                  </dictionary>
                </state>
              </object>
            </value>
        </item>
        <item>
            <key> <string>_body</string> </key>
            <value> <string encoding="cdata"><![CDATA[

requester_instance = state_change[\'object\']\n
portal = requester_instance.getPortalObject()\n
# Get required arguments\n
kwargs = state_change.kwargs\n
\n
# Required args\n
# Raise TypeError if all parameters are not provided\n
try:\n
  software_release_url_string = kwargs[\'software_release\']\n
  software_title = kwargs["software_title"]\n
  software_type = kwargs["software_type"]\n
  instance_xml = kwargs["instance_xml"]\n
  sla_xml = kwargs["sla_xml"]\n
  is_slave = kwargs["shared"]\n
  root_state = kwargs["state"]\n
except KeyError:\n
  raise\n
  raise TypeError, "RequesterInstance_request takes exactly 7 arguments"\n
\n
if is_slave not in [True, False]:\n
  raise ValueError, "shared should be a boolean"\n
\n
# Hosting subscriptin is used as the root of the instance tree\n
if requester_instance.getPortalType() == "Hosting Subscription":\n
  hosting_subscription = requester_instance\n
else:\n
  hosting_subscription = requester_instance.getSpecialiseValue(portal_type="Hosting Subscription")\n
\n
# Instance can be moved from one requester to another\n
# Prevent creating two instances with the same title\n
tag = "%s_%s_inProgress" % (hosting_subscription.getUid(), software_title)\n
if (portal.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, it is better to raise an error\n
  raise NotImplementedError(tag)\n
\n
# graph allows to "simulate" tree change after requested operation\n
graph = {}\n
predecessor_list = hosting_subscription.getPredecessorValueList()\n
graph[hosting_subscription.getUid()] = [predecessor.getUid() for predecessor in predecessor_list]\n
while True:\n
  try:\n
    current_software_instance = predecessor_list.pop(0)\n
  except IndexError:\n
    break\n
  current_software_instance_predecessor_list = current_software_instance.getPredecessorValueList() or []\n
  graph[current_software_instance.getUid()] = [predecessor.getUid()\n
                                               for predecessor in current_software_instance_predecessor_list]\n
  predecessor_list.extend(current_software_instance_predecessor_list)\n
\n
# Check if it already exists\n
request_software_instance_list = portal.portal_catalog(\n
  # Fetch all portal type, as it is not allowed to change it\n
  portal_type=["Software Instance", "Slave Instance"],\n
  title={\'query\': software_title, \'key\': \'ExactMatch\'},\n
  specialise_uid=hosting_subscription.getUid(),\n
  # Do not fetch destroyed instances\n
  # XXX slap_state=["start_requested", "stop_requested"],\n
  validation_state="validated",\n
  limit=2,\n
)\n
instance_count = len(request_software_instance_list)\n
if instance_count == 0:\n
  request_software_instance = None\n
elif instance_count == 1:\n
  request_software_instance = request_software_instance_list[0].getObject()\n
else:\n
  raise ValueError, "Too many instances \'%s\' found: %s" % (software_title, [x.path for x in request_software_instance_list])\n
\n
if (request_software_instance is None):\n
  if (root_state == "destroyed"):\n
    instance_found = False\n
  else:\n
    instance_found = True\n
    # First time that the software instance is requested\n
\n
    # Create a new one\n
    reference = "SOFTINST-%s" % portal.portal_ids.generateNewId(\n
      id_group=\'slap_software_instance_reference\',\n
      id_generator=\'uid\')\n
\n
    new_content_kw = {}\n
    if is_slave == True:\n
      software_instance_portal_type = "Slave Instance"\n
    else:\n
      software_instance_portal_type = "Software Instance"\n
      certificate_dict = portal.portal_certificate_authority.getNewCertificate(reference)\n
      new_content_kw[\'destination_reference\'] = certificate_dict[\'id\']\n
      new_content_kw[\'ssl_key\'] = certificate_dict[\'key\']\n
      new_content_kw[\'ssl_certificate\'] = certificate_dict[\'certificate\']\n
\n
    module = portal.getDefaultModule(portal_type="Software Instance")\n
    request_software_instance = module.newContent(\n
      portal_type=software_instance_portal_type,\n
      title=software_title,\n
      specialise_value=hosting_subscription,\n
      reference=reference,\n
      activate_kw={\'tag\': tag},\n
      **new_content_kw\n
    )\n
    # request_software_instance.portal_workflow.doActionFor(request_software_instance, \'validate_action\')\n
    request_software_instance.validate()\n
    graph[request_software_instance.getUid()] = []\n
\n
else:\n
  instance_found = True\n
  # Update the predecessor category of the previous requester\n
  predecessor = request_software_instance.getPredecessorRelatedValue(portal_type="Software Instance")\n
  if (predecessor is None):\n
    if (requester_instance.getPortalType() != "Hosting Subscription"):\n
      raise ValueError(\'It is disallowed to request root software instance %s\' % request_software_instance.getRelativeUrl())\n
    else:\n
      predecessor = requester_instance\n
  predecessor_uid_list = predecessor.getPredecessorUidList()\n
  predecessor_uid_list.remove(request_software_instance.getUid())\n
  predecessor.edit(predecessor_uid_list=predecessor_uid_list)\n
  graph[predecessor.getUid()] = predecessor_uid_list\n
\n
if instance_found:\n
\n
  # Change desired state\n
  promise_kw = {\n
    \'instance_xml\': instance_xml,\n
    \'software_type\': software_type,\n
    \'sla_xml\': sla_xml,\n
    \'software_release\': software_release_url_string,\n
    \'shared\': is_slave,\n
  }\n
  request_software_instance_url = request_software_instance.getRelativeUrl()\n
  context.REQUEST.set(\'request_instance\', request_software_instance)\n
  if (root_state == "started"):\n
    request_software_instance.requestStart(**promise_kw)\n
  elif (root_state == "stopped"):\n
    request_software_instance.requestStop(**promise_kw)\n
  elif (root_state == "destroyed"):\n
    request_software_instance.requestDestroy(**promise_kw)\n
    context.REQUEST.set(\'request_instance\', None)\n
  else:\n
    raise ValueError, "state should be started, stopped or destroyed"\n
\n
  predecessor_list = requester_instance.getPredecessorList() + [request_software_instance_url]\n
  uniq_predecessor_list = list(set(predecessor_list))\n
  predecessor_list.sort()\n
  uniq_predecessor_list.sort()\n
\n
  assert predecessor_list == uniq_predecessor_list, "%s != %s" % (predecessor_list, uniq_predecessor_list)\n
\n
  # update graph to reflect requested operation\n
  graph[requester_instance.getUid()] = requester_instance.getPredecessorUidList() + [request_software_instance.getUid()]\n
\n
  # check if all elements are still connected and if there is no cycle\n
  request_software_instance.checkConnected(graph, hosting_subscription.getUid())\n
  request_software_instance.checkNotCyclic(graph)\n
\n
  requester_instance.edit(predecessor_list=predecessor_list)\n
\n
else:\n
  context.REQUEST.set(\'request_instance\', None)\n


]]></string> </value>
        </item>
        <item>
            <key> <string>_params</string> </key>
            <value> <string>state_change</string> </value>
        </item>
        <item>
            <key> <string>id</string> </key>
            <value> <string>RequesterInstance_request</string> </value>
        </item>
      </dictionary>
    </pickle>
  </record>
</ZopeData>
