ovs-vsctl: Add new "create" command.
authorBen Pfaff <blp@nicira.com>
Wed, 27 Jan 2010 21:19:46 +0000 (13:19 -0800)
committerBen Pfaff <blp@nicira.com>
Wed, 27 Jan 2010 21:51:52 +0000 (13:51 -0800)
utilities/ovs-vsctl.8.in
utilities/ovs-vsctl.c

index 4dc971c..d50a752 100644 (file)
@@ -523,6 +523,12 @@ Sets each \fIcolumn\fR in \fIrecord\fR in \fItable\fR to the empty set
 or empty map, as appropriate.  This command applies only to columns
 that are allowed to be empty.
 .
+.IP "\fB\-\-force create \fItable column\fR[\fB:\fIkey\fR]\fB=\fIvalue\fR..."
+Creates a new record in \fItable\fR and sets the initial values of
+each \fIcolumn\fR.  Columns not explicitly set will receive their
+default values.
+.IP
+This command requires the \fB\-\-force\fR option.
 .SH "EXAMPLES"
 Create a new bridge named br0 and add port eth0 to it:
 .IP
index 18d7e08..a9a8950 100644 (file)
@@ -1855,7 +1855,7 @@ parse_column_key_value(const char *arg, const struct vsctl_table_class *table,
     if (columnp) {
         char *column_name;
 
-        error = ovsdb_token_parse(&arg, &column_name);
+        error = ovsdb_token_parse(&p, &column_name);
         if (error) {
             goto error;
         }
@@ -2119,72 +2119,78 @@ check_constraint(const struct ovsdb_datum *datum,
 }
 
 static void
-cmd_set(struct vsctl_context *ctx)
+set_column(const struct vsctl_table_class *table,
+           const struct ovsdb_idl_row *row,
+           const char *arg, bool force)
 {
-    bool force = shash_find(&ctx->options, "--force");
-    const char *table_name = ctx->argv[1];
-    const char *record_id = ctx->argv[2];
-    const struct vsctl_table_class *table;
-    const struct ovsdb_idl_row *row;
-    struct ds *out = &ctx->output;
-    int i;
+    const struct vsctl_column *column;
+    char *key_string, *value_string;
+    char *error;
 
-    table = get_table(table_name);
-    row = get_row(ctx, table, record_id);
-    for (i = 3; i < ctx->argc; i++) {
-        const struct vsctl_column *column;
-        char *key_string, *value_string;
-        char *error;
+    error = parse_column_key_value(arg, table, &column, &key_string,
+                                   &value_string);
+    die_if_error(error);
+    if (column->flags & VSCF_READONLY && !force) {
+        ovs_fatal(0, "%s: cannot modify read-only column %s in table %s",
+                  arg, column->idl->name, table->class->name);
+    }
+    if (!value_string) {
+        ovs_fatal(0, "%s: missing value", arg);
+    }
 
-        error = parse_column_key_value(ctx->argv[i], table,
-                                       &column, &key_string, &value_string);
-        die_if_error(error);
-        if (column->flags & VSCF_READONLY && !force) {
-            ovs_fatal(0, "%s: cannot modify read-only column %s in table %s",
-                      ctx->argv[i], column->idl->name, table_name);
-        }
-        if (!value_string) {
-            ovs_fatal(0, "%s: missing value", ctx->argv[i]);
+    if (key_string) {
+        union ovsdb_atom key, value;
+        struct ovsdb_datum old, new;
+
+        if (column->idl->type.value_type == OVSDB_TYPE_VOID) {
+            ovs_fatal(0, "cannot specify key to set for non-map column %s",
+                      column->idl->name);
         }
 
-        if (key_string) {
-            union ovsdb_atom key, value;
-            struct ovsdb_datum old, new;
+        die_if_error(ovsdb_atom_from_string(&key,
+                                            column->idl->type.key_type,
+                                            key_string));
+        die_if_error(ovsdb_atom_from_string(&value,
+                                            column->idl->type.value_type,
+                                            value_string));
 
-            if (column->idl->type.value_type == OVSDB_TYPE_VOID) {
-                ovs_fatal(0, "cannot specify key to set for non-map column %s",
-                          column->idl->name);
-            }
+        ovsdb_datum_init_empty(&new);
+        ovsdb_datum_add_unsafe(&new, &key, &value, &column->idl->type);
 
-            die_if_error(ovsdb_atom_from_string(&key,
-                                                column->idl->type.key_type,
-                                                key_string));
-            die_if_error(ovsdb_atom_from_string(&value,
-                                                column->idl->type.value_type,
-                                                value_string));
+        ovsdb_idl_txn_read(row, column->idl, &old);
+        ovsdb_datum_union(&old, &new, &column->idl->type, true);
+        ovsdb_idl_txn_write(row, column->idl, &old);
 
-            ovsdb_datum_init_empty(&new);
-            ovsdb_datum_add_unsafe(&new, &key, &value, &column->idl->type);
+        ovsdb_datum_destroy(&new, &column->idl->type);
+    } else {
+        struct ovsdb_datum datum;
 
-            ovsdb_idl_txn_read(row, column->idl, &old);
-            ovsdb_datum_union(&old, &new, &column->idl->type, true);
-            ovsdb_idl_txn_write(row, column->idl, &old);
+        die_if_error(ovsdb_datum_from_string(&datum, &column->idl->type,
+                                             value_string));
+        if (!force) {
+            check_constraint(&datum, &column->idl->type,
+                             column->constraint);
+        }
+        ovsdb_idl_txn_write(row, column->idl, &datum);
+    }
 
-            ovsdb_datum_destroy(&new, &column->idl->type);
-        } else {
-            struct ovsdb_datum datum;
+    free(key_string);
+}
 
-            die_if_error(ovsdb_datum_from_string(&datum, &column->idl->type,
-                                                 value_string));
-            if (!force) {
-                check_constraint(&datum, &column->idl->type,
-                                 column->constraint);
-            }
-            ovsdb_idl_txn_write(row, column->idl, &datum);
-        }
-        ds_put_char(out, '\n');
+static void
+cmd_set(struct vsctl_context *ctx)
+{
+    bool force = shash_find(&ctx->options, "--force");
+    const char *table_name = ctx->argv[1];
+    const char *record_id = ctx->argv[2];
+    const struct vsctl_table_class *table;
+    const struct ovsdb_idl_row *row;
+    int i;
 
-        free(key_string);
+    table = get_table(table_name);
+    row = get_row(ctx, table, record_id);
+    for (i = 3; i < ctx->argc; i++) {
+        set_column(table, row, ctx->argv[i], force);
     }
 }
 
@@ -2317,6 +2323,26 @@ cmd_clear(struct vsctl_context *ctx)
         ovsdb_idl_txn_write(row, column->idl, &datum);
     }
 }
+
+static void
+cmd_create(struct vsctl_context *ctx)
+{
+    bool force = shash_find(&ctx->options, "--force");
+    const char *table_name = ctx->argv[1];
+    const struct vsctl_table_class *table;
+    const struct ovsdb_idl_row *row;
+    int i;
+
+    if (!force) {
+        ovs_fatal(0, "\"create\" requires --force");
+    }
+
+    table = get_table(table_name);
+    row = ovsdb_idl_txn_insert(txn_from_openvswitch(ctx->ovs), table->class);
+    for (i = 2; i < ctx->argc; i++) {
+        set_column(table, row, ctx->argv[i], force);
+    }
+}
 \f
 typedef void vsctl_handler_func(struct vsctl_context *);
 
@@ -2529,7 +2555,7 @@ get_vsctl_handler(int argc, char *argv[], struct vsctl_context *ctx)
         {"add", 4, INT_MAX, cmd_add, "--force"},
         {"remove", 4, INT_MAX, cmd_remove, "--force"},
         {"clear", 3, INT_MAX, cmd_clear, "--force"},
-        {"create", 1, INT_MAX, cmd_create, "--force"},
+        {"create", 2, INT_MAX, cmd_create, "--force"},
     };
 
     const struct vsctl_command *p;