X-Git-Url: https://osm.etsi.org/gitweb/?p=osm%2FRO.git;a=blobdiff_plain;f=RO%2Fosm_ro%2Fvim_thread.py;h=380bd6a6a510bb868a1986ed7afbcf045415e8dd;hp=06e2592ec0cbb772f6942faff717e739df2a1653;hb=bf1d0f10e219ae475213b947ce8c76c77c40c452;hpb=8a2dda3d4ff0a0c72a6c31232937f4f66a032106 diff --git a/RO/osm_ro/vim_thread.py b/RO/osm_ro/vim_thread.py index 06e2592e..380bd6a6 100644 --- a/RO/osm_ro/vim_thread.py +++ b/RO/osm_ro/vim_thread.py @@ -126,7 +126,7 @@ class vim_thread(threading.Thread): self.error_status = None self.wim_account_id = wim_account_id self.datacenter_tenant_id = datacenter_tenant_id - self.port_mapping = None + self.port_mappings = None if self.wim_account_id: self.target_k = "wim_account_id" self.target_v = self.wim_account_id @@ -293,9 +293,6 @@ class vim_thread(threading.Thread): }) continue - # task of creation must be the first in the list of related_task - assert(related_tasks[0]["action"] in ("CREATE", "FIND")) - task["params"] = None if task["extra"]: extra = yaml.load(task["extra"], Loader=yaml.Loader) @@ -323,6 +320,8 @@ class vim_thread(threading.Thread): copy_to["sdn_net_id"] = copy_from["sdn_net_id"] if copy_from.get("interfaces"): copy_to["interfaces"] = copy_from["interfaces"] + if copy_from.get("sdn-ports"): + copy_to["sdn-ports"] = copy_from["sdn-ports"] if copy_from.get("created_items"): if not copy_to.get("created_items"): copy_to["created_items"] = {} @@ -330,11 +329,13 @@ class vim_thread(threading.Thread): task_create = None dependency_task = None - deletion_needed = False + deletion_needed = task["extra"].get("created", False) if task["status"] == "FAILED": return # TODO need to be retry?? try: - # get all related tasks + # get all related tasks. task of creation must be the first in the list of related_task, + # unless the deletion fails and it is pendingit fails + # TODO this should be removed, passing related_tasks related_tasks = self.db.get_rows(FROM="vim_wim_actions", WHERE={self.target_k: self.target_v, "status": ['SCHEDULED', 'BUILD', 'DONE', 'FAILED'], @@ -358,13 +359,14 @@ class vim_thread(threading.Thread): break # mark task_create as FINISHED - self.db.update_rows("vim_wim_actions", UPDATE={"status": "FINISHED"}, - WHERE={self.target_k: self.target_v, - "instance_action_id": task_create["instance_action_id"], - "task_index": task_create["task_index"] - }) + if task_create: + self.db.update_rows("vim_wim_actions", UPDATE={"status": "FINISHED"}, + WHERE={self.target_k: self.target_v, + "instance_action_id": task_create["instance_action_id"], + "task_index": task_create["task_index"] + }) if not deletion_needed: - return + return False elif dependency_task: # move create information from task_create to relate_task extra_new_created = yaml.load(dependency_task["extra"], Loader=yaml.Loader) or {} @@ -380,10 +382,19 @@ class vim_thread(threading.Thread): "task_index": dependency_task["task_index"] }) return False - else: + elif task_create: task["vim_id"] = task_create["vim_id"] copy_extra_created(copy_to=task["extra"], copy_from=task_create["extra"]) + # Ensure this task extra information is stored at database + self.db.update_rows("vim_wim_actions", + UPDATE={"extra": yaml.safe_dump(task["extra"], default_flow_style=True, + width=256)}, + WHERE={self.target_k: self.target_v, + "instance_action_id": task["instance_action_id"], + "task_index": task["task_index"], + }) return True + return deletion_needed except Exception as e: self.logger.critical("Unexpected exception at _delete_task: " + str(e), exc_info=True) @@ -548,6 +559,7 @@ class vim_thread(threading.Thread): old_task_status = task["status"] create_or_find = False # if as result of processing this task something is created or found next_refresh = 0 + task_id = task["instance_action_id"] + "." + str(task["task_index"]) try: if task["status"] == "SCHEDULED": @@ -706,16 +718,17 @@ class vim_thread(threading.Thread): else: raise vimconn.vimconnException(self.name + "unknown task item {}".format(task["item"])) # TODO - except VimThreadException as e: + except Exception as e: + if not isinstance(e, VimThreadException): + self.logger.error("Error executing task={}: {}".format(task_id, e), exc_info=True) task["error_msg"] = str(e) task["status"] = "FAILED" database_update = {"status": "VIM_ERROR", "error_msg": task["error_msg"]} - if task["item"] == 'instance_vms': - database_update["vim_vm_id"] = None - elif task["item"] == 'instance_nets': - database_update["vim_net_id"] = None + # if task["item"] == 'instance_vms': + # database_update["vim_vm_id"] = None + # elif task["item"] == 'instance_nets': + # database_update["vim_net_id"] = None - task_id = task["instance_action_id"] + "." + str(task["task_index"]) self.logger.debug("task={} item={} action={} result={}:'{}' params={}".format( task_id, task["item"], task["action"], task["status"], task["vim_id"] if task["status"] == "DONE" else task.get("error_msg"), task["params"])) @@ -1127,19 +1140,21 @@ class vim_thread(threading.Thread): # look for ports sdn_ports = [] pending_ports = 0 + vlan_used = None ports = self.db.get_rows(FROM='instance_interfaces', WHERE={'instance_wim_net_id': task["item_id"]}) sdn_need_update = False for port in ports: + vlan_used = port.get("vlan") or vlan_used # TODO. Do not connect if already done if port.get("compute_node") and port.get("pci"): - for map in self.port_mappings: - if map.get("device_id") == port["compute_node"] and \ - map.get("device_interface_id") == port["pci"]: + for pmap in self.port_mappings: + if pmap.get("device_id") == port["compute_node"] and \ + pmap.get("device_interface_id") == port["pci"]: break else: if self.sdnconn_config.get("mapping_not_needed"): - map = { + pmap = { "service_endpoint_id": "{}:{}".format(port["compute_node"], port["pci"]), "service_endpoint_encapsulation_info": { "vlan": port["vlan"], @@ -1149,25 +1164,25 @@ class vim_thread(threading.Thread): } } else: - map = None + pmap = None error_list.append("Port mapping not found for compute_node={} pci={}".format( port["compute_node"], port["pci"])) - if map: - if port["uuid"] not in connected_ports or port["modified_at"] > last_update: + if pmap: + if port["modified_at"] > last_update: sdn_need_update = True new_connected_ports.append(port["uuid"]) sdn_ports.append({ - "service_endpoint_id": map["service_endpoint_id"], + "service_endpoint_id": pmap["service_endpoint_id"], "service_endpoint_encapsulation_type": "dot1q" if port["model"] == "SR-IOV" else None, "service_endpoint_encapsulation_info": { "vlan": port["vlan"], "mac": port["mac_address"], - "device_id": map.get("device_id"), - "device_interface_id": map.get("device_interface_id"), - "switch_dpid": map.get("switch_dpid"), - "switch_port": map.get("switch_port"), - "service_mapping_info": map.get("service_mapping_info"), + "device_id": pmap.get("device_id"), + "device_interface_id": pmap.get("device_interface_id"), + "switch_dpid": pmap.get("switch_dpid"), + "switch_port": pmap.get("switch_port"), + "service_mapping_info": pmap.get("service_mapping_info"), } }) @@ -1176,8 +1191,28 @@ class vim_thread(threading.Thread): if pending_ports: error_list.append("Waiting for getting interfaces location from VIM. Obtained '{}' of {}" .format(len(ports)-pending_ports, len(ports))) + + # connect external ports + for index, external_port in enumerate(task["extra"].get("sdn-ports") or ()): + external_port_id = external_port.get("service_endpoint_id") or str(index) + sdn_ports.append({ + "service_endpoint_id": external_port_id, + "service_endpoint_encapsulation_type": external_port.get("service_endpoint_encapsulation_type", + "dot1q"), + "service_endpoint_encapsulation_info": { + "vlan": external_port.get("vlan") or vlan_used, + "mac": external_port.get("mac_address"), + "device_id": external_port.get("device_id"), + "device_interface_id": external_port.get("device_interface_id"), + "switch_dpid": external_port.get("switch_dpid") or external_port.get("switch_id"), + "switch_port": external_port.get("switch_port"), + "service_mapping_info": external_port.get("service_mapping_info"), + }}) + new_connected_ports.append(external_port_id) + # if there are more ports to connect or they have been modified, call create/update - if sdn_need_update and len(sdn_ports) >= 2: + if (set(connected_ports) != set(new_connected_ports) or sdn_need_update) and len(sdn_ports) >= 2: + last_update = time.time() if not wimconn_net_id: if params[0] == "data": net_type = "ELAN" @@ -1190,7 +1225,6 @@ class vim_thread(threading.Thread): else: created_items = self.sdnconnector.edit_connectivity_service(wimconn_net_id, conn_info=created_items, connection_points=sdn_ports) - last_update = time.time() connected_ports = new_connected_ports elif wimconn_net_id: try: