txn.add(self.ovsdb.db_set('Controller',
controller_uuid, *attr))
+ def _create_qos_bw_limit_queue(self, port_name, max_bw_in_bits,
+ max_burst_in_bits):
+ external_ids = {'id': port_name}
+ queue_other_config = {'min-rate': max_bw_in_bits,
+ 'max-rate': max_bw_in_bits,
+ 'burst': max_burst_in_bits}
+
+ self.ovsdb.db_create(
+ 'Queue', external_ids=external_ids,
+ other_config=queue_other_config).execute(check_error=True)
+
+ def _create_qos_bw_limit_profile(self, port_name, max_bw_in_bits):
+ external_ids = {'id': port_name}
+ queue = self.ovsdb.db_find(
+ 'Queue',
+ ('external_ids', '=', {'id': port_name}),
+ columns=['_uuid']).execute(
+ check_error=True)
+ queues = {}
+ queues[0] = queue[0]['_uuid']
+ qos_other_config = {'max-rate': max_bw_in_bits}
+ self.ovsdb.db_create('QoS', external_ids=external_ids,
+ other_config=qos_other_config,
+ type='linux-htb',
+ queues=queues).execute(check_error=True)
+
+ def create_qos_bw_limit_for_port(self, port_name, max_kbps,
+ max_burst_kbps):
+ # TODO(QoS) implement this with transactions,
+ # or roll back on failure
+ max_bw_in_bits = str(max_kbps * 1000)
+ max_burst_in_bits = str(max_burst_kbps * 1000)
+
+ self._create_qos_bw_limit_queue(port_name, max_bw_in_bits,
+ max_burst_in_bits)
+ self._create_qos_bw_limit_profile(port_name, max_bw_in_bits)
+
+ qos = self.ovsdb.db_find('QoS',
+ ('external_ids', '=', {'id': port_name}),
+ columns=['_uuid']).execute(check_error=True)
+ qos_profile = qos[0]['_uuid']
+ self.set_db_attribute('Port', port_name, 'qos', qos_profile,
+ check_error=True)
+
+ def get_qos_bw_limit_for_port(self, port_name):
+
+ res = self.ovsdb.db_find(
+ 'Queue',
+ ('external_ids', '=', {'id': port_name}),
+ columns=['other_config']).execute(check_error=True)
+
+ if res is None or len(res) == 0:
+ return None, None
+
+ other_config = res[0]['other_config']
+ max_kbps = int(other_config['max-rate']) / 1000
+ max_burst_kbps = int(other_config['burst']) / 1000
+ return max_kbps, max_burst_kbps
+
+ def del_qos_bw_limit_for_port(self, port_name):
+ qos = self.ovsdb.db_find('QoS',
+ ('external_ids', '=', {'id': port_name}),
+ columns=['_uuid']).execute(check_error=True)
+ qos_row = qos[0]['_uuid']
+
+ queue = self.ovsdb.db_find('Queue',
+ ('external_ids', '=', {'id': port_name}),
+ columns=['_uuid']).execute(check_error=True)
+ queue_row = queue[0]['_uuid']
+
+ with self.ovsdb.transaction(check_error=True) as txn:
+ txn.add(self.ovsdb.db_set('Port', port_name, ('qos', [])))
+ txn.add(self.ovsdb.db_destroy('QoS', qos_row))
+ txn.add(self.ovsdb.db_destroy('Queue', queue_row))
+
def __enter__(self):
self.create()
return self
:returns: :class:`Command` with field value result
"""
+ @abc.abstractmethod
+ def db_create(self, table, **col_values):
+ """Create a command to create new record
+
+ :param table: The OVS table containing the record to be created
+ :type table: string
+ :param col_values: The columns and their associated values
+ to be set after create
+ :type col_values: Dictionary of columns id's and values
+ :returns: :class:`Command` with no result
+ """
+
+ @abc.abstractmethod
+ def db_destroy(self, table, record):
+ """Create a command to destroy a record
+
+ :param table: The OVS table containing the record to be destroyed
+ :type table: string
+ :param record: The record id (name/uuid) to be destroyed
+ :type record: uuid/string
+ :returns: :class:`Command` with no result
+ """
+
@abc.abstractmethod
def db_set(self, table, record, *col_values):
"""Create a command to set fields in a record
def br_set_external_id(self, name, field, value):
return cmd.BrSetExternalIdCommand(self, name, field, value)
+ def db_create(self, table, **col_values):
+ return cmd.DbCreateCommand(self, table, **col_values)
+
+ def db_destroy(self, table, record):
+ return cmd.DbDestroyCommand(self, table, record)
+
def db_set(self, table, record, *col_values):
return cmd.DbSetCommand(self, table, record, *col_values)
return BaseCommand(self.context, 'br-get-external-id',
args=[name, field])
+ def db_create(self, table, **col_values):
+ args = [table]
+ args += _set_colval_args(*col_values.items())
+ return BaseCommand(self.context, 'create', args=args)
+
+ def db_destroy(self, table, record):
+ args = [table, record]
+ return BaseCommand(self.context, 'destroy', args=args)
+
def db_set(self, table, record, *col_values):
args = [table, record]
args += _set_colval_args(*col_values)
col, k, op, ovsdb.py_to_val(v)) for k, v in val.items()]
elif (isinstance(val, collections.Sequence)
and not isinstance(val, six.string_types)):
- args.append(
- "%s%s%s" % (col, op, ",".join(map(ovsdb.py_to_val, val))))
+ if len(val) == 0:
+ args.append("%s%s%s" % (col, op, "[]"))
+ else:
+ args.append(
+ "%s%s%s" % (col, op, ",".join(map(ovsdb.py_to_val, val))))
else:
args.append("%s%s%s" % (col, op, ovsdb.py_to_val(val)))
return args
br.external_ids = external_ids
+class DbCreateCommand(BaseCommand):
+ def __init__(self, api, table, **columns):
+ super(DbCreateCommand, self).__init__(api)
+ self.table = table
+ self.columns = columns
+
+ def run_idl(self, txn):
+ row = txn.insert(self.api._tables[self.table])
+ for col, val in self.columns.items():
+ setattr(row, col, val)
+ self.result = row
+
+
+class DbDestroyCommand(BaseCommand):
+ def __init__(self, api, table, record):
+ super(DbDestroyCommand, self).__init__(api)
+ self.table = table
+ self.record = record
+
+ def run_idl(self, txn):
+ record = idlutils.row_by_record(self.api.idl, self.table, self.record)
+ record.delete()
+
+
class DbSetCommand(BaseCommand):
def __init__(self, api, table, record, *col_values):
super(DbSetCommand, self).__init__(api)
controller,
'connection_mode'))
+ def test_qos_bw_limit(self):
+ port_name, _ = self.create_ovs_port()
+ self.br.create_qos_bw_limit_for_port(port_name, 700, 70)
+ max_rate, burst = self.br.get_qos_bw_limit_for_port(port_name)
+ self.assertEqual(700, max_rate)
+ self.assertEqual(70, burst)
+ self.br.del_qos_bw_limit_for_port(port_name)
+ max_rate, burst = self.br.get_qos_bw_limit_for_port(port_name)
+ self.assertIsNone(max_rate)
+ self.assertIsNone(burst)
+
class OVSLibTestCase(base.BaseOVSLinuxTestCase):