ovs-vsctl: Add --force option to database commands to override safety checks.
authorBen Pfaff <blp@nicira.com>
Wed, 27 Jan 2010 20:48:47 +0000 (12:48 -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 18f1a599211e3f2aa3efc202e80e942cdb9e9e16..4dc971cab7127f4aecf320bf140f5d0893928827 100644 (file)
@@ -472,6 +472,13 @@ as \fB{}\fR, and curly braces may be optionally enclose non-empty maps
 as well.
 .
 .ST "Database Command Syntax"
+.PP
+By default, database commands refuse to make some kinds of
+modifications that could violate database structuring constraints.  If
+you are sure that you know what you are doing, use \fB\-\-force\fR to
+override this safety measure.  Constraints that are enforced by the
+database server itself, instead of by \fBovs\-vsctl\fR, cannot be
+overridden this way.
 .
 .IP "\fBlist \fItable \fR[\fIrecord\fR]..."
 List the values of all columns of each specified \fIrecord\fR.  If no
@@ -483,23 +490,23 @@ Prints the value of each specified \fIcolumn\fR in the given
 optionally be specified, in which case the value associated with
 \fIkey\fR in the column is printed, instead of the entire map.
 .
-.IP "\fBset \fItable record column\fR[\fB:\fIkey\fR]\fB=\fIvalue\fR..."
+.IP "[\fB\-\-force\fR] \fBset \fItable record column\fR[\fB:\fIkey\fR]\fB=\fIvalue\fR..."
 Sets the value of each specified \fIcolumn\fR in the given
 \fIrecord\fR in \fItable\fR to \fIvalue\fR.  For map columns, a
 \fIkey\fR may optionally be specified, in which case the value
 associated with \fIkey\fR in that column is changed (or added, if none
 exists), instead of the entire map.
 .
-.IP "\fBadd \fItable record column \fR[\fIkey\fB=\fR]\fIvalue\fR..."
+.IP "[\fB\-\-force\fR] \fBadd \fItable record column \fR[\fIkey\fB=\fR]\fIvalue\fR..."
 Adds the specified value or key-value pair to \fIcolumn\fR in
 \fIrecord\fR in \fItable\fR.  If \fIcolumn\fR is a map, then \fIkey\fR
 is required, otherwise it is prohibited.  If \fIkey\fR already exists
 in a map column, then the current \fIvalue\fR is not replaced (use the
 \fBset\fR command to replace an existing value).
 .
-.IP "\fBremove \fItable record column \fR\fIvalue\fR..."
-.IQ "\fBremove \fItable record column \fR\fIkey\fR..."
-.IQ "\fBremove \fItable record column \fR\fIkey\fB=\fR\fIvalue\fR..."
+.IP "[\fB\-\-force\fR] \fBremove \fItable record column \fR\fIvalue\fR..."
+.IQ "[\fB\-\-force\fR] \fBremove \fItable record column \fR\fIkey\fR..."
+.IQ "[\fB\-\-force\fR] \fBremove \fItable record column \fR\fIkey\fB=\fR\fIvalue\fR..."
 Removes the specified values or key-value pairs from \fIcolumn\fR in
 \fIrecord\fR in \fItable\fR.  The first form applies to columns that
 are not maps: each specified \fIvalue\fR is removed from the column.
@@ -511,7 +518,7 @@ pair is removed only if both key and value match.
 It is not an error if the column does not contain the specified key or
 value or pair.
 .
-.IP "\fBclear \fItable record column\fR..."
+.IP "\fB[\fB\-\-force\fR] \fBclear\fR \fItable record column\fR..."
 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.
index f4b2c25afbf3f7557a259d0c34d1f3569731a649..18d7e083fa740de326300de76ca0d379b0784789 100644 (file)
@@ -2121,6 +2121,7 @@ check_constraint(const struct ovsdb_datum *datum,
 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;
@@ -2138,7 +2139,7 @@ cmd_set(struct vsctl_context *ctx)
         error = parse_column_key_value(ctx->argv[i], table,
                                        &column, &key_string, &value_string);
         die_if_error(error);
-        if (column->flags & VSCF_READONLY) {
+        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);
         }
@@ -2175,7 +2176,10 @@ cmd_set(struct vsctl_context *ctx)
 
             die_if_error(ovsdb_datum_from_string(&datum, &column->idl->type,
                                                  value_string));
-            check_constraint(&datum, &column->idl->type, column->constraint);
+            if (!force) {
+                check_constraint(&datum, &column->idl->type,
+                                 column->constraint);
+            }
             ovsdb_idl_txn_write(row, column->idl, &datum);
         }
         ds_put_char(out, '\n');
@@ -2187,6 +2191,7 @@ cmd_set(struct vsctl_context *ctx)
 static void
 cmd_add(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 char *column_name = ctx->argv[3];
@@ -2206,7 +2211,7 @@ cmd_add(struct vsctl_context *ctx)
         struct ovsdb_type add_type;
         struct ovsdb_datum add;
 
-        if (column->flags & VSCF_READONLY) {
+        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);
         }
@@ -2231,6 +2236,7 @@ cmd_add(struct vsctl_context *ctx)
 static void
 cmd_remove(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 char *column_name = ctx->argv[3];
@@ -2251,7 +2257,7 @@ cmd_remove(struct vsctl_context *ctx)
         struct ovsdb_datum rm;
         char *error;
 
-        if (column->flags & VSCF_READONLY) {
+        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);
         }
@@ -2281,6 +2287,7 @@ cmd_remove(struct vsctl_context *ctx)
 static void
 cmd_clear(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;
@@ -2297,7 +2304,7 @@ cmd_clear(struct vsctl_context *ctx)
         die_if_error(get_column(table, ctx->argv[i], &column));
 
         type = &column->idl->type;
-        if (column->flags & VSCF_READONLY) {
+        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);
         } else if (type->n_min > 0) {
@@ -2518,10 +2525,11 @@ get_vsctl_handler(int argc, char *argv[], struct vsctl_context *ctx)
         /* Parameter commands. */
         {"get", 3, INT_MAX, cmd_get, ""},
         {"list", 1, INT_MAX, cmd_list, ""},
-        {"set", 3, INT_MAX, cmd_set, ""},
-        {"add", 4, INT_MAX, cmd_add, ""},
-        {"remove", 4, INT_MAX, cmd_remove, ""},
-        {"clear", 3, INT_MAX, cmd_clear, ""},
+        {"set", 3, INT_MAX, cmd_set, "--force"},
+        {"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"},
     };
 
     const struct vsctl_command *p;