Commit c1ace1b5 authored by Jiří Klimeš's avatar Jiří Klimeš

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
parent 363ec8de
......@@ -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);
......
......@@ -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
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment