def _manage_ports(self): try: self.apiroutine.subroutine(self._get_existing_ports()) connsetup = OVSDBConnectionSetup.createMatcher() bridgedown = OVSDBBridgeSetup.createMatcher(OVSDBBridgeSetup.DOWN) while True: yield (connsetup, bridgedown) e = self.apiroutine.event if self.apiroutine.matcher is connsetup: self.monitor_routines.add(self.apiroutine.subroutine(self._get_ports(e.connection, e.connection.protocol))) else: # Remove ports of the bridge ports = self.managed_ports.get((e.vhost, e.datapathid)) if ports is not None: ports_original = ports ports = [p for _,p in ports] for p in ports: if p['id']: self._remove_interface_id(e.connection, e.connection.protocol, e.datapathid, p) newdpid = getattr(e, 'new_datapath_id', None) buuid = e.bridgeuuid if newdpid is not None: # This bridge changes its datapath id if buuid in self.bridge_datapathid and self.bridge_datapathid[buuid] == e.datapathid: self.bridge_datapathid[buuid] = newdpid def re_add_interfaces(): with closing(self.apiroutine.executeAll( [self._get_interface_info(e.connection, e.connection.protocol, buuid, r['_uuid'], puuid) for puuid, r in ports_original])) as g: for m in g: yield m add = list(itertools.chain(r[0] for r in self.apiroutine.retvalue)) for m in self.apiroutine.waitForSend(ModuleNotification(self.getServiceName(), 'update', datapathid = e.datapathid, connection = e.connection, vhost = e.vhost, add = add, remove = [], reason = 'bridgeup' )): yield m self.apiroutine.subroutine(re_add_interfaces()) else: # The ports are removed for puuid, _ in ports_original: if puuid in self.ports_uuids[puuid] and self.ports_uuids[puuid] == buuid: del self.ports_uuids[puuid] del self.managed_ports[(e.vhost, e.datapathid)] self.scheduler.emergesend(ModuleNotification(self.getServiceName(), 'update', datapathid = e.datapathid, connection = e.connection, vhost = e.vhost, add = [], remove = ports, reason = 'bridgedown' )) finally: for r in list(self.monitor_routines): r.close() self.scheduler.emergesend(ModuleNotification(self.getServiceName(), 'unsynchronized'))
def process_port(buuid, port_uuid, interfaces, remove_ids): if buuid not in self.bridge_datapathid: return datapath_id = self.bridge_datapathid[buuid] ports = self.managed_ports.get((protocol.vhost, datapath_id)) remove = [] if ports is not None: remove = [p for _,p in ports if p['_uuid'] in remove_ids] not_remove = [(_,p) for _,p in ports if p['_uuid'] not in remove_ids] ports[:len(not_remove)] = not_remove del ports[len(not_remove):] if interfaces: try: with closing(self.apiroutine.executeAll([self._get_interface_info(connection, protocol, buuid, iuuid, port_uuid) for iuuid in interfaces])) as g: for m in g: yield m add = list(itertools.chain((r[0] for r in self.apiroutine.retvalue if r[0]))) except Exception: self._logger.warning("Cannot get new port information", exc_info = True) add = [] else: add = [] if update: for m in self.apiroutine.waitForSend(ModuleNotification(self.getServiceName(), 'update', datapathid = datapath_id, connection = connection, vhost = protocol.vhost, add = add, remove = remove, reason = 'bridgemodify' )): yield m
def re_add_interfaces(): with closing( self.apiroutine.executeAll([ self._get_interface_info( e.connection, e.connection.protocol, buuid, r['_uuid'], puuid) for puuid, r in ports_original ])) as g: for m in g: yield m add = list( itertools.chain( r[0] for r in self.apiroutine.retvalue)) for m in self.apiroutine.waitForSend( ModuleNotification( self.getServiceName(), 'update', datapathid=e.datapathid, connection=e.connection, vhost=e.vhost, add=add, remove=[], reason='bridgeup')): yield m
async def _get_existing_ports(self): r = await call_api(self.apiroutine, 'ovsdbmanager', 'getallconnections', {'vhost':None}) matchers = [] for c in r: self.monitor_routines.add(self.apiroutine.subroutine(self._get_ports(c, c.protocol))) matchers.append(OVSDBConnectionPortsSynchronized.createMatcher(c)) await self.apiroutine.wait_for_all(*matchers) self._synchronized = True await self.apiroutine.wait_for_send(ModuleNotification(self.getServiceName(), 'synchronized'))
async def _manage_existing(self): result = await call_api(self.apiroutine, "openflowserver", "getconnections", {}) vb = self.vhostbind for c in result: if vb is None or c.protocol.vhost in vb: self._add_connection(c) self._synchronized = True await self.apiroutine.wait_for_send( ModuleNotification(self.getServiceName(), 'synchronized'))
def _get_ports(self, connection, protocol, onup=False, update=True): ofdef = connection.openflowdef dpid = connection.openflow_datapathid vhost = connection.protocol.vhost add = [] try: if hasattr(ofdef, 'ofp_multipart_request'): # Openflow 1.3, use ofp_multipart_request to get ports for m in protocol.querymultipart( ofdef.ofp_multipart_request( type=ofdef.OFPMP_PORT_DESC), connection, self.apiroutine): yield m ports = self.managed_ports.setdefault((vhost, dpid), {}) for msg in self.apiroutine.openflow_reply: for p in msg.ports: add.append(p) ports[p.port_no] = p else: # Openflow 1.0, use features_request if onup: # Use the features_reply on connection setup reply = connection.openflow_featuresreply else: request = ofdef.ofp_msg() request.header.type = ofdef.OFPT_FEATURES_REQUEST for m in protocol.querywithreply(request): yield m reply = self.apiroutine.retvalue ports = self.managed_ports.setdefault((vhost, dpid), {}) for p in reply.ports: add.append(p) ports[p.port_no] = p if update: for m in self.apiroutine.waitForSend( OpenflowPortSynchronized(connection)): yield m self._logger.info( "Openflow port synchronized on connection %r", connection) for m in self.apiroutine.waitForSend( ModuleNotification( self.getServiceName(), 'update', datapathid=connection.openflow_datapathid, connection=connection, vhost=protocol.vhost, add=add, remove=[], reason='connected')): yield m except ConnectionResetException: pass except OpenflowProtocolException: pass
async def _get_existing_ports(self): r = await call_api(self.apiroutine, 'openflowmanager', 'getallconnections', {'vhost': None}) await self.apiroutine.execute_all([ self._get_ports(c, c.protocol, False, False) for c in r if c.openflow_auxiliaryid == 0 ]) self._synchronized = True self._logger.info("Openflow ports synchronized") await self.apiroutine.wait_for_send( ModuleNotification(self.getServiceName(), 'synchronized'))
def _manage_existing(self): for m in callAPI(self.apiroutine, "openflowserver", "getconnections", {}): yield m vb = self.vhostbind for c in self.apiroutine.retvalue: if vb is None or c.protocol.vhost in vb: self._add_connection(c) self._synchronized = True for m in self.apiroutine.waitForSend( ModuleNotification(self.getServiceName(), 'synchronized')): yield m
def _get_existing_ports(self): for m in callAPI(self.apiroutine, 'ovsdbmanager', 'getallconnections', {'vhost':None}): yield m matchers = [] for c in self.apiroutine.retvalue: self.monitor_routines.add(self.apiroutine.subroutine(self._get_ports(c, c.protocol))) matchers.append(OVSDBConnectionPortsSynchronized.createMatcher(c)) for m in self.apiroutine.waitForAll(*matchers): yield m self._synchronized = True for m in self.apiroutine.waitForSend(ModuleNotification(self.getServiceName(), 'synchronized')): yield m
async def re_add_interfaces(): result = await self.apiroutine.execute_all( [self._get_interface_info(e.connection, e.connection.protocol, buuid, r['_uuid'], puuid) for puuid, r in ports_original]) add = list(itertools.chain(r[0] for r in result)) await self.apiroutine.wait_for_send(ModuleNotification(self.getServiceName(), 'update', datapathid = e.datapathid, connection = e.connection, vhost = e.vhost, add = add, remove = [], reason = 'bridgeup' ))
def _get_existing_ports(self): for m in callAPI(self.apiroutine, 'openflowmanager', 'getallconnections', {'vhost': None}): yield m for m in self.apiroutine.executeAll([ self._get_ports(c, c.protocol, False, False) for c in self.apiroutine.retvalue if c.openflow_auxiliaryid == 0 ]): yield m self._synchronized = True for m in self.apiroutine.waitForSend( ModuleNotification(self.getServiceName(), 'synchronized')): yield m
def _manage_existing(self): for m in callAPI(self.apiroutine, "jsonrpcserver", "getconnections", {}): yield m vb = self.vhostbind conns = self.apiroutine.retvalue for c in conns: if vb is None or c.protocol.vhost in vb: if not hasattr(c, '_ovsdb_manager_get_bridges'): c._ovsdb_manager_get_bridges = self.apiroutine.subroutine(self._get_bridges(c, c.protocol)) matchers = [OVSDBConnectionSetup.createMatcher(None, c, c.connmark) for c in conns] for m in self.apiroutine.waitForAll(*matchers): yield m self._synchronized = True for m in self.apiroutine.waitForSend(ModuleNotification(self.getServiceName(), 'synchronized')): yield m
def _manage_ports(self): try: self.apiroutine.subroutine(self._get_existing_ports()) connsetup = OVSDBConnectionSetup.createMatcher() bridgedown = OVSDBBridgeSetup.createMatcher(OVSDBBridgeSetup.DOWN) while True: yield (connsetup, bridgedown) e = self.apiroutine.event if self.apiroutine.matcher is connsetup: self.apiroutine.subroutine( self._get_ports(e.connection, e.connection.protocol)) else: # Remove ports of the bridge ports = self.managed_ports.get((e.vhost, e.datapathid)) if ports is not None: ports = [p for _, p in ports] for p in ports: if p['id']: self._remove_interface_id( e.connection, e.connection.protocol, e.datapathid, p) del self.managed_ports[(e.vhost, e.datapathid)] self.scheduler.emergesend( ModuleNotification(self.getServiceName(), 'update', datapathid=e.datapathid, connection=e.connection, vhost=e.vhost, add=[], remove=ports, reason='bridgedown')) finally: for r in self.monitor_routines: r.close() self.scheduler.emergesend( ModuleNotification(self.getServiceName(), 'unsynchronized'))
async def _manage_existing(self): conns = await call_api(self.apiroutine, "jsonrpcserver", "getconnections", {}) vb = self.vhostbind for c in conns: if vb is None or c.protocol.vhost in vb: if not hasattr(c, '_ovsdb_manager_get_bridges'): c._ovsdb_manager_get_bridges = self.apiroutine.subroutine( self._get_bridges(c, c.protocol)) matchers = [ OVSDBConnectionSetup.createMatcher(None, c, c.connmark) for c in conns if vb is None or c.protocol.vhost in vb ] await self.apiroutine.wait_for_all(*matchers) self._synchronized = True await self.apiroutine.wait_for_send( ModuleNotification(self.getServiceName(), 'synchronized'))
def _manage_ports(self): try: self.apiroutine.subroutine(self._get_existing_ports()) conn_update = ModuleNotification.createMatcher('openflowmanager', 'update') port_status = OpenflowAsyncMessageEvent.createMatcher(of13.OFPT_PORT_STATUS, None, 0) while True: yield (conn_update, port_status) if self.apiroutine.matcher is port_status: e = self.apiroutine.event m = e.message c = e.connection if (c.protocol.vhost, c.openflow_datapathid) in self.managed_ports: if m.reason == c.openflowdef.OFPPR_ADD: # A new port is added self.managed_ports[(c.protocol.vhost, c.openflow_datapathid)][m.desc.port_no] = m.desc self.scheduler.emergesend(ModuleNotification(self.getServiceName(), 'update', datapathid = c.openflow_datapathid, connection = c, vhost = c.protocol.vhost, add = [m.desc], remove = [], reason = 'add')) elif m.reason == c.openflowdef.OFPPR_DELETE: try: del self.managed_ports[(c.protocol.vhost, c.openflow_datapathid)][m.desc.port_no] self.scheduler.emergesend(ModuleNotification(self.getServiceName(), 'update', datapathid = c.openflow_datapathid, connection = c, vhost = c.protocol.vhost, add = [], remove = [m.desc], reason = 'delete')) except KeyError: pass elif m.reason == c.openflowdef.OFPPR_MODIFY: try: self.scheduler.emergesend(ModuleNotification(self.getServiceName(), 'modified', datapathid = c.openflow_datapathid, connection = c, vhost = c.protocol.vhost, old = self.managed_ports[(c.protocol.vhost, c.openflow_datapathid)][m.desc.port_no], new = m.desc, reason = 'modified')) except KeyError: self.scheduler.emergesend(ModuleNotification(self.getServiceName(), 'update', datapathid = c.openflow_datapathid, connection = c, vhost = c.protocol.vhost, add = [m.desc], remove = [], reason = 'add')) self.managed_ports[(c.protocol.vhost, c.openflow_datapathid)][m.desc.port_no] = m.desc else: e = self.apiroutine.event for c in e.remove: if c.openflow_auxiliaryid == 0 and (c.protocol.vhost, c.openflow_datapathid) in self.managed_ports: self.scheduler.emergesend(ModuleNotification(self.getServiceName(), 'update', datapathid = c.openflow_datapathid, connection = c, vhost = c.protocol.vhost, add = [], remove = list(self.managed_ports[(c.protocol.vhost, c.openflow_datapathid)].values()), reason = 'disconnected')) del self.managed_ports[(c.protocol.vhost, c.openflow_datapathid)] for c in e.add: if c.openflow_auxiliaryid == 0: self.apiroutine.subroutine(self._get_ports(c, c.protocol, True, True)) finally: self.scheduler.emergesend(ModuleNotification(self.getServiceName(), 'unsynchronized'))
def _wait_for_sync(self): if not self._synchronized: yield (ModuleNotification.createMatcher(self.getServiceName(), 'synchronized'), )
def _wait_for_sync(self): if not self._synchronized: yield (ModuleNotification.createMatcher(self.getServiceName(), 'synchronized'),)
def _manage_conns(self): vb = self.vhostbind self.apiroutine.subroutine(self._manage_existing(), False) try: if vb is not None: conn_up = OpenflowConnectionStateEvent.createMatcher( state=OpenflowConnectionStateEvent.CONNECTION_SETUP, _ismatch=lambda x: x.createby.vhost in vb) conn_down = OpenflowConnectionStateEvent.createMatcher( state=OpenflowConnectionStateEvent.CONNECTION_DOWN, _ismatch=lambda x: x.createby.vhost in vb) else: conn_up = OpenflowConnectionStateEvent.createMatcher( state=OpenflowConnectionStateEvent.CONNECTION_SETUP) conn_down = OpenflowConnectionStateEvent.createMatcher( state=OpenflowConnectionStateEvent.CONNECTION_DOWN) while True: yield (conn_up, conn_down) if self.apiroutine.matcher is conn_up: e = self.apiroutine.event remove = self._add_connection(e.connection) self.scheduler.emergesend( ModuleNotification(self.getServiceName(), 'update', add=[e.connection], remove=remove)) else: e = self.apiroutine.event conns = self.managed_conns.get( (e.createby.vhost, e.datapathid)) remove = [] if conns is not None: try: conns.remove(e.connection) except ValueError: pass else: remove.append(e.connection) if not conns: del self.managed_conns[(e.createby.vhost, e.datapathid)] # Also delete from endpoint_conns ep = _get_endpoint(e.connection) econns = self.endpoint_conns.get( (e.createby.vhost, ep)) if econns is not None: try: econns.remove(e.connection) except ValueError: pass if not econns: del self.endpoint_conns[(e.createby.vhost, ep)] if remove: self.scheduler.emergesend( ModuleNotification(self.getServiceName(), 'update', add=[], remove=remove)) finally: self.scheduler.emergesend( ModuleNotification(self.getServiceName(), 'unsynchronized'))
def resync(self, datapathid, vhost=''): ''' Resync with current ports ''' # Sometimes when the OpenFlow connection is very busy, PORT_STATUS message may be dropped. # We must deal with this and recover from it # Save current manged_ports if (vhost, datapathid) not in self.managed_ports: self.apiroutine.retvalue = None return else: last_ports = set(self.managed_ports[(vhost, datapathid)].keys()) add = set() remove = set() ports = {} for _ in range(0, 10): for m in callAPI(self.apiroutine, 'openflowmanager', 'getconnection', { 'datapathid': datapathid, 'vhost': vhost }): yield m c = self.apiroutine.retvalue if c is None: # Disconnected, will automatically resync when reconnected self.apiroutine.retvalue = None return ofdef = c.openflowdef protocol = c.protocol try: if hasattr(ofdef, 'ofp_multipart_request'): # Openflow 1.3, use ofp_multipart_request to get ports for m in protocol.querymultipart( ofdef.ofp_multipart_request( type=ofdef.OFPMP_PORT_DESC), c, self.apiroutine): yield m for msg in self.apiroutine.openflow_reply: for p in msg.ports: ports[p.port_no] = p else: # Openflow 1.0, use features_request request = ofdef.ofp_msg() request.header.type = ofdef.OFPT_FEATURES_REQUEST for m in protocol.querywithreply(request): yield m reply = self.apiroutine.retvalue for p in reply.ports: ports[p.port_no] = p except ConnectionResetException: break except OpenflowProtocolException: break else: if (vhost, datapathid) not in self.managed_ports: self.apiroutine.retvalue = None return current_ports = set(self.managed_ports[(vhost, datapathid)]) # If a port is already removed remove.intersection_update(current_ports) # If a port is already added add.difference_update(current_ports) # If a port is not acquired, we do not add it acquired_keys = set(ports.keys()) add.difference_update(acquired_keys) # Add and remove previous added/removed ports current_ports.difference_update(remove) current_ports.update(add) # If there are changed ports, the changed ports may or may not appear in the acquired port list # We only deal with following situations: # 1. If both lack ports, we add them # 2. If both have additional ports, we remote them to_add = acquired_keys.difference( current_ports.union(last_ports)) to_remove = current_ports.intersection(last_ports).difference( acquired_keys) if not to_add and not to_remove and current_ports == last_ports: break else: add.update(to_add) remove.update(to_remove) current_ports.update(to_add) current_ports.difference_update(to_remove) last_ports = current_ports # Actual add and remove mports = self.managed_ports[(vhost, datapathid)] add_ports = [] remove_ports = [] for k in add: if k not in mports: add_ports.append(ports[k]) mports[k] = ports[k] for k in remove: try: oldport = mports.pop(k) except KeyError: pass else: remove_ports.append(oldport) for m in self.apiroutine.waitForSend( ModuleNotification(self.getServiceName(), 'update', datapathid=datapathid, connection=c, vhost=vhost, add=add_ports, remove=remove_ports, reason='resync')): yield m self.apiroutine.retvalue = None
def _manage_ports(self): try: self.apiroutine.subroutine(self._get_existing_ports()) conn_update = ModuleNotification.createMatcher( 'openflowmanager', 'update') port_status = OpenflowAsyncMessageEvent.createMatcher( of13.OFPT_PORT_STATUS, None, 0) while True: yield (conn_update, port_status) if self.apiroutine.matcher is port_status: e = self.apiroutine.event m = e.message c = e.connection if (c.protocol.vhost, c.openflow_datapathid) in self.managed_ports: if m.reason == c.openflowdef.OFPPR_ADD: # A new port is added self.managed_ports[(c.protocol.vhost, c.openflow_datapathid )][m.desc.port_no] = m.desc self.scheduler.emergesend( ModuleNotification( self.getServiceName(), 'update', datapathid=c.openflow_datapathid, connection=c, vhost=c.protocol.vhost, add=[m.desc], remove=[], reason='add')) elif m.reason == c.openflowdef.OFPPR_DELETE: try: del self.managed_ports[( c.protocol.vhost, c.openflow_datapathid)][m.desc.port_no] self.scheduler.emergesend( ModuleNotification( self.getServiceName(), 'update', datapathid=c.openflow_datapathid, connection=c, vhost=c.protocol.vhost, add=[], remove=[m.desc], reason='delete')) except KeyError: pass elif m.reason == c.openflowdef.OFPPR_MODIFY: try: self.scheduler.emergesend( ModuleNotification( self.getServiceName(), 'modified', datapathid=c.openflow_datapathid, connection=c, vhost=c.protocol.vhost, old=self.managed_ports[( c.protocol.vhost, c.openflow_datapathid )][m.desc.port_no], new=m.desc, reason='modified')) except KeyError: self.scheduler.emergesend( ModuleNotification( self.getServiceName(), 'update', datapathid=c.openflow_datapathid, connection=c, vhost=c.protocol.vhost, add=[m.desc], remove=[], reason='add')) self.managed_ports[(c.protocol.vhost, c.openflow_datapathid )][m.desc.port_no] = m.desc else: e = self.apiroutine.event for c in e.remove: if c.openflow_auxiliaryid == 0 and ( c.protocol.vhost, c.openflow_datapathid) in self.managed_ports: self.scheduler.emergesend( ModuleNotification( self.getServiceName(), 'update', datapathid=c.openflow_datapathid, connection=c, vhost=c.protocol.vhost, add=[], remove=list(self.managed_ports[( c.protocol.vhost, c.openflow_datapathid)].values()), reason='disconnected')) del self.managed_ports[(c.protocol.vhost, c.openflow_datapathid)] for c in e.add: if c.openflow_auxiliaryid == 0: self.apiroutine.subroutine( self._get_ports(c, c.protocol, True, True)) finally: self.scheduler.emergesend( ModuleNotification(self.getServiceName(), 'unsynchronized'))
def process_bridge(buuid, uo): try: nv = uo['new'] if 'datapath_id' in nv: if ovsdb.getoptional(nv['datapath_id']) is None: # This bridge is not initialized. Wait for the bridge to be initialized. for m in callAPI( self.apiroutine, 'ovsdbmanager', 'waitbridge', { 'connection': connection, 'name': nv['name'], 'timeout': 5 }): yield m datapath_id = self.apiroutine.retvalue else: datapath_id = int(nv['datapath_id'], 16) self.bridge_datapathid[buuid] = datapath_id elif buuid in self.bridge_datapathid: datapath_id = self.bridge_datapathid[buuid] else: # This should not happen, but just in case... for m in callAPI(self.apiroutine, 'ovsdbmanager', 'waitbridge', { 'connection': connection, 'name': nv['name'], 'timeout': 5 }): yield m datapath_id = self.apiroutine.retvalue self.bridge_datapathid[buuid] = datapath_id if 'ports' in nv: nset = set((p for _, p in ovsdb.getlist(nv['ports']))) else: nset = set() if 'old' in uo: ov = uo['old'] if 'ports' in ov: oset = set((p for _, p in ovsdb.getlist(ov['ports']))) else: # new ports are not really added; it is only sent because datapath_id is modified nset = set() oset = set() if 'datapath_id' in ov and ovsdb.getoptional( ov['datapath_id']) is not None: old_datapathid = int(ov['datapath_id'], 16) else: old_datapathid = datapath_id else: oset = set() old_datapathid = datapath_id # For every deleted port, remove the interfaces with this port _uuid remove = [] add_routine = [] for puuid in oset - nset: remove += self._remove_all_interface( connection, protocol, old_datapathid, puuid, buuid) # For every port not changed, check if the interfaces are modified; for puuid in oset.intersection(nset): if puuid in port_update: # The port is modified, there should be an 'old' set and 'new' set pu = port_update[puuid] if 'old' in pu: poset = set((p for _, p in ovsdb.getlist( pu['old']['interfaces']))) else: poset = set() if 'new' in pu: pnset = set((p for _, p in ovsdb.getlist( pu['new']['interfaces']))) else: pnset = set() # Remove old interfaces remove += [ r for r in (self._remove_interface( connection, protocol, datapath_id, iuuid, puuid) for iuuid in (poset - pnset)) if r is not None ] # Prepare to add new interfaces add_routine += [ self._get_interface_info(connection, protocol, buuid, iuuid, puuid) for iuuid in (pnset - poset) ] # For every port added, add the interfaces def add_port_interfaces(puuid): # If the uuid does not appear in update info, we have no choice but to query interfaces with select # we cannot use data from other bridges; the port may be moved from a bridge which is not tracked try: method, params = ovsdb.transact( 'Open_vSwitch', ovsdb.select('Port', [["_uuid", "==", ovsdb.uuid(puuid)]], ["interfaces"])) for m in protocol.querywithreply( method, params, connection, self.apiroutine): yield m r = self.apiroutine.jsonrpc_result[0] if 'error' in r: raise JsonRPCErrorResultException( 'Error when query interfaces from port ' + repr(puuid) + ': ' + r['error']) if r['rows']: interfaces = ovsdb.getlist( r['rows'][0]['interfaces']) with closing( self.apiroutine.executeAll([ self._get_interface_info( connection, protocol, buuid, iuuid, puuid) for _, iuuid in interfaces ])) as g: for m in g: yield m self.apiroutine.retvalue = list( itertools.chain( r[0] for r in self.apiroutine.retvalue)) else: self.apiroutine.retvalue = [] except JsonRPCProtocolException: self.apiroutine.retvalue = [] except ConnectionResetException: self.apiroutine.retvalue = [] for puuid in nset - oset: self.ports_uuids[puuid] = buuid if puuid in port_update and 'new' in port_update[puuid] \ and 'old' not in port_update[puuid]: # Add all the interfaces in 'new' interfaces = ovsdb.getlist( port_update[puuid]['new']['interfaces']) add_routine += [ self._get_interface_info(connection, protocol, buuid, iuuid, puuid) for _, iuuid in interfaces ] else: add_routine.append(add_port_interfaces(puuid)) # Execute the add_routine try: with closing(self.apiroutine.executeAll(add_routine)) as g: for m in g: yield m except: add = [] raise else: add = list( itertools.chain(r[0] for r in self.apiroutine.retvalue)) finally: if update: self.scheduler.emergesend( ModuleNotification(self.getServiceName(), 'update', datapathid=datapath_id, connection=connection, vhost=protocol.vhost, add=add, remove=remove, reason='bridgemodify' if 'old' in uo else 'bridgeup')) except JsonRPCProtocolException: pass except ConnectionResetException: pass except OVSDBBridgeNotAppearException: pass