Exemplo n.º 1
0
 def _update_bridge(self, connection, protocol, bridge_uuid, vhost):
     try:
         method, params = ovsdb.transact('Open_vSwitch',
                                         ovsdb.wait('Bridge', [["_uuid", "==", ovsdb.uuid(bridge_uuid)]],
                                                     ["datapath_id"], [{"datapath_id": ovsdb.oset()}], False, 5000),
                                         ovsdb.select('Bridge', [["_uuid", "==", ovsdb.uuid(bridge_uuid)]],
                                                                      ["datapath_id","name"]))
         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 while acquiring datapath-id: ' + repr(r['error']))
         r = self.apiroutine.jsonrpc_result[1]
         if 'error' in r:
             raise JsonRPCErrorResultException('Error while acquiring datapath-id: ' + repr(r['error']))
         if r['rows']:
             r0 = r['rows'][0]
             name = r0['name']
             dpid = int(r0['datapath_id'], 16)
             if self.bridgenames is None or name in self.bridgenames:
                 self.managed_bridges[connection].append((vhost, dpid, name, bridge_uuid))
                 self.managed_conns[(vhost, dpid)] = connection
                 for m in self.apiroutine.waitForSend(OVSDBBridgeSetup(OVSDBBridgeSetup.UP,
                                                            dpid,
                                                            connection.ovsdb_systemid,
                                                            name,
                                                            connection,
                                                            connection.connmark,
                                                            vhost,
                                                            bridge_uuid)):
                     yield m
     except JsonRPCProtocolException:
         pass
Exemplo n.º 2
0
 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 = []
Exemplo n.º 3
0
 def _get_ports(self, connection, protocol):
     try:
         try:
             method, params = ovsdb.monitor(
                 'Open_vSwitch', 'ovsdb_port_manager_interfaces_monitor', {
                     'Bridge': [ovsdb.monitor_request(["name", "ports"])],
                     'Port': [ovsdb.monitor_request(["interfaces"])]
                 })
             for m in protocol.querywithreply(method, params, connection,
                                              self.apiroutine):
                 yield m
             if 'error' in self.apiroutine.jsonrpc_result:
                 # The monitor is already set, cancel it first
                 method2, params2 = ovsdb.monitor_cancel(
                     'ovsdb_port_manager_interfaces_monitor')
                 for m in protocol.querywithreply(method2, params2,
                                                  connection,
                                                  self.apiroutine, False):
                     yield m
                 for m in protocol.querywithreply(method, params,
                                                  connection,
                                                  self.apiroutine):
                     yield m
                 if 'error' in self.apiroutine.jsonrpc_result:
                     raise JsonRPCErrorResultException(
                         'OVSDB request failed: ' +
                         repr(self.apiroutine.jsonrpc_result))
             r = self.apiroutine.jsonrpc_result
         except:
             for m in self.apiroutine.waitForSend(
                     OVSDBConnectionPortsSynchronized(connection)):
                 yield m
             raise
         # This is the initial state, it should contains all the ids of ports and interfaces
         self.apiroutine.subroutine(
             self._update_interfaces(connection, protocol, r, False))
         update_matcher = JsonRPCNotificationEvent.createMatcher(
             'update',
             connection,
             connection.connmark,
             _ismatch=lambda x: x.params[
                 0] == 'ovsdb_port_manager_interfaces_monitor')
         conn_state = protocol.statematcher(connection)
         while True:
             yield (update_matcher, conn_state)
             if self.apiroutine.matcher is conn_state:
                 break
             else:
                 self.apiroutine.subroutine(
                     self._update_interfaces(
                         connection, protocol,
                         self.apiroutine.event.params[1], True))
     except JsonRPCProtocolException:
         pass
