[gnome-disk-utility/wip/iscsi] Add back iSCSI bits
- From: David Zeuthen <davidz src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-disk-utility/wip/iscsi] Add back iSCSI bits
- Date: Tue, 28 Feb 2012 14:58:07 +0000 (UTC)
commit fc2a233964da35798c332179929736e10df7ab9e
Author: David Zeuthen <davidz redhat com>
Date: Tue Feb 28 09:57:54 2012 -0500
Add back iSCSI bits
Signed-off-by: David Zeuthen <davidz redhat com>
data/ui/palimpsest.ui | 331 +++++++++++++++++++++++++++++-
src/palimpsest/Makefile.am | 1 +
src/palimpsest/gdudevicetreemodel.c | 279 +++++++++++++++++++++++++-
src/palimpsest/gduiscsipathmodel.c | 325 +++++++++++++++++++++++++++++
src/palimpsest/gduiscsipathmodel.h | 55 +++++
src/palimpsest/gdutypes.h | 3 +
src/palimpsest/gduwindow.c | 386 +++++++++++++++++++++++++++++++++++
7 files changed, 1373 insertions(+), 7 deletions(-)
---
diff --git a/data/ui/palimpsest.ui b/data/ui/palimpsest.ui
index 4d45b79..5b72446 100644
--- a/data/ui/palimpsest.ui
+++ b/data/ui/palimpsest.ui
@@ -1162,17 +1162,316 @@
</packing>
</child>
<child>
- <object class="GtkVBox" id="newtab_vbox">
+ <object class="GtkVBox" id="iscsitab_vbox">
<property name="visible">True</property>
<property name="can_focus">False</property>
+ <property name="spacing">12</property>
<child>
- <placeholder/>
+ <object class="GtkTable" id="iscsitab-table">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="n_rows">2</property>
+ <property name="n_columns">2</property>
+ <property name="column_spacing">12</property>
+ <child>
+ <object class="GtkLabel" id="iscsitab-name-label">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="xalign">1</property>
+ <property name="label" translatable="yes">Target Name</property>
+ <style>
+ <class name="dim-label"/>
+ </style>
+ </object>
+ <packing>
+ <property name="top_attach">0</property>
+ <property name="bottom_attach">1</property>
+ <property name="x_options">GTK_FILL</property>
+ <property name="y_options"></property>
+ <property name="y_padding">4</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="iscsitab-name-value-label">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="xalign">0</property>
+ <property name="selectable">True</property>
+ <property name="ellipsize">end</property>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
+ <property name="top_attach">0</property>
+ <property name="bottom_attach">1</property>
+ <property name="x_options">GTK_FILL</property>
+ <property name="y_options"></property>
+ <property name="y_padding">4</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="iscsitab-discovery-label">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="xalign">1</property>
+ <property name="label" translatable="yes">Discovery</property>
+ <style>
+ <class name="dim-label"/>
+ </style>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="right_attach">1</property>
+ <property name="top_attach">1</property>
+ <property name="bottom_attach">2</property>
+ <property name="x_options">GTK_FILL</property>
+ <property name="y_options"></property>
+ <property name="y_padding">4</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="iscsitab-discovery-value-label">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="xalign">0</property>
+ <property name="selectable">True</property>
+ <property name="ellipsize">end</property>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
+ <property name="top_attach">1</property>
+ <property name="bottom_attach">2</property>
+ <property name="x_options">GTK_FILL</property>
+ <property name="y_options"></property>
+ <property name="y_padding">4</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
</child>
<child>
- <placeholder/>
+ <object class="GtkLabel" id="iscsitab-main-label">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes"><b>_Connections</b></property>
+ <property name="use_markup">True</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">iscsi-connections-treeview</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
</child>
<child>
- <placeholder/>
+ <object class="GtkAlignment" id="alignment2">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="left_padding">24</property>
+ <child>
+ <object class="GtkVBox" id="vbox2">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <child>
+ <object class="GtkScrolledWindow" id="iscsitab-scrolledwindow">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="hscrollbar_policy">never</property>
+ <property name="shadow_type">in</property>
+ <child>
+ <object class="GtkTreeView" id="iscsi-connections-treeview">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="show_expanders">False</property>
+ <property name="level_indentation">12</property>
+ <child internal-child="selection">
+ <object class="GtkTreeSelection" id="iscsi-treeview-selection"/>
+ </child>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkToolbar" id="iscsitab-toolbar">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="icon_size">1</property>
+ <child>
+ <object class="GtkToolButton" id="iscsitab-configure-toolbutton">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="use_action_appearance">False</property>
+ <property name="icon_name">system-run-symbolic</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="homogeneous">True</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+
+ <child>
+ <object class="GtkTable" id="iscsitab-connection-table">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="n_rows">2</property>
+ <property name="n_columns">2</property>
+ <property name="column_spacing">12</property>
+
+ <child>
+ <object class="GtkLabel" id="iscsitab-connection-startup-label">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="xalign">1</property>
+ <property name="label" translatable="yes">Startup</property>
+ <style>
+ <class name="dim-label"/>
+ </style>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="right_attach">1</property>
+ <property name="top_attach">0</property>
+ <property name="bottom_attach">1</property>
+ <property name="x_options">GTK_FILL</property>
+ <property name="y_options"></property>
+ <property name="y_padding">4</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="iscsitab-connection-startup-value-label">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="xalign">0</property>
+ <property name="selectable">True</property>
+ <property name="ellipsize">end</property>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
+ <property name="top_attach">0</property>
+ <property name="bottom_attach">1</property>
+ <property name="x_options">GTK_FILL</property>
+ <property name="y_options"></property>
+ <property name="y_padding">4</property>
+ </packing>
+ </child>
+
+ <child>
+ <object class="GtkLabel" id="iscsitab-connection-timeout-label">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="xalign">1</property>
+ <property name="label" translatable="yes">Timeout</property>
+ <style>
+ <class name="dim-label"/>
+ </style>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="right_attach">1</property>
+ <property name="top_attach">1</property>
+ <property name="bottom_attach">2</property>
+ <property name="x_options">GTK_FILL</property>
+ <property name="y_options"></property>
+ <property name="y_padding">4</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="iscsitab-connection-timeout-value-label">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="xalign">0</property>
+ <property name="selectable">True</property>
+ <property name="ellipsize">end</property>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
+ <property name="top_attach">1</property>
+ <property name="bottom_attach">2</property>
+ <property name="x_options">GTK_FILL</property>
+ <property name="y_options"></property>
+ <property name="y_padding">4</property>
+ </packing>
+ </child>
+
+ <child>
+ <object class="GtkLabel" id="iscsitab-connection-auth-label">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="xalign">1</property>
+ <property name="label" translatable="yes">Authentication</property>
+ <style>
+ <class name="dim-label"/>
+ </style>
+ </object>
+ <packing>
+ <property name="top_attach">2</property>
+ <property name="bottom_attach">3</property>
+ <property name="x_options">GTK_FILL</property>
+ <property name="y_options"></property>
+ <property name="y_padding">4</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="iscsitab-connection-auth-value-label">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="xalign">0</property>
+ <property name="selectable">True</property>
+ <property name="ellipsize">end</property>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
+ <property name="top_attach">2</property>
+ <property name="bottom_attach">3</property>
+ <property name="x_options">GTK_FILL</property>
+ <property name="y_options"></property>
+ <property name="y_padding">4</property>
+ </packing>
+ </child>
+
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ </object>
+
+ </child>
+ </object>
+ <packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ <property name="position">2</property>
+ </packing>
</child>
</object>
<packing>
@@ -1180,10 +1479,10 @@
</packing>
</child>
<child type="tab">
- <object class="GtkLabel" id="newtab_label">
+ <object class="GtkLabel" id="iscsitab_label">
<property name="visible">True</property>
<property name="can_focus">False</property>
- <property name="label">new</property>
+ <property name="label" translatable="yes">iscsi target</property>
</object>
<packing>
<property name="position">3</property>
@@ -1191,6 +1490,26 @@
</packing>
</child>
<child>
+ <object class="GtkVBox" id="newtab_vbox">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ </object>
+ <packing>
+ <property name="position">4</property>
+ </packing>
+ </child>
+ <child type="tab">
+ <object class="GtkLabel" id="newtab_label">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes">new</property>
+ </object>
+ <packing>
+ <property name="position">4</property>
+ <property name="tab_fill">False</property>
+ </packing>
+ </child>
+ <child>
<placeholder/>
</child>
<child type="tab">
diff --git a/src/palimpsest/Makefile.am b/src/palimpsest/Makefile.am
index 6cfeaca..703b140 100644
--- a/src/palimpsest/Makefile.am
+++ b/src/palimpsest/Makefile.am
@@ -47,6 +47,7 @@ palimpsest_SOURCES = \
gdupasswordstrengthwidget.h gdupasswordstrengthwidget.c \
gduestimator.h gduestimator.c \
gduchangepassphrasedialog.h gduchangepassphrasedialog.c \
+ gduiscsipathmodel.h gduiscsipathmodel.c \
$(enum_built_sources) \
$(NULL)
diff --git a/src/palimpsest/gdudevicetreemodel.c b/src/palimpsest/gdudevicetreemodel.c
index f84f26b..37b7626 100644
--- a/src/palimpsest/gdudevicetreemodel.c
+++ b/src/palimpsest/gdudevicetreemodel.c
@@ -43,6 +43,10 @@ struct _GduDeviceTreeModel
GtkTreeIter block_iter;
gboolean block_iter_valid;
+ GList *current_iscsi_objects;
+ GtkTreeIter iscsi_iter;
+ gboolean iscsi_iter_valid;
+
guint spinner_timeout;
};
@@ -209,6 +213,28 @@ find_iter_for_object (GduDeviceTreeModel *model,
return data.found;
}
+static gboolean
+find_iter_for_object_path (GduDeviceTreeModel *model,
+ const gchar *object_path,
+ GtkTreeIter *out_iter)
+{
+ FindIterData data;
+
+ memset (&data, 0, sizeof (data));
+ data.object_path = object_path;
+ data.found = FALSE;
+ gtk_tree_model_foreach (GTK_TREE_MODEL (model),
+ find_iter_for_object_cb,
+ &data);
+ if (data.found)
+ {
+ if (out_iter != NULL)
+ *out_iter = data.iter;
+ }
+
+ return data.found;
+}
+
gboolean
gdu_device_tree_model_get_iter_for_object (GduDeviceTreeModel *model,
UDisksObject *object,
@@ -736,6 +762,27 @@ update_drive (GduDeviceTreeModel *model,
return jobs_running;
}
+static gboolean
+should_include_drive (UDisksObject *object,
+ gboolean allow_iscsi)
+{
+ UDisksDrive *drive;
+ gboolean ret;
+
+ ret = FALSE;
+
+ drive = udisks_object_peek_drive (object);
+
+ /* unless specificlly allowed, don't show DRIVEs paired with an iSCSI target */
+ if (!allow_iscsi && g_strcmp0 (udisks_drive_get_iscsi_target (drive), "/") != 0)
+ goto out;
+
+ ret = TRUE;
+
+ out:
+ return ret;
+}
+
static void
update_drives (GduDeviceTreeModel *model)
{
@@ -759,7 +806,8 @@ update_drives (GduDeviceTreeModel *model)
if (drive == NULL)
continue;
- drives = g_list_prepend (drives, g_object_ref (object));
+ if (should_include_drive (object, FALSE))
+ drives = g_list_prepend (drives, g_object_ref (object));
}
drives = g_list_sort (drives, (GCompareFunc) _g_dbus_object_compare);
@@ -1115,12 +1163,241 @@ update_blocks (GduDeviceTreeModel *model)
/* ---------------------------------------------------------------------------------------------------- */
+static GtkTreeIter *
+get_iscsi_iter (GduDeviceTreeModel *model)
+{
+ gchar *s;
+
+ if (model->iscsi_iter_valid)
+ goto out;
+
+ /* TODO: once https://bugzilla.gnome.org/show_bug.cgi?id=657194 is resolved, use that instead
+ * of hard-coding the color
+ */
+ s = g_strdup_printf ("<small><span foreground=\"#555555\">%s</span></small>",
+ _("iSCSI Targets"));
+ gtk_tree_store_insert_with_values (GTK_TREE_STORE (model),
+ &model->iscsi_iter,
+ NULL, /* GtkTreeIter *parent */
+ 0,
+ GDU_DEVICE_TREE_MODEL_COLUMN_IS_HEADING, TRUE,
+ GDU_DEVICE_TREE_MODEL_COLUMN_HEADING_TEXT, s,
+ GDU_DEVICE_TREE_MODEL_COLUMN_SORT_KEY, "02_iscsi",
+ -1);
+ g_free (s);
+
+ model->iscsi_iter_valid = TRUE;
+
+ out:
+ return &model->iscsi_iter;
+}
+
+static void
+nuke_iscsi_iter (GduDeviceTreeModel *model)
+{
+ if (model->iscsi_iter_valid)
+ {
+ gtk_tree_store_remove (GTK_TREE_STORE (model), &model->iscsi_iter);
+ model->iscsi_iter_valid = FALSE;
+ }
+}
+
+static void
+add_iscsi_target (GduDeviceTreeModel *model,
+ UDisksObject *object,
+ GtkTreeIter *parent)
+{
+ UDisksiSCSITarget *target;
+ GIcon *icon;
+ gchar *s;
+ gchar *sort_key;
+ GtkTreeIter iter;
+
+ target = udisks_object_peek_iscsi_target (object);
+
+#if 0
+ GIcon *base_icon;
+ GIcon *emblem_icon;
+ GEmblem *emblem;
+ emblem_icon = g_themed_icon_new_with_default_fallbacks ("emblem-web");
+ emblem = g_emblem_new (emblem_icon);
+ base_icon = g_themed_icon_new_with_default_fallbacks ("drive-harddisk");
+ icon = g_emblemed_icon_new (base_icon, emblem);
+ g_object_unref (emblem);
+ g_object_unref (base_icon);
+ g_object_unref (emblem_icon);
+#endif
+ icon = g_themed_icon_new_with_default_fallbacks ("network-server");
+
+ s = g_strdup_printf ("%s\n"
+ "<small><span foreground=\"#555555\">%s</span></small>",
+ "iSCSI Target", /* TODO: alias */
+ udisks_iscsi_target_get_name (target));
+
+ sort_key = g_strdup (g_dbus_object_get_object_path (G_DBUS_OBJECT (object))); /* for now */
+ gtk_tree_store_insert_with_values (GTK_TREE_STORE (model),
+ &iter,
+ parent,
+ 0,
+ GDU_DEVICE_TREE_MODEL_COLUMN_ICON, icon,
+ GDU_DEVICE_TREE_MODEL_COLUMN_NAME, s,
+ GDU_DEVICE_TREE_MODEL_COLUMN_SORT_KEY, sort_key,
+ GDU_DEVICE_TREE_MODEL_COLUMN_OBJECT, object,
+ -1);
+ g_object_unref (icon);
+ g_free (sort_key);
+ g_free (s);
+}
+
+static void
+remove_iscsi_target (GduDeviceTreeModel *model,
+ UDisksObject *object)
+{
+ GtkTreeIter iter;
+ if (!find_iter_for_object (model,
+ object,
+ &iter))
+ {
+ g_warning ("Error finding iter for object at %s",
+ g_dbus_object_get_object_path (G_DBUS_OBJECT (object)));
+ goto out;
+ }
+ gtk_tree_store_remove (GTK_TREE_STORE (model), &iter);
+
+ out:
+ ;
+}
+
+static void
+update_iscsi_targets (GduDeviceTreeModel *model)
+{
+ GDBusObjectManager *object_manager;
+ GList *objects;
+ GList *iscsi_objects;
+ GList *added;
+ GList *removed;
+ GList *l;
+
+ object_manager = udisks_client_get_object_manager (model->client);
+ objects = g_dbus_object_manager_get_objects (object_manager);
+
+ iscsi_objects = NULL;
+ for (l = objects; l != NULL; l = l->next)
+ {
+ UDisksObject *object = UDISKS_OBJECT (l->data);
+ UDisksiSCSITarget *target;
+ target = udisks_object_peek_iscsi_target (object);
+ if (target != NULL)
+ {
+ GList *ll;
+ const gchar *target_object_path;
+
+ iscsi_objects = g_list_prepend (iscsi_objects, g_object_ref (object));
+
+ /* also include the drives that are associated with this target */
+ target_object_path = g_dbus_object_get_object_path (G_DBUS_OBJECT (object));
+ for (ll = objects; ll != NULL; ll = ll->next)
+ {
+ UDisksObject *drive_object = UDISKS_OBJECT (ll->data);
+ UDisksDrive *drive;
+ drive = udisks_object_peek_drive (drive_object);
+ if (drive != NULL)
+ {
+ if (g_strcmp0 (udisks_drive_get_iscsi_target (drive), target_object_path) == 0)
+ {
+ if (should_include_drive (drive_object, TRUE))
+ iscsi_objects = g_list_prepend (iscsi_objects, g_object_ref (drive_object));
+ }
+ }
+ }
+ }
+ }
+
+ iscsi_objects = g_list_sort (iscsi_objects, (GCompareFunc) _g_dbus_object_compare);
+ model->current_iscsi_objects = g_list_sort (model->current_iscsi_objects, (GCompareFunc) _g_dbus_object_compare);
+ diff_sorted_lists (model->current_iscsi_objects,
+ iscsi_objects,
+ (GCompareFunc) _g_dbus_object_compare,
+ &added,
+ &removed);
+
+ for (l = removed; l != NULL; l = l->next)
+ {
+ UDisksObject *object = UDISKS_OBJECT (l->data);
+
+ g_assert (g_list_find (model->current_iscsi_objects, object) != NULL);
+
+ model->current_iscsi_objects = g_list_remove (model->current_iscsi_objects, object);
+ if (udisks_object_peek_iscsi_target (object) != NULL)
+ {
+ remove_iscsi_target (model, object);
+ }
+ else if (udisks_object_peek_drive (object) != NULL)
+ {
+ remove_drive (model, object);
+ }
+ g_object_unref (object);
+ }
+
+ /* Add targets */
+ for (l = added; l != NULL; l = l->next)
+ {
+ UDisksObject *object = UDISKS_OBJECT (l->data);
+ if (udisks_object_peek_iscsi_target (object) != NULL)
+ {
+ model->current_iscsi_objects = g_list_prepend (model->current_iscsi_objects,
+ g_object_ref (object));
+ add_iscsi_target (model, object, get_iscsi_iter (model));
+ }
+ }
+
+ /* ... then add drives */
+ for (l = added; l != NULL; l = l->next)
+ {
+ UDisksObject *object = UDISKS_OBJECT (l->data);
+ if (udisks_object_peek_drive (object) != NULL)
+ {
+ GtkTreeIter iter;
+ model->current_iscsi_objects = g_list_prepend (model->current_iscsi_objects,
+ g_object_ref (object));
+ g_warn_if_fail (find_iter_for_object_path (model,
+ udisks_drive_get_iscsi_target (udisks_object_peek_drive (object)),
+ &iter));
+ add_drive (model, object, &iter);
+ }
+ }
+
+ /* update all drives (newly added as well as the existing ones) */
+ for (l = model->current_iscsi_objects; l != NULL; l = l->next)
+ {
+ UDisksObject *object = UDISKS_OBJECT (l->data);
+ if (udisks_object_peek_drive (object) != NULL)
+ {
+ update_drive (model, object, FALSE);
+ }
+ }
+
+ if (g_list_length (model->current_iscsi_objects) == 0)
+ nuke_iscsi_iter (model);
+
+ g_list_free (added);
+ g_list_free (removed);
+ g_list_foreach (iscsi_objects, (GFunc) g_object_unref, NULL);
+ g_list_free (iscsi_objects);
+
+ g_list_foreach (objects, (GFunc) g_object_unref, NULL);
+ g_list_free (objects);
+}
+
+/* ---------------------------------------------------------------------------------------------------- */
+
static void
update_all (GduDeviceTreeModel *model)
{
/* TODO: if this is CPU intensive we could coalesce all updates / schedule timeouts */
update_drives (model);
update_blocks (model);
+ update_iscsi_targets (model);
}
static void
diff --git a/src/palimpsest/gduiscsipathmodel.c b/src/palimpsest/gduiscsipathmodel.c
new file mode 100644
index 0000000..fc62ee5
--- /dev/null
+++ b/src/palimpsest/gduiscsipathmodel.c
@@ -0,0 +1,325 @@
+/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
+ *
+ * Copyright (C) 2008-2011 Red Hat, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General
+ * Public License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Author: David Zeuthen <davidz redhat com>
+ */
+
+#include "config.h"
+#include <glib/gi18n.h>
+
+#include "gduiscsipathmodel.h"
+#include "gduutils.h"
+
+struct _GduiSCSIPathModel
+{
+ GtkListStore parent_instance;
+
+ UDisksClient *client;
+
+ UDisksiSCSITarget *iscsi_target;
+ UDisksObject *object;
+};
+
+typedef struct
+{
+ GtkListStoreClass parent_class;
+} GduiSCSIPathModelClass;
+
+enum
+{
+ PROP_0,
+ PROP_CLIENT,
+ PROP_OBJECT
+};
+
+static void update_all (GduiSCSIPathModel *model);
+static void on_notify_for_iscsi_target (GObject *object,
+ GParamSpec *pspec,
+ gpointer user_data);
+
+G_DEFINE_TYPE (GduiSCSIPathModel, gdu_iscsi_path_model, GTK_TYPE_LIST_STORE);
+
+static void
+gdu_iscsi_path_model_finalize (GObject *object)
+{
+ GduiSCSIPathModel *model = GDU_ISCSI_PATH_MODEL (object);
+
+ g_signal_handlers_disconnect_by_func (model->iscsi_target,
+ G_CALLBACK (on_notify_for_iscsi_target),
+ model);
+ g_object_unref (model->iscsi_target);
+ g_object_unref (model->client);
+
+ G_OBJECT_CLASS (gdu_iscsi_path_model_parent_class)->finalize (object);
+}
+
+static void
+gdu_iscsi_path_model_init (GduiSCSIPathModel *model)
+{
+}
+
+static void
+gdu_iscsi_path_model_get_property (GObject *object,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ GduiSCSIPathModel *model = GDU_ISCSI_PATH_MODEL (object);
+
+ switch (prop_id)
+ {
+ case PROP_CLIENT:
+ g_value_set_object (value, gdu_iscsi_path_model_get_client (model));
+ break;
+
+ case PROP_OBJECT:
+ g_value_set_object (value, gdu_iscsi_path_model_get_object (model));
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+gdu_iscsi_path_model_set_property (GObject *object,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ GduiSCSIPathModel *model = GDU_ISCSI_PATH_MODEL (object);
+
+ switch (prop_id)
+ {
+ case PROP_CLIENT:
+ model->client = g_value_dup_object (value);
+ break;
+
+ case PROP_OBJECT:
+ model->object = g_value_dup_object (value);
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+/* ---------------------------------------------------------------------------------------------------- */
+
+static void
+gdu_iscsi_path_model_constructed (GObject *object)
+{
+ GduiSCSIPathModel *model = GDU_ISCSI_PATH_MODEL (object);
+ GType types[GDU_ISCSI_PATH_MODEL_N_COLUMNS];
+ /* GDBusObjectManager *object_manager; */
+
+ model->iscsi_target = udisks_object_get_iscsi_target (model->object);
+ g_assert (model->iscsi_target != NULL);
+
+ types[0] = G_TYPE_BOOLEAN;
+ types[1] = G_TYPE_STRING;
+ types[2] = G_TYPE_INT;
+ types[3] = G_TYPE_INT;
+ types[4] = G_TYPE_STRING;
+ types[5] = G_TYPE_STRING;
+ G_STATIC_ASSERT (6 == GDU_ISCSI_PATH_MODEL_N_COLUMNS);
+ gtk_list_store_set_column_types (GTK_LIST_STORE (model),
+ GDU_ISCSI_PATH_MODEL_N_COLUMNS,
+ types);
+
+ update_all (model);
+ g_signal_connect (model->iscsi_target,
+ "notify",
+ G_CALLBACK (on_notify_for_iscsi_target),
+ model);
+
+ if (G_OBJECT_CLASS (gdu_iscsi_path_model_parent_class)->constructed != NULL)
+ G_OBJECT_CLASS (gdu_iscsi_path_model_parent_class)->constructed (object);
+}
+
+static void
+gdu_iscsi_path_model_class_init (GduiSCSIPathModelClass *klass)
+{
+ GObjectClass *gobject_class;
+
+ gobject_class = G_OBJECT_CLASS (klass);
+ gobject_class->finalize = gdu_iscsi_path_model_finalize;
+ gobject_class->constructed = gdu_iscsi_path_model_constructed;
+ gobject_class->get_property = gdu_iscsi_path_model_get_property;
+ gobject_class->set_property = gdu_iscsi_path_model_set_property;
+
+ /**
+ * GduiSCSIPathModel:client:
+ *
+ * The #UDisksClient used by the #GduiSCSIPathModel instance.
+ */
+ g_object_class_install_property (gobject_class,
+ PROP_CLIENT,
+ g_param_spec_object ("client",
+ "Client",
+ "The client used by the tree model",
+ UDISKS_TYPE_CLIENT,
+ G_PARAM_READABLE |
+ G_PARAM_WRITABLE |
+ G_PARAM_CONSTRUCT_ONLY |
+ G_PARAM_STATIC_STRINGS));
+
+ /**
+ * GduiSCSIPathModel:object:
+ *
+ * The #UDisksObject that is a iSCSI target.
+ */
+ g_object_class_install_property (gobject_class,
+ PROP_OBJECT,
+ g_param_spec_object ("object",
+ "Object",
+ "The iSCSI target",
+ UDISKS_TYPE_OBJECT,
+ G_PARAM_READABLE |
+ G_PARAM_WRITABLE |
+ G_PARAM_CONSTRUCT_ONLY |
+ G_PARAM_STATIC_STRINGS));
+}
+
+/**
+ * gdu_iscsi_path_model_new:
+ * @client: A #UDisksClient.
+ * @object: A #UDisksObject.
+ *
+ * Creates a new #GduiSCSIPathModel for viewing the paths on the iSCSI
+ * target on @object.
+ *
+ * Returns: A #GduiSCSIPathModel. Free with g_object_unref().
+ */
+GduiSCSIPathModel *
+gdu_iscsi_path_model_new (UDisksClient *client,
+ UDisksObject *object)
+{
+ return GDU_ISCSI_PATH_MODEL (g_object_new (GDU_TYPE_ISCSI_PATH_MODEL,
+ "client", client,
+ "object", object,
+ NULL));
+}
+
+/**
+ * gdu_iscsi_path_model_get_client:
+ * @model: A #GduiSCSIPathModel.
+ *
+ * Gets the #UDisksClient used by @model.
+ *
+ * Returns: (transfer none): A #UDisksClient. Do not free, the object
+ * belongs to @model.
+ */
+UDisksClient *
+gdu_iscsi_path_model_get_client (GduiSCSIPathModel *model)
+{
+ g_return_val_if_fail (GDU_IS_ISCSI_PATH_MODEL (model), NULL);
+ return model->client;
+}
+
+/**
+ * gdu_iscsi_path_model_get_object:
+ * @model: A #GduiSCSIPathModel.
+ *
+ * Gets the #UDisksObject used by @model.
+ *
+ * Returns: (transfer none): A #UDisksObject. Do not free, the object
+ * belongs to @model.
+ */
+UDisksObject *
+gdu_iscsi_path_model_get_object (GduiSCSIPathModel *model)
+{
+ g_return_val_if_fail (GDU_IS_ISCSI_PATH_MODEL (model), NULL);
+ return model->object;
+}
+
+/* ---------------------------------------------------------------------------------------------------- */
+
+static void
+update_all (GduiSCSIPathModel *model)
+{
+ GVariant *portals_and_interfaces;
+ GVariantIter portal_iter;
+ const gchar *portal_name;
+ gint port;
+ gint group;
+ const gchar *iface_name;
+ const gchar *state;
+
+ gtk_list_store_clear (GTK_LIST_STORE (model));
+
+ portals_and_interfaces = udisks_iscsi_target_get_connections (model->iscsi_target);
+ g_variant_iter_init (&portal_iter, portals_and_interfaces);
+
+ while (g_variant_iter_next (&portal_iter,
+ "(&sii&s&sa{sv})",
+ &portal_name,
+ &port,
+ &group,
+ &iface_name,
+ &state,
+ NULL)) /* expansion */
+ {
+ gchar *status;
+ gboolean active;
+ if (g_strcmp0 (state, "LOGGED_IN") == 0)
+ {
+ active = TRUE;
+ status = g_strdup (_("Logged In"));
+ }
+ else if (g_strcmp0 (state, "FAILED") == 0)
+ {
+ active = TRUE;
+ status = g_strdup_printf ("<span foreground=\"#ff0000\"><b>%s</b></span>", _("FAILED"));
+ }
+ else if (g_strcmp0 (state, "") == 0)
+ {
+ active = FALSE;
+ status = g_strdup (_("Not Logged In"));
+ }
+ else
+ {
+ active = TRUE;
+ status = g_strdup (state);
+ }
+
+ gtk_list_store_insert_with_values (GTK_LIST_STORE (model),
+ NULL, /* GtkTreeIter *out */
+ G_MAXINT, /* position */
+ GDU_ISCSI_PATH_MODEL_COLUMN_ACTIVE, active,
+ GDU_ISCSI_PATH_MODEL_COLUMN_PORTAL_ADDRESS, portal_name,
+ GDU_ISCSI_PATH_MODEL_COLUMN_PORTAL_PORT, port,
+ GDU_ISCSI_PATH_MODEL_COLUMN_TPGT, group,
+ GDU_ISCSI_PATH_MODEL_COLUMN_INTERFACE, iface_name,
+ GDU_ISCSI_PATH_MODEL_COLUMN_STATUS, status,
+ -1);
+ g_free (status);
+ }
+}
+
+static void
+on_notify_for_iscsi_target (GObject *object,
+ GParamSpec *pspec,
+ gpointer user_data)
+{
+ GduiSCSIPathModel *model = GDU_ISCSI_PATH_MODEL (user_data);
+ update_all (model);
+}
diff --git a/src/palimpsest/gduiscsipathmodel.h b/src/palimpsest/gduiscsipathmodel.h
new file mode 100644
index 0000000..938ab36
--- /dev/null
+++ b/src/palimpsest/gduiscsipathmodel.h
@@ -0,0 +1,55 @@
+/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
+ *
+ * Copyright (C) 2008-2011 Red Hat, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General
+ * Public License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Author: David Zeuthen <davidz redhat com>
+ */
+
+#ifndef __GDU_ISCSI_PATH_MODEL_H__
+#define __GDU_ISCSI_PATH_MODEL_H__
+
+#include <gtk/gtk.h>
+#include "gdutypes.h"
+
+G_BEGIN_DECLS
+
+#define GDU_TYPE_ISCSI_PATH_MODEL (gdu_iscsi_path_model_get_type ())
+#define GDU_ISCSI_PATH_MODEL(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GDU_TYPE_ISCSI_PATH_MODEL, GduiSCSIPathModel))
+#define GDU_IS_ISCSI_PATH_MODEL(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), GDU_TYPE_ISCSI_PATH_MODEL))
+
+enum
+{
+ GDU_ISCSI_PATH_MODEL_COLUMN_ACTIVE,
+ GDU_ISCSI_PATH_MODEL_COLUMN_PORTAL_ADDRESS,
+ GDU_ISCSI_PATH_MODEL_COLUMN_PORTAL_PORT,
+ GDU_ISCSI_PATH_MODEL_COLUMN_TPGT,
+ GDU_ISCSI_PATH_MODEL_COLUMN_INTERFACE,
+ GDU_ISCSI_PATH_MODEL_COLUMN_STATUS,
+ GDU_ISCSI_PATH_MODEL_N_COLUMNS
+};
+
+GType gdu_iscsi_path_model_get_type (void) G_GNUC_CONST;
+GduiSCSIPathModel *gdu_iscsi_path_model_new (UDisksClient *client,
+ UDisksObject *object);
+UDisksClient *gdu_iscsi_path_model_get_client (GduiSCSIPathModel *model);
+UDisksObject *gdu_iscsi_path_model_get_object (GduiSCSIPathModel *model);
+
+
+G_END_DECLS
+
+#endif /* __GDU_ISCSI_PATH_MODEL_H__ */
diff --git a/src/palimpsest/gdutypes.h b/src/palimpsest/gdutypes.h
index 917908a..9728722 100644
--- a/src/palimpsest/gdutypes.h
+++ b/src/palimpsest/gdutypes.h
@@ -52,6 +52,9 @@ typedef struct _GduPasswordStrengthWidget GduPasswordStrengthWidget;
struct _GduEstimator;
typedef struct _GduEstimator GduEstimator;
+struct _GduiSCSIPathModel;
+typedef struct _GduiSCSIPathModel GduiSCSIPathModel;
+
G_END_DECLS
#endif /* __GDU_TYPES_H__ */
diff --git a/src/palimpsest/gduwindow.c b/src/palimpsest/gduwindow.c
index 607e9d6..9dc79aa 100644
--- a/src/palimpsest/gduwindow.c
+++ b/src/palimpsest/gduwindow.c
@@ -49,6 +49,7 @@
#include "gducreatediskimagedialog.h"
#include "gdurestorediskimagedialog.h"
#include "gduchangepassphrasedialog.h"
+#include "gduiscsipathmodel.h"
/* Keep in sync with tabs in palimpsest.ui file */
typedef enum
@@ -56,6 +57,7 @@ typedef enum
DETAILS_PAGE_NOT_SELECTED,
DETAILS_PAGE_NOT_IMPLEMENTED,
DETAILS_PAGE_DEVICE,
+ DETAILS_PAGE_ISCSI_TARGET,
} DetailsPage;
struct _GduWindow
@@ -106,6 +108,11 @@ struct _GduWindow
GtkWidget *devtab_action_deactivate_swap;
GtkWidget *devtab_action_generic_drive;
+ GtkWidget *iscsitab_scrolledwindow;
+ GtkWidget *iscsitab_table;
+ GtkWidget *iscsitab_toolbar;
+ GtkWidget *iscsitab_connections_treeview;
+
GtkWidget *generic_drive_menu;
GtkWidget *generic_drive_menu_item_view_smart;
GtkWidget *generic_drive_menu_item_format_disk;
@@ -161,6 +168,11 @@ static const struct {
{G_STRUCT_OFFSET (GduWindow, devtab_action_deactivate_swap), "devtab-action-deactivate-swap"},
{G_STRUCT_OFFSET (GduWindow, devtab_action_generic_drive), "devtab-action-generic-drive"},
+ {G_STRUCT_OFFSET (GduWindow, iscsitab_scrolledwindow), "iscsitab-scrolledwindow"},
+ {G_STRUCT_OFFSET (GduWindow, iscsitab_table), "iscsitab-table"},
+ {G_STRUCT_OFFSET (GduWindow, iscsitab_toolbar), "iscsitab-toolbar"},
+ {G_STRUCT_OFFSET (GduWindow, iscsitab_connections_treeview), "iscsi-connections-treeview"},
+
{G_STRUCT_OFFSET (GduWindow, generic_drive_menu), "generic-drive-menu"},
{G_STRUCT_OFFSET (GduWindow, generic_drive_menu_item_create_disk_image), "generic-drive-menu-item-create-disk-image"},
{G_STRUCT_OFFSET (GduWindow, generic_drive_menu_item_restore_disk_image), "generic-drive-menu-item-restore-disk-image"},
@@ -232,6 +244,10 @@ static void setup_device_page (GduWindow *window, UDisksObject *object);
static void update_device_page (GduWindow *window, ShowFlags *show_flags);
static void teardown_device_page (GduWindow *window);
+static void setup_iscsi_target_page (GduWindow *window, UDisksObject *object);
+static void update_iscsi_target_page (GduWindow *window);
+static void teardown_iscsi_target_page (GduWindow *window);
+
static void on_volume_grid_changed (GduVolumeGrid *grid,
gpointer user_data);
@@ -444,6 +460,10 @@ set_selected_object (GduWindow *window,
{
select_details_page (window, object, DETAILS_PAGE_DEVICE, &show_flags);
}
+ else if (udisks_object_peek_iscsi_target (object) != NULL)
+ {
+ select_details_page (window, object, DETAILS_PAGE_ISCSI_TARGET, &show_flags);
+ }
else
{
g_warning ("no page for object %s", g_dbus_object_get_object_path (G_DBUS_OBJECT (object)));
@@ -913,6 +933,12 @@ gdu_window_constructed (GObject *object)
gtk_style_context_add_class (context, GTK_STYLE_CLASS_INLINE_TOOLBAR);
gtk_style_context_set_junction_sides (context, GTK_JUNCTION_TOP);
+ context = gtk_widget_get_style_context (window->iscsitab_scrolledwindow);
+ gtk_style_context_set_junction_sides (context, GTK_JUNCTION_BOTTOM);
+ context = gtk_widget_get_style_context (window->iscsitab_toolbar);
+ gtk_style_context_add_class (context, GTK_STYLE_CLASS_INLINE_TOOLBAR);
+ gtk_style_context_set_junction_sides (context, GTK_JUNCTION_TOP);
+
window->model = gdu_device_tree_model_new (window->client);
/* set up mnemonic */
@@ -1254,6 +1280,10 @@ teardown_details_page (GduWindow *window,
case DETAILS_PAGE_DEVICE:
teardown_device_page (window);
break;
+
+ case DETAILS_PAGE_ISCSI_TARGET:
+ teardown_iscsi_target_page (window);
+ break;
}
}
@@ -1372,6 +1402,10 @@ setup_details_page (GduWindow *window,
case DETAILS_PAGE_DEVICE:
setup_device_page (window, object);
break;
+
+ case DETAILS_PAGE_ISCSI_TARGET:
+ setup_iscsi_target_page (window, object);
+ break;
}
}
@@ -1398,6 +1432,10 @@ update_details_page (GduWindow *window,
case DETAILS_PAGE_DEVICE:
update_device_page (window, show_flags);
break;
+
+ case DETAILS_PAGE_ISCSI_TARGET:
+ update_iscsi_target_page (window);
+ break;
}
}
@@ -1445,6 +1483,12 @@ update_all (GduWindow *window)
update_details_page (window, window->current_page, &show_flags);
update_for_show_flags (window, show_flags);
break;
+
+ case DETAILS_PAGE_ISCSI_TARGET:
+ show_flags = SHOW_FLAGS_NONE;
+ update_details_page (window, window->current_page, &show_flags);
+ update_for_show_flags (window, show_flags);
+ break;
}
}
@@ -2146,6 +2190,348 @@ teardown_device_page (GduWindow *window)
/* ---------------------------------------------------------------------------------------------------- */
+static void
+iscsi_target_format_portal_address (GtkCellLayout *cell_layout,
+ GtkCellRenderer *renderer,
+ GtkTreeModel *tree_model,
+ GtkTreeIter *iter,
+ gpointer user_data)
+{
+ /* GduWindow *window = GDU_WINDOW (user_data); */
+ gchar *portal_address;
+ gint portal_port;
+ gchar *markup;
+
+ gtk_tree_model_get (tree_model,
+ iter,
+ GDU_ISCSI_PATH_MODEL_COLUMN_PORTAL_ADDRESS, &portal_address,
+ GDU_ISCSI_PATH_MODEL_COLUMN_PORTAL_PORT, &portal_port,
+ -1);
+
+ /* only show port if it is non-standard */
+ if (portal_port != 3260)
+ markup = g_strdup_printf ("%s:%d", portal_address, portal_port);
+ else
+ markup = g_strdup (portal_address);
+
+ g_object_set (renderer,
+ "markup", markup,
+ NULL);
+
+ g_free (markup);
+ g_free (portal_address);
+}
+
+static void
+iscsi_target_login_cb (UDisksiSCSITarget *target,
+ GAsyncResult *res,
+ gpointer user_data)
+{
+ GduWindow *window = GDU_WINDOW (user_data);
+ GError *error;
+ error = NULL;
+ if (!udisks_iscsi_target_call_login_finish (target, res, &error))
+ {
+ gdu_window_show_error (window,
+ _("Error logging in to iSCSI target"),
+ error);
+ g_error_free (error);
+ }
+ g_object_unref (window);
+}
+
+static void
+iscsi_target_logout_cb (UDisksiSCSITarget *target,
+ GAsyncResult *res,
+ gpointer user_data)
+{
+ GduWindow *window = GDU_WINDOW (user_data);
+ GError *error;
+ error = NULL;
+ if (!udisks_iscsi_target_call_logout_finish (target, res, &error))
+ {
+ gdu_window_show_error (window,
+ _("Error logging out of iSCSI target"),
+ error);
+ g_error_free (error);
+ }
+ g_object_unref (window);
+}
+
+static void
+on_iscsi_active_toggled (GtkCellRendererToggle *renderer,
+ gchar *path,
+ gpointer user_data)
+{
+ GduWindow *window = GDU_WINDOW (user_data);
+ gboolean is_active;
+ GtkTreeModel *tree_model;
+ GtkTreeIter iter;
+ gchar *portal_address;
+ gchar *iface_name;
+ gint portal_port;
+ gint tpgt;
+ UDisksiSCSITarget *target;
+
+ portal_address = NULL;
+ iface_name = NULL;
+
+ tree_model = gtk_tree_view_get_model (GTK_TREE_VIEW (window->iscsitab_connections_treeview));
+
+ target = udisks_object_peek_iscsi_target (window->current_object);
+ if (target == NULL)
+ {
+ g_warning ("Expected selected object to be an iSCSI target");
+ goto out;
+ }
+
+ if (!gtk_tree_model_get_iter_from_string (tree_model,
+ &iter,
+ path))
+ {
+ g_warning ("Unable to get tree iter");
+ goto out;
+ }
+
+ gtk_tree_model_get (tree_model,
+ &iter,
+ GDU_ISCSI_PATH_MODEL_COLUMN_PORTAL_ADDRESS, &portal_address,
+ GDU_ISCSI_PATH_MODEL_COLUMN_PORTAL_PORT, &portal_port,
+ GDU_ISCSI_PATH_MODEL_COLUMN_TPGT, &tpgt,
+ GDU_ISCSI_PATH_MODEL_COLUMN_INTERFACE, &iface_name,
+ -1);
+
+ is_active = gtk_cell_renderer_toggle_get_active (renderer);
+ if (is_active)
+ {
+ udisks_iscsi_target_call_logout (target,
+ portal_address,
+ portal_port,
+ tpgt,
+ iface_name,
+ g_variant_new ("a{sv}", NULL), /* options */
+ NULL, /* GCancellable* */
+ (GAsyncReadyCallback) iscsi_target_logout_cb,
+ g_object_ref (window));
+ }
+ else
+ {
+ udisks_iscsi_target_call_login (target,
+ portal_address,
+ portal_port,
+ tpgt,
+ iface_name,
+ g_variant_new ("a{sv}", NULL), /* options */
+ NULL, /* GCancellable* */
+ (GAsyncReadyCallback) iscsi_target_login_cb,
+ g_object_ref (window));
+ }
+
+ out:
+ g_free (portal_address);
+ g_free (iface_name);
+}
+
+static void
+init_iscsi_target_page (GduWindow *window)
+{
+ static volatile gsize init_val = 0;
+ GtkTreeView *tree_view;
+ /* GtkTreeSelection *selection; */
+ GtkTreeViewColumn *column;
+ GtkCellRenderer *renderer;
+
+ if (!g_once_init_enter (&init_val))
+ goto out;
+
+ tree_view = GTK_TREE_VIEW (window->iscsitab_connections_treeview);
+ gtk_tree_view_set_rules_hint (tree_view, TRUE);
+#if 0
+ selection = gtk_tree_view_get_selection (tree_view);
+ gtk_tree_selection_set_select_function (selection, dont_select_headings, NULL, NULL);
+ g_signal_connect (selection,
+ "changed",
+ G_CALLBACK (on_tree_selection_changed),
+ window);
+#endif
+
+ column = gtk_tree_view_column_new ();
+ gtk_tree_view_append_column (tree_view, column);
+ renderer = gtk_cell_renderer_toggle_new ();
+ gtk_tree_view_column_pack_end (column, renderer, FALSE);
+ gtk_tree_view_column_set_attributes (column, renderer,
+ "active", GDU_ISCSI_PATH_MODEL_COLUMN_ACTIVE, NULL);
+ g_signal_connect (renderer,
+ "toggled",
+ G_CALLBACK (on_iscsi_active_toggled),
+ window);
+
+ column = gtk_tree_view_column_new ();
+ gtk_tree_view_column_set_title (column, _("Portal"));
+ gtk_tree_view_append_column (tree_view, column);
+ renderer = gtk_cell_renderer_text_new ();
+ gtk_tree_view_column_pack_start (column, renderer, TRUE);
+ gtk_tree_view_column_set_alignment (column, 0.0);
+ gtk_cell_layout_set_cell_data_func (GTK_CELL_LAYOUT (column),
+ renderer,
+ iscsi_target_format_portal_address,
+ window,
+ NULL);
+
+ column = gtk_tree_view_column_new ();
+ gtk_tree_view_column_set_title (column, _("Interface"));
+ gtk_tree_view_append_column (tree_view, column);
+ renderer = gtk_cell_renderer_text_new ();
+ gtk_tree_view_column_pack_start (column, renderer, FALSE);
+ gtk_tree_view_column_set_attributes (column, renderer,
+ "markup", GDU_ISCSI_PATH_MODEL_COLUMN_INTERFACE, NULL);
+
+ column = gtk_tree_view_column_new ();
+ gtk_tree_view_column_set_title (column, _("TPGT"));
+ gtk_tree_view_append_column (tree_view, column);
+ renderer = gtk_cell_renderer_text_new ();
+ gtk_tree_view_column_pack_start (column, renderer, FALSE);
+ gtk_tree_view_column_set_attributes (column, renderer,
+ "markup", GDU_ISCSI_PATH_MODEL_COLUMN_TPGT, NULL);
+
+ column = gtk_tree_view_column_new ();
+ gtk_tree_view_column_set_title (column, _("Status"));
+ gtk_tree_view_append_column (tree_view, column);
+ renderer = gtk_cell_renderer_text_new ();
+ gtk_tree_view_column_pack_start (column, renderer, FALSE);
+ gtk_tree_view_column_set_attributes (column, renderer,
+ "markup", GDU_ISCSI_PATH_MODEL_COLUMN_STATUS, NULL);
+
+ g_once_init_leave (&init_val, 1);
+ out:
+ ;
+}
+
+static gboolean
+iscsi_target_has_active_connections (UDisksiSCSITarget *target)
+{
+ gboolean ret = FALSE;
+ GVariant *portals_and_interfaces;
+ GVariantIter portal_iter;
+ const gchar *state;
+
+ portals_and_interfaces = udisks_iscsi_target_get_connections (target);
+ g_variant_iter_init (&portal_iter, portals_and_interfaces);
+ while (g_variant_iter_next (&portal_iter,
+ "(^&siis&sa{sv})",
+ NULL, /* &portal_adress */
+ NULL, /* &port */
+ NULL, /* &tpgt */
+ NULL, /* iface_name */
+ &state,
+ NULL)) /* expansion */
+ {
+ if (g_strcmp0 (state, "LOGGED_IN") == 0)
+ {
+ ret = TRUE;
+ goto out;
+ }
+ }
+ out:
+ return ret;
+}
+
+
+static void
+update_iscsi_target_page (GduWindow *window)
+{
+ GList *children;
+ GList *l;
+ UDisksiSCSITarget *target;
+ UDisksObject *source_object = NULL;
+ UDisksiSCSISource *source = NULL;
+ gchar *discovery = NULL;
+
+ /* first hide everything */
+ children = gtk_container_get_children (GTK_CONTAINER (window->iscsitab_table));
+ for (l = children; l != NULL; l = l->next)
+ {
+ GtkWidget *child = GTK_WIDGET (l->data);
+ gtk_widget_hide (child);
+ }
+ g_list_free (children);
+
+ target = udisks_object_peek_iscsi_target (window->current_object);
+ set_markup (window,
+ "iscsitab-name-label",
+ "iscsitab-name-value-label",
+ udisks_iscsi_target_get_name (target), SET_MARKUP_FLAGS_NONE);
+
+ /* TODO: also show Alias for the target */
+
+ source_object = udisks_client_peek_object (window->client, udisks_iscsi_target_get_source (target));
+ if (source_object != NULL)
+ source = udisks_object_peek_iscsi_source (source_object);
+ if (source != NULL)
+ {
+ const gchar *mechanism = udisks_iscsi_source_get_mechanism (source);
+ if (g_strcmp0 (mechanism, "static") == 0)
+ {
+ discovery = g_strdup (_("Statically configured"));
+ }
+ else if (g_strcmp0 (mechanism, "firmware") == 0)
+ {
+ discovery = g_strdup (_("Configured in firmware"));
+ }
+ else if (g_strcmp0 (mechanism, "sendtargets") == 0)
+ {
+ discovery = g_strdup_printf (_("%s (SendTargets protocol)"),
+ udisks_iscsi_source_get_address (source));
+ }
+ else if (g_strcmp0 (mechanism, "isns") == 0)
+ {
+ discovery = g_strdup_printf (_("%s (iSNS server)"),
+ udisks_iscsi_source_get_address (source));
+ }
+ else
+ {
+ discovery = g_strdup_printf (_("%s (Mechanism: %s)"),
+ mechanism,
+ udisks_iscsi_source_get_address (source));
+ }
+ }
+ set_markup (window,
+ "iscsitab-discovery-label",
+ "iscsitab-discovery-value-label",
+ discovery, SET_MARKUP_FLAGS_HYPHEN_IF_EMPTY);
+ g_free (discovery);
+}
+
+static void
+setup_iscsi_target_page (GduWindow *window,
+ UDisksObject *object)
+{
+ GtkTreeView *tree_view;
+ GduiSCSIPathModel *model;
+ GtkTreeIter first_iter;
+
+ init_iscsi_target_page (window);
+
+ tree_view = GTK_TREE_VIEW (window->iscsitab_connections_treeview);
+ model = gdu_iscsi_path_model_new (window->client, object);
+ gtk_tree_view_set_model (tree_view, GTK_TREE_MODEL (model));
+ /* select the first row */
+ if (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (model), &first_iter))
+ gtk_tree_selection_select_iter (gtk_tree_view_get_selection (tree_view), &first_iter);
+ g_object_unref (model);
+}
+
+static void
+teardown_iscsi_target_page (GduWindow *window)
+{
+ GtkTreeView *tree_view;
+
+ tree_view = GTK_TREE_VIEW (window->iscsitab_connections_treeview);
+ gtk_tree_view_set_model (tree_view, NULL);
+}
+
+/* ---------------------------------------------------------------------------------------------------- */
+
/* TODO: right now we show a MessageDialog but we could do things like an InfoBar etc */
void
gdu_window_show_error (GduWindow *window,
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]