[network-manager-applet/nma-1-0] editor: use ifname instead of UUID in slaves' master property (rh #1083186)



commit 9cb1889b0daf3acd19fd1823201d1610291c3448
Author: Jiří Klimeš <jklimes redhat com>
Date:   Mon Mar 9 17:45:56 2015 +0100

    editor: use ifname instead of UUID in slaves' master property (rh #1083186)
    
    NetworkManager accepts both UUID and interface name in slave's master property
    (identifying master). UUID is easier to use in the editor and may be more
    appropriate for 'connection based' configurations. On the other hand, some
    users may expect master property to be rather interface name. And this is also
    the only supported option for some legacy configurations, such as initscripts
    in Red Hat based distros.
    
    We only use interface name for newly added slaves to ensure we don't change
    existing connections (which would be unexpected for users).
    
    https://bugzilla.redhat.com/show_bug.cgi?id=1083186
    (cherry picked from commit d06a73e2bb2a6a73c1de33bd7ce606225b018bcd)

 src/connection-editor/ce-page.c              |   12 ++++
 src/connection-editor/ce-page.h              |    2 +
 src/connection-editor/nm-connection-editor.c |    5 ++
 src/connection-editor/page-master.c          |   72 +++++++++++++++++++++++++-
 4 files changed, 90 insertions(+), 1 deletions(-)
---
diff --git a/src/connection-editor/ce-page.c b/src/connection-editor/ce-page.c
index bde329f..eb6dd4d 100644
--- a/src/connection-editor/ce-page.c
+++ b/src/connection-editor/ce-page.c
@@ -138,6 +138,18 @@ ce_page_validate (CEPage *self, NMConnection *connection, GError **error)
        return TRUE;
 }
 
+gboolean
+ce_page_last_update (CEPage *self, NMConnection *connection, GError **error)
+{
+       g_return_val_if_fail (CE_IS_PAGE (self), FALSE);
+       g_return_val_if_fail (NM_IS_CONNECTION (connection), FALSE);
+
+       if (CE_PAGE_GET_CLASS (self)->last_update)
+               return CE_PAGE_GET_CLASS (self)->last_update (self, connection, error);
+
+       return TRUE;
+}
+
 char **
 ce_page_get_mac_list (CEPage *self, GType device_type, const char *mac_property)
 {
diff --git a/src/connection-editor/ce-page.h b/src/connection-editor/ce-page.h
index 639beb3..4306fc8 100644
--- a/src/connection-editor/ce-page.h
+++ b/src/connection-editor/ce-page.h
@@ -83,6 +83,7 @@ typedef struct {
 
        /* Virtual functions */
        gboolean    (*validate)     (CEPage *self, NMConnection *connection, GError **error);
+       gboolean    (*last_update)  (CEPage *self, NMConnection *connection, GError **error);
 
        /* Signals */
        void        (*changed)     (CEPage *self);
@@ -105,6 +106,7 @@ GtkWidget *  ce_page_get_page (CEPage *self);
 const char * ce_page_get_title (CEPage *self);
 
 gboolean ce_page_validate (CEPage *self, NMConnection *connection, GError **error);
+gboolean ce_page_last_update (CEPage *self, NMConnection *connection, GError **error);
 
 char **ce_page_get_mac_list (CEPage *self, GType device_type, const char *mac_property);
 void ce_page_setup_mac_combo (CEPage *self, GtkComboBox *combo,
diff --git a/src/connection-editor/nm-connection-editor.c b/src/connection-editor/nm-connection-editor.c
index df463e2..fe0f08b 100644
--- a/src/connection-editor/nm-connection-editor.c
+++ b/src/connection-editor/nm-connection-editor.c
@@ -982,6 +982,7 @@ static void
 ok_button_clicked_cb (GtkWidget *widget, gpointer user_data)
 {
        NMConnectionEditor *self = NM_CONNECTION_EDITOR (user_data);
+       GSList *iter;
 
        /* If the dialog is busy waiting for authorization or something,
         * don't destroy it until authorization returns.
@@ -992,6 +993,10 @@ ok_button_clicked_cb (GtkWidget *widget, gpointer user_data)
        /* Validate one last time to ensure all pages update the connection */
        connection_editor_validate (self);
 
+       /* Perform page specific actions before the connection is saved */
+       for (iter = self->pages; iter; iter = g_slist_next (iter))
+               ce_page_last_update (CE_PAGE (iter->data), self->connection, NULL);
+
        ok_button_clicked_save_connection (self);
 }
 
diff --git a/src/connection-editor/page-master.c b/src/connection-editor/page-master.c
index 69af074..a1104ba 100644
--- a/src/connection-editor/page-master.c
+++ b/src/connection-editor/page-master.c
@@ -45,6 +45,8 @@ typedef struct {
        GtkTreeModel *connections_model;
        GtkButton *add, *edit, *delete;
 
+       GHashTable *new_slaves;  /* track whether some slave(s) were added */
+
 } CEPageMasterPrivate;
 
 enum {
@@ -113,6 +115,8 @@ dispose (GObject *object)
                } while (gtk_tree_model_iter_next (priv->connections_model, &iter));
        }
 
+       g_hash_table_destroy (priv->new_slaves);
+
        G_OBJECT_CLASS (ce_page_master_parent_class)->dispose (object);
 }
 
@@ -342,6 +346,14 @@ connections_selection_changed_cb (GtkTreeSelection *selection, gpointer user_dat
 static void
 add_response_cb (NMConnectionEditor *editor, GtkResponseType response, gpointer user_data)
 {
+       CEPageMaster *self = user_data;
+       CEPageMasterPrivate *priv = CE_PAGE_MASTER_GET_PRIVATE (self);
+       const char *uuid;
+
+       if (response == GTK_RESPONSE_OK) {
+               uuid = nm_connection_get_uuid (editor->connection);
+               g_hash_table_add (priv->new_slaves, g_strdup (uuid));
+       }
        g_object_unref (editor);
 }
 
@@ -475,6 +487,20 @@ connection_double_clicked_cb (GtkTreeView *tree_view,
 }
 
 static void
+delete_result_cb (NMRemoteConnection *connection,
+                  gboolean deleted,
+                  gpointer user_data)
+{
+       CEPageMaster *self = user_data;
+       CEPageMasterPrivate *priv = CE_PAGE_MASTER_GET_PRIVATE (self);
+
+       if (deleted) {
+               g_hash_table_remove (priv->new_slaves,
+                                    nm_connection_get_uuid (NM_CONNECTION (connection)));
+       }
+}
+
+static void
 delete_clicked (GtkButton *button, gpointer user_data)
 {
        CEPageMaster *self = user_data;
@@ -485,7 +511,7 @@ delete_clicked (GtkButton *button, gpointer user_data)
        if (!connection)
                return;
 
-       delete_connection (priv->toplevel, connection, NULL, NULL);
+       delete_connection (priv->toplevel, connection, delete_result_cb, self);
 }
 
 static void
@@ -598,9 +624,52 @@ validate (CEPage *page, NMConnection *connection, GError **error)
        return TRUE;
 }
 
+static gboolean
+last_update (CEPage *page, NMConnection *connection, GError **error)
+{
+       CEPageMaster *self = CE_PAGE_MASTER (page);
+       CEPageMasterPrivate *priv = CE_PAGE_MASTER_GET_PRIVATE (self);
+       const char *interface_name, *tmp, *uuid;
+       NMSettingConnection *s_con;
+       GtkTreeIter iter;
+
+       /* No new slave added - leave master property as it is. */
+       if (g_hash_table_size (priv->new_slaves) == 0)
+               return TRUE;
+
+       /*
+        * Set master property of all slaves to be the interface name.
+        * Even if UUID has the advantage of being stable and thus easier to use,
+        * users may prefer using interface name instead.
+       */
+       interface_name = gtk_entry_get_text (priv->interface_name);
+       if (gtk_tree_model_get_iter_first (priv->connections_model, &iter)) {
+               do {
+                       NMRemoteConnection *rcon = NULL;
+
+                       gtk_tree_model_get (priv->connections_model, &iter,
+                                           COL_CONNECTION, &rcon,
+                                           -1);
+                       tmp = nm_connection_get_interface_name (NM_CONNECTION (rcon));
+                       uuid = nm_connection_get_uuid (NM_CONNECTION (rcon));
+                       if (   g_hash_table_contains (priv->new_slaves, uuid)
+                           && g_strcmp0 (interface_name, tmp) != 0) {
+                               s_con = nm_connection_get_setting_connection (NM_CONNECTION (rcon));
+                               g_object_set (s_con, NM_SETTING_CONNECTION_MASTER, interface_name, NULL);
+                               nm_remote_connection_commit_changes_async (rcon, TRUE, NULL, NULL, NULL);
+                       }
+                       g_object_unref (rcon);
+               } while (gtk_tree_model_iter_next (priv->connections_model, &iter));
+       }
+       return TRUE;
+}
+
 static void
 ce_page_master_init (CEPageMaster *self)
 {
+       CEPageMasterPrivate *priv = CE_PAGE_MASTER_GET_PRIVATE (self);
+
+       priv->new_slaves = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
 }
 
 static void
@@ -616,6 +685,7 @@ ce_page_master_class_init (CEPageMasterClass *master_class)
        object_class->dispose = dispose;
 
        parent_class->validate = validate;
+       parent_class->last_update = last_update;
 
        /* Signals */
        signals[CREATE_CONNECTION] = 


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]