Exemplo n.º 4
0
 def _get_interface_info(self, connection, protocol, buuid, interface_uuid,
                         port_uuid):
     try:
         method, params = ovsdb.transact(
             'Open_vSwitch',
             ovsdb.wait(
                 'Interface',
                 [["_uuid", "==", ovsdb.uuid(interface_uuid)]], ["ofport"],
                 [{
                     "ofport": ovsdb.oset()
                 }], False, 5000),
             ovsdb.wait(
                 'Interface',
                 [["_uuid", "==", ovsdb.uuid(interface_uuid)]], ["ofport"],
                 [{
                     "ofport": -1
                 }], False, 0),
             ovsdb.wait(
                 'Interface',
                 [["_uuid", "==", ovsdb.uuid(interface_uuid)]], ["ifindex"],
                 [{
                     "ifindex": ovsdb.oset()
                 }], False, 5000),
             ovsdb.select(
                 'Interface',
                 [["_uuid", "==", ovsdb.uuid(interface_uuid)]], [
                     "_uuid", "name", "ifindex", "ofport", "type",
                     "external_ids"
                 ]))
         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 while acquiring interface: ' + repr(r['error']))
         r = self.apiroutine.jsonrpc_result[1]
         if 'error' in r:
             raise JsonRPCErrorResultException(
                 'Error while acquiring interface: ' + repr(r['error']))
         r = self.apiroutine.jsonrpc_result[2]
         if 'error' in r:
             # Ignore this port because it is in an error state
             self.apiroutine.retvalue = []
             return
         r = self.apiroutine.jsonrpc_result[3]
         if 'error' in r:
             raise JsonRPCErrorResultException(
                 'Error while acquiring interface: ' + repr(r['error']))
         if not r['rows']:
             self.apiroutine.retvalue = []
             return
         r0 = r['rows'][0]
         if r0['ofport'] < 0:
             # Ignore this port because it is in an error state
             self.apiroutine.retvalue = []
             return
         r0['_uuid'] = r0['_uuid'][1]
         r0['ifindex'] = ovsdb.getoptional(r0['ifindex'])
         r0['external_ids'] = ovsdb.getdict(r0['external_ids'])
         if buuid not in self.bridge_datapathid:
             self.apiroutine.retvalue = []
             return
         else:
             datapath_id = self.bridge_datapathid[buuid]
         if 'iface-id' in r0['external_ids']:
             eid = r0['external_ids']['iface-id']
             r0['id'] = eid
             id_ports = self.managed_ids.setdefault((protocol.vhost, eid),
                                                    [])
             id_ports.append((datapath_id, r0))
         else:
             r0['id'] = None
         self.managed_ports.setdefault((protocol.vhost, datapath_id),
                                       []).append((port_uuid, r0))
         notify = False
         if (protocol.vhost, datapath_id,
                 r0['ofport']) in self.wait_portnos:
             notify = True
             del self.wait_portnos[(protocol.vhost, datapath_id,
                                    r0['ofport'])]
         if (protocol.vhost, datapath_id, r0['name']) in self.wait_names:
             notify = True
             del self.wait_names[(protocol.vhost, datapath_id, r0['name'])]
         if (protocol.vhost, r0['id']) in self.wait_ids:
             notify = True
             del self.wait_ids[(protocol.vhost, r0['id'])]
         if notify:
             for m in self.apiroutine.waitForSend(
                     OVSDBPortUpNotification(connection,
                                             r0['name'],
                                             r0['ofport'],
                                             r0['id'],
                                             protocol.vhost,
                                             datapath_id,
                                             port=r0)):
                 yield m
         self.apiroutine.retvalue = [r0]
     except JsonRPCProtocolException:
         self.apiroutine.retvalue = []
