mirror of
https://github.com/openvswitch/ovs
synced 2025-08-31 14:25:26 +00:00
ovsdb-idl: Add the support to specify the uuid for row insert.
ovsdb-server allows the OVSDB clients to specify the uuid for the row inserts [1]. Both the C IDL client library and Python IDL are missing this feature. This patch adds this support. In C IDL, for each schema table, a new function is generated - <schema_table>insert_persistent_uuid(txn, uuid) which can be used the clients to persist the uuid. ovs-vsctl and other derivatives of ctl now supports the same in the generic 'create' command with the option "--id=<UUID>". In Python IDL, the uuid to persist can be specified in the Transaction.insert() function. [1] - a529e3cd1f("ovsdb-server: Allow OVSDB clients to specify the UUID for inserted rows.:) Acked-by: Adrian Moreno <amorenoz@redhat.com> Acked-by: Han Zhou <hzhou@ovn.org> Acked-by: Terry Wilson <twilson@redhat.com> Signed-off-by: Numan Siddique <numans@ovn.org> Signed-off-by: Ilya Maximets <i.maximets@ovn.org>
This commit is contained in:
committed by
Ilya Maximets
parent
954ae38a12
commit
55b9507e68
3
NEWS
3
NEWS
@@ -3,6 +3,9 @@ Post-v3.0.0
|
|||||||
- ovs-appctl:
|
- ovs-appctl:
|
||||||
* "ovs-appctl ofproto/trace" command can now display port names with the
|
* "ovs-appctl ofproto/trace" command can now display port names with the
|
||||||
"--names" option.
|
"--names" option.
|
||||||
|
- OVSDB-IDL:
|
||||||
|
* Add the support to specify the persistent uuid for row insert in both
|
||||||
|
C and Python IDLs.
|
||||||
- Windows:
|
- Windows:
|
||||||
* Conntrack IPv6 fragment support.
|
* Conntrack IPv6 fragment support.
|
||||||
- DPDK:
|
- DPDK:
|
||||||
|
@@ -1731,29 +1731,43 @@ cmd_create(struct ctl_context *ctx)
|
|||||||
const struct ovsdb_idl_table_class *table;
|
const struct ovsdb_idl_table_class *table;
|
||||||
const struct ovsdb_idl_row *row;
|
const struct ovsdb_idl_row *row;
|
||||||
const struct uuid *uuid = NULL;
|
const struct uuid *uuid = NULL;
|
||||||
|
bool persist_uuid = false;
|
||||||
|
struct uuid uuid_;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
ctx->error = get_table(table_name, &table);
|
ctx->error = get_table(table_name, &table);
|
||||||
if (ctx->error) {
|
if (ctx->error) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (id) {
|
|
||||||
struct ovsdb_symbol *symbol = NULL;
|
|
||||||
|
|
||||||
ctx->error = create_symbol(ctx->symtab, id, &symbol, NULL);
|
if (id) {
|
||||||
if (ctx->error) {
|
if (uuid_from_string(&uuid_, id)) {
|
||||||
return;
|
uuid = &uuid_;
|
||||||
|
persist_uuid = true;
|
||||||
|
} else {
|
||||||
|
struct ovsdb_symbol *symbol = NULL;
|
||||||
|
|
||||||
|
ctx->error = create_symbol(ctx->symtab, id, &symbol, NULL);
|
||||||
|
if (ctx->error) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (table->is_root) {
|
||||||
|
/* This table is in the root set, meaning that rows created in
|
||||||
|
* it won't disappear even if they are unreferenced, so disable
|
||||||
|
* warnings about that by pretending that there is a
|
||||||
|
* reference. */
|
||||||
|
symbol->strong_ref = true;
|
||||||
|
}
|
||||||
|
uuid = &symbol->uuid;
|
||||||
}
|
}
|
||||||
if (table->is_root) {
|
|
||||||
/* This table is in the root set, meaning that rows created in it
|
|
||||||
* won't disappear even if they are unreferenced, so disable
|
|
||||||
* warnings about that by pretending that there is a reference. */
|
|
||||||
symbol->strong_ref = true;
|
|
||||||
}
|
|
||||||
uuid = &symbol->uuid;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
row = ovsdb_idl_txn_insert(ctx->txn, table, uuid);
|
if (persist_uuid) {
|
||||||
|
row = ovsdb_idl_txn_insert_persist_uuid(ctx->txn, table, uuid);
|
||||||
|
} else {
|
||||||
|
row = ovsdb_idl_txn_insert(ctx->txn, table, uuid);
|
||||||
|
}
|
||||||
|
|
||||||
for (i = 2; i < ctx->argc; i++) {
|
for (i = 2; i < ctx->argc; i++) {
|
||||||
ctx->error = set_column(table, row, ctx->argv[i], ctx->symtab);
|
ctx->error = set_column(table, row, ctx->argv[i], ctx->symtab);
|
||||||
if (ctx->error) {
|
if (ctx->error) {
|
||||||
|
@@ -203,7 +203,7 @@ Without \fB\-\-if-exists\fR, it is an error if \fIrecord\fR does not
|
|||||||
exist. With \fB\-\-if-exists\fR, this command does nothing if
|
exist. With \fB\-\-if-exists\fR, this command does nothing if
|
||||||
\fIrecord\fR does not exist.
|
\fIrecord\fR does not exist.
|
||||||
.
|
.
|
||||||
.IP "[\fB\-\-id=@\fIname\fR] \fBcreate\fR \fItable column\fR[\fB:\fIkey\fR]\fB=\fIvalue\fR..."
|
.IP "[\fB\-\-id=(@\fIname\fR | \fIuuid\fR] \fBcreate\fR \fItable column\fR[\fB:\fIkey\fR]\fB=\fIvalue\fR..."
|
||||||
Creates a new record in \fItable\fR and sets the initial values of
|
Creates a new record in \fItable\fR and sets the initial values of
|
||||||
each \fIcolumn\fR. Columns not explicitly set will receive their
|
each \fIcolumn\fR. Columns not explicitly set will receive their
|
||||||
default values. Outputs the UUID of the new row.
|
default values. Outputs the UUID of the new row.
|
||||||
@@ -212,6 +212,9 @@ If \fB@\fIname\fR is specified, then the UUID for the new row may be
|
|||||||
referred to by that name elsewhere in the same \fB\*(PN\fR
|
referred to by that name elsewhere in the same \fB\*(PN\fR
|
||||||
invocation in contexts where a UUID is expected. Such references may
|
invocation in contexts where a UUID is expected. Such references may
|
||||||
precede or follow the \fBcreate\fR command.
|
precede or follow the \fBcreate\fR command.
|
||||||
|
.IP
|
||||||
|
If a valid \fIuuid\fR is specified, then it is used as the UUID
|
||||||
|
of the new row.
|
||||||
.
|
.
|
||||||
.RS
|
.RS
|
||||||
.IP "Caution (ovs-vsctl as example)"
|
.IP "Caution (ovs-vsctl as example)"
|
||||||
|
@@ -310,7 +310,7 @@
|
|||||||
</p>
|
</p>
|
||||||
</dd>
|
</dd>
|
||||||
|
|
||||||
<dt>[<code>--id=@</code><var>name</var>] <code>create</code> <var>table column</var>[<code>:</code><var>key</var>]<code>=</code><var>value</var>...</dt>
|
<dt>[<code>--id=(@</code><var>name</var>|<var>uuid</var>)] <code>create</code> <var>table column</var>[<code>:</code><var>key</var>]<code>=</code><var>value</var>...</dt>
|
||||||
<dd>
|
<dd>
|
||||||
<p>
|
<p>
|
||||||
Creates a new record in <var>table</var> and sets the initial values of
|
Creates a new record in <var>table</var> and sets the initial values of
|
||||||
@@ -323,6 +323,10 @@
|
|||||||
invocation in contexts where a UUID is expected. Such references may
|
invocation in contexts where a UUID is expected. Such references may
|
||||||
precede or follow the <code>create</code> command.
|
precede or follow the <code>create</code> command.
|
||||||
</p>
|
</p>
|
||||||
|
<p>
|
||||||
|
If a valid <var>uuid</var> is specified, then it is used as the
|
||||||
|
UUID of the new row.
|
||||||
|
</p>
|
||||||
<dl>
|
<dl>
|
||||||
<dt>Caution (ovs-vsctl as example)</dt>
|
<dt>Caution (ovs-vsctl as example)</dt>
|
||||||
<dd>
|
<dd>
|
||||||
|
@@ -74,6 +74,7 @@ struct ovsdb_idl_row {
|
|||||||
struct ovs_list dst_arcs; /* Backward arcs (ovsdb_idl_arc.dst_node). */
|
struct ovs_list dst_arcs; /* Backward arcs (ovsdb_idl_arc.dst_node). */
|
||||||
struct ovsdb_idl_table *table; /* Containing table. */
|
struct ovsdb_idl_table *table; /* Containing table. */
|
||||||
struct ovsdb_datum *old_datum; /* Committed data (null if orphaned). */
|
struct ovsdb_datum *old_datum; /* Committed data (null if orphaned). */
|
||||||
|
bool persist_uuid; /* Persist 'uuid' during insert txn if set. */
|
||||||
bool parsed; /* Whether the row is parsed. */
|
bool parsed; /* Whether the row is parsed. */
|
||||||
struct ovs_list reparse_node; /* Rows that needs to be re-parsed due to
|
struct ovs_list reparse_node; /* Rows that needs to be re-parsed due to
|
||||||
* insertion of a referenced row. */
|
* insertion of a referenced row. */
|
||||||
|
@@ -2855,11 +2855,14 @@ substitute_uuids(struct json *json, const struct ovsdb_idl_txn *txn)
|
|||||||
|
|
||||||
row = ovsdb_idl_txn_get_row(txn, &uuid);
|
row = ovsdb_idl_txn_get_row(txn, &uuid);
|
||||||
if (row && !row->old_datum && row->new_datum) {
|
if (row && !row->old_datum && row->new_datum) {
|
||||||
json_destroy(json);
|
if (row->persist_uuid) {
|
||||||
|
return json;
|
||||||
return json_array_create_2(
|
} else {
|
||||||
json_string_create("named-uuid"),
|
json_destroy(json);
|
||||||
json_string_create_nocopy(ovsdb_data_row_name(&uuid)));
|
return json_array_create_2(
|
||||||
|
json_string_create("named-uuid"),
|
||||||
|
json_string_create_nocopy(ovsdb_data_row_name(&uuid)));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -3284,9 +3287,19 @@ ovsdb_idl_txn_commit(struct ovsdb_idl_txn *txn)
|
|||||||
|
|
||||||
any_updates = true;
|
any_updates = true;
|
||||||
|
|
||||||
json_object_put(op, "uuid-name",
|
char *uuid_json;
|
||||||
json_string_create_nocopy(
|
struct json *value;
|
||||||
ovsdb_data_row_name(&row->uuid)));
|
if (row->persist_uuid) {
|
||||||
|
uuid_json = "uuid";
|
||||||
|
value = json_string_create_nocopy(
|
||||||
|
xasprintf(UUID_FMT, UUID_ARGS(&row->uuid)));
|
||||||
|
} else {
|
||||||
|
uuid_json = "uuid-name";
|
||||||
|
value = json_string_create_nocopy(
|
||||||
|
ovsdb_data_row_name(&row->uuid));
|
||||||
|
}
|
||||||
|
|
||||||
|
json_object_put(op, uuid_json, value);
|
||||||
|
|
||||||
insert = xmalloc(sizeof *insert);
|
insert = xmalloc(sizeof *insert);
|
||||||
insert->dummy = row->uuid;
|
insert->dummy = row->uuid;
|
||||||
@@ -3770,6 +3783,31 @@ ovsdb_idl_txn_delete(const struct ovsdb_idl_row *row_)
|
|||||||
row->new_datum = NULL;
|
row->new_datum = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static const struct ovsdb_idl_row *
|
||||||
|
ovsdb_idl_txn_insert__(struct ovsdb_idl_txn *txn,
|
||||||
|
const struct ovsdb_idl_table_class *class,
|
||||||
|
const struct uuid *uuid,
|
||||||
|
bool persist_uuid)
|
||||||
|
{
|
||||||
|
struct ovsdb_idl_row *row = ovsdb_idl_row_create__(class);
|
||||||
|
|
||||||
|
ovs_assert(uuid || !persist_uuid);
|
||||||
|
if (uuid) {
|
||||||
|
ovs_assert(!ovsdb_idl_txn_get_row(txn, uuid));
|
||||||
|
row->uuid = *uuid;
|
||||||
|
} else {
|
||||||
|
uuid_generate(&row->uuid);
|
||||||
|
}
|
||||||
|
row->persist_uuid = persist_uuid;
|
||||||
|
row->table = ovsdb_idl_table_from_class(txn->idl, class);
|
||||||
|
row->new_datum = xmalloc(class->n_columns * sizeof *row->new_datum);
|
||||||
|
hmap_insert(&row->table->rows, &row->hmap_node, uuid_hash(&row->uuid));
|
||||||
|
hmap_insert(&txn->txn_rows, &row->txn_node, uuid_hash(&row->uuid));
|
||||||
|
ovsdb_idl_add_to_indexes(row);
|
||||||
|
|
||||||
|
return row;
|
||||||
|
}
|
||||||
|
|
||||||
/* Inserts and returns a new row in the table with the specified 'class' in the
|
/* Inserts and returns a new row in the table with the specified 'class' in the
|
||||||
* database with open transaction 'txn'.
|
* database with open transaction 'txn'.
|
||||||
*
|
*
|
||||||
@@ -3787,22 +3825,23 @@ ovsdb_idl_txn_insert(struct ovsdb_idl_txn *txn,
|
|||||||
const struct ovsdb_idl_table_class *class,
|
const struct ovsdb_idl_table_class *class,
|
||||||
const struct uuid *uuid)
|
const struct uuid *uuid)
|
||||||
{
|
{
|
||||||
struct ovsdb_idl_row *row = ovsdb_idl_row_create__(class);
|
return ovsdb_idl_txn_insert__(txn, class, uuid, false);
|
||||||
|
}
|
||||||
|
|
||||||
if (uuid) {
|
/* Inserts and returns a new row in the table with the specified 'class' in the
|
||||||
ovs_assert(!ovsdb_idl_txn_get_row(txn, uuid));
|
* database with open transaction 'txn'.
|
||||||
row->uuid = *uuid;
|
*
|
||||||
} else {
|
* The new row is assigned the specified UUID (which cannot be null).
|
||||||
uuid_generate(&row->uuid);
|
*
|
||||||
}
|
* Usually this function is used indirectly through one of the
|
||||||
|
* "insert_persist_uuid" functions generated by ovsdb-idlc. */
|
||||||
row->table = ovsdb_idl_table_from_class(txn->idl, class);
|
const struct ovsdb_idl_row *
|
||||||
row->new_datum = xmalloc(class->n_columns * sizeof *row->new_datum);
|
ovsdb_idl_txn_insert_persist_uuid(struct ovsdb_idl_txn *txn,
|
||||||
hmap_insert(&row->table->rows, &row->hmap_node, uuid_hash(&row->uuid));
|
const struct ovsdb_idl_table_class *class,
|
||||||
hmap_insert(&txn->txn_rows, &row->txn_node, uuid_hash(&row->uuid));
|
const struct uuid *uuid)
|
||||||
ovsdb_idl_add_to_indexes(row);
|
{
|
||||||
|
ovs_assert(uuid);
|
||||||
return row;
|
return ovsdb_idl_txn_insert__(txn, class, uuid, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@@ -375,6 +375,9 @@ void ovsdb_idl_txn_delete(const struct ovsdb_idl_row *);
|
|||||||
const struct ovsdb_idl_row *ovsdb_idl_txn_insert(
|
const struct ovsdb_idl_row *ovsdb_idl_txn_insert(
|
||||||
struct ovsdb_idl_txn *, const struct ovsdb_idl_table_class *,
|
struct ovsdb_idl_txn *, const struct ovsdb_idl_table_class *,
|
||||||
const struct uuid *);
|
const struct uuid *);
|
||||||
|
const struct ovsdb_idl_row *ovsdb_idl_txn_insert_persist_uuid(
|
||||||
|
struct ovsdb_idl_txn *txn, const struct ovsdb_idl_table_class *class,
|
||||||
|
const struct uuid *uuid);
|
||||||
|
|
||||||
struct ovsdb_idl *ovsdb_idl_txn_get_idl (struct ovsdb_idl_txn *);
|
struct ovsdb_idl *ovsdb_idl_txn_get_idl (struct ovsdb_idl_txn *);
|
||||||
void ovsdb_idl_get_initial_snapshot(struct ovsdb_idl *);
|
void ovsdb_idl_get_initial_snapshot(struct ovsdb_idl *);
|
||||||
|
@@ -362,6 +362,8 @@ struct %(s)s *%(s)s_cursor_data(struct ovsdb_idl_cursor *);
|
|||||||
void %(s)s_init(struct %(s)s *);
|
void %(s)s_init(struct %(s)s *);
|
||||||
void %(s)s_delete(const struct %(s)s *);
|
void %(s)s_delete(const struct %(s)s *);
|
||||||
struct %(s)s *%(s)s_insert(struct ovsdb_idl_txn *);
|
struct %(s)s *%(s)s_insert(struct ovsdb_idl_txn *);
|
||||||
|
struct %(s)s *%(s)s_insert_persist_uuid(
|
||||||
|
struct ovsdb_idl_txn *txn, const struct uuid *uuid);
|
||||||
|
|
||||||
/* Returns true if the tracked column referenced by 'enum %(s)s_column_id' of
|
/* Returns true if the tracked column referenced by 'enum %(s)s_column_id' of
|
||||||
* the row referenced by 'struct %(s)s *' was updated since the last change
|
* the row referenced by 'struct %(s)s *' was updated since the last change
|
||||||
@@ -809,6 +811,19 @@ struct %(s)s *
|
|||||||
return %(s)s_cast(ovsdb_idl_txn_insert(txn, &%(p)stable_%(tl)s, NULL));
|
return %(s)s_cast(ovsdb_idl_txn_insert(txn, &%(p)stable_%(tl)s, NULL));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Inserts and returns a new row in the table "%(t)s" in the database
|
||||||
|
* with open transaction 'txn'.
|
||||||
|
*
|
||||||
|
* The new row is assigned the UUID specified in the 'uuid' parameter
|
||||||
|
* (which cannot be null). ovsdb-server will try to assign the same
|
||||||
|
* UUID when 'txn' is committed. */
|
||||||
|
struct %(s)s *
|
||||||
|
%(s)s_insert_persist_uuid(struct ovsdb_idl_txn *txn, const struct uuid *uuid)
|
||||||
|
{
|
||||||
|
return %(s)s_cast(ovsdb_idl_txn_insert_persist_uuid(
|
||||||
|
txn, &%(p)stable_%(tl)s, uuid));
|
||||||
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
%(s)s_is_updated(const struct %(s)s *row, enum %(s)s_column_id column)
|
%(s)s_is_updated(const struct %(s)s *row, enum %(s)s_column_id column)
|
||||||
{
|
{
|
||||||
|
@@ -1223,7 +1223,7 @@ class Row(object):
|
|||||||
d["a"] = "b"
|
d["a"] = "b"
|
||||||
row.mycolumn = d
|
row.mycolumn = d
|
||||||
"""
|
"""
|
||||||
def __init__(self, idl, table, uuid, data):
|
def __init__(self, idl, table, uuid, data, persist_uuid=False):
|
||||||
# All of the explicit references to self.__dict__ below are required
|
# All of the explicit references to self.__dict__ below are required
|
||||||
# to set real attributes with invoking self.__getattr__().
|
# to set real attributes with invoking self.__getattr__().
|
||||||
self.__dict__["uuid"] = uuid
|
self.__dict__["uuid"] = uuid
|
||||||
@@ -1278,6 +1278,10 @@ class Row(object):
|
|||||||
# in the dictionary are all None.
|
# in the dictionary are all None.
|
||||||
self.__dict__["_prereqs"] = {}
|
self.__dict__["_prereqs"] = {}
|
||||||
|
|
||||||
|
# Indicates if the specified 'uuid' should be used as the row uuid
|
||||||
|
# or let the server generate it.
|
||||||
|
self.__dict__["_persist_uuid"] = persist_uuid
|
||||||
|
|
||||||
def __lt__(self, other):
|
def __lt__(self, other):
|
||||||
if not isinstance(other, Row):
|
if not isinstance(other, Row):
|
||||||
return NotImplemented
|
return NotImplemented
|
||||||
@@ -1816,7 +1820,11 @@ class Transaction(object):
|
|||||||
op = {"table": row._table.name}
|
op = {"table": row._table.name}
|
||||||
if row._data is None:
|
if row._data is None:
|
||||||
op["op"] = "insert"
|
op["op"] = "insert"
|
||||||
op["uuid-name"] = _uuid_name_from_uuid(row.uuid)
|
if row._persist_uuid:
|
||||||
|
op["uuid"] = row.uuid
|
||||||
|
else:
|
||||||
|
op["uuid-name"] = _uuid_name_from_uuid(row.uuid)
|
||||||
|
|
||||||
any_updates = True
|
any_updates = True
|
||||||
|
|
||||||
op_index = len(operations) - 1
|
op_index = len(operations) - 1
|
||||||
@@ -2056,20 +2064,22 @@ class Transaction(object):
|
|||||||
row._mutations['_removes'].pop(column.name, None)
|
row._mutations['_removes'].pop(column.name, None)
|
||||||
row._changes[column.name] = datum.copy()
|
row._changes[column.name] = datum.copy()
|
||||||
|
|
||||||
def insert(self, table, new_uuid=None):
|
def insert(self, table, new_uuid=None, persist_uuid=False):
|
||||||
"""Inserts and returns a new row in 'table', which must be one of the
|
"""Inserts and returns a new row in 'table', which must be one of the
|
||||||
ovs.db.schema.TableSchema objects in the Idl's 'tables' dict.
|
ovs.db.schema.TableSchema objects in the Idl's 'tables' dict.
|
||||||
|
|
||||||
The new row is assigned a provisional UUID. If 'uuid' is None then one
|
The new row is assigned a provisional UUID. If 'uuid' is None then one
|
||||||
is randomly generated; otherwise 'uuid' should specify a randomly
|
is randomly generated; otherwise 'uuid' should specify a randomly
|
||||||
generated uuid.UUID not otherwise in use. ovsdb-server will assign a
|
generated uuid.UUID not otherwise in use. If 'persist_uuid' is true
|
||||||
different UUID when 'txn' is committed, but the IDL will replace any
|
and 'new_uuid' is specified, IDL requests the ovsdb-server to assign
|
||||||
uses of the provisional UUID in the data to be to be committed by the
|
the same UUID, otherwise ovsdb-server will assign a different UUID when
|
||||||
UUID assigned by ovsdb-server."""
|
'txn' is committed and the IDL will replace any uses of the provisional
|
||||||
|
UUID in the data to be committed by the UUID assigned by
|
||||||
|
ovsdb-server."""
|
||||||
assert self._status == Transaction.UNCOMMITTED
|
assert self._status == Transaction.UNCOMMITTED
|
||||||
if new_uuid is None:
|
if new_uuid is None:
|
||||||
new_uuid = uuid.uuid4()
|
new_uuid = uuid.uuid4()
|
||||||
row = Row(self.idl, table, new_uuid, None)
|
row = Row(self.idl, table, new_uuid, None, persist_uuid=persist_uuid)
|
||||||
table.rows[row.uuid] = row
|
table.rows[row.uuid] = row
|
||||||
self._txn_rows[row.uuid] = row
|
self._txn_rows[row.uuid] = row
|
||||||
return row
|
return row
|
||||||
|
@@ -1710,3 +1710,28 @@ ingress_policing_kpkts_rate: 100
|
|||||||
])
|
])
|
||||||
OVS_VSCTL_CLEANUP
|
OVS_VSCTL_CLEANUP
|
||||||
AT_CLEANUP
|
AT_CLEANUP
|
||||||
|
|
||||||
|
AT_SETUP([ovs-vsctl create bridge with uuid])
|
||||||
|
AT_KEYWORDS([create bridge with uuid])
|
||||||
|
OVS_VSCTL_SETUP
|
||||||
|
|
||||||
|
AT_CHECK([ovs-vsctl --no-wait --id=c5cc12f8-eaa1-43a7-8a73-bccd18df1111 create bridge \
|
||||||
|
name=tst0 -- add open . bridges c5cc12f8-eaa1-43a7-8a73-bccd18df1111], [0],[dnl
|
||||||
|
c5cc12f8-eaa1-43a7-8a73-bccd18df1111
|
||||||
|
])
|
||||||
|
|
||||||
|
AT_CHECK([ovs-vsctl --no-wait --id=c5cc12f8-eaa1-43a7-8a73-bccd18df1111 create bridge \
|
||||||
|
name=tst1 -- add open . bridges c5cc12f8-eaa1-43a7-8a73-bccd18df1111], [1], [ignore], [ignore])
|
||||||
|
|
||||||
|
AT_CHECK([ovs-vsctl --no-wait --bare --columns _uuid,name list bridge], [0], [dnl
|
||||||
|
c5cc12f8-eaa1-43a7-8a73-bccd18df1111
|
||||||
|
tst0
|
||||||
|
])
|
||||||
|
|
||||||
|
ovs-vsctl --no-wait --id=@a create bridge \
|
||||||
|
name=tst1 -- add open . bridges @a
|
||||||
|
|
||||||
|
AT_CHECK([ovs-vsctl --no-wait --bare --columns _uuid,name list bridge tst1], [0], [ignore])
|
||||||
|
|
||||||
|
OVS_VSCTL_CLEANUP
|
||||||
|
AT_CLEANUP
|
||||||
|
@@ -2555,3 +2555,61 @@ OVSDB_CHECK_IDL_TRACK([track, insert and delete, refs to link2],
|
|||||||
005: table link2: i=1 l1= uuid=<1>
|
005: table link2: i=1 l1= uuid=<1>
|
||||||
006: done
|
006: done
|
||||||
]])
|
]])
|
||||||
|
|
||||||
|
m4_define([OVSDB_CHECK_IDL_PERS_UUID_INSERT_C],
|
||||||
|
[AT_SETUP([$1 - C])
|
||||||
|
AT_KEYWORDS([idl persistent uuid insert])
|
||||||
|
AT_CHECK([ovsdb_start_idltest "" "$abs_srcdir/idltest.ovsschema"])
|
||||||
|
AT_CHECK([test-ovsdb '-vPATTERN:console:test-ovsdb|%c|%m' -vjsonrpc -t10 idl unix:socket $2],
|
||||||
|
[0], [stdout], [stderr])
|
||||||
|
AT_CHECK([sort stdout],
|
||||||
|
[0], [$3])
|
||||||
|
AT_CHECK([grep $4 stderr], [0], [ignore])
|
||||||
|
OVSDB_SERVER_SHUTDOWN
|
||||||
|
AT_CLEANUP])
|
||||||
|
|
||||||
|
m4_define([OVSDB_CHECK_IDL_PERS_UUID_INSERT_PY],
|
||||||
|
[AT_SETUP([$1 - Python3])
|
||||||
|
AT_KEYWORDS([idl persistent uuid insert])
|
||||||
|
AT_CHECK([ovsdb_start_idltest "" "$abs_srcdir/idltest.ovsschema"])
|
||||||
|
AT_CHECK([$PYTHON3 $srcdir/test-ovsdb.py -t10 idl $srcdir/idltest.ovsschema unix:socket $2],
|
||||||
|
[0], [stdout], [stderr])
|
||||||
|
AT_CHECK([sort stdout],
|
||||||
|
[0], [$3])
|
||||||
|
AT_CHECK([grep $4 stderr], [0], [ignore])
|
||||||
|
OVSDB_SERVER_SHUTDOWN
|
||||||
|
AT_CLEANUP])
|
||||||
|
|
||||||
|
|
||||||
|
m4_define([OVSDB_CHECK_IDL_PERS_UUID_INSERT],
|
||||||
|
[OVSDB_CHECK_IDL_PERS_UUID_INSERT_C($@)
|
||||||
|
OVSDB_CHECK_IDL_PERS_UUID_INSERT_PY($@)])
|
||||||
|
|
||||||
|
OVSDB_CHECK_IDL_PERS_UUID_INSERT([simple idl, persistent uuid insert],
|
||||||
|
[['insert_uuid c5cc12f8-eaa1-43a7-8a73-bccd18df2222 2, insert_uuid c5cc12f8-eaa1-43a7-8a73-bccd18df3333 3' \
|
||||||
|
'insert_uuid c5cc12f8-eaa1-43a7-8a73-bccd18df4444 4, insert_uuid c5cc12f8-eaa1-43a7-8a73-bccd18df2222 5' \
|
||||||
|
'insert_uuid c5cc12f8-eaa1-43a7-8a73-bccd18df4444 4' \
|
||||||
|
'delete 2' \
|
||||||
|
'insert_uuid c5cc12f8-eaa1-43a7-8a73-bccd18df2222 5'
|
||||||
|
]],
|
||||||
|
[[000: empty
|
||||||
|
001: commit, status=success
|
||||||
|
002: table simple: i=2 r=0 b=false s= u=00000000-0000-0000-0000-000000000000 ia=[] ra=[] ba=[] sa=[] ua=[] uuid=c5cc12f8-eaa1-43a7-8a73-bccd18df2222
|
||||||
|
002: table simple: i=3 r=0 b=false s= u=00000000-0000-0000-0000-000000000000 ia=[] ra=[] ba=[] sa=[] ua=[] uuid=c5cc12f8-eaa1-43a7-8a73-bccd18df3333
|
||||||
|
003: commit, status=error
|
||||||
|
004: table simple: i=2 r=0 b=false s= u=00000000-0000-0000-0000-000000000000 ia=[] ra=[] ba=[] sa=[] ua=[] uuid=c5cc12f8-eaa1-43a7-8a73-bccd18df2222
|
||||||
|
004: table simple: i=3 r=0 b=false s= u=00000000-0000-0000-0000-000000000000 ia=[] ra=[] ba=[] sa=[] ua=[] uuid=c5cc12f8-eaa1-43a7-8a73-bccd18df3333
|
||||||
|
005: commit, status=success
|
||||||
|
006: table simple: i=2 r=0 b=false s= u=00000000-0000-0000-0000-000000000000 ia=[] ra=[] ba=[] sa=[] ua=[] uuid=c5cc12f8-eaa1-43a7-8a73-bccd18df2222
|
||||||
|
006: table simple: i=3 r=0 b=false s= u=00000000-0000-0000-0000-000000000000 ia=[] ra=[] ba=[] sa=[] ua=[] uuid=c5cc12f8-eaa1-43a7-8a73-bccd18df3333
|
||||||
|
006: table simple: i=4 r=0 b=false s= u=00000000-0000-0000-0000-000000000000 ia=[] ra=[] ba=[] sa=[] ua=[] uuid=c5cc12f8-eaa1-43a7-8a73-bccd18df4444
|
||||||
|
007: commit, status=success
|
||||||
|
008: table simple: i=3 r=0 b=false s= u=00000000-0000-0000-0000-000000000000 ia=[] ra=[] ba=[] sa=[] ua=[] uuid=c5cc12f8-eaa1-43a7-8a73-bccd18df3333
|
||||||
|
008: table simple: i=4 r=0 b=false s= u=00000000-0000-0000-0000-000000000000 ia=[] ra=[] ba=[] sa=[] ua=[] uuid=c5cc12f8-eaa1-43a7-8a73-bccd18df4444
|
||||||
|
009: commit, status=success
|
||||||
|
010: table simple: i=3 r=0 b=false s= u=00000000-0000-0000-0000-000000000000 ia=[] ra=[] ba=[] sa=[] ua=[] uuid=c5cc12f8-eaa1-43a7-8a73-bccd18df3333
|
||||||
|
010: table simple: i=4 r=0 b=false s= u=00000000-0000-0000-0000-000000000000 ia=[] ra=[] ba=[] sa=[] ua=[] uuid=c5cc12f8-eaa1-43a7-8a73-bccd18df4444
|
||||||
|
010: table simple: i=5 r=0 b=false s= u=00000000-0000-0000-0000-000000000000 ia=[] ra=[] ba=[] sa=[] ua=[] uuid=c5cc12f8-eaa1-43a7-8a73-bccd18df2222
|
||||||
|
011: done
|
||||||
|
]],
|
||||||
|
[['This UUID would duplicate a UUID already present within the table or deleted within the same transaction']])
|
||||||
|
@@ -2400,7 +2400,7 @@ idltest_find_simple(struct ovsdb_idl *idl, int i)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static bool
|
||||||
idl_set(struct ovsdb_idl *idl, char *commands, int step)
|
idl_set(struct ovsdb_idl *idl, char *commands, int step)
|
||||||
{
|
{
|
||||||
char *cmd, *save_ptr1 = NULL;
|
char *cmd, *save_ptr1 = NULL;
|
||||||
@@ -2458,6 +2458,19 @@ idl_set(struct ovsdb_idl *idl, char *commands, int step)
|
|||||||
|
|
||||||
s = idltest_simple_insert(txn);
|
s = idltest_simple_insert(txn);
|
||||||
idltest_simple_set_i(s, atoi(arg1));
|
idltest_simple_set_i(s, atoi(arg1));
|
||||||
|
} else if (!strcmp(name, "insert_uuid")) {
|
||||||
|
struct idltest_simple *s;
|
||||||
|
|
||||||
|
if (!arg1 || !arg2) {
|
||||||
|
ovs_fatal(0, "\"insert\" command requires 2 arguments");
|
||||||
|
}
|
||||||
|
|
||||||
|
struct uuid s_uuid;
|
||||||
|
if (!uuid_from_string(&s_uuid, arg1)) {
|
||||||
|
ovs_fatal(0, "\"insert_uuid\" command requires valid uuid");
|
||||||
|
}
|
||||||
|
s = idltest_simple_insert_persist_uuid(txn, &s_uuid);
|
||||||
|
idltest_simple_set_i(s, atoi(arg2));
|
||||||
} else if (!strcmp(name, "delete")) {
|
} else if (!strcmp(name, "delete")) {
|
||||||
const struct idltest_simple *s;
|
const struct idltest_simple *s;
|
||||||
|
|
||||||
@@ -2522,7 +2535,7 @@ idl_set(struct ovsdb_idl *idl, char *commands, int step)
|
|||||||
print_and_log("%03d: destroy", step);
|
print_and_log("%03d: destroy", step);
|
||||||
ovsdb_idl_txn_destroy(txn);
|
ovsdb_idl_txn_destroy(txn);
|
||||||
ovsdb_idl_check_consistency(idl);
|
ovsdb_idl_check_consistency(idl);
|
||||||
return;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
ovs_fatal(0, "unknown command %s", name);
|
ovs_fatal(0, "unknown command %s", name);
|
||||||
}
|
}
|
||||||
@@ -2543,6 +2556,8 @@ idl_set(struct ovsdb_idl *idl, char *commands, int step)
|
|||||||
|
|
||||||
ovsdb_idl_txn_destroy(txn);
|
ovsdb_idl_txn_destroy(txn);
|
||||||
ovsdb_idl_check_consistency(idl);
|
ovsdb_idl_check_consistency(idl);
|
||||||
|
|
||||||
|
return (status != TXN_ERROR);
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct ovsdb_idl_table_class *
|
static const struct ovsdb_idl_table_class *
|
||||||
@@ -2777,7 +2792,14 @@ do_idl(struct ovs_cmdl_context *ctx)
|
|||||||
update_conditions(idl, arg + strlen(cond_s));
|
update_conditions(idl, arg + strlen(cond_s));
|
||||||
print_and_log("%03d: change conditions", step++);
|
print_and_log("%03d: change conditions", step++);
|
||||||
} else if (arg[0] != '[') {
|
} else if (arg[0] != '[') {
|
||||||
idl_set(idl, arg, step++);
|
if (!idl_set(idl, arg, step++)) {
|
||||||
|
/* If idl_set() returns false, then no transaction
|
||||||
|
* was sent to the server and most likely 'seqno'
|
||||||
|
* would remain the same. And the above 'Wait for update'
|
||||||
|
* for loop poll_block() would never return.
|
||||||
|
* So set seqno to 0. */
|
||||||
|
seqno = 0;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
struct json *json = parse_json(arg);
|
struct json *json = parse_json(arg);
|
||||||
substitute_uuids(json, symtab);
|
substitute_uuids(json, symtab);
|
||||||
|
@@ -429,6 +429,14 @@ def idl_set(idl, commands, step):
|
|||||||
|
|
||||||
s = txn.insert(idl.tables["simple"])
|
s = txn.insert(idl.tables["simple"])
|
||||||
s.i = int(args[0])
|
s.i = int(args[0])
|
||||||
|
elif name == "insert_uuid":
|
||||||
|
if len(args) != 2:
|
||||||
|
sys.stderr.write('"set" command requires 2 argument\n')
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
s = txn.insert(idl.tables["simple"], new_uuid=args[0],
|
||||||
|
persist_uuid=True)
|
||||||
|
s.i = int(args[1])
|
||||||
elif name == "delete":
|
elif name == "delete":
|
||||||
if len(args) != 1:
|
if len(args) != 1:
|
||||||
sys.stderr.write('"delete" command requires 1 argument\n')
|
sys.stderr.write('"delete" command requires 1 argument\n')
|
||||||
@@ -491,7 +499,7 @@ def idl_set(idl, commands, step):
|
|||||||
print("%03d: destroy" % step)
|
print("%03d: destroy" % step)
|
||||||
sys.stdout.flush()
|
sys.stdout.flush()
|
||||||
txn.abort()
|
txn.abort()
|
||||||
return
|
return True
|
||||||
elif name == "linktest":
|
elif name == "linktest":
|
||||||
l1_0 = txn.insert(idl.tables["link1"])
|
l1_0 = txn.insert(idl.tables["link1"])
|
||||||
l1_0.i = 1
|
l1_0.i = 1
|
||||||
@@ -615,6 +623,8 @@ def idl_set(idl, commands, step):
|
|||||||
sys.stdout.write("\n")
|
sys.stdout.write("\n")
|
||||||
sys.stdout.flush()
|
sys.stdout.flush()
|
||||||
|
|
||||||
|
return status != ovs.db.idl.Transaction.ERROR
|
||||||
|
|
||||||
|
|
||||||
def update_condition(idl, commands):
|
def update_condition(idl, commands):
|
||||||
commands = commands[len("condition "):].split(";")
|
commands = commands[len("condition "):].split(";")
|
||||||
@@ -748,7 +758,13 @@ def do_idl(schema_file, remote, *commands):
|
|||||||
sys.stdout.flush()
|
sys.stdout.flush()
|
||||||
step += 1
|
step += 1
|
||||||
elif not command.startswith("["):
|
elif not command.startswith("["):
|
||||||
idl_set(idl, command, step)
|
if not idl_set(idl, command, step):
|
||||||
|
# If idl_set() returns false, then no transaction
|
||||||
|
# was sent to the server and most likely seqno
|
||||||
|
# would remain the same. And the above 'Wait for update'
|
||||||
|
# for loop poller.block() would never return.
|
||||||
|
# So set seqno to 0.
|
||||||
|
seqno = 0
|
||||||
step += 1
|
step += 1
|
||||||
else:
|
else:
|
||||||
json = ovs.json.from_string(command)
|
json = ovs.json.from_string(command)
|
||||||
|
Reference in New Issue
Block a user