On Thu, Nov 21, 2019 at 7:22 PM Mark Michelson <[email protected]> wrote: > > I pushed this to master.
Thanks! > > On 11/15/19 8:39 PM, Mark Michelson wrote: > > Acked-by: Mark Michelson <[email protected]> > > > > On 11/15/19 2:24 PM, Dumitru Ceara wrote: > >> Two new command line arguments are added to ovn-detrace: > >> - "--ovs": which will instruct ovn-detrace to connect to the local OVS > >> db.sock and try to decode input/output ofport values and pretty print > >> the corresponding OVS interfaces. > >> - "--ovsdb": which allows the user to point ovn-detrace to other OVS DB > >> remotes (useful when ovn-trace is not run on the hypervisor where > >> ofproto-trace was run. > >> > >> Signed-off-by: Dumitru Ceara <[email protected]> > >> --- > >> utilities/ovn-detrace.1.in | 11 +++++ > >> utilities/ovn-detrace.in | 105 > >> +++++++++++++++++++++++++++++++++------------ > >> 2 files changed, 88 insertions(+), 28 deletions(-) > >> > >> diff --git a/utilities/ovn-detrace.1.in b/utilities/ovn-detrace.1.in > >> index 2f662d4..b899b63 100644 > >> --- a/utilities/ovn-detrace.1.in > >> +++ b/utilities/ovn-detrace.1.in > >> @@ -33,6 +33,17 @@ Otherwise, the default is > >> \fBunix:@RUNDIR@/ovnnb_db.sock\fR, but this > >> default is unlikely to be useful outside of single-machine OVN test > >> environments. > >> . > >> +.IP "\fB\-\-ovs=\fR" > >> +Also decode flow information (like OVS ofport) from the flows by > >> connecting > >> +to the OVS DB. > >> +. > >> +.IP "\fB\-\-ovsdb=\fIserver\fR" > >> +The OVS DB remote to contact if \fB\-\-ovs\f is present. If the > >> +\fBOVS_RUNDIR\fR environment variable is set, its value is used as the > >> +default. Otherwise, the default is \fBunix:@RUNDIR@/db.sock\fR, but this > >> +default is unlikely to be useful outside of single-machine OVN test > >> +environments. > >> +. > >> .SH "SEE ALSO" > >> . > >> .BR ovs\-appctl (8), ovn\-sbctl (8), ovn-\-nbctl (8), ovn\-trace (8) > >> diff --git a/utilities/ovn-detrace.in b/utilities/ovn-detrace.in > >> index c645658..52f6f4f 100755 > >> --- a/utilities/ovn-detrace.in > >> +++ b/utilities/ovn-detrace.in > >> @@ -28,6 +28,7 @@ try: > >> from ovs import jsonrpc > >> from ovs.poller import Poller > >> from ovs.stream import Stream > >> + from ovs import dirs > >> except Exception: > >> print("ERROR: Please install the correct Open vSwitch python > >> support") > >> print(" libraries (@VERSION@).") > >> @@ -49,7 +50,8 @@ The following options are also available: > >> -h, --help display this help message > >> -V, --version display version information > >> --ovnsb=DATABASE use DATABASE as southbound DB > >> - --ovnnb=DATABASE use DATABASE as northbound DB\ > >> + --ovnnb=DATABASE use DATABASE as northbound DB > >> + --ovsdb=DATABASE use DATABASE as OVS DB\ > >> """ % {'argv0': argv0}) > >> sys.exit(0) > >> @@ -102,15 +104,15 @@ class OVSDB(object): > >> def get_table(self, table_name): > >> return self._idl_conn.tables[table_name] > >> - def _find_row(self, table_name, find_fn): > >> + def _find_rows(self, table_name, find_fn): > >> return filter(find_fn, > >> self.get_table(table_name).rows.values()) > >> def _find_rows_by_name(self, table_name, value): > >> - return self._find_row(table_name, lambda row: row.name == value) > >> + return self._find_rows(table_name, lambda row: row.name == > >> value) > >> def find_rows_by_partial_uuid(self, table_name, value): > >> - return self._find_row(table_name, > >> - lambda row: > >> str(row.uuid).startswith(value)) > >> + return self._find_rows(table_name, > >> + lambda row: > >> str(row.uuid).startswith(value)) > >> class CookieHandler(object): > >> def __init__(self, db, table): > >> @@ -118,9 +120,7 @@ class CookieHandler(object): > >> self._table = table > >> def get_records(self, cookie): > >> - # Adjust cookie to include leading zeroes if needed. > >> - cookie = cookie.zfill(8) > >> - return self._db.find_rows_by_partial_uuid(self._table, cookie) > >> + return [] > >> def print_record(self, record): > >> pass > >> @@ -128,7 +128,16 @@ class CookieHandler(object): > >> def print_hint(self, record, db): > >> pass > >> -class LogicalFlowHandler(CookieHandler): > >> +class CookieHandlerByUUUID(CookieHandler): > >> + def __init__(self, db, table): > >> + super(CookieHandlerByUUUID, self).__init__(db, table) > >> + > >> + def get_records(self, cookie): > >> + # Adjust cookie to include leading zeroes if needed. > >> + cookie = cookie.zfill(8) > >> + return self._db.find_rows_by_partial_uuid(self._table, cookie) > >> + > >> +class LogicalFlowHandler(CookieHandlerByUUUID): > >> def __init__(self, ovnsb_db): > >> super(LogicalFlowHandler, self).__init__(ovnsb_db, > >> 'Logical_Flow') > >> @@ -163,7 +172,7 @@ class LogicalFlowHandler(CookieHandler): > >> output += ' (log)' > >> print_h(output) > >> -class PortBindingHandler(CookieHandler): > >> +class PortBindingHandler(CookieHandlerByUUUID): > >> def __init__(self, ovnsb_db): > >> super(PortBindingHandler, self).__init__(ovnsb_db, > >> 'Port_Binding') > >> @@ -173,7 +182,7 @@ class PortBindingHandler(CookieHandler): > >> (pb.logical_port, pb.tunnel_key, > >> chassis_str(pb.chassis))) > >> -class MacBindingHandler(CookieHandler): > >> +class MacBindingHandler(CookieHandlerByUUUID): > >> def __init__(self, ovnsb_db): > >> super(MacBindingHandler, self).__init__(ovnsb_db, > >> 'MAC_Binding') > >> @@ -182,7 +191,7 @@ class MacBindingHandler(CookieHandler): > >> print_p('MAC Binding: ip "%s", logical_port "%s", mac "%s"' % > >> (mb.ip, mb.logical_port, mb.mac)) > >> -class MulticastGroupHandler(CookieHandler): > >> +class MulticastGroupHandler(CookieHandlerByUUUID): > >> def __init__(self, ovnsb_db): > >> super(MulticastGroupHandler, self).__init__(ovnsb_db, > >> 'Multicast_Group') > >> @@ -194,31 +203,47 @@ class MulticastGroupHandler(CookieHandler): > >> print_p('Multicast Group: name "%s", tunnel_key %ld ports: > >> (%s)' % > >> (mc.name, mc.tunnel_key, mc_ports)) > >> -class ChassisHandler(CookieHandler): > >> +class ChassisHandler(CookieHandlerByUUUID): > >> def __init__(self, ovnsb_db): > >> super(ChassisHandler, self).__init__(ovnsb_db, 'Chassis') > >> def print_record(self, chassis): > >> print_p('Chassis: %s' % (chassis_str([chassis]))) > >> -def print_sb_record_from_cookie(ovnnb_db, ovnsb_db, cookie_handlers, > >> cookie): > >> +class OvsInterfaceHandler(CookieHandler): > >> + def __init__(self, ovs_db): > >> + super(OvsInterfaceHandler, self).__init__(ovs_db, 'Interface') > >> + > >> + def get_records(self, ofport): > >> + return self._db._find_rows(self._table, > >> + lambda intf: len(intf.ofport) > 0 and > >> + str(intf.ofport[0]) == ofport) > >> + > >> + def print_record(self, intf): > >> + print_p('OVS Interface: %s (%s)' % > >> + (intf.name, intf.external_ids.get('iface-id'))) > >> + > >> +def print_record_from_cookie(ovnnb_db, cookie_handlers, cookie): > >> for handler in cookie_handlers: > >> - for i, sb_record in enumerate(handler.get_records(cookie)): > >> + for i, record in enumerate(handler.get_records(cookie)): > >> if i > 0: > >> handler.print('[Duplicate uuid cookie]') > >> - handler.print_record(sb_record) > >> - handler.print_hint(sb_record, ovnnb_db) > >> + handler.print_record(record) > >> + handler.print_hint(record, ovnnb_db) > >> def main(): > >> try: > >> options, args = getopt.gnu_getopt(sys.argv[1:], 'hV', > >> - ['help', 'version', > >> 'ovnsb=', 'ovnnb=']) > >> + ['help', 'version', 'ovs', > >> + 'ovnsb=', 'ovnnb=', > >> 'ovsdb=']) > >> except getopt.GetoptError, geo: > >> sys.stderr.write("%s: %s\n" % (argv0, geo.msg)) > >> sys.exit(1) > >> ovnsb_db = None > >> ovnnb_db = None > >> + ovs_db = None > >> + ovs = False > >> for key, value in options: > >> if key in ['-h', '--help']: > >> @@ -229,6 +254,10 @@ def main(): > >> ovnsb_db = value > >> elif key in ['--ovnnb']: > >> ovnnb_db = value > >> + elif key in ['--ovsdb']: > >> + ovs_db = value > >> + elif key in ['--ovs']: > >> + ovs = True > >> else: > >> sys.exit(0) > >> @@ -238,6 +267,8 @@ def main(): > >> sys.exit(1) > >> ovn_rundir = os.getenv('OVN_RUNDIR', '@OVN_RUNDIR@') > >> + ovs_rundir = os.getenv('OVS_RUNDIR', dirs.RUNDIR) > >> + > >> if not ovnsb_db: > >> ovnsb_db = os.getenv('OVN_SB_DB') > >> if not ovnsb_db: > >> @@ -247,6 +278,8 @@ def main(): > >> ovnnb_db = os.getenv('OVN_NB_DB') > >> if not ovnnb_db: > >> ovnnb_db = 'unix:%s/ovnnb_db.sock' % ovn_rundir > >> + if ovs and not ovs_db: > >> + ovs_db = 'unix:%s/db.sock' % ovs_rundir > >> ovsdb_ovnsb = OVSDB(ovnsb_db, 'OVN_Southbound') > >> ovsdb_ovnnb = OVSDB(ovnnb_db, 'OVN_Northbound') > >> @@ -260,25 +293,41 @@ def main(): > >> ] > >> regex_cookie = re.compile(r'^.*cookie 0x([0-9a-fA-F]+)') > >> + regex_handlers = [ > >> + (regex_cookie, cookie_handlers) > >> + ] > >> + > >> + if ovs: > >> + ovsdb_ovs = OVSDB(ovs_db, 'Open_vSwitch') > >> + regex_inport = re.compile(r'^ *[0-9]+\. *in_port=([0-9])+') > >> + regex_outport = re.compile(r'^ *output:([0-9]+)') > >> + ofport_handlers = [ > >> + OvsInterfaceHandler(ovsdb_ovs) > >> + ] > >> + regex_handlers += [ > >> + (regex_outport, ofport_handlers), > >> + (regex_inport, ofport_handlers) > >> + ] > >> + > >> regex_table_id = re.compile(r'^ *[0-9]+\.') > >> - cookie = None > >> + cookies = [] > >> while True: > >> line = sys.stdin.readline() > >> - if cookie: > >> - # Print SB record info when the current flow block ends. > >> + if len(cookies) > 0: > >> + # Print record info when the current flow block ends. > >> if regex_table_id.match(line) or line.strip() == '': > >> - print_sb_record_from_cookie(ovsdb_ovnnb, ovsdb_ovnsb, > >> - cookie_handlers, cookie) > >> - cookie = None > >> + for cookie, handlers in cookies: > >> + print_record_from_cookie(ovsdb_ovnnb, handlers, > >> cookie) > >> + cookies = [] > >> print(line.strip()) > >> if line == '': > >> break > >> - m = regex_cookie.match(line) > >> - if not m: > >> - continue > >> - cookie = m.group(1) > >> + for regex, handlers in regex_handlers: > >> + m = regex.match(line) > >> + if m: > >> + cookies.append((m.group(1), handlers)) > >> if __name__ == "__main__": > >> > > > _______________________________________________ dev mailing list [email protected] https://mail.openvswitch.org/mailman/listinfo/ovs-dev