Exemplo n.º 5
0
 def _get_bridges(self, connection, protocol):
     try:
         try:
             vhost = protocol.vhost
             if not hasattr(connection, 'ovsdb_systemid'):
                 method, params = ovsdb.transact('Open_vSwitch', ovsdb.select('Open_vSwitch', [], ['external_ids']))
                 for m in protocol.querywithreply(method, params, connection, self.apiroutine):
                     yield m
                 result = self.apiroutine.jsonrpc_result[0]
                 system_id = ovsdb.omap_getvalue(result['rows'][0]['external_ids'], 'system-id')
                 connection.ovsdb_systemid = system_id
             else:
                 system_id = connection.ovsdb_systemid
             if (vhost, system_id) in self.managed_systemids:
                 oc = self.managed_systemids[(vhost, system_id)]
                 ep = _get_endpoint(oc)
                 econns = self.endpoint_conns.get((vhost, ep))
                 if econns:
                     try:
                         econns.remove(oc)
                     except ValueError:
                         pass
                 del self.managed_systemids[(vhost, system_id)]
             self.managed_systemids[(vhost, system_id)] = connection
             self.managed_bridges[connection] = []
             ep = _get_endpoint(connection)
             self.endpoint_conns.setdefault((vhost, ep), []).append(connection)
             method, params = ovsdb.monitor('Open_vSwitch', 'ovsdb_manager_bridges_monitor', {'Open_vSwitch':ovsdb.monitor_request(['bridges'])})
             for m in protocol.querywithreply(method, params, connection, self.apiroutine):
                 yield m
             if 'error' in self.apiroutine.jsonrpc_result:
                 # The monitor is already set, cancel it first
                 method, params = ovsdb.monitor_cancel('ovsdb_manager_bridges_monitor')
                 for m in protocol.querywithreply(method, params, connection, self.apiroutine, False):
                     yield m
                 method, params = ovsdb.monitor('Open_vSwitch', 'ovsdb_manager_bridges_monitor', {'Open_vSwitch':ovsdb.monitor_request(['bridges'], True, False, False, True)})
                 for m in protocol.querywithreply(method, params, connection, self.apiroutine):
                     yield m
                 if 'error' in self.apiroutine.jsonrpc_result:
                     raise JsonRPCErrorResultException('OVSDB request failed: ' + repr(self.apiroutine.jsonrpc_result))
         except Exception:
             for m in self.apiroutine.waitForSend(OVSDBConnectionSetup(system_id, connection, connection.connmark, vhost)):
                 yield m
             raise
         else:
             # Process initial bridges
             init_subprocesses = [self._update_bridge(connection, protocol, buuid, vhost)
                                 for v in self.apiroutine.jsonrpc_result['Open_vSwitch'].values()
                                 for _, buuid in ovsdb.getlist(v['new']['bridges'])]
             def init_process():
                 try:
                     for m in self.apiroutine.executeAll(init_subprocesses, retnames = ()):
                         yield m
                 except Exception:
                     for m in self.apiroutine.waitForSend(OVSDBConnectionSetup(system_id, connection, connection.connmark, vhost)):
                         yield m
                     raise
                 else:
                     for m in self.apiroutine.waitForSend(OVSDBConnectionSetup(system_id, connection, connection.connmark, vhost)):
                         yield m
             self.apiroutine.subroutine(init_process())
         # Wait for notify
         notification = JsonRPCNotificationEvent.createMatcher('update', connection, connection.connmark, _ismatch = lambda x: x.params[0] == 'ovsdb_manager_bridges_monitor')
         conn_down = protocol.statematcher(connection)
         while True:
             yield (conn_down, notification)
             if self.apiroutine.matcher is conn_down:
                 break
             else:
                 for v in self.apiroutine.event.params[1]['Open_vSwitch'].values():
                     if 'old' not in v:
                         old = set()
                     else:
                         old = set((oid for _, oid in ovsdb.getlist(v['old']['bridges'])))
                     if 'new' not in v:
                         new = set()
                     else:
                         new = set((oid for _, oid in ovsdb.getlist(v['new']['bridges'])))
                     for buuid in (new - old):
                         self.apiroutine.subroutine(self._update_bridge(connection, protocol, buuid, vhost))
                     for buuid in (old - new):
                         bridges = self.managed_bridges[connection]
                         for i in range(0, len(bridges)):
                             if buuid == bridges[i][3]:
                                 self.scheduler.emergesend(OVSDBBridgeSetup(OVSDBBridgeSetup.DOWN,
                                                                            bridges[i][1],
                                                                            system_id,
                                                                            bridges[i][2],
                                                                            connection,
                                                                            connection.connmark,
                                                                            vhost,
                                                                            bridges[i][3]))
                                 del self.managed_conns[(vhost, bridges[i][1])]
                                 del bridges[i]
                                 break
     except JsonRPCProtocolException:
         pass
     finally:
         del connection._ovsdb_manager_get_bridges