summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Haller <thaller@redhat.com>2019-04-12 16:08:54 +0200
committerThomas Haller <thaller@redhat.com>2019-04-15 20:50:50 +0200
commit68bd018a88b4696608ce141d2d0d8576bd148ce8 (patch)
tree3e1590edee993742667de92f48b83a852a9cbeff
parent87d16e935c91fb36727332dacd27e334f1db972c (diff)
downloadNetworkManager-68bd018a88b4696608ce141d2d0d8576bd148ce8.tar.gz
cli: prefer matching connections by "uuid" instead of "id"
Scripts should refer to connections by UUID. That means, whenever a UUID matches, that is really what the user wants. The specifier "uuid" must have precedence over "id" (and all others). That means, we must search all connections. For example: $ UUIDS=($(nmcli -g TYPE,UUID connection show | sed -n 's/802-11-wireless://p')) $ nmcli -f connection.id,connection.uuid connection show "${UUIDS[@]}" in this case we must preferrably match by UUID, regardless of whether a "connection.id" exists. Note that if you have: $ nmcli connection show | grep fdf7b2d2-2858-3938-9b14-7f1b514a9a00 b fdf7b2d2-2858-3938-9b14-7f1b514a9a00 ethernet -- fdf7b2d2-2858-3938-9b14-7f1b514a9a00 ab9f3891-3420-335e-89da-f14c1b94c540 ethernet -- then certain commands will still select all matching connections: $ nmcli -f connection.id,connection.uuid --mode multiline connection show fdf7b2d2-2858-3938-9b14-7f1b514a9a00 connection.id: fdf7b2d2-2858-3938-9b14-7f1b514a9a00 connection.uuid: ab9f3891-3420-335e-89da-f14c1b94c540 connection.id: b connection.uuid: fdf7b2d2-2858-3938-9b14-7f1b514a9a00 This only makes a difference for commands that must pick only one profile: $ nmcli connection modify fdf7b2d2-2858-3938-9b14-7f1b514a9a00 con-name new-name
-rw-r--r--clients/cli/common.c78
1 files changed, 51 insertions, 27 deletions
diff --git a/clients/cli/common.c b/clients/cli/common.c
index cb75e345f6..d94dbd0ba0 100644
--- a/clients/cli/common.c
+++ b/clients/cli/common.c
@@ -425,35 +425,37 @@ nmc_find_connection (const GPtrArray *connections,
GPtrArray **out_result,
gboolean complete)
{
- NMConnection *connection;
+ NMConnection *best_candidate_uuid = NULL;
NMConnection *best_candidate = NULL;
+ gs_unref_ptrarray GPtrArray *result_allocated = NULL;
GPtrArray *result = out_result ? *out_result : NULL;
+ const guint result_inital_len = result ? result->len : 0u;
guint i, j;
nm_assert (connections);
nm_assert (filter_val);
for (i = 0; i < connections->len; i++) {
- const char *v, *v_num;
+ gboolean match_by_uuid = FALSE;
+ NMConnection *connection;
+ const char *v;
+ const char *v_num;
connection = NM_CONNECTION (connections->pdata[i]);
- /* When filter_type is NULL, compare connection ID (filter_val)
- * against all types. Otherwise, only compare against the specific
- * type. If 'path' filter type is specified, comparison against
- * numeric index (in addition to the whole path) is allowed.
- */
- if (NM_IN_STRSET (filter_type, NULL, "id")) {
- v = nm_connection_get_id (connection);
- if (complete)
+ if (NM_IN_STRSET (filter_type, NULL, "uuid")) {
+ v = nm_connection_get_uuid (connection);
+ if (complete && (filter_type || *filter_val))
nmc_complete_strings (filter_val, v);
- if (nm_streq0 (filter_val, v))
+ if (nm_streq0 (filter_val, v)) {
+ match_by_uuid = TRUE;
goto found;
+ }
}
- if (NM_IN_STRSET (filter_type, NULL, "uuid")) {
- v = nm_connection_get_uuid (connection);
- if (complete && (filter_type || *filter_val))
+ if (NM_IN_STRSET (filter_type, NULL, "id")) {
+ v = nm_connection_get_id (connection);
+ if (complete)
nmc_complete_strings (filter_val, v);
if (nm_streq0 (filter_val, v))
goto found;
@@ -478,23 +480,45 @@ nmc_find_connection (const GPtrArray *connections,
}
continue;
+
found:
- if (!out_result)
- return connection;
- if (!best_candidate)
- best_candidate = connection;
- if (!result)
- result = g_ptr_array_new_with_free_func (g_object_unref);
- for (j = 0; j < result->len; j++) {
- if (connection == result->pdata[j])
- break;
+ if (match_by_uuid) {
+ if ( !complete
+ && !out_result)
+ return connection;
+ best_candidate_uuid = connection;
+ } else {
+ if (!best_candidate)
+ best_candidate = connection;
+ }
+ if (out_result) {
+ gboolean already_tracked = FALSE;
+
+ if (!result) {
+ result_allocated = g_ptr_array_new_with_free_func (g_object_unref);
+ result = result_allocated;
+ } else {
+ for (j = 0; j < result->len; j++) {
+ if (connection == result->pdata[j]) {
+ already_tracked = TRUE;
+ break;
+ }
+ }
+ }
+ if (!already_tracked) {
+ if (match_by_uuid) {
+ /* the profile is matched exactly (by UUID). We prepend it
+ * to the list of all found profiles. */
+ g_ptr_array_insert (result, result_inital_len, g_object_ref (connection));
+ } else
+ g_ptr_array_add (result, g_object_ref (connection));
+ }
}
- if (j == result->len)
- g_ptr_array_add (result, g_object_ref (connection));
}
- NM_SET_OUT (out_result, result);
- return best_candidate;
+ if (result_allocated)
+ *out_result = g_steal_pointer (&result_allocated);
+ return best_candidate_uuid ?: best_candidate;
}
NMActiveConnection *