cli: support removing items from container-type properties in 'nmcli con modify'

Synopsis:
nmcli con modify -<property>.<setting> <value>

'value' can be empty ("") to remove the whole property value value (in this
case the behaviour is the same as without '-').
Or the 'value' is an index of the item to remove, or an option name (for a few
properties that have option names, like bond.options or ethernet.s390-options).

$ nmcli con mod myeth ipv4.dns "10.0.0.55 10.0.0.66 8.8.8.8 8.8.4.4"
---> ipv4.dns: 10.0.0.55, 10.0.0.66, 8.8.8.8, 8.8.4.4
$ nmcli con mod myeth -ipv4.dns 1
---> ipv4.dns: 10.0.0.55, 8.8.8.8, 8.8.4.4

---> bond.options: mode=balance-rr
$ nmcli con mod bond0 +bond.options "mii=500, downdelay=800"
---> bond.options: downdelay=800,miimon=500,mode=balance-rr
$ nmcli con mod bond0 -bond.options downdelay
---> bond.options: miimon=500,mode=balance-rr
This commit is contained in:
Jiří Klimeš 2014-02-17 12:42:17 +01:00
parent 363ec8de68
commit c1ace1b5b2
2 changed files with 51 additions and 18 deletions

View file

@ -268,7 +268,7 @@ usage (void)
#endif
" down [id | uuid | path | apath] <ID>\n\n"
" add COMMON_OPTIONS TYPE_SPECIFIC_OPTIONS IP_OPTIONS\n\n"
" modify [--temporary] [id | uuid | path] <ID> ([+]<setting>.<property> <value>)+\n\n"
" modify [--temporary] [id | uuid | path] <ID> ([+|-]<setting>.<property> <value>)+\n\n"
" edit [id | uuid | path] <ID>\n"
" edit [type <new_con_type>] [con-name <new_con_name>]\n\n"
" delete [id | uuid | path] <ID>\n\n"
@ -416,17 +416,21 @@ usage_connection_modify (void)
fprintf (stderr,
_("Usage: nmcli connection modify { ARGUMENTS | help }\n"
"\n"
"ARGUMENTS := [id | uuid | path] <ID> ([+]<setting>.<property> <value>)+\n"
"ARGUMENTS := [id | uuid | path] <ID> ([+|-]<setting>.<property> <value>)+\n"
"\n"
"Modify one or more properties of the connection profile.\n"
"The profile is identified by its name, UUID or D-Bus path. The optional '+'\n"
"sign before the property instruct nmcli to append the value instead of \n"
"overwriting it.\n"
"The profile is identified by its name, UUID or D-Bus path. For multi-value\n"
"properties you can use optional '+' or '-' prefix to the property name.\n"
"The '+' sign instructs nmcli to append the value instead of overwriting it.\n"
"The '-' sign allows removing selected items instead of the whole value.\n"
"\n"
"Examples:\n"
"nmcli con mod home-wifi wifi.ssid rakosnicek\n"
"nmcli con mod em1-1 ipv4.method manual ipv4.addr \"192.168.1.2/24, 10.10.1.5/8\"\n"
"nmcli con mod em1-1 +ipv4.dns 8.8.4.4\n\n"));
"nmcli con mod em1-1 +ipv4.dns 8.8.4.4\n"
"nmcli con mod em1-1 -ipv4.dns 1\n"
"nmcli con mod bond0 +bond.options mii=500\n"
"nmcli con mod bond0 -bond.options downdelay\n\n"));
}
static void
@ -7850,6 +7854,7 @@ do_connection_modify (NmCli *nmc,
const char *setting_name;
char *property_name = NULL;
gboolean append = FALSE;
gboolean remove = FALSE;
GError *error = NULL;
nmc->should_wait = FALSE;
@ -7934,6 +7939,9 @@ do_connection_modify (NmCli *nmc,
if (s_dot_p[0] == '+') {
s_dot_p++;
append = TRUE;
} else if (s_dot_p[0] == '-') {
s_dot_p++;
remove = TRUE;
}
strv = g_strsplit (s_dot_p, ".", 2);
@ -7973,13 +7981,36 @@ do_connection_modify (NmCli *nmc,
goto finish;
}
if (!append)
nmc_setting_reset_property (setting, property_name, NULL);
if (!nmc_setting_set_property (setting, property_name, value, &error)) {
g_string_printf (nmc->return_text, _("Error: failed to modify %s.%s: %s."),
strv[0], strv[1], error->message);
nmc->return_value = NMC_RESULT_ERROR_USER_INPUT;
goto finish;
if (!remove) {
/* Set/add value */
if (!append)
nmc_setting_reset_property (setting, property_name, NULL);
if (!nmc_setting_set_property (setting, property_name, value, &error)) {
g_string_printf (nmc->return_text, _("Error: failed to modify %s.%s: %s."),
strv[0], strv[1], error->message);
nmc->return_value = NMC_RESULT_ERROR_USER_INPUT;
goto finish;
}
} else {
/* Remove value
* - either empty: remove whole value
* - or specified by index <0-n>: remove item at the index
* - or option name: remove item with the option name
*/
if (value) {
unsigned long idx;
if (nmc_string_to_uint (value, TRUE, 0, G_MAXUINT32, &idx))
nmc_setting_remove_property_option (setting, property_name, NULL, idx, &error);
else
nmc_setting_remove_property_option (setting, property_name, value, 0, &error);
if (error) {
g_string_printf (nmc->return_text, _("Error: failed to remove a value from %s.%s: %s."),
strv[0], strv[1], error->message);
nmc->return_value = NMC_RESULT_ERROR_USER_INPUT;
goto finish;
}
} else
nmc_setting_reset_property (setting, property_name, NULL);
}
g_strfreev (strv);

View file

@ -619,8 +619,8 @@ See also \fInm-settings\fP(5) for all NetworkManager settings and property names
descriptions; and \fInmcli-examples\fP(5) for sample editor sessions.
.RE
.TP
.B modify [--temporary] [ id | uuid | path ] <ID> [+]<setting>.<property> <value>
.B [+]<setting>.<property> <value> ...
.B modify [--temporary] [ id | uuid | path ] <ID> [+|-]<setting>.<property> <value>
.B [+|-]<setting>.<property> <value> ...
.br
Modify one or more properties in the connection profile.
.br
@ -632,10 +632,12 @@ and \fIproperty name\fP provided they are unique. Empty \fIvalue\fP ("")
removes the property value (sets the property to the default value).
The provided value overwrite the existing property value. If you want to
append to the existing value instead, use \fI+\fP prefix for the property name.
But it only has a real effect for multi-value (container) properties like ipv4.dns,
ipv4.addresses, etc.
If you want to remove just one item from container-type property, use \fI-\fP
prefix for the property name and specify its index (or option name) as
\fIvalue\fP. Of course, it only has a real effect for multi-value (container)
properties like ipv4.dns, ipv4.addresses, bond.options, etc.
.br
The changed values will be saved persistently by NetworkManager, unless
The changes will be saved persistently by NetworkManager, unless
\fI--temporary\fP option is provided, in which case the changes won't persist
over NetworkManager restart.
.TP