Hi Tim,
Thank you for your reporting.
I could reproduce the same problem, but this problem is on "ovs" python library
and not on Ryu...
My Script:
=====
from ryu.lib.ovs import vsctl
OVSDB_ADDR = 'tcp:127.0.0.1:6640'
# Equivalent to
# $ ovs-vsctl get Port bond0 interfaces
ovs_vsctl = vsctl.VSCtl(OVSDB_ADDR)
command = vsctl.VSCtlCommand('get', ('Port', 'bond0', 'interfaces'))
ovs_vsctl.run_command([command])
print('*** %s' % command)
=====
Also, I added some "print" for debugging:
=====
$ git diff
diff --git a/ryu/lib/ovs/vsctl.py b/ryu/lib/ovs/vsctl.py
index 2391c90..4bc5c90 100644
--- a/ryu/lib/ovs/vsctl.py
+++ b/ryu/lib/ovs/vsctl.py
@@ -792,6 +792,10 @@ class VSCtlContext(object):
return column, value
def get_column(self, ovsrec_row, column, key=None, if_exists=False):
+ print(type(ovsrec_row))
+ print(ovsrec_row._table.columns)
+ print(ovsrec_row.name)
+ print(ovsrec_row.interfaces)
value = getattr(ovsrec_row, column, None)
if isinstance(value, dict) and key is not None:
value = value.get(key, None)
=====
Port info:
=====
$ ovs-vsctl list Port bond0
_uuid : d1c90fc5-1be7-4449-87ed-be4886eb27c3
bond_active_slave : "16:a5:69:64:4b:2f"
bond_downdelay : 0
bond_fake_iface : false
bond_mode : []
bond_updelay : 0
cvlans : []
external_ids : {}
fake_bridge : false
interfaces : [5efc3ba8-6fd1-4f0c-83bf-74ff6e3f2909,
a756d290-62f0-4030-a5b6-fcc3a5e8b662]
lacp : []
mac : []
name : "bond0"
other_config : {}
protected : false
qos : []
rstp_statistics : {}
rstp_status : {}
statistics : {}
status : {}
tag : []
trunks : []
vlan_mode : []
=====
Traceback messages:
=====
$ python test_lib_ovs.py
<class 'ovs.db.idl.Row'>
{'interfaces': <ovs.db.schema.ColumnSchema object at 0x7fc19d22af28>, 'name':
<ovs.db.schema.ColumnSchema object at 0x7fc19d1ac208>}
bond0
Traceback (most recent call last):
File "test_lib_ovs.py", line 372, in <module>
ovs_vsctl.run_command([command])
File "<...>/python3.5/site-packages/ryu/lib/ovs/vsctl.py", line 1245, in
run_command
self._run_command(commands)
File "<...>/python3.5/site-packages/ryu/lib/ovs/vsctl.py", line 1241, in
_run_command
self._do_main(commands)
File "<...>/python3.5/site-packages/ryu/lib/ovs/vsctl.py", line 1147, in
_do_main
if self._do_vsctl(idl_, commands):
File "<...>/python3.5/site-packages/ryu/lib/ovs/vsctl.py", line 1082, in
_do_vsctl
command._run(ctx, command)
File "<...>/python3.5/site-packages/ryu/lib/ovs/vsctl.py", line 2169, in
_cmd_get
ctx, table_name, record_id, column_keys, id_, if_exists)
File "<...>/python3.5/site-packages/ryu/lib/ovs/vsctl.py", line 2154, in _get
result.append(ctx.get_column(ovsrec_row, column, key, if_exists))
File "<...>/python3.5/site-packages/ryu/lib/ovs/vsctl.py", line 798, in
get_column
print(ovsrec_row.interfaces)
File "<...>/python3.5/site-packages/ovs/db/idl.py", line 829, in __getattr__
return datum.to_python(_uuid_to_row)
File "<...>/python3.5/site-packages/ovs/db/data.py", line 499, in to_python
dk = uuid_to_row(k.value, self.type.key)
File "<...>/python3.5/site-packages/ovs/db/idl.py", line 663, in _uuid_to_row
return base.ref_table.rows.get(atom)
AttributeError: 'TableSchema' object has no attribute 'rows'
=====
Although "ovs.db.idl.Row" class has "interfaces" column, it seems to fail to
convert the column into Python representation.
I guess we need to contact to OVS dev team to solve this issue.
Thanks,
Iwase
On 2017年12月19日 03:44, Tim Ireland wrote:
I’m writing a wrapper around the vsctl command so I can collect data about a
remote ovs instance. I have a need to get the mapping from each Interface to
it’s corresponding Port. Using the “get” command, I can fetch all data that is
visible in the "ovsdb-client dump" command for a Port, except the “interfaces”
column of the “Port” table.
# ovs-vsctl list Port bond0
_uuid : a2198907-9d08-4872-bcf6-f87a8b111e35
bond_active_slave : "00:e0:ed:75:bb:07"
bond_downdelay : 0
bond_fake_iface : false
bond_mode : balance-slb
bond_updelay : 0
external_ids : {}
fake_bridge : false
interfaces : [98f33062-83dd-4c0b-a0c7-400eaecd9dc3,
c8ba39a6-2642-4c66-95d1-9f1a4b4c57ff]
lacp : []
mac : []
name : "bond0"
other_config : {bond-rebalance="10000"}
qos : []
rstp_statistics : {}
rstp_status : {}
statistics : {}
status : {}
tag : []
trunks : []
vlan_mode : []
Here is the wrapper class:
class OvsdbClient(object):
/"""Open vSwitch OVSDB client, via ryu vsctl interface."""/
//
//def __init__(self, host, port, logger):
/"""Initialize OvsdbClient./
//
/ Arguments:/
/ host (str): Host running OVS./
/ port (int): OVSDB server port./
/ logger (logging.Logger): Logging instance./
/ """/
//self._logger = logger
self._vsctl = vsctl.VSCtl('tcp:{}:{}'.format(host, port))
def run_vsctl_commands(self, commands):
self._vsctl.run_command(commands, timeout_sec=2)
def run_command(self, command, args=None):
/"""Run an ovsdb command./
//
/ Arguments:/
/ command (str): The command to execute./
/ args (list): Optional list of arguments to pass to the command./
//
/ Returns:/
/ VSCtlCommand.result: data returned as a result of the command./
/ """/
//args = args if args else []
vsctl_command = vsctl.VSCtlCommand(command, args=args)
self.run_vsctl_commands([vsctl_command])
return vsctl_command.result
def show(self):
/"""Show the current ovsdb configuration in one large dump."""/
//return self.run_command('show')
def list(self, table):
/"""List the contents of a single table in ovsdb."""/
//return self.run_command('list', args=[table])
def get(self, table, record, keys):
/"""Retrieve specific data from ovsdb tables./
//
/ Arguments:/
/ table (str): Ovsdb table name, ex: 'Bridge', 'Port`, etc./
/ record (str): Name of the item in the table, ex: 'br0'/
/ keys (list): List of keys which identify additional settings, ex:
'other_config'/
/ """/
//args = [table, record]
args.extend(keys)
return self.run_command('get', args=args)
I am executing a “get” command for the Port table and including “interfaces” in
the list of keys.
PORT_KEYS = [vswitch_idl.OVSREC_PORT_COL_NAME,
vswitch_idl.OVSREC_PORT_COL_BOND_ACTIVE_SLAVE,
vswitch_idl.OVSREC_PORT_COL_BOND_MODE,
vswitch_idl.OVSREC_PORT_COL_OTHER_CONFIG,
vswitch_idl.OVSREC_PORT_COL_LACP,
vswitch_idl.OVSREC_PORT_COL_EXTERNAL_IDS,
vswitch_idl.OVSREC_PORT_COL_TAG,
//vswitch_idl.OVSREC_PORT_COL_INTERFACES,
vswitch_idl.OVSREC_PORT_COL_VLAN_MODE]
data = dict(zip(PORT_KEYS, client.get(vswitch_idl.OVSREC_TABLE_PORT, ‘bond0',
self.PORT_KEYS)))
However, of all the keys, the “interfaces” key does not seem to work.
File
"/opt/stackstorm/virtualenvs/nutanix/lib/python2.7/site-packages/ryu/lib/ovs/vsctl.py",
line 1207, in run_command
self._run_command(commands)
File
"/opt/stackstorm/virtualenvs/nutanix/lib/python2.7/site-packages/ryu/lib/ovs/vsctl.py",
line 1200, in _run_command
self._do_main(commands)
File
"/opt/stackstorm/virtualenvs/nutanix/lib/python2.7/site-packages/ryu/lib/ovs/vsctl.py",
line 1106, in _do_main
if self._do_vsctl(idl_, commands):
File
"/opt/stackstorm/virtualenvs/nutanix/lib/python2.7/site-packages/ryu/lib/ovs/vsctl.py",
line 1041, in _do_vsctl
command._run(ctx, command)
File
"/opt/stackstorm/virtualenvs/nutanix/lib/python2.7/site-packages/ryu/lib/ovs/vsctl.py",
line 2128, in _cmd_get
ctx, table_name, record_id, column_keys, id_, if_exists)
File
"/opt/stackstorm/virtualenvs/nutanix/lib/python2.7/site-packages/ryu/lib/ovs/vsctl.py",
line 2113, in _get
result.append(ctx.get_column(ovsrec_row, column, key, if_exists))
File
"/opt/stackstorm/virtualenvs/nutanix/lib/python2.7/site-packages/ryu/lib/ovs/vsctl.py",
line 767, in get_column
% (ovsrec_row._table.name, column))
File
"/opt/stackstorm/virtualenvs/nutanix/lib/python2.7/site-packages/ryu/lib/ovs/vsctl.py",
line 140, in vsctl_fatal
raise Exception(msg) # not call ovs.utils.ovs_fatal for reusability
Exception: Port does not contain a column whose name matches “interfaces"
I can’t seem to find another way to get the interfaces mapping. There is the
“iface-to-br" command, but that seems to suggest that there is a one to one
mapping between bridges and ports, which is an assumption I can probably make
for now, but will that always be the case?
Regards,
-Tim
------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
_______________________________________________
Ryu-devel mailing list
Ryu-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/ryu-devel
------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
_______________________________________________
Ryu-devel mailing list
Ryu-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/ryu-devel