Created
November 12, 2020 01:26
-
-
Save otherwiseguy/3f0443b07880cdbb24e15610dc1dc04b to your computer and use it in GitHub Desktop.
Handle schema changes
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import logging | |
import json | |
import time | |
from ovs.db import custom_index | |
from ovs.db import idl | |
from ovsdbapp.backend.ovs_idl import connection | |
from ovsdbapp.backend.ovs_idl import event | |
from ovsdbapp.backend.ovs_idl import vlog | |
from ovsdbapp.schema.ovn_southbound import impl_idl | |
logging.basicConfig() | |
vlog.use_python_logger() | |
class AgentEvent(event.RowEvent): | |
GLOBAL = True | |
event_name = 'AgentEvent' | |
def __init__(self): | |
super().__init__((self.ROW_CREATE, self.ROW_UPDATE), 'Chassis_Private', | |
None) | |
def run(self, event, row, updates=None): | |
print(event, row) | |
class MyIdl(connection.OvsdbIdl): | |
def __init__(self, *args, **kwargs): | |
self.event_handler = event.RowEventHandler() | |
super().__init__(*args, **kwargs) | |
def notify(self, event, row, updates=None): | |
# __send_monitor_request() is called after notify() in python-ovs, but | |
# RowEventHandler pushes processing the notification to a different | |
# thread, so I think we have to process these schema changes here or | |
# we might miss monitoring the new table. We could create a list of | |
# "in the connection thread" events to match... | |
if (event == 'create' and row._table.name == 'Database' and | |
row.name == 'OVN_Southbound'): | |
sh = idl.SchemaHelper(None, json.loads(row.schema[0])) | |
# We need to set up the schema helper exactly how we did in the | |
# from_server() call. This should be an approximation, but breaking | |
# those out into a setup_schema() method would be ideal I think. | |
for table in self.tables: | |
if table in sh.schema_json['tables']: | |
sh.register_table(table) | |
if 'Chassis_Private' in sh.schema_json['tables']: | |
sh.register_table('Chassis_Private') | |
schema = sh.get_idl_schema() | |
self._db = schema | |
self.tables = schema.tables | |
for table in schema.tables.values(): | |
for column in table.columns.values(): | |
if not hasattr(column, 'alert'): | |
column.alert = True | |
table.need_table = False | |
table.rows = custom_index.IndexedRows(table) | |
table.idl = self | |
table.condition = [True] | |
table.cond_changed = False | |
# RowEventHandler events lose easy access to the idl by losing self | |
# I don't know whether this is good or bad. :p | |
else: | |
self.event_handler.notify(event, row, updates) | |
def row_repr(self): | |
return "{table}({data})".format( | |
table=self._table.name, | |
data=", ".join("{col}={val}".format(col=c, | |
val=getattr(self, c, '<unset>')) | |
for c in sorted(self._table.columns))) | |
idl.Row.__repr__ = idl.Row.__str__ = row_repr | |
conn = "tcp:127.0.0.1:6642" | |
i = MyIdl.from_server(conn, 'OVN_Southbound') | |
i.event_handler.watch_event(AgentEvent()) | |
c = connection.Connection(idl=i, timeout=3) | |
api = impl_idl.OvnSbApiIdlImpl(c) | |
while True: | |
print('Chassis_Private' in api.tables) | |
time.sleep(2) | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
It would be nice if
Idl.__init__()
broke out the the table setup into a helper function that we could just call instead of re-implementing